From: <sa...@us...> - 2006-11-05 17:29:10
|
Revision: 17672 http://svn.sourceforge.net/gaim/?rev=17672&view=rev Author: sadrul Date: 2006-11-05 09:28:33 -0800 (Sun, 05 Nov 2006) Log Message: ----------- Rearranging a bunch of stuff. Users shouldn't notice any change, apart from the added ability to bind keys for the window-manager. I will update the manual in a while. I need to know how to revert a commit in case things go terribly wrong. ... I am going to remind everyone that Dido is AWESOME! Modified Paths: -------------- trunk/console/libgnt/Makefile.am trunk/console/libgnt/gntcombobox.c trunk/console/libgnt/gntentry.c trunk/console/libgnt/gntmain.c trunk/console/libgnt/gntmarshal.c trunk/console/libgnt/gntmarshal.h trunk/console/libgnt/gntmenu.c trunk/console/libgnt/gntmenuitem.c trunk/console/libgnt/gntstyle.c trunk/console/libgnt/gntstyle.h trunk/console/libgnt/gnttree.c trunk/console/libgnt/gntwidget.c trunk/console/libgnt/gntwidget.h trunk/console/libgnt/gntwm.h trunk/console/libgnt/test/multiwin.c trunk/console/libgnt/test/tv.c trunk/console/libgnt/wms/s.c Added Paths: ----------- trunk/console/libgnt/gntbindable.c trunk/console/libgnt/gntbindable.h trunk/console/libgnt/gntwm.c Modified: trunk/console/libgnt/Makefile.am =================================================================== --- trunk/console/libgnt/Makefile.am 2006-11-05 14:57:05 UTC (rev 17671) +++ trunk/console/libgnt/Makefile.am 2006-11-05 17:28:33 UTC (rev 17672) @@ -6,6 +6,7 @@ libgnt_la_SOURCES = \ gntwidget.c \ + gntbindable.c \ gntbox.c \ gntbutton.c \ gntcheckbox.c \ @@ -24,10 +25,12 @@ gnttree.c \ gntutils.c \ gntwindow.c \ + gntwm.c \ gntmain.c libgnt_la_headers = \ gntwidget.h \ + gntbindable.h \ gntbox.h \ gntbutton.h \ gntcheckbox.h \ Added: trunk/console/libgnt/gntbindable.c =================================================================== --- trunk/console/libgnt/gntbindable.c (rev 0) +++ trunk/console/libgnt/gntbindable.c 2006-11-05 17:28:33 UTC (rev 17672) @@ -0,0 +1,212 @@ +#include "gntbindable.h" +#include "gntstyle.h" +#include "gnt.h" +#include "gntutils.h" + +static GObjectClass *parent_class = NULL; + +static void +gnt_bindable_class_init(GntBindableClass *klass) +{ + parent_class = g_type_class_peek_parent(klass); + + klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (GDestroyNotify)gnt_bindable_action_free); + klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (GDestroyNotify)gnt_bindable_action_param_free); + + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); + GNTDEBUG; +} + +static void +duplicate_hashes(GntBindableClass *klass) +{ + /* Duplicate the bindings from parent class */ + if (klass->actions) { + klass->actions = g_hash_table_duplicate(klass->actions, g_str_hash, + g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_free); + klass->bindings = g_hash_table_duplicate(klass->bindings, g_str_hash, + g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_param_free); + } else { + klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (GDestroyNotify)gnt_bindable_action_free); + klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + (GDestroyNotify)gnt_bindable_action_param_free); + } + + GNTDEBUG; +} + +/****************************************************************************** + * GntBindable API + *****************************************************************************/ +GType +gnt_bindable_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) { + static const GTypeInfo info = { + sizeof(GntBindableClass), + (GBaseInitFunc)duplicate_hashes, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_bindable_class_init, + NULL, + NULL, /* class_data */ + sizeof(GntBindable), + 0, /* n_preallocs */ + NULL, /* instance_init */ + }; + + type = g_type_register_static(G_TYPE_OBJECT, + "GntBindable", + &info, G_TYPE_FLAG_ABSTRACT); + } + + return type; +} + +/** + * Key Remaps + */ +const char * +gnt_bindable_remap_keys(GntBindable *bindable, const char *text) +{ + const char *remap = NULL; + GType type = G_OBJECT_TYPE(bindable); + GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); + + if (klass->remaps == NULL) + { + klass->remaps = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + gnt_styles_get_keyremaps(type, klass->remaps); + } + + remap = g_hash_table_lookup(klass->remaps, text); + + return (remap ? remap : text); +} + +/** + * Actions and Bindings + */ +gboolean +gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...) +{ + GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); + GList *list = NULL; + va_list args; + GntBindableAction *action; + void *p; + + va_start(args, name); + while ((p = va_arg(args, void *)) != NULL) + list = g_list_append(list, p); + va_end(args); + + action = g_hash_table_lookup(klass->actions, name); + if (action && action->u.action) { + if (list) + return action->u.action(bindable, list); + else + return action->u.action_noparam(bindable); + } + return FALSE; +} + +gboolean +gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys) +{ + GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bindable)); + GntBindableActionParam *param = g_hash_table_lookup(klass->bindings, keys); + + if (param && param->action) { + if (param->list) + return param->action->u.action(bindable, param->list); + else + return param->action->u.action_noparam(bindable); + } + return FALSE; +} + +static void +register_binding(GntBindableClass *klass, const char *name, const char *trigger, GList *list) +{ + GntBindableActionParam *param; + GntBindableAction *action; + + if (name == NULL || *name == '\0') { + g_hash_table_remove(klass->bindings, (char*)trigger); + return; + } + + action = g_hash_table_lookup(klass->actions, name); + if (!action) { + g_printerr("GntWidget: Invalid action name %s for %s\n", + name, g_type_name(G_OBJECT_CLASS_TYPE(klass))); + if (list) + g_list_free(list); + return; + } + + param = g_new0(GntBindableActionParam, 1); + param->action = action; + param->list = list; + g_hash_table_replace(klass->bindings, g_strdup(trigger), param); +} + +void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, + const char *trigger, ...) +{ + GList *list = NULL; + va_list args; + void *data; + + va_start(args, trigger); + while ((data = va_arg(args, void *))) { + list = g_list_append(list, data); + } + va_end(args); + + register_binding(klass, name, trigger, list); +} + +void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name, + GntBindableActionCallback callback, const char *trigger, ...) +{ + void *data; + va_list args; + GntBindableAction *action = g_new0(GntBindableAction, 1); + GList *list; + + action->name = g_strdup(name); + action->u.action = callback; + + g_hash_table_replace(klass->actions, g_strdup(name), action); + + if (trigger) { + list = NULL; + va_start(args, trigger); + while ((data = va_arg(args, void *))) { + list = g_list_append(list, data); + } + va_end(args); + + register_binding(klass, name, trigger, list); + } +} + +void gnt_bindable_action_free(GntBindableAction *action) +{ + g_free(action->name); + g_free(action); +} + +void gnt_bindable_action_param_free(GntBindableActionParam *param) +{ + g_list_free(param->list); /* XXX: There may be a leak here for string parameters */ + g_free(param); +} + + Property changes on: trunk/console/libgnt/gntbindable.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/console/libgnt/gntbindable.h =================================================================== --- trunk/console/libgnt/gntbindable.h (rev 0) +++ trunk/console/libgnt/gntbindable.h 2006-11-05 17:28:33 UTC (rev 17672) @@ -0,0 +1,90 @@ +#ifndef GNT_BINDABLE_H +#define GNT_BINDABLE_H + +#include <stdio.h> +#include <glib.h> +#include <glib-object.h> +#include <ncurses.h> + +#define GNT_TYPE_BINDABLE (gnt_bindable_get_gtype()) +#define GNT_BINDABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BINDABLE, GntBindable)) +#define GNT_BINDABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BINDABLE, GntBindableClass)) +#define GNT_IS_BINDABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BINDABLE)) +#define GNT_IS_BINDABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BINDABLE)) +#define GNT_BINDABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BINDABLE, GntBindableClass)) + +#define GNTDEBUG fprintf(stderr, "%s\n", __FUNCTION__) + +typedef struct _GnBindable GntBindable; +typedef struct _GnBindableClass GntBindableClass; + +struct _GnBindable +{ + GObject inherit; +}; + +struct _GnBindableClass +{ + GObjectClass parent; + + GHashTable *remaps; /* Key remaps */ + GHashTable *actions; /* name -> Action */ + GHashTable *bindings; /* key -> ActionParam */ + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_bindable_get_gtype(void); + +/******************/ +/* Key Remaps */ +/******************/ +const char * gnt_bindable_remap_keys(GntBindable *bindable, const char *text); + +/******************/ +/* Bindable Actions */ +/******************/ +typedef gboolean (*GntBindableActionCallback) (GntBindable *bindable, GList *params); +typedef gboolean (*GntBindableActionCallbackNoParam)(GntBindable *bindable); + +typedef struct _GnBindableAction GntBindableAction; +typedef struct _GnBindableActionParam GntBindableActionParam; + +struct _GnBindableAction +{ + char *name; /* The name of the action */ + union { + gboolean (*action)(GntBindable *bindable, GList *params); + gboolean (*action_noparam)(GntBindable *bindable); + } u; +}; + +struct _GnBindableActionParam +{ + GntBindableAction *action; + GList *list; +}; + + +/*GntBindableAction *gnt_bindable_action_parse(const char *name);*/ + +void gnt_bindable_action_free(GntBindableAction *action); +void gnt_bindable_action_param_free(GntBindableActionParam *param); + +void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name, + GntBindableActionCallback callback, const char *trigger, ...); +void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, + const char *trigger, ...); + +gboolean gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys); +gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...); + +G_END_DECLS + +#endif /* GNT_BINDABLE_H */ + Property changes on: trunk/console/libgnt/gntbindable.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Modified: trunk/console/libgnt/gntcombobox.c =================================================================== --- trunk/console/libgnt/gntcombobox.c 2006-11-05 14:57:05 UTC (rev 17671) +++ trunk/console/libgnt/gntcombobox.c 2006-11-05 17:28:33 UTC (rev 17672) @@ -105,6 +105,7 @@ parent->priv.width = widget->priv.width; parent->priv.height = height + 2; + GNT_WIDGET_UNSET_FLAGS(parent, GNT_WIDGET_INVISIBLE); gnt_widget_draw(parent); } Modified: trunk/console/libgnt/gntentry.c =================================================================== --- trunk/console/libgnt/gntentry.c 2006-11-05 14:57:05 UTC (rev 17671) +++ trunk/console/libgnt/gntentry.c 2006-11-05 17:28:33 UTC (rev 17672) @@ -74,8 +74,6 @@ if (y + 10 >= getmaxy(stdscr)) y -= 11; gnt_widget_set_position(box, x, y); - - gnt_widget_draw(box); } else gnt_tree_remove_all(GNT_TREE(entry->ddown)); @@ -99,6 +97,7 @@ return FALSE; } + gnt_widget_draw(entry->ddown->parent); return TRUE; } @@ -159,9 +158,9 @@ } static gboolean -move_back(GntWidget *widget, GList *null) +move_back(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->cursor <= entry->start) return FALSE; entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor); @@ -172,9 +171,9 @@ } static gboolean -move_forward(GntWidget *widget, GList *list) +move_forward(GntBindable *bind, GList *list) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->cursor >= entry->end) return FALSE; entry->cursor = g_utf8_find_next_char(entry->cursor, NULL); @@ -185,10 +184,10 @@ } static gboolean -backspace(GntWidget *widget, GList *null) +backspace(GntBindable *bind, GList *null) { int len; - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->cursor <= entry->start) return TRUE; @@ -208,10 +207,10 @@ } static gboolean -delkey(GntWidget *widget, GList *null) +delkey(GntBindable *bind, GList *null) { int len; - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->cursor >= entry->end) return FALSE; @@ -227,18 +226,18 @@ } static gboolean -move_start(GntWidget *widget, GList *null) +move_start(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); entry->scroll = entry->cursor = entry->start; entry_redraw(GNT_WIDGET(entry)); return TRUE; } static gboolean -move_end(GntWidget *widget, GList *null) +move_end(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); entry->cursor = entry->end; /* This should be better than this */ while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) @@ -248,9 +247,9 @@ } static gboolean -history_prev(GntWidget *widget, GList *null) +history_prev(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->histlength && entry->history->prev) { entry->history = entry->history->prev; @@ -263,9 +262,9 @@ } static gboolean -history_next(GntWidget *widget, GList *null) +history_next(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->histlength && entry->history->next) { if (entry->history->prev == NULL) @@ -286,52 +285,52 @@ } static gboolean -suggest_show(GntWidget *widget, GList *null) +suggest_show(GntBindable *bind, GList *null) { - return show_suggest_dropdown(GNT_ENTRY(widget)); + return show_suggest_dropdown(GNT_ENTRY(bind)); } static gboolean -suggest_next(GntWidget *widget, GList *null) +suggest_next(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->ddown) { - gnt_widget_perform_action_named(entry->ddown, "move-down", NULL); + gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL); return TRUE; } return FALSE; } static gboolean -suggest_prev(GntWidget *widget, GList *null) +suggest_prev(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); if (entry->ddown) { - gnt_widget_perform_action_named(entry->ddown, "move-up", NULL); + gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-up", NULL); return TRUE; } return FALSE; } static gboolean -del_to_home(GntWidget *widget, GList *null) +del_to_home(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); memmove(entry->start, entry->cursor, entry->end - entry->cursor); entry->end -= (entry->cursor - entry->start); entry->cursor = entry->scroll = entry->start; memset(entry->end, '\0', entry->buffer - (entry->end - entry->start)); - entry_redraw(widget); + entry_redraw(GNT_WIDGET(bind)); return TRUE; } static gboolean -del_to_end(GntWidget *widget, GList *null) +del_to_end(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); entry->end = entry->cursor; memset(entry->end, '\0', entry->buffer - (entry->end - entry->start)); - entry_redraw(widget); + entry_redraw(GNT_WIDGET(bind)); return TRUE; } @@ -351,9 +350,9 @@ } static gboolean -move_back_word(GntWidget *widget, GList *null) +move_back_word(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntEntry *entry = GNT_ENTRY(bind); const char *iter = entry->cursor - 1; if (iter < entry->start) @@ -362,14 +361,15 @@ entry->cursor = (char*)iter; if (entry->cursor < entry->scroll) entry->scroll = entry->cursor; - entry_redraw(widget); + entry_redraw(GNT_WIDGET(bind)); return TRUE; } static gboolean -del_prev_word(GntWidget *widget, GList *null) +del_prev_word(GntBindable *bind, GList *null) { - GntEntry *entry = GNT_ENTRY(widget); + GntWidget *widget = GNT_WIDGET(bind); + GntEntry *entry = GNT_ENTRY(bind); char *iter = entry->cursor - 1; int count; @@ -535,6 +535,7 @@ static void gnt_entry_class_init(GntEntryClass *klass) { + GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); parent_class = GNT_WIDGET_CLASS(klass); parent_class->destroy = gnt_entry_destroy; parent_class->draw = gnt_entry_draw; @@ -543,53 +544,47 @@ parent_class->key_pressed = gnt_entry_key_pressed; parent_class->lost_focus = gnt_entry_lost_focus; - parent_class->actions = g_hash_table_duplicate(parent_class->actions, g_str_hash, - g_str_equal, g_free, (GDestroyNotify)gnt_widget_action_free); - parent_class->bindings = g_hash_table_duplicate(parent_class->bindings, g_str_hash, - g_str_equal, g_free, (GDestroyNotify)gnt_widget_action_param_free); - - gnt_widget_class_register_action(parent_class, "cursor-home", move_start, + gnt_bindable_class_register_action(bindable, "cursor-home", move_start, GNT_KEY_CTRL_A, NULL); - gnt_widget_register_binding(parent_class, "cursor-home", GNT_KEY_HOME, NULL); - gnt_widget_class_register_action(parent_class, "cursor-end", move_end, + gnt_bindable_register_binding(bindable, "cursor-home", GNT_KEY_HOME, NULL); + gnt_bindable_class_register_action(bindable, "cursor-end", move_end, GNT_KEY_CTRL_E, NULL); - gnt_widget_register_binding(parent_class, "cursor-end", GNT_KEY_END, NULL); - gnt_widget_class_register_action(parent_class, "delete-prev", backspace, + gnt_bindable_register_binding(bindable, "cursor-end", GNT_KEY_END, NULL); + gnt_bindable_class_register_action(bindable, "delete-prev", backspace, GNT_KEY_BACKSPACE, NULL); - gnt_widget_class_register_action(parent_class, "delete-next", delkey, + gnt_bindable_class_register_action(bindable, "delete-next", delkey, GNT_KEY_DEL, NULL); - gnt_widget_register_binding(parent_class, "delete-next", GNT_KEY_CTRL_D, NULL); - gnt_widget_class_register_action(parent_class, "delete-start", del_to_home, + gnt_bindable_register_binding(bindable, "delete-next", GNT_KEY_CTRL_D, NULL); + gnt_bindable_class_register_action(bindable, "delete-start", del_to_home, GNT_KEY_CTRL_U, NULL); - gnt_widget_class_register_action(parent_class, "delete-end", del_to_end, + gnt_bindable_class_register_action(bindable, "delete-end", del_to_end, GNT_KEY_CTRL_K, NULL); - gnt_widget_class_register_action(parent_class, "delete-prev-word", del_prev_word, + gnt_bindable_class_register_action(bindable, "delete-prev-word", del_prev_word, NULL, NULL); #if 0 - gnt_widget_class_register_action(parent_class, "delete-next-word", del_next_word, + gnt_bindable_class_register_action(bindable, "delete-next-word", del_next_word, NULL, 1, NULL); #endif - gnt_widget_class_register_action(parent_class, "cursor-prev-word", move_back_word, + gnt_bindable_class_register_action(bindable, "cursor-prev-word", move_back_word, NULL, NULL); - gnt_widget_class_register_action(parent_class, "cursor-prev", move_back, + gnt_bindable_class_register_action(bindable, "cursor-prev", move_back, GNT_KEY_LEFT, NULL); - gnt_widget_register_binding(parent_class, "cursor-prev", GNT_KEY_CTRL_B, NULL); - gnt_widget_class_register_action(parent_class, "cursor-next", move_forward, + gnt_bindable_register_binding(bindable, "cursor-prev", GNT_KEY_CTRL_B, NULL); + gnt_bindable_class_register_action(bindable, "cursor-next", move_forward, GNT_KEY_RIGHT, NULL); - gnt_widget_register_binding(parent_class, "cursor-next", GNT_KEY_CTRL_F, NULL); - gnt_widget_class_register_action(parent_class, "suggest-show", suggest_show, + gnt_bindable_register_binding(bindable, "cursor-next", GNT_KEY_CTRL_F, NULL); + gnt_bindable_class_register_action(bindable, "suggest-show", suggest_show, "\t", NULL); - gnt_widget_class_register_action(parent_class, "suggest-next", suggest_next, + gnt_bindable_class_register_action(bindable, "suggest-next", suggest_next, GNT_KEY_DOWN, NULL); - gnt_widget_class_register_action(parent_class, "suggest-prev", suggest_prev, + gnt_bindable_class_register_action(bindable, "suggest-prev", suggest_prev, GNT_KEY_UP, NULL); - gnt_widget_class_register_action(parent_class, "history-prev", history_prev, + gnt_bindable_class_register_action(bindable, "history-prev", history_prev, "\033" GNT_KEY_CTRL_DOWN, NULL); - gnt_widget_class_register_action(parent_class, "history-next", history_next, + gnt_bindable_class_register_action(bindable, "history-next", history_next, "\033" GNT_KEY_CTRL_UP, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), parent_class); - + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; } Modified: trunk/console/libgnt/gntmain.c =================================================================== --- trunk/console/libgnt/gntmain.c 2006-11-05 14:57:05 UTC (rev 17671) +++ trunk/console/libgnt/gntmain.c 2006-11-05 17:28:33 UTC (rev 17672) @@ -38,544 +38,17 @@ * Need to wattrset for colors to use with PDCurses. */ -/** - * There can be at most one menu at a time on the screen. - * If there is a menu being displayed, then all the keystrokes will be sent to - * the menu until it is closed, either when the user activates a menuitem, or - * presses Escape to cancel the menu. - */ -static GntMenu *menu; +static GIOChannel *channel = NULL; -static int lock_focus_list; -static GList *focus_list; -static GList *ordered; - -static int X_MIN; -static int X_MAX; -static int Y_MIN; -static int Y_MAX; - static gboolean ascii_only; static gboolean mouse_enabled; -/** - * 'event_stack' will be set to TRUE when a user-event, ie. a mouse-click - * or a key-press is being processed. This variable will be used to determine - * whether to give focus to a new window. - */ -static gboolean event_stack; +static void setup_io(); -static GMainLoop *loop; - -static struct -{ - GntWidget *window; - GntWidget *tree; -} _list, *window_list, *action_list; - -typedef struct -{ - GntWidget *me; - - PANEL *panel; -} GntNode; - -typedef enum -{ - GNT_KP_MODE_NORMAL, - GNT_KP_MODE_RESIZE, - GNT_KP_MODE_MOVE, - GNT_KP_MODE_MENU, - GNT_KP_MODE_WINDOW_LIST -} GntKeyPressMode; - -static GHashTable *nodes; - -static void free_node(gpointer data); -static void draw_taskbar(gboolean reposition); -static void bring_on_top(GntWidget *widget); - static gboolean refresh_screen(); -static const GList *list_all_windows(); -static void show_actions_list(); +GntWM *wm; -static GntWM wm = -{ - NULL, /* new_window */ - NULL, /* close_window */ - NULL, /* window_resize_confirm */ - NULL, /* window_resized */ - NULL, /* window_move_confirm */ - NULL, /* window_moved */ - NULL, /* window_update */ - NULL, /* key_pressed */ - NULL, /* mouse clicked */ - bring_on_top, /* give_focus */ - NULL, /* uninit */ - list_all_windows, /* window_list */ -}; - -static const GList *list_all_windows() -{ - return focus_list; -} - -static GList * -g_list_bring_to_front(GList *list, gpointer data) -{ - list = g_list_remove(list, data); - list = g_list_prepend(list, data); - return list; -} - -static gboolean -update_screen(gpointer null) -{ - if (menu) { - GntMenu *top = menu; - while (top) { - GntNode *node = g_hash_table_lookup(nodes, top); - if (node) - top_panel(node->panel); - top = top->submenu; - } - } - update_panels(); - doupdate(); - return TRUE; -} - -void gnt_screen_take_focus(GntWidget *widget) -{ - GntWidget *w = NULL; - - if (lock_focus_list) - return; - if (g_list_find(focus_list, widget)) - return; - - if (ordered) - w = ordered->data; - - focus_list = g_list_append(focus_list, widget); - - if (event_stack) { - ordered = g_list_prepend(ordered, widget); - g_object_set_data(G_OBJECT(widget), "give_focus", GINT_TO_POINTER(event_stack)); - } else - ordered = g_list_append(ordered, widget); - - gnt_widget_set_focus(widget, TRUE); - if (w) - gnt_widget_set_focus(w, FALSE); - draw_taskbar(FALSE); -} - -void gnt_screen_remove_widget(GntWidget *widget) -{ - int pos = g_list_index(focus_list, widget); - - if (lock_focus_list) - return; - - if (pos == -1) - return; - - focus_list = g_list_remove(focus_list, widget); - ordered = g_list_remove(ordered, widget); - - if (ordered) - { - wm.give_focus(ordered->data); - } - draw_taskbar(FALSE); -} - -static void -bring_on_top(GntWidget *widget) -{ - GntNode *node = g_hash_table_lookup(nodes, widget); - - if (!node) - return; - - if (ordered->data != widget) { - GntWidget *w = ordered->data; - ordered = g_list_bring_to_front(ordered, widget); - gnt_widget_set_focus(w, FALSE); - } - - gnt_widget_set_focus(widget, TRUE); - gnt_widget_draw(widget); - top_panel(node->panel); - - if (_list.window) - { - GntNode *nd = g_hash_table_lookup(nodes, _list.window); - top_panel(nd->panel); - } - update_screen(NULL); - draw_taskbar(FALSE); -} - -static void -update_window_in_list(GntWidget *wid) -{ - GntTextFormatFlags flag = 0; - - if (window_list == NULL) - return; - - if (wid == ordered->data) - flag |= GNT_TEXT_FLAG_DIM; - else if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT)) - flag |= GNT_TEXT_FLAG_BOLD; - - gnt_tree_set_row_flags(GNT_TREE(window_list->tree), wid, flag); -} - -static void -draw_taskbar(gboolean reposition) -{ - static WINDOW *taskbar = NULL; - GList *iter; - int n, width = 0; - int i; - - if (taskbar == NULL) - { - taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); - } - else if (reposition) - { - mvwin(taskbar, Y_MAX, 0); - } - - wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(taskbar); - - n = g_list_length(focus_list); - if (n) - width = getmaxx(stdscr) / n; - - for (i = 0, iter = focus_list; iter; iter = iter->next, i++) - { - GntWidget *w = iter->data; - int color; - const char *title; - - if (w == ordered->data) { - /* This is the current window in focus */ - color = GNT_COLOR_TITLE; - GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_URGENT); - if (wm.window_update) { - GntNode *node = g_hash_table_lookup(nodes, w); - wm.window_update(node ? node->panel : NULL, w); - } - } else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_URGENT)) { - /* This is a window with the URGENT hint set */ - color = GNT_COLOR_URGENT; - } else { - color = GNT_COLOR_NORMAL; - } - wbkgdset(taskbar, '\0' | COLOR_PAIR(color)); - mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), width); - title = GNT_BOX(w)->title; - mvwprintw(taskbar, 0, width * i, "%s", title ? title : "<gnt>"); - if (i) - mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | COLOR_PAIR(GNT_COLOR_NORMAL)); - - update_window_in_list(w); - } - - wrefresh(taskbar); -} - -static void -switch_window(int direction) -{ - GntWidget *w = NULL, *wid = NULL; - int pos; - - if (!ordered || !ordered->next) - return; - - w = ordered->data; - pos = g_list_index(focus_list, w); - pos += direction; - - if (pos < 0) - wid = g_list_last(focus_list)->data; - else if (pos >= g_list_length(focus_list)) - wid = focus_list->data; - else if (pos >= 0) - wid = g_list_nth_data(focus_list, pos); - - ordered = g_list_bring_to_front(ordered, wid); - - wm.give_focus(ordered->data); - - if (w != wid) - { - gnt_widget_set_focus(w, FALSE); - } -} - -static void -switch_window_n(int n) -{ - GntWidget *w = NULL; - GList *l; - - if (!ordered) - return; - - w = ordered->data; - - if ((l = g_list_nth(focus_list, n)) != NULL) - { - ordered = g_list_bring_to_front(ordered, l->data); - wm.give_focus(ordered->data); - } - - if (l && w != l->data) - { - gnt_widget_set_focus(w, FALSE); - } -} - -static void -window_list_activate(GntTree *tree, gpointer null) -{ - GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree)); - GntWidget *old = NULL; - - if (!ordered || !widget) - return; - - old = ordered->data; - ordered = g_list_bring_to_front(ordered, widget); - wm.give_focus(widget); - - if (old != widget) - { - gnt_widget_set_focus(old, FALSE); - } -} - -static void -setup__list() -{ - GntWidget *tree, *win; - win = _list.window = gnt_box_new(FALSE, FALSE); - gnt_box_set_toplevel(GNT_BOX(win), TRUE); - gnt_box_set_pad(GNT_BOX(win), 0); - - tree = _list.tree = gnt_tree_new(); - gnt_box_add_widget(GNT_BOX(win), tree); -} - -static void -show_window_list() -{ - GntWidget *tree, *win; - GList *iter; - - if (window_list) - return; - - setup__list(); - - window_list = &_list; - - win = window_list->window; - tree = window_list->tree; - - gnt_box_set_title(GNT_BOX(win), "Window List"); - - for (iter = focus_list; iter; iter = iter->next) - { - GntBox *box = GNT_BOX(iter->data); - - gnt_tree_add_row_last(GNT_TREE(tree), box, - gnt_tree_create_row(GNT_TREE(tree), box->title), NULL); - update_window_in_list(GNT_WIDGET(box)); - } - - gnt_tree_set_selected(GNT_TREE(tree), ordered->data); - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), NULL); - - gnt_tree_set_col_width(GNT_TREE(tree), 0, getmaxx(stdscr) / 3); - gnt_widget_set_size(tree, 0, getmaxy(stdscr) / 2); - gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); - - lock_focus_list = 1; - gnt_widget_show(win); - lock_focus_list = 0; -} - -static void -shift_window(GntWidget *widget, int dir) -{ - GList *all = focus_list; - GList *list = g_list_find(all, widget); - int length, pos; - if (!list) - return; - - length = g_list_length(all); - pos = g_list_position(all, list); - - pos += dir; - if (dir > 0) - pos++; - - if (pos < 0) - pos = length; - else if (pos > length) - pos = 0; - - all = g_list_insert(all, widget, pos); - all = g_list_delete_link(all, list); - focus_list = all; - draw_taskbar(FALSE); -} - -static void -dump_screen() -{ - int x, y; - chtype old = 0, now = 0; - FILE *file = fopen("dump.html", "w"); - - fprintf(file, "<pre>"); - for (y = 0; y < getmaxy(stdscr); y++) - { - for (x = 0; x < getmaxx(stdscr); x++) - { - char ch; - now = mvwinch(curscr, y, x); - ch = now & A_CHARTEXT; - now ^= ch; - -#define CHECK(attr, start, end) \ - do \ - { \ - if (now & attr) \ - { \ - if (!(old & attr)) \ - fprintf(file, start); \ - } \ - else if (old & attr) \ - { \ - fprintf(file, end); \ - } \ - } while (0) - - CHECK(A_BOLD, "<b>", "</b>"); - CHECK(A_UNDERLINE, "<u>", "</u>"); - CHECK(A_BLINK, "<blink>", "</blink>"); - - if ((now & A_COLOR) != (old & A_COLOR) || - (now & A_REVERSE) != (old & A_REVERSE)) - { - int ret; - short fgp, bgp, r, g, b; - struct - { - int r, g, b; - } fg, bg; - - ret = pair_content(PAIR_NUMBER(now & A_COLOR), &fgp, &bgp); - if (fgp == -1) - fgp = COLOR_BLACK; - if (bgp == -1) - bgp = COLOR_WHITE; - if (now & A_REVERSE) - fgp ^= bgp ^= fgp ^= bgp; /* *wink* */ - ret = color_content(fgp, &r, &g, &b); - fg.r = r; fg.b = b; fg.g = g; - ret = color_content(bgp, &r, &g, &b); - bg.r = r; bg.b = b; bg.g = g; -#define ADJUST(x) (x = x * 255 / 1000) - ADJUST(fg.r); - ADJUST(fg.g); - ADJUST(fg.b); - ADJUST(bg.r); - ADJUST(bg.b); - ADJUST(bg.g); - - if (x) fprintf(file, "</span>"); - fprintf(file, "<span style=\"background:#%02x%02x%02x;color:#%02x%02x%02x\">", - bg.r, bg.g, bg.b, fg.r, fg.g, fg.b); - } - if (now & A_ALTCHARSET) - { - switch (ch) - { - case 'q': - ch = '-'; break; - case 't': - case 'u': - case 'x': - ch = '|'; break; - case 'v': - case 'w': - case 'l': - case 'm': - case 'k': - case 'j': - case 'n': - ch = '+'; break; - case '-': - ch = '^'; break; - case '.': - ch = 'v'; break; - case 'a': - ch = '#'; break; - default: - ch = ' '; break; - } - } - if (ch == '&') - fprintf(file, "&"); - else if (ch == '<') - fprintf(file, "<"); - else if (ch == '>') - fprintf(file, ">"); - else - fprintf(file, "%c", ch); - old = now; - } - fprintf(file, "</span>\n"); - old = 0; - } - fprintf(file, "</pre>"); - fclose(file); -} - -static void -refresh_node(GntWidget *widget, GntNode *node, gpointer null) -{ - int x, y, w, h; - int nw, nh; - - gnt_widget_get_position(widget, &x, &y); - gnt_widget_get_size(widget, &w, &h); - - if (x + w >= X_MAX) - x = MAX(0, X_MAX - w); - if (y + h >= Y_MAX) - y = MAX(0, Y_MAX - h); - gnt_screen_move_widget(widget, x, y); - - nw = MIN(w, X_MAX); - nh = MIN(h, Y_MAX); - if (nw != w || nh != h) - gnt_screen_resize_widget(widget, nw, nh); -} - /** * Mouse support: * - bring a window on top if you click on its taskbar @@ -602,7 +75,7 @@ GntWidget *widget = NULL; PANEL *p = NULL; - if (!ordered || buffer[0] != 27) + if (!wm->ordered || buffer[0] != 27) return FALSE; buffer++; @@ -653,16 +126,13 @@ } else return FALSE; - if (wm.mouse_clicked && wm.mouse_clicked(event, x, y, widget)) + if (gnt_wm_process_click(wm, event, x, y, widget)) return TRUE; - if (event == GNT_LEFT_MOUSE_DOWN && widget && widget != _list.window && + if (event == GNT_LEFT_MOUSE_DOWN && widget && widget != wm->_list.window && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { - if (widget != ordered->data) { - GntWidget *w = ordered->data; - ordered = g_list_bring_to_front(ordered, widget); - wm.give_focus(ordered->data); - gnt_widget_set_focus(w, FALSE); + if (widget != wm->ordered->data) { + gnt_wm_raise_window(wm, widget); } if (y == widget->priv.y) { offset = x - widget->priv.x; @@ -672,17 +142,16 @@ } else if (event == GNT_MOUSE_UP) { if (button == MOUSE_NONE && y == getmaxy(stdscr) - 1) { /* Clicked on the taskbar */ - int n = g_list_length(focus_list); + int n = g_list_length(wm->list); if (n) { int width = getmaxx(stdscr) / n; - switch_window_n(x / width); + gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "switch-window-n", x/width, NULL); } } else if (button == MOUSE_LEFT && remember) { x -= offset; if (x < 0) x = 0; if (y < 0) y = 0; gnt_screen_move_widget(remember, x, y); - refresh_node(remember, NULL, NULL); } button = MOUSE_NONE; remember = NULL; @@ -690,87 +159,25 @@ } gnt_widget_clicked(widget, event, x, y); - return TRUE; /* XXX: this should be TRUE */ + return TRUE; } -#ifndef NO_WIDECHAR -static int -widestringwidth(wchar_t *wide) +static gboolean +io_invoke_error(GIOChannel *source, GIOCondition cond, gpointer data) { - int len, ret; - char *string; + int id = GPOINTER_TO_INT(data); + g_source_remove(id); + g_io_channel_unref(source); - len = wcstombs(NULL, wide, 0) + 1; - string = g_new0(char, len); - wcstombs(string, wide, len); - ret = gnt_util_onscreen_width(string, NULL); - g_free(string); - return ret; + channel = NULL; + setup_io(); + return TRUE; } -#endif -/* Returns the onscreen width of the character at the position */ -static int -reverse_char(WINDOW *d, int y, int x, gboolean set) -{ -#define DECIDE(ch) (set ? ((ch) | A_REVERSE) : ((ch) & ~A_REVERSE)) - -#ifdef NO_WIDECHAR - chtype ch; - ch = mvwinch(d, y, x); - mvwaddch(d, y, x, DECIDE(ch)); - return 1; -#else - cchar_t ch; - int wc = 1; - if (mvwin_wch(d, y, x, &ch) == OK) { - wc = widestringwidth(ch.chars); - ch.attr = DECIDE(ch.attr); - ch.attr &= WA_ATTRIBUTES; /* XXX: This is a workaround for a bug */ - mvwadd_wch(d, y, x, &ch); - } - - return wc; -#endif -} - -static void -window_reverse(GntWidget *win, gboolean set) -{ - int i; - int w, h; - WINDOW *d; - - if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER)) - return; - - d = win->window; - gnt_widget_get_size(win, &w, &h); - - if (gnt_widget_has_shadow(win)) { - --w; - --h; - } - - /* the top and bottom */ - for (i = 0; i < w; i += reverse_char(d, 0, i, set)); - for (i = 0; i < w; i += reverse_char(d, h-1, i, set)); - - /* the left and right */ - for (i = 0; i < h; i += reverse_char(d, i, 0, set)); - for (i = 0; i < h; i += reverse_char(d, i, w-1, set)); - - wrefresh(win->window); -} - static gboolean io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char keys[256]; - gboolean ret = FALSE; - static GntKeyPressMode mode = GNT_KP_MODE_NORMAL; - const char *buffer; - int rd = read(STDIN_FILENO, keys, sizeof(keys) - 1); if (rd < 0) { @@ -787,255 +194,48 @@ raise(SIGABRT); } - event_stack = TRUE; keys[rd] = 0; - - if (keys[0] == 27 && keys[1] == 'd' && keys[2] == 0) - { - /* This dumps the screen contents in an html file */ - dump_screen(); - } - gnt_keys_refine(keys); if (mouse_enabled && detect_mouse_action(keys)) return TRUE; - if (wm.key_pressed) { - buffer = wm.key_pressed(keys); - if (buffer == NULL) { - event_stack = FALSE; - return TRUE; - } - } else - buffer = keys; + gnt_wm_process_input(wm, keys); - if (mode == GNT_KP_MODE_NORMAL) - { - if (menu) { - ret = gnt_widget_key_pressed(GNT_WIDGET(menu), buffer); - } else if (ordered) { - ret = gnt_widget_key_pressed(ordered->data, buffer); - } + return TRUE; +} - if (!ret) - { - if (buffer[0] == 27) - { - /* Some special key has been pressed */ - if (strcmp(buffer, GNT_KEY_POPUP) == 0) - {} - else if (strcmp(buffer + 1, "c") == 0) - { - /* Alt + c was pressed. I am going to use it to close a window. */ - if (ordered) - { - gnt_widget_destroy(ordered->data); - } - } - else if (strcmp(buffer + 1, "q") == 0) - { - /* I am going to use Alt + q to quit. */ - g_main_loop_quit(loop); - } - else if (strcmp(buffer + 1, "n") == 0) - { - /* Alt + n to go to the next window */ - switch_window(1); - } - else if (strcmp(buffer + 1, "p") == 0) - { - /* Alt + p to go to the previous window */ - switch_window(-1); - } - else if (strcmp(buffer + 1, "m") == 0 && focus_list) - { - /* Move a window */ - mode = GNT_KP_MODE_MOVE; - window_reverse(ordered->data, TRUE); - } - else if (strcmp(buffer + 1, "w") == 0 && focus_list) - { - /* Window list */ - mode = GNT_KP_MODE_WINDOW_LIST; - show_window_list(); - } - else if (strcmp(buffer + 1, "a") == 0) - { - mode = GNT_KP_MODE_WINDOW_LIST; - show_actions_list(); - } - else if (strcmp(buffer + 1, "r") == 0 && focus_list) - { - /* Resize window */ - mode = GNT_KP_MODE_RESIZE; - window_reverse(ordered->data, TRUE); - } - else if (strcmp(buffer + 1, ",") == 0 && focus_list) - { - /* Re-order the list of windows */ - shift_window(ordered->data, -1); - } - else if (strcmp(buffer + 1, ".") == 0 && focus_list) - { - shift_window(ordered->data, 1); - } - else if (strcmp(buffer + 1, "l") == 0) - { - refresh_screen(); - } - else if (strlen(buffer) == 2 && isdigit(*(buffer + 1))) - { - int n = *(buffer + 1) - '0'; +static void +setup_io() +{ + int result; + channel = g_io_channel_unix_new(STDIN_FILENO); - if (n == 0) - n = 10; + g_io_channel_set_encoding(channel, NULL, NULL); + g_io_channel_set_buffered(channel, FALSE); +#if 0 + g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL ); +#endif - switch_window_n(n - 1); - } - } - } - } - else if (mode == GNT_KP_MODE_MOVE && focus_list) - { - if (buffer[0] == 27) - { - gboolean changed = FALSE; - int x, y, w, h; - GntWidget *widget = GNT_WIDGET(ordered->data); + result = g_io_add_watch_full(channel, G_PRIORITY_HIGH, + (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI), + io_invoke, NULL, NULL); + + g_io_add_watch_full(channel, G_PRIORITY_HIGH, + (G_IO_NVAL), + io_invoke_error, GINT_TO_POINTER(result), NULL); + + g_io_channel_unref(channel); /* Apparently this caused crashes for some people. + But irssi does this, so I am going to assume the + crashes were caused by some other stuff. */ - gnt_widget_get_position(widget, &x, &y); - gnt_widget_get_size(widget, &w, &h); - - if (strcmp(buffer, GNT_KEY_LEFT) == 0) - { - if (x > X_MIN) - { - x--; - changed = TRUE; - } - } - else if (strcmp(buffer, GNT_KEY_RIGHT) == 0) - { - if (x + w < X_MAX) - { - x++; - changed = TRUE; - } - } - else if (strcmp(buffer, GNT_KEY_UP) == 0) - { - if (y > Y_MIN) - { - y--; - changed = TRUE; - } - } - else if (strcmp(buffer, GNT_KEY_DOWN) == 0) - { - if (y + h < Y_MAX) - { - y++; - changed = TRUE; - } - } - else if (buffer[1] == 0) - { - mode = GNT_KP_MODE_NORMAL; - window_reverse(widget, FALSE); - } - - if (changed) - { - gnt_screen_move_widget(widget, x, y); - } - } - else if (*buffer == '\r') - { - mode = GNT_KP_MODE_NORMAL; - window_reverse(ordered->data, FALSE); - } - } - else if (mode == GNT_KP_MODE_WINDOW_LIST && _list.window) - { - gnt_widget_key_pressed(_list.window, buffer); - - if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0)) - { - mode = GNT_KP_MODE_NORMAL; - lock_focus_list = 1; - gnt_widget_destroy(_list.window); - _list.window = NULL; - _list.tree = NULL; - lock_focus_list = 0; - window_list = NULL; - action_list = NULL; - } - } - else if (mode == GNT_KP_MODE_RESIZE) - { - if (buffer[0] == '\r' || (buffer[0] == 27 && buffer[1] == 0)) { - mode = GNT_KP_MODE_NORMAL; - window_reverse(ordered->data, FALSE); - } else if (buffer[0] == 27) { - GntWidget *widget = ordered->data; - gboolean changed = FALSE; - int width, height; - - gnt_widget_get_size(widget, &width, &height); - - if (strcmp(buffer, GNT_KEY_DOWN) == 0) - { - if (widget->priv.y + height < Y_MAX) - { - height++; - changed = TRUE; - } - } - else if (strcmp(buffer, GNT_KEY_UP) == 0) - { - height--; - changed = TRUE; - } - else if (strcmp(buffer, GNT_KEY_LEFT) == 0) - { - width--; - changed = TRUE; - } - else if (strcmp(buffer, GNT_KEY_RIGHT) == 0) - { - if (widget->priv.x + width < X_MAX) - { - width++; - changed = TRUE; - } - } - - if (changed) - { - gnt_screen_resize_widget(widget, width, height); - window_reverse(widget, TRUE); - } - } - } - - event_stack = FALSE; - return TRUE; + g_printerr("gntmain: setting up IO\n"); } static gboolean refresh_screen() { - endwin(); - refresh(); - - X_MAX = getmaxx(stdscr); - Y_MAX = getmaxy(stdscr) - 1; - - g_hash_table_foreach(nodes, (GHFunc)refresh_node, NULL); - update_screen(NULL); - draw_taskbar(TRUE); - + gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "refresh-screen", NULL); return FALSE; } @@ -1082,44 +282,29 @@ const char *name = gnt_style_get(GNT_STYLE_WM); gpointer handle; - if (!name || !*name) - return; - - handle = g_module_open(name, G_MODULE_BIND_LAZY); - if (handle) { - gboolean (*init)(GntWM *); - if (g_module_symbol(handle, "gntwm_init", (gpointer)&init)) { - init(&wm); + if (name && *name) { + handle = g_module_open(name, G_MODULE_BIND_LAZY); + if (handle) { + gboolean (*init)(GntWM **); + if (g_module_symbol(handle, "gntwm_init", (gpointer)&init)) { + init(&wm); + } } } + if (wm == NULL) + wm = g_object_new(GNT_TYPE_WM, NULL); } void gnt_init() { - static GIOChannel *channel = NULL; char *filename; - int result; const char *locale; if (channel) return; - channel = g_io_channel_unix_new(STDIN_FILENO); + setup_io(); - g_io_channel_set_encoding(channel, NULL, NULL); - g_io_channel_set_buffered(channel, FALSE); -#if 0 - g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL ); -#endif - - result = g_io_add_watch_full(channel, G_PRIORITY_HIGH, - (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI | G_IO_NVAL), - io_invoke, NULL, NULL); - - g_io_channel_unref(channel); /* Apparently this caused crashes for some people. - But irssi does this, so I am going to assume the - crashes were caused by some other stuff. */ - locale = setlocale(LC_ALL, ""); if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) @@ -1139,13 +324,7 @@ g_free(filename); gnt_init_colors(); - X_MIN = 0; - Y_MIN = 0; - X_MAX = getmaxx(stdscr); - Y_MAX = getmaxy(stdscr) - 1; - nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); - wbkgdset(stdscr, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); refresh(); @@ -1171,112 +350,27 @@ void gnt_main() { - loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(loop); + wm->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(wm->loop); } /********************************* * Stuff for 'window management' * *********************************/ -static void -free_node(gpointer data) -{ - GntNode *node = data; - hide_panel(node->panel); - del_panel(node->panel); - g_free(node); -} - void gnt_screen_occupy(GntWidget *widget) { - GntNode *node; - - while (widget->parent) - widget = widget->parent; - - if (g_hash_table_lookup(nodes, widget)) - return; /* XXX: perhaps _update instead? */ - - node = g_new0(GntNode, 1); - node->me = widget; - - g_hash_table_replace(nodes, widget, node); - - refresh_node(widget, node, NULL); - - if (window_list) - { - if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && window_list->window != widget - && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) - { - gnt_tree_add_row_last(GNT_TREE(window_list->tree), widget, - gnt_tree_create_row(GNT_TREE(window_list->tree), GNT_BOX(widget)->title), - NULL); - update_window_in_list(widget); - } - } - - update_screen(NULL); + gnt_wm_new_window(wm, widget); } void gnt_screen_release(GntWidget *widget) { - GntNode *node; - - gnt_screen_remove_widget(widget); - node = g_hash_table_lookup(nodes, widget); - - if (node == NULL) /* Yay! Nothing to do. */ - return; - - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DESTROYING) && wm.close_window) - wm.close_window(widget); - - g_hash_table_remove(nodes, widget); - - if (window_list) - { - gnt_tree_remove(GNT_TREE(window_list->tree), widget); - } - - update_screen(NULL); + gnt_wm_window_close(wm, widget); } void gnt_screen_update(GntWidget *widget) { - GntNode *node; - - while (widget->parent) - widget = widget->parent; - if (!GNT_IS_MENU(widget)) - gnt_box_sync_children(GNT_BOX(widget)); - node = g_hash_table_lookup(nodes, widget); - if (node && !node->panel) - { - if (wm.new_window && node->me != _list.window) - node->panel = wm.new_window(node->me); - else - node->panel = new_panel(node->me->window); - set_panel_userptr(node->panel, node); - if (!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT)) { - if (!g_object_get_data(G_OBJECT(node->me), "give_focus")) { - bottom_panel(node->panel); /* New windows should not grab focus */ - gnt_widget_set_urgent(node->me); - } - else { - bring_on_top(node->me); - } - } - } - - if (_list.window) - { - GntNode *nd = g_hash_table_lookup(nodes, _list.window); - top_panel(nd->panel); - } - - update_screen(NULL); + gnt_wm_update_window(wm, widget); } gboolean gnt_widget_has_focus(GntWidget *widget) @@ -1293,16 +387,13 @@ while (widget->parent) widget = widget->parent; - if (widget == _list.window) + if (widget == wm->_list.window) return TRUE; - - if (ordered && ordered->data == widget) - { + if (wm->ordered && wm->ordered->data == widget) { if (GNT_IS_BOX(widget) && (GNT_BOX(widget)->active == w || widget == w)) return TRUE; } - return FALSE; } @@ -1311,21 +402,19 @@ while (widget->parent) widget = widget->parent; - if (ordered && ordered->data == widget) + if (wm->ordered && wm->ordered->data == widget) return; GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_URGENT); - if (wm.window_update) { - GntNode *node = g_hash_table_lookup(nodes, widget); - wm.window_update(node ? node->panel : NULL, widget); - } - - draw_taskbar(FALSE); + gnt_wm_update_window(wm, widget); } void gnt_quit() { + g_hash_table_destroy(wm->nodes); /* XXX: */ + update_panels(); + doupdate(); gnt_uninit_colors(); gnt_uninit_styles(); endwin(); @@ -1338,145 +427,48 @@ void gnt_screen_resize_widget(GntWidget *widget, int width, int height) { - if (widget->parent == NULL) - { - GntNode *node = g_hash_table_lookup(nodes, widget); - if (!node) - return; - - if (wm.window_resize_confirm && !wm.window_resize_confirm(widget, &width, &height)) - return; - - hide_panel(node->panel); - gnt_widget_set_size(widget, width, height); - gnt_widget_draw(widget); - if (wm.window_resized) - node->panel = wm.window_resized(node->panel, widget); - else - replace_panel(node->panel, widget->window); - show_panel(node->panel); - update_screen(NULL); - } + gnt_wm_resize_window(wm, widget, width, height); } void gnt_screen_move_widget(GntWidget *widget, int x, int y) { - GntNode *node = g_hash_table_lookup(nodes, widget); - - if (wm.window_move_confirm && !wm.window_move_confirm(widget, &x, &y)) - return; - - gnt_widget_set_position(widget, x, y); - move_panel(node->panel, y, x); - - if (wm.window_moved) - wm.window_moved(node->panel, widget); - - update_screen(NULL); + gnt_wm_move_window(wm, widget, x, y); } void gnt_screen_rename_widget(GntWidget *widget, const char *text) { gnt_box_set_title(GNT_BOX(widget), text); gnt_widget_draw(widget); - - if (wm.window_update) { - GntNode *node = g_hash_table_lookup(nodes, widget); - wm.window_update(node ? node->panel : NULL, widget); - } - - draw_taskbar(FALSE); + gnt_wm_update_window(wm, widget); } -/** - * An application can register actions which will show up in a 'start-menu' like popup - */ -typedef struct _GnAction -{ - const char *label; - void (*callback)(); -} GntAction; - -static GList *actions; - void gnt_register_action(const char *label, void (*callback)()) { GntAction *action = g_new0(GntAction, 1); action->label = g_strdup(label); action->callback = callback; - actions = g_list_append(actions, action); + wm->acts = g_list_append(wm->acts, action); } static void -action_list_activate(GntTree *tree, gpointer null) -{ - GntAction *action = gnt_tree_get_selection_data(tree); - action->callback(); -} - -static int -compare_action(gconstpointer p1, gconstpointer p2) -{ - const GntAction *a1 = p1; - const GntAction *a2 = p2; - - return g_utf8_collate(a1->label, a2->label); -} - -static void -show_actions_list() -{ - GntWidget *tree, *win; - GList *iter; - int h; - - if (action_list) - return; - - setup__list(); - action_list = &_list; - win = action_list->window; - tree = action_list->tree; - - gnt_box_set_title(GNT_BOX(win), "Actions"); - GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); - /* XXX: Do we really want this? */ - gnt_tree_set_compare_func(GNT_TREE(tree), compare_action); - - for (iter = actions; iter; iter = iter->next) { - GntAction *action = iter->data; - gnt_tree_add_row_last(GNT_TREE(tree), action, - gnt_tree_create_row(GNT_TREE(tree), action->label), NULL); - } - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(action_list_activate), NULL); - gnt_widget_set_size(tree, 0, g_list_length(actions)); - gnt_widget_get_size(win, NULL, &h); - gnt_widget_set_position(win, 0, getmaxy(stdscr) - 1 - h); - - lock_focus_list = 1; - gnt_widget_show(win); - lock_focus_list = 0; -} - -static void reset_menu(GntWidget *widget, gpointer null) { - menu = NULL; + wm->menu = NULL; } gboolean gnt_screen_menu_show(gpointer newmenu) { - if (menu) { + if (wm->menu) { /* For now, if a menu is being displayed, then another menu * can NOT take over. */ return FALSE; } - menu = newmenu; - gnt_widget_draw(GNT_WIDGET(menu)); + wm->menu = newmenu; + gnt_widget_draw(GNT_WIDGET(wm->menu)); - g_signal_connect(G_OBJECT(menu), "hide", G_CALLBACK(reset_menu), NULL); + g_signal_connect(G_OBJECT(wm->menu), "hide", G_CALLBACK(reset_menu), NULL); return TRUE; } Modified: trunk/console/libgnt/gntmarshal.c =================================================================== --- trunk/console/libgnt/gntmarshal.c 2006-11-05 14:57:05 UTC (rev 17671) +++ trunk/console/libgnt/gntmarshal.c 2006-11-05 17:28:33 UTC (rev 17672) @@ -1,237 +1,427 @@ -#include "gntmarshal.h" -void gnt_closure_marshal_BOOLEAN__VOID(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +#include <glib-object.h> + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* BOOLEAN:VOID (/dev/stdin:1) */ +void +gnt_closure_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef gboolean (*func) (gpointer data1, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean ret; + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_BOOLEAN__VOID callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - g_return_if_fail(ret_value != NULL); - g_return_if_fail(n_param_values == 1); + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); - if (G_CCLOSURE_SWAP_DATA(closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer(param_values + 0); - } - else - { - data1 = g_value_peek_pointer(param_values + 0); - data2 = closure->data; - } + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); - callback = (func) (marshal_data ? marshal_data : cc->callback); - ret = callback(data1, data2); - g_value_set_boolean(ret_value, ret); + v_return = callback (data1, + data2); + + g_value_set_boolean (return_value, v_return); } -void gnt_closure_marshal_BOOLEAN__STRING(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* BOOLEAN:STRING (/dev/stdin:2) */ +void +gnt_closure_marshal_BOOLEAN__STRING (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef gboolean (*func) (gpointer data1, const char *arg1, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean ret; + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer data1, + gpointer arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - g_return_if_fail(ret_value != NULL); - g_return_if_fail(n_param_values == 2); + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); - if (G_CCLOSURE_SWAP_DATA(closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer(param_values + 0); - } - else - { - data1 = g_value_peek_pointer(param_values + 0); - data2 = closure->data; - } + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING) (marshal_data ? marshal_data : cc->callback); - callback = (func) (marshal_data ? marshal_data : cc->callback); - ret = callback(data1, g_value_get_string(param_values + 1) , data2); - g_value_set_boolean(ret_value, ret); + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); } -void gnt_closure_marshal_VOID__INT_INT_INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* VOID:INT,INT,INT,INT (/dev/stdin:3) */ +void +gnt_clo... [truncated message content] |