Mercurial > pidgin.yaz
changeset 14900:065e7ac30338
[gaim-migrate @ 17672]
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!
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Sun, 05 Nov 2006 17:28:33 +0000 |
parents | a8f92a837590 |
children | d9d28bd79715 |
files | console/libgnt/Makefile.am console/libgnt/gntbindable.c console/libgnt/gntbindable.h console/libgnt/gntcombobox.c console/libgnt/gntentry.c console/libgnt/gntmain.c console/libgnt/gntmarshal.c console/libgnt/gntmarshal.h console/libgnt/gntmenu.c console/libgnt/gntmenuitem.c console/libgnt/gntstyle.c console/libgnt/gntstyle.h console/libgnt/gnttree.c console/libgnt/gntwidget.c console/libgnt/gntwidget.h console/libgnt/gntwm.c console/libgnt/gntwm.h console/libgnt/test/multiwin.c console/libgnt/test/tv.c console/libgnt/wms/s.c |
diffstat | 20 files changed, 2376 insertions(+), 1756 deletions(-) [+] |
line wrap: on
line diff
--- a/console/libgnt/Makefile.am Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/Makefile.am Sun Nov 05 17:28:33 2006 +0000 @@ -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 \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntbindable.c Sun Nov 05 17:28:33 2006 +0000 @@ -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); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntbindable.h Sun Nov 05 17:28:33 2006 +0000 @@ -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 */ +
--- a/console/libgnt/gntcombobox.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntcombobox.c Sun Nov 05 17:28:33 2006 +0000 @@ -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); }
--- a/console/libgnt/gntentry.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntentry.c Sun Nov 05 17:28:33 2006 +0000 @@ -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; }
--- a/console/libgnt/gntmain.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntmain.c Sun Nov 05 17:28:33 2006 +0000 @@ -38,543 +38,16 @@ * 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 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 GIOChannel *channel = NULL; 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 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 void setup_io(); static gboolean refresh_screen(); -static const GList *list_all_windows(); -static void show_actions_list(); - -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); -} +GntWM *wm; /** * Mouse support: @@ -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; - - 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; -} -#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)) + int id = GPOINTER_TO_INT(data); + g_source_remove(id); + g_io_channel_unref(source); -#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); + channel = NULL; + setup_io(); + return TRUE; } 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'; - - if (n == 0) - n = 10; - - 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); - - gnt_widget_get_position(widget, &x, &y); - gnt_widget_get_size(widget, &w, &h); +static void +setup_io() +{ + int result; + channel = g_io_channel_unix_new(STDIN_FILENO); - 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); + 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 - 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); + 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. */ - 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,43 +282,28 @@ 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); - - 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. */ + setup_io(); locale = setlocale(LC_ALL, ""); @@ -1139,12 +324,6 @@ 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); -} - -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; + wm->acts = g_list_append(wm->acts, action); } 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; }
--- a/console/libgnt/gntmarshal.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntmarshal.c Sun Nov 05 17:28:33 2006 +0000 @@ -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) -{ - typedef gboolean (*func) (gpointer data1, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean ret; +#include <glib-object.h> + - g_return_if_fail(ret_value != NULL); - g_return_if_fail(n_param_values == 1); +#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 */ - 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; - } + +/* 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 (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_BOOLEAN__VOID callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - callback = (func) (marshal_data ? marshal_data : cc->callback); - ret = callback(data1, data2); - g_value_set_boolean(ret_value, ret); + 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; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + + 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_closure_marshal_VOID__INT_INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef void (*func) (gpointer data1, int, int, int, int, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; + typedef void (*GMarshalFunc_VOID__INT_INT_INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gint arg_3, + gint arg_4, + gpointer data2); + register GMarshalFunc_VOID__INT_INT_INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 5); - g_return_if_fail(n_param_values == 5); + 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_VOID__INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback); - 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 (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_int (param_values + 4), + data2); +} - callback = (func) (marshal_data ? marshal_data : cc->callback); - callback(data1, - g_value_get_int(param_values + 1) , - g_value_get_int(param_values + 2) , - g_value_get_int(param_values + 3) , - g_value_get_int(param_values + 4) , - data2); +/* VOID:INT,INT (/dev/stdin:4) */ +void +gnt_closure_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gpointer data2); + register GMarshalFunc_VOID__INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + 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_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + data2); } -void gnt_closure_marshal_VOID__INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* VOID:POINTER,POINTER (/dev/stdin:5) */ +void +gnt_closure_marshal_VOID__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef void (*func) (gpointer data1, int, int, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - - g_return_if_fail(n_param_values == 3); + typedef void (*GMarshalFunc_VOID__POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_VOID__POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; - 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; - } + g_return_if_fail (n_param_values == 3); - callback = (func) (marshal_data ? marshal_data : cc->callback); - callback(data1, - g_value_get_int(param_values + 1) , - g_value_get_int(param_values + 2) , - data2); + 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_VOID__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); } -void gnt_closure_marshal_VOID__POINTER_POINTER(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* BOOLEAN:INT,INT (/dev/stdin:6) */ +void +gnt_closure_marshal_BOOLEAN__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef void (*func) (gpointer data1, gpointer, gpointer, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - - g_return_if_fail(n_param_values == 3); + typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - 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; - } + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); - callback = (func) (marshal_data ? marshal_data : cc->callback); - callback(data1, - g_value_get_pointer(param_values + 1) , - g_value_get_pointer(param_values + 2) , - data2); + 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__INT_INT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); } -void gnt_closure_marshal_BOOLEAN__INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* BOOLEAN:INT,INT,INT (/dev/stdin:7) */ +void +gnt_closure_marshal_BOOLEAN__INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef gboolean (*func) (gpointer data1, int, int, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean ret; - - g_return_if_fail(ret_value != NULL); - g_return_if_fail(n_param_values == 3); + typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gint arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__INT_INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - 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; - } + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); - callback = (func) (marshal_data ? marshal_data : cc->callback); - ret = callback(data1, - g_value_get_int(param_values + 1) , - g_value_get_int(param_values + 2) , - data2); - g_value_set_boolean(ret_value, ret); + 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__INT_INT_INT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); } - -void gnt_closure_marshal_BOOLEAN__INT_INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +/* BOOLEAN:POINTER,POINTER,POINTER (/dev/stdin:8) */ +void +gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) { - typedef gboolean (*func) (gpointer data1, int, int, int, gpointer data2); - register func callback; - register GCClosure *cc = (GCClosure*)closure; - register gpointer data1, data2; - gboolean ret; - - g_return_if_fail(ret_value != NULL); - g_return_if_fail(n_param_values == 4); + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; - 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; - } + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); - callback = (func) (marshal_data ? marshal_data : cc->callback); - ret = callback(data1, - g_value_get_int(param_values + 1) , - g_value_get_int(param_values + 2) , - g_value_get_int(param_values + 3) , - data2); - g_value_set_boolean(ret_value, ret); + 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__POINTER_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); } +/* BOOLEAN:INT,INT,INT,POINTER (/dev/stdin:9) */ +void +gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_INT_POINTER) (gpointer data1, + gint arg_1, + gint arg_2, + gint arg_3, + gpointer arg_4, + gpointer data2); + register GMarshalFunc_BOOLEAN__INT_INT_INT_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 5); + + 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__INT_INT_INT_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_pointer (param_values + 4), + data2); + + g_value_set_boolean (return_value, v_return); +} + +gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_handled; + + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; + + return continue_emission; +} +
--- a/console/libgnt/gntmarshal.h Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntmarshal.h Sun Nov 05 17:28:33 2006 +0000 @@ -1,51 +1,91 @@ -#include "gntwidget.h" + +#ifndef __gnt_closure_marshal_MARSHAL_H__ +#define __gnt_closure_marshal_MARSHAL_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS -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); +/* BOOLEAN:VOID (/dev/stdin:1) */ +extern 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); -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) */ +extern 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); -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) */ +extern void gnt_closure_marshal_VOID__INT_INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:INT,INT (/dev/stdin:4) */ +extern void gnt_closure_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); -void gnt_closure_marshal_VOID__INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* VOID:POINTER,POINTER (/dev/stdin:5) */ +extern void gnt_closure_marshal_VOID__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); -void gnt_closure_marshal_VOID__POINTER_POINTER(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* BOOLEAN:INT,INT (/dev/stdin:6) */ +extern void gnt_closure_marshal_BOOLEAN__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:INT,INT,INT (/dev/stdin:7) */ +extern void gnt_closure_marshal_BOOLEAN__INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); -void gnt_closure_marshal_BOOLEAN__INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* BOOLEAN:POINTER,POINTER,POINTER (/dev/stdin:8) */ +extern void gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); -void gnt_closure_marshal_BOOLEAN__INT_INT_INT(GClosure *closure, - GValue *ret_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* BOOLEAN:INT,INT,INT,POINTER (/dev/stdin:9) */ +extern void gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +G_END_DECLS +#endif /* __gnt_closure_marshal_MARSHAL_H__ */ + +gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy); + + +
--- a/console/libgnt/gntmenu.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntmenu.c Sun Nov 05 17:28:33 2006 +0000 @@ -175,7 +175,7 @@ gnt_menu_destroy(GntWidget *widget) { GntMenu *menu = GNT_MENU(widget); - g_list_foreach(menu->list, (GFunc)g_object_run_dispose, NULL); + g_list_foreach(menu->list, (GFunc)g_object_unref, NULL); g_list_free(menu->list); org_destroy(widget); } @@ -252,7 +252,7 @@ { GntWidget *widget = GNT_WIDGET(instance); GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | - GNT_WIDGET_CAN_TAKE_FOCUS); + GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_TRANSIENT); GNTDEBUG; }
--- a/console/libgnt/gntmenuitem.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntmenuitem.c Sun Nov 05 17:28:33 2006 +0000 @@ -11,14 +11,16 @@ item->text = NULL; if (item->submenu) gnt_widget_destroy(GNT_WIDGET(item->submenu)); + parent_class->dispose(obj); } static void gnt_menuitem_class_init(GntMenuItemClass *klass) { - parent_class = G_OBJECT_CLASS(klass); + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + parent_class = g_type_class_peek_parent(klass); - parent_class->dispose = gnt_menuitem_destroy; + obj_class->dispose = gnt_menuitem_destroy; } static void @@ -75,7 +77,7 @@ void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu) { if (item->submenu) - gnt_widget_destroy(item->submenu); + gnt_widget_destroy(GNT_WIDGET(item->submenu)); item->submenu = menu; }
--- a/console/libgnt/gntstyle.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntstyle.c Sun Nov 05 17:28:33 2006 +0000 @@ -161,7 +161,7 @@ return ret; } -void gnt_style_read_actions(GType type, GntWidgetClass *klass) +void gnt_style_read_actions(GType type, GntBindableClass *klass) { #if GLIB_CHECK_VERSION(2,6,0) char *name; @@ -202,7 +202,7 @@ if (keycode == NULL) { g_printerr("GntStyle: Invalid key-binding %s\n", key); } else { - gnt_widget_register_binding(klass, action, keycode, NULL); + gnt_bindable_register_binding(klass, action, keycode, NULL); g_free(keycode); } }
--- a/console/libgnt/gntstyle.h Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntstyle.h Sun Nov 05 17:28:33 2006 +0000 @@ -18,7 +18,7 @@ /* This should be called only once for the each type */ void gnt_styles_get_keyremaps(GType type, GHashTable *hash); -void gnt_style_read_actions(GType type, GntWidgetClass *klass); +void gnt_style_read_actions(GType type, GntBindableClass *klass); void gnt_init_styles();
--- a/console/libgnt/gnttree.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gnttree.c Sun Nov 05 17:28:33 2006 +0000 @@ -483,10 +483,10 @@ } static gboolean -action_down(GntWidget *widget, GList *null) +action_down(GntBindable *bind, GList *null) { int dist; - GntTree *tree = GNT_TREE(widget); + GntTree *tree = GNT_TREE(bind); GntTreeRow *old = tree->current; GntTreeRow *row = get_next(tree->current); if (row == NULL) @@ -502,10 +502,10 @@ } static gboolean -action_up(GntWidget *widget, GList *list) +action_up(GntBindable *bind, GList *list) { int dist; - GntTree *tree = GNT_TREE(widget); + GntTree *tree = GNT_TREE(bind); GntTreeRow *old = tree->current; GntTreeRow *row = get_prev(tree->current); if (!row) @@ -522,9 +522,9 @@ } static gboolean -action_page_down(GntWidget *widget, GList *null) +action_page_down(GntBindable *bind, GList *null) { - GntTree *tree = GNT_TREE(widget); + GntTree *tree = GNT_TREE(bind); GntTreeRow *old = tree->current; GntTreeRow *row = get_next(tree->bottom); if (row) @@ -546,9 +546,10 @@ } static gboolean -action_page_up(GntWidget *widget, GList *null) +action_page_up(GntBindable *bind, GList *null) { - GntTree *tree = GNT_TREE(widget); + GntWidget *widget = GNT_WIDGET(bind); + GntTree *tree = GNT_TREE(bind); GntTreeRow *row; GntTreeRow *old = tree->current; @@ -631,9 +632,9 @@ GntTree *tree = GNT_TREE(widget); GntTreeRow *old = tree->current; if (event == GNT_MOUSE_SCROLL_UP) { - action_up(widget, NULL); + action_up(GNT_BINDABLE(widget), NULL); } else if (event == GNT_MOUSE_SCROLL_DOWN) { - action_down(widget, NULL); + action_down(GNT_BINDABLE(widget), NULL); } else if (event == GNT_LEFT_MOUSE_DOWN) { GntTreeRow *row; GntTree *tree = GNT_TREE(widget); @@ -670,6 +671,7 @@ static void gnt_tree_class_init(GntTreeClass *klass) { + GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); parent_class = GNT_WIDGET_CLASS(klass); parent_class->destroy = gnt_tree_destroy; parent_class->draw = gnt_tree_draw; @@ -703,24 +705,18 @@ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - 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, "move-up", action_up, + gnt_bindable_class_register_action(bindable, "move-up", action_up, GNT_KEY_UP, NULL); - gnt_widget_register_binding(parent_class, "move-up", GNT_KEY_CTRL_P, NULL); - gnt_widget_class_register_action(parent_class, "move-down", action_down, + gnt_bindable_register_binding(bindable, "move-up", GNT_KEY_CTRL_P, NULL); + gnt_bindable_class_register_action(bindable, "move-down", action_down, GNT_KEY_DOWN, NULL); - gnt_widget_register_binding(parent_class, "move-down", GNT_KEY_CTRL_N, NULL); - gnt_widget_class_register_action(parent_class, "page-up", action_page_up, + gnt_bindable_register_binding(bindable, "move-down", GNT_KEY_CTRL_N, NULL); + gnt_bindable_class_register_action(bindable, "page-up", action_page_up, GNT_KEY_PGUP, NULL); - gnt_widget_class_register_action(parent_class, "page-down", action_page_down, + gnt_bindable_class_register_action(bindable, "page-down", action_page_down, GNT_KEY_PGDOWN, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), parent_class); - + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable); GNTDEBUG; }
--- a/console/libgnt/gntwidget.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntwidget.c Sun Nov 05 17:28:33 2006 +0000 @@ -84,29 +84,13 @@ } static gboolean -context_menu(GntWidget *widget, GList *null) +context_menu(GntBindable *bind, GList *null) { gboolean ret = FALSE; - g_signal_emit(widget, signals[SIG_CONTEXT_MENU], 0, &ret); + g_signal_emit(bind, signals[SIG_CONTEXT_MENU], 0, &ret); return ret; } -static gboolean -gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer dummy) -{ - gboolean continue_emission; - gboolean signal_handled; - - signal_handled = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accu, signal_handled); - continue_emission = !signal_handled; - - return continue_emission; -} - static void gnt_widget_class_init(GntWidgetClass *klass) { @@ -252,17 +236,11 @@ gnt_closure_marshal_BOOLEAN__VOID, G_TYPE_BOOLEAN, 0); - klass->actions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)gnt_widget_action_free); - klass->bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)gnt_widget_action_param_free); - /* This is relevant for all widgets */ - gnt_widget_class_register_action(klass, "context-menu", context_menu, + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "context-menu", context_menu, GNT_KEY_POPUP, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), klass); - + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); GNTDEBUG; } @@ -287,7 +265,7 @@ gnt_widget_init, /* instance_init */ }; - type = g_type_register_static(G_TYPE_OBJECT, + type = g_type_register_static(GNT_TYPE_BINDABLE, "GntWidget", &info, G_TYPE_FLAG_ABSTRACT); } @@ -295,30 +273,6 @@ return type; } -static const char * -gnt_widget_remap_keys(GntWidget *widget, const char *text) -{ - const char *remap = NULL; - GType type = G_OBJECT_TYPE(widget); - GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget)); - - 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); -} - -static void -gnt_widget_take_focus(GntWidget *widget) -{ - gnt_screen_take_focus(widget); -} - void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) { if (can) @@ -350,10 +304,9 @@ gnt_widget_show(GntWidget *widget) { /* Draw the widget and take focus */ - if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) - { - gnt_widget_take_focus(widget); - } + /*if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS) {*/ + /*gnt_widget_take_focus(widget);*/ + /*}*/ gnt_widget_draw(widget); } @@ -365,10 +318,8 @@ return; GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING); - if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) - { + if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) { gnt_widget_map(widget); - gnt_screen_occupy(widget); } if (widget->window == NULL) @@ -405,6 +356,7 @@ widget->priv.y, widget->priv.x); } init_widget(widget); + gnt_screen_occupy(widget); } g_signal_emit(widget, signals[SIG_DRAW], 0); @@ -413,55 +365,16 @@ } gboolean -gnt_widget_perform_action_named(GntWidget *widget, const char *name, ...) -{ - GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget)); - GList *list = NULL; - va_list args; - GntWidgetAction *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(widget, list); - else - return action->u.action_noparam(widget); - } - return FALSE; -} - -static gboolean -gnt_widget_perform_action(GntWidget *widget, const char *keys) -{ - GntWidgetClass *klass = GNT_WIDGET_CLASS(G_OBJECT_GET_CLASS(widget)); - GntWidgetActionParam *param = g_hash_table_lookup(klass->bindings, keys); - - if (param && param->action) { - if (param->list) - return param->action->u.action(widget, param->list); - else - return param->action->u.action_noparam(widget); - } - return FALSE; -} - -gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys) { gboolean ret; if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) return FALSE; - if (gnt_widget_perform_action(widget, keys)) + if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), keys)) return TRUE; - keys = gnt_widget_remap_keys(widget, keys); + keys = gnt_bindable_remap_keys(GNT_BINDABLE(widget), keys); g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); return ret; } @@ -707,83 +620,3 @@ gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE)); } -static void -register_binding(GntWidgetClass *klass, const char *name, const char *trigger, GList *list) -{ - GntWidgetActionParam *param; - GntWidgetAction *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(GntWidgetActionParam, 1); - param->action = action; - param->list = list; - g_hash_table_replace(klass->bindings, g_strdup(trigger), param); -} - -void gnt_widget_register_binding(GntWidgetClass *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_widget_class_register_action(GntWidgetClass *klass, const char *name, - GntWidgetActionCallback callback, - const char *trigger, ...) -{ - void *data; - va_list args; - GntWidgetAction *action = g_new0(GntWidgetAction, 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_widget_action_free(GntWidgetAction *action) -{ - g_free(action->name); - g_free(action); -} - -void gnt_widget_action_param_free(GntWidgetActionParam *param) -{ - g_list_free(param->list); /* XXX: There may be a leak here for string parameters */ - g_free(param); -} -
--- a/console/libgnt/gntwidget.h Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntwidget.h Sun Nov 05 17:28:33 2006 +0000 @@ -3,14 +3,15 @@ #include <stdio.h> #include <glib.h> -#include <glib-object.h> #include <ncurses.h> +#include "gntbindable.h" + #define GNT_TYPE_WIDGET (gnt_widget_get_gtype()) #define GNT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WIDGET, GntWidget)) #define GNT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WIDGET, GntWidgetClass)) #define GNT_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WIDGET)) -#define GNT_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WIDGET)) +#define GNT_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WIDGET)) #define GNT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WIDGET, GntWidgetClass)) #define GNT_WIDGET_FLAGS(obj) (GNT_WIDGET(obj)->priv.flags) @@ -18,8 +19,6 @@ #define GNT_WIDGET_UNSET_FLAGS(obj, flags) (GNT_WIDGET_FLAGS(obj) &= ~(flags)) #define GNT_WIDGET_IS_FLAG_SET(obj, flags) (GNT_WIDGET_FLAGS(obj) & (flags)) -#define GNTDEBUG fprintf(stderr, "%s\n", __FUNCTION__) - typedef struct _GnWidget GntWidget; typedef struct _GnWidgetPriv GntWidgetPriv; typedef struct _GnWidgetClass GntWidgetClass; @@ -42,6 +41,7 @@ GNT_WIDGET_TRANSIENT = 1 << 11, } GntWidgetFlags; +/* XXX: This will probably move elsewhere */ typedef enum _GnMouseEvent { GNT_LEFT_MOUSE_DOWN = 1, @@ -70,7 +70,7 @@ struct _GnWidget { - GObject inherit; + GntBindable inherit; GntWidget *parent; @@ -85,11 +85,7 @@ struct _GnWidgetClass { - GObjectClass parent; - - GHashTable *remaps; /* Key remaps */ - GHashTable *actions; /* name -> Action */ - GHashTable *bindings; /* key -> ActionParam */ + GntBindableClass parent; void (*map)(GntWidget *obj); void (*show)(GntWidget *obj); /* This will call draw() and take focus (if it can take focus) */ @@ -151,44 +147,6 @@ gboolean gnt_widget_has_shadow(GntWidget *widget); -/******************/ -/* Widget Actions */ -/******************/ -typedef gboolean (*GntWidgetActionCallback) (GntWidget *widget, GList *params); -typedef gboolean (*GntWidgetActionCallbackNoParam)(GntWidget *widget); - -typedef struct _GnWidgetAction GntWidgetAction; -typedef struct _GnWidgetActionParam GntWidgetActionParam; - -struct _GnWidgetAction -{ - char *name; /* The name of the action */ - union { - gboolean (*action)(GntWidget *widget, GList *params); - gboolean (*action_noparam)(GntWidget *widget); - } u; -}; - -struct _GnWidgetActionParam -{ - GntWidgetAction *action; - GList *list; -}; - - -GntWidgetAction *gnt_widget_action_parse(const char *name); - -void gnt_widget_action_free(GntWidgetAction *action); -void gnt_widget_action_param_free(GntWidgetActionParam *param); - -void gnt_widget_register_binding(GntWidgetClass *klass, const char *name, - const char *trigger, ...); - -void gnt_widget_class_register_action(GntWidgetClass *klass, const char *name, - GntWidgetActionCallback callback, const char *trigger, ...); - -gboolean gnt_widget_perform_action_named(GntWidget *widget, const char *name, ...); - G_END_DECLS #endif /* GNT_WIDGET_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntwm.c Sun Nov 05 17:28:33 2006 +0000 @@ -0,0 +1,1170 @@ +#define _GNU_SOURCE +#if defined(__APPLE__) +#define _XOPEN_SOURCE_EXTENDED +#endif + +#include "gntwm.h" +#include "gntstyle.h" +#include "gntmarshal.h" +#include "gnt.h" +#include "gntbox.h" +#include "gntmenu.h" +#include "gnttextview.h" +#include "gnttree.h" +#include "gntutils.h" + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +enum +{ + SIG_NEW_WIN, + SIG_DECORATE_WIN, + SIG_CLOSE_WIN, + SIG_CONFIRM_RESIZE, + SIG_RESIZED, + SIG_CONFIRM_MOVE, + SIG_MOVED, + SIG_UPDATE_WIN, + SIG_GIVE_FOCUS, + SIG_KEY_PRESS, + SIG_MOUSE_CLICK, + SIGS +}; + +static guint signals[SIGS] = { 0 }; +static void gnt_wm_new_window_real(GntWM *wm, GntWidget *widget); +static void gnt_wm_win_resized(GntWM *wm, GntNode *node); +static void gnt_wm_win_moved(GntWM *wm, GntNode *node); +static void gnt_wm_give_focus(GntWM *wm, GntWidget *widget); +static void update_window_in_list(GntWM *wm, GntWidget *wid); + +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 void +free_node(gpointer data) +{ + GntNode *node = data; + hide_panel(node->panel); + del_panel(node->panel); + g_free(node); +} + +static void +draw_taskbar(GntWM *wm, 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) { + int Y_MAX = getmaxy(stdscr) - 1; + mvwin(taskbar, Y_MAX, 0); + } + + wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + werase(taskbar); + + n = g_list_length(wm->list); + if (n) + width = getmaxx(stdscr) / n; + + for (i = 0, iter = wm->list; iter; iter = iter->next, i++) + { + GntWidget *w = iter->data; + int color; + const char *title; + + if (w == wm->ordered->data) { + /* This is the current window in focus */ + color = GNT_COLOR_TITLE; + } 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(wm, w); + } + + wrefresh(taskbar); +} +static gboolean +update_screen(GntWM *wm) +{ + if (wm->menu) { + GntMenu *top = wm->menu; + while (top) { + GntNode *node = g_hash_table_lookup(wm->nodes, top); + if (node) + top_panel(node->panel); + top = top->submenu; + } + } + update_panels(); + doupdate(); + return TRUE; +} +static void +refresh_node(GntWidget *widget, GntNode *node, gpointer null) +{ + int x, y, w, h; + int nw, nh, nx, ny; + + int X_MAX = getmaxx(stdscr); + int Y_MAX = getmaxy(stdscr) - 1; + + gnt_widget_get_position(widget, &x, &y); + gnt_widget_get_size(widget, &w, &h); + nx = x; ny = y; + + if (x + w >= X_MAX) + nx = MAX(0, X_MAX - w); + if (y + h >= Y_MAX) + ny = MAX(0, Y_MAX - h); + if (x != nx || y != ny) + gnt_screen_move_widget(widget, nx, ny); + + nw = MIN(w, X_MAX); + nh = MIN(h, Y_MAX); + if (nw != w || nh != h) + gnt_screen_resize_widget(widget, nw, nh); +} +static void +gnt_wm_init(GTypeInstance *instance, gpointer class) +{ + GntWM *wm = GNT_WM(instance); + wm->list = NULL; + wm->ordered = NULL; + wm->event_stack = FALSE; + wm->windows = NULL; + wm->actions = NULL; + wm->nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); +} + +static void +switch_window(GntWM *wm, int direction) +{ + GntWidget *w = NULL, *wid = NULL; + int pos; + + if (wm->_list.window || wm->menu) + return; + + if (!wm->ordered || !wm->ordered->next) + return; + + w = wm->ordered->data; + pos = g_list_index(wm->list, w); + pos += direction; + + if (pos < 0) + wid = g_list_last(wm->list)->data; + else if (pos >= g_list_length(wm->list)) + wid = wm->list->data; + else if (pos >= 0) + wid = g_list_nth_data(wm->list, pos); + + wm->ordered = g_list_bring_to_front(wm->ordered, wid); + + gnt_wm_raise_window(wm, wm->ordered->data); + + if (w != wid) { + gnt_widget_set_focus(w, FALSE); + } +} + +static gboolean +window_next(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + switch_window(wm, 1); + return TRUE; +} + +static gboolean +window_prev(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + switch_window(wm, -1); + return TRUE; +} + +static gboolean +switch_window_n(GntBindable *bind, GList *list) +{ + GntWM *wm = GNT_WM(bind); + GntWidget *w = NULL; + GList *l; + int n; + + if (!wm->ordered || !list) + return TRUE; + + n = GPOINTER_TO_INT(list->data); + + w = wm->ordered->data; + + if ((l = g_list_nth(wm->list, n)) != NULL) + { + gnt_wm_raise_window(wm, l->data); + } + + if (l && w != l->data) + { + gnt_widget_set_focus(w, FALSE); + } + return TRUE; +} +static gboolean +window_close(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + + if (wm->_list.window) + return TRUE; + + if (wm->ordered) { + gnt_widget_destroy(wm->ordered->data); + } + + return TRUE; +} + +static void +destroy__list(GntWidget *widget, GntWM *wm) +{ + wm->_list.window = NULL; + wm->_list.tree = NULL; + wm->windows = NULL; + wm->actions = NULL; + update_screen(wm); +} + +static void +setup__list(GntWM *wm) +{ + GntWidget *tree, *win; + win = wm->_list.window = gnt_box_new(FALSE, FALSE); + gnt_box_set_toplevel(GNT_BOX(win), TRUE); + gnt_box_set_pad(GNT_BOX(win), 0); + GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_TRANSIENT); + + tree = wm->_list.tree = gnt_tree_new(); + gnt_box_add_widget(GNT_BOX(win), tree); + + g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(destroy__list), wm); +} + +static void +window_list_activate(GntTree *tree, GntWM *wm) +{ + GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree)); + + if (!wm->ordered || !widget) + return; + + gnt_widget_destroy(wm->_list.window); + gnt_wm_raise_window(wm, widget); +} + +static gboolean +window_list(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *tree, *win; + GList *iter; + + if (wm->_list.window || wm->menu) + return TRUE; + + if (!wm->ordered) + return TRUE; + + setup__list(wm); + wm->windows = &wm->_list; + + win = wm->windows->window; + tree = wm->windows->tree; + + gnt_box_set_title(GNT_BOX(win), "Window List"); + + for (iter = wm->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(wm, GNT_WIDGET(box)); + } + + gnt_tree_set_selected(GNT_TREE(tree), wm->ordered->data); + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm); + + 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); + + gnt_widget_show(win); + return TRUE; +} + +static gboolean +dump_screen(GntBindable *bindable, GList *null) +{ + 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); + return TRUE; +} + +static void +shift_window(GntWM *wm, GntWidget *widget, int dir) +{ + GList *all = wm->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); + wm->list = all; + draw_taskbar(wm, FALSE); +} + +static gboolean +shift_left(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + if (wm->_list.window) + return TRUE; + + shift_window(wm, wm->ordered->data, -1); + return TRUE; +} + +static gboolean +shift_right(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + if (wm->_list.window) + return TRUE; + + shift_window(wm, wm->ordered->data, 1); + return TRUE; +} + +static void +action_list_activate(GntTree *tree, GntWM *wm) +{ + GntAction *action = gnt_tree_get_selection_data(tree); + action->callback(); + gnt_widget_destroy(wm->_list.window); +} + +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 gboolean +list_actions(GntBindable *bindable, GList *null) +{ + GntWidget *tree, *win; + GList *iter; + GntWM *wm = GNT_WM(bindable); + if (wm->_list.window || wm->menu) + return TRUE; + + if (wm->acts == NULL) + return TRUE; + + setup__list(wm); + wm->actions = &wm->_list; + + win = wm->actions->window; + tree = wm->actions->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 = wm->acts; 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), wm); + gnt_widget_set_size(tree, 0, g_list_length(wm->acts)); + gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - g_list_length(wm->acts)); + + gnt_widget_show(win); + return TRUE; +} + +#ifndef NO_WIDECHAR +static int +widestringwidth(wchar_t *wide) +{ + int len, ret; + char *string; + + 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; +} +#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 +start_move(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + if (wm->_list.window || wm->menu) + return TRUE; + if (!wm->ordered) + return TRUE; + + wm->mode = GNT_KP_MODE_MOVE; + window_reverse(GNT_WIDGET(wm->ordered->data), TRUE); + + return TRUE; +} + +static gboolean +start_resize(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + if (wm->_list.window || wm->menu) + return TRUE; + if (!wm->ordered) + return TRUE; + + wm->mode = GNT_KP_MODE_RESIZE; + window_reverse(GNT_WIDGET(wm->ordered->data), TRUE); + + return TRUE; +} + +static gboolean +wm_quit(GntBindable *bindable, GList *list) +{ + GntWM *wm = GNT_WM(bindable); + g_main_loop_quit(wm->loop); + return TRUE; +} + +static gboolean +return_true(GntWM *wm, GntWidget *w, int *a, int *b) +{ + return TRUE; +} + +static gboolean +refresh_screen(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + + endwin(); + refresh(); + + g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, NULL); + update_screen(wm); + draw_taskbar(wm, TRUE); + + return FALSE; +} + +static void +gnt_wm_class_init(GntWMClass *klass) +{ + klass->new_window = gnt_wm_new_window_real; + klass->decorate_window = NULL; + klass->close_window = NULL; + klass->window_resize_confirm = return_true; + klass->window_resized = gnt_wm_win_resized; + klass->window_move_confirm = return_true; + klass->window_moved = gnt_wm_win_moved; + klass->window_update = NULL; + klass->key_pressed = NULL; + klass->mouse_clicked = NULL; + klass->give_focus = gnt_wm_give_focus; + + signals[SIG_NEW_WIN] = + g_signal_new("new_win", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, new_window), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[SIG_DECORATE_WIN] = + g_signal_new("decorate_win", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, decorate_window), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[SIG_CLOSE_WIN] = + g_signal_new("close_win", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, close_window), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[SIG_CONFIRM_RESIZE] = + g_signal_new("confirm_resize", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, window_resize_confirm), + gnt_boolean_handled_accumulator, NULL, + gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER, + G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER); + + signals[SIG_CONFIRM_MOVE] = + g_signal_new("confirm_move", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, window_move_confirm), + gnt_boolean_handled_accumulator, NULL, + gnt_closure_marshal_BOOLEAN__POINTER_POINTER_POINTER, + G_TYPE_BOOLEAN, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER); + + signals[SIG_RESIZED] = + g_signal_new("window_resized", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, window_resized), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[SIG_MOVED] = + g_signal_new("window_moved", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, window_moved), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[SIG_UPDATE_WIN] = + g_signal_new("window_update", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, window_update), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + signals[SIG_GIVE_FOCUS] = + g_signal_new("give_focus", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, give_focus), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + signals[SIG_MOUSE_CLICK] = + g_signal_new("mouse_clicked", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntWMClass, mouse_clicked), + gnt_boolean_handled_accumulator, NULL, + gnt_closure_marshal_BOOLEAN__INT_INT_INT_POINTER, + G_TYPE_BOOLEAN, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER); + + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-next", window_next, + "\033" "n", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-prev", window_prev, + "\033" "p", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-close", window_close, + "\033" "c", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-list", window_list, + "\033" "w", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "dump-screen", dump_screen, + "\033" "d", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-left", shift_left, + "\033" ",", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "shift-right", shift_right, + "\033" ".", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "action-list", list_actions, + "\033" "a", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-move", start_move, + "\033" "m", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "start-resize", start_resize, + "\033" "r", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "wm-quit", wm_quit, + "\033" "q", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "refresh-screen", refresh_screen, + "\033" "l", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "switch-window-n", switch_window_n, + NULL, NULL); + + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); + GNTDEBUG; +} + +/****************************************************************************** + * GntWM API + *****************************************************************************/ +GType +gnt_wm_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) { + static const GTypeInfo info = { + sizeof(GntWMClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_wm_class_init, + NULL, + NULL, /* class_data */ + sizeof(GntWM), + 0, /* n_preallocs */ + gnt_wm_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_BINDABLE, + "GntWM", + &info, 0); + } + + return type; +} +static void +update_window_in_list(GntWM *wm, GntWidget *wid) +{ + GntTextFormatFlags flag = 0; + + if (wm->windows == NULL) + return; + + if (wid == wm->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(wm->windows->tree), wid, flag); +} + +static void +gnt_wm_new_window_real(GntWM *wm, GntWidget *widget) +{ + GntNode *node; + gboolean transient = FALSE; + + if (widget->window == NULL) + return; + + node = g_new0(GntNode, 1); + node->me = widget; + + g_hash_table_replace(wm->nodes, widget, node); + + refresh_node(widget, node, NULL); + + transient = !!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT); + + node->panel = new_panel(node->me->window); + set_panel_userptr(node->panel, node); + + if (!transient) { + if (node->me != wm->_list.window) { + GntWidget *w = NULL; + + if (wm->ordered) + w = wm->ordered->data; + + wm->list = g_list_append(wm->list, widget); + + if (wm->event_stack) + wm->ordered = g_list_prepend(wm->ordered, widget); + else + wm->ordered = g_list_append(wm->ordered, widget); + + gnt_widget_set_focus(widget, TRUE); + if (w) + gnt_widget_set_focus(w, FALSE); + } + + if (wm->event_stack || node->me == wm->_list.window) { + gnt_wm_raise_window(wm, node->me); + } else { + bottom_panel(node->panel); /* New windows should not grab focus */ + gnt_widget_set_urgent(node->me); + } + } +} + +void gnt_wm_new_window(GntWM *wm, GntWidget *widget) +{ + while (widget->parent) + widget = widget->parent; + + if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_INVISIBLE) || + g_hash_table_lookup(wm->nodes, widget)) { + update_screen(wm); + return; + } + + g_signal_emit(wm, signals[SIG_NEW_WIN], 0, widget); + g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget); + + if (wm->windows && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { + if ((GNT_IS_BOX(widget) && GNT_BOX(widget)->title) && wm->_list.window != widget + && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) { + gnt_tree_add_row_last(GNT_TREE(wm->windows->tree), widget, + gnt_tree_create_row(GNT_TREE(wm->windows->tree), GNT_BOX(widget)->title), + NULL); + update_window_in_list(wm, widget); + } + } + + update_screen(wm); + draw_taskbar(wm, FALSE); +} + +void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget) +{ + g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget); +} + +void gnt_wm_window_close(GntWM *wm, GntWidget *widget) +{ + GntNode *node; + int pos; + + if ((node = g_hash_table_lookup(wm->nodes, widget)) == NULL) + return; + + g_signal_emit(wm, signals[SIG_CLOSE_WIN], 0, widget); + g_hash_table_remove(wm->nodes, widget); + + if (wm->windows) { + gnt_tree_remove(GNT_TREE(wm->windows->tree), widget); + } + + pos = g_list_index(wm->list, widget); + + if (pos != -1) { + wm->list = g_list_remove(wm->list, widget); + wm->ordered = g_list_remove(wm->ordered, widget); + + if (wm->ordered) + gnt_wm_raise_window(wm, wm->ordered->data); + } + + update_screen(wm); + draw_taskbar(wm, FALSE); +} + +void gnt_wm_process_input(GntWM *wm, const char *keys) +{ + keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys); + + if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) + return; + + /* Do some manual checking */ + if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) { + int xmin = 0, ymin = 0, xmax = getmaxx(stdscr), ymax = getmaxy(stdscr) - 1; + int x, y, w, h; + GntWidget *widget = GNT_WIDGET(wm->ordered->data); + int ox, oy, ow, oh; + + gnt_widget_get_position(widget, &x, &y); + gnt_widget_get_size(widget, &w, &h); + ox = x; oy = y; + ow = w; oh = h; + + if (wm->mode == GNT_KP_MODE_MOVE) { + if (strcmp(keys, GNT_KEY_LEFT) == 0) { + if (x > xmin) + x--; + } else if (strcmp(keys, GNT_KEY_RIGHT) == 0) { + if (x + w < xmax) + x++; + } else if (strcmp(keys, GNT_KEY_UP) == 0) { + if (y > ymin) + y--; + } else if (strcmp(keys, GNT_KEY_DOWN) == 0) { + if (y + h < ymax) + y++; + } + if (ox != x || oy != y) { + gnt_screen_move_widget(widget, x, y); + window_reverse(widget, TRUE); + return; + } + } else if (wm->mode == GNT_KP_MODE_RESIZE) { + if (strcmp(keys, GNT_KEY_LEFT) == 0) { + w--; + } else if (strcmp(keys, GNT_KEY_RIGHT) == 0) { + if (x + w < xmax) + w++; + } else if (strcmp(keys, GNT_KEY_UP) == 0) { + h--; + } else if (strcmp(keys, GNT_KEY_DOWN) == 0) { + if (y + h < ymax) + h++; + } + if (oh != h || ow != w) { + gnt_screen_resize_widget(widget, w, h); + window_reverse(widget, TRUE); + return; + } + } + if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) { + window_reverse(widget, FALSE); + wm->mode = GNT_KP_MODE_NORMAL; + return; + } + } + + wm->event_stack = TRUE; + + /* Escape to close the window-list or action-list window */ + if (strcmp(keys, "\033") == 0) { + if (wm->_list.window) { + gnt_widget_destroy(wm->_list.window); + wm->event_stack = FALSE; + return; + } + } else if (keys[0] == '\033' && isdigit(keys[1]) && keys[2] == '\0') { + /* Alt+x for quick switch */ + int n = *(keys + 1) - '0'; + GList *list = NULL; + + if (n == 0) + n = 10; + + list = g_list_append(list, GINT_TO_POINTER(n - 1)); + switch_window_n(GNT_BINDABLE(wm), list); + g_list_free(list); + return; + } + + if (wm->menu) + gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); + else if (wm->_list.window) + gnt_widget_key_pressed(wm->_list.window, keys); + else if (wm->ordered) + gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys); + wm->event_stack = FALSE; +} + +static void +gnt_wm_win_resized(GntWM *wm, GntNode *node) +{ + refresh_node(node->me, node, NULL); + replace_panel(node->panel, node->me->window); +} + +static void +gnt_wm_win_moved(GntWM *wm, GntNode *node) +{ + refresh_node(node->me, node, NULL); +} + +void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height) +{ + gboolean ret = TRUE; + GntNode *node; + + while (widget->parent) + widget = widget->parent; + node = g_hash_table_lookup(wm->nodes, widget); + if (!node) + return; + + g_signal_emit(wm, signals[SIG_CONFIRM_RESIZE], 0, widget, &width, &height, &ret); + if (!ret) + return; /* resize is not permitted */ + hide_panel(node->panel); + gnt_widget_set_size(widget, width, height); + gnt_widget_draw(widget); + + g_signal_emit(wm, signals[SIG_RESIZED], 0, node); + + show_panel(node->panel); + update_screen(wm); +} + +void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y) +{ + gboolean ret = TRUE; + GntNode *node; + + while (widget->parent) + widget = widget->parent; + node = g_hash_table_lookup(wm->nodes, widget); + if (!node) + return; + + g_signal_emit(wm, signals[SIG_CONFIRM_MOVE], 0, widget, &x, &y, &ret); + if (!ret) + return; /* resize is not permitted */ + + gnt_widget_set_position(widget, x, y); + move_panel(node->panel, y, x); + + g_signal_emit(wm, signals[SIG_MOVED], 0, node); + + update_screen(wm); +} + +static void +gnt_wm_give_focus(GntWM *wm, GntWidget *widget) +{ + GntNode *node = g_hash_table_lookup(wm->nodes, widget); + + if (!node) + return; + + if (widget != wm->_list.window && !GNT_IS_MENU(widget) && + wm->ordered->data != widget) { + GntWidget *w = wm->ordered->data; + wm->ordered = g_list_bring_to_front(wm->ordered, widget); + gnt_widget_set_focus(w, FALSE); + } + + gnt_widget_set_focus(widget, TRUE); + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_URGENT); + gnt_widget_draw(widget); + top_panel(node->panel); + + if (wm->_list.window) { + GntNode *nd = g_hash_table_lookup(wm->nodes, wm->_list.window); + top_panel(nd->panel); + } + update_screen(wm); + draw_taskbar(wm, FALSE); +} + +void gnt_wm_update_window(GntWM *wm, 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(wm->nodes, widget); + if (node == NULL) { + gnt_wm_new_window(wm, widget); + } else + g_signal_emit(wm, signals[SIG_UPDATE_WIN], 0, node); + + update_screen(wm); + draw_taskbar(wm, FALSE); +} + +gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget) +{ + gboolean ret = TRUE; + g_signal_emit(wm, signals[SIG_MOUSE_CLICK], 0, event, x, y, widget, &ret); + return ret; +} + +void gnt_wm_raise_window(GntWM *wm, GntWidget *widget) +{ + g_signal_emit(wm, signals[SIG_GIVE_FOCUS], 0, widget); +} +
--- a/console/libgnt/gntwm.h Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/gntwm.h Sun Nov 05 17:28:33 2006 +0000 @@ -1,55 +1,155 @@ #include <panel.h> #include "gntwidget.h" +#include "gntmenu.h" -/* XXX: It might be a good idea to move GntNode from gntmain.c to here. */ +#define GNT_TYPE_WM (gnt_wm_get_gtype()) +#define GNT_WM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WM, GntWM)) +#define GNT_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WM, GntWMClass)) +#define GNT_IS_WM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WM)) +#define GNT_IS_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WM)) +#define GNT_WM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WM, GntWMClass)) + +typedef enum +{ + GNT_KP_MODE_NORMAL, + GNT_KP_MODE_RESIZE, + GNT_KP_MODE_MOVE, +} GntKeyPressMode; + +typedef struct +{ + GntWidget *me; + + PANEL *panel; +} GntNode; typedef struct _GntWM GntWM; +/** + * An application can register actions which will show up in a 'start-menu' like popup + */ +typedef struct _GnAction +{ + const char *label; + void (*callback)(); +} GntAction; + struct _GntWM { - /* This should return a PANEL for the win */ - PANEL *(*new_window)(GntWidget *win); + GntBindable inherit; + + GMainLoop *loop; + + GList *list; /* List of windows ordered on their creation time */ + GList *ordered; /* List of windows ordered on their focus */ + + struct { + GntWidget *window; + GntWidget *tree; + } _list, + *windows, /* Window-list window */ + *actions; /* Action-list window */ + + GHashTable *nodes; /* GntWidget -> GntNode */ + + GList *acts; /* List of actions */ + + /** + * 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. + */ + GntMenu *menu; /* Currently active menu */ + /** + * '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. + */ + gboolean event_stack; + + GntKeyPressMode mode; + + void *res1; + void *res2; + void *res3; + void *res4; +}; + +typedef struct _GnWMClass GntWMClass; + +struct _GnWMClass +{ + GntBindableClass parent; + + /* This is called when a new window is shown */ + void (*new_window)(GntWM *wm, GntWidget *win); + + void (*decorate_window)(GntWM *wm, GntWidget *win); /* This is called when a window is being closed */ - gboolean (*close_window)(GntWidget *win); + gboolean (*close_window)(GntWM *wm, GntWidget *win); /* The WM may want to confirm a size for a window first */ - gboolean (*window_resize_confirm)(GntWidget *win, int *w, int *h); + gboolean (*window_resize_confirm)(GntWM *wm, GntWidget *win, int *w, int *h); - /* Can del_panel the old panel and return a new_panel. - * Otherwise, this should at least do a replace_panel. */ - PANEL *(*window_resized)(PANEL *pan, GntWidget *win); + void (*window_resized)(GntWM *wm, GntNode *node); /* The WM may want to confirm the position of a window */ - gboolean (*window_move_confirm)(GntWidget *win, int *x, int *y); + gboolean (*window_move_confirm)(GntWM *wm, GntWidget *win, int *x, int *y); - void (*window_moved)(PANEL *pan, GntWidget *win); + void (*window_moved)(GntWM *wm, GntNode *node); /* This gets called when: * - the title of the window changes * - the 'urgency' of the window changes */ - void (*window_update)(PANEL *pan, GntWidget *win); + void (*window_update)(GntWM *wm, GntNode *node); /* This should usually return NULL if the keys were processed by the WM. * If not, the WM can simply return the original string, which will be * processed by the default WM. The custom WM can also return a different * static string for the default WM to process. */ - const char *(*key_pressed)(const char *key); + gboolean (*key_pressed)(GntWM *wm, const char *key); - gboolean (*mouse_clicked)(GntMouseEvent event, int x, int y, GntWidget *widget); + gboolean (*mouse_clicked)(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget); /* Whatever the WM wants to do when a window is given focus */ - void (*give_focus)(GntWidget *widget); - - /* If something needs to be uninited */ - void (*gntwm_uninit)(); + void (*give_focus)(GntWM *wm, GntWidget *widget); /* List of windows. Although the WM can keep a list of its own for the windows, * it'd be better if there was a way to share between the 'core' and the WM. */ - const GList *(*window_list)(); + /*const GList *(*window_list)();*/ + + void (*res1)(void); + void (*res2)(void); + void (*res3)(void); + void (*res4)(void); }; +G_BEGIN_DECLS + +GType gnt_wm_get_gtype(void); + +void gnt_wm_new_window(GntWM *wm, GntWidget *widget); + +void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget); + +void gnt_wm_window_close(GntWM *wm, GntWidget *widget); + +void gnt_wm_process_input(GntWM *wm, const char *string); + +gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget); + +void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height); + +void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y); + +void gnt_wm_update_window(GntWM *wm, GntWidget *widget); + +void gnt_wm_raise_window(GntWM *wm, GntWidget *widget); + +G_END_DECLS
--- a/console/libgnt/test/multiwin.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/test/multiwin.c Sun Nov 05 17:28:33 2006 +0000 @@ -62,7 +62,6 @@ gnt_tree_add_row_after(GNT_TREE(tree), "6", gnt_tree_create_row(GNT_TREE(tree), "6", " long text", "a2"), "4", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), NULL, NULL, NULL, "4"); int i; for (i = 110; i < 430; i++) {
--- a/console/libgnt/test/tv.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/test/tv.c Sun Nov 05 17:28:33 2006 +0000 @@ -25,9 +25,9 @@ } else if (key[0] == 27) { - if (strcmp(key+1, GNT_KEY_UP) == 0) + if (strcmp(key, GNT_KEY_UP) == 0) gnt_text_view_scroll(GNT_TEXT_VIEW(view), -1); - else if (strcmp(key+1, GNT_KEY_DOWN) == 0) + else if (strcmp(key, GNT_KEY_DOWN) == 0) gnt_text_view_scroll(GNT_TEXT_VIEW(view), 1); else return FALSE;
--- a/console/libgnt/wms/s.c Sun Nov 05 14:57:05 2006 +0000 +++ b/console/libgnt/wms/s.c Sun Nov 05 17:28:33 2006 +0000 @@ -1,13 +1,30 @@ #include "gnt.h" #include "gntbox.h" #include "gntmenu.h" +#include "gntstyle.h" #include "gntwm.h" #include "gntblist.h" #include <string.h> -static GntWM *gwm; +#define TYPE_S (s_get_gtype()) + +typedef struct _S +{ + GntWM inherit; +} S; + +typedef struct _SClass +{ + GntWMClass inherit; +} SClass; + +GType s_get_gtype(void); +void gntwm_init(GntWM **wm); + +static void (*org_new_window)(GntWM *wm, GntWidget *win); +static gboolean (*org_mouse_clicked)(GntWM *wm, GntMouseEvent event, int cx, int cy, GntWidget *widget); static void envelope_buddylist(GntWidget *win) @@ -24,7 +41,7 @@ { int w, h; - if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER)) + if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT)) return; gnt_widget_get_size(win, &w, &h); @@ -32,8 +49,8 @@ mvwprintw(win->window, 0, w - 4, "[X]"); } -static PANEL * -s_resize_window(PANEL *panel, GntWidget *win) +static void +s_decorate_window(GntWM *wm, GntWidget *win) { const char *name; @@ -43,67 +60,69 @@ } else { envelope_normal_window(win); } - replace_panel(panel, win->window); - return panel; } -static PANEL * -s_new_window(GntWidget *win) +static void +s_window_update(GntWM *wm, GntNode *node) +{ + s_decorate_window(wm, node->me); +} + +static void +s_new_window(GntWM *wm, GntWidget *win) { int x, y, w, h; int maxx, maxy; const char *name; + gboolean blist = FALSE; - if (GNT_IS_MENU(win)) - return new_panel(win->window); - getmaxyx(stdscr, maxy, maxx); + if (!GNT_IS_MENU(win)) { + getmaxyx(stdscr, maxy, maxx); - gnt_widget_get_position(win, &x, &y); - gnt_widget_get_size(win, &w, &h); + gnt_widget_get_position(win, &x, &y); + gnt_widget_get_size(win, &w, &h); - name = gnt_widget_get_name(win); + name = gnt_widget_get_name(win); - if (name && strcmp(name, "buddylist") == 0) { - /* The buddylist doesn't have no border nor nothing! */ - x = 0; - y = 0; - h = maxy - 1; + if (name && strcmp(name, "buddylist") == 0) { + /* The buddylist doesn't have no border nor nothing! */ + x = 0; + y = 0; + h = maxy - 1; + blist = TRUE; - gnt_box_set_toplevel(GNT_BOX(win), FALSE); - GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_CAN_TAKE_FOCUS); - gnt_box_readjust(GNT_BOX(win)); - - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); + gnt_box_set_toplevel(GNT_BOX(win), FALSE); + GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_CAN_TAKE_FOCUS); - gnt_widget_set_size(win, -1, h); - gnt_widget_draw(win); - envelope_buddylist(win); - } else if (name && strcmp(name, "conversation-window") == 0) { - /* Put the conversation windows to the far-right */ - x = maxx - w; - y = 0; - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); - gnt_widget_draw(win); - envelope_normal_window(win); - } else if (!GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) { - /* In the middle of the screen */ - x = (maxx - w) / 2; - y = (maxy - h) / 2; + gnt_widget_set_position(win, x, y); + mvwin(win->window, y, x); - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); - envelope_normal_window(win); + gnt_widget_set_size(win, -1, h + 2); /* XXX: Why is the +2 needed here? -- sadrul */ + } else if (name && strcmp(name, "conversation-window") == 0) { + /* Put the conversation windows to the far-right */ + x = maxx - w; + y = 0; + gnt_widget_set_position(win, x, y); + mvwin(win->window, y, x); + } else if (!GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) { + /* In the middle of the screen */ + x = (maxx - w) / 2; + y = (maxy - h) / 2; + + gnt_widget_set_position(win, x, y); + mvwin(win->window, y, x); + } } + org_new_window(wm, win); - return new_panel(win->window); + if (blist) + gnt_wm_raise_window(wm, win); } static GntWidget * -find_widget(const char *wname) +find_widget(GntWM *wm, const char *wname) { - const GList *iter = gwm->window_list(); + const GList *iter = wm->list; for (; iter; iter = iter->next) { GntWidget *widget = iter->data; const char *name = gnt_widget_get_name(widget); @@ -115,41 +134,17 @@ } static gboolean -give_the_darned_focus(gpointer w) -{ - gwm->give_focus(w); - return FALSE; -} - -static const char* -s_key_pressed(const char *key) -{ - /* Alt+b to toggle the buddylist */ - if (key[0] == 27 && key[1] == 'b' && key[2] == '\0') { - GntWidget *w = find_widget("buddylist"); - if (w == NULL) { - gg_blist_show(); - w = find_widget("buddylist"); - g_timeout_add(0, give_the_darned_focus, w); - } else { - gnt_widget_destroy(w); - } - return NULL; - } - return key; -} - -static gboolean -s_mouse_clicked(GntMouseEvent event, int cx, int cy, GntWidget *widget) +s_mouse_clicked(GntWM *wm, GntMouseEvent event, int cx, int cy, GntWidget *widget) { int x, y, w, h; if (!widget) - return FALSE; /* This might a place to bring up a context menu */ + return org_mouse_clicked(wm, event, cx, cy, widget); + /* This might be a place to bring up a context menu */ if (event != GNT_LEFT_MOUSE_DOWN || GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - return FALSE; /* For now, just the left-button to close a window */ + return org_mouse_clicked(wm, event, cx, cy, widget); gnt_widget_get_position(widget, &x, &y); gnt_widget_get_size(widget, &w, &h); @@ -158,25 +153,69 @@ gnt_widget_destroy(widget); return TRUE; } - return FALSE; + + return org_mouse_clicked(wm, event, cx, cy, widget); +} + +static gboolean +toggle_buddylist(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *blist = find_widget(wm, "buddylist"); + if (blist) + gnt_widget_destroy(blist); + else + gg_blist_show(); + return TRUE; } static void -s_window_update(PANEL *panel, GntWidget *window) +s_class_init(SClass *klass) { - const char *name = gnt_widget_get_name(window); - if (name && strcmp(name, "buddylist")) - envelope_normal_window(window); + GntWMClass *pclass = GNT_WM_CLASS(klass); + + org_new_window = pclass->new_window; + org_mouse_clicked = pclass->mouse_clicked; + + pclass->new_window = s_new_window; + pclass->decorate_window = s_decorate_window; + pclass->window_update = s_window_update; + pclass->mouse_clicked = s_mouse_clicked; + + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-buddylist", + toggle_buddylist, "\033" "b", NULL); + gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); + GNTDEBUG; +} + +void gntwm_init(GntWM **wm) +{ + *wm = g_object_new(TYPE_S, NULL); } -void gntwm_init(GntWM *wm); -void gntwm_init(GntWM *wm) +GType s_get_gtype(void) { - gwm = wm; - wm->new_window = s_new_window; - wm->window_resized = s_resize_window; - wm->key_pressed = s_key_pressed; - wm->mouse_clicked = s_mouse_clicked; - wm->window_update = s_window_update; + static GType type = 0; + + if(type == 0) { + static const GTypeInfo info = { + sizeof(SClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)s_class_init, + NULL, + NULL, /* class_data */ + sizeof(S), + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL + }; + + type = g_type_register_static(GNT_TYPE_WM, + "GntS", + &info, 0); + } + + return type; }