Mercurial > pidgin.yaz
diff console/libgnt/gntmain.c @ 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 | 5228f8cf2a6a |
children | 1bd0456fe1c3 |
line wrap: on
line diff
--- 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; }