Sat, 27 Jul 2019 03:23:16 +0000
Merged in purple-media-require-encryption-api-addition (pull request #523)
Purple media require encryption api addition
Approved-by: Elliott Sales de Andrade
Approved-by: Gary Kramlich
| libpurple/media.c | file | annotate | diff | comparison | revisions |
--- a/COPYRIGHT Tue Jul 23 12:47:17 2019 +0200 +++ b/COPYRIGHT Sat Jul 27 03:23:16 2019 +0000 @@ -52,7 +52,7 @@ Carlos Bederian Dave Bell Matthew W.S. Bell -bellet +Fabrice Bellet <fabrice@bellet.info> Igor Belyi David Benjamin Brian Bernas
--- a/Doxyfile.in Tue Jul 23 12:47:17 2019 +0200 +++ b/Doxyfile.in Sat Jul 27 03:23:16 2019 +0000 @@ -591,7 +591,6 @@ INPUT = @top_srcdir@/libpurple \ @top_srcdir@/finch \ - @top_srcdir@/finch/libgnt \ @top_srcdir@/pidgin \ @top_srcdir@/doc @@ -914,7 +913,7 @@ # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. -GENERATE_HTMLHELP = YES +GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You
--- a/bitbucket-pipelines.yml Tue Jul 23 12:47:17 2019 +0200 +++ b/bitbucket-pipelines.yml Sat Jul 27 03:23:16 2019 +0000 @@ -13,5 +13,9 @@ - step: image: pidgin/builders-2:debian-buster-amd64 script: + - set -ex + - hg clone https://bitbucket.org/pidgin/libgnt -b release-2.x.y + - meson -Dprefix=/usr libgnt libgnt/build + - ninja -C libgnt/build install + - ldconfig - build.sh -
--- a/config.h.mingw Tue Jul 23 12:47:17 2019 +0200 +++ b/config.h.mingw Sat Jul 27 03:23:16 2019 +0000 @@ -465,9 +465,6 @@ /* Use GNU Libidn for stringprep and IDN */ /* #define USE_IDN 1 */ -/* Define if python headers are available. */ -/* #undef USE_PYTHON */ - /* Define if we're using XScreenSaver. */ #define USE_SCREENSAVER 1
--- a/configure.ac Tue Jul 23 12:47:17 2019 +0200 +++ b/configure.ac Sat Jul 27 03:23:16 2019 +0000 @@ -21,28 +21,6 @@ # For code under development: [devel] # For production releases: [] # -# -# If any code has changed in libgnt: -# gnt_micro_version += 1 -# -# If any functions have been added to libgnt: -# gnt_micro_version = 0 -# gnt_minor_version += 1 -# gnt_lt_current += 1 -# -# If backwards compatibility has been broken in libgnt: -# gnt_micro_version = 0 -# gnt_minor_version = 0 -# gnt_major_version += 1; -# gnt_lt_current += 1 -# -# gnt_version_suffix should be similar to one of the following: -# For beta releases: [beta2] -# For code under development: [devel] -# For production releases: [] -# -# Make sure to update finch/libgnt/configure.ac with libgnt version changes. -# m4_define([purple_lt_current], [14]) m4_define([purple_major_version], [2]) m4_define([purple_minor_version], [14]) @@ -52,15 +30,6 @@ [purple_major_version.purple_minor_version.purple_micro_version]) m4_define([purple_display_version], purple_version[]m4_ifdef([purple_version_suffix],[purple_version_suffix])) -m4_define([gnt_lt_current], [8]) -m4_define([gnt_major_version], [2]) -m4_define([gnt_minor_version], [8]) -m4_define([gnt_micro_version], [10]) -m4_define([gnt_version_suffix], [devel]) -m4_define([gnt_version], - [gnt_major_version.gnt_minor_version.gnt_micro_version]) -m4_define([gnt_display_version], gnt_version[]m4_ifdef([gnt_version_suffix],[gnt_version_suffix])) - AC_INIT([pidgin], [purple_display_version], [devel@pidgin.im]) @@ -90,18 +59,6 @@ PURPLE_LT_VERSION_INFO="purple_lt_current:purple_micro_version:purple_minor_version" AC_SUBST(PURPLE_LT_VERSION_INFO) -GNT_MAJOR_VERSION=gnt_major_version -GNT_MINOR_VERSION=gnt_minor_version -GNT_MICRO_VERSION=gnt_micro_version -GNT_VERSION=[gnt_display_version] -AC_SUBST(GNT_MAJOR_VERSION) -AC_SUBST(GNT_MINOR_VERSION) -AC_SUBST(GNT_MICRO_VERSION) -AC_SUBST(GNT_VERSION) - -GNT_LT_VERSION_INFO="gnt_lt_current:gnt_micro_version:gnt_minor_version" -AC_SUBST(GNT_LT_VERSION_INFO) - AC_PATH_PROG(sedpath, sed) dnl Storing configure arguments @@ -629,6 +586,19 @@ dnl ####################################################################### dnl # Check for ncurses and other things used by the console UI dnl ####################################################################### +if test "x$enable_consoleui" = "xyes"; then +PKG_CHECK_MODULES(LIBGNT, [gnt >= 2.14.0], , [ + if test "x$force_finch" = "xyes"; then + AC_MSG_ERROR([ + +Finch will not be built. You must have libgnt >= 2.14.0 development headers installed to build. + +]) + fi + enable_consoleui=no +]) +fi + GNT_LIBS="" GNT_CFLAGS="" AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR], @@ -713,8 +683,6 @@ AC_SUBST(GNT_CFLAGS) AM_CONDITIONAL(ENABLE_GNT, test "x$enable_consoleui" = "xyes") -#AC_CHECK_FUNC(wcwidth, [AC_DEFINE([HAVE_WCWIDTH], [1], [Define to 1 if you have wcwidth function.])]) - dnl ####################################################################### dnl # Check for LibXML2 (required) dnl ####################################################################### @@ -1492,7 +1460,7 @@ [which python interpreter to use for dbus code generation]), PYTHON=$withval) -if test "x$enable_dbus" = "xyes" || test "x$enable_consoleui" = "xyes" ; then +if test "x$enable_dbus" = "xyes" ; then if test -z "$PYTHON" -o "x$PYTHON" = "xyes"; then AC_PATH_PROG([PYTHON], [python], [no]) fi @@ -1570,24 +1538,6 @@ AM_CONDITIONAL(ENABLE_DBUS, test "x$enable_dbus" = "xyes") -dnl Check for Python headers (currently useful only for libgnt) -dnl (Thanks to XChat) -if test "x$enable_consoleui" = "xyes" -a ! -z "$PYTHON" -a x"$PYTHON" != x"no" ; then - AC_MSG_CHECKING(for Python compile flags) - if test -f ${PYTHON}-config; then - PY_CFLAGS=`${PYTHON}-config --includes` - PY_LIBS=`${PYTHON}-config --libs` - AC_DEFINE(USE_PYTHON, [1], [Define if python headers are available.]) - AC_MSG_RESULT(ok) - else - AC_MSG_RESULT([Cannot find ${PYTHON}-config]) - PY_CFLAGS="" - PY_LIBS="" - fi -fi -AC_SUBST(PY_CFLAGS) -AC_SUBST(PY_LIBS) - dnl ####################################################################### dnl # Check for Mono support dnl ####################################################################### @@ -2669,9 +2619,6 @@ share/ca-certs/Makefile finch/finch.pc finch/Makefile - finch/libgnt/Makefile - finch/libgnt/gnt.pc - finch/libgnt/wms/Makefile finch/plugins/Makefile po/Makefile.in pidgin.spec
--- a/finch/Makefile.am Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/Makefile.am Sat Jul 27 03:23:16 2019 +0000 @@ -7,7 +7,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = finch.pc -SUBDIRS = libgnt plugins +SUBDIRS = plugins if ENABLE_GNT @@ -74,18 +74,19 @@ $(GNT_LIBS) \ $(GSTREAMER_LIBS) \ $(GSTVIDEO_LIBS) \ - ./libgnt/libgnt.la \ + $(LIBGNT_LIBS) \ $(top_builddir)/libpurple/libpurple.la AM_CPPFLAGS = \ -DSTANDALONE \ + -DGNTSEAL_ENABLE \ -DDATADIR=\"$(datadir)\" \ -DLIBDIR=\"$(libdir)/finch/\" \ -DLOCALEDIR=\"$(datadir)/locale\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -I$(top_srcdir)/libpurple/ \ -I$(top_srcdir) \ - -I$(srcdir)/libgnt/ \ + $(LIBGNT_CFLAGS) \ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \
--- a/finch/gntaccount.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntaccount.c Sat Jul 27 03:23:16 2019 +0000 @@ -801,7 +801,7 @@ gnt_box_add_widget(GNT_BOX(accounts.window), gnt_line_new(FALSE)); accounts.tree = gnt_tree_new_with_columns(2); - GNT_WIDGET_SET_FLAGS(accounts.tree, GNT_WIDGET_NO_BORDER); + gnt_widget_set_has_border(accounts.tree, FALSE); for (iter = purple_accounts_get_all(); iter; iter = iter->next) { @@ -1100,23 +1100,32 @@ aa, 2, _("Authorize"), authorize_and_add_cb, _("Deny"), deny_no_add_cb); - gnt_screen_release(widget); + /* Since GntWindow is a GntBox, hide it so it's unmapped, then + * add it to the outer window, and make it visible again. */ + gnt_widget_hide(widget); gnt_box_set_toplevel(GNT_BOX(widget), FALSE); gnt_box_add_widget(GNT_BOX(uihandle), widget); + gnt_widget_set_visible(widget, TRUE); gnt_box_add_widget(GNT_BOX(uihandle), gnt_hline_new()); widget = finch_retrieve_user_info(purple_account_get_connection(account), remote_user); - for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) { + for (iter = gnt_box_get_children(GNT_BOX(widget)); iter; + iter = g_list_delete_link(iter, iter)) { if (GNT_IS_BUTTON(iter->data)) { gnt_widget_destroy(iter->data); gnt_box_remove(GNT_BOX(widget), iter->data); + g_list_free(iter); break; } } + /* Since GntWindow is a GntBox, hide it so it's unmapped, then + * add it to the outer window, and make it visible again. */ + gnt_widget_hide(widget); gnt_box_set_toplevel(GNT_BOX(widget), FALSE); - gnt_screen_release(widget); gnt_box_add_widget(GNT_BOX(uihandle), widget); + gnt_widget_set_visible(widget, TRUE); + gnt_widget_show(uihandle); g_signal_connect_swapped(G_OBJECT(uihandle), "destroy", G_CALLBACK(free_auth_and_add), aa);
--- a/finch/gntblist.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntblist.c Sat Jul 27 03:23:16 2019 +0000 @@ -1854,7 +1854,7 @@ tree = GNT_TREE(widget); if (!gnt_widget_has_focus(ggblist->tree) || - (ggblist->context && !GNT_WIDGET_IS_FLAG_SET(ggblist->context, GNT_WIDGET_INVISIBLE))) + (ggblist->context && gnt_widget_get_visible(ggblist->context))) return FALSE; if (ggblist->tooltip) @@ -1880,7 +1880,7 @@ box = gnt_box_new(FALSE, FALSE); gnt_box_set_toplevel(GNT_BOX(box), TRUE); - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW); + gnt_widget_set_has_shadow(box, FALSE); gnt_box_set_title(GNT_BOX(box), title); str = make_sure_text_fits(str); @@ -1894,8 +1894,8 @@ if (x + w >= getmaxx(stdscr)) x -= w + width + 2; gnt_widget_set_position(box, x, y); - GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_CAN_TAKE_FOCUS); - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); + gnt_widget_set_take_focus(box, FALSE); + gnt_widget_set_transient(box, TRUE); gnt_widget_draw(box); gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(tv), str->str, GNT_TEXT_FLAG_NORMAL); @@ -3131,7 +3131,7 @@ ggblist->tree = gnt_tree_new(); - GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); + gnt_widget_set_has_border(ggblist->tree, FALSE); gnt_widget_set_size(ggblist->tree, purple_prefs_get_int(PREF_ROOT "/size/width"), purple_prefs_get_int(PREF_ROOT "/size/height")); gnt_widget_set_position(ggblist->window, purple_prefs_get_int(PREF_ROOT "/position/x"),
--- a/finch/gntconv.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntconv.c Sat Jul 27 03:23:16 2019 +0000 @@ -705,7 +705,7 @@ static void completion_cb(GntEntry *entry, const char *start, const char *end) { - if (start == entry->start && *start != '/') + if (start == gnt_entry_get_text(entry) && *start != '/') gnt_widget_key_pressed(GNT_WIDGET(entry), ": "); } @@ -824,7 +824,7 @@ gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)g_utf8_collate); gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free); gnt_tree_set_search_column(GNT_TREE(tree), 1); - GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); + gnt_widget_set_has_border(tree, FALSE); gnt_box_add_widget(GNT_BOX(hbox), ggc->tv); gnt_box_add_widget(GNT_BOX(hbox), tree); gnt_box_add_widget(GNT_BOX(ggc->window), hbox); @@ -1375,10 +1375,10 @@ ch = fc->u.chat; gnt_widget_set_visible(ch->userlist, - (GNT_WIDGET_IS_FLAG_SET(ch->userlist, GNT_WIDGET_INVISIBLE))); + !gnt_widget_get_visible(ch->userlist)); gnt_box_readjust(GNT_BOX(fc->window)); gnt_box_give_focus_to_child(GNT_BOX(fc->window), fc->entry); - purple_prefs_set_bool(PREF_USERLIST, !(GNT_WIDGET_IS_FLAG_SET(ch->userlist, GNT_WIDGET_INVISIBLE))); + purple_prefs_set_bool(PREF_USERLIST, gnt_widget_get_visible(ch->userlist)); return PURPLE_CMD_RET_OK; }
--- a/finch/gntdebug.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntdebug.c Sat Jul 27 03:23:16 2019 +0000 @@ -278,18 +278,12 @@ } fprintf(fp, "Finch Debug Log : %s\n", purple_date_format_full(NULL)); - fprintf(fp, "%s", tv->string->str); + fprintf(fp, "%s", gnt_text_view_get_text(tv)); fclose(fp); gnt_widget_destroy(GNT_WIDGET(fs)); } static void -file_cancel(GntWidget *w, GntFileSel *fs) -{ - gnt_widget_destroy(GNT_WIDGET(fs)); -} - -static void save_debug_win(GntWidget *w, GntTextView *tv) { GntWidget *window = gnt_file_sel_new(); @@ -297,7 +291,7 @@ gnt_file_sel_set_current_location(sel, purple_home_dir()); gnt_file_sel_set_suggested_filename(sel, "debug.txt"); g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(file_save), tv); - g_signal_connect(G_OBJECT(sel->cancel), "activate", G_CALLBACK(file_cancel), sel); + g_signal_connect(G_OBJECT(sel), "cancelled", G_CALLBACK(gnt_widget_destroy), NULL); gnt_widget_show(window); } @@ -336,28 +330,28 @@ */ wid = gnt_button_new(_("Clear")); g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(clear_debug_win), debug.tview); - GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_widget_set_grow_y(wid, TRUE); gnt_box_add_widget(GNT_BOX(box), wid); wid = gnt_button_new(_("Save")); g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(save_debug_win), debug.tview); - GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_widget_set_grow_y(wid, TRUE); gnt_box_add_widget(GNT_BOX(box), wid); debug.search = gnt_entry_new(purple_prefs_get_string(PREF_ROOT "/filter")); label = gnt_label_new(_("Filter:")); - GNT_WIDGET_UNSET_FLAGS(label, GNT_WIDGET_GROW_X); + gnt_widget_set_grow_x(label, FALSE); gnt_box_add_widget(GNT_BOX(box), label); gnt_box_add_widget(GNT_BOX(box), debug.search); g_signal_connect(G_OBJECT(debug.search), "text_changed", G_CALLBACK(update_filter_string), NULL); wid = gnt_check_box_new(_("Pause")); g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_pause), NULL); - GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y); + gnt_widget_set_grow_y(wid, TRUE); gnt_box_add_widget(GNT_BOX(box), wid); gnt_box_add_widget(GNT_BOX(debug.window), box); - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_GROW_Y); + gnt_widget_set_grow_y(box, TRUE); gnt_widget_set_name(debug.window, "debug-window");
--- a/finch/gntmedia.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntmedia.c Sat Jul 27 03:23:16 2019 +0000 @@ -203,9 +203,7 @@ gntmedia->priv->reject = NULL; gntmedia->priv->calling = NULL; - parent = GNT_WIDGET(gntmedia); - while (parent->parent) - parent = parent->parent; + parent = gnt_widget_get_toplevel(GNT_WIDGET(gntmedia)); gnt_box_readjust(GNT_BOX(parent)); gnt_widget_draw(parent); } @@ -223,9 +221,7 @@ gnt_box_add_widget(GNT_BOX(gntmedia), gntmedia->priv->calling); gnt_box_add_widget(GNT_BOX(gntmedia), gntmedia->priv->hangup); - parent = GNT_WIDGET(gntmedia); - while (parent->parent) - parent = parent->parent; + parent = gnt_widget_get_toplevel(GNT_WIDGET(gntmedia)); gnt_box_readjust(GNT_BOX(parent)); gnt_widget_draw(parent); }
--- a/finch/gntnotify.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntnotify.c Sat Jul 27 03:23:16 2019 +0000 @@ -134,8 +134,7 @@ if (!widget) return; - while (widget->parent) - widget = widget->parent; + widget = gnt_widget_get_toplevel(widget); if (type == PURPLE_NOTIFY_SEARCHRESULTS) purple_notify_searchresults_free(g_object_get_data(handle, "notify-results")); @@ -341,10 +340,10 @@ GntTextView *msg = GNT_TEXT_VIEW(g_object_get_data(G_OBJECT(ui_handle), "info-widget")); char *strip = purple_markup_strip_html(info); int tvw, tvh, width, height, ntvw, ntvh; + GntWidget *window; - while (GNT_WIDGET(ui_handle)->parent) - ui_handle = GNT_WIDGET(ui_handle)->parent; - gnt_widget_get_size(GNT_WIDGET(ui_handle), &width, &height); + ui_handle = window = gnt_widget_get_toplevel(GNT_WIDGET(ui_handle)); + gnt_widget_get_size(window, &width, &height); gnt_widget_get_size(GNT_WIDGET(msg), &tvw, &tvh); gnt_text_view_clear(msg); @@ -355,7 +354,7 @@ ntvw += 3; ntvh++; - gnt_screen_resize_widget(GNT_WIDGET(ui_handle), width + MAX(0, ntvw - tvw), height + MAX(0, ntvh - tvh)); + gnt_screen_resize_widget(window, width + MAX(0, ntvw - tvw), height + MAX(0, ntvh - tvh)); g_free(strip); g_free(key); } else {
--- a/finch/gntplugin.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntplugin.c Sat Jul 27 03:23:16 2019 +0000 @@ -366,7 +366,7 @@ gnt_box_set_pad(GNT_BOX(box), 0); plugins.tree = tree = gnt_tree_new(); gnt_tree_set_compare_func(GNT_TREE(tree), (GCompareFunc)plugin_compare); - GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); + gnt_widget_set_has_border(tree, FALSE); gnt_box_add_widget(GNT_BOX(box), tree); gnt_box_add_widget(GNT_BOX(box), gnt_vline_new());
--- a/finch/gntrequest.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntrequest.c Sat Jul 27 03:23:16 2019 +0000 @@ -146,14 +146,13 @@ PurpleRequestInputCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); const char *text = gnt_entry_get_text(GNT_ENTRY(entry)); + GntWidget *window; if (callback) callback(data, text); - while (button->parent) - button = button->parent; - - purple_request_close(PURPLE_REQUEST_INPUT, button); + window = gnt_widget_get_toplevel(button); + purple_request_close(PURPLE_REQUEST_INPUT, window); } static void * @@ -193,8 +192,7 @@ purple_request_fields_destroy(fields); } - while (widget->parent) - widget = widget->parent; + widget = gnt_widget_get_toplevel(widget); gnt_widget_destroy(widget); } @@ -204,14 +202,13 @@ PurpleRequestChoiceCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); int choice = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))) - 1; + GntWidget *window; if (callback) callback(data, choice); - while (button->parent) - button = button->parent; - - purple_request_close(PURPLE_REQUEST_INPUT, button); + window = gnt_widget_get_toplevel(button); + purple_request_close(PURPLE_REQUEST_INPUT, window); } static void * @@ -304,6 +301,7 @@ PurpleRequestFieldsCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); GList *list; + GntWidget *window; /* Update the data of the fields. Pidgin does this differently. Instead of * updating the fields at the end like here, it updates the appropriate field @@ -404,17 +402,16 @@ if (callback) callback(data, fields); - while (button->parent) - button = button->parent; - - purple_request_close(PURPLE_REQUEST_FIELDS, button); + window = gnt_widget_get_toplevel(button); + purple_request_close(PURPLE_REQUEST_FIELDS, window); } static void update_selected_account(GntEntry *username, const char *start, const char *end, GntComboBox *accountlist) { - GList *accounts = gnt_tree_get_rows(GNT_TREE(accountlist->dropdown)); + GList *accounts = + gnt_tree_get_rows(GNT_TREE(gnt_combo_box_get_dropdown(accountlist))); const char *name = gnt_entry_get_text(username); while (accounts) { if (purple_find_buddy(accounts->data, name)) { @@ -686,29 +683,34 @@ } static void -file_cancel_cb(gpointer fq, GntWidget *wid) +file_cancel_cb(GntWidget *wid, gpointer fq) { FinchFileRequest *data = fq; + if (data->dialog == NULL) { + /* We've already handled this request, and are in the destroy handler. */ + return; + } + if (data->cbs[1] != NULL) ((PurpleRequestFileCb)data->cbs[1])(data->user_data, NULL); purple_request_close(PURPLE_REQUEST_FILE, data->dialog); + data->dialog = NULL; } static void -file_ok_cb(gpointer fq, GntWidget *widget) +file_ok_cb(GntWidget *widget, const char *path, const char *file, gpointer fq) { FinchFileRequest *data = fq; - char *file = gnt_file_sel_get_selected_file(GNT_FILE_SEL(data->dialog)); - char *dir = g_path_get_dirname(file); + char *dir = g_path_get_dirname(path); if (data->cbs[0] != NULL) ((PurpleRequestFileCb)data->cbs[0])(data->user_data, file); - g_free(file); purple_prefs_set_path(data->save ? "/finch/filelocations/last_save_folder" : "/finch/filelocations/last_open_folder", dir); g_free(dir); purple_request_close(PURPLE_REQUEST_FILE, data->dialog); + data->dialog = NULL; } static void @@ -736,16 +738,13 @@ gnt_file_sel_set_current_location(sel, (path && *path) ? path : purple_home_dir()); - g_signal_connect(G_OBJECT(sel->cancel), "activate", - G_CALLBACK(action_performed), window); - g_signal_connect(G_OBJECT(sel->select), "activate", - G_CALLBACK(action_performed), window); - g_signal_connect_swapped(G_OBJECT(sel->cancel), "activate", + g_signal_connect(G_OBJECT(sel), "destroy", G_CALLBACK(file_cancel_cb), data); - g_signal_connect_swapped(G_OBJECT(sel->select), "activate", + g_signal_connect(G_OBJECT(sel), "cancelled", + G_CALLBACK(file_cancel_cb), data); + g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(file_ok_cb), data); - setup_default_callback(window, file_cancel_cb, data); g_object_set_data_full(G_OBJECT(window), "filerequestdata", data, (GDestroyNotify)file_request_destroy);
--- a/finch/gntsound.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/gntsound.c Sat Jul 27 03:23:16 2019 +0000 @@ -755,7 +755,7 @@ (event && event->file) ? (path = g_path_get_dirname(event->file)) : purple_home_dir()); - g_signal_connect_swapped(G_OBJECT(sel->cancel), "activate", G_CALLBACK(gnt_widget_destroy), sel); + g_signal_connect(G_OBJECT(sel), "cancelled", G_CALLBACK(gnt_widget_destroy), NULL); g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(file_cb), event); g_signal_connect_swapped(G_OBJECT(sel), "destroy", G_CALLBACK(g_nullify_pointer), &pref_dialog->selector); @@ -974,7 +974,8 @@ gnt_box_set_pad(GNT_BOX(box), 0); pref_dialog->method = cmbox = gnt_combo_box_new(); - gnt_tree_set_hash_fns(GNT_TREE(GNT_COMBO_BOX(cmbox)->dropdown), g_str_hash, g_str_equal, NULL); + gnt_tree_set_hash_fns(GNT_TREE(gnt_combo_box_get_dropdown(GNT_COMBO_BOX(cmbox))), + g_str_hash, g_str_equal, NULL); gnt_combo_box_add_data(GNT_COMBO_BOX(cmbox), "automatic", _("Automatic")); gnt_combo_box_add_data(GNT_COMBO_BOX(cmbox), "alsa", "ALSA"); gnt_combo_box_add_data(GNT_COMBO_BOX(cmbox), "esd", "ESD");
--- a/finch/libgnt/COPYING Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License.
--- a/finch/libgnt/INSTALL Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. -
--- a/finch/libgnt/Makefile.am Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -EXTRA_DIST=genmarshal - -SUBDIRS = . wms -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = gnt.pc - -lib_LTLIBRARIES = libgnt.la - -noinst_HEADERS = gntinternal.h - -BUILT_SOURCES = gntmarshal.h - -libgnt_la_SOURCES = \ - gntmarshal.c \ - gntwidget.c \ - gntbindable.c \ - gntbox.c \ - gntbutton.c \ - gntcheckbox.c \ - gntclipboard.c \ - gntcolors.c \ - gntcombobox.c \ - gntentry.c \ - gntfilesel.c \ - gntkeys.c \ - gntlabel.c \ - gntline.c \ - gntmenu.c \ - gntmenuitem.c \ - gntmenuitemcheck.c \ - gntprogressbar.c \ - gntslider.c \ - gntstyle.c \ - gnttextview.c \ - gnttree.c \ - gntutils.c \ - gntwindow.c \ - gntwm.c \ - gntws.c \ - gntmain.c - -libgnt_la_headers = \ - gntwidget.h \ - gntbindable.h \ - gntbox.h \ - gntbutton.h \ - gntcheckbox.h \ - gntclipboard.h \ - gntcolors.h \ - gntcombobox.h \ - gntentry.h \ - gntfilesel.h \ - gntkeys.h \ - gntlabel.h \ - gntline.h \ - gntmarshal.h \ - gntmenu.h \ - gntmenuitem.h \ - gntmenuitemcheck.h \ - gntprogressbar.h \ - gntslider.h \ - gntstyle.h \ - gnttextview.h \ - gnttree.h \ - gntutils.h \ - gntwindow.h \ - gntwm.h \ - gntws.h \ - gnt.h - -CLEANFILES = \ - gntmarshal.h \ - gntmarshal.c - -gntmarshal.c: $(srcdir)/genmarshal gntmarshal.h - echo "#include \"gntmarshal.h\"" > $@ - glib-genmarshal --prefix=gnt_closure_marshal --body $(srcdir)/genmarshal >> $@ - -gntmarshal.h: $(srcdir)/genmarshal - glib-genmarshal --prefix=gnt_closure_marshal --header $(srcdir)/genmarshal > $@ - -libgnt_laincludedir=$(includedir)/gnt -libgnt_lainclude_HEADERS = \ - $(libgnt_la_headers) - -libgnt_la_DEPENDENCIES = -libgnt_la_LDFLAGS = -export-dynamic -version-info $(GNT_LT_VERSION_INFO) -no-undefined -libgnt_la_LIBADD = \ - $(GLIB_LIBS) \ - $(GNT_LIBS) \ - $(LIBXML_LIBS) \ - $(PY_LIBS) - -AM_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(GNT_CFLAGS) \ - $(DEBUG_CFLAGS) \ - $(LIBXML_CFLAGS) \ - $(PY_CFLAGS)
--- a/finch/libgnt/autogen.sh Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -#!/bin/sh - -(libtoolize --version) < /dev/null > /dev/null 2>&1 || { - echo; - echo "You must have libtool installed to compile LibGNT"; - echo; - exit; -} - -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo; - echo "You must have automake installed to compile LibGNT"; - echo; - exit; -} - -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo; - echo "You must have autoconf installed to compile LibGNT"; - echo; - exit; -} - -echo "Generating configuration files for LibGNT, please wait...." -echo; - -echo "Running libtoolize, please ignore non-fatal messages...." -echo n | libtoolize --copy --force || exit; - -# Add other directories to this list if people continue to experience -# brokennesses ... Obviously the real answer is for them to fix it -# themselves, but for Luke's sake we have this. -for dir in "/usr/local/share/aclocal" \ - "/opt/gnome-1.4/share/aclocal" -do - if test -d $dir ; then - ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $dir" - fi -done - -libtoolize -c -f --automake -aclocal $ACLOCAL_FLAGS || exit; -autoheader || exit; -automake --add-missing --copy; -autoconf || exit; -automake || exit; -./configure $@ -
--- a/finch/libgnt/configure.ac Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -AC_PREREQ([2.50]) - -# UPDATING VERSION NUMBERS FOR RELEASES -# -# gnt_micro_version += 1 -# -# If any functions have been added to libgnt: -# gnt_micro_version = 0 -# gnt_minor_version += 1 -# gnt_lt_current += 1 -# -# If backwards compatibility has been broken in libgnt: -# gnt_micro_version = 0 -# gnt_minor_version = 0 -# gnt_major_version += 1; -# gnt_lt_current += 1 -# -# gnt_version_suffix should be similar to one of the following: -# For beta releases: [beta2] -# For code under development: [devel] -# For production releases: [] -# -# Make sure to update ../../configure.ac with libgnt version changes. -# - -m4_define([gnt_lt_current], [8]) -m4_define([gnt_major_version], [2]) -m4_define([gnt_minor_version], [8]) -m4_define([gnt_micro_version], [0]) -m4_define([gnt_version_suffix], [devel]) -m4_define([gnt_version], - [gnt_major_version.gnt_minor_version.gnt_micro_version]) -m4_define([gnt_display_version], gnt_version[]m4_ifdef([gnt_version_suffix],[gnt_version_suffix])) - -AC_INIT([libgnt], [gnt_display_version], [devel@pidgin.im]) -AC_CANONICAL_SYSTEM -AM_CONFIG_HEADER(config.h) -AC_CONFIG_AUX_DIR([.]) -AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) - -GNT_MAJOR_VERSION=gnt_major_version -GNT_MINOR_VERSION=gnt_minor_version -GNT_MICRO_VERSION=gnt_micro_version -GNT_VERSION=[gnt_display_version] -AC_SUBST(GNT_MAJOR_VERSION) -AC_SUBST(GNT_MINOR_VERSION) -AC_SUBST(GNT_MICRO_VERSION) -AC_SUBST(GNT_VERSION) - -GNT_LT_VERSION_INFO="gnt_lt_current:gnt_micro_version:gnt_minor_version" -AC_SUBST(GNT_LT_VERSION_INFO) - -AC_PATH_PROG(sedpath, sed) - -dnl Storing configure arguments -AC_DEFINE_UNQUOTED(CONFIG_ARGS, "$ac_configure_args", [configure arguments]) - -dnl Checks for programs. -AC_PROG_CC -AC_DISABLE_STATIC -AM_PROG_LIBTOOL -LIBTOOL="$LIBTOOL --silent" -AC_PROG_INSTALL - -dnl we don't use autobreak on cygwin!! -dnl AC_CYGWIN - -dnl Checks for header files. -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(arpa/nameser_compat.h fcntl.h sys/time.h unistd.h locale.h signal.h stdint.h regex.h) - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_STRUCT_TM - -AC_C_BIGENDIAN - -dnl Checks for library functions. -AC_TYPE_SIGNAL -AC_FUNC_STRFTIME -AC_CHECK_FUNCS(strdup strstr atexit setlocale) - -dnl to prevent the g_stat()/g_unlink() crash, -dnl (09:50:07) Robot101: LSchiere2: it's easy. +LC_SYS_LARGEFILE somewhere in configure.ac -AC_SYS_LARGEFILE - -dnl FreeBSD doesn't have libdl, dlopen is provided by libc -AC_CHECK_FUNC(dlopen, LIBDL="", [AC_CHECK_LIB(dl, dlopen, LIBDL="-ldl")]) - -AC_MSG_CHECKING(for the %z format string in strftime()) -AC_TRY_RUN([ -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <time.h> -#include <stdio.h> - -int main() -{ - char buf[6]; - time_t t = time(NULL); - - if (strftime(buf, sizeof(buf), "%z", localtime(&t)) != 5) - return 1; - - fprintf(stderr, "strftime(\"%%z\") yields: \"%s\"\n", buf); - - return !((buf[0] == '-' || buf[0] == '+') && - (buf[1] >= '0' && buf[1] <= '9') && - (buf[2] >= '0' && buf[2] <= '9') && - (buf[3] >= '0' && buf[3] <= '9') && - (buf[4] >= '0' && buf[4] <= '9') - ); -} -], -[ - AC_MSG_RESULT(yes) - AC_DEFINE([HAVE_STRFTIME_Z_FORMAT], [1], - [Define to 1 if you have a strftime() that supports the %z format string.]) -], -[ - AC_MSG_RESULT(no) -], -[ - # Fallback for Cross Compiling... - # This will enable the compatibility code. - AC_MSG_RESULT(no) -] -) - - -AC_CHECK_HEADER(sys/utsname.h) -AC_CHECK_FUNC(uname) - -if test "x$enable_debug" = "xyes" ; then - AC_DEFINE(DEBUG, 1, [Define if debugging is enabled.]) - enable_fatal_asserts="yes" -fi - -if test "x$enable_fatal_asserts" = "xyes" ; then - AC_DEFINE(GAIM_FATAL_ASSERTS, 1, [Define to make assertions fatal (useful for debugging).]) -fi - -if test "x$enable_deprecated" = "xno"; then - DEBUG_CFLAGS="$DEBUG_CFLAGS -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" -fi - -if test "x$GCC" = "xyes"; then - dnl We enable -Wall later. - dnl If it's set after the warning CFLAGS in the compiler invocation, it counteracts the -Wno... flags. - dnl This leads to warnings we don't want. - CFLAGS=`echo $CFLAGS |$sedpath 's/-Wall//'` - - dnl ENABLE WARNINGS SUPPORTED BY THE VERSION OF GCC IN USE - dnl - dnl Future Possibilities - dnl - dnl Consider adding -Wbad-function-cast. - dnl This leads to spurious warnings using GPOINTER_TO_INT(), et al. directly on a function call. - dnl We'd need an intermediate variable. - dnl - dnl Consider adding -Wfloat-equal. - dnl This leads to warnings with Perl. - dnl Perhaps we could write ugly configure magic and pass -Wno-float-equal down to that subdirectory. - dnl On the other hand, it's probably actually broken, so maybe the Perl folks should fix that? - dnl - dnl Consider removing -Wno-sign-compare (from the -Wextra set) and fixing all those cases. - dnl This is likely non-trivial. - dnl - for newflag in \ - "-Waggregate-return" \ - "-Wcast-align" \ - "-Wdeclaration-after-statement" \ - "-Werror-implicit-function-declaration" \ - "-Wextra -Wno-sign-compare -Wno-unused-parameter" \ - "-Winit-self" \ - "-Wmissing-declarations" \ - "-Wmissing-prototypes" \ - "-Wnested-externs" \ - "-Wpointer-arith" \ - "-Wundef" \ - ; do - orig_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $newflag" - AC_MSG_CHECKING(for $newflag option to gcc) - AC_TRY_COMPILE([], [ - int main() {return 0;} - ], [ - AC_MSG_RESULT(yes) - CFLAGS="$orig_CFLAGS" - DEBUG_CFLAGS="$DEBUG_CFLAGS $newflag" - ], [ - AC_MSG_RESULT(no) - CFLAGS="$orig_CFLAGS" - ]) - done - - if test "x$enable_fortify" = "xyes"; then - AC_MSG_CHECKING(for FORTIFY_SOURCE support) - AC_TRY_COMPILE([#include <features.h>], [ - int main() { - #if !(__GNUC_PREREQ (4, 1) \ - || (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (4, 0)) \ - || (defined __GNUC_RH_RELEASE__ && __GNUC_PREREQ (3, 4) \ - && __GNUC_MINOR__ == 4 \ - && (__GNUC_PATCHLEVEL__ > 2 \ - || (__GNUC_PATCHLEVEL__ == 2 && __GNUC_RH_RELEASE__ >= 8)))) - #error No FORTIFY_SOURCE support - #endif - return 0; - } - ], [ - AC_MSG_RESULT(yes) - DEBUG_CFLAGS="$DEBUG_CFLAGS -D_FORTIFY_SOURCE=2" - ], [ - AC_MSG_RESULT(no) - ]) - fi - - DEBUG_CFLAGS="-Wall $DEBUG_CFLAGS" - CFLAGS="-g $CFLAGS" -fi -AC_SUBST(CFLAGS) - -PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.0.0 gobject-2.0 gmodule-2.0],, - [ - AC_MSG_ERROR([ -*** GLib 2.0 is required to build LibGNT; please make sure you have the GLib -*** development headers installed. The latest version of GLib is -*** always available at http://www.gtk.org/.]) - ]) -AC_SUBST(GLIB_CFLAGS) -AC_SUBST(GLIB_LIBS) - - -AC_MSG_CHECKING(for me pot o' gold) -AC_MSG_RESULT(no) -AC_CHECK_FUNCS(gethostid lrand48) -AC_CHECK_FUNCS(memcpy memmove random strchr strerror vprintf) -AC_CHECK_HEADERS(malloc.h paths.h sgtty.h stdarg.h sys/cdefs.h) -AC_CHECK_HEADERS(sys/file.h sys/filio.h sys/ioctl.h sys/msgbuf.h) -AC_CHECK_HEADERS(sys/select.h sys/uio.h sys/utsname.h sys/wait.h) -AC_CHECK_HEADERS(termios.h) -#AC_CHECK_FUNC(wcwidth, [AC_DEFINE([HAVE_WCWIDTH], [1], [Define to 1 if you have wcwidth function.])]) -#AC_VAR_TIMEZONE_EXTERNALS - -GNT_CFLAGS= -GNT_LIBS= -AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR], - [compile finch against the ncurses includes in DIR])], - [ac_ncurses_includes="$withval"], [ac_ncurses_includes=""]) -AC_CHECK_LIB(ncursesw, initscr, [GNT_LIBS="-lncursesw"], [enable_gnt=no]) -AC_CHECK_LIB(panelw, update_panels, [GNT_LIBS="$GNT_LIBS -lpanelw"], [enable_gnt=no]) - -# If ncursesw is not found, look for plain old ncurses -if test "x$enable_gnt" = "xno"; then - AC_CHECK_LIB(ncurses, initscr, [[GNT_LIBS="-lncurses"] [enable_gnt=yes]], [enable_gnt=no]) - AC_CHECK_LIB(panel, update_panels, [[GNT_LIBS="$GNT_LIBS -lpanel"] [enable_gnt=yes]], [enable_gnt=no]) - AC_DEFINE(NO_WIDECHAR, [1], [Define to 1 if you do not have ncursesw.]) -else - dnl # Some distros put the headers in ncursesw/, some don't - found_ncurses_h=no - for location in $ac_ncurses_includes /usr/include/ncursesw /usr/include - do - f="$location/ncurses.h" - orig_CFLAGS="$CFLAGS" - orig_CPPFLAGS="$CPPFLAGS" - CFLAGS="$CFLAGS -I$location" - CPPFLAGS="$CPPFLAGS -I$location" - AC_CHECK_HEADER($f,[ - AC_MSG_CHECKING([if $f supports wide characters]) - AC_TRY_COMPILE([ - #define _XOPEN_SOURCE_EXTENDED - #include <$f> - ], [ - #ifndef get_wch - # error get_wch not found! - #endif - ], [ - dir=$location - if test x"$dir" != x"." ; then - GNT_CFLAGS="-I$dir/" - else - GNT_CFLAGS="" - fi - - found_ncurses_h=yes - CFLAGS="$orig_CFLAGS" - CPPFLAGS="$orig_CPPFLAGS" - AC_MSG_RESULT([yes]) - break - ], [ - CFLAGS="$orig_CFLAGS" - CPPFLAGS="$orig_CPPFLAGS" - AC_MSG_RESULT([no]) - ]) - ]) - done - if test x"$found_ncurses_h" != "xyes"; then - enable_gnt="no" - fi -fi -AC_SUBST(GNT_CFLAGS) -AC_SUBST(GNT_LIBS) - -if test "x$enable_gnt" = "xno"; then - AC_MSG_ERROR([ -*** You need ncursesw or ncurses and its header files.]) -fi - -dnl Check for Python headers (currently useful only for libgnt) -dnl (Thanks to XChat) -AC_PATH_PROG(pythonpath, python) -if test "_$pythonpath" != _ ; then - AC_MSG_CHECKING(for Python compile flags) - PY_PREFIX=`$pythonpath -c 'import sys ; print sys.prefix'` - PY_EXEC_PREFIX=`$pythonpath -c 'import sys ; print sys.exec_prefix'` - changequote(<<, >>)dnl - PY_VERSION=`$pythonpath -c 'import sys ; print sys.version[0:3]'` - PY_MAJOR=`$pythonpath -c 'import sys ; print sys.version[0:2]'` - changequote([, ])dnl - if test -f $PY_PREFIX/include/python$PY_VERSION/Python.h -a "$PY_MAJOR" = "2."; then - AC_CHECK_LIB(pthread, pthread_create, ) - AC_CHECK_LIB(util, openpty, ) - AC_CHECK_LIB(db, dbopen, ) - PY_LIBS="-lpython$PY_VERSION -L$PY_EXEC_PREFIX/lib/python$PY_VERSION/config" - PY_CFLAGS="-I$PY_PREFIX/include/python$PY_VERSION" - AC_DEFINE(USE_PYTHON, [1], [Define if python headers are available.]) - AC_MSG_RESULT(ok) - else - AC_MSG_RESULT([Can't find Python.h]) - PY_LIBS="" - PY_CFLAGS="" - fi -fi -AC_SUBST(PY_CFLAGS) -AC_SUBST(PY_LIBS) - -dnl Check for libxml -have_libxml=yes -PKG_CHECK_MODULES(LIBXML, [libxml-2.0], , [ - AC_MSG_RESULT(no) - have_libxml=no - ]) -AC_SUBST(LIBXML_CFLAGS) -AC_SUBST(LIBXML_LIBS) - -if test "x$have_libxml" = "xno"; then - AC_DEFINE(NO_LIBXML, 1, [Do not have libxml2.]) -fi - -AM_CONDITIONAL(PURPLE_AVAILABLE, false) - -AC_OUTPUT([Makefile - gnt.pc - wms/Makefile - ]) -
--- a/finch/libgnt/genmarshal Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -BOOLEAN:VOID -BOOLEAN:STRING -VOID:INT,INT,INT,INT -VOID:INT,INT -VOID:POINTER,POINTER -BOOLEAN:INT,INT -BOOLEAN:INT,INT,INT -BOOLEAN:POINTER,POINTER,POINTER -BOOLEAN:INT,INT,INT,POINTER -VOID:STRING,STRING -VOID:POINTER,BOOLEAN
--- a/finch/libgnt/gnt-skel.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gnt-skel.h" - -enum -{ - SIGS = 1, -}; - -static GntWidgetClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; - -static void -gnt_skel_draw(GntWidget *widget) -{ - GNTDEBUG; -} - -static void -gnt_skel_size_request(GntWidget *widget) -{ -} - -static void -gnt_skel_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static gboolean -gnt_skel_key_pressed(GntWidget *widget, const char *text) -{ - return FALSE; -} - -static void -gnt_skel_destroy(GntWidget *widget) -{ -} - -static void -gnt_skel_class_init(GntSkelClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->destroy = gnt_skel_destroy; - parent_class->draw = gnt_skel_draw; - parent_class->map = gnt_skel_map; - parent_class->size_request = gnt_skel_size_request; - parent_class->key_pressed = gnt_skel_key_pressed; - - parent_class->actions = g_hash_table_duplicate(parent_class->actions, g_str_hash, - g_str_equal, NULL, (GDestroyNotify)gnt_widget_action_free); - parent_class->bindings = g_hash_table_duplicate(parent_class->bindings, g_str_hash, - g_str_equal, NULL, (GDestroyNotify)gnt_widget_action_param_free); - - gnt_widget_actions_read(G_OBJECT_CLASS_TYPE(klass), klass); - - GNTDEBUG; -} - -static void -gnt_skel_init(GTypeInstance *instance, gpointer class) -{ - GNTDEBUG; -} - -/****************************************************************************** - * GntSkel API - *****************************************************************************/ -GType -gnt_skel_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntSkelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_skel_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntSkel), - 0, /* n_preallocs */ - gnt_skel_init, /* instance_init */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntSkel", - &info, 0); - } - - return type; -} - -GntWidget *gnt_skel_new() -{ - GntWidget *widget = g_object_new(GNT_TYPE_SKEL, NULL); - GntSkel *skel = GNT_SKEL(widget); - - return widget; -} -
--- a/finch/libgnt/gnt-skel.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/** - * @file gnt-skel.h -skel API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_SKEL_H -#define GNT_SKEL_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_SKEL (gnt_skel_get_gtype()) -#define GNT_SKEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SKEL, GntSkel)) -#define GNT_SKEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_SKEL, GntSkelClass)) -#define GNT_IS_SKEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_SKEL)) -#define GNT_IS_SKEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_SKEL)) -#define GNT_SKEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_SKEL, GntSkelClass)) - -typedef struct _GntSkel GntSkel; -typedef struct _GntSkelPriv GntSkelPriv; -typedef struct _GntSkelClass GntSkelClass; - -struct _GntSkel -{ - GntWidget parent; -}; - -struct _GntSkelClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * - * - * @return - */ -GType gnt_skel_get_gtype(void); - -/** - * - * - * @return - */ -GntWidget * gnt_skel_new(); - -G_END_DECLS - -#endif /* GNT_SKEL_H */
--- a/finch/libgnt/gnt.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -/** - * @defgroup gnt GNT (GLib Ncurses Toolkit) - * - * GNT is an ncurses toolkit for creating text-mode graphical user interfaces - * in a fast and easy way. - */ -/** - * @file gnt.h GNT API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_H -#define GNT_H - -#include <glib.h> -#include "gntwidget.h" -#include "gntclipboard.h" -#include "gntcolors.h" -#include "gntkeys.h" - -/** - * Get things to compile in Glib < 2.8 - */ -#if !GLIB_CHECK_VERSION(2,8,0) - #define G_PARAM_STATIC_NAME G_PARAM_PRIVATE - #define G_PARAM_STATIC_NICK G_PARAM_PRIVATE - #define G_PARAM_STATIC_BLURB G_PARAM_PRIVATE -#endif - -#if !GLIB_CHECK_VERSION(2,14,0) - #define g_timeout_add_seconds(time, callback, data) g_timeout_add(time * 1000, callback, data) -#endif - -/** - * Initialize GNT. - */ -void gnt_init(void); - -/** - * Start running the mainloop for gnt. - */ -void gnt_main(void); - -/** - * Check whether the terminal is capable of UTF8 display. - * - * @return @c FALSE if the terminal is capable of drawing UTF-8, @c TRUE otherwise. - */ -gboolean gnt_ascii_only(void); - -/** - * Present a window. If the event was triggered because of user interaction, - * the window is moved to the foreground. Otherwise, the Urgent hint is set. - * - * @param window The window the present. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_window_present(GntWidget *window); - -/** - * @internal - * Use #gnt_widget_show instead. - */ -void gnt_screen_occupy(GntWidget *widget); - -/** - * @internal - * Use #gnt_widget_hide instead. - */ -void gnt_screen_release(GntWidget *widget); - -/** - * @internal - * Use #gnt_widget_draw instead. - */ -void gnt_screen_update(GntWidget *widget); - -/** - * Resize a widget. - * - * @param widget The widget to resize. - * @param width The desired width. - * @param height The desired height. - */ -void gnt_screen_resize_widget(GntWidget *widget, int width, int height); - -/** - * Move a widget. - * - * @param widget The widget to move. - * @param x The desired x-coordinate. - * @param y The desired y-coordinate. - */ -void gnt_screen_move_widget(GntWidget *widget, int x, int y); - -/** - * Rename a widget. - * - * @param widget The widget to rename. - * @param text The new name for the widget. - */ -void gnt_screen_rename_widget(GntWidget *widget, const char *text); - -/** - * Check whether a widget has focus. - * - * @param widget The widget. - * - * @return @c TRUE if the widget has the current focus, @c FALSE otherwise. - */ -gboolean gnt_widget_has_focus(GntWidget *widget); - -/** - * Set the URGENT hint for a widget. - * - * @param widget The widget to set the URGENT hint for. - */ -void gnt_widget_set_urgent(GntWidget *widget); - -/** - * Register a global action. - * - * @param label The user-visible label for the action. - * @param callback The callback function for the action. - */ -void gnt_register_action(const char *label, void (*callback)(void)); - -/** - * Show a menu. - * - * @param menu The menu to display. - * - * @return @c TRUE if the menu is displayed, @c FALSE otherwise (e.g., if another menu is currently displayed). - */ -gboolean gnt_screen_menu_show(gpointer menu); - -/** - * Terminate the mainloop of gnt. - */ -void gnt_quit(void); - -/** - * Get the global clipboard. - * - * @return The clipboard. - */ -GntClipboard * gnt_get_clipboard(void); - -/** - * Get the string in the clipboard. - * - * @return A copy of the string in the clipboard. The caller must @c g_free the string. - */ -gchar * gnt_get_clipboard_string(void); - -/** - * Set the contents of the global clipboard. - * - * @param string The new content of the new clipboard. - */ -void gnt_set_clipboard_string(const gchar *string); - -/** - * Spawn a different application that will consume the console. - * - * @param wd The working directory for the new application. - * @param argv The argument vector. - * @param envp The environment, or @c NULL. - * @param stin Location to store the child's stdin, or @c NULL. - * @param stout Location to store the child's stdout, or @c NULL. - * @param sterr Location to store the child's stderr, or @c NULL. - * @param callback The callback to call after the child exits. - * @param data The data to pass to the callback. - * - * @return @c TRUE if the child was successfully spawned, @c FALSE otherwise. - */ -gboolean gnt_giveup_console(const char *wd, char **argv, char **envp, - gint *stin, gint *stout, gint *sterr, - void (*callback)(int status, gpointer data), gpointer data); - -/** - * Check whether a child process is in control of the current terminal. - * - * @return @c TRUE if a child process (eg., PAGER) is occupying the current - * terminal, @c FALSE otherwise. - */ -gboolean gnt_is_refugee(void); - -#endif /* GNT_H */
--- a/finch/libgnt/gnt.pc.in Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -datarootdir=@datarootdir@ -datadir=@datadir@ -sysconfdir=@sysconfdir@ - -Name: LibGNT -Description: Glib Ncurses Toolkit is a collection of curses-widgets. -Version: @VERSION@ -Requires: glib-2.0 -Cflags: -I${includedir}/gnt -Libs: -L${libdir} -lgnt
--- a/finch/libgnt/gntbindable.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,485 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include <string.h> - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Bindable" - -#include "gntbindable.h" -#include "gntstyle.h" -#include "gnt.h" -#include "gntutils.h" -#include "gnttextview.h" -#include "gnttree.h" -#include "gntbox.h" -#include "gntbutton.h" -#include "gntwindow.h" -#include "gntlabel.h" - -static GObjectClass *parent_class = NULL; - -static struct -{ - char * okeys; /* Old keystrokes */ - char * keys; /* New Keystrokes being bound to the action */ - GntBindableClass * klass; /* Class of the object that's getting keys rebound */ - char * name; /* The name of the action */ - GList * params; /* The list of paramaters */ -} rebind_info; - -static void -gnt_bindable_free_rebind_info(void) -{ - g_free(rebind_info.name); - g_free(rebind_info.keys); - g_free(rebind_info.okeys); -} - -static void -gnt_bindable_rebinding_cancel(GntWidget *button, gpointer data) -{ - gnt_bindable_free_rebind_info(); - gnt_widget_destroy(GNT_WIDGET(data)); -} - -static void -gnt_bindable_rebinding_rebind(GntWidget *button, gpointer data) -{ - if (rebind_info.keys) { - gnt_bindable_register_binding(rebind_info.klass, - NULL, - rebind_info.okeys, - rebind_info.params); - gnt_bindable_register_binding(rebind_info.klass, - rebind_info.name, - rebind_info.keys, - rebind_info.params); - } - gnt_bindable_free_rebind_info(); - gnt_widget_destroy(GNT_WIDGET(data)); -} - -static gboolean -gnt_bindable_rebinding_grab_key(GntBindable *bindable, const char *text, gpointer data) -{ - GntTextView *textview = GNT_TEXT_VIEW(data); - char *new_text; - const char *tmp; - - if (text && *text) { - /* Rebinding tab or enter for something is probably not that great an idea */ - if (!strcmp(text, GNT_KEY_CTRL_I) || !strcmp(text, GNT_KEY_ENTER)) { - return FALSE; - } - - tmp = gnt_key_lookup(text); - new_text = g_strdup_printf("KEY: \"%s\"", tmp); - gnt_text_view_clear(textview); - gnt_text_view_append_text_with_flags(textview, new_text, GNT_TEXT_FLAG_NORMAL); - g_free(new_text); - - g_free(rebind_info.keys); - rebind_info.keys = g_strdup(text); - - return TRUE; - } - return FALSE; -} -static void -gnt_bindable_rebinding_activate(GntBindable *data, gpointer bindable) -{ - const char *widget_name = g_type_name(G_OBJECT_TYPE(bindable)); - char *keys; - GntWidget *key_textview; - GntWidget *label; - GntWidget *bind_button, *cancel_button; - GntWidget *button_box; - GList *current_row_data; - char *tmp; - GntWidget *win = gnt_window_new(); - GntTree *tree = GNT_TREE(data); - GntWidget *vbox = gnt_box_new(FALSE, TRUE); - - rebind_info.klass = GNT_BINDABLE_GET_CLASS(bindable); - - current_row_data = gnt_tree_get_selection_text_list(tree); - rebind_info.name = g_strdup(g_list_nth_data(current_row_data, 1)); - - keys = gnt_tree_get_selection_data(tree); - rebind_info.okeys = g_strdup(gnt_key_translate(keys)); - - rebind_info.params = NULL; - - g_list_foreach(current_row_data, (GFunc)g_free, NULL); - g_list_free(current_row_data); - - gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID); - - gnt_box_set_title(GNT_BOX(win), "Key Capture"); - - tmp = g_strdup_printf("Type the new bindings for %s in a %s.", rebind_info.name, widget_name); - label = gnt_label_new(tmp); - g_free(tmp); - gnt_box_add_widget(GNT_BOX(vbox), label); - - tmp = g_strdup_printf("KEY: \"%s\"", keys); - key_textview = gnt_text_view_new(); - gnt_widget_set_size(key_textview, key_textview->priv.x, 2); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(key_textview), tmp, GNT_TEXT_FLAG_NORMAL); - g_free(tmp); - gnt_widget_set_name(key_textview, "keystroke"); - gnt_box_add_widget(GNT_BOX(vbox), key_textview); - - g_signal_connect(G_OBJECT(win), "key_pressed", G_CALLBACK(gnt_bindable_rebinding_grab_key), key_textview); - - button_box = gnt_box_new(FALSE, FALSE); - - bind_button = gnt_button_new("BIND"); - gnt_widget_set_name(bind_button, "bind"); - gnt_box_add_widget(GNT_BOX(button_box), bind_button); - - cancel_button = gnt_button_new("Cancel"); - gnt_widget_set_name(cancel_button, "cancel"); - gnt_box_add_widget(GNT_BOX(button_box), cancel_button); - - g_signal_connect(G_OBJECT(bind_button), "activate", G_CALLBACK(gnt_bindable_rebinding_rebind), win); - g_signal_connect(G_OBJECT(cancel_button), "activate", G_CALLBACK(gnt_bindable_rebinding_cancel), win); - - gnt_box_add_widget(GNT_BOX(vbox), button_box); - - gnt_box_add_widget(GNT_BOX(win), vbox); - gnt_widget_show(win); -} - -typedef struct -{ - GHashTable *hash; - GntTree *tree; -} BindingView; - -static void -add_binding(gpointer key, gpointer value, gpointer data) -{ - BindingView *bv = data; - GntBindableActionParam *act = value; - const char *name = g_hash_table_lookup(bv->hash, act->action); - if (name && *name) { - const char *k = gnt_key_lookup(key); - if (!k) - k = key; - gnt_tree_add_row_after(bv->tree, (gpointer)k, - gnt_tree_create_row(bv->tree, k, name), NULL, NULL); - } -} - -static void -add_action(gpointer key, gpointer value, gpointer data) -{ - BindingView *bv = data; - g_hash_table_insert(bv->hash, value, key); -} - -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 gpointer -bindable_clone(GntBindableAction *action) -{ - GntBindableAction *ret = g_new0(GntBindableAction, 1); - ret->name = g_strdup(action->name); - ret->u = action->u; - return ret; -} - -static gpointer -binding_clone(GntBindableActionParam *param) -{ - GntBindableActionParam *p = g_new0(GntBindableActionParam, 1); - p->list = g_list_copy(param->list); - p->action = param->action; - return p; -} - -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, - (GDupFunc)g_strdup, (GDupFunc)bindable_clone); - klass->bindings = g_hash_table_duplicate(klass->bindings, g_str_hash, - g_str_equal, g_free, (GDestroyNotify)gnt_bindable_action_param_free, - (GDupFunc)g_strdup, (GDupFunc)binding_clone); - } 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 */ - NULL /* value_table */ - }; - - 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) { - return action->u.action(bindable, list); - } - 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; -} - -gboolean -gnt_bindable_check_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); - return (param && param->action); -} - -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); - gnt_keys_del_combination(trigger); - return; - } - - action = g_hash_table_lookup(klass->actions, name); - if (!action) { - gnt_warning("Invalid action name %s for %s", - 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); - gnt_keys_add_combination(trigger); -} - -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 && *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); -} - -GntBindable * gnt_bindable_bindings_view(GntBindable *bind) -{ - GntBindable *tree = GNT_BINDABLE(gnt_tree_new_with_columns(2)); - GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind)); - GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal); - BindingView bv = {hash, GNT_TREE(tree)}; - - gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate); - g_hash_table_foreach(klass->actions, add_action, &bv); - g_hash_table_foreach(klass->bindings, add_binding, &bv); - if (GNT_TREE(tree)->list == NULL) { - gnt_widget_destroy(GNT_WIDGET(tree)); - tree = NULL; - } else - gnt_tree_adjust_columns(bv.tree); - g_hash_table_destroy(hash); - - return tree; -} - -static void -reset_binding_window(GntBindableClass *window, gpointer k) -{ - GntBindableClass *klass = GNT_BINDABLE_CLASS(k); - klass->help_window = NULL; -} - -gboolean -gnt_bindable_build_help_window(GntBindable *bindable) -{ - GntWidget *tree; - GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable); - char *title; - - tree = GNT_WIDGET(gnt_bindable_bindings_view(bindable)); - - klass->help_window = GNT_BINDABLE(gnt_window_new()); - title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(bindable))); - gnt_box_set_title(GNT_BOX(klass->help_window), title); - if (tree) { - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(gnt_bindable_rebinding_activate), bindable); - gnt_box_add_widget(GNT_BOX(klass->help_window), tree); - } else - gnt_box_add_widget(GNT_BOX(klass->help_window), gnt_label_new("This widget has no customizable bindings.")); - - g_signal_connect(G_OBJECT(klass->help_window), "destroy", G_CALLBACK(reset_binding_window), klass); - gnt_widget_show(GNT_WIDGET(klass->help_window)); - g_free(title); - - return TRUE; -} -
--- a/finch/libgnt/gntbindable.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/** - * @file gntbindable.h Bindable API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#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 - -typedef struct _GntBindable GntBindable; -typedef struct _GntBindableClass GntBindableClass; - -struct _GntBindable -{ - GObject inherit; -}; - -struct _GntBindableClass -{ - GObjectClass parent; - - GHashTable *remaps; /* Key remaps */ - GHashTable *actions; /* name -> Action */ - GHashTable *bindings; /* key -> ActionParam */ - - GntBindable * help_window; - - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * - * - * @return - */ -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 _GntBindableAction GntBindableAction; -typedef struct _GntBindableActionParam GntBindableActionParam; - -struct _GntBindableAction -{ - char *name; /* The name of the action */ - union { - gboolean (*action)(GntBindable *bindable, GList *params); - gboolean (*action_noparam)(GntBindable *bindable); - } u; -}; - -struct _GntBindableActionParam -{ - GntBindableAction *action; - GList *list; -}; - -/*GntBindableAction *gnt_bindable_action_parse(const char *name);*/ - -/** - * Free a bindable action. - * - * @param action The bindable action. - */ -void gnt_bindable_action_free(GntBindableAction *action); - -/** - * Free a GntBindableActionParam. - * - * @param param The GntBindableActionParam to free. - */ -void gnt_bindable_action_param_free(GntBindableActionParam *param); - -/** - * Register a bindable action for a class. - * - * @param klass The class the binding is for. - * @param name The name of the binding. - * @param callback The callback for the binding. - * @param trigger The default trigger for the binding, or @c NULL, followed by a NULL-terminated - * list of default parameters. - */ -void gnt_bindable_class_register_action(GntBindableClass *klass, const char *name, GntBindableActionCallback callback, const char *trigger, ...); - -/** - * Register a key-binding to an existing action. - * - * @param klass The class the binding is for. - * @param name The name of the binding. - * @param trigger A new trigger for the binding, followed by a @c NULL-terminated list of parameters for the callback. - */ -void gnt_bindable_register_binding(GntBindableClass *klass, const char *name, const char *trigger, ...); - -/** - * Perform an action from a keybinding. - * - * @param bindable The bindable object. - * @param keys The key to trigger the action. - * - * @return @c TRUE if the action was performed successfully, @c FALSE otherwise. - */ -gboolean gnt_bindable_perform_action_key(GntBindable *bindable, const char *keys); - -/** - * Discover if a key is bound. - * - * @param bindable The bindable object. - * @param keys The key to check for. - * - * @return @c TRUE if the the key has an action associated with it. - */ -gboolean gnt_bindable_check_key(GntBindable *bindable, const char *keys); - -/** - * Perform an action on a bindable object. - * - * @param bindable The bindable object. - * @param name The action to perform, followed by a @c NULL-terminated list of parameters. - * - * @return @c TRUE if the action was performed successfully, @c FALSE otherwise. - */ -gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...) G_GNUC_NULL_TERMINATED; - -/** - * Returns a GntTree populated with "key" -> "binding" for the widget. - * - * @param bind The object to list the bindings for. - * - * @return The GntTree. - */ -GntBindable * gnt_bindable_bindings_view(GntBindable *bind); - -/** - * Builds a window that list the key bindings for a GntBindable object. - * From this window a user can select a listing to rebind a new key for the given action. - * - * @param bindable The object to list the bindings for. - * - * @return @c TRUE - */ - -gboolean gnt_bindable_build_help_window(GntBindable *bindable); - -G_END_DECLS - -#endif /* GNT_BINDABLE_H */ -
--- a/finch/libgnt/gntbox.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,903 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntbox.h" -#include "gntstyle.h" -#include "gntutils.h" - -#include <string.h> - -#define PROP_LAST_RESIZE_S "last-resize" -#define PROP_SIZE_QUEUED_S "size-queued" - -enum -{ - PROP_0, - PROP_VERTICAL, - PROP_HOMO /* ... */ -}; - -enum -{ - SIGS = 1, -}; - -static GntWidgetClass *parent_class = NULL; - -static GntWidget * find_focusable_widget(GntBox *box); - -static void -add_to_focus(gpointer value, gpointer data) -{ - GntBox *box = GNT_BOX(data); - GntWidget *w = GNT_WIDGET(value); - - if (GNT_IS_BOX(w)) - g_list_foreach(GNT_BOX(w)->list, add_to_focus, box); - else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_CAN_TAKE_FOCUS)) - box->focus = g_list_append(box->focus, w); -} - -static void -get_title_thingies(GntBox *box, char *title, int *p, int *r) -{ - GntWidget *widget = GNT_WIDGET(box); - int len; - char *end = (char*)gnt_util_onscreen_width_to_pointer(title, widget->priv.width - 4, &len); - - if (p) - *p = (widget->priv.width - len) / 2; - if (r) - *r = (widget->priv.width + len) / 2; - *end = '\0'; -} - -static void -gnt_box_draw(GntWidget *widget) -{ - GntBox *box = GNT_BOX(widget); - - if (box->focus == NULL && widget->parent == NULL) - g_list_foreach(box->list, add_to_focus, box); - - g_list_foreach(box->list, (GFunc)gnt_widget_draw, NULL); - - if (box->title && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - { - int pos, right; - char *title = g_strdup(box->title); - - get_title_thingies(box, title, &pos, &right); - - if (gnt_widget_has_focus(widget)) - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TITLE)); - else - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TITLE_D)); - mvwaddch(widget->window, 0, pos-1, ACS_RTEE | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddstr(widget->window, 0, pos, C_(title)); - mvwaddch(widget->window, 0, right, ACS_LTEE | gnt_color_pair(GNT_COLOR_NORMAL)); - g_free(title); - } - - gnt_box_sync_children(box); -} - -static void -reposition_children(GntWidget *widget) -{ - GList *iter; - GntBox *box = GNT_BOX(widget); - int w, h, curx, cury, max; - gboolean has_border = FALSE; - - w = h = 0; - max = 0; - curx = widget->priv.x; - cury = widget->priv.y; - if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) - { - has_border = TRUE; - curx += 1; - cury += 1; - } - - for (iter = box->list; iter; iter = iter->next) - { - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(iter->data), GNT_WIDGET_INVISIBLE)) - continue; - gnt_widget_set_position(GNT_WIDGET(iter->data), curx, cury); - gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); - if (box->vertical) - { - if (h) - { - cury += h + box->pad; - if (max < w) - max = w; - } - } - else - { - if (w) - { - curx += w + box->pad; - if (max < h) - max = h; - } - } - } - - if (has_border) - { - curx += 1; - cury += 1; - max += 2; - } - - if (box->list) - { - if (box->vertical) - cury -= box->pad; - else - curx -= box->pad; - } - - if (box->vertical) - { - widget->priv.width = max; - widget->priv.height = cury - widget->priv.y; - } - else - { - widget->priv.width = curx - widget->priv.x; - widget->priv.height = max; - } -} - -static void -gnt_box_set_position(GntWidget *widget, int x, int y) -{ - GList *iter; - int changex, changey; - - changex = widget->priv.x - x; - changey = widget->priv.y - y; - - for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) - { - GntWidget *w = GNT_WIDGET(iter->data); - gnt_widget_set_position(w, w->priv.x - changex, - w->priv.y - changey); - } -} - -static void -gnt_box_size_request(GntWidget *widget) -{ - GntBox *box = GNT_BOX(widget); - GList *iter; - int maxw = 0, maxh = 0; - - g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL); - - for (iter = box->list; iter; iter = iter->next) - { - int w, h; - gnt_widget_get_size(GNT_WIDGET(iter->data), &w, &h); - if (maxh < h) - maxh = h; - if (maxw < w) - maxw = w; - } - - for (iter = box->list; iter; iter = iter->next) - { - int w, h; - GntWidget *wid = GNT_WIDGET(iter->data); - - gnt_widget_get_size(wid, &w, &h); - - if (box->homogeneous) - { - if (box->vertical) - h = maxh; - else - w = maxw; - } - if (box->fill) - { - if (box->vertical) - w = maxw; - else - h = maxh; - } - - if (gnt_widget_confirm_size(wid, w, h)) - gnt_widget_set_size(wid, w, h); - } - - reposition_children(widget); -} - -static void -gnt_box_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - { - gnt_widget_size_request(widget); - find_focusable_widget(GNT_BOX(widget)); - } - GNTDEBUG; -} - -/* Ensures that the current widget can take focus */ -static GntWidget * -find_focusable_widget(GntBox *box) -{ - /* XXX: Make sure the widget is visible? */ - if (box->focus == NULL && GNT_WIDGET(box)->parent == NULL) - g_list_foreach(box->list, add_to_focus, box); - - if (box->active == NULL && box->focus) - box->active = box->focus->data; - - return box->active; -} - -static void -find_next_focus(GntBox *box) -{ - gpointer last = box->active; - do - { - GList *iter = g_list_find(box->focus, box->active); - if (iter && iter->next) - box->active = iter->next->data; - else if (box->focus) - box->active = box->focus->data; - if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE) && - GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_CAN_TAKE_FOCUS)) - break; - } while (box->active != last); -} - -static void -find_prev_focus(GntBox *box) -{ - gpointer last = box->active; - - if (!box->focus) - return; - - do - { - GList *iter = g_list_find(box->focus, box->active); - if (!iter) - box->active = box->focus->data; - else if (!iter->prev) - box->active = g_list_last(box->focus)->data; - else - box->active = iter->prev->data; - if (!GNT_WIDGET_IS_FLAG_SET(box->active, GNT_WIDGET_INVISIBLE)) - break; - } while (box->active != last); -} - -static gboolean -gnt_box_key_pressed(GntWidget *widget, const char *text) -{ - GntBox *box = GNT_BOX(widget); - gboolean ret; - - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DISABLE_ACTIONS)) - return FALSE; - - if (box->active == NULL && !find_focusable_widget(box)) - return FALSE; - - if (gnt_widget_key_pressed(box->active, text)) - return TRUE; - - /* This dance is necessary to make sure that the child widgets get a chance - to trigger their bindings first */ - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DISABLE_ACTIONS); - ret = gnt_widget_key_pressed(widget, text); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DISABLE_ACTIONS); - return ret; -} - -static gboolean -box_focus_change(GntBox *box, gboolean next) -{ - GntWidget *now; - now = box->active; - - if (next) { - find_next_focus(box); - } else { - find_prev_focus(box); - } - - if (now && now != box->active) { - gnt_widget_set_focus(now, FALSE); - gnt_widget_set_focus(box->active, TRUE); - return TRUE; - } - - return FALSE; -} - -static gboolean -action_focus_next(GntBindable *bindable, GList *null) -{ - return box_focus_change(GNT_BOX(bindable), TRUE); -} - -static gboolean -action_focus_prev(GntBindable *bindable, GList *null) -{ - return box_focus_change(GNT_BOX(bindable), FALSE); -} - -static void -gnt_box_lost_focus(GntWidget *widget) -{ - GntWidget *w = GNT_BOX(widget)->active; - if (w) - gnt_widget_set_focus(w, FALSE); - gnt_widget_draw(widget); -} - -static void -gnt_box_gained_focus(GntWidget *widget) -{ - GntWidget *w = GNT_BOX(widget)->active; - if (w) - gnt_widget_set_focus(w, TRUE); - gnt_widget_draw(widget); -} - -static void -gnt_box_destroy(GntWidget *w) -{ - GntBox *box = GNT_BOX(w); - - gnt_box_remove_all(box); - gnt_screen_release(w); -} - -static void -gnt_box_expose(GntWidget *widget, int x, int y, int width, int height) -{ - WINDOW *win = newwin(height, width, widget->priv.y + y, widget->priv.x + x); - copywin(widget->window, win, y, x, 0, 0, height - 1, width - 1, FALSE); - wrefresh(win); - delwin(win); -} - -static gboolean -gnt_box_confirm_size(GntWidget *widget, int width, int height) -{ - GList *iter; - GntBox *box = GNT_BOX(widget); - int wchange, hchange; - GntWidget *child, *last; - - if (!box->list) - return TRUE; - - wchange = widget->priv.width - width; - hchange = widget->priv.height - height; - - if (wchange == 0 && hchange == 0) - return TRUE; /* Quit playing games with my size */ - - child = NULL; - last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S); - - /* First, make sure all the widgets will fit into the box after resizing. */ - for (iter = box->list; iter; iter = iter->next) { - GntWidget *wid = iter->data; - int w, h; - - gnt_widget_get_size(wid, &w, &h); - - if (wid != last && !child && w > 0 && h > 0 && - !GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_INVISIBLE) && - gnt_widget_confirm_size(wid, w - wchange, h - hchange)) { - child = wid; - break; - } - } - - if (!child && (child = last)) { - int w, h; - gnt_widget_get_size(child, &w, &h); - if (!gnt_widget_confirm_size(child, w - wchange, h - hchange)) - child = NULL; - } - - g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child); - - if (child) { - for (iter = box->list; iter; iter = iter->next) { - GntWidget *wid = iter->data; - int w, h; - - if (wid == child) - continue; - - gnt_widget_get_size(wid, &w, &h); - if (box->vertical) { - /* For a vertical box, if we are changing the width, make sure the widgets - * in the box will fit after resizing the width. */ - if (wchange > 0 && - w >= child->priv.width && - !gnt_widget_confirm_size(wid, w - wchange, h)) - return FALSE; - } else { - /* If we are changing the height, make sure the widgets in the box fit after - * the resize. */ - if (hchange > 0 && - h >= child->priv.height && - !gnt_widget_confirm_size(wid, w, h - hchange)) - return FALSE; - } - - } - } - - return (child != NULL); -} - -static void -gnt_box_size_changed(GntWidget *widget, int oldw, int oldh) -{ - int wchange, hchange; - GList *i; - GntBox *box = GNT_BOX(widget); - GntWidget *wid; - int tw, th; - - wchange = widget->priv.width - oldw; - hchange = widget->priv.height - oldh; - - wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S); - if (wid) { - gnt_widget_get_size(wid, &tw, &th); - gnt_widget_set_size(wid, tw + wchange, th + hchange); - g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL); - g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid); - } - - if (box->vertical) - hchange = 0; - else - wchange = 0; - - for (i = box->list; i; i = i->next) - { - if (wid != i->data) - { - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); - gnt_widget_set_size(i->data, tw + wchange, th + hchange); - } - } - - reposition_children(widget); -} - -static gboolean -gnt_box_clicked(GntWidget *widget, GntMouseEvent event, int cx, int cy) -{ - GList *iter; - for (iter = GNT_BOX(widget)->list; iter; iter = iter->next) { - int x, y, w, h; - GntWidget *wid = iter->data; - - gnt_widget_get_position(wid, &x, &y); - gnt_widget_get_size(wid, &w, &h); - - if (cx >= x && cx < x + w && cy >= y && cy < y + h) { - if (event <= GNT_MIDDLE_MOUSE_DOWN && - GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_CAN_TAKE_FOCUS)) { - while (widget->parent) - widget = widget->parent; - gnt_box_give_focus_to_child(GNT_BOX(widget), wid); - } - return gnt_widget_clicked(wid, event, cx, cy); - } - } - return FALSE; -} - -static void -gnt_box_set_property(GObject *obj, guint prop_id, const GValue *value, - GParamSpec *spec) -{ - GntBox *box = GNT_BOX(obj); - switch (prop_id) { - case PROP_VERTICAL: - box->vertical = g_value_get_boolean(value); - break; - case PROP_HOMO: - box->homogeneous = g_value_get_boolean(value); - break; - default: - g_return_if_reached(); - break; - } -} - -static void -gnt_box_get_property(GObject *obj, guint prop_id, GValue *value, - GParamSpec *spec) -{ - GntBox *box = GNT_BOX(obj); - switch (prop_id) { - case PROP_VERTICAL: - g_value_set_boolean(value, box->vertical); - break; - case PROP_HOMO: - g_value_set_boolean(value, box->homogeneous); - break; - default: - break; - } -} - -static void -gnt_box_class_init(GntBoxClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - GObjectClass *gclass = G_OBJECT_CLASS(klass); - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->destroy = gnt_box_destroy; - parent_class->draw = gnt_box_draw; - parent_class->expose = gnt_box_expose; - parent_class->map = gnt_box_map; - parent_class->size_request = gnt_box_size_request; - parent_class->set_position = gnt_box_set_position; - parent_class->key_pressed = gnt_box_key_pressed; - parent_class->clicked = gnt_box_clicked; - parent_class->lost_focus = gnt_box_lost_focus; - parent_class->gained_focus = gnt_box_gained_focus; - parent_class->confirm_size = gnt_box_confirm_size; - parent_class->size_changed = gnt_box_size_changed; - - gclass->set_property = gnt_box_set_property; - gclass->get_property = gnt_box_get_property; - g_object_class_install_property(gclass, - PROP_VERTICAL, - g_param_spec_boolean("vertical", "Vertical", - "Whether the child widgets in the box should be stacked vertically.", - TRUE, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - g_object_class_install_property(gclass, - PROP_HOMO, - g_param_spec_boolean("homogeneous", "Homogeneous", - "Whether the child widgets in the box should have the same size.", - TRUE, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - - gnt_bindable_class_register_action(bindable, "focus-next", action_focus_next, - "\t", NULL); - gnt_bindable_register_binding(bindable, "focus-next", GNT_KEY_RIGHT, NULL); - gnt_bindable_class_register_action(bindable, "focus-prev", action_focus_prev, - GNT_KEY_BACK_TAB, NULL); - gnt_bindable_register_binding(bindable, "focus-prev", GNT_KEY_LEFT, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable); -} - -static void -gnt_box_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntBox *box = GNT_BOX(widget); - /* Initially make both the height and width resizable. - * Update the flags as necessary when widgets are added to it. */ - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_DISABLE_ACTIONS); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - box->pad = 1; - box->fill = TRUE; - GNTDEBUG; -} - -/****************************************************************************** - * GntBox API - *****************************************************************************/ -GType -gnt_box_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntBoxClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_box_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntBox), - 0, /* n_preallocs */ - gnt_box_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntBox", - &info, 0); - } - - return type; -} - -GntWidget *gnt_box_new(gboolean homo, gboolean vert) -{ - GntWidget *widget = g_object_new(GNT_TYPE_BOX, NULL); - GntBox *box = GNT_BOX(widget); - - box->homogeneous = homo; - box->vertical = vert; - box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID; - - return widget; -} - -void gnt_box_add_widget(GntBox *b, GntWidget *widget) -{ - b->list = g_list_append(b->list, widget); - widget->parent = GNT_WIDGET(b); -} - -void gnt_box_set_title(GntBox *b, const char *title) -{ - char *prev = b->title; - GntWidget *w = GNT_WIDGET(b); - b->title = g_strdup(title); - if (w->window && !GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_NO_BORDER)) { - /* Erase the old title */ - int pos, right; - get_title_thingies(b, prev, &pos, &right); - mvwhline(w->window, 0, pos - 1, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), - right - pos + 2); - } - g_free(prev); -} - -void gnt_box_set_pad(GntBox *box, int pad) -{ - box->pad = pad; - /* XXX: Perhaps redraw if already showing? */ -} - -void gnt_box_set_toplevel(GntBox *box, gboolean set) -{ - GntWidget *widget = GNT_WIDGET(box); - if (set) - { - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); - } - else - { - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); - } -} - -void gnt_box_sync_children(GntBox *box) -{ - GList *iter; - GntWidget *widget = GNT_WIDGET(box); - int pos = 1; - - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - pos = 0; - - if (!box->active) - find_focusable_widget(box); - - for (iter = box->list; iter; iter = iter->next) - { - GntWidget *w = GNT_WIDGET(iter->data); - int height, width; - int x, y; - - if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_INVISIBLE)) - continue; - - if (GNT_IS_BOX(w)) - gnt_box_sync_children(GNT_BOX(w)); - - gnt_widget_get_size(w, &width, &height); - - x = w->priv.x - widget->priv.x; - y = w->priv.y - widget->priv.y; - - if (box->vertical) - { - x = pos; - if (box->alignment == GNT_ALIGN_RIGHT) - x += widget->priv.width - width; - else if (box->alignment == GNT_ALIGN_MID) - x += (widget->priv.width - width)/2; - if (x + width > widget->priv.width - pos) - x -= x + width - (widget->priv.width - pos); - } - else - { - y = pos; - if (box->alignment == GNT_ALIGN_BOTTOM) - y += widget->priv.height - height; - else if (box->alignment == GNT_ALIGN_MID) - y += (widget->priv.height - height)/2; - if (y + height >= widget->priv.height - pos) - y = widget->priv.height - height - pos; - } - - copywin(w->window, widget->window, 0, 0, - y, x, y + height - 1, x + width - 1, FALSE); - gnt_widget_set_position(w, x + widget->priv.x, y + widget->priv.y); - if (w == box->active) { - wmove(widget->window, y + getcury(w->window), x + getcurx(w->window)); - } - } -} - -void gnt_box_set_alignment(GntBox *box, GntAlignment alignment) -{ - box->alignment = alignment; -} - -void gnt_box_remove(GntBox *box, GntWidget *widget) -{ - box->list = g_list_remove(box->list, widget); - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS) - && GNT_WIDGET(box)->parent == NULL && box->focus) - { - if (widget == box->active) - { - find_next_focus(box); - if (box->active == widget) /* There's only one widget */ - box->active = NULL; - } - box->focus = g_list_remove(box->focus, widget); - } - - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(box), GNT_WIDGET_MAPPED)) - gnt_widget_draw(GNT_WIDGET(box)); -} - -void gnt_box_remove_all(GntBox *box) -{ - g_list_foreach(box->list, (GFunc)gnt_widget_destroy, NULL); - g_list_free(box->list); - g_list_free(box->focus); - box->list = NULL; - box->focus = NULL; - GNT_WIDGET(box)->priv.width = 0; - GNT_WIDGET(box)->priv.height = 0; -} - -void gnt_box_readjust(GntBox *box) -{ - GList *iter; - GntWidget *wid; - int width, height; - - if (GNT_WIDGET(box)->parent != NULL) - return; - - for (iter = box->list; iter; iter = iter->next) - { - GntWidget *w = iter->data; - if (GNT_IS_BOX(w)) - gnt_box_readjust(GNT_BOX(w)); - else - { - GNT_WIDGET_UNSET_FLAGS(w, GNT_WIDGET_MAPPED); - w->priv.width = 0; - w->priv.height = 0; - } - } - - wid = GNT_WIDGET(box); - GNT_WIDGET_UNSET_FLAGS(wid, GNT_WIDGET_MAPPED); - wid->priv.width = 0; - wid->priv.height = 0; - - if (wid->parent == NULL) - { - g_list_free(box->focus); - box->focus = NULL; - box->active = NULL; - gnt_widget_size_request(wid); - gnt_widget_get_size(wid, &width, &height); - gnt_screen_resize_widget(wid, width, height); - find_focusable_widget(box); - } -} - -void gnt_box_set_fill(GntBox *box, gboolean fill) -{ - box->fill = fill; -} - -void gnt_box_move_focus(GntBox *box, int dir) -{ - GntWidget *now; - - if (box->active == NULL) - { - find_focusable_widget(box); - return; - } - - now = box->active; - - if (dir == 1) - find_next_focus(box); - else if (dir == -1) - find_prev_focus(box); - - if (now && now != box->active) - { - gnt_widget_set_focus(now, FALSE); - gnt_widget_set_focus(box->active, TRUE); - } - - if (GNT_WIDGET(box)->window) - gnt_widget_draw(GNT_WIDGET(box)); -} - -void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget) -{ - GList *find; - gpointer now; - - while (GNT_WIDGET(box)->parent) - box = GNT_BOX(GNT_WIDGET(box)->parent); - - find = g_list_find(box->focus, widget); - now = box->active; - if (find) - box->active = widget; - if (now && now != box->active) - { - gnt_widget_set_focus(now, FALSE); - gnt_widget_set_focus(box->active, TRUE); - } - - if (GNT_WIDGET(box)->window) - gnt_widget_draw(GNT_WIDGET(box)); -} -
--- a/finch/libgnt/gntbox.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -/** - * @file gntbox.h Box API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_BOX_H -#define GNT_BOX_H - -#include "gnt.h" -#include "gntwidget.h" - -#define GNT_TYPE_BOX (gnt_box_get_gtype()) -#define GNT_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BOX, GntBox)) -#define GNT_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BOX, GntBoxClass)) -#define GNT_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BOX)) -#define GNT_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BOX)) -#define GNT_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BOX, GntBoxClass)) - -typedef struct _GntBox GntBox; -typedef struct _GntBoxClass GntBoxClass; - -typedef enum -{ - /* These for vertical boxes */ - GNT_ALIGN_LEFT, - GNT_ALIGN_RIGHT, - - GNT_ALIGN_MID, - - /* These for horizontal boxes */ - GNT_ALIGN_TOP, - GNT_ALIGN_BOTTOM -} GntAlignment; - -struct _GntBox -{ - GntWidget parent; - - gboolean vertical; - gboolean homogeneous; - gboolean fill; - GList *list; /* List of widgets */ - - GntWidget *active; - int pad; /* Number of spaces to use between widgets */ - GntAlignment alignment; /* How are the widgets going to be aligned? */ - - char *title; - GList *focus; /* List of widgets to cycle focus (only valid for parent boxes) */ - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -struct _GntBoxClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * The GType for GntBox. - * @return The GType. - */ -GType gnt_box_get_gtype(void); - -#define gnt_vbox_new(homo) gnt_box_new(homo, TRUE) -#define gnt_hbox_new(homo) gnt_box_new(homo, FALSE) - -/** - * Create a new GntBox. - * - * @param homo If @c TRUE, all the widgets in it will have the same width (or height) - * @param vert Whether the widgets in it should be stacked vertically (if @c TRUE) - * or horizontally (if @c FALSE). - * - * @return The new GntBox. - */ -GntWidget * gnt_box_new(gboolean homo, gboolean vert); - -/** - * Add a widget in the box. - * - * @param box The box - * @param widget The widget to add - */ -void gnt_box_add_widget(GntBox *box, GntWidget *widget); - -/** - * Set a title for the box. - * - * @param box The box - * @param title The title to set - */ -void gnt_box_set_title(GntBox *box, const char *title); - -/** - * Set the padding to use between the widgets in the box. - * - * @param box The box - * @param pad The padding to use - */ -void gnt_box_set_pad(GntBox *box, int pad); - -/** - * Set whether it's a toplevel box (ie, a window) or not. If a box is toplevel, - * then it will show borders, the title (if set) and shadow (if enabled in - * @e .gntrc) - * - * @param box The box - * @param set @c TRUE if it's a toplevel box, @c FALSE otherwise. - */ -void gnt_box_set_toplevel(GntBox *box, gboolean set); - -/** - * Reposition and refresh the widgets in the box. - * - * @param box The box - */ -void gnt_box_sync_children(GntBox *box); - -/** - * Set the alignment for the widgets in the box. - * - * @param box The box - * @param alignment The alignment to use - */ -void gnt_box_set_alignment(GntBox *box, GntAlignment alignment); - -/** - * Remove a widget from the box. Calling this does NOT destroy the removed widget. - * - * @param box The box - * @param widget The widget to remove - */ -void gnt_box_remove(GntBox *box, GntWidget *widget); - -/** - * Remove all widgets from the box. This DOES destroy all widgets in the box. - * - * @param box The box - */ -void gnt_box_remove_all(GntBox *box); - -/** - * Readjust the size of each child widget, reposition the child widgets and - * recalculate the size of the box. - * - * @param box The box - */ -void gnt_box_readjust(GntBox *box); - -/** - * Set whether the widgets in the box should fill the empty spaces. - * - * @param box The box - * @param fill Whether the child widgets should fill the empty space - */ -void gnt_box_set_fill(GntBox *box, gboolean fill); - -/** - * Move the focus from one widget to the other. - * - * @param box The box - * @param dir The direction. If it's 1, then the focus is moved forwards, if it's - * -1, the focus is moved backwards. - */ -void gnt_box_move_focus(GntBox *box, int dir); - -/** - * Give focus to a specific child widget. - * - * @param box The box - * @param widget The child widget to give focus - */ -void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget); - -G_END_DECLS - -#endif /* GNT_BOX_H */ -
--- a/finch/libgnt/gntbutton.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include <stdlib.h> -#include <string.h> - -#include "gntinternal.h" -#include "gntbutton.h" -#include "gntstyle.h" -#include "gntutils.h" - -enum -{ - SIGS = 1, -}; - -static GntWidgetClass *parent_class = NULL; -static gboolean small_button = FALSE; - -static void -gnt_button_draw(GntWidget *widget) -{ - GntButton *button = GNT_BUTTON(widget); - GntColorType type; - gboolean focus; - - if ((focus = gnt_widget_has_focus(widget))) - type = GNT_COLOR_HIGHLIGHT; - else - type = GNT_COLOR_NORMAL; - - wbkgdset(widget->window, '\0' | gnt_color_pair(type)); - mvwaddstr(widget->window, (small_button) ? 0 : 1, 2, C_(button->priv->text)); - if (small_button) { - type = GNT_COLOR_HIGHLIGHT; - mvwchgat(widget->window, 0, 0, widget->priv.width, focus ? A_BOLD : A_REVERSE, type, NULL); - } - - GNTDEBUG; -} - -static void -gnt_button_size_request(GntWidget *widget) -{ - GntButton *button = GNT_BUTTON(widget); - gnt_util_get_text_bound(button->priv->text, - &widget->priv.width, &widget->priv.height); - widget->priv.width += 4; - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - widget->priv.height += 2; -} - -static void -gnt_button_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static gboolean -gnt_button_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - if (event == GNT_LEFT_MOUSE_DOWN) { - gnt_widget_activate(widget); - return TRUE; - } - return FALSE; -} - -static void -gnt_button_destroy(GntWidget *widget) -{ - GntButton *button = GNT_BUTTON(widget); - g_free(button->priv->text); - g_free(button->priv); -} - -static gboolean -button_activate(GntBindable *bind, GList *null) -{ - gnt_widget_activate(GNT_WIDGET(bind)); - return TRUE; -} - -static void -gnt_button_class_init(GntWidgetClass *klass) -{ - char *style; - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->draw = gnt_button_draw; - parent_class->map = gnt_button_map; - parent_class->size_request = gnt_button_size_request; - parent_class->clicked = gnt_button_clicked; - parent_class->destroy = gnt_button_destroy; - - style = gnt_style_get_from_name(NULL, "small-button"); - small_button = gnt_style_parse_bool(style); - g_free(style); - - gnt_bindable_class_register_action(bindable, "activate", button_activate, - GNT_KEY_ENTER, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); -} - -static void -gnt_button_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntButton *button = GNT_BUTTON(instance); - button->priv = g_new0(GntButtonPriv, 1); - - widget->priv.minw = 4; - widget->priv.minh = small_button ? 1 : 3; - if (small_button) - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y); - GNTDEBUG; -} - -/****************************************************************************** - * GntButton API - *****************************************************************************/ -GType -gnt_button_get_gtype(void) { - static GType type = 0; - - if(type == 0) { - static const GTypeInfo info = { - sizeof(GntButtonClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_button_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntButton), - 0, /* n_preallocs */ - gnt_button_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntButton", - &info, 0); - } - - return type; -} - -GntWidget *gnt_button_new(const char *text) -{ - GntWidget *widget = g_object_new(GNT_TYPE_BUTTON, NULL); - GntButton *button = GNT_BUTTON(widget); - - button->priv->text = gnt_util_onscreen_fit_string(text, -1); - gnt_widget_set_take_focus(widget, TRUE); - - return widget; -} -
--- a/finch/libgnt/gntbutton.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/** - * @file gntbutton.h Button API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_BUTTON_H -#define GNT_BUTTON_H - -#include <glib.h> -#include <glib-object.h> -#include "gnt.h" -#include "gntwidget.h" - -#define GNT_TYPE_BUTTON (gnt_button_get_gtype()) -#define GNT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BUTTON, GntButton)) -#define GNT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BUTTON, GntButtonClass)) -#define GNT_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_BUTTON)) -#define GNT_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_BUTTON)) -#define GNT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_BUTTON, GntButtonClass)) - -typedef struct _GntButton GntButton; -typedef struct _GntButtonPriv GntButtonPriv; -typedef struct _GntButtonClass GntButtonClass; - -struct _GntButtonPriv -{ - char *text; -}; - -struct _GntButton -{ - GntWidget parent; - - GntButtonPriv *priv; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -struct _GntButtonClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for Gntbutton - */ -GType gnt_button_get_gtype(void); - -/** - * Create a new button. - * - * @param text The text for the button. - * - * @return The newly created button. - */ -GntWidget * gnt_button_new(const char *text); - -G_END_DECLS - -#endif /* GNT_BUTTON_H */
--- a/finch/libgnt/gntcheckbox.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntcheckbox.h" - -enum -{ - SIG_TOGGLED = 1, - SIGS, -}; - -static GntButtonClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; - -static void -gnt_check_box_draw(GntWidget *widget) -{ - GntCheckBox *cb = GNT_CHECK_BOX(widget); - GntColorType type; - gboolean focus = gnt_widget_has_focus(widget); - - if (focus) - type = GNT_COLOR_HIGHLIGHT; - else - type = GNT_COLOR_NORMAL; - - wbkgdset(widget->window, '\0' | gnt_color_pair(type)); - - mvwaddch(widget->window, 0, 0, '['); - mvwaddch(widget->window, 0, 1, (cb->checked ? 'X' : ' ') | (focus ? A_UNDERLINE : A_NORMAL)); - mvwaddch(widget->window, 0, 2, ']'); - - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddstr(widget->window, 0, 4, C_(GNT_BUTTON(cb)->priv->text)); - (void)wmove(widget->window, 0, 1); - - GNTDEBUG; -} - -static void -toggle_selection(GntWidget *widget) -{ - GNT_CHECK_BOX(widget)->checked = !GNT_CHECK_BOX(widget)->checked; - g_signal_emit(widget, signals[SIG_TOGGLED], 0); - gnt_widget_draw(widget); -} - -static gboolean -gnt_check_box_key_pressed(GntWidget *widget, const char *text) -{ - if (text[0] == ' ' && text[1] == '\0') - { - toggle_selection(widget); - return TRUE; - } - - return FALSE; -} - -static gboolean -gnt_check_box_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - if (event == GNT_LEFT_MOUSE_DOWN) { - toggle_selection(widget); - return TRUE; - } - return FALSE; -} - -static void -gnt_check_box_class_init(GntCheckBoxClass *klass) -{ - GntWidgetClass *wclass = GNT_WIDGET_CLASS(klass); - - parent_class = GNT_BUTTON_CLASS(klass); - /*parent_class->destroy = gnt_check_box_destroy;*/ - wclass->draw = gnt_check_box_draw; - /*parent_class->map = gnt_check_box_map;*/ - /*parent_class->size_request = gnt_check_box_size_request;*/ - wclass->key_pressed = gnt_check_box_key_pressed; - wclass->clicked = gnt_check_box_clicked; - - signals[SIG_TOGGLED] = - g_signal_new("toggled", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntCheckBoxClass, toggled), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - GNTDEBUG; -} - -static void -gnt_check_box_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - widget->priv.minh = 1; - widget->priv.minw = 4; - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNTDEBUG; -} - -/****************************************************************************** - * GntCheckBox API - *****************************************************************************/ -GType -gnt_check_box_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntCheckBoxClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_check_box_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntCheckBox), - 0, /* n_preallocs */ - gnt_check_box_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_BUTTON, - "GntCheckBox", - &info, 0); - } - - return type; -} - -GntWidget *gnt_check_box_new(const char *text) -{ - GntWidget *widget = g_object_new(GNT_TYPE_CHECK_BOX, NULL); - - GNT_BUTTON(widget)->priv->text = g_strdup(text); - gnt_widget_set_take_focus(widget, TRUE); - - return widget; -} - -void gnt_check_box_set_checked(GntCheckBox *box, gboolean set) -{ - if (set != box->checked) - { - box->checked = set; - g_signal_emit(box, signals[SIG_TOGGLED], 0); - } -} - -gboolean gnt_check_box_get_checked(GntCheckBox *box) -{ - return box->checked; -} - - -
--- a/finch/libgnt/gntcheckbox.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/** - * @file gntcheckbox.h Checkbox API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_CHECK_BOX_H -#define GNT_CHECK_BOX_H - -#include "gntbutton.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_CHECK_BOX (gnt_check_box_get_gtype()) -#define GNT_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CHECK_BOX, GntCheckBox)) -#define GNT_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) -#define GNT_IS_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CHECK_BOX)) -#define GNT_IS_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CHECK_BOX)) -#define GNT_CHECK_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) - -#define GNT_CHECK_BOX_FLAGS(obj) (GNT_CHECK_BOX(obj)->priv.flags) -#define GNT_CHECK_BOX_SET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) |= flags) -#define GNT_CHECK_BOX_UNSET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) &= ~(flags)) - -typedef struct _GntCheckBox GntCheckBox; -typedef struct _GntCheckBoxPriv GntCheckBoxPriv; -typedef struct _GntCheckBoxClass GntCheckBoxClass; - -struct _GntCheckBox -{ - GntButton parent; - gboolean checked; -}; - -struct _GntCheckBoxClass -{ - GntButtonClass parent; - - void (*toggled)(void); - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntCheckBox - */ -GType gnt_check_box_get_gtype(void); - -/** - * Create a new checkbox. - * - * @param text The text for the checkbox. - * - * @return The newly created checkbox. - */ -GntWidget * gnt_check_box_new(const char *text); - -/** - * Set whether the checkbox should be checked or not. - * - * @param box The checkbox. - * @param set @c TRUE if the checkbox should be selected, @c FALSE otherwise. - */ -void gnt_check_box_set_checked(GntCheckBox *box, gboolean set); - -/** - * Return the checked state of the checkbox. - * - * @param box The checkbox. - * - * @return @c TRUE if the checkbox is selected, @c FALSE otherwise. - */ -gboolean gnt_check_box_get_checked(GntCheckBox *box); - -G_END_DECLS - -#endif /* GNT_CHECK_BOX_H */
--- a/finch/libgnt/gntclipboard.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntclipboard.h" - -enum { - SIG_CLIPBOARD = 0, - SIGS -}; - -static guint signals[SIGS] = { 0 }; - -static void -gnt_clipboard_class_init(GntClipboardClass *klass) -{ - signals[SIG_CLIPBOARD] = - g_signal_new("clipboard_changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - -} - -/****************************************************************************** - * GntClipboard API - *****************************************************************************/ - -void -gnt_clipboard_set_string(GntClipboard *clipboard, const gchar *string) -{ - g_free(clipboard->string); - clipboard->string = g_strdup(string); - g_signal_emit(clipboard, signals[SIG_CLIPBOARD], 0, clipboard->string); -} - -gchar * -gnt_clipboard_get_string(GntClipboard *clipboard) -{ - return g_strdup(clipboard->string); -} - -static void gnt_clipboard_init(GTypeInstance *instance, gpointer class) { - GntClipboard *clipboard = GNT_CLIPBOARD(instance); - clipboard->string = g_strdup(""); -} - -GType -gnt_clipboard_get_gtype(void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof(GntClipboardClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_clipboard_class_init, - NULL, - NULL, /* class_data */ - sizeof(GntClipboard), - 0, /* n_preallocs */ - gnt_clipboard_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(G_TYPE_OBJECT, - "GntClipboard", - &info, 0); - } - - return type; -}
--- a/finch/libgnt/gntclipboard.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/** - * @file gntclipboard.h Clipboard API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_CLIPBOARD_H -#define GNT_CLIPBOARD_H - -#include <stdio.h> -#include <glib.h> -#include <glib-object.h> - -#define GNT_TYPE_CLIPBOARD (gnt_clipboard_get_gtype()) -#define GNT_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CLIPBOARD, GntClipboard)) -#define GNT_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CLIPBOARD, GntClipboardClass)) -#define GNT_IS_CLIPBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CLIPBOARD)) -#define GNT_IS_CLIPBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CLIPBOARD)) -#define GNT_CLIPBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CLIPBOARD, GntClipboardClass)) - -typedef struct _GntClipboard GntClipboard; -typedef struct _GntClipboardClass GntClipboardClass; - -struct _GntClipboard -{ - GObject inherit; - gchar *string; -}; - -struct _GntClipboardClass -{ - GObjectClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntClipboard. - */ -GType gnt_clipboard_get_gtype(void); - -/** - * Get the current text from the clipboard. - * - * @param clip The clipboard. - * - * @return A copy of the string in the clipboard. The caller should free the - * returned value. - */ -gchar * gnt_clipboard_get_string(GntClipboard *clip); - -/** - * Set the text in the clipboard. - * - * @param clip The clipboard. - * @param string New string for the clipboard. - */ -void gnt_clipboard_set_string(GntClipboard *clip, const gchar *string); - -G_END_DECLS - -#endif
--- a/finch/libgnt/gntcolors.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,309 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "config.h" - -#include <ncurses.h> - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Colors" - -#include "gntcolors.h" -#include "gntstyle.h" - -#include <glib.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -static gboolean hascolors; -static int custom_type = GNT_COLORS; -static struct -{ - short r, g, b; -} colors[GNT_TOTAL_COLORS]; - -static void -backup_colors(void) -{ - short i; - for (i = 0; i < GNT_TOTAL_COLORS; i++) - { - color_content(i, &colors[i].r, - &colors[i].g, &colors[i].b); - } -} - -static gboolean -can_use_custom_color(void) -{ - return (gnt_style_get_bool(GNT_STYLE_COLOR, FALSE) && can_change_color()); -} - -static void -restore_colors(void) -{ - short i; - for (i = 0; i < GNT_TOTAL_COLORS; i++) - { - init_color(i, colors[i].r, - colors[i].g, colors[i].b); - } -} - -void gnt_init_colors() -{ - static gboolean init = FALSE; - int defaults; - - if (init) - return; - init = TRUE; - - start_color(); - if (!(hascolors = has_colors())) - return; - defaults = use_default_colors(); - - if (can_use_custom_color()) - { - backup_colors(); - - /* Do some init_color()s */ - init_color(GNT_COLOR_BLACK, 0, 0, 0); - init_color(GNT_COLOR_RED, 1000, 0, 0); - init_color(GNT_COLOR_GREEN, 0, 1000, 0); - init_color(GNT_COLOR_BLUE, 250, 250, 700); - init_color(GNT_COLOR_WHITE, 1000, 1000, 1000); - init_color(GNT_COLOR_GRAY, 699, 699, 699); - init_color(GNT_COLOR_DARK_GRAY, 256, 256, 256); - - /* Now some init_pair()s */ - init_pair(GNT_COLOR_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_WHITE); - init_pair(GNT_COLOR_HIGHLIGHT, GNT_COLOR_WHITE, GNT_COLOR_BLUE); - init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY); - - init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_BLUE); - init_pair(GNT_COLOR_TITLE_D, GNT_COLOR_WHITE, GNT_COLOR_GRAY); - - init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_WHITE, GNT_COLOR_BLUE); - init_pair(GNT_COLOR_HIGHLIGHT_D, GNT_COLOR_BLACK, GNT_COLOR_GRAY); - init_pair(GNT_COLOR_DISABLED, GNT_COLOR_GRAY, GNT_COLOR_WHITE); - init_pair(GNT_COLOR_URGENT, GNT_COLOR_WHITE, GNT_COLOR_RED); - } - else - { - int bg; - - if (defaults == OK) { - init_pair(GNT_COLOR_NORMAL, -1, -1); - bg = -1; - } else { - init_pair(GNT_COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); - bg = COLOR_WHITE; - } - init_pair(GNT_COLOR_DISABLED, COLOR_YELLOW, bg); - init_pair(GNT_COLOR_URGENT, COLOR_GREEN, bg); - - init_pair(GNT_COLOR_HIGHLIGHT, COLOR_WHITE, COLOR_BLUE); - init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK); - init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLUE); - init_pair(GNT_COLOR_TITLE_D, COLOR_WHITE, COLOR_BLACK); - init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_WHITE, COLOR_BLUE); - init_pair(GNT_COLOR_HIGHLIGHT_D, COLOR_CYAN, COLOR_BLACK); - } -} - -void -gnt_uninit_colors() -{ - if (can_use_custom_color()) - restore_colors(); -} - -#if GLIB_CHECK_VERSION(2,6,0) -int -gnt_colors_get_color(char *key) -{ - int color; - gboolean custom = can_use_custom_color(); - - key = g_strstrip(key); - - if (strcmp(key, "black") == 0) - color = custom ? GNT_COLOR_BLACK : COLOR_BLACK; - else if (strcmp(key, "red") == 0) - color = custom ? GNT_COLOR_RED : COLOR_RED; - else if (strcmp(key, "green") == 0) - color = custom ? GNT_COLOR_GREEN : COLOR_GREEN; - else if (strcmp(key, "blue") == 0) - color = custom ? GNT_COLOR_BLUE : COLOR_BLUE; - else if (strcmp(key, "white") == 0) - color = custom ? GNT_COLOR_WHITE : COLOR_WHITE; - else if (strcmp(key, "gray") == 0 || strcmp(key, "grey") == 0) - color = custom ? GNT_COLOR_GRAY : COLOR_YELLOW; /* eh? */ - else if (strcmp(key, "darkgray") == 0 || strcmp(key, "darkgrey") == 0) - color = custom ? GNT_COLOR_DARK_GRAY : COLOR_BLACK; - else if (strcmp(key, "magenta") == 0) - color = COLOR_MAGENTA; - else if (strcmp(key, "cyan") == 0) - color = COLOR_CYAN; - else if (strcmp(key, "default") == 0) - color = -1; - else { - g_warning("Invalid color name: %s\n", key); - color = -EINVAL; - } - return color; -} - -void gnt_colors_parse(GKeyFile *kfile) -{ - GError *error = NULL; - gsize nkeys; - char **keys = g_key_file_get_keys(kfile, "colors", &nkeys, &error); - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - error = NULL; - } - else if (nkeys) - { - gnt_init_colors(); - while (nkeys--) - { - gsize len; - gchar *key = keys[nkeys]; - char **list = g_key_file_get_string_list(kfile, "colors", key, &len, NULL); - if (len == 3) - { - int r = atoi(list[0]); - int g = atoi(list[1]); - int b = atoi(list[2]); - int color = -1; - - key = g_ascii_strdown(key, -1); - color = gnt_colors_get_color(key); - g_free(key); - if (color == -EINVAL) { - g_strfreev(list); - continue; - } - - init_color(color, r, g, b); - } - g_strfreev(list); - } - - g_strfreev(keys); - } - - gnt_color_pairs_parse(kfile); -} - -void gnt_color_pairs_parse(GKeyFile *kfile) -{ - GError *error = NULL; - gsize nkeys; - char **keys = g_key_file_get_keys(kfile, "colorpairs", &nkeys, &error); - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - return; - } - else if (nkeys) - gnt_init_colors(); - - while (nkeys--) - { - gsize len; - gchar *key = keys[nkeys]; - char **list = g_key_file_get_string_list(kfile, "colorpairs", key, &len, NULL); - if (len == 2) - { - GntColorType type = 0; - gchar *fgc = g_ascii_strdown(list[0], -1); - gchar *bgc = g_ascii_strdown(list[1], -1); - int fg = gnt_colors_get_color(fgc); - int bg = gnt_colors_get_color(bgc); - g_free(fgc); - g_free(bgc); - if (fg == -EINVAL || bg == -EINVAL) { - g_strfreev(list); - continue; - } - - key = g_ascii_strdown(key, -1); - - if (strcmp(key, "normal") == 0) - type = GNT_COLOR_NORMAL; - else if (strcmp(key, "highlight") == 0) - type = GNT_COLOR_HIGHLIGHT; - else if (strcmp(key, "highlightd") == 0) - type = GNT_COLOR_HIGHLIGHT_D; - else if (strcmp(key, "shadow") == 0) - type = GNT_COLOR_SHADOW; - else if (strcmp(key, "title") == 0) - type = GNT_COLOR_TITLE; - else if (strcmp(key, "titled") == 0) - type = GNT_COLOR_TITLE_D; - else if (strcmp(key, "text") == 0) - type = GNT_COLOR_TEXT_NORMAL; - else if (strcmp(key, "disabled") == 0) - type = GNT_COLOR_DISABLED; - else if (strcmp(key, "urgent") == 0) - type = GNT_COLOR_URGENT; - else { - g_strfreev(list); - g_free(key); - continue; - } - g_free(key); - - init_pair(type, fg, bg); - } - g_strfreev(list); - } - - g_strfreev(keys); -} - -#endif /* GKeyFile */ - -int gnt_color_pair(int pair) -{ - return (hascolors ? COLOR_PAIR(pair) : - ((pair == GNT_COLOR_NORMAL || pair == GNT_COLOR_HIGHLIGHT_D || - pair == GNT_COLOR_TITLE_D || pair == GNT_COLOR_DISABLED) ? 0 : (int)A_STANDOUT)); -} - -int gnt_color_add_pair(int fg, int bg) -{ - init_pair(custom_type, fg, bg); - return custom_type++; -}
--- a/finch/libgnt/gntcolors.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/** - * @file gntcolors.h Colors API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_COLORS_H -#define GNT_COLORS_H - -#include <glib.h> - -/** - * Different classes of colors. - */ -typedef enum -{ - GNT_COLOR_NORMAL = 1, - GNT_COLOR_HIGHLIGHT, /* eg. when a button is selected */ - GNT_COLOR_DISABLED, /* eg. when a button is disabled */ - GNT_COLOR_HIGHLIGHT_D, /* eg. when a button is selected, but some other window is in focus */ - GNT_COLOR_TEXT_NORMAL, - GNT_COLOR_TEXT_INACTIVE, /* when the entry is out of focus */ - GNT_COLOR_MNEMONIC, - GNT_COLOR_MNEMONIC_D, - GNT_COLOR_SHADOW, - GNT_COLOR_TITLE, - GNT_COLOR_TITLE_D, - GNT_COLOR_URGENT, /* this is for the 'urgent' windows */ - GNT_COLORS -} GntColorType; - -enum -{ - GNT_COLOR_BLACK = 0, - GNT_COLOR_RED, - GNT_COLOR_GREEN, - GNT_COLOR_BLUE, - GNT_COLOR_WHITE, - GNT_COLOR_GRAY, - GNT_COLOR_DARK_GRAY, - GNT_TOTAL_COLORS -}; - -/** - * Initialize the colors. - */ -void gnt_init_colors(void); - -/** - * Uninitialize the colors. - */ -void gnt_uninit_colors(void); - -#if GLIB_CHECK_VERSION(2,6,0) -/** - * Parse color information from a file. - * - * @param kfile The file containing color information. - */ -void gnt_colors_parse(GKeyFile *kfile); - -/** - * Parse color-pair information from a file. - * - * @param kfile The file containing the color-pair information. - */ -void gnt_color_pairs_parse(GKeyFile *kfile); - -/** - * Parse a string color - * - * @param kfile The string value - * - * @return A color. For an unknown color name, returns -EINVAL. - * - * @since 2.4.0 - */ -int gnt_colors_get_color(char *key); -#endif - -/** - * Return the appropriate character attribute for a specified color. - * If the terminal doesn't have color support, this returns A_STANDOUT - * when deemed appropriate. - * - * @param color The color code. - * - * @return A character attribute. - * - * @since 2.3.0 - */ -int gnt_color_pair(int color); - -/** - * Adds a color definition - * - * @param fg Foreground - * @param bg Background - * - * @return A color pair - * - * @since 2.4.0 - */ -int gnt_color_add_pair(int fg, int bg); -#endif
--- a/finch/libgnt/gntcombobox.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntbox.h" -#include "gntcombobox.h" -#include "gnttree.h" -#include "gntmarshal.h" -#include "gntstyle.h" -#include "gntutils.h" - -#include <string.h> - -enum -{ - SIG_SELECTION_CHANGED, - SIGS, -}; - -static GntWidgetClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; -static void (*widget_lost_focus)(GntWidget *widget); - -static void -set_selection(GntComboBox *box, gpointer key) -{ - if (box->selected != key) - { - /* XXX: make sure the key actually does exist */ - gpointer old = box->selected; - box->selected = key; - if (GNT_WIDGET(box)->window) - gnt_widget_draw(GNT_WIDGET(box)); - if (box->dropdown) - gnt_tree_set_selected(GNT_TREE(box->dropdown), key); - g_signal_emit(box, signals[SIG_SELECTION_CHANGED], 0, old, key); - } -} - -static void -hide_popup(GntComboBox *box, gboolean set) -{ - gnt_widget_set_size(box->dropdown, - box->dropdown->priv.width - 1, box->dropdown->priv.height); - if (set) - set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); - else - gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected); - gnt_widget_hide(box->dropdown->parent); -} - -static void -gnt_combo_box_draw(GntWidget *widget) -{ - GntComboBox *box = GNT_COMBO_BOX(widget); - char *text = NULL, *s; - GntColorType type; - int len; - - if (box->dropdown && box->selected) - text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); - - if (text == NULL) - text = g_strdup(""); - - if (gnt_widget_has_focus(widget)) - type = GNT_COLOR_HIGHLIGHT; - else - type = GNT_COLOR_NORMAL; - - wbkgdset(widget->window, '\0' | gnt_color_pair(type)); - - s = (char*)gnt_util_onscreen_width_to_pointer(text, widget->priv.width - 4, &len); - *s = '\0'; - - mvwaddstr(widget->window, 1, 1, C_(text)); - whline(widget->window, ' ' | gnt_color_pair(type), widget->priv.width - 4 - len); - mvwaddch(widget->window, 1, widget->priv.width - 3, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddch(widget->window, 1, widget->priv.width - 2, ACS_DARROW | gnt_color_pair(GNT_COLOR_NORMAL)); - (void)wmove(widget->window, 1, 1); - - g_free(text); - GNTDEBUG; -} - -static void -gnt_combo_box_size_request(GntWidget *widget) -{ - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - { - GntWidget *dd = GNT_COMBO_BOX(widget)->dropdown; - gnt_widget_size_request(dd); - widget->priv.height = 3; /* For now, a combobox will have border */ - widget->priv.width = MAX(10, dd->priv.width + 2); - } -} - -static void -gnt_combo_box_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static void -popup_dropdown(GntComboBox *box) -{ - GntWidget *widget = GNT_WIDGET(box); - GntWidget *parent = box->dropdown->parent; - int height = g_list_length(GNT_TREE(box->dropdown)->list); - int y = widget->priv.y + widget->priv.height - 1; - gnt_widget_set_size(box->dropdown, widget->priv.width, height + 2); - - if (y + height + 2 >= getmaxy(stdscr)) - y = widget->priv.y - height - 1; - gnt_widget_set_position(parent, widget->priv.x, y); - if (parent->window) - { - mvwin(parent->window, y, widget->priv.x); - wresize(parent->window, height+2, widget->priv.width); - } - parent->priv.width = widget->priv.width; - parent->priv.height = height + 2; - - GNT_WIDGET_UNSET_FLAGS(parent, GNT_WIDGET_INVISIBLE); - gnt_widget_draw(parent); -} - -static gboolean -gnt_combo_box_key_pressed(GntWidget *widget, const char *text) -{ - GntComboBox *box = GNT_COMBO_BOX(widget); - gboolean showing = !!GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED); - - if (showing) { - if (text[1] == 0) { - switch (text[0]) { - case '\r': - case '\t': - case '\n': - hide_popup(box, TRUE); - return TRUE; - case 27: - hide_popup(box, FALSE); - return TRUE; - } - } - } - - if (gnt_widget_key_pressed(box->dropdown, text)) { - if (!showing) - popup_dropdown(box); - return TRUE; - } - - { -#define SEARCH_IN_RANGE(start, end) do { \ - GntTreeRow *row; \ - for (row = start; row != end; \ - row = gnt_tree_row_get_next(tree, row)) { \ - gpointer key = gnt_tree_row_get_key(tree, row); \ - GList *list = gnt_tree_get_row_text_list(tree, key); \ - gboolean found = FALSE; \ - found = (list->data && g_ascii_strncasecmp(text, list->data, len) == 0); \ - g_list_foreach(list, (GFunc)g_free, NULL); \ - g_list_free(list); \ - if (found) { \ - if (!showing) \ - popup_dropdown(box); \ - gnt_tree_set_selected(tree, key); \ - return TRUE; \ - } \ - } \ -} while (0) - - int len = strlen(text); - GntTree *tree = GNT_TREE(box->dropdown); - GntTreeRow *current = tree->current; - - SEARCH_IN_RANGE(gnt_tree_row_get_next(tree, current), NULL); - SEARCH_IN_RANGE(tree->top, current); - -#undef SEARCH_IN_RANGE - } - - return FALSE; -} - -static void -gnt_combo_box_destroy(GntWidget *widget) -{ - gnt_widget_destroy(GNT_COMBO_BOX(widget)->dropdown->parent); -} - -static void -gnt_combo_box_lost_focus(GntWidget *widget) -{ - GntComboBox *combo = GNT_COMBO_BOX(widget); - if (GNT_WIDGET_IS_FLAG_SET(combo->dropdown->parent, GNT_WIDGET_MAPPED)) - hide_popup(combo, FALSE); - widget_lost_focus(widget); -} - -static gboolean -gnt_combo_box_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - GntComboBox *box = GNT_COMBO_BOX(widget); - gboolean dshowing = GNT_WIDGET_IS_FLAG_SET(box->dropdown->parent, GNT_WIDGET_MAPPED); - - if (event == GNT_MOUSE_SCROLL_UP) { - if (dshowing) - gnt_widget_key_pressed(box->dropdown, GNT_KEY_UP); - } else if (event == GNT_MOUSE_SCROLL_DOWN) { - if (dshowing) - gnt_widget_key_pressed(box->dropdown, GNT_KEY_DOWN); - } else if (event == GNT_LEFT_MOUSE_DOWN) { - if (dshowing) { - hide_popup(box, TRUE); - } else { - popup_dropdown(GNT_COMBO_BOX(widget)); - } - } else - return FALSE; - return TRUE; -} - -static void -gnt_combo_box_size_changed(GntWidget *widget, int oldw, int oldh) -{ - GntComboBox *box = GNT_COMBO_BOX(widget); - gnt_widget_set_size(box->dropdown, widget->priv.width - 1, box->dropdown->priv.height); -} - -static gboolean -dropdown_menu(GntBindable *b, GList *null) -{ - if (GNT_WIDGET_IS_FLAG_SET(GNT_COMBO_BOX(b)->dropdown->parent, GNT_WIDGET_MAPPED)) - return FALSE; - popup_dropdown(GNT_COMBO_BOX(b)); - return TRUE; -} - -static void -gnt_combo_box_class_init(GntComboBoxClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - - parent_class = GNT_WIDGET_CLASS(klass); - - parent_class->destroy = gnt_combo_box_destroy; - parent_class->draw = gnt_combo_box_draw; - parent_class->map = gnt_combo_box_map; - parent_class->size_request = gnt_combo_box_size_request; - parent_class->key_pressed = gnt_combo_box_key_pressed; - parent_class->clicked = gnt_combo_box_clicked; - parent_class->size_changed = gnt_combo_box_size_changed; - - widget_lost_focus = parent_class->lost_focus; - parent_class->lost_focus = gnt_combo_box_lost_focus; - - signals[SIG_SELECTION_CHANGED] = - g_signal_new("selection-changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - gnt_closure_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - - gnt_bindable_class_register_action(bindable, "dropdown", dropdown_menu, - GNT_KEY_DOWN, NULL); - gnt_bindable_register_binding(bindable, "dropdown", GNT_KEY_UP, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable); - - GNTDEBUG; -} - -static void -gnt_combo_box_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *box; - GntWidget *widget = GNT_WIDGET(instance); - GntComboBox *combo = GNT_COMBO_BOX(instance); - - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), - GNT_WIDGET_GROW_X | GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_NO_SHADOW); - combo->dropdown = gnt_tree_new(); - - box = gnt_box_new(FALSE, FALSE); - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT); - gnt_box_set_pad(GNT_BOX(box), 0); - gnt_box_add_widget(GNT_BOX(box), combo->dropdown); - - widget->priv.minw = 4; - widget->priv.minh = 3; - GNTDEBUG; -} - -/****************************************************************************** - * GntComboBox API - *****************************************************************************/ -GType -gnt_combo_box_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntComboBoxClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_combo_box_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntComboBox), - 0, /* n_preallocs */ - gnt_combo_box_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntComboBox", - &info, 0); - } - - return type; -} - -GntWidget *gnt_combo_box_new() -{ - GntWidget *widget = g_object_new(GNT_TYPE_COMBO_BOX, NULL); - - return widget; -} - -void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text) -{ - gnt_tree_add_row_last(GNT_TREE(box->dropdown), key, - gnt_tree_create_row(GNT_TREE(box->dropdown), text), NULL); - if (box->selected == NULL) - set_selection(box, key); -} - -gpointer gnt_combo_box_get_selected_data(GntComboBox *box) -{ - return box->selected; -} - -void gnt_combo_box_set_selected(GntComboBox *box, gpointer key) -{ - set_selection(box, key); -} - -void gnt_combo_box_remove(GntComboBox *box, gpointer key) -{ - gnt_tree_remove(GNT_TREE(box->dropdown), key); - if (box->selected == key) - set_selection(box, NULL); -} - -void gnt_combo_box_remove_all(GntComboBox *box) -{ - gnt_tree_remove_all(GNT_TREE(box->dropdown)); - set_selection(box, NULL); -} -
--- a/finch/libgnt/gntcombobox.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/** - * @file gntcombobox.h Combobox API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_COMBO_BOX_H -#define GNT_COMBO_BOX_H - -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" -#include "gntwidget.h" - -#define GNT_TYPE_COMBO_BOX (gnt_combo_box_get_gtype()) -#define GNT_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_COMBO_BOX, GntComboBox)) -#define GNT_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_COMBO_BOX, GntComboBoxClass)) -#define GNT_IS_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_COMBO_BOX)) -#define GNT_IS_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_COMBO_BOX)) -#define GNT_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_COMBO_BOX, GntComboBoxClass)) - -#define GNT_COMBO_BOX_FLAGS(obj) (GNT_COMBO_BOX(obj)->priv.flags) -#define GNT_COMBO_BOX_SET_FLAGS(obj, flags) (GNT_COMBO_BOX_FLAGS(obj) |= flags) -#define GNT_COMBO_BOX_UNSET_FLAGS(obj, flags) (GNT_COMBO_BOX_FLAGS(obj) &= ~(flags)) - -typedef struct _GntComboBox GntComboBox; -typedef struct _GntComboBoxPriv GntComboBoxPriv; -typedef struct _GntComboBoxClass GntComboBoxClass; - -struct _GntComboBox -{ - GntWidget parent; - - GntWidget *dropdown; /* This is a GntTree */ - - void *selected; /* Currently selected key */ -}; - -struct _GntComboBoxClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return Get the GType for GntComboBox - */ -GType gnt_combo_box_get_gtype(void); - -/** - * Create a new GntComboBox - * - * @return A new GntComboBox - */ -GntWidget * gnt_combo_box_new(void); - -/** - * Add an entry - * - * @param box The GntComboBox - * @param key The data - * @param text The text to display - */ -void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text); - -/** - * Remove an entry - * - * @param box The GntComboBox - * @param key The data to be removed - */ -void gnt_combo_box_remove(GntComboBox *box, gpointer key); - -/** - * Remove all entries - * - * @param box The GntComboBox - */ -void gnt_combo_box_remove_all(GntComboBox *box); - -/** - * Get the data that is currently selected - * - * @param box The GntComboBox - * - * @return The data of the currently selected entry - */ -gpointer gnt_combo_box_get_selected_data(GntComboBox *box); - -/** - * Set the current selection to a specific entry - * - * @param box The GntComboBox - * @param key The data to be set to - */ -void gnt_combo_box_set_selected(GntComboBox *box, gpointer key); - -G_END_DECLS - -#endif /* GNT_COMBO_BOX_H */
--- a/finch/libgnt/gntentry.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1272 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include <ctype.h> -#include <string.h> - -#include "gntinternal.h" -#include "gntbox.h" -#include "gntentry.h" -#include "gntmarshal.h" -#include "gntstyle.h" -#include "gnttree.h" -#include "gntutils.h" - -enum -{ - SIG_TEXT_CHANGED, - SIG_COMPLETION, - SIGS, -}; - -typedef enum -{ - ENTRY_JAIL = -1, /* Suspend the kill ring. */ - ENTRY_DEL_BWD_WORD = 1, - ENTRY_DEL_BWD_CHAR, - ENTRY_DEL_FWD_WORD, - ENTRY_DEL_FWD_CHAR, - ENTRY_DEL_EOL, - ENTRY_DEL_BOL, -} GntEntryAction; - -struct _GntEntryKillRing -{ - GString *buffer; - GntEntryAction last; -}; - -struct _GntEntrySearch -{ - char *needle; -}; - -static guint signals[SIGS] = { 0 }; - -static GntWidgetClass *parent_class = NULL; - -static gboolean gnt_entry_key_pressed(GntWidget *widget, const char *text); -static void gnt_entry_set_text_internal(GntEntry *entry, const char *text); - -static gboolean -update_kill_ring(GntEntry *entry, GntEntryAction action, const char *text, int len) -{ - if (action < 0) { - entry->killring->last = action; - return FALSE; - } - - if (len == 0) - len = strlen(text); - else if (len < 0) { - text += len; - len = -len; - } - - if (action != entry->killring->last) { - struct { - GntEntryAction one; - GntEntryAction two; - } merges[] = { - {ENTRY_DEL_BWD_WORD, ENTRY_DEL_FWD_WORD}, - {ENTRY_DEL_BWD_CHAR, ENTRY_DEL_FWD_CHAR}, - {ENTRY_DEL_BOL, ENTRY_DEL_EOL}, - {ENTRY_JAIL, ENTRY_JAIL}, - }; - int i; - - for (i = 0; merges[i].one != ENTRY_JAIL; i++) { - if (merges[i].one == entry->killring->last && - merges[i].two == action) { - g_string_append_len(entry->killring->buffer, text, len); - break; - } else if (merges[i].one == action && - merges[i].two == entry->killring->last) { - g_string_prepend_len(entry->killring->buffer, text, len); - break; - } - } - if (merges[i].one == ENTRY_JAIL) { - g_string_assign(entry->killring->buffer, text); - g_string_truncate(entry->killring->buffer, len); - } - entry->killring->last = action; - } else { - if (action == ENTRY_DEL_BWD_CHAR || action == ENTRY_DEL_BWD_WORD) - g_string_prepend_len(entry->killring->buffer, text, len); - else - g_string_append_len(entry->killring->buffer, text, len); - } - return TRUE; -} - -static void -destroy_suggest(GntEntry *entry) -{ - if (entry->ddown) - { - gnt_widget_destroy(entry->ddown->parent); - entry->ddown = NULL; - } -} - -static char * -get_beginning_of_word(GntEntry *entry) -{ - char *s = entry->cursor; - while (s > entry->start) - { - char *t = g_utf8_find_prev_char(entry->start, s); - if (isspace(*t)) - break; - s = t; - } - return s; -} - -static gboolean -complete_suggest(GntEntry *entry, const char *text) -{ - int offstart = 0, offend = 0; - - if (entry->word) { - char *s = get_beginning_of_word(entry); - const char *iter = text; - offstart = g_utf8_pointer_to_offset(entry->start, s); - while (*iter && toupper(*s) == toupper(*iter)) { - *s++ = *iter++; - } - if (*iter) { - gnt_entry_key_pressed(GNT_WIDGET(entry), iter); - } - offend = g_utf8_pointer_to_offset(entry->start, entry->cursor); - } else { - offstart = 0; - gnt_entry_set_text_internal(entry, text); - offend = g_utf8_strlen(text, -1); - } - - g_signal_emit(G_OBJECT(entry), signals[SIG_COMPLETION], 0, - entry->start + offstart, entry->start + offend); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; -} - -static int -max_common_prefix(const char *s, const char *t) -{ - const char *f = s; - while (*f && *t && *f == *t++) - f++; - return f - s; -} - -static gboolean -show_suggest_dropdown(GntEntry *entry) -{ - char *suggest = NULL; - gsize len; - int offset = 0, x, y; - int count = 0; - GList *iter; - const char *text = NULL; - const char *sgst = NULL; - int max = -1; - - if (entry->word) - { - char *s = get_beginning_of_word(entry); - suggest = g_strndup(s, entry->cursor - s); - if (entry->scroll < s) - offset = gnt_util_onscreen_width(entry->scroll, s); - } - else - suggest = g_strdup(entry->start); - len = strlen(suggest); /* Don't need to use the utf8-function here */ - - if (entry->ddown == NULL) - { - GntWidget *box = gnt_vbox_new(FALSE); - entry->ddown = gnt_tree_new(); - gnt_tree_set_compare_func(GNT_TREE(entry->ddown), (GCompareFunc)g_utf8_collate); - gnt_box_add_widget(GNT_BOX(box), entry->ddown); - - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_TRANSIENT); - - gnt_widget_get_position(GNT_WIDGET(entry), &x, &y); - x += offset; - y++; - if (y + 10 >= getmaxy(stdscr)) - y -= 11; - gnt_widget_set_position(box, x, y); - } - else - gnt_tree_remove_all(GNT_TREE(entry->ddown)); - - for (count = 0, iter = entry->suggests; iter; iter = iter->next) - { - text = iter->data; - if (g_ascii_strncasecmp(suggest, text, len) == 0 && strlen(text) >= len) - { - gnt_tree_add_row_after(GNT_TREE(entry->ddown), (gpointer)text, - gnt_tree_create_row(GNT_TREE(entry->ddown), text), - NULL, NULL); - count++; - if (max == -1) - max = strlen(text) - len; - else if (max) - max = MIN(max, max_common_prefix(sgst + len, text + len)); - sgst = text; - } - } - g_free(suggest); - - if (count == 0) { - destroy_suggest(entry); - return FALSE; - } else if (count == 1) { - char *store = g_strndup(entry->start, entry->end - entry->start); - gboolean ret; - - destroy_suggest(entry); - complete_suggest(entry, sgst); - - ret = (strncmp(store, entry->start, entry->end - entry->start) != 0); - g_free(store); - return ret; - } else { - if (max > 0) { - GntWidget *ddown = entry->ddown; - char *match = g_strndup(sgst + len, max); - entry->ddown = NULL; - gnt_entry_key_pressed(GNT_WIDGET(entry), match); - g_free(match); - if (entry->ddown) - gnt_widget_destroy(ddown); - else - entry->ddown = ddown; - } - gnt_widget_draw(entry->ddown->parent); - } - - return TRUE; -} - -static void -gnt_entry_draw(GntWidget *widget) -{ - GntEntry *entry = GNT_ENTRY(widget); - int stop; - gboolean focus; - int curpos; - - if ((focus = gnt_widget_has_focus(widget))) - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TEXT_NORMAL)); - else - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - - if (entry->masked) - { - mvwhline(widget->window, 0, 0, gnt_ascii_only() ? '*' : ACS_BULLET, - g_utf8_pointer_to_offset(entry->scroll, entry->end)); - } - else - mvwprintw(widget->window, 0, 0, "%s", C_(entry->scroll)); - - stop = gnt_util_onscreen_width(entry->scroll, entry->end); - if (stop < widget->priv.width) - mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop); - - curpos = gnt_util_onscreen_width(entry->scroll, entry->cursor); - if (focus) - mvwchgat(widget->window, 0, curpos, 1, A_REVERSE, GNT_COLOR_TEXT_NORMAL, NULL); - (void)wmove(widget->window, 0, curpos); - - GNTDEBUG; -} - -static void -gnt_entry_size_request(GntWidget *widget) -{ - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - { - widget->priv.height = 1; - widget->priv.width = 20; - } -} - -static void -gnt_entry_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static void -entry_redraw(GntWidget *widget) -{ - gnt_entry_draw(widget); - gnt_widget_queue_update(widget); -} - -static void -entry_text_changed(GntEntry *entry) -{ - g_signal_emit(entry, signals[SIG_TEXT_CHANGED], 0); -} - -static gboolean -move_back(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->cursor <= entry->start) - return FALSE; - entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor); - if (entry->cursor < entry->scroll) - entry->scroll = entry->cursor; - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(GNT_WIDGET(entry)); - return TRUE; -} - -static gboolean -move_forward(GntBindable *bind, GList *list) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->cursor >= entry->end) - return FALSE; - entry->cursor = g_utf8_find_next_char(entry->cursor, NULL); - while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) - entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(GNT_WIDGET(entry)); - return TRUE; -} - -static gboolean -backspace(GntBindable *bind, GList *null) -{ - int len; - GntEntry *entry = GNT_ENTRY(bind); - - if (entry->cursor <= entry->start) - return TRUE; - - len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor); - update_kill_ring(entry, ENTRY_JAIL, entry->cursor, -len); - entry->cursor -= len; - - memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor); - entry->end -= len; - - if (entry->scroll > entry->start) - entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll); - - entry_redraw(GNT_WIDGET(entry)); - if (entry->ddown) - show_suggest_dropdown(entry); - entry_text_changed(entry); - return TRUE; -} - -static gboolean -delkey(GntBindable *bind, GList *null) -{ - int len; - GntEntry *entry = GNT_ENTRY(bind); - - if (entry->cursor >= entry->end) - return FALSE; - - len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor; - update_kill_ring(entry, ENTRY_JAIL, entry->cursor, len); - memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1); - entry->end -= len; - entry_redraw(GNT_WIDGET(entry)); - - if (entry->ddown) - show_suggest_dropdown(entry); - entry_text_changed(entry); - return TRUE; -} - -static gboolean -move_start(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - entry->scroll = entry->cursor = entry->start; - entry_redraw(GNT_WIDGET(entry)); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; -} - -static gboolean -move_end(GntBindable *bind, GList *null) -{ - 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) - entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); - entry_redraw(GNT_WIDGET(entry)); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; -} - -static gboolean -history_next(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->histlength && entry->history->prev) - { - entry->history = entry->history->prev; - gnt_entry_set_text_internal(entry, entry->history->data); - destroy_suggest(entry); - entry_text_changed(entry); - - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; - } - return FALSE; -} - -static gboolean -history_prev(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->histlength && entry->history->next) - { - if (entry->history->prev == NULL) - { - /* Save the current contents */ - char *text = g_strdup(gnt_entry_get_text(entry)); - g_free(entry->history->data); - entry->history->data = text; - } - - entry->history = entry->history->next; - gnt_entry_set_text_internal(entry, entry->history->data); - destroy_suggest(entry); - entry_text_changed(entry); - - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; - } - return FALSE; -} - -static gboolean -history_search(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - GList *iter; - const char *current; - - if (entry->history->prev && entry->search->needle) - current = entry->search->needle; - else - current = gnt_entry_get_text(entry); - - if (!entry->histlength || !entry->history->next || !*current) - return FALSE; - - for (iter = entry->history->next; iter; iter = iter->next) { - const char *str = iter->data; - /* A more utf8-friendly version of strstr would have been better, but - * for now, this will have to do. */ - if (strstr(str, current) != NULL) - break; - } - - if (!iter) - return TRUE; - - if (entry->history->prev == NULL) { - /* We are doing it for the first time. Save the current contents */ - char *text = g_strdup(gnt_entry_get_text(entry)); - - g_free(entry->search->needle); - entry->search->needle = g_strdup(current); - - g_free(entry->history->data); - entry->history->data = text; - } - - entry->history = iter; - gnt_entry_set_text_internal(entry, entry->history->data); - destroy_suggest(entry); - entry_text_changed(entry); - - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - return TRUE; -} - -static gboolean -clipboard_paste(GntBindable *bind, GList *n) -{ - GntEntry *entry = GNT_ENTRY(bind); - gchar *i, *text, *a, *all; - text = i = gnt_get_clipboard_string(); - while (*i != '\0') { - i = g_utf8_next_char(i); - if (*i == '\r' || *i == '\n') - *i = ' '; - } - a = g_strndup(entry->start, entry->cursor - entry->start); - all = g_strconcat(a, text, entry->cursor, NULL); - gnt_entry_set_text_internal(entry, all); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - g_free(a); - g_free(text); - g_free(all); - return TRUE; -} - -static gboolean -suggest_show(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL); - return TRUE; - } - return show_suggest_dropdown(entry); -} - -static gboolean -suggest_next(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-down", NULL); - return TRUE; - } - return FALSE; -} - -static gboolean -suggest_prev(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "move-up", NULL); - return TRUE; - } - return FALSE; -} - -static gboolean -suggest_next_page(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "page-down", NULL); - return TRUE; - } - return FALSE; -} - -static gboolean -suggest_prev_page(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->ddown) { - gnt_bindable_perform_action_named(GNT_BINDABLE(entry->ddown), "page-up", NULL); - return TRUE; - } - return FALSE; -} - -static gboolean -del_to_home(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->cursor <= entry->start) - return TRUE; - update_kill_ring(entry, ENTRY_DEL_BOL, entry->start, entry->cursor - entry->start); - 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(GNT_WIDGET(bind)); - entry_text_changed(entry); - return TRUE; -} - -static gboolean -del_to_end(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - if (entry->end <= entry->cursor) - return TRUE; - update_kill_ring(entry, ENTRY_DEL_EOL, entry->cursor, entry->end - entry->cursor); - entry->end = entry->cursor; - memset(entry->end, '\0', entry->buffer - (entry->end - entry->start)); - entry_redraw(GNT_WIDGET(bind)); - entry_text_changed(entry); - return TRUE; -} - -#define SAME(a,b) ((g_unichar_isalnum(a) && g_unichar_isalnum(b)) || \ - (g_unichar_isspace(a) && g_unichar_isspace(b)) || \ - (g_unichar_iswide(a) && g_unichar_iswide(b)) || \ - (g_unichar_ispunct(a) && g_unichar_ispunct(b))) - -static const char * -begin_word(const char *text, const char *begin) -{ - gunichar ch = 0; - while (text > begin && (!*text || g_unichar_isspace(g_utf8_get_char(text)))) - text = g_utf8_find_prev_char(begin, text); - ch = g_utf8_get_char(text); - while ((text = g_utf8_find_prev_char(begin, text)) >= begin) { - gunichar cur = g_utf8_get_char(text); - if (!SAME(ch, cur)) - break; - } - - return (text ? g_utf8_find_next_char(text, NULL) : begin); -} - -static const char * -next_begin_word(const char *text, const char *end) -{ - gunichar ch = 0; - - while (text && text < end && g_unichar_isspace(g_utf8_get_char(text))) - text = g_utf8_find_next_char(text, end); - - if (text) { - ch = g_utf8_get_char(text); - while ((text = g_utf8_find_next_char(text, end)) != NULL && text <= end) { - gunichar cur = g_utf8_get_char(text); - if (!SAME(ch, cur)) - break; - } - } - return (text ? text : end); -} - -#undef SAME -static gboolean -move_back_word(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - const char *iter = g_utf8_find_prev_char(entry->start, entry->cursor); - - if (iter < entry->start) - return TRUE; - iter = begin_word(iter, entry->start); - entry->cursor = (char*)iter; - if (entry->cursor < entry->scroll) - entry->scroll = entry->cursor; - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(GNT_WIDGET(bind)); - return TRUE; -} - -static gboolean -del_prev_word(GntBindable *bind, GList *null) -{ - GntWidget *widget = GNT_WIDGET(bind); - GntEntry *entry = GNT_ENTRY(bind); - char *iter = g_utf8_find_prev_char(entry->start, entry->cursor); - int count; - - if (iter < entry->start) - return TRUE; - iter = (char*)begin_word(iter, entry->start); - count = entry->cursor - iter; - update_kill_ring(entry, ENTRY_DEL_BWD_WORD, iter, count); - memmove(iter, entry->cursor, entry->end - entry->cursor); - entry->end -= count; - entry->cursor = iter; - if (entry->cursor <= entry->scroll) { - entry->scroll = entry->cursor - widget->priv.width + 2; - if (entry->scroll < entry->start) - entry->scroll = entry->start; - } - memset(entry->end, '\0', entry->buffer - (entry->end - entry->start)); - entry_redraw(widget); - entry_text_changed(entry); - - return TRUE; -} - -static gboolean -move_forward_word(GntBindable *bind, GList *list) -{ - GntEntry *entry = GNT_ENTRY(bind); - GntWidget *widget = GNT_WIDGET(bind); - entry->cursor = (char *)next_begin_word(entry->cursor, entry->end); - while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) { - entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); - } - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(widget); - return TRUE; -} - -static gboolean -delete_forward_word(GntBindable *bind, GList *list) -{ - GntEntry *entry = GNT_ENTRY(bind); - GntWidget *widget = GNT_WIDGET(bind); - char *iter = (char *)next_begin_word(entry->cursor, entry->end); - int len = entry->end - iter + 1; - if (len <= 0) - return TRUE; - update_kill_ring(entry, ENTRY_DEL_FWD_WORD, entry->cursor, iter - entry->cursor); - memmove(entry->cursor, iter, len); - len = iter - entry->cursor; - entry->end -= len; - memset(entry->end, '\0', len); - entry_redraw(widget); - entry_text_changed(entry); - return TRUE; -} - -static gboolean -transpose_chars(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - char *current, *prev; - char hold[8]; /* that's right */ - - if (entry->cursor <= entry->start) - return FALSE; - - if (!*entry->cursor) - entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor); - - current = entry->cursor; - prev = g_utf8_find_prev_char(entry->start, entry->cursor); - move_forward(bind, null); - - /* Let's do this dance! */ - memcpy(hold, prev, current - prev); - memmove(prev, current, entry->cursor - current); - memcpy(prev + (entry->cursor - current), hold, current - prev); - - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(GNT_WIDGET(entry)); - entry_text_changed(entry); - return TRUE; -} - -static gboolean -entry_yank(GntBindable *bind, GList *null) -{ - GntEntry *entry = GNT_ENTRY(bind); - gnt_entry_key_pressed(GNT_WIDGET(entry), entry->killring->buffer->str); - return TRUE; -} - -static gboolean -gnt_entry_key_pressed(GntWidget *widget, const char *text) -{ - GntEntry *entry = GNT_ENTRY(widget); - - if (text[0] == 27) - { - if (text[1] == 0) - { - destroy_suggest(entry); - return TRUE; - } - - return FALSE; - } - - if ((text[0] == '\r' || text[0] == ' ' || text[0] == '\n') && entry->ddown) - { - char *text = g_strdup(gnt_tree_get_selection_data(GNT_TREE(entry->ddown))); - destroy_suggest(entry); - complete_suggest(entry, text); - g_free(text); - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_text_changed(entry); - return TRUE; - } - - if (!iscntrl(text[0])) - { - const char *str, *next; - - for (str = text; *str; str = next) - { - gsize len; - next = g_utf8_find_next_char(str, NULL); - len = next - str; - - /* Valid input? */ - /* XXX: Is it necessary to use _unichar_ variants here? */ - if (ispunct(*str) && (entry->flag & GNT_ENTRY_FLAG_NO_PUNCT)) - continue; - if (isspace(*str) && (entry->flag & GNT_ENTRY_FLAG_NO_SPACE)) - continue; - if (isalpha(*str) && !(entry->flag & GNT_ENTRY_FLAG_ALPHA)) - continue; - if (isdigit(*str) && !(entry->flag & GNT_ENTRY_FLAG_INT)) - continue; - - /* Reached the max? */ - if (entry->max && g_utf8_pointer_to_offset(entry->start, entry->end) >= entry->max) - continue; - - if ((gsize)(entry->end + len - entry->start) >= entry->buffer) - { - /* This will cause the buffer to grow */ - char *tmp = g_strdup(entry->start); - gnt_entry_set_text_internal(entry, tmp); - g_free(tmp); - } - - memmove(entry->cursor + len, entry->cursor, entry->end - entry->cursor + 1); - entry->end += len; - - while (str < next) - { - if (*str == '\r' || *str == '\n') - *entry->cursor = ' '; - else - *entry->cursor = *str; - entry->cursor++; - str++; - } - - while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= widget->priv.width) - entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); - - if (entry->ddown) - show_suggest_dropdown(entry); - } - update_kill_ring(entry, ENTRY_JAIL, NULL, 0); - entry_redraw(widget); - entry_text_changed(entry); - return TRUE; - } - - if (text[0] == '\r' || text[0] == '\n') { - gnt_widget_activate(widget); - return TRUE; - } - - return FALSE; -} - -static void -jail_killring(GntEntryKillRing *kr) -{ - g_string_free(kr->buffer, TRUE); - g_free(kr); -} - -static void -gnt_entry_destroy(GntWidget *widget) -{ - GntEntry *entry = GNT_ENTRY(widget); - g_free(entry->start); - - if (entry->history) - { - entry->history = g_list_first(entry->history); - g_list_foreach(entry->history, (GFunc)g_free, NULL); - g_list_free(entry->history); - } - - if (entry->suggests) - { - g_list_foreach(entry->suggests, (GFunc)g_free, NULL); - g_list_free(entry->suggests); - } - - if (entry->ddown) - { - gnt_widget_destroy(entry->ddown->parent); - } - - g_free(entry->search->needle); - g_free(entry->search); - - jail_killring(entry->killring); -} - -static void -gnt_entry_lost_focus(GntWidget *widget) -{ - GntEntry *entry = GNT_ENTRY(widget); - destroy_suggest(entry); - entry_redraw(widget); -} - -static gboolean -gnt_entry_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - if (event == GNT_MIDDLE_MOUSE_DOWN) { - clipboard_paste(GNT_BINDABLE(widget), NULL); - return TRUE; - } - return FALSE; - -} - -static void -gnt_entry_class_init(GntEntryClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - char s[3] = {'\033', erasechar(), 0}; - - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->clicked = gnt_entry_clicked; - parent_class->destroy = gnt_entry_destroy; - parent_class->draw = gnt_entry_draw; - parent_class->map = gnt_entry_map; - parent_class->size_request = gnt_entry_size_request; - parent_class->key_pressed = gnt_entry_key_pressed; - parent_class->lost_focus = gnt_entry_lost_focus; - - signals[SIG_TEXT_CHANGED] = - g_signal_new("text_changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntEntryClass, text_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SIG_COMPLETION] = - g_signal_new("completion", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - gnt_closure_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - - gnt_bindable_class_register_action(bindable, "cursor-home", move_start, - GNT_KEY_CTRL_A, NULL); - 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_bindable_register_binding(bindable, "cursor-end", GNT_KEY_END, NULL); - gnt_bindable_class_register_action(bindable, "delete-prev", backspace, - GNT_KEY_BACKSPACE, NULL); - gnt_bindable_register_binding(bindable, "delete-prev", s + 1, NULL); - gnt_bindable_register_binding(bindable, "delete-prev", GNT_KEY_CTRL_H, NULL); - gnt_bindable_class_register_action(bindable, "delete-next", delkey, - GNT_KEY_DEL, NULL); - 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_bindable_class_register_action(bindable, "delete-end", del_to_end, - GNT_KEY_CTRL_K, NULL); - gnt_bindable_class_register_action(bindable, "delete-prev-word", del_prev_word, - GNT_KEY_CTRL_W, NULL); - gnt_bindable_register_binding(bindable, "delete-prev-word", s, NULL); - gnt_bindable_class_register_action(bindable, "cursor-prev-word", move_back_word, - "\033" "b", NULL); - gnt_bindable_class_register_action(bindable, "cursor-prev", move_back, - GNT_KEY_LEFT, NULL); - 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_bindable_register_binding(bindable, "cursor-next", GNT_KEY_CTRL_F, NULL); - gnt_bindable_class_register_action(bindable, "cursor-next-word", move_forward_word, - "\033" "f", NULL); - gnt_bindable_class_register_action(bindable, "delete-next-word", delete_forward_word, - "\033" "d", NULL); - gnt_bindable_class_register_action(bindable, "transpose-chars", transpose_chars, - GNT_KEY_CTRL_T, NULL); - gnt_bindable_class_register_action(bindable, "yank", entry_yank, - GNT_KEY_CTRL_Y, NULL); - gnt_bindable_class_register_action(bindable, "suggest-show", suggest_show, - "\t", NULL); - gnt_bindable_class_register_action(bindable, "suggest-next", suggest_next, - GNT_KEY_DOWN, NULL); - gnt_bindable_class_register_action(bindable, "suggest-prev", suggest_prev, - GNT_KEY_UP, NULL); - gnt_bindable_class_register_action(bindable, "suggest-next-page", suggest_next_page, - GNT_KEY_PGDOWN, NULL); - gnt_bindable_class_register_action(bindable, "suggest-prev-page", suggest_prev_page, - GNT_KEY_PGUP, NULL); - gnt_bindable_class_register_action(bindable, "history-next", history_next, - GNT_KEY_CTRL_DOWN, NULL); - gnt_bindable_class_register_action(bindable, "history-prev", history_prev, - GNT_KEY_CTRL_UP, NULL); - gnt_bindable_register_binding(bindable, "history-prev", GNT_KEY_CTRL_P, NULL); - gnt_bindable_register_binding(bindable, "history-next", GNT_KEY_CTRL_N, NULL); - gnt_bindable_class_register_action(bindable, "history-search", history_search, - GNT_KEY_CTRL_R, NULL); - gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste, - GNT_KEY_CTRL_V, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); - GNTDEBUG; -} - -static GntEntryKillRing * -new_killring(void) -{ - GntEntryKillRing *kr = g_new0(GntEntryKillRing, 1); - kr->buffer = g_string_new(NULL); - return kr; -} - -static void -gnt_entry_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntEntry *entry = GNT_ENTRY(instance); - - entry->flag = GNT_ENTRY_FLAG_ALL; - entry->max = 0; - - entry->histlength = 0; - entry->history = NULL; - - entry->word = TRUE; - entry->always = FALSE; - entry->suggests = NULL; - entry->killring = new_killring(); - entry->search = g_new0(GntEntrySearch, 1); - - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), - GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), GNT_WIDGET_GROW_X); - - widget->priv.minw = 3; - widget->priv.minh = 1; - - GNTDEBUG; -} - -/****************************************************************************** - * GntEntry API - *****************************************************************************/ -GType -gnt_entry_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntEntryClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_entry_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntEntry), - 0, /* n_preallocs */ - gnt_entry_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntEntry", - &info, 0); - } - - return type; -} - -GntWidget *gnt_entry_new(const char *text) -{ - GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL); - GntEntry *entry = GNT_ENTRY(widget); - - gnt_entry_set_text_internal(entry, text); - - return widget; -} - -static void -gnt_entry_set_text_internal(GntEntry *entry, const char *text) -{ - int len; - int scroll, cursor; - - g_free(entry->start); - - if (text && text[0]) - { - len = strlen(text); - } - else - { - len = 0; - } - - entry->buffer = len + 128; - - scroll = entry->scroll - entry->start; - cursor = entry->end - entry->cursor; - - entry->start = g_new0(char, entry->buffer); - if (text) - snprintf(entry->start, len + 1, "%s", text); - entry->end = entry->start + len; - - if ((entry->scroll = entry->start + scroll) > entry->end) - entry->scroll = entry->end; - - if ((entry->cursor = entry->end - cursor) > entry->end) - entry->cursor = entry->end; - - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(entry), GNT_WIDGET_MAPPED)) - entry_redraw(GNT_WIDGET(entry)); -} - -void gnt_entry_set_text(GntEntry *entry, const char *text) -{ - gboolean changed = TRUE; - if (text == NULL && entry->start == NULL) - changed = FALSE; - if (text && entry->start && g_utf8_collate(text, entry->start) == 0) - changed = FALSE; - gnt_entry_set_text_internal(entry, text); - if (changed) - entry_text_changed(entry); -} - -void gnt_entry_set_max(GntEntry *entry, int max) -{ - entry->max = max; -} - -void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag) -{ - entry->flag = flag; - /* XXX: Check the existing string to make sure the flags are respected? */ -} - -const char *gnt_entry_get_text(GntEntry *entry) -{ - return entry->start; -} - -void gnt_entry_clear(GntEntry *entry) -{ - gnt_entry_set_text_internal(entry, NULL); - entry->scroll = entry->cursor = entry->end = entry->start; - entry_redraw(GNT_WIDGET(entry)); - destroy_suggest(entry); - entry_text_changed(entry); -} - -void gnt_entry_set_masked(GntEntry *entry, gboolean set) -{ - entry->masked = set; -} - -void gnt_entry_add_to_history(GntEntry *entry, const char *text) -{ - g_return_if_fail(entry->history != NULL); /* Need to set_history_length first */ - - if (entry->histlength >= 0 && - g_list_length(entry->history) >= (gsize)entry->histlength) - { - return; - } - - entry->history = g_list_first(entry->history); - g_free(entry->history->data); - entry->history->data = g_strdup(text); - entry->history = g_list_prepend(entry->history, NULL); -} - -void gnt_entry_set_history_length(GntEntry *entry, int num) -{ - if (num == 0) - { - entry->histlength = num; - if (entry->history) - { - entry->history = g_list_first(entry->history); - g_list_foreach(entry->history, (GFunc)g_free, NULL); - g_list_free(entry->history); - entry->history = NULL; - } - return; - } - - if (entry->histlength == 0) - { - entry->histlength = num; - entry->history = g_list_append(NULL, NULL); - return; - } - - if (num > 0 && num < entry->histlength) - { - GList *first, *iter; - int index = 0; - for (first = entry->history, index = 0; first->prev; first = first->prev, index++); - while ((iter = g_list_nth(first, num)) != NULL) - { - g_free(iter->data); - first = g_list_delete_link(first, iter); - } - entry->histlength = num; - if (index >= num) - entry->history = g_list_last(first); - return; - } - - entry->histlength = num; -} - -void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word) -{ - entry->word = word; -} - -void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always) -{ - entry->always = always; -} - -void gnt_entry_add_suggest(GntEntry *entry, const char *text) -{ - GList *find; - - if (!text || !*text) - return; - - find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate); - if (find) - return; - entry->suggests = g_list_append(entry->suggests, g_strdup(text)); -} - -void gnt_entry_remove_suggest(GntEntry *entry, const char *text) -{ - GList *find = g_list_find_custom(entry->suggests, text, (GCompareFunc)g_utf8_collate); - if (find) - { - g_free(find->data); - entry->suggests = g_list_delete_link(entry->suggests, find); - } -} -
--- a/finch/libgnt/gntentry.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -/** - * @file gntentry.h Entry API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_ENTRY_H -#define GNT_ENTRY_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_ENTRY (gnt_entry_get_gtype()) -#define GNT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_ENTRY, GntEntry)) -#define GNT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_ENTRY, GntEntryClass)) -#define GNT_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_ENTRY)) -#define GNT_IS_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_ENTRY)) -#define GNT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_ENTRY, GntEntryClass)) - -#define GNT_ENTRY_FLAGS(obj) (GNT_ENTRY(obj)->priv.flags) -#define GNT_ENTRY_SET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) |= flags) -#define GNT_ENTRY_UNSET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) &= ~(flags)) - -#define ENTRY_CHAR '_' /* The character to use to fill in the blank places */ - -typedef struct _GntEntry GntEntry; -typedef struct _GntEntryPriv GntEntryPriv; -typedef struct _GntEntryClass GntEntryClass; -typedef struct _GntEntryKillRing GntEntryKillRing; -typedef struct _GntEntrySearch GntEntrySearch; - -typedef enum -{ - GNT_ENTRY_FLAG_ALPHA = 1 << 0, /* Only alpha */ - GNT_ENTRY_FLAG_INT = 1 << 1, /* Only integer */ - GNT_ENTRY_FLAG_NO_SPACE = 1 << 2, /* No blank space is allowed */ - GNT_ENTRY_FLAG_NO_PUNCT = 1 << 3, /* No punctuations */ - GNT_ENTRY_FLAG_MASK = 1 << 4, /* Mask the inputs */ -} GntEntryFlag; - -#define GNT_ENTRY_FLAG_ALL (GNT_ENTRY_FLAG_ALPHA | GNT_ENTRY_FLAG_INT) - -struct _GntEntry -{ - GntWidget parent; - - GntEntryFlag flag; - - char *start; - char *end; - char *scroll; /* Current scrolling position */ - char *cursor; /* Cursor location */ - /* 0 <= cursor - scroll < widget-width */ - - size_t buffer; /* Size of the buffer */ - - int max; /* 0 means infinite */ - gboolean masked; - - GList *history; /* History of the strings. User can use this by pressing ctrl+up/down */ - int histlength; /* How long can the history be? */ - - GList *suggests; /* List of suggestions */ - gboolean word; /* Are the suggestions for only a word, or for the whole thing? */ - gboolean always; /* Should the list of suggestions show at all times, or only on tab-press? */ - GntWidget *ddown; /* The dropdown with the suggested list */ - GntEntryKillRing *killring; /**< @since 2.3.0 */ - GntEntrySearch *search; /**< @since 2.7.0 */ -}; - -struct _GntEntryClass -{ - GntWidgetClass parent; - - void (*text_changed)(GntEntry *entry); - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntEntry. - */ -GType gnt_entry_get_gtype(void); - -/** - * Create a new GntEntry. - * - * @param text The text in the new entry box. - * - * @return The newly created entry box. - */ -GntWidget * gnt_entry_new(const char *text); - -/** - * Set the maximum length of the text in the entry box. - * - * @param entry The entry box. - * @param max The maximum length for text. A value of 0 means infinite length. - */ -void gnt_entry_set_max(GntEntry *entry, int max); - -/** - * Set the text in an entry box. - * - * @param entry The entry box. - * @param text The text to set in the box. - */ -void gnt_entry_set_text(GntEntry *entry, const char *text); - -/** - * Set flags an entry box. - * - * @param entry The entry box. - * @param flag The flags to set for the entry box. - */ -void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag); - -/** - * Get the text in an entry box. - * - * @param entry The entry box. - * - * @return The current text in the entry box. - */ -const char *gnt_entry_get_text(GntEntry *entry); - -/** - * Clear the text in the entry box. - * - * @param entry The entry box. - */ -void gnt_entry_clear(GntEntry *entry); - -/** - * Set whether the text in the entry box should be masked for display. - * - * @param entry The entry box. - * @param set @c TRUE if the text should be masked, @c FALSE otherwise. - */ -void gnt_entry_set_masked(GntEntry *entry, gboolean set); - -/** - * Add a text to the history list for the text. The history length for the - * entry box needs to be set first by gnt_entry_set_history_length. - * - * @param entry The entry box. - * @param text A new entry for the history list. - */ -void gnt_entry_add_to_history(GntEntry *entry, const char *text); - -/** - * Set the length of history for the entry box. - * - * @param entry The entry box. - * @param num The maximum length of the history. - */ -void gnt_entry_set_history_length(GntEntry *entry, int num); - -/** - * Set whether the suggestions are for the entire entry box, or for each - * individual word in the entry box. - * - * @param entry The entry box. - * @param word @c TRUE if the suggestions are for individual words, @c FALSE otherwise. - */ -void gnt_entry_set_word_suggest(GntEntry *entry, gboolean word); - -/** - * Set whether to always display the suggestions list, or only when the - * tab-completion key is pressed (the TAB key, by default). - * - * @param entry The entry box. - * @param always @c TRUE if the suggestion list should always be displayed. - */ -void gnt_entry_set_always_suggest(GntEntry *entry, gboolean always); - -/** - * Add an item to the suggestion list. - * - * @param entry The entry box. - * @param text An item to add to the suggestion list. - */ -void gnt_entry_add_suggest(GntEntry *entry, const char *text); - -/** - * Remove an entry from the suggestion list. - * - * @param entry The entry box. - * @param text The item to remove from the suggestion list. - */ -void gnt_entry_remove_suggest(GntEntry *entry, const char *text); - -G_END_DECLS - -#endif /* GNT_ENTRY_H */
--- a/finch/libgnt/gntfilesel.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,786 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "FileSel" - -#include "gntbutton.h" -#include "gntentry.h" -#include "gntfilesel.h" -#include "gntlabel.h" -#include "gntmarshal.h" -#include "gntstyle.h" -#include "gnttree.h" - -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#if 0 -#include <glob.h> -#endif - -enum -{ - SIG_FILE_SELECTED, - SIGS -}; - -static GntWindowClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; -static void (*orig_map)(GntWidget *widget); -static void (*orig_size_request)(GntWidget *widget); - -static void select_activated_cb(GntWidget *button, GntFileSel *sel); - -static void -gnt_file_sel_destroy(GntWidget *widget) -{ - GntFileSel *sel = GNT_FILE_SEL(widget); - g_free(sel->current); - g_free(sel->suggest); - if (sel->tags) { - g_list_foreach(sel->tags, (GFunc)g_free, NULL); - g_list_free(sel->tags); - } -} - -#if !GLIB_CHECK_VERSION(2,8,0) -/* ripped from glib/gfileutils.c */ -static gchar * -g_build_path_va (const gchar *separator, - gchar **str_array) -{ - GString *result; - gint separator_len = strlen (separator); - gboolean is_first = TRUE; - gboolean have_leading = FALSE; - const gchar *single_element = NULL; - const gchar *next_element; - const gchar *last_trailing = NULL; - gint i = 0; - - result = g_string_new (NULL); - - next_element = str_array[i++]; - - while (TRUE) { - const gchar *element; - const gchar *start; - const gchar *end; - - if (next_element) { - element = next_element; - next_element = str_array[i++]; - } else - break; - - /* Ignore empty elements */ - if (!*element) - continue; - - start = element; - - if (separator_len) { - while (start && - strncmp (start, separator, separator_len) == 0) - start += separator_len; - } - - end = start + strlen (start); - - if (separator_len) { - while (end >= start + separator_len && - strncmp (end - separator_len, separator, separator_len) == 0) - end -= separator_len; - - last_trailing = end; - while (last_trailing >= element + separator_len && - strncmp (last_trailing - separator_len, separator, separator_len) == 0) - last_trailing -= separator_len; - - if (!have_leading) { - /* If the leading and trailing separator strings are in the - * same element and overlap, the result is exactly that element - */ - if (last_trailing <= start) - single_element = element; - - g_string_append_len (result, element, start - element); - have_leading = TRUE; - } else - single_element = NULL; - } - - if (end == start) - continue; - - if (!is_first) - g_string_append (result, separator); - - g_string_append_len (result, start, end - start); - is_first = FALSE; - } - - if (single_element) { - g_string_free (result, TRUE); - return g_strdup (single_element); - } else { - if (last_trailing) - g_string_append (result, last_trailing); - - return g_string_free (result, FALSE); - } -} - -static gchar * -g_build_pathv (const gchar *separator, - gchar **args) -{ - if (!args) - return NULL; - - return g_build_path_va (separator, args); -} - -#endif - -static char * -process_path(const char *path) -{ - char **splits = NULL; - int i, j; - char *str, *ret; - - splits = g_strsplit(path, G_DIR_SEPARATOR_S, -1); - for (i = 0, j = 0; splits[i]; i++) { - if (strcmp(splits[i], ".") == 0) { - g_free(splits[i]); - splits[i] = NULL; - } else if (strcmp(splits[i], "..") == 0) { - if (j) - j--; - g_free(splits[i]); - splits[i] = NULL; - } else { - if (i != j) { - g_free(splits[j]); - splits[j] = splits[i]; - splits[i] = NULL; - } - j++; - } - } - g_free(splits[j]); - splits[j] = NULL; - str = g_build_pathv(G_DIR_SEPARATOR_S, splits); - ret = g_strdup_printf(G_DIR_SEPARATOR_S "%s", str); - g_free(str); - g_strfreev(splits); - return ret; -} - -static void -update_location(GntFileSel *sel) -{ - char *old; - const char *tmp; - tmp = sel->suggest ? sel->suggest : - (const char*)gnt_tree_get_selection_data(sel->dirsonly ? GNT_TREE(sel->dirs) : GNT_TREE(sel->files)); - old = g_strdup_printf("%s%s%s", SAFE(sel->current), SAFE(sel->current)[1] ? G_DIR_SEPARATOR_S : "", tmp ? tmp : ""); - gnt_entry_set_text(GNT_ENTRY(sel->location), old); - g_free(old); -} - -static gboolean -is_tagged(GntFileSel *sel, const char *f) -{ - char *ret = g_strdup_printf("%s%s%s", sel->current, sel->current[1] ? G_DIR_SEPARATOR_S : "", f); - gboolean find = g_list_find_custom(sel->tags, ret, (GCompareFunc)g_utf8_collate) != NULL; - g_free(ret); - return find; -} - -GntFile* gnt_file_new_dir(const char *name) -{ - GntFile *file = g_new0(GntFile, 1); - file->basename = g_strdup(name); - file->type = GNT_FILE_DIR; - return file; -} - -GntFile* gnt_file_new(const char *name, unsigned long size) -{ - GntFile *file = g_new0(GntFile, 1); - file->basename = g_strdup(name); - file->type = GNT_FILE_REGULAR; - file->size = size; - return file; -} - -static gboolean -local_read_fn(const char *path, GList **files, GError **error) -{ - GDir *dir; - GntFile *file; - const char *str; - - dir = g_dir_open(path, 0, error); - if (dir == NULL || (error && *error)) { - return FALSE; - } - - *files = NULL; - if (*path != '\0' && strcmp(path, G_DIR_SEPARATOR_S)) { - file = gnt_file_new_dir(".."); - *files = g_list_prepend(*files, file); - } - - while ((str = g_dir_read_name(dir)) != NULL) { - char *fp = g_build_filename(path, str, NULL); - struct stat st; - - if (stat(fp, &st)) { - gnt_warning("Error stating location %s", fp); - } else { - if (S_ISDIR(st.st_mode)) { - file = gnt_file_new_dir(str); - } else { - file = gnt_file_new(str, (long)st.st_size); - } - *files = g_list_prepend(*files, file); - } - g_free(fp); - } - g_dir_close(dir); - - *files = g_list_reverse(*files); - return TRUE; -} - -static void -gnt_file_free(GntFile *file) -{ - g_free(file->fullpath); - g_free(file->basename); - g_free(file); -} - -static gboolean -location_changed(GntFileSel *sel, GError **err) -{ - GList *files, *iter; - gboolean success; - - if (!sel->dirs) - return TRUE; - - gnt_tree_remove_all(GNT_TREE(sel->dirs)); - if (sel->files) - gnt_tree_remove_all(GNT_TREE(sel->files)); - gnt_entry_set_text(GNT_ENTRY(sel->location), NULL); - if (sel->current == NULL) { - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(sel), GNT_WIDGET_MAPPED)) - gnt_widget_draw(GNT_WIDGET(sel)); - return TRUE; - } - - /* XXX:\ - * XXX: This is blocking. - * XXX:/ - */ - files = NULL; - if (sel->read_fn) - success = sel->read_fn(sel->current, &files, err); - else - success = local_read_fn(sel->current, &files, err); - - if (!success || *err) { - gnt_warning("error opening location %s (%s)", - sel->current, *err ? (*err)->message : "reason unknown"); - return FALSE; - } - - for (iter = files; iter; iter = iter->next) { - GntFile *file = iter->data; - char *str = file->basename; - if (file->type == GNT_FILE_DIR) { - gnt_tree_add_row_after(GNT_TREE(sel->dirs), g_strdup(str), - gnt_tree_create_row(GNT_TREE(sel->dirs), str), NULL, NULL); - if (sel->multiselect && sel->dirsonly && is_tagged(sel, str)) - gnt_tree_set_row_flags(GNT_TREE(sel->dirs), (gpointer)str, GNT_TEXT_FLAG_BOLD); - } else if (!sel->dirsonly) { - char size[128]; - snprintf(size, sizeof(size), "%ld", file->size); - - gnt_tree_add_row_after(GNT_TREE(sel->files), g_strdup(str), - gnt_tree_create_row(GNT_TREE(sel->files), str, size, ""), NULL, NULL); - if (sel->multiselect && is_tagged(sel, str)) - gnt_tree_set_row_flags(GNT_TREE(sel->files), (gpointer)str, GNT_TEXT_FLAG_BOLD); - } - } - g_list_foreach(files, (GFunc)gnt_file_free, NULL); - g_list_free(files); - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(sel), GNT_WIDGET_MAPPED)) - gnt_widget_draw(GNT_WIDGET(sel)); - return TRUE; -} - -static gboolean -dir_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) -{ - if (strcmp(key, "\r") == 0 || strcmp(key, "\n") == 0) { - char *str = g_strdup(gnt_tree_get_selection_data(tree)); - char *path, *dir; - - if (!str) - return TRUE; - - path = g_build_filename(sel->current, str, NULL); - dir = g_path_get_basename(sel->current); - if (!gnt_file_sel_set_current_location(sel, path)) { - gnt_tree_set_selected(tree, str); - } else if (strcmp(str, "..") == 0) { - gnt_tree_set_selected(tree, dir); - } - gnt_bindable_perform_action_named(GNT_BINDABLE(tree), "end-search", NULL); - g_free(dir); - g_free(str); - g_free(path); - return TRUE; - } - return FALSE; -} - -static gboolean -location_key_pressed(GntTree *tree, const char *key, GntFileSel *sel) -{ - char *path; - char *str; -#if 0 - int count; - glob_t gl; - struct stat st; - int glob_ret; -#endif - if (strcmp(key, "\r") && strcmp(key, "\n")) - return FALSE; - - str = (char*)gnt_entry_get_text(GNT_ENTRY(sel->location)); - if (*str == G_DIR_SEPARATOR) - path = g_strdup(str); - else - path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", sel->current, str); - str = process_path(path); - g_free(path); - path = str; - - if (gnt_file_sel_set_current_location(sel, path)) - goto success; - - path = g_path_get_dirname(str); - g_free(str); - - if (!gnt_file_sel_set_current_location(sel, path)) { - g_free(path); - return FALSE; - } -#if 0 - /* XXX: there needs to be a way to allow other methods for globbing, - * like the read_fn stuff. */ - glob_ret = glob(path, GLOB_MARK, NULL, &gl); - if (!glob_ret) { /* XXX: do something with the return value */ - char *loc = g_path_get_dirname(gl.gl_pathv[0]); - - stat(gl.gl_pathv[0], &st); - gnt_file_sel_set_current_location(sel, loc); /* XXX: check the return value */ - g_free(loc); - if (!S_ISDIR(st.st_mode) && !sel->dirsonly) { - gnt_tree_remove_all(GNT_TREE(sel->files)); - for (count = 0; count < gl.gl_pathc; count++) { - char *tmp = process_path(gl.gl_pathv[count]); - loc = g_path_get_dirname(tmp); - if (g_utf8_collate(sel->current, loc) == 0) { - char *base = g_path_get_basename(tmp); - char size[128]; - snprintf(size, sizeof(size), "%ld", (long)st.st_size); - gnt_tree_add_row_after(GNT_TREE(sel->files), base, - gnt_tree_create_row(GNT_TREE(sel->files), base, size, ""), NULL, NULL); - } - g_free(loc); - g_free(tmp); - } - gnt_widget_draw(sel->files); - } - } else if (sel->files) { - gnt_tree_remove_all(GNT_TREE(sel->files)); - gnt_widget_draw(sel->files); - } - globfree(&gl); -#endif -success: - g_free(path); - return TRUE; -} - -static void -file_sel_changed(GntWidget *widget, gpointer old, gpointer current, GntFileSel *sel) -{ - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) { - g_free(sel->suggest); - sel->suggest = NULL; - update_location(sel); - } -} - -static void -gnt_file_sel_map(GntWidget *widget) -{ - GntFileSel *sel = GNT_FILE_SEL(widget); - GntWidget *hbox, *vbox; - - if (sel->current == NULL) - gnt_file_sel_set_current_location(sel, g_get_home_dir()); - - vbox = gnt_vbox_new(FALSE); - gnt_box_set_pad(GNT_BOX(vbox), 0); - gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID); - - /* The dir. and files list */ - hbox = gnt_hbox_new(FALSE); - gnt_box_set_pad(GNT_BOX(hbox), 0); - - gnt_box_add_widget(GNT_BOX(hbox), sel->dirs); - - if (!sel->dirsonly) { - gnt_box_add_widget(GNT_BOX(hbox), sel->files); - } else { - g_signal_connect(G_OBJECT(sel->dirs), "selection_changed", G_CALLBACK(file_sel_changed), sel); - } - - gnt_box_add_widget(GNT_BOX(vbox), hbox); - gnt_box_add_widget(GNT_BOX(vbox), sel->location); - - /* The buttons */ - hbox = gnt_hbox_new(FALSE); - gnt_box_add_widget(GNT_BOX(hbox), sel->cancel); - gnt_box_add_widget(GNT_BOX(hbox), sel->select); - gnt_box_add_widget(GNT_BOX(vbox), hbox); - - gnt_box_add_widget(GNT_BOX(sel), vbox); - orig_map(widget); - update_location(sel); -} - -static gboolean -toggle_tag_selection(GntBindable *bind, GList *null) -{ - GntFileSel *sel = GNT_FILE_SEL(bind); - char *str; - GList *find; - char *file; - GntWidget *tree; - - if (!sel->multiselect) - return FALSE; - tree = sel->dirsonly ? sel->dirs : sel->files; - if (!gnt_widget_has_focus(tree) || - gnt_tree_is_searching(GNT_TREE(tree))) - return FALSE; - - file = gnt_tree_get_selection_data(GNT_TREE(tree)); - - str = gnt_file_sel_get_selected_file(sel); - if ((find = g_list_find_custom(sel->tags, str, (GCompareFunc)g_utf8_collate)) != NULL) { - g_free(find->data); - sel->tags = g_list_delete_link(sel->tags, find); - gnt_tree_set_row_flags(GNT_TREE(tree), file, GNT_TEXT_FLAG_NORMAL); - g_free(str); - } else { - sel->tags = g_list_prepend(sel->tags, str); - gnt_tree_set_row_flags(GNT_TREE(tree), file, GNT_TEXT_FLAG_BOLD); - } - - gnt_bindable_perform_action_named(GNT_BINDABLE(tree), "move-down", NULL); - - return TRUE; -} - -static gboolean -clear_tags(GntBindable *bind, GList *null) -{ - GntFileSel *sel = GNT_FILE_SEL(bind); - GntWidget *tree; - GList *iter; - - if (!sel->multiselect) - return FALSE; - tree = sel->dirsonly ? sel->dirs : sel->files; - if (!gnt_widget_has_focus(tree) || - gnt_tree_is_searching(GNT_TREE(tree))) - return FALSE; - - g_list_foreach(sel->tags, (GFunc)g_free, NULL); - g_list_free(sel->tags); - sel->tags = NULL; - - for (iter = GNT_TREE(tree)->list; iter; iter = iter->next) - gnt_tree_set_row_flags(GNT_TREE(tree), iter->data, GNT_TEXT_FLAG_NORMAL); - - return TRUE; -} - -static gboolean -up_directory(GntBindable *bind, GList *null) -{ - char *path, *dir; - GntFileSel *sel = GNT_FILE_SEL(bind); - if (!gnt_widget_has_focus(sel->dirs) && - !gnt_widget_has_focus(sel->files)) - return FALSE; - if (gnt_tree_is_searching(GNT_TREE(sel->dirs)) || - gnt_tree_is_searching(GNT_TREE(sel->files))) - return FALSE; - - path = g_build_filename(sel->current, "..", NULL); - dir = g_path_get_basename(sel->current); - if (gnt_file_sel_set_current_location(sel, path)) - gnt_tree_set_selected(GNT_TREE(sel->dirs), dir); - g_free(dir); - g_free(path); - return TRUE; -} - -static void -gnt_file_sel_size_request(GntWidget *widget) -{ - GntFileSel *sel; - if (widget->priv.height > 0) - return; - - sel = GNT_FILE_SEL(widget); - sel->dirs->priv.height = 16; - sel->files->priv.height = 16; - orig_size_request(widget); -} - -static void -gnt_file_sel_class_init(GntFileSelClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - GntWidgetClass *kl = GNT_WIDGET_CLASS(klass); - parent_class = GNT_WINDOW_CLASS(klass); - kl->destroy = gnt_file_sel_destroy; - orig_map = kl->map; - kl->map = gnt_file_sel_map; - orig_size_request = kl->size_request; - kl->size_request = gnt_file_sel_size_request; - - signals[SIG_FILE_SELECTED] = - g_signal_new("file_selected", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntFileSelClass, file_selected), - NULL, NULL, - gnt_closure_marshal_VOID__STRING_STRING, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); - - gnt_bindable_class_register_action(bindable, "toggle-tag", toggle_tag_selection, "t", NULL); - gnt_bindable_class_register_action(bindable, "clear-tags", clear_tags, "c", NULL); - gnt_bindable_class_register_action(bindable, "up-directory", up_directory, GNT_KEY_BACKSPACE, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); - - GNTDEBUG; -} - -static void -gnt_file_sel_init(GTypeInstance *instance, gpointer class) -{ - GntFileSel *sel = GNT_FILE_SEL(instance); - - sel->dirs = gnt_tree_new(); - gnt_tree_set_compare_func(GNT_TREE(sel->dirs), (GCompareFunc)g_utf8_collate); - gnt_tree_set_hash_fns(GNT_TREE(sel->dirs), g_str_hash, g_str_equal, g_free); - gnt_tree_set_column_titles(GNT_TREE(sel->dirs), "Directories"); - gnt_tree_set_show_title(GNT_TREE(sel->dirs), TRUE); - gnt_tree_set_col_width(GNT_TREE(sel->dirs), 0, 20); - g_signal_connect(G_OBJECT(sel->dirs), "key_pressed", G_CALLBACK(dir_key_pressed), sel); - - sel->files = gnt_tree_new_with_columns(2); /* Name, Size */ - gnt_tree_set_compare_func(GNT_TREE(sel->files), (GCompareFunc)g_utf8_collate); - gnt_tree_set_hash_fns(GNT_TREE(sel->files), g_str_hash, g_str_equal, g_free); - gnt_tree_set_column_titles(GNT_TREE(sel->files), "Filename", "Size"); - gnt_tree_set_show_title(GNT_TREE(sel->files), TRUE); - gnt_tree_set_col_width(GNT_TREE(sel->files), 0, 25); - gnt_tree_set_col_width(GNT_TREE(sel->files), 1, 10); - gnt_tree_set_column_is_right_aligned(GNT_TREE(sel->files), 1, TRUE); - g_signal_connect(G_OBJECT(sel->files), "selection_changed", G_CALLBACK(file_sel_changed), sel); - - /* The location entry */ - sel->location = gnt_entry_new(NULL); - g_signal_connect(G_OBJECT(sel->location), "key_pressed", G_CALLBACK(location_key_pressed), sel); - - sel->cancel = gnt_button_new("Cancel"); - sel->select = gnt_button_new("Select"); - - g_signal_connect_swapped(G_OBJECT(sel->files), "activate", G_CALLBACK(gnt_widget_activate), sel->select); - g_signal_connect(G_OBJECT(sel->select), "activate", G_CALLBACK(select_activated_cb), sel); -} - -/****************************************************************************** - * GntFileSel API - *****************************************************************************/ -GType -gnt_file_sel_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntFileSelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_file_sel_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntFileSel), - 0, /* n_preallocs */ - gnt_file_sel_init, /* instance_init */ - NULL - }; - - type = g_type_register_static(GNT_TYPE_WINDOW, - "GntFileSel", - &info, 0); - } - - return type; -} - -static void -select_activated_cb(GntWidget *button, GntFileSel *sel) -{ - char *path = gnt_file_sel_get_selected_file(sel); - char *file = g_path_get_basename(path); - g_signal_emit(sel, signals[SIG_FILE_SELECTED], 0, path, file); - g_free(file); - g_free(path); -} - -GntWidget *gnt_file_sel_new(void) -{ - GntWidget *widget = g_object_new(GNT_TYPE_FILE_SEL, NULL); - return widget; -} - -gboolean gnt_file_sel_set_current_location(GntFileSel *sel, const char *path) -{ - char *old; - GError *error = NULL; - gboolean ret = TRUE; - - old = sel->current; - sel->current = process_path(path); - if (!location_changed(sel, &error)) { - g_error_free(error); - error = NULL; - g_free(sel->current); - sel->current = old; - location_changed(sel, &error); - ret = FALSE; - } else - g_free(old); - - update_location(sel); - return ret; -} - -void gnt_file_sel_set_dirs_only(GntFileSel *sel, gboolean dirs) -{ - sel->dirsonly = dirs; -} - -gboolean gnt_file_sel_get_dirs_only(GntFileSel *sel) -{ - return sel->dirsonly; -} - -void gnt_file_sel_set_suggested_filename(GntFileSel *sel, const char *suggest) -{ - g_free(sel->suggest); - sel->suggest = g_strdup(suggest); -} - -char *gnt_file_sel_get_selected_file(GntFileSel *sel) -{ - char *ret; - if (sel->dirsonly) { - ret = g_path_get_dirname(gnt_entry_get_text(GNT_ENTRY(sel->location))); - } else { - ret = g_strdup(gnt_entry_get_text(GNT_ENTRY(sel->location))); - } - return ret; -} - -void gnt_file_sel_set_must_exist(GntFileSel *sel, gboolean must) -{ - /*XXX: What do I do with this? */ - sel->must_exist = must; -} - -gboolean gnt_file_sel_get_must_exist(GntFileSel *sel) -{ - return sel->must_exist; -} - -void gnt_file_sel_set_multi_select(GntFileSel *sel, gboolean set) -{ - sel->multiselect = set; -} - -GList *gnt_file_sel_get_selected_multi_files(GntFileSel *sel) -{ - GList *list = NULL, *iter; - char *str = gnt_file_sel_get_selected_file(sel); - - for (iter = sel->tags; iter; iter = iter->next) { - list = g_list_prepend(list, g_strdup(iter->data)); - if (g_utf8_collate(str, iter->data)) { - g_free(str); - str = NULL; - } - } - if (str) - list = g_list_prepend(list, str); - list = g_list_reverse(list); - return list; -} - -void gnt_file_sel_set_read_fn(GntFileSel *sel, gboolean (*read_fn)(const char *path, GList **files, GError **error)) -{ - sel->read_fn = read_fn; -} - -
--- a/finch/libgnt/gntfilesel.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -/** - * @file gntfilesel.h File selector API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_FILE_SEL_H -#define GNT_FILE_SEL_H - -#include "gntwindow.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_FILE_SEL (gnt_file_sel_get_gtype()) -#define GNT_FILE_SEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_FILE_SEL, GntFileSel)) -#define GNT_FILE_SEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_FILE_SEL, GntFileSelClass)) -#define GNT_IS_FILE_SEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_FILE_SEL)) -#define GNT_IS_FILE_SEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_FILE_SEL)) -#define GNT_FILE_SEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_FILE_SEL, GntFileSelClass)) - -#define GNT_FILE_SEL_FLAGS(obj) (GNT_FILE_SEL(obj)->priv.flags) -#define GNT_FILE_SEL_SET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) |= flags) -#define GNT_FILE_SEL_UNSET_FLAGS(obj, flags) (GNT_FILE_SEL_FLAGS(obj) &= ~(flags)) - -typedef struct _GntFileSel GntFileSel; -typedef struct _GntFileSelPriv GntFileSelPriv; -typedef struct _GntFileSelClass GntFileSelClass; -typedef struct _GntFile GntFile; - -struct _GntFileSel -{ - GntWindow parent; - - GntWidget *dirs; /* list of files */ - GntWidget *files; /* list of directories */ - GntWidget *location; /* location entry */ - - GntWidget *select; /* select button */ - GntWidget *cancel; /* cancel button */ - - char *current; /* Full path of the current location */ - char *suggest; /* Suggested filename */ - /* XXX: someone should make these useful */ - gboolean must_exist; /* Make sure the selected file (the name entered in 'location') exists */ - gboolean dirsonly; /* Show only directories */ - gboolean multiselect; - GList *tags; /* List of tagged files when multiselect is set */ - - gboolean (*read_fn)(const char *path, GList **files, GError **error); -}; - -struct _GntFileSelClass -{ - GntWindowClass parent; - - void (*file_selected)(GntFileSel *sel, const char *path, const char *filename); - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -typedef enum _GntFileType -{ - GNT_FILE_REGULAR, - GNT_FILE_DIR -} GntFileType; - -struct _GntFile -{ - char *fullpath; - char *basename; - GntFileType type; - unsigned long size; -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntFileSel. - */ -GType gnt_file_sel_get_gtype(void); - -/** - * Create a new file selector. - * - * @return The newly created file selector. - */ -GntWidget * gnt_file_sel_new(void); - -/** - * Set the current location of the file selector. - * - * @param sel The file selector. - * @param path The current path of the selector. - * - * @return @c TRUE if the current location was successfully changed, @c FALSE otherwise. - */ -gboolean gnt_file_sel_set_current_location(GntFileSel *sel, const char *path); - -/** - * Set wheter to only allow selecting directories. - * - * @param sel The file selector. - * @param dirs @c TRUE if only directories can be selected, @c FALSE if files - * can also be selected. - */ -void gnt_file_sel_set_dirs_only(GntFileSel *sel, gboolean dirs); - -/** - * Check whether the file selector allows only selecting directories. - * - * @param sel The file selector. - * - * @return @c TRUE if only directories can be selected. - */ -gboolean gnt_file_sel_get_dirs_only(GntFileSel *sel); - -/** - * Set whether a selected file must exist. - * - * @param sel The file selector. - * @param must @c TRUE if the selected file must exist. - */ -void gnt_file_sel_set_must_exist(GntFileSel *sel, gboolean must); - -/** - * Check whether the selector allows selecting non-existent files. - * - * @param sel The file selector. - * - * @return @c TRUE if the selected file must exist, @c FALSE if a non-existent - * file can be selected. - */ -gboolean gnt_file_sel_get_must_exist(GntFileSel *sel); - -/** - * Get the selected file in the selector. - * - * @param sel The file selector. - * - * @return The path of the selected file. The caller should g_free the returned - * string. - */ -char * gnt_file_sel_get_selected_file(GntFileSel *sel); - -/** - * Get the list of selected files in the selector. - * - * @param sel The file selector. - * - * @return A list of paths for the selected files. The caller must g_free the - * contents of the list, and g_list_free the list. - */ -GList * gnt_file_sel_get_selected_multi_files(GntFileSel *sel); - -/** - * Allow selecting multiple files. - * - * @param sel The file selector. - * @param set @c TRUE if selecting multiple files should be allowed. - */ -void gnt_file_sel_set_multi_select(GntFileSel *sel, gboolean set); - -/** - * Set the suggested file to have selected at startup. - * - * @param sel The file selector. - * @param suggest The suggested filename. - */ -void gnt_file_sel_set_suggested_filename(GntFileSel *sel, const char *suggest); - -/** - * Set custom functions to read the names of files. - * - * @param sel The file selector. - * @param read_fn The custom read function. - */ -void gnt_file_sel_set_read_fn(GntFileSel *sel, gboolean (*read_fn)(const char *path, GList **files, GError **error)); - -/** - * Create a new GntFile. - * - * @param name The name of the file. - * @param size The size of the file. - * - * @return The newly created GntFile. - */ -GntFile* gnt_file_new(const char *name, unsigned long size); - -/** - * Create a new GntFile for a directory. - * - * @param name The name of the directory. - * - * @return The newly created GntFile. - */ -GntFile* gnt_file_new_dir(const char *name); - -G_END_DECLS - -#endif /* GNT_FILE_SEL_H */ -
--- a/finch/libgnt/gntinternal.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ -#include <glib.h> -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "Gnt" - -#ifdef __GNUC__ -# ifndef GNT_LOG_DOMAIN -# define GNT_LOG_DOMAIN "" -# endif -# define gnt_warning(format, args...) g_warning("(%s) %s: " format, GNT_LOG_DOMAIN, __PRETTY_FUNCTION__, args) -#else /* __GNUC__ */ -# define gnt_warning g_warning -#endif - -#ifndef G_GNUC_NULL_TERMINATED -# if defined(__GNUC__) && __GNUC__ >= 4 -# define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) -# else -# define G_GNUC_NULL_TERMINATED -# endif -#endif - -extern int gnt_need_conversation_to_locale; -extern const char *C_(const char *x); -
--- a/finch/libgnt/gntkeys.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,312 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Keys" - -#include "gntkeys.h" - -#include <glib.h> -#include <stdlib.h> -#include <string.h> - -char *gnt_key_cup; -char *gnt_key_cdown; -char *gnt_key_cleft; -char *gnt_key_cright; - -static const char *term; -static GHashTable *specials; - -void gnt_init_keys() -{ - const char *controls[] = {"", "c-", "ctrl-", "ctr-", "ctl-", NULL}; - const char *alts[] = {"", "alt-", "a-", "m-", "meta-", NULL}; - int c, a, ch; - char key[32]; - - if (term == NULL) { - term = getenv("TERM"); - if (!term) - term = ""; /* Just in case */ - } - - if (strstr(term, "xterm") == term || strcmp(term, "rxvt") == 0) { - gnt_key_cup = "\033" "[1;5A"; - gnt_key_cdown = "\033" "[1;5B"; - gnt_key_cright = "\033" "[1;5C"; - gnt_key_cleft = "\033" "[1;5D"; - } else if (strstr(term, "screen") == term || strcmp(term, "rxvt-unicode") == 0) { - gnt_key_cup = "\033" "Oa"; - gnt_key_cdown = "\033" "Ob"; - gnt_key_cright = "\033" "Oc"; - gnt_key_cleft = "\033" "Od"; - } - - specials = g_hash_table_new(g_str_hash, g_str_equal); - -#define INSERT_KEY(k, code) do { \ - g_hash_table_insert(specials, g_strdup(k), g_strdup(code)); \ - gnt_keys_add_combination(code); \ - } while (0) - - INSERT_KEY("home", GNT_KEY_HOME); - INSERT_KEY("end", GNT_KEY_END); - INSERT_KEY("pageup", GNT_KEY_PGUP); - INSERT_KEY("pagedown", GNT_KEY_PGDOWN); - INSERT_KEY("insert", GNT_KEY_INS); - INSERT_KEY("delete", GNT_KEY_DEL); - INSERT_KEY("back_tab", GNT_KEY_BACK_TAB); - - INSERT_KEY("left", GNT_KEY_LEFT); - INSERT_KEY("right", GNT_KEY_RIGHT); - INSERT_KEY("up", GNT_KEY_UP); - INSERT_KEY("down", GNT_KEY_DOWN); - - INSERT_KEY("tab", "\t"); - INSERT_KEY("escape", "\033"); - INSERT_KEY("space", " "); - INSERT_KEY("return", GNT_KEY_ENTER); - INSERT_KEY("menu", GNT_KEY_POPUP); - - INSERT_KEY("f1", GNT_KEY_F1); - INSERT_KEY("f2", GNT_KEY_F2); - INSERT_KEY("f3", GNT_KEY_F3); - INSERT_KEY("f4", GNT_KEY_F4); - INSERT_KEY("f5", GNT_KEY_F5); - INSERT_KEY("f6", GNT_KEY_F6); - INSERT_KEY("f7", GNT_KEY_F7); - INSERT_KEY("f8", GNT_KEY_F8); - INSERT_KEY("f9", GNT_KEY_F9); - INSERT_KEY("f10", GNT_KEY_F10); - INSERT_KEY("f11", GNT_KEY_F11); - INSERT_KEY("f12", GNT_KEY_F12); - -#define REM_LENGTH (sizeof(key) - (cur - key)) -#define INSERT_COMB(k, code) do { \ - snprintf(key, sizeof(key), "%s%s%s", controls[c], alts[a], k); \ - INSERT_KEY(key, code); \ - } while (0) -#define INSERT_COMB_CODE(k, c1, c2) do { \ - char __[32]; \ - snprintf(__, sizeof(__), "%s%s", c1, c2); \ - INSERT_COMB(k, __); \ - } while (0) - - /* Lower-case alphabets */ - for (a = 0, c = 0; controls[c]; c++, a = 0) { - if (c) { - INSERT_COMB("up", gnt_key_cup); - INSERT_COMB("down", gnt_key_cdown); - INSERT_COMB("left", gnt_key_cleft); - INSERT_COMB("right", gnt_key_cright); - } - - for (a = 0; alts[a]; a++) { - for (ch = 0; ch < 26; ch++) { - char str[2] = {'a' + ch, 0}, code[4] = "\0\0\0\0"; - int ind = 0; - if (a) - code[ind++] = '\033'; - code[ind] = (c ? 1 : 'a') + ch; - INSERT_COMB(str, code); - } - if (c == 0 && a) { - INSERT_COMB("tab", "\033\t"); - INSERT_COMB_CODE("up", "\033", GNT_KEY_UP); - INSERT_COMB_CODE("down", "\033", GNT_KEY_DOWN); - INSERT_COMB_CODE("left", "\033", GNT_KEY_LEFT); - INSERT_COMB_CODE("right", "\033", GNT_KEY_RIGHT); - } - } - } - c = 0; - for (a = 0; alts[a]; a++) { - /* Upper-case alphabets */ - for (ch = 0; ch < 26; ch++) { - char str[2] = {'A' + ch, 0}, code[] = {'\033', 'A' + ch, 0}; - INSERT_COMB(str, code); - } - /* Digits */ - for (ch = 0; ch < 10; ch++) { - char str[2] = {'0' + ch, 0}, code[] = {'\033', '0' + ch, 0}; - INSERT_COMB(str, code); - } - } -} - -void gnt_keys_refine(char *text) -{ - while (*text == 27 && *(text + 1) == 27) - text++; - if (*text == 27 && *(text + 1) == '[' && - (*(text + 2) >= 'A' && *(text + 2) <= 'D')) { - /* Apparently this is necessary for urxvt and screen and xterm */ - if (strstr(term, "screen") == term || strcmp(term, "rxvt-unicode") == 0 || - strstr(term, "xterm") == term || - strstr(term, "vt100") == term) - *(text + 1) = 'O'; - } else if (g_utf8_get_char(text) == 195) { - if (*(text + 2) == 0 && strstr(term, "xterm") == term) { - *(text) = 27; - *(text + 1) -= 64; /* Say wha? */ - } - } -} - -const char *gnt_key_translate(const char *name) -{ - return name ? g_hash_table_lookup(specials, name) : NULL; -} - -typedef struct { - const char *name; - const char *key; -} gntkey; - -static void -get_key_name(gpointer key, gpointer value, gpointer data) -{ - gntkey *k = data; - if (k->name) - return; - if (g_utf8_collate(value, k->key) == 0) - k->name = key; -} - -const char *gnt_key_lookup(const char *key) -{ - gntkey k = {NULL, key}; - g_hash_table_foreach(specials, get_key_name, &k); - return k.name; -} - -/** - * The key-bindings will be saved in a tree. When a keystroke happens, GNT will - * find the sequence that matches a binding and return the length. - * A sequence should not be a prefix of another sequence. If it is, then only - * the shortest one will be processed. If we want to change that, we will need - * to allow getting the k-th prefix that matches the input, and pay attention - * to the return value of gnt_wm_process_input in gntmain.c. - */ -#define SIZE 256 - -#define IS_END (1 << 0) -struct _node -{ - struct _node *next[SIZE]; - int ref; - int flags; -}; - -static struct _node root = {.ref = 1, .flags = 0}; - -static void add_path(struct _node *node, const char *path) -{ - struct _node *n = NULL; - if (!path || !*path) { - node->flags |= IS_END; - return; - } - while (*path && node->next[(unsigned char)*path]) { - node = node->next[(unsigned char)*path]; - node->ref++; - path++; - } - if (!*path) - return; - n = g_new0(struct _node, 1); - n->ref = 1; - node->next[(unsigned char)*path++] = n; - add_path(n, path); -} - -void gnt_keys_add_combination(const char *path) -{ - add_path(&root, path); -} - -static void del_path(struct _node *node, const char *path) -{ - struct _node *next = NULL; - - if (!*path) - return; - next = node->next[(unsigned char)*path]; - if (!next) - return; - del_path(next, path + 1); - next->ref--; - if (next->ref == 0) { - node->next[(unsigned char)*path] = NULL; - g_free(next); - } -} - -void gnt_keys_del_combination(const char *path) -{ - del_path(&root, path); -} - -int gnt_keys_find_combination(const char *path) -{ - int depth = 0; - struct _node *n = &root; - - root.flags &= ~IS_END; - while (*path && n->next[(unsigned char)*path] && !(n->flags & IS_END)) { - if (!g_ascii_isspace(*path) && - !g_ascii_iscntrl(*path) && - !g_ascii_isgraph(*path)) - return 0; - n = n->next[(unsigned char)*path++]; - depth++; - } - - if (!(n->flags & IS_END)) - depth = 0; - return depth; -} - -static void -print_path(struct _node *node, int depth) -{ - int i; - for (i = 0; i < SIZE; i++) { - if (node->next[i]) { - g_printerr("%*c (%d:%d)\n", depth * 4, i, node->next[i]->ref, - node->next[i]->flags); - print_path(node->next[i], depth + 1); - } - } -} - -/* this is purely for debugging purposes. */ -void gnt_keys_print_combinations(void); -void gnt_keys_print_combinations() -{ - g_printerr("--------\n"); - print_path(&root, 1); - g_printerr("--------\n"); -} -
--- a/finch/libgnt/gntkeys.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/** - * @file gntkeys.h Keys API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_KEYS_H -#define GNT_KEYS_H - -#include <curses.h> -#include <term.h> - -/** - * terminfo/termcap doesn't provide all the information that I want to use, eg. - * ctrl-up, ctrl-down etc. So I am going to hard-code some of the information - * for some popular $TERMs - */ -extern char *gnt_key_cup; -extern char *gnt_key_cdown; -extern char *gnt_key_cleft; -extern char *gnt_key_cright; - -#define SAFE(x) ((x) ? (x) : "") - -#define GNT_KEY_POPUP SAFE(key_f16) /* Apparently */ - -/* Arrow keys */ -#define GNT_KEY_LEFT SAFE(key_left) -#define GNT_KEY_RIGHT SAFE(key_right) -#define GNT_KEY_UP SAFE(key_up) -#define GNT_KEY_DOWN SAFE(key_down) - -#define GNT_KEY_CTRL_UP SAFE(gnt_key_cup) -#define GNT_KEY_CTRL_DOWN SAFE(gnt_key_cdown) -#define GNT_KEY_CTRL_RIGHT SAFE(gnt_key_cright) -#define GNT_KEY_CTRL_LEFT SAFE(gnt_key_cleft) - -#define GNT_KEY_PGUP SAFE(key_ppage) -#define GNT_KEY_PGDOWN SAFE(key_npage) -#define GNT_KEY_HOME SAFE(key_home) -#define GNT_KEY_END SAFE(key_end) - -#define GNT_KEY_ENTER carriage_return - -#define GNT_KEY_BACKSPACE SAFE(key_backspace) -#define GNT_KEY_DEL SAFE(key_dc) -#define GNT_KEY_INS SAFE(key_ic) -#define GNT_KEY_BACK_TAB (back_tab ? back_tab : SAFE(key_btab)) - -#define GNT_KEY_CTRL_A "\001" -#define GNT_KEY_CTRL_B "\002" -#define GNT_KEY_CTRL_D "\004" -#define GNT_KEY_CTRL_E "\005" -#define GNT_KEY_CTRL_F "\006" -#define GNT_KEY_CTRL_G "\007" -#define GNT_KEY_CTRL_H "\010" -#define GNT_KEY_CTRL_I "\011" -#define GNT_KEY_CTRL_J "\012" -#define GNT_KEY_CTRL_K "\013" -#define GNT_KEY_CTRL_L "\014" -#define GNT_KEY_CTRL_M "\012" -#define GNT_KEY_CTRL_N "\016" -#define GNT_KEY_CTRL_O "\017" -#define GNT_KEY_CTRL_P "\020" -#define GNT_KEY_CTRL_R "\022" -#define GNT_KEY_CTRL_T "\024" -#define GNT_KEY_CTRL_U "\025" -#define GNT_KEY_CTRL_V "\026" -#define GNT_KEY_CTRL_W "\027" -#define GNT_KEY_CTRL_X "\030" -#define GNT_KEY_CTRL_Y "\031" - -#define GNT_KEY_F1 SAFE(key_f1) -#define GNT_KEY_F2 SAFE(key_f2) -#define GNT_KEY_F3 SAFE(key_f3) -#define GNT_KEY_F4 SAFE(key_f4) -#define GNT_KEY_F5 SAFE(key_f5) -#define GNT_KEY_F6 SAFE(key_f6) -#define GNT_KEY_F7 SAFE(key_f7) -#define GNT_KEY_F8 SAFE(key_f8) -#define GNT_KEY_F9 SAFE(key_f9) -#define GNT_KEY_F10 SAFE(key_f10) -#define GNT_KEY_F11 SAFE(key_f11) -#define GNT_KEY_F12 SAFE(key_f12) - -/** - * Initialize the keys. - */ -void gnt_init_keys(void); - -/** - * Refine input text. This usually looks at what the terminal claims it is, - * and tries to change the text to work around some oft-broken terminfo entries. - * - * @param text The input text to refine. - */ -void gnt_keys_refine(char *text); - -/** - * Translate a user-readable representation of an input to a machine-readable representation. - * - * @param name The user-readable representation of an input (eg.: c-t) - * - * @return A machine-readable representation of the input. - */ -const char *gnt_key_translate(const char *name); - -/** - * Translate a machine-readable representation of an input to a user-readable representation. - * - * @param key The machine-readable representation of an input. - * - * @return A user-readable representation of the input (eg.: c-t). - */ -const char *gnt_key_lookup(const char *key); - -/** - * Add a key combination to the internal key-tree. - * - * @param key The key to add - */ -void gnt_keys_add_combination(const char *key); - -/** - * Remove a key combination from the internal key-tree. - * - * @param key The key to remove. - */ -void gnt_keys_del_combination(const char *key); - -/** - * Find a combination from the given string. - * - * @param key The input string. - * - * @return The number of bytes in the combination that starts at the beginning - * of key (can be 0). - */ -int gnt_keys_find_combination(const char *key); - -/* A lot of commonly used variable names are defined in <term.h>. - * #undef them to make life easier for everyone. */ - -#undef columns -#undef lines -#undef buttons -#undef newline -#undef set_clock - -#endif
--- a/finch/libgnt/gntlabel.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntlabel.h" -#include "gntutils.h" - -#include <string.h> - -enum -{ - PROP_0, - PROP_TEXT, - PROP_TEXT_FLAG -}; - -enum -{ - SIGS = 1, -}; - -static GntWidgetClass *parent_class = NULL; - -static void -gnt_label_destroy(GntWidget *widget) -{ - GntLabel *label = GNT_LABEL(widget); - g_free(label->text); -} - -static void -gnt_label_draw(GntWidget *widget) -{ - GntLabel *label = GNT_LABEL(widget); - chtype flag = gnt_text_format_flag_to_chtype(label->flags); - - wbkgdset(widget->window, '\0' | flag); - mvwaddstr(widget->window, 0, 0, C_(label->text)); - - GNTDEBUG; -} - -static void -gnt_label_size_request(GntWidget *widget) -{ - GntLabel *label = GNT_LABEL(widget); - - gnt_util_get_text_bound(label->text, - &widget->priv.width, &widget->priv.height); -} - -static void -gnt_label_set_property(GObject *obj, guint prop_id, const GValue *value, - GParamSpec *spec) -{ - GntLabel *label = GNT_LABEL(obj); - switch (prop_id) { - case PROP_TEXT: - g_free(label->text); - label->text = gnt_util_onscreen_fit_string(g_value_get_string(value), -1); - break; - case PROP_TEXT_FLAG: - label->flags = g_value_get_int(value); - break; - default: - g_return_if_reached(); - break; - } -} - -static void -gnt_label_get_property(GObject *obj, guint prop_id, GValue *value, - GParamSpec *spec) -{ - GntLabel *label = GNT_LABEL(obj); - switch (prop_id) { - case PROP_TEXT: - g_value_set_string(value, label->text); - break; - case PROP_TEXT_FLAG: - g_value_set_int(value, label->flags); - break; - default: - break; - } -} - -static void -gnt_label_class_init(GntLabelClass *klass) -{ - GObjectClass *gclass = G_OBJECT_CLASS(klass); - - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->destroy = gnt_label_destroy; - parent_class->draw = gnt_label_draw; - parent_class->map = NULL; - parent_class->size_request = gnt_label_size_request; - - gclass->set_property = gnt_label_set_property; - gclass->get_property = gnt_label_get_property; - - g_object_class_install_property(gclass, - PROP_TEXT, - g_param_spec_string("text", "Text", - "The text for the label.", - NULL, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - - g_object_class_install_property(gclass, - PROP_TEXT_FLAG, - g_param_spec_int("text-flag", "Text flag", - "Text attribute to use when displaying the text in the label.", - GNT_TEXT_FLAG_NORMAL, - GNT_TEXT_FLAG_NORMAL|GNT_TEXT_FLAG_BOLD|GNT_TEXT_FLAG_UNDERLINE| - GNT_TEXT_FLAG_BLINK|GNT_TEXT_FLAG_DIM|GNT_TEXT_FLAG_HIGHLIGHT, - GNT_TEXT_FLAG_NORMAL, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - GNTDEBUG; -} - -static void -gnt_label_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - gnt_widget_set_take_focus(widget, FALSE); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); - widget->priv.minw = 3; - widget->priv.minh = 1; - GNTDEBUG; -} - -/****************************************************************************** - * GntLabel API - *****************************************************************************/ -GType -gnt_label_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntLabelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_label_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntLabel), - 0, /* n_preallocs */ - gnt_label_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntLabel", - &info, 0); - } - - return type; -} - -GntWidget *gnt_label_new(const char *text) -{ - return gnt_label_new_with_format(text, 0); -} - -GntWidget *gnt_label_new_with_format(const char *text, GntTextFormatFlags flags) -{ - GntWidget *widget = g_object_new(GNT_TYPE_LABEL, "text-flag", flags, "text", text, NULL); - return widget; -} - -void gnt_label_set_text(GntLabel *label, const char *text) -{ - g_object_set(label, "text", text, NULL); - - if (GNT_WIDGET(label)->window) - { - werase(GNT_WIDGET(label)->window); - gnt_widget_draw(GNT_WIDGET(label)); - } -} -
--- a/finch/libgnt/gntlabel.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/** - * @file gntlabel.h Label API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_LABEL_H -#define GNT_LABEL_H - -#include "gnt.h" -#include "gntwidget.h" -#include "gnttextview.h" - -#define GNT_TYPE_LABEL (gnt_label_get_gtype()) -#define GNT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LABEL, GntLabel)) -#define GNT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LABEL, GntLabelClass)) -#define GNT_IS_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LABEL)) -#define GNT_IS_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LABEL)) -#define GNT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LABEL, GntLabelClass)) - -typedef struct _GntLabel GntLabel; -typedef struct _GntLabelClass GntLabelClass; - -struct _GntLabel -{ - GntWidget parent; - - char *text; - GntTextFormatFlags flags; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -struct _GntLabelClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntLabel. - */ -GType gnt_label_get_gtype(void); - -/** - * Create a new GntLabel. - * - * @param text The text of the label. - * - * @return The newly created label. - */ -GntWidget * gnt_label_new(const char *text); - -/** - * Create a new label with specified text attributes. - * - * @param text The text. - * @param flags Text attributes for the text. - * - * @return The newly created label. - */ -GntWidget * gnt_label_new_with_format(const char *text, GntTextFormatFlags flags); - -/** - * Change the text of a label. - * - * @param label The label. - * @param text The new text to set in the label. - */ -void gnt_label_set_text(GntLabel *label, const char *text); - -G_END_DECLS - -#endif /* GNT_LABEL_H */ -
--- a/finch/libgnt/gntline.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntline.h" - -enum -{ - PROP_0, - PROP_VERTICAL -}; - -enum -{ - SIGS = 1, -}; - -static GntWidgetClass *parent_class = NULL; - -static void -gnt_line_draw(GntWidget *widget) -{ - GntLine *line = GNT_LINE(widget); - if (line->vertical) - mvwvline(widget->window, 1, 0, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL), - widget->priv.height - 2); - else - mvwhline(widget->window, 0, 1, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), - widget->priv.width - 2); -} - -static void -gnt_line_size_request(GntWidget *widget) -{ - if (GNT_LINE(widget)->vertical) - { - widget->priv.width = 1; - widget->priv.height = 5; - } - else - { - widget->priv.width = 5; - widget->priv.height = 1; - } -} - -static void -gnt_line_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static void -gnt_line_set_property(GObject *obj, guint prop_id, const GValue *value, - GParamSpec *spec) -{ - GntLine *line = GNT_LINE(obj); - switch (prop_id) { - case PROP_VERTICAL: - line->vertical = g_value_get_boolean(value); - if (line->vertical) { - GNT_WIDGET_SET_FLAGS(line, GNT_WIDGET_GROW_Y); - } else { - GNT_WIDGET_SET_FLAGS(line, GNT_WIDGET_GROW_X); - } - break; - default: - break; - } -} - -static void -gnt_line_get_property(GObject *obj, guint prop_id, GValue *value, - GParamSpec *spec) -{ - GntLine *line = GNT_LINE(obj); - switch (prop_id) { - case PROP_VERTICAL: - g_value_set_boolean(value, line->vertical); - break; - default: - break; - } -} - -static void -gnt_line_class_init(GntLineClass *klass) -{ - GObjectClass *gclass = G_OBJECT_CLASS(klass); - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->draw = gnt_line_draw; - parent_class->map = gnt_line_map; - parent_class->size_request = gnt_line_size_request; - - gclass->set_property = gnt_line_set_property; - gclass->get_property = gnt_line_get_property; - g_object_class_install_property(gclass, - PROP_VERTICAL, - g_param_spec_boolean("vertical", "Vertical", - "Whether it's a vertical line or a horizontal one.", - TRUE, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); -} - -static void -gnt_line_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER); - widget->priv.minw = 1; - widget->priv.minh = 1; - GNTDEBUG; -} - -/****************************************************************************** - * GntLine API - *****************************************************************************/ -GType -gnt_line_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntLineClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_line_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntLine), - 0, /* n_preallocs */ - gnt_line_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntLine", - &info, 0); - } - - return type; -} - -GntWidget *gnt_line_new(gboolean vertical) -{ - GntWidget *widget = g_object_new(GNT_TYPE_LINE, "vertical", vertical, NULL); - return widget; -} -
--- a/finch/libgnt/gntline.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/** - * @file gntline.h Line API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_LINE_H -#define GNT_LINE_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_LINE (gnt_line_get_gtype()) -#define GNT_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_LINE, GntLine)) -#define GNT_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_LINE, GntLineClass)) -#define GNT_IS_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_LINE)) -#define GNT_IS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_LINE)) -#define GNT_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_LINE, GntLineClass)) - -#define GNT_LINE_FLAGS(obj) (GNT_LINE(obj)->priv.flags) -#define GNT_LINE_SET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) |= flags) -#define GNT_LINE_UNSET_FLAGS(obj, flags) (GNT_LINE_FLAGS(obj) &= ~(flags)) - -typedef struct _GntLine GntLine; -typedef struct _GntLinePriv GntLinePriv; -typedef struct _GntLineClass GntLineClass; - -struct _GntLine -{ - GntWidget parent; - - gboolean vertical; -}; - -struct _GntLineClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntLine. - */ -GType gnt_line_get_gtype(void); - -#define gnt_hline_new() gnt_line_new(FALSE) -#define gnt_vline_new() gnt_line_new(TRUE) - -/** - * Create new line - * - * @param vertical @c TRUE if the line should be vertical, @c FALSE for a horizontal line. - * - * @return The newly created line. - */ -GntWidget * gnt_line_new(gboolean vertical); - -G_END_DECLS - -#endif /* GNT_LINE_H */
--- a/finch/libgnt/gntmain.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,779 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#define _GNU_SOURCE -#if (defined(__APPLE__) || defined(__unix__)) && !defined(__FreeBSD__) && !defined(__OpenBSD__) -#define _XOPEN_SOURCE_EXTENDED -#endif - -#include "config.h" - -#include <gmodule.h> - -#include <sys/types.h> -#include <sys/wait.h> - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Main" - -#include "gnt.h" -#include "gntbox.h" -#include "gntbutton.h" -#include "gntcolors.h" -#include "gntclipboard.h" -#include "gntkeys.h" -#include "gntlabel.h" -#include "gntmenu.h" -#include "gntstyle.h" -#include "gnttree.h" -#include "gntutils.h" -#include "gntwindow.h" -#include "gntwm.h" - -#include <panel.h> - -#include <stdio.h> -#include <stdlib.h> -#include <locale.h> -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> - -/** - * Notes: Interesting functions to look at: - * scr_dump, scr_init, scr_restore: for workspaces - * - * Need to wattrset for colors to use with PDCurses. - */ - -static GIOChannel *channel = NULL; -static guint channel_read_callback = 0; -static guint channel_error_callback = 0; - -static gboolean ascii_only; -static gboolean mouse_enabled; - -static void setup_io(void); - -static gboolean refresh_screen(void); - -static GntWM *wm; -static GntClipboard *clipboard; - -int gnt_need_conversation_to_locale; - -#define HOLDING_ESCAPE (escape_stuff.timer != 0) - -static struct { - int timer; -} escape_stuff; - -static gboolean -escape_timeout(gpointer data) -{ - gnt_wm_process_input(wm, "\033"); - escape_stuff.timer = 0; - return FALSE; -} - -/** - * Mouse support: - * - bring a window on top if you click on its taskbar - * - click on the top-bar of the active window and drag+drop to move a window - * - click on a window to bring it to focus - * - allow scrolling in tree/textview on wheel-scroll event - * - click to activate button or select a row in tree - * wishlist: - * - have a little [X] on the windows, and clicking it will close that window. - */ -static gboolean -detect_mouse_action(const char *buffer) -{ - int x, y; - static enum { - MOUSE_NONE, - MOUSE_LEFT, - MOUSE_RIGHT, - MOUSE_MIDDLE - } button = MOUSE_NONE; - static GntWidget *remember = NULL; - static int offset = 0; - GntMouseEvent event; - GntWidget *widget = NULL; - PANEL *p = NULL; - - if (!wm->cws->ordered || buffer[0] != 27) - return FALSE; - - buffer++; - if (strlen(buffer) < 5) - return FALSE; - - x = buffer[3]; - y = buffer[4]; - if (x < 0) x += 256; - if (y < 0) y += 256; - x -= 33; - y -= 33; - - while ((p = panel_below(p)) != NULL) { - const GntNode *node = panel_userptr(p); - GntWidget *wid; - if (!node) - continue; - wid = node->me; - if (x >= wid->priv.x && x < wid->priv.x + wid->priv.width) { - if (y >= wid->priv.y && y < wid->priv.y + wid->priv.height) { - widget = wid; - break; - } - } - } - - if (strncmp(buffer, "[M ", 3) == 0) { - /* left button down */ - /* Bring the window you clicked on to front */ - /* If you click on the topbar, then you can drag to move the window */ - event = GNT_LEFT_MOUSE_DOWN; - } else if (strncmp(buffer, "[M\"", 3) == 0) { - /* right button down */ - event = GNT_RIGHT_MOUSE_DOWN; - } else if (strncmp(buffer, "[M!", 3) == 0) { - /* middle button down */ - event = GNT_MIDDLE_MOUSE_DOWN; - } else if (strncmp(buffer, "[M`", 3) == 0) { - /* wheel up*/ - event = GNT_MOUSE_SCROLL_UP; - } else if (strncmp(buffer, "[Ma", 3) == 0) { - /* wheel down */ - event = GNT_MOUSE_SCROLL_DOWN; - } else if (strncmp(buffer, "[M#", 3) == 0) { - /* button up */ - event = GNT_MOUSE_UP; - } else - return FALSE; - - if (widget && gnt_wm_process_click(wm, event, x, y, widget)) - return TRUE; - - if (event == GNT_LEFT_MOUSE_DOWN && widget && widget != wm->_list.window && - !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { - if (widget != wm->cws->ordered->data) { - gnt_wm_raise_window(wm, widget); - } - if (y == widget->priv.y) { - offset = x - widget->priv.x; - remember = widget; - button = MOUSE_LEFT; - } - } else if (event == GNT_MOUSE_UP) { - if (button == MOUSE_NONE && y == getmaxy(stdscr) - 1) { - /* Clicked on the taskbar */ - int n = g_list_length(wm->cws->list); - if (n) { - int width = getmaxx(stdscr) / n; - 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); - } - button = MOUSE_NONE; - remember = NULL; - offset = 0; - } - - if (widget) - gnt_widget_clicked(widget, event, x, y); - return TRUE; -} - -static gboolean -io_invoke_error(GIOChannel *source, GIOCondition cond, gpointer data) -{ - int id = GPOINTER_TO_INT(data); - g_source_remove(id); - g_io_channel_unref(source); - - channel = NULL; - setup_io(); - return TRUE; -} - -static gboolean -io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) -{ - char keys[256]; - gssize rd; - char *k; - char *cvrt = NULL; - - if (wm->mode == GNT_KP_MODE_WAIT_ON_CHILD) - return FALSE; - - rd = read(STDIN_FILENO, keys + HOLDING_ESCAPE, sizeof(keys) - 1 - HOLDING_ESCAPE); - if (rd < 0) - { - int ch = getch(); /* This should return ERR, but let's see what it really returns */ - endwin(); - printf("ERROR: %s\n", strerror(errno)); - printf("File descriptor is: %d\n\nGIOChannel is: %p\ngetch() = %d\n", STDIN_FILENO, source, ch); - raise(SIGABRT); - } - else if (rd == 0) - { - endwin(); - printf("EOF\n"); - raise(SIGABRT); - } - - rd += HOLDING_ESCAPE; - if (HOLDING_ESCAPE) { - keys[0] = '\033'; - g_source_remove(escape_stuff.timer); - escape_stuff.timer = 0; - } - keys[rd] = 0; - gnt_wm_set_event_stack(wm, TRUE); - - cvrt = g_locale_to_utf8(keys, rd, (gsize*)&rd, NULL, NULL); - k = cvrt ? cvrt : keys; - if (mouse_enabled && detect_mouse_action(k)) - goto end; - -#if 0 - /* I am not sure what's happening here. If this actually does something, - * then this needs to go in gnt_keys_refine. */ - if (*k < 0) { /* Alt not sending ESC* */ - *(k + 1) = 128 - *k; - *k = 27; - *(k + 2) = 0; - rd++; - } -#endif - - while (rd) { - char back; - int p; - - if (k[0] == '\033' && rd == 1) { - escape_stuff.timer = g_timeout_add(250, escape_timeout, NULL); - break; - } - - gnt_keys_refine(k); - p = MAX(1, gnt_keys_find_combination(k)); - back = k[p]; - k[p] = '\0'; - gnt_wm_process_input(wm, k); /* XXX: */ - k[p] = back; - rd -= p; - k += p; - } -end: - if (wm) - gnt_wm_set_event_stack(wm, FALSE); - g_free(cvrt); - return TRUE; -} - -static void -setup_io() -{ - int result; - channel = g_io_channel_unix_new(STDIN_FILENO); - g_io_channel_set_close_on_unref(channel, TRUE); - -#if 0 - g_io_channel_set_encoding(channel, NULL, NULL); - g_io_channel_set_buffered(channel, FALSE); - g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL ); -#endif - - channel_read_callback = 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); - - channel_error_callback = g_io_add_watch_full(channel, G_PRIORITY_HIGH, - (G_IO_NVAL), - io_invoke_error, GINT_TO_POINTER(result), NULL); - - g_io_channel_unref(channel); /* Apparently this caused crashes for some people. - But irssi does this, so I am going to assume the - crashes were caused by some other stuff. */ - - gnt_warning("setting up IO (%d)", channel_read_callback); -} - -static gboolean -refresh_screen(void) -{ - gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "refresh-screen", NULL); - return FALSE; -} - -/* Xerox */ -static void -clean_pid(void) -{ - int status; - pid_t pid; - - do { - pid = waitpid(-1, &status, WNOHANG); - } while (pid != 0 && pid != (pid_t)-1); - - if ((pid == (pid_t) - 1) && (errno != ECHILD)) { - char errmsg[BUFSIZ]; - g_snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid); - perror(errmsg); - } -} - -static void -exit_confirmed(gpointer null) -{ - gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "wm-quit", NULL); -} - -static void -exit_win_close(GntWidget *w, GntWidget **win) -{ - *win = NULL; -} - -static void -ask_before_exit(void) -{ - static GntWidget *win = NULL; - GntWidget *bbox, *button; - - if (wm->menu) { - do { - gnt_widget_hide(GNT_WIDGET(wm->menu)); - if (wm->menu) - wm->menu = wm->menu->parentmenu; - } while (wm->menu); - } - - if (win) - goto raise; - - win = gnt_vwindow_new(FALSE); - gnt_box_add_widget(GNT_BOX(win), gnt_label_new("Are you sure you want to quit?")); - gnt_box_set_title(GNT_BOX(win), "Quit?"); - gnt_box_set_alignment(GNT_BOX(win), GNT_ALIGN_MID); - g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(exit_win_close), &win); - - bbox = gnt_hbox_new(FALSE); - gnt_box_add_widget(GNT_BOX(win), bbox); - - button = gnt_button_new("Quit"); - g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(exit_confirmed), NULL); - gnt_box_add_widget(GNT_BOX(bbox), button); - - button = gnt_button_new("Cancel"); - g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win); - gnt_box_add_widget(GNT_BOX(bbox), button); - - gnt_widget_show(win); -raise: - gnt_wm_raise_window(wm, win); -} - -#ifdef SIGWINCH -static void (*org_winch_handler)(int); -static void (*org_winch_handler_sa)(int, siginfo_t *, void *); -#endif - -static void -sighandler(int sig, siginfo_t *info, void *data) -{ - switch (sig) { -#ifdef SIGWINCH - case SIGWINCH: - erase(); - g_idle_add((GSourceFunc)refresh_screen, NULL); - if (org_winch_handler) - org_winch_handler(sig); - if (org_winch_handler_sa) - org_winch_handler_sa(sig, info, data); - break; -#endif - case SIGCHLD: - clean_pid(); - break; - case SIGINT: - ask_before_exit(); - break; - } -} - -static void -init_wm(void) -{ - const char *name = gnt_style_get(GNT_STYLE_WM); - gpointer handle; - - 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() -{ - char *filename; - const char *locale; - struct sigaction act; -#ifdef SIGWINCH - struct sigaction oact; -#endif - - if (channel) - return; - - locale = setlocale(LC_ALL, ""); - - setup_io(); - -#ifdef NO_WIDECHAR - ascii_only = TRUE; -#else - if (locale && (strstr(locale, "UTF") || strstr(locale, "utf"))) { - ascii_only = FALSE; - } else { - ascii_only = TRUE; - gnt_need_conversation_to_locale = TRUE; - } -#endif - - initscr(); - typeahead(-1); - noecho(); - curs_set(0); - - gnt_init_keys(); - gnt_init_styles(); - - filename = g_build_filename(g_get_home_dir(), ".gntrc", NULL); - gnt_style_read_configure_file(filename); - g_free(filename); - - gnt_init_colors(); - - wbkgdset(stdscr, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); - refresh(); - -#ifdef ALL_MOUSE_EVENTS - if ((mouse_enabled = gnt_style_get_bool(GNT_STYLE_MOUSE, FALSE))) - mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL); -#endif - - wbkgdset(stdscr, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); - werase(stdscr); - wrefresh(stdscr); - - act.sa_sigaction = sighandler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; - -#ifdef SIGWINCH - org_winch_handler = NULL; - org_winch_handler_sa = NULL; - sigaction(SIGWINCH, &act, &oact); - if (oact.sa_flags & SA_SIGINFO) - { - org_winch_handler_sa = oact.sa_sigaction; - } - else if (oact.sa_handler != SIG_DFL && oact.sa_handler != SIG_IGN) - { - org_winch_handler = oact.sa_handler; - } -#endif - sigaction(SIGCHLD, &act, NULL); - sigaction(SIGINT, &act, NULL); - signal(SIGPIPE, SIG_IGN); - -#if !GLIB_CHECK_VERSION(2, 36, 0) - /* GLib type system is automaticaly initialized since 2.36. */ - g_type_init(); -#endif - - init_wm(); - - clipboard = g_object_new(GNT_TYPE_CLIPBOARD, NULL); -} - -void gnt_main() -{ - wm->loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(wm->loop); -} - -/********************************* - * Stuff for 'window management' * - *********************************/ - -void gnt_window_present(GntWidget *window) -{ - if (wm->event_stack) - gnt_wm_raise_window(wm, window); - else - gnt_widget_set_urgent(window); -} - -void gnt_screen_occupy(GntWidget *widget) -{ - gnt_wm_new_window(wm, widget); -} - -void gnt_screen_release(GntWidget *widget) -{ - if (wm) - gnt_wm_window_close(wm, widget); -} - -void gnt_screen_update(GntWidget *widget) -{ - gnt_wm_update_window(wm, widget); -} - -gboolean gnt_widget_has_focus(GntWidget *widget) -{ - GntWidget *w; - if (!widget) - return FALSE; - - if (GNT_IS_MENU(widget)) - return TRUE; - - w = widget; - - while (widget->parent) - widget = widget->parent; - - if (widget == wm->_list.window) - return TRUE; - if (wm->cws->ordered && wm->cws->ordered->data == widget) { - if (GNT_IS_BOX(widget) && - (GNT_BOX(widget)->active == w || widget == w)) - return TRUE; - } - return FALSE; -} - -void gnt_widget_set_urgent(GntWidget *widget) -{ - while (widget->parent) - widget = widget->parent; - - if (wm->cws->ordered && wm->cws->ordered->data == widget) - return; - - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_URGENT); - - gnt_wm_update_window(wm, widget); -} - -void gnt_quit() -{ - /* Prevent io_invoke() from being called after wm is destroyed */ - g_source_remove(channel_error_callback); - g_source_remove(channel_read_callback); - - channel_error_callback = 0; - channel_read_callback = 0; - - g_object_unref(G_OBJECT(wm)); - wm = NULL; - - update_panels(); - doupdate(); - gnt_uninit_colors(); - gnt_uninit_styles(); - endwin(); -} - -gboolean gnt_ascii_only() -{ - return ascii_only; -} - -void gnt_screen_resize_widget(GntWidget *widget, int width, int height) -{ - gnt_wm_resize_window(wm, widget, width, height); -} - -void gnt_screen_move_widget(GntWidget *widget, int x, int y) -{ - 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); - gnt_wm_update_window(wm, widget); -} - -void gnt_register_action(const char *label, void (*callback)(void)) -{ - GntAction *action = g_new0(GntAction, 1); - action->label = g_strdup(label); - action->callback = callback; - - wm->acts = g_list_append(wm->acts, action); -} - -static void -reset_menu(GntWidget *widget, gpointer null) -{ - wm->menu = NULL; -} - -gboolean gnt_screen_menu_show(gpointer newmenu) -{ - if (wm->menu) { - /* For now, if a menu is being displayed, then another menu - * can NOT take over. */ - return FALSE; - } - - wm->menu = newmenu; - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(wm->menu), GNT_WIDGET_INVISIBLE); - gnt_widget_draw(GNT_WIDGET(wm->menu)); - - g_signal_connect(G_OBJECT(wm->menu), "hide", G_CALLBACK(reset_menu), NULL); - g_signal_connect(G_OBJECT(wm->menu), "destroy", G_CALLBACK(reset_menu), NULL); - - return TRUE; -} - -void gnt_set_clipboard_string(const gchar *string) -{ - gnt_clipboard_set_string(clipboard, string); -} - -GntClipboard *gnt_get_clipboard() -{ - return clipboard; -} - -gchar *gnt_get_clipboard_string() -{ - return gnt_clipboard_get_string(clipboard); -} - -#if GLIB_CHECK_VERSION(2,4,0) -typedef struct -{ - void (*callback)(int status, gpointer data); - gpointer data; -} ChildProcess; - -static void -reap_child(GPid pid, gint status, gpointer data) -{ - ChildProcess *cp = data; - if (cp->callback) { - cp->callback(status, cp->data); - } - g_free(cp); - clean_pid(); - wm->mode = GNT_KP_MODE_NORMAL; - endwin(); - setup_io(); - refresh(); - refresh_screen(); -} -#endif - -gboolean gnt_giveup_console(const char *wd, char **argv, char **envp, - gint *stin, gint *stout, gint *sterr, - void (*callback)(int status, gpointer data), gpointer data) -{ -#if GLIB_CHECK_VERSION(2,4,0) - GPid pid = 0; - ChildProcess *cp = NULL; - - if (!g_spawn_async_with_pipes(wd, argv, envp, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - (GSpawnChildSetupFunc)endwin, NULL, - &pid, stin, stout, sterr, NULL)) - return FALSE; - - cp = g_new0(ChildProcess, 1); - cp->callback = callback; - cp->data = data; - g_source_remove(channel_read_callback); - wm->mode = GNT_KP_MODE_WAIT_ON_CHILD; - g_child_watch_add(pid, reap_child, cp); - - return TRUE; -#else - return FALSE; -#endif -} - -gboolean gnt_is_refugee() -{ -#if GLIB_CHECK_VERSION(2,4,0) - return (wm && wm->mode == GNT_KP_MODE_WAIT_ON_CHILD); -#else - return FALSE; -#endif -} - -const char *C_(const char *x) -{ - static char *c = NULL; - if (gnt_need_conversation_to_locale) { - GError *error = NULL; - g_free(c); - c = g_locale_from_utf8(x, -1, NULL, NULL, &error); - if (c == NULL || error) { - char *store = c; - c = NULL; - gnt_warning("Error: %s\n", error ? error->message : "(unknown)"); - g_error_free(error); - error = NULL; - g_free(c); - c = store; - } - return c ? c : x; - } else - return x; -} -
--- a/finch/libgnt/gntmenu.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,535 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntmenu.h" -#include "gntmenuitemcheck.h" - -#include <ctype.h> -#include <string.h> - -enum -{ - SIGS = 1, -}; - -enum -{ - ITEM_TEXT = 0, - ITEM_TRIGGER, - ITEM_SUBMENU, - NUM_COLUMNS -}; - -static GntTreeClass *parent_class = NULL; - -static void (*org_draw)(GntWidget *wid); -static void (*org_destroy)(GntWidget *wid); -static void (*org_map)(GntWidget *wid); -static void (*org_size_request)(GntWidget *wid); -static gboolean (*org_key_pressed)(GntWidget *w, const char *t); -static gboolean (*org_clicked)(GntWidget *w, GntMouseEvent event, int x, int y); - -static void menuitem_activate(GntMenu *menu, GntMenuItem *item); - -static void -menu_hide_all(GntMenu *menu) -{ - while (menu->parentmenu) - menu = menu->parentmenu; - gnt_widget_hide(GNT_WIDGET(menu)); -} - -static void -show_submenu(GntMenu *menu) -{ - GntMenuItem *item; - - if (menu->type != GNT_MENU_TOPLEVEL) - return; - - item = g_list_nth_data(menu->list, menu->selected); - if (!item || !item->submenu) - return; - menuitem_activate(menu, item); -} - -static void -gnt_menu_draw(GntWidget *widget) -{ - GntMenu *menu = GNT_MENU(widget); - GList *iter; - chtype type; - int i; - - if (menu->type == GNT_MENU_TOPLEVEL) { - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - werase(widget->window); - - for (i = 0, iter = menu->list; iter; iter = iter->next, i++) { - GntMenuItem *item = GNT_MENU_ITEM(iter->data); - type = ' ' | gnt_color_pair(GNT_COLOR_HIGHLIGHT); - if (i == menu->selected) - type |= A_REVERSE; - item->priv.x = getcurx(widget->window) + widget->priv.x; - item->priv.y = getcury(widget->window) + widget->priv.y + 1; - wbkgdset(widget->window, type); - wprintw(widget->window, " %s ", C_(item->text)); - } - } else { - org_draw(widget); - } - - GNTDEBUG; -} - -static void -gnt_menu_size_request(GntWidget *widget) -{ - GntMenu *menu = GNT_MENU(widget); - - if (menu->type == GNT_MENU_TOPLEVEL) { - widget->priv.height = 1; - widget->priv.width = getmaxx(stdscr); - } else { - org_size_request(widget); - widget->priv.height = g_list_length(menu->list) + 2; - } -} - -static void -menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent) -{ - char trigger[4] = "\0 )\0"; - - if ((trigger[1] = gnt_menuitem_get_trigger(item)) && trigger[1] != ' ') - trigger[0] = '('; - - if (GNT_IS_MENU_ITEM_CHECK(item)) { - gnt_tree_add_choice(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, " "), parent, NULL); - gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item))); - } else - gnt_tree_add_row_last(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, item->submenu ? ">" : " "), parent); - - if (0 && item->submenu) { - GntMenu *sub = GNT_MENU(item->submenu); - GList *iter; - for (iter = sub->list; iter; iter = iter->next) { - GntMenuItem *it = GNT_MENU_ITEM(iter->data); - menu_tree_add(menu, it, item); - } - } -} - -#define GET_VAL(ch) ((ch >= '0' && ch <= '9') ? (ch - '0') : (ch >= 'a' && ch <= 'z') ? (10 + ch - 'a') : 36) - -static void -assign_triggers(GntMenu *menu) -{ - GList *iter; - gboolean bools[37]; - - memset(bools, 0, sizeof(bools)); - bools[36] = 1; - - for (iter = menu->list; iter; iter = iter->next) { - GntMenuItem *item = iter->data; - char trigger = tolower(gnt_menuitem_get_trigger(item)); - if (trigger == '\0' || trigger == ' ') - continue; - bools[(int)GET_VAL(trigger)] = 1; - } - - for (iter = menu->list; iter; iter = iter->next) { - GntMenuItem *item = iter->data; - char trigger = gnt_menuitem_get_trigger(item); - const char *text = item->text; - if (trigger != '\0') - continue; - while (*text) { - char ch = tolower(*text++); - char t[2] = {ch, '\0'}; - if (ch == ' ' || bools[(int)GET_VAL(ch)] || gnt_bindable_check_key(GNT_BINDABLE(menu), t)) - continue; - trigger = ch; - break; - } - if (trigger == 0) - trigger = item->text[0]; - gnt_menuitem_set_trigger(item, trigger); - bools[(int)GET_VAL(trigger)] = 1; - } -} - -static void -gnt_menu_map(GntWidget *widget) -{ - GntMenu *menu = GNT_MENU(widget); - - if (menu->type == GNT_MENU_TOPLEVEL) { - gnt_widget_size_request(widget); - } else { - /* Populate the tree */ - GList *iter; - gnt_tree_remove_all(GNT_TREE(widget)); - /* Try to assign some trigger for the items */ - assign_triggers(menu); - for (iter = menu->list; iter; iter = iter->next) { - GntMenuItem *item = GNT_MENU_ITEM(iter->data); - menu_tree_add(menu, item, NULL); - } - org_map(widget); - gnt_tree_adjust_columns(GNT_TREE(widget)); - } - GNTDEBUG; -} - -static void -menuitem_activate(GntMenu *menu, GntMenuItem *item) -{ - if (!item) - return; - - if (gnt_menuitem_activate(item)) { - menu_hide_all(menu); - } else { - if (item->submenu) { - GntMenu *sub = GNT_MENU(item->submenu); - menu->submenu = sub; - sub->type = GNT_MENU_POPUP; /* Submenus are *never* toplevel */ - sub->parentmenu = menu; - if (menu->type != GNT_MENU_TOPLEVEL) { - GntWidget *widget = GNT_WIDGET(menu); - item->priv.x = widget->priv.x + widget->priv.width - 1; - item->priv.y = widget->priv.y + gnt_tree_get_selection_visible_line(GNT_TREE(menu)); - } - gnt_widget_set_position(GNT_WIDGET(sub), item->priv.x, item->priv.y); - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(sub), GNT_WIDGET_INVISIBLE); - gnt_widget_draw(GNT_WIDGET(sub)); - } else { - menu_hide_all(menu); - } - } -} - -static GList* -find_item_with_trigger(GList *start, GList *end, char trigger) -{ - GList *iter; - for (iter = start; iter != (end ? end : NULL); iter = iter->next) { - if (gnt_menuitem_get_trigger(iter->data) == trigger) - return iter; - } - return NULL; -} - -static gboolean -check_for_trigger(GntMenu *menu, char trigger) -{ - /* check for a trigger key */ - GList *iter; - GList *find; - GList *nth = g_list_find(menu->list, gnt_tree_get_selection_data(GNT_TREE(menu))); - - if (nth == NULL) - return FALSE; - - find = find_item_with_trigger(nth->next, NULL, trigger); - if (!find) - find = find_item_with_trigger(menu->list, nth->next, trigger); - if (!find) - return FALSE; - if (find != nth) { - gnt_tree_set_selected(GNT_TREE(menu), find->data); - iter = find_item_with_trigger(find->next, NULL, trigger); - if (iter != NULL && iter != find) - return TRUE; - iter = find_item_with_trigger(menu->list, nth, trigger); - if (iter != NULL && iter != find) - return TRUE; - } - gnt_widget_activate(GNT_WIDGET(menu)); - return TRUE; -} - -static gboolean -gnt_menu_key_pressed(GntWidget *widget, const char *text) -{ - GntMenu *menu = GNT_MENU(widget); - int current = menu->selected; - - if (menu->submenu) { - GntMenu *sub = menu; - do sub = sub->submenu; while (sub->submenu); - if (gnt_widget_key_pressed(GNT_WIDGET(sub), text)) - return TRUE; - if (menu->type != GNT_MENU_TOPLEVEL) - return FALSE; - } - - if ((text[0] == 27 && text[1] == 0) || - (menu->type != GNT_MENU_TOPLEVEL && strcmp(text, GNT_KEY_LEFT) == 0)) { - /* Escape closes menu */ - GntMenu *par = menu->parentmenu; - if (par != NULL) { - par->submenu = NULL; - gnt_widget_hide(widget); - } else - gnt_widget_hide(widget); - if (par && par->type == GNT_MENU_TOPLEVEL) - gnt_menu_key_pressed(GNT_WIDGET(par), text); - return TRUE; - } - - if (menu->type == GNT_MENU_TOPLEVEL) { - if (strcmp(text, GNT_KEY_LEFT) == 0) { - menu->selected--; - if (menu->selected < 0) - menu->selected = g_list_length(menu->list) - 1; - } else if (strcmp(text, GNT_KEY_RIGHT) == 0) { - menu->selected++; - if ((guint)menu->selected >= g_list_length(menu->list)) - menu->selected = 0; - } else if (strcmp(text, GNT_KEY_ENTER) == 0 || - strcmp(text, GNT_KEY_DOWN) == 0) { - gnt_widget_activate(widget); - } - - if (current != menu->selected) { - GntMenu *sub = menu->submenu; - if (sub) - gnt_widget_hide(GNT_WIDGET(sub)); - show_submenu(menu); - gnt_widget_draw(widget); - return TRUE; - } - } else { - if (text[1] == '\0') { - if (check_for_trigger(menu, text[0])) - return TRUE; - } else if (strcmp(text, GNT_KEY_RIGHT) == 0) { - GntMenuItem *item = gnt_tree_get_selection_data(GNT_TREE(menu)); - if (item && item->submenu) { - menuitem_activate(menu, item); - return TRUE; - } - } - if (gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text)) - return TRUE; - return org_key_pressed(widget, text); - } - - return gnt_bindable_perform_action_key(GNT_BINDABLE(widget), text); -} - -static void -gnt_menu_destroy(GntWidget *widget) -{ - GntMenu *menu = GNT_MENU(widget); - g_list_foreach(menu->list, (GFunc)g_object_unref, NULL); - g_list_free(menu->list); - org_destroy(widget); -} - -static void -gnt_menu_toggled(GntTree *tree, gpointer key) -{ - GntMenuItem *item = GNT_MENU_ITEM(key); - GntMenu *menu = GNT_MENU(tree); - gboolean check = gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item)); - gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), !check); - gnt_menuitem_activate(item); - while (menu) { - gnt_widget_hide(GNT_WIDGET(menu)); - menu = menu->parentmenu; - } -} - -static void -gnt_menu_activate(GntWidget *widget) -{ - GntMenu *menu = GNT_MENU(widget); - GntMenuItem *item; - - if (menu->type == GNT_MENU_TOPLEVEL) { - item = g_list_nth_data(menu->list, menu->selected); - } else { - item = gnt_tree_get_selection_data(GNT_TREE(menu)); - } - - if (item) { - if (GNT_IS_MENU_ITEM_CHECK(item)) - gnt_menu_toggled(GNT_TREE(widget), item); - else - menuitem_activate(menu, item); - } -} - -static void -gnt_menu_hide(GntWidget *widget) -{ - GntMenu *sub, *menu = GNT_MENU(widget); - - while ((sub = menu->submenu)) - gnt_widget_hide(GNT_WIDGET(sub)); - if (menu->parentmenu) - menu->parentmenu->submenu = NULL; -} - -static gboolean -gnt_menu_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - if (GNT_MENU(widget)->type != GNT_MENU_POPUP) - return FALSE; - - if (org_clicked && org_clicked(widget, event, x, y)) - return TRUE; - gnt_widget_activate(widget); - return TRUE; -} - -static void -gnt_menu_class_init(GntMenuClass *klass) -{ - GntWidgetClass *wid_class = GNT_WIDGET_CLASS(klass); - parent_class = GNT_TREE_CLASS(klass); - - org_destroy = wid_class->destroy; - org_map = wid_class->map; - org_draw = wid_class->draw; - org_key_pressed = wid_class->key_pressed; - org_size_request = wid_class->size_request; - org_clicked = wid_class->clicked; - - wid_class->destroy = gnt_menu_destroy; - wid_class->draw = gnt_menu_draw; - wid_class->map = gnt_menu_map; - wid_class->size_request = gnt_menu_size_request; - wid_class->key_pressed = gnt_menu_key_pressed; - wid_class->activate = gnt_menu_activate; - wid_class->hide = gnt_menu_hide; - wid_class->clicked = gnt_menu_clicked; - - parent_class->toggled = gnt_menu_toggled; - - GNTDEBUG; -} - -static void -gnt_menu_init(GTypeInstance *instance, gpointer class) -{ - 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_TRANSIENT | GNT_WIDGET_DISABLE_ACTIONS); - GNTDEBUG; -} - -/****************************************************************************** - * GntMenu API - *****************************************************************************/ -GType -gnt_menu_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntMenuClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_menu_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntMenu), - 0, /* n_preallocs */ - gnt_menu_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_TREE, - "GntMenu", - &info, 0); - } - - return type; -} - -GntWidget *gnt_menu_new(GntMenuType type) -{ - GntWidget *widget = g_object_new(GNT_TYPE_MENU, NULL); - GntMenu *menu = GNT_MENU(widget); - menu->list = NULL; - menu->selected = 0; - menu->type = type; - - if (type == GNT_MENU_TOPLEVEL) { - widget->priv.x = 0; - widget->priv.y = 0; - } else { - GNT_TREE(widget)->show_separator = FALSE; - g_object_set(G_OBJECT(widget), "columns", NUM_COLUMNS, NULL); - gnt_tree_set_col_width(GNT_TREE(widget), ITEM_TRIGGER, 3); - gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_TRIGGER, FALSE); - gnt_tree_set_col_width(GNT_TREE(widget), ITEM_SUBMENU, 1); - gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_SUBMENU, FALSE); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); - } - - return widget; -} - -void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item) -{ - menu->list = g_list_append(menu->list, item); -} - -GntMenuItem *gnt_menu_get_item(GntMenu *menu, const char *id) -{ - GntMenuItem *item = NULL; - GList *iter = menu->list; - - if (!id || !*id) - return NULL; - - for (; iter; iter = iter->next) { - GntMenu *sub; - item = iter->data; - sub = gnt_menuitem_get_submenu(item); - if (sub) { - item = gnt_menu_get_item(sub, id); - if (item) - break; - } else { - const char *itid = gnt_menuitem_get_id(item); - if (itid && strcmp(itid, id) == 0) - break; - /* XXX: Perhaps look at the menu-label as well? */ - } - item = NULL; - } - - return item; -} -
--- a/finch/libgnt/gntmenu.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/** - * @file gntmenu.h Menu API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_MENU_H -#define GNT_MENU_H - -#include "gnttree.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_MENU (gnt_menu_get_gtype()) -#define GNT_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENU, GntMenu)) -#define GNT_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENU, GntMenuClass)) -#define GNT_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENU)) -#define GNT_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENU)) -#define GNT_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENU, GntMenuClass)) - -#define GNT_MENU_FLAGS(obj) (GNT_MENU(obj)->priv.flags) -#define GNT_MENU_SET_FLAGS(obj, flags) (GNT_MENU_FLAGS(obj) |= flags) -#define GNT_MENU_UNSET_FLAGS(obj, flags) (GNT_MENU_FLAGS(obj) &= ~(flags)) - -typedef struct _GntMenu GntMenu; -typedef struct _GntMenuPriv GntMenuPriv; -typedef struct _GntMenuClass GntMenuClass; - -#include "gntmenuitem.h" - -/** - * A toplevel-menu is displayed at the top of the screen, and it spans accross - * the entire width of the screen. - * A popup-menu could be displayed, for example, as a context menu for widgets. - */ -typedef enum -{ - GNT_MENU_TOPLEVEL = 1, /* Menu for a toplevel window */ - GNT_MENU_POPUP, /* A popup menu */ -} GntMenuType; - -struct _GntMenu -{ - GntTree parent; - GntMenuType type; - - GList *list; - int selected; - - /* This will keep track of its immediate submenu which is visible so that - * keystrokes can be passed to it. */ - GntMenu *submenu; - GntMenu *parentmenu; -}; - -struct _GntMenuClass -{ - GntTreeClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return The GType for GntMenu. - */ -GType gnt_menu_get_gtype(void); - -/** - * Create a new menu. - * - * @param type The type of the menu, whether it's a toplevel menu or a popup menu. - * - * @return The newly created menu. - */ -GntWidget * gnt_menu_new(GntMenuType type); - -/** - * Add an item to the menu. - * - * @param menu The menu. - * @param item The item to add to the menu. - */ -void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item); - -/** - * Return the GntMenuItem with the given ID. - * - * @param menu The menu. - * @param id The ID for an item. - * - * @return The menuitem with the given ID, or @c NULL. - * - * @since 2.3.0 - */ -GntMenuItem *gnt_menu_get_item(GntMenu *menu, const char *id); - -G_END_DECLS - -#endif /* GNT_MENU_H */
--- a/finch/libgnt/gntmenuitem.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntmenu.h" -#include "gntmenuitem.h" - -enum -{ - SIG_ACTIVATE, - SIGS -}; -static guint signals[SIGS] = { 0 }; - -static GObjectClass *parent_class = NULL; - -static void -gnt_menuitem_destroy(GObject *obj) -{ - GntMenuItem *item = GNT_MENU_ITEM(obj); - g_free(item->text); - item->text = NULL; - if (item->submenu) - gnt_widget_destroy(GNT_WIDGET(item->submenu)); - g_free(item->priv.id); - parent_class->dispose(obj); -} - -static void -gnt_menuitem_class_init(GntMenuItemClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - parent_class = g_type_class_peek_parent(klass); - - obj_class->dispose = gnt_menuitem_destroy; - - signals[SIG_ACTIVATE] = - g_signal_new("activate", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gnt_menuitem_init(GTypeInstance *instance, gpointer klass) -{ -} - -/****************************************************************************** - * GntMenuItem API - *****************************************************************************/ -GType -gnt_menuitem_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntMenuItemClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_menuitem_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntMenuItem), - 0, /* n_preallocs */ - gnt_menuitem_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(G_TYPE_OBJECT, - "GntMenuItem", - &info, 0); - } - - return type; -} - -GntMenuItem *gnt_menuitem_new(const char *text) -{ - GObject *item = g_object_new(GNT_TYPE_MENU_ITEM, NULL); - GntMenuItem *menuitem = GNT_MENU_ITEM(item); - - menuitem->text = g_strdup(text); - - return menuitem; -} - -void gnt_menuitem_set_callback(GntMenuItem *item, GntMenuItemCallback callback, gpointer data) -{ - item->callback = callback; - item->callbackdata = data; -} - -void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu) -{ - if (item->submenu) - gnt_widget_destroy(GNT_WIDGET(item->submenu)); - item->submenu = menu; -} - -GntMenu *gnt_menuitem_get_submenu(GntMenuItem *item) -{ - return item->submenu; -} - -void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger) -{ - item->priv.trigger = trigger; -} - -char gnt_menuitem_get_trigger(GntMenuItem *item) -{ - return item->priv.trigger; -} - -void gnt_menuitem_set_id(GntMenuItem *item, const char *id) -{ - g_free(item->priv.id); - item->priv.id = g_strdup(id); -} - -const char * gnt_menuitem_get_id(GntMenuItem *item) -{ - return item->priv.id; -} - -gboolean gnt_menuitem_activate(GntMenuItem *item) -{ - g_signal_emit(item, signals[SIG_ACTIVATE], 0); - if (item->callback) { - item->callback(item, item->callbackdata); - return TRUE; - } - return FALSE; -} -
--- a/finch/libgnt/gntmenuitem.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/** - * @file gntmenuitem.h Menuitem API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_MENUITEM_H -#define GNT_MENUITEM_H - -#include <glib.h> -#include <glib-object.h> - -#define GNT_TYPE_MENU_ITEM (gnt_menuitem_get_gtype()) -#define GNT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENU_ITEM, GntMenuItem)) -#define GNT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENU_ITEM, GntMenuItemClass)) -#define GNT_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENU_ITEM)) -#define GNT_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENU_ITEM)) -#define GNT_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENU_ITEM, GntMenuItemClass)) - -#define GNT_MENU_ITEM_FLAGS(obj) (GNT_MENU_ITEM(obj)->priv.flags) -#define GNT_MENU_ITEM_SET_FLAGS(obj, flags) (GNT_MENU_ITEM_FLAGS(obj) |= flags) -#define GNT_MENU_ITEM_UNSET_FLAGS(obj, flags) (GNT_MENU_ITEM_FLAGS(obj) &= ~(flags)) - -typedef struct _GntMenuItem GntMenuItem; -typedef struct _GntMenuItemPriv GntMenuItemPriv; -typedef struct _GntMenuItemClass GntMenuItemClass; - -#include "gntmenu.h" - -struct _GntMenuItemPriv -{ - /* These will be used to determine the position of the submenu */ - int x; - int y; - char trigger; - char *id; -}; - -typedef void (*GntMenuItemCallback)(GntMenuItem *item, gpointer data); - -struct _GntMenuItem -{ - GObject parent; - GntMenuItemPriv priv; - - char *text; - - /* A GntMenuItem can have a callback associated with it. - * The callback will be activated whenever the suer selects it and presses enter (or clicks). - * However, if the GntMenuItem has some child, then the callback and callbackdata will be ignored. */ - gpointer callbackdata; - GntMenuItemCallback callback; - - GntMenu *submenu; -}; - -struct _GntMenuItemClass -{ - GObjectClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntMenuItem. - */ -GType gnt_menuitem_get_gtype(void); - -/** - * Create a new menuitem. - * - * @param text Label for the menuitem. - * - * @return The newly created menuitem. - */ -GntMenuItem * gnt_menuitem_new(const char *text); - -/** - * Set a callback function for a menuitem. - * - * @param item The menuitem. - * @param callback The callback function. - * @param data Data to send to the callback function. - */ -void gnt_menuitem_set_callback(GntMenuItem *item, GntMenuItemCallback callback, gpointer data); - -/** - * Set a submenu for a menuitem. A menuitem with a submenu cannot have a callback. - * - * @param item The menuitem. - * @param menu The submenu. - */ -void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu); - -/** - * Get the submenu for a menuitem. - * - * @param item The menuitem. - * - * @return The submenu, or @c NULL. - * - * @since 2.3.0 - */ -GntMenu *gnt_menuitem_get_submenu(GntMenuItem *item); - -/** - * Set a trigger key for the item. - * - * @param item The menuitem - * @param trigger The key that will trigger the item when the parent manu is visible - */ -void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger); - -/** - * Get the trigger key for a menuitem. - * - * @param item The menuitem - * - * @return The trigger key for the menuitem. - * - * @see gnt_menuitem_set_trigger - */ -char gnt_menuitem_get_trigger(GntMenuItem *item); - -/** - * Set an ID for the menuitem. - * - * @param item The menuitem. - * @param id The ID for the menuitem. - * - * @since 2.3.0 - */ -void gnt_menuitem_set_id(GntMenuItem *item, const char *id); - -/** - * Get the ID of the menuitem. - * - * @param item The menuitem. - * - * @return The ID for the menuitem. - * - * @since 2.3.0 - */ -const char * gnt_menuitem_get_id(GntMenuItem *item); - -/** - * Activate a menuitem. - * Activating the menuitem will first trigger the 'activate' signal for the - * menuitem. Then the callback for the menuitem is triggered, if there is one. - * - * @param item The menuitem. - * - * @return Whether the callback for the menuitem was called. - * - * @since 2.3.0 - */ -gboolean gnt_menuitem_activate(GntMenuItem *item); - -G_END_DECLS - -#endif /* GNT_MENUITEM_H */
--- a/finch/libgnt/gntmenuitemcheck.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntmenuitemcheck.h" - -static GntMenuItemClass *parent_class = NULL; - -static void -gnt_menuitem_check_class_init(GntMenuItemCheckClass *klass) -{ - parent_class = GNT_MENU_ITEM_CLASS(klass); - - GNTDEBUG; -} - -static void -gnt_menuitem_check_init(GTypeInstance *instance, gpointer class) -{ - GNTDEBUG; -} - -/****************************************************************************** - * GntMenuItemCheck API - *****************************************************************************/ -GType -gnt_menuitem_check_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntMenuItemCheckClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_menuitem_check_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntMenuItemCheck), - 0, /* n_preallocs */ - gnt_menuitem_check_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_MENU_ITEM, - "GntMenuItemCheck", - &info, 0); - } - - return type; -} - -GntMenuItem *gnt_menuitem_check_new(const char *text) -{ - GntMenuItem *item = g_object_new(GNT_TYPE_MENU_ITEM_CHECK, NULL); - GntMenuItem *menuitem = GNT_MENU_ITEM(item); - - menuitem->text = g_strdup(text); - return item; -} - -gboolean gnt_menuitem_check_get_checked(GntMenuItemCheck *item) -{ - return item->checked; -} - -void gnt_menuitem_check_set_checked(GntMenuItemCheck *item, gboolean set) -{ - item->checked = set; -} -
--- a/finch/libgnt/gntmenuitemcheck.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/** - * @file gntmenuitemcheck.h Check Menuitem API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_MENU_ITEM_CHECK_H -#define GNT_MENU_ITEM_CHECK_H - -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" -#include "gntmenuitem.h" - -#define GNT_TYPE_MENU_ITEM_CHECK (gnt_menuitem_check_get_gtype()) -#define GNT_MENU_ITEM_CHECK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_MENU_ITEM_CHECK, GntMenuItemCheck)) -#define GNT_MENU_ITEM_CHECK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_MENU_ITEM_CHECK, GntMenuItemCheckClass)) -#define GNT_IS_MENU_ITEM_CHECK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_MENU_ITEM_CHECK)) -#define GNT_IS_MENU_ITEM_CHECK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_MENU_ITEM_CHECK)) -#define GNT_MENU_ITEM_CHECK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_MENU_ITEM_CHECK, GntMenuItemCheckClass)) - -#define GNT_MENU_ITEM_CHECK_FLAGS(obj) (GNT_MENU_ITEM_CHECK(obj)->priv.flags) -#define GNT_MENU_ITEM_CHECK_SET_FLAGS(obj, flags) (GNT_MENU_ITEM_CHECK_FLAGS(obj) |= flags) -#define GNT_MENU_ITEM_CHECK_UNSET_FLAGS(obj, flags) (GNT_MENU_ITEM_CHECK_FLAGS(obj) &= ~(flags)) - -typedef struct _GntMenuItemCheck GntMenuItemCheck; -typedef struct _GntMenuItemCheckPriv GntMenuItemCheckPriv; -typedef struct _GntMenuItemCheckClass GntMenuItemCheckClass; - -struct _GntMenuItemCheck -{ - GntMenuItem parent; - gboolean checked; -}; - -struct _GntMenuItemCheckClass -{ - GntMenuItemClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntMenuItemCheck. - */ -GType gnt_menuitem_check_get_gtype(void); - -/** - * Create a new menuitem. - * - * @param text The text for the menuitem. - * - * @return The newly created menuitem. - */ -GntMenuItem * gnt_menuitem_check_new(const char *text); - -/** - * Check whether the menuitem is checked or not. - * - * @param item The menuitem. - * - * @return @c TRUE if the item is checked, @c FALSE otherwise. - */ -gboolean gnt_menuitem_check_get_checked(GntMenuItemCheck *item); - -/** - * Set whether the menuitem is checked or not. - * - * @param item The menuitem. - * @param set @c TRUE if the item should be checked, @c FALSE otherwise. - */ -void gnt_menuitem_check_set_checked(GntMenuItemCheck *item, gboolean set); - -G_END_DECLS - -#endif /* GNT_MENU_ITEM_CHECK_H */
--- a/finch/libgnt/gntprogressbar.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - **/ - -#include "gntinternal.h" -#include "gntprogressbar.h" -#include "gntutils.h" - -#include <string.h> - -typedef struct _GntProgressBarPrivate -{ - gdouble fraction; - gboolean show_value; - GntProgressBarOrientation orientation; -} GntProgressBarPrivate; - -struct _GntProgressBar -{ - GntWidget parent; -#if !GLIB_CHECK_VERSION(2,4,0) - GntProgressBarPrivate priv; -#endif -}; - -#if GLIB_CHECK_VERSION(2,4,0) -#define GNT_PROGRESS_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarPrivate)) -#else -#define GNT_PROGRESS_BAR_GET_PRIVATE(o) &(GNT_PROGRESS_BAR(o)->priv) -#endif - -static GntWidgetClass *parent_class = NULL; - - -static void -gnt_progress_bar_draw (GntWidget *widget) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (GNT_PROGRESS_BAR (widget)); - gchar progress[8]; - gint start, end, i, pos; - int color; - - g_snprintf (progress, sizeof (progress), "%.1f%%", priv->fraction * 100); - color = gnt_color_pair(GNT_COLOR_NORMAL); - - switch (priv->orientation) { - case GNT_PROGRESS_LEFT_TO_RIGHT: - case GNT_PROGRESS_RIGHT_TO_LEFT: - start = (priv->orientation == GNT_PROGRESS_LEFT_TO_RIGHT ? 0 : (1.0 - priv->fraction) * widget->priv.width); - end = (priv->orientation == GNT_PROGRESS_LEFT_TO_RIGHT ? widget->priv.width * priv->fraction : widget->priv.width); - - /* background */ - for (i = 0; i < widget->priv.height; i++) - mvwhline (widget->window, i, 0, ' ' | color, widget->priv.width); - - /* foreground */ - for (i = 0; i < widget->priv.height; i++) - mvwhline (widget->window, i, start, ACS_CKBOARD | color | A_REVERSE, end); - - /* text */ - if (priv->show_value) { - pos = widget->priv.width / 2 - strlen (progress) / 2; - for (i = 0; i < progress[i]; i++, pos++) { - wattrset (widget->window, color | ((pos < start || pos > end) ? A_NORMAL : A_REVERSE)); - mvwprintw (widget->window, widget->priv.height / 2, pos, "%c", progress[i]); - } - wattrset (widget->window, color); - } - - break; - case GNT_PROGRESS_TOP_TO_BOTTOM: - case GNT_PROGRESS_BOTTOM_TO_TOP: - start = (priv->orientation == GNT_PROGRESS_TOP_TO_BOTTOM ? 0 : (1.0 - priv->fraction) * widget->priv.height); - end = (priv->orientation == GNT_PROGRESS_TOP_TO_BOTTOM ? widget->priv.height * priv->fraction : widget->priv.height); - - /* background */ - for (i = 0; i < widget->priv.width; i++) - mvwvline (widget->window, 0, i, ' ' | color, widget->priv.height); - - /* foreground */ - for (i = 0; i < widget->priv.width; i++) - mvwvline (widget->window, start, i, ACS_CKBOARD | color | A_REVERSE, end); - - /* text */ - if (priv->show_value) { - pos = widget->priv.height / 2 - strlen (progress) / 2; - for (i = 0; i < progress[i]; i++, pos++) { - wattrset (widget->window, color | ((pos < start || pos > end) ? A_NORMAL : A_REVERSE)); - mvwprintw (widget->window, pos, widget->priv.width / 2, "%c\n", progress[i]); - } - wattrset (widget->window, color); - } - - break; - default: - g_assert_not_reached (); - } -} - -static void -gnt_progress_bar_size_request (GntWidget *widget) -{ - gnt_widget_set_size (widget, widget->priv.minw, widget->priv.minh); -} - -static void -gnt_progress_bar_class_init (gpointer klass, gpointer class_data) -{ - GObjectClass *g_class = G_OBJECT_CLASS (klass); - - parent_class = GNT_WIDGET_CLASS (klass); - -#if GLIB_CHECK_VERSION(2,4,0) - g_type_class_add_private (g_class, sizeof (GntProgressBarPrivate)); -#endif - - parent_class->draw = gnt_progress_bar_draw; - parent_class->size_request = gnt_progress_bar_size_request; -} - -static void -gnt_progress_bar_init (GTypeInstance *instance, gpointer g_class) -{ - GntWidget *widget = GNT_WIDGET (instance); - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (GNT_PROGRESS_BAR (widget)); - - gnt_widget_set_take_focus (widget, FALSE); - GNT_WIDGET_SET_FLAGS (widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_GROW_X); - - widget->priv.minw = 8; - widget->priv.minh = 1; - - priv->show_value = TRUE; -} - -GType -gnt_progress_bar_get_type (void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof (GntProgressBarClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - gnt_progress_bar_class_init, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GntProgressBar), - 0, /* n_preallocs */ - gnt_progress_bar_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static (GNT_TYPE_WIDGET, "GntProgressBar", &info, 0); - } - - return type; -} - -GntWidget * -gnt_progress_bar_new (void) -{ - GntWidget *widget = g_object_new (GNT_TYPE_PROGRESS_BAR, NULL); - return widget; -} - -void -gnt_progress_bar_set_fraction (GntProgressBar *pbar, gdouble fraction) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - - if (fraction > 1.0) - priv->fraction = 1.0; - else if (fraction < 0.0) - priv->fraction = 0.0; - else - priv->fraction = fraction; - - if ((GNT_WIDGET_FLAGS(pbar) & GNT_WIDGET_MAPPED)) - gnt_widget_draw(GNT_WIDGET(pbar)); -} - -void -gnt_progress_bar_set_orientation (GntProgressBar *pbar, - GntProgressBarOrientation orientation) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - GntWidget *widget = GNT_WIDGET(pbar); - - priv->orientation = orientation; - if (orientation == GNT_PROGRESS_LEFT_TO_RIGHT || - orientation == GNT_PROGRESS_RIGHT_TO_LEFT) { - GNT_WIDGET_SET_FLAGS(pbar, GNT_WIDGET_GROW_X); - GNT_WIDGET_UNSET_FLAGS(pbar, GNT_WIDGET_GROW_Y); - widget->priv.minw = 8; - widget->priv.minh = 1; - } else { - GNT_WIDGET_UNSET_FLAGS(pbar, GNT_WIDGET_GROW_X); - GNT_WIDGET_SET_FLAGS(pbar, GNT_WIDGET_GROW_Y); - widget->priv.minw = 1; - widget->priv.minh = 8; - } - - if ((GNT_WIDGET_FLAGS(pbar) & GNT_WIDGET_MAPPED)) - gnt_widget_draw(GNT_WIDGET(pbar)); -} - -void -gnt_progress_bar_set_show_progress (GntProgressBar *pbar, gboolean show) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - priv->show_value = show; -} - -gdouble -gnt_progress_bar_get_fraction (GntProgressBar *pbar) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - return priv->fraction; -} - -GntProgressBarOrientation -gnt_progress_bar_get_orientation (GntProgressBar *pbar) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - return priv->orientation; -} - -gboolean -gnt_progress_bar_get_show_progress (GntProgressBar *pbar) -{ - GntProgressBarPrivate *priv = GNT_PROGRESS_BAR_GET_PRIVATE (pbar); - return priv->show_value; -} -
--- a/finch/libgnt/gntprogressbar.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/** - * @file gntprogressbar.h Progress Bar API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_PROGRESS_BAR_H -#define GNT_PROGRESS_BAR_H - -#include "gnt.h" -#include "gntwidget.h" - -#define GNT_TYPE_PROGRESS_BAR (gnt_progress_bar_get_type ()) -#define GNT_PROGRESS_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBar)) -#define GNT_PROGRESS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GNT_TYPE_PROGRESS_BAR, GntProgressBarClass)) -#define GNT_IS_PROGRESS_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNT_TYPE_PROGRESS_BAR)) -#define GNT_IS_PROGRESS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNT_TYPE_PROGRESS_BAR)) -#define GNT_PROGRESS_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GNT_TYPE_PROGRESS_BAR, GntProgressBarClass)) - -typedef enum _GntProgressBarOrientation -{ - GNT_PROGRESS_LEFT_TO_RIGHT, - GNT_PROGRESS_RIGHT_TO_LEFT, - GNT_PROGRESS_BOTTOM_TO_TOP, - GNT_PROGRESS_TOP_TO_BOTTOM, -} GntProgressBarOrientation; - -typedef struct _GntProgressBar GntProgressBar; - -typedef struct _GntProgressBarClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -} GntProgressBarClass; - -G_BEGIN_DECLS - -/** - * Get the GType for GntProgressBar - * @return The GType for GntProrgressBar - **/ -GType -gnt_progress_bar_get_type (void); - -/** - * Create a new GntProgressBar - * @return The new GntProgressBar - **/ -GntWidget * -gnt_progress_bar_new (void); - -/** - * Set the progress for a progress bar - * - * @param pbar The GntProgressBar - * @param fraction The value between 0 and 1 to display - **/ -void -gnt_progress_bar_set_fraction (GntProgressBar *pbar, gdouble fraction); - -/** - * Set the orientation for a progress bar - * - * @param pbar The GntProgressBar - * @param orientation The orientation to use - **/ -void -gnt_progress_bar_set_orientation (GntProgressBar *pbar, GntProgressBarOrientation orientation); - -/** - * Controls whether the progress value is shown - * - * @param pbar The GntProgressBar - * @param show A boolean indicating if the value is shown - **/ -void -gnt_progress_bar_set_show_progress (GntProgressBar *pbar, gboolean show); - -/** - * Get the progress that is displayed - * - * @param pbar The GntProgressBar - * @return The progress displayed as a value between 0 and 1 - **/ -gdouble -gnt_progress_bar_get_fraction (GntProgressBar *pbar); - -/** - * Get the orientation for the progress bar - * - * @param pbar The GntProgressBar - * @return The current orientation of the progress bar - **/ -GntProgressBarOrientation -gnt_progress_bar_get_orientation (GntProgressBar *pbar); - -/** - * Get a boolean describing if the progress value is shown - * - * @param pbar The GntProgressBar - * @return A boolean @c true if the progress value is shown, @c false otherwise. - **/ -gboolean -gnt_progress_bar_get_show_progress (GntProgressBar *pbar); - -G_END_DECLS - -#endif /* GNT_PROGRESS_BAR_H */
--- a/finch/libgnt/gntrc.sample Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -[general] -shadow = 0 - -[colors] -black = 0; 0; 0 -red = 1000; 0; 0 -green = 0; 1000; 0 -blue = 250; 250; 700 -white = 1000; 1000; 1000 -gray = 700; 700; 700 -darkgray = 256; 256; 256 - -[colorpairs] -normal = black; white -highlight = white; blue -highlightd = black; gray -shadow = black; darkgray -title = white; blue -titled = white; gray -text = white; blue -disabled = gray; white
--- a/finch/libgnt/gntslider.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,344 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntcolors.h" -#include "gntkeys.h" -#include "gntslider.h" -#include "gntstyle.h" - -enum -{ - SIG_VALUE_CHANGED, - SIGS, -}; - -static guint signals[SIGS] = { 0 }; - -static GntWidgetClass *parent_class = NULL; - -/* returns TRUE if the value was changed */ -static gboolean -sanitize_value(GntSlider *slider) -{ - if (slider->current < slider->min) - slider->current = slider->min; - else if (slider->current > slider->max) - slider->current = slider->max; - else - return FALSE; - return TRUE; -} - -static void -redraw_slider(GntSlider *slider) -{ - GntWidget *widget = GNT_WIDGET(slider); - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - gnt_widget_draw(widget); -} - -static void -slider_value_changed(GntSlider *slider) -{ - g_signal_emit(slider, signals[SIG_VALUE_CHANGED], 0, slider->current); -} - -static void -gnt_slider_draw(GntWidget *widget) -{ - GntSlider *slider = GNT_SLIDER(widget); - int attr = 0; - int position, size = 0; - - if (slider->vertical) - size = widget->priv.height; - else - size = widget->priv.width; - - if (gnt_widget_has_focus(widget)) - attr |= GNT_COLOR_HIGHLIGHT; - else - attr |= GNT_COLOR_HIGHLIGHT_D; - - if (slider->max != slider->min) - position = ((size - 1) * (slider->current - slider->min)) / (slider->max - slider->min); - else - position = 0; - if (slider->vertical) { - mvwvline(widget->window, size-position, 0, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL) | A_BOLD, - position); - mvwvline(widget->window, 0, 0, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL), - size-position); - } else { - mvwhline(widget->window, 0, 0, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL) | A_BOLD, - position); - mvwhline(widget->window, 0, position, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), - size - position); - } - - mvwaddch(widget->window, - slider->vertical ? (size - position - 1) : 0, - slider->vertical ? 0 : position, - ACS_CKBOARD | gnt_color_pair(attr)); -} - -static void -gnt_slider_size_request(GntWidget *widget) -{ - if (GNT_SLIDER(widget)->vertical) { - widget->priv.width = 1; - widget->priv.height = 5; - } else { - widget->priv.width = 5; - widget->priv.height = 1; - } -} - -static void -gnt_slider_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static gboolean -step_back(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_advance_step(slider, -1); - return TRUE; -} - -static gboolean -small_step_back(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->current - slider->smallstep); - return TRUE; -} - -static gboolean -large_step_back(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->current - slider->largestep); - return TRUE; -} - -static gboolean -step_forward(GntBindable *bindable, GList *list) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_advance_step(slider, 1); - return TRUE; -} - -static gboolean -small_step_forward(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->current + slider->smallstep); - return TRUE; -} - -static gboolean -large_step_forward(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->current + slider->largestep); - return TRUE; -} - -static gboolean -move_min_value(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->min); - return TRUE; -} - -static gboolean -move_max_value(GntBindable *bindable, GList *null) -{ - GntSlider *slider = GNT_SLIDER(bindable); - gnt_slider_set_value(slider, slider->max); - return TRUE; -} - -static void -gnt_slider_class_init(GntSliderClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->draw = gnt_slider_draw; - parent_class->map = gnt_slider_map; - parent_class->size_request = gnt_slider_size_request; - - klass->changed = NULL; - - signals[SIG_VALUE_CHANGED] = - g_signal_new("changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntSliderClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - gnt_bindable_class_register_action(bindable, "step-backward", step_back, GNT_KEY_LEFT, NULL); - gnt_bindable_register_binding(bindable, "step-backward", GNT_KEY_DOWN, NULL); - gnt_bindable_class_register_action(bindable, "step-forward", step_forward, GNT_KEY_RIGHT, NULL); - gnt_bindable_register_binding(bindable, "step-forward", GNT_KEY_UP, NULL); - gnt_bindable_class_register_action(bindable, "small-step-backward", small_step_back, GNT_KEY_CTRL_LEFT, NULL); - gnt_bindable_register_binding(bindable, "small-step-backward", GNT_KEY_CTRL_DOWN, NULL); - gnt_bindable_class_register_action(bindable, "small-step-forward", small_step_forward, GNT_KEY_CTRL_RIGHT, NULL); - gnt_bindable_register_binding(bindable, "small-step-forward", GNT_KEY_CTRL_UP, NULL); - gnt_bindable_class_register_action(bindable, "large-step-backward", large_step_back, GNT_KEY_PGDOWN, NULL); - gnt_bindable_class_register_action(bindable, "large-step-forward", large_step_forward, GNT_KEY_PGUP, NULL); - gnt_bindable_class_register_action(bindable, "min-value", move_min_value, GNT_KEY_HOME, NULL); - gnt_bindable_class_register_action(bindable, "max-value", move_max_value, GNT_KEY_END, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); -} - -static void -gnt_slider_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_CAN_TAKE_FOCUS); - widget->priv.minw = 1; - widget->priv.minh = 1; - GNTDEBUG; -} - -/****************************************************************************** - * GntSlider API - *****************************************************************************/ -GType -gnt_slider_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntSliderClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_slider_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntSlider), - 0, /* n_preallocs */ - gnt_slider_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntSlider", - &info, 0); - } - - return type; -} - -GntWidget *gnt_slider_new(gboolean vertical, int max, int min) -{ - GntWidget *widget = g_object_new(GNT_TYPE_SLIDER, NULL); - GntSlider *slider = GNT_SLIDER(widget); - - slider->vertical = vertical; - - if (vertical) { - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_Y); - } else { - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X); - } - - gnt_slider_set_range(slider, max, min); - slider->step = 1; - - return widget; -} - -void gnt_slider_set_value(GntSlider *slider, int value) -{ - int old; - if (slider->current == value) - return; - old = slider->current; - slider->current = value; - sanitize_value(slider); - if (old == slider->current) - return; - redraw_slider(slider); - slider_value_changed(slider); -} - -int gnt_slider_get_value(GntSlider *slider) -{ - return slider->current; -} - -int gnt_slider_advance_step(GntSlider *slider, int steps) -{ - gnt_slider_set_value(slider, slider->current + steps * slider->step); - return slider->current; -} - -void gnt_slider_set_step(GntSlider *slider, int step) -{ - slider->step = step; -} - -void gnt_slider_set_small_step(GntSlider *slider, int step) -{ - slider->smallstep = step; -} - -void gnt_slider_set_large_step(GntSlider *slider, int step) -{ - slider->largestep = step; -} - -void gnt_slider_set_range(GntSlider *slider, int max, int min) -{ - slider->max = MAX(max, min); - slider->min = MIN(max, min); - sanitize_value(slider); -} - -static void -update_label(GntSlider *slider, int current_value, GntLabel *label) -{ - char value[256]; - g_snprintf(value, sizeof(value), "%d/%d", current_value, slider->max); - gnt_label_set_text(label, value); -} - -void gnt_slider_reflect_label(GntSlider *slider, GntLabel *label) -{ - g_signal_connect(G_OBJECT(slider), "changed", G_CALLBACK(update_label), label); -} -
--- a/finch/libgnt/gntslider.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/** - * @file gntslider.h Slider API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_SLIDER_H -#define GNT_SLIDER_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntlabel.h" - -#define GNT_TYPE_SLIDER (gnt_slider_get_gtype()) -#define GNT_SLIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SLIDER, GntSlider)) -#define GNT_SLIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_SLIDER, GntSliderClass)) -#define GNT_IS_SLIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_SLIDER)) -#define GNT_IS_SLIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_SLIDER)) -#define GNT_SLIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_SLIDER, GntSliderClass)) - -#define GNT_SLIDER_FLAGS(obj) (GNT_SLIDER(obj)->priv.flags) -#define GNT_SLIDER_SET_FLAGS(obj, flags) (GNT_SLIDER_FLAGS(obj) |= flags) -#define GNT_SLIDER_UNSET_FLAGS(obj, flags) (GNT_SLIDER_FLAGS(obj) &= ~(flags)) - -typedef struct _GntSlider GntSlider; -typedef struct _GntSliderPriv GntSliderPriv; -typedef struct _GntSliderClass GntSliderClass; - -struct _GntSlider -{ - GntWidget parent; - - gboolean vertical; - - int max; /* maximum value */ - int min; /* minimum value */ - int step; /* amount to change at each step */ - int current; /* current value */ - int smallstep; - int largestep; -}; - -struct _GntSliderClass -{ - GntWidgetClass parent; - - void (*changed)(GntSlider *slider, int); - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return The GType for GntSlider - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -GType gnt_slider_get_gtype(void); - -#define gnt_hslider_new(max, min) gnt_slider_new(FALSE, max, min) -#define gnt_vslider_new(max, min) gnt_slider_new(TRUE, max, min) - -/** - * Create a new slider. - * - * @param orient A vertical slider is created if @c TRUE, otherwise the slider is horizontal. - * @param max The maximum value for the slider - * @param min The minimum value for the slider - * - * @return The newly created slider - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -GntWidget * gnt_slider_new(gboolean orient, int max, int min); - -/** - * Set the range of the slider. - * - * @param slider The slider - * @param max The maximum value - * @param min The minimum value - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_slider_set_range(GntSlider *slider, int max, int min); - -/** - * Sets the amount of change at each step. - * - * @param slider The slider - * @param step The amount for each step - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_slider_set_step(GntSlider *slider, int step); - -/** - * Sets the amount of change a small step. - * - * @param slider The slider - * @param step The amount for a small step (for the slider) - * - * @since 2.2.0 - */ -void gnt_slider_set_small_step(GntSlider *slider, int step); - -/** - * Sets the amount of change a large step. - * - * @param slider The slider - * @param step The amount for a large step (for the slider) - * - * @since 2.2.0 - */ -void gnt_slider_set_large_step(GntSlider *slider, int step); - -/** - * Advance the slider forward or backward. - * - * @param slider The slider - * @param steps The number of amounts to change, positive to change - * forward, negative to change backward - * - * @return The value of the slider after the change - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -int gnt_slider_advance_step(GntSlider *slider, int steps); - -/** - * Set the current value for the slider. - * - * @param slider The slider - * @param value The current value - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_slider_set_value(GntSlider *slider, int value); - -/** - * Get the current value for the slider. - * - * @param slider The slider - * - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -int gnt_slider_get_value(GntSlider *slider); - -/** - * Update a label with the value of the slider whenever the value changes. - * - * @param slider The slider - * @param label The label to update - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_slider_reflect_label(GntSlider *slider, GntLabel *label); - - -G_END_DECLS - -#endif /* GNT_SLIDER_H */
--- a/finch/libgnt/gntstyle.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,466 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Style" - -#include "gntstyle.h" -#include "gntcolors.h" -#include "gntws.h" - -#include <glib.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#define MAX_WORKSPACES 99 - -#if GLIB_CHECK_VERSION(2,6,0) -static GKeyFile *gkfile; -#endif - -static char * str_styles[GNT_STYLES]; -static int int_styles[GNT_STYLES]; -static int bool_styles[GNT_STYLES]; - -const char *gnt_style_get(GntStyle style) -{ - return str_styles[style]; -} - -char *gnt_style_get_from_name(const char *group, const char *key) -{ -#if GLIB_CHECK_VERSION(2,6,0) - const char *prg = g_get_prgname(); - if ((group == NULL || *group == '\0') && prg && - g_key_file_has_group(gkfile, prg)) - group = prg; - if (!group) - group = "general"; - return g_key_file_get_value(gkfile, group, key, NULL); -#else - return NULL; -#endif -} - -int -gnt_style_get_color(char *group, char *key) -{ -#if GLIB_CHECK_VERSION(2,6,0) - int fg = 0, bg = 0; - gsize n; - char **vals; - int ret = 0; - vals = gnt_style_get_string_list(group, key, &n); - if (vals && n == 2) { - fg = gnt_colors_get_color(vals[0]); - bg = gnt_colors_get_color(vals[1]); - ret = gnt_color_add_pair(fg, bg); - } - g_strfreev(vals); - return ret; -#else - return 0; -#endif -} - -char **gnt_style_get_string_list(const char *group, const char *key, gsize *length) -{ -#if GLIB_CHECK_VERSION(2,6,0) - const char *prg = g_get_prgname(); - if ((group == NULL || *group == '\0') && prg && - g_key_file_has_group(gkfile, prg)) - group = prg; - if (!group) - group = "general"; - return g_key_file_get_string_list(gkfile, group, key, length, NULL); -#else - return NULL; -#endif -} - -gboolean gnt_style_get_bool(GntStyle style, gboolean def) -{ - const char * str; - - if (bool_styles[style] != -1) - return bool_styles[style]; - - str = gnt_style_get(style); - - bool_styles[style] = str ? gnt_style_parse_bool(str) : def; - return bool_styles[style]; -} - -gboolean gnt_style_parse_bool(const char *str) -{ - gboolean def = FALSE; - int i; - - if (str) - { - if (g_ascii_strcasecmp(str, "false") == 0) - def = FALSE; - else if (g_ascii_strcasecmp(str, "true") == 0) - def = TRUE; - else if (sscanf(str, "%d", &i) == 1) - { - if (i) - def = TRUE; - else - def = FALSE; - } - } - return def; -} - -#if GLIB_CHECK_VERSION(2,6,0) -static void -refine(char *text) -{ - char *s = text, *t = text; - - while (*s) - { - if (*s == '^' && *(s + 1) == '[') - { - *t = '\033'; /* escape */ - s++; - } - else if (*s == '\\') - { - if (*(s + 1) == '\0') - *t = ' '; - else - { - s++; - if (*s == 'r' || *s == 'n') - *t = '\r'; - else if (*s == 't') - *t = '\t'; - else - *t = *s; - } - } - else - *t = *s; - t++; - s++; - } - *t = '\0'; -} - -static char * -parse_key(const char *key) -{ - return (char *)gnt_key_translate(key); -} -#endif - -void gnt_style_read_workspaces(GntWM *wm) -{ -#if GLIB_CHECK_VERSION(2,6,0) - int i; - gchar *name; - gsize c; - - for (i = 1; i < MAX_WORKSPACES; ++i) { - gsize j; - GntWS *ws; - gchar **titles; - char group[32]; - g_snprintf(group, sizeof(group), "Workspace-%d", i); - name = g_key_file_get_value(gkfile, group, "name", NULL); - if (!name) - return; - - ws = gnt_ws_new(name); - gnt_wm_add_workspace(wm, ws); - g_free(name); - - titles = g_key_file_get_string_list(gkfile, group, "window-names", &c, NULL); - if (titles) { - for (j = 0; j < c; ++j) - g_hash_table_replace(wm->name_places, g_strdup(titles[j]), ws); - g_strfreev(titles); - } - - titles = g_key_file_get_string_list(gkfile, group, "window-titles", &c, NULL); - if (titles) { - for (j = 0; j < c; ++j) - g_hash_table_replace(wm->title_places, g_strdup(titles[j]), ws); - g_strfreev(titles); - } - } -#endif -} -void gnt_style_read_actions(GType type, GntBindableClass *klass) -{ -#if GLIB_CHECK_VERSION(2,6,0) - char *name; - GError *error = NULL; - - name = g_strdup_printf("%s::binding", g_type_name(type)); - - if (g_key_file_has_group(gkfile, name)) - { - gsize len = 0; - char **keys; - - keys = g_key_file_get_keys(gkfile, name, &len, &error); - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - g_free(name); - return; - } - - while (len--) - { - char *key, *action; - - key = g_strdup(keys[len]); - action = g_key_file_get_string(gkfile, name, keys[len], &error); - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - error = NULL; - } - else - { - const char *keycode = parse_key(key); - if (keycode == NULL) { - gnt_warning("Invalid key-binding %s", key); - } else { - gnt_bindable_register_binding(klass, action, keycode, NULL); - } - } - g_free(key); - g_free(action); - } - g_strfreev(keys); - } - g_free(name); -#endif -} - -gboolean gnt_style_read_menu_accels(const char *name, GHashTable *table) -{ -#if GLIB_CHECK_VERSION(2,6,0) - char *kname; - GError *error = NULL; - gboolean ret = FALSE; - - kname = g_strdup_printf("%s::menu", name); - - if (g_key_file_has_group(gkfile, kname)) - { - gsize len = 0; - char **keys; - - keys = g_key_file_get_keys(gkfile, kname, &len, &error); - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - g_free(kname); - return ret; - } - - while (len--) - { - char *key, *menuid; - - key = g_strdup(keys[len]); - menuid = g_key_file_get_string(gkfile, kname, keys[len], &error); - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - error = NULL; - } - else - { - const char *keycode = parse_key(key); - if (keycode == NULL) { - gnt_warning("Invalid key-binding %s", key); - } else { - ret = TRUE; - g_hash_table_replace(table, g_strdup(keycode), menuid); - menuid = NULL; - } - } - g_free(key); - g_free(menuid); - } - g_strfreev(keys); - } - - g_free(kname); - return ret; -#endif - return FALSE; -} - -void gnt_styles_get_keyremaps(GType type, GHashTable *hash) -{ -#if GLIB_CHECK_VERSION(2,6,0) - char *name; - GError *error = NULL; - - name = g_strdup_printf("%s::remap", g_type_name(type)); - - if (g_key_file_has_group(gkfile, name)) - { - gsize len = 0; - char **keys; - - keys = g_key_file_get_keys(gkfile, name, &len, &error); - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - g_free(name); - return; - } - - while (len--) - { - char *key, *replace; - - key = g_strdup(keys[len]); - replace = g_key_file_get_string(gkfile, name, keys[len], &error); - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - error = NULL; - g_free(key); - } - else - { - refine(key); - refine(replace); - g_hash_table_insert(hash, key, replace); - } - } - g_strfreev(keys); - } - - g_free(name); -#endif -} - -#if GLIB_CHECK_VERSION(2,6,0) -static void -read_general_style(GKeyFile *kfile) -{ - GError *error = NULL; - gsize nkeys; - const char *prgname = g_get_prgname(); - char **keys = NULL; - int i; - struct - { - const char *style; - GntStyle en; - } styles[] = {{"shadow", GNT_STYLE_SHADOW}, - {"customcolor", GNT_STYLE_COLOR}, - {"mouse", GNT_STYLE_MOUSE}, - {"wm", GNT_STYLE_WM}, - {"remember_position", GNT_STYLE_REMPOS}, - {NULL, 0}}; - - if (prgname && *prgname) - keys = g_key_file_get_keys(kfile, prgname, &nkeys, NULL); - - if (keys == NULL) { - prgname = "general"; - keys = g_key_file_get_keys(kfile, prgname, &nkeys, &error); - } - - if (error) - { - gnt_warning("%s", error->message); - g_error_free(error); - } - else - { - for (i = 0; styles[i].style; i++) - { - str_styles[styles[i].en] = - g_key_file_get_string(kfile, prgname, styles[i].style, NULL); - } - } - g_strfreev(keys); -} -#endif - -void gnt_style_read_configure_file(const char *filename) -{ -#if GLIB_CHECK_VERSION(2,6,0) - GError *error = NULL; - gkfile = g_key_file_new(); - - if (!g_key_file_load_from_file(gkfile, filename, - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)) - { - gnt_warning("%s", error->message); - g_error_free(error); - return; - } - gnt_colors_parse(gkfile); - read_general_style(gkfile); -#endif -} - -void gnt_init_styles() -{ - int i; - for (i = 0; i < GNT_STYLES; i++) - { - str_styles[i] = NULL; - int_styles[i] = -1; - bool_styles[i] = -1; - } -} - -void gnt_uninit_styles() -{ - int i; - for (i = 0; i < GNT_STYLES; i++) { - g_free(str_styles[i]); - str_styles[i] = NULL; - } - -#if GLIB_CHECK_VERSION(2,6,0) - g_key_file_free(gkfile); - gkfile = NULL; -#endif -} -
--- a/finch/libgnt/gntstyle.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/** - * @file gntstyle.h Style API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gnt.h" -#include "gntwm.h" - -typedef enum -{ - GNT_STYLE_SHADOW = 0, - GNT_STYLE_COLOR = 1, - GNT_STYLE_MOUSE = 2, - GNT_STYLE_WM = 3, - GNT_STYLE_REMPOS = 4, - GNT_STYLES -} GntStyle; - -/** - * Read configuration from a file. - * - * @param filename The filename to read configuration from. - */ -void gnt_style_read_configure_file(const char *filename); - -/** - * Get the user-setting for a style. - * @param style The style. - * @return The user-setting, or @c NULL. - */ -const char *gnt_style_get(GntStyle style); - -/** - * Get the value of a preference in ~/.gntrc. - * - * @param group The name of the group in the keyfile. If @c NULL, the prgname - * will be used first, if available. Otherwise, "general" will be used. - * @param key The key - * - * @return The value of the setting as a string, or @c NULL - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -char *gnt_style_get_from_name(const char *group, const char *key); - -/** - * Get the value of a preference in ~/.gntrc. - * - * @param group The name of the group in the keyfile. If @c NULL, the prgname - * will be used first, if available. Otherwise, "general" will be used. - * @param key The key - * @param length Return location for the number of strings returned, or NULL - * - * @return NULL terminated string array. The array should be freed with g_strfreev(). - * - * @since 2.4.0 - */ -char **gnt_style_get_string_list(const char *group, const char *key, gsize *length); - -/** - * Get the value of a color pair in ~/.gntrc. - * - * @param group The name of the group in the keyfile. If @c NULL, the prgname - * will be used first, if available. Otherwise, "general" will be used. - * @param key The key - * - * @return The value of the color as an int, or 0 on error. - * - * @since 2.4.0 - */ -int gnt_style_get_color(char *group, char *key); - -/** - * Parse a boolean preference. For example, if 'value' is "false" (ignoring case) - * or "0", the return value will be @c FALSE, otherwise @c TRUE. - * - * @param value The value of the boolean setting as a string - * @return The boolean value - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -gboolean gnt_style_parse_bool(const char *value); - -/** - * Get the boolean value for a user-setting. - * - * @param style The style. - * @param def The default value (i.e, the value if the user didn't define - * any value) - * - * @return The value of the setting. - */ -gboolean gnt_style_get_bool(GntStyle style, gboolean def); - -/** - * @internal - */ -void gnt_styles_get_keyremaps(GType type, GHashTable *hash); - -/** - * @internal - */ -void gnt_style_read_actions(GType type, GntBindableClass *klass); - -/** - * Read menu-accels from ~/.gntrc - * - * @param name The name of the window. - * @param table The hastable to store the accel information. - * - * @return @c TRUE if some accels were read, @c FALSE otherwise. - */ -gboolean gnt_style_read_menu_accels(const char *name, GHashTable *table); - -/** - * @internal - * Read workspace information. - */ -void gnt_style_read_workspaces(GntWM *wm); - -/** - * Initialize style settings. - */ -void gnt_init_styles(void); - -/** - * Uninitialize style settings. - */ -void gnt_uninit_styles(void); - -
--- a/finch/libgnt/gnttextview.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,955 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "TextView" - -#include "gntstyle.h" -#include "gnttextview.h" -#include "gntutils.h" - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -enum -{ - SIGS = 1, -}; - -typedef struct -{ - GntTextFormatFlags tvflag; - chtype flags; - int start; - int end; /* This is the next byte of the last character of this segment */ -} GntTextSegment; - -typedef struct -{ - GList *segments; /* A list of GntTextSegments */ - int length; /* The current length of the line so far (ie. onscreen width) */ - gboolean soft; /* TRUE if it's an overflow from prev. line */ -} GntTextLine; - -typedef struct -{ - char *name; - int start; - int end; -} GntTextTag; - -static GntWidgetClass *parent_class = NULL; - -static gchar *select_start; -static gchar *select_end; -static gboolean double_click; - -static void reset_text_view(GntTextView *view); - -static gboolean -text_view_contains(GntTextView *view, const char *str) -{ - return (str >= view->string->str && str < view->string->str + view->string->len); -} - -static void -gnt_text_view_draw(GntWidget *widget) -{ - GntTextView *view = GNT_TEXT_VIEW(widget); - int n; - int i = 0; - GList *lines; - int rows, scrcol; - int comp = 0; /* Used for top-aligned text */ - gboolean has_scroll = !(view->flags & GNT_TEXT_VIEW_NO_SCROLL); - - wbkgd(widget->window, gnt_color_pair(GNT_COLOR_NORMAL)); - werase(widget->window); - - n = g_list_length(view->list); - if ((view->flags & GNT_TEXT_VIEW_TOP_ALIGN) && - n < widget->priv.height) { - GList *now = view->list; - comp = widget->priv.height - n; - view->list = g_list_nth_prev(view->list, comp); - if (!view->list) { - view->list = g_list_first(now); - comp = widget->priv.height - g_list_length(view->list); - } else { - comp = 0; - } - } - - for (i = 0, lines = view->list; i < widget->priv.height && lines; i++, lines = lines->next) - { - GList *iter; - GntTextLine *line = lines->data; - - (void)wmove(widget->window, widget->priv.height - 1 - i - comp, 0); - - for (iter = line->segments; iter; iter = iter->next) - { - GntTextSegment *seg = iter->data; - char *end = view->string->str + seg->end; - char back = *end; - chtype fl = seg->flags; - *end = '\0'; - if (select_start && select_start < view->string->str + seg->start && select_end > view->string->str + seg->end) { - fl |= A_REVERSE; - wattrset(widget->window, fl); - wprintw(widget->window, "%s", C_(view->string->str + seg->start)); - } else if (select_start && select_end && - ((select_start >= view->string->str + seg->start && select_start <= view->string->str + seg->end) || - (select_end <= view->string->str + seg->end && select_start <= view->string->str + seg->start))) { - char *cur = view->string->str + seg->start; - while (*cur != '\0') { - gchar *last = g_utf8_next_char(cur); - gchar *str; - if (cur >= select_start && cur <= select_end) - fl |= A_REVERSE; - else - fl = seg->flags; - str = g_strndup(cur, last - cur); - wattrset(widget->window, fl); - waddstr(widget->window, C_(str)); - g_free(str); - cur = g_utf8_next_char(cur); - } - } else { - wattrset(widget->window, fl); - wprintw(widget->window, "%s", C_(view->string->str + seg->start)); - } - *end = back; - } - wattroff(widget->window, A_UNDERLINE | A_BLINK | A_REVERSE); - whline(widget->window, ' ', widget->priv.width - line->length - has_scroll); - } - - scrcol = widget->priv.width - 1; - rows = widget->priv.height - 2; - if (has_scroll && rows > 0) - { - int total = g_list_length(g_list_first(view->list)); - int showing, position, up, down; - - showing = rows * rows / total + 1; - showing = MIN(rows, showing); - - total -= rows; - up = g_list_length(lines); - down = total - up; - - position = (rows - showing) * up / MAX(1, up + down); - position = MAX((lines != NULL), position); - - if (showing + position > rows) - position = rows - showing; - - if (showing + position == rows && view->list && view->list->prev) - position = MAX(1, rows - 1 - showing); - else if (showing + position < rows && view->list && !view->list->prev) - position = rows - showing; - - mvwvline(widget->window, position + 1, scrcol, - ACS_CKBOARD | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D), showing); - } - - if (has_scroll) { - mvwaddch(widget->window, 0, scrcol, - (lines ? ACS_UARROW : ' ') | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - mvwaddch(widget->window, widget->priv.height - 1, scrcol, - ((view->list && view->list->prev) ? ACS_DARROW : ' ') | - gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - } - - wmove(widget->window, 0, 0); -} - -static void -gnt_text_view_size_request(GntWidget *widget) -{ - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - { - gnt_widget_set_size(widget, 64, 20); - } -} - -static void -gnt_text_view_map(GntWidget *widget) -{ - if (widget->priv.width == 0 || widget->priv.height == 0) - gnt_widget_size_request(widget); - GNTDEBUG; -} - -static gboolean -gnt_text_view_key_pressed(GntWidget *widget, const char *text) -{ - return FALSE; -} - -static void -free_text_segment(gpointer data, gpointer null) -{ - GntTextSegment *seg = data; - g_free(seg); -} - -static void -free_text_line(gpointer data, gpointer null) -{ - GntTextLine *line = data; - g_list_foreach(line->segments, free_text_segment, NULL); - g_list_free(line->segments); - g_free(line); -} - -static void -free_tag(gpointer data, gpointer null) -{ - GntTextTag *tag = data; - g_free(tag->name); - g_free(tag); -} - -static void -gnt_text_view_destroy(GntWidget *widget) -{ - GntTextView *view = GNT_TEXT_VIEW(widget); - view->list = g_list_first(view->list); - g_list_foreach(view->list, free_text_line, NULL); - g_list_free(view->list); - g_list_foreach(view->tags, free_tag, NULL); - g_list_free(view->tags); - g_string_free(view->string, TRUE); -} - -static char * -gnt_text_view_get_p(GntTextView *view, int x, int y) -{ - int n; - int i = 0; - GntWidget *wid = GNT_WIDGET(view); - GntTextLine *line; - GList *lines; - GList *segs; - GntTextSegment *seg; - gchar *pos; - - n = g_list_length(view->list); - y = wid->priv.height - y; - if (n < y) { - x = 0; - y = n - 1; - } - - lines = g_list_nth(view->list, y - 1); - if (!lines) - return NULL; - do { - line = lines->data; - lines = lines->next; - } while (line && !line->segments && lines); - - if (!line || !line->segments) /* no valid line */ - return NULL; - segs = line->segments; - seg = (GntTextSegment *)segs->data; - pos = view->string->str + seg->start; - x = MIN(x, line->length); - while (++i <= x) { - gunichar *u; - pos = g_utf8_next_char(pos); - u = g_utf8_to_ucs4(pos, -1, NULL, NULL, NULL); - if (u && g_unichar_iswide(*u)) - i++; - g_free(u); - } - return pos; -} - -static GString * -select_word_text(GntTextView *view, gchar *c) -{ - gchar *start = c; - gchar *end = c; - gchar *t, *endsize; - while ((t = g_utf8_prev_char(start))) { - if (!g_ascii_isspace(*t)) { - if (start == view->string->str) - break; - start = t; - } else - break; - } - while ((t = g_utf8_next_char(end))) { - if (!g_ascii_isspace(*t)) - end = t; - else - break; - } - select_start = start; - select_end = end; - endsize = g_utf8_next_char(select_end); /* End at the correct byte */ - return g_string_new_len(start, endsize - start); -} - -static gboolean too_slow(gpointer n) -{ - double_click = FALSE; - return FALSE; -} - -static gboolean -gnt_text_view_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - if (event == GNT_MOUSE_SCROLL_UP) { - gnt_text_view_scroll(GNT_TEXT_VIEW(widget), -1); - } else if (event == GNT_MOUSE_SCROLL_DOWN) { - gnt_text_view_scroll(GNT_TEXT_VIEW(widget), 1); - } else if (event == GNT_LEFT_MOUSE_DOWN) { - select_start = gnt_text_view_get_p(GNT_TEXT_VIEW(widget), x - widget->priv.x, y - widget->priv.y); - g_timeout_add(500, too_slow, NULL); - } else if (event == GNT_MOUSE_UP) { - GntTextView *view = GNT_TEXT_VIEW(widget); - if (text_view_contains(view, select_start)) { - GString *clip; - select_end = gnt_text_view_get_p(view, x - widget->priv.x, y - widget->priv.y); - if (select_end < select_start) { - gchar *t = select_start; - select_start = select_end; - select_end = t; - } - if (select_start == select_end) { - if (double_click) { - clip = select_word_text(view, select_start); - double_click = FALSE; - } else { - double_click = TRUE; - select_start = 0; - select_end = 0; - gnt_widget_draw(widget); - return TRUE; - } - } else { - gchar *endsize = g_utf8_next_char(select_end); /* End at the correct byte */ - clip = g_string_new_len(select_start, endsize - select_start); - } - gnt_widget_draw(widget); - gnt_set_clipboard_string(clip->str); - g_string_free(clip, TRUE); - } - } else - return FALSE; - return TRUE; -} - -static void -gnt_text_view_reflow(GntTextView *view) -{ - /* This is pretty ugly, and inefficient. Someone do something about it. */ - GntTextLine *line; - GList *back, *iter, *list; - GString *string; - int pos = 0; /* no. of 'real' lines */ - - list = view->list; - while (list->prev) { - line = list->data; - if (!line->soft) - pos++; - list = list->prev; - } - - back = g_list_last(view->list); - view->list = NULL; - - string = view->string; - view->string = NULL; - reset_text_view(view); - - view->string = g_string_set_size(view->string, string->len); - view->string->len = 0; - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING); - - for (; back; back = back->prev) { - line = back->data; - if (back->next && !line->soft) { - gnt_text_view_append_text_with_flags(view, "\n", GNT_TEXT_FLAG_NORMAL); - } - - for (iter = line->segments; iter; iter = iter->next) { - GntTextSegment *seg = iter->data; - char *start = string->str + seg->start; - char *end = string->str + seg->end; - char back = *end; - *end = '\0'; - gnt_text_view_append_text_with_flags(view, start, seg->tvflag); - *end = back; - } - free_text_line(line, NULL); - } - g_list_free(list); - - list = view->list = g_list_first(view->list); - /* Go back to the line that was in view before resizing started */ - while (pos--) { - while (((GntTextLine*)list->data)->soft) - list = list->next; - list = list->next; - } - view->list = list; - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING); - if (GNT_WIDGET(view)->window) - gnt_widget_draw(GNT_WIDGET(view)); - g_string_free(string, TRUE); -} - -static void -gnt_text_view_size_changed(GntWidget *widget, int w, int h) -{ - if (w != widget->priv.width && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) { - gnt_text_view_reflow(GNT_TEXT_VIEW(widget)); - } -} - -static void -gnt_text_view_class_init(GntTextViewClass *klass) -{ - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->destroy = gnt_text_view_destroy; - parent_class->draw = gnt_text_view_draw; - parent_class->map = gnt_text_view_map; - parent_class->size_request = gnt_text_view_size_request; - parent_class->key_pressed = gnt_text_view_key_pressed; - parent_class->clicked = gnt_text_view_clicked; - parent_class->size_changed = gnt_text_view_size_changed; - - GNTDEBUG; -} - -static void -gnt_text_view_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntTextView *view = GNT_TEXT_VIEW(widget); - GntTextLine *line = g_new0(GntTextLine, 1); - - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | - GNT_WIDGET_GROW_Y | GNT_WIDGET_GROW_X); - widget->priv.minw = 5; - widget->priv.minh = 2; - view->string = g_string_new(NULL); - view->list = g_list_append(view->list, line); - - GNTDEBUG; -} - -/****************************************************************************** - * GntTextView API - *****************************************************************************/ -GType -gnt_text_view_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntTextViewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_text_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntTextView), - 0, /* n_preallocs */ - gnt_text_view_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntTextView", - &info, 0); - } - - return type; -} - -GntWidget *gnt_text_view_new() -{ - GntWidget *widget = g_object_new(GNT_TYPE_TEXT_VIEW, NULL); - - return widget; -} - -void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags) -{ - gnt_text_view_append_text_with_tag(view, text, flags, NULL); -} - -void gnt_text_view_append_text_with_tag(GntTextView *view, const char *text, - GntTextFormatFlags flags, const char *tagname) -{ - GntWidget *widget = GNT_WIDGET(view); - chtype fl = 0; - const char *start, *end; - GList *list = view->list; - GntTextLine *line; - int len; - gboolean has_scroll = !(view->flags & GNT_TEXT_VIEW_NO_SCROLL); - gboolean wrap_word = !(view->flags & GNT_TEXT_VIEW_WRAP_CHAR); - - if (text == NULL || *text == '\0') - return; - - fl = gnt_text_format_flag_to_chtype(flags); - - len = view->string->len; - view->string = g_string_append(view->string, text); - - if (tagname) { - GntTextTag *tag = g_new0(GntTextTag, 1); - tag->name = g_strdup(tagname); - tag->start = len; - tag->end = view->string->len; - view->tags = g_list_append(view->tags, tag); - } - - view->list = g_list_first(view->list); - - start = end = view->string->str + len; - - while (*start) { - GntTextLine *oldl; - GntTextSegment *seg = NULL; - - if (*end == '\n' || *end == '\r') { - if (!strncmp(end, "\r\n", 2)) - end++; - end++; - start = end; - gnt_text_view_next_line(view); - view->list = g_list_first(view->list); - continue; - } - - line = view->list->data; - if (line->length == widget->priv.width - has_scroll) { - /* The last added line was exactly the same width as the widget */ - line = g_new0(GntTextLine, 1); - line->soft = TRUE; - view->list = g_list_prepend(view->list, line); - } - - if ((end = strchr(start, '\r')) != NULL || - (end = strchr(start, '\n')) != NULL) { - len = gnt_util_onscreen_width(start, end - has_scroll); - if (widget->priv.width > 0 && - len >= widget->priv.width - line->length - has_scroll) { - end = NULL; - } - } - - if (end == NULL) - end = gnt_util_onscreen_width_to_pointer(start, - widget->priv.width - line->length - has_scroll, &len); - - /* Try to append to the previous segment if possible */ - if (line->segments) { - seg = g_list_last(line->segments)->data; - if (seg->flags != fl) - seg = NULL; - } - - if (seg == NULL) { - seg = g_new0(GntTextSegment, 1); - seg->start = start - view->string->str; - seg->tvflag = flags; - seg->flags = fl; - line->segments = g_list_append(line->segments, seg); - } - - oldl = line; - if (wrap_word && *end && *end != '\n' && *end != '\r') { - const char *tmp = end; - while (end && *end != '\n' && *end != '\r' && !g_ascii_isspace(*end)) { - end = g_utf8_find_prev_char(seg->start + view->string->str, end); - } - if (!end || !g_ascii_isspace(*end)) - end = tmp; - else - end++; /* Remove the space */ - - line = g_new0(GntTextLine, 1); - line->soft = TRUE; - view->list = g_list_prepend(view->list, line); - } - seg->end = end - view->string->str; - oldl->length += len; - start = end; - } - - view->list = list; - - gnt_widget_draw(widget); -} - -void gnt_text_view_scroll(GntTextView *view, int scroll) -{ - if (scroll == 0) - { - view->list = g_list_first(view->list); - } - else if (scroll > 0) - { - GList *list = g_list_nth_prev(view->list, scroll); - if (list == NULL) - list = g_list_first(view->list); - view->list = list; - } - else if (scroll < 0) - { - GList *list = g_list_nth(view->list, -scroll); - if (list == NULL) - list = g_list_last(view->list); - view->list = list; - } - - gnt_widget_draw(GNT_WIDGET(view)); -} - -void gnt_text_view_next_line(GntTextView *view) -{ - GntTextLine *line = g_new0(GntTextLine, 1); - GList *list = view->list; - - view->list = g_list_prepend(g_list_first(view->list), line); - view->list = list; - gnt_widget_draw(GNT_WIDGET(view)); -} - -chtype gnt_text_format_flag_to_chtype(GntTextFormatFlags flags) -{ - chtype fl = 0; - - if (flags & GNT_TEXT_FLAG_BOLD) - fl |= A_BOLD; - if (flags & GNT_TEXT_FLAG_UNDERLINE) - fl |= A_UNDERLINE; - if (flags & GNT_TEXT_FLAG_BLINK) - fl |= A_BLINK; - - if (flags & GNT_TEXT_FLAG_DIM) - fl |= (A_DIM | gnt_color_pair(GNT_COLOR_DISABLED)); - else if (flags & GNT_TEXT_FLAG_HIGHLIGHT) - fl |= (A_DIM | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - else if ((flags & A_COLOR) == 0) - fl |= gnt_color_pair(GNT_COLOR_NORMAL); - else - fl |= (flags & A_COLOR); - - return fl; -} - -static void reset_text_view(GntTextView *view) -{ - GntTextLine *line; - - g_list_foreach(view->list, free_text_line, NULL); - g_list_free(view->list); - view->list = NULL; - - line = g_new0(GntTextLine, 1); - view->list = g_list_append(view->list, line); - if (view->string) - g_string_free(view->string, TRUE); - view->string = g_string_new(NULL); -} - -void gnt_text_view_clear(GntTextView *view) -{ - reset_text_view(view); - - g_list_foreach(view->tags, free_tag, NULL); - view->tags = NULL; - - if (GNT_WIDGET(view)->window) - gnt_widget_draw(GNT_WIDGET(view)); -} - -int gnt_text_view_get_lines_below(GntTextView *view) -{ - int below = 0; - GList *list = view->list; - while ((list = list->prev)) - ++below; - return below; -} - -int gnt_text_view_get_lines_above(GntTextView *view) -{ - int above = 0; - GList *list; - list = g_list_nth(view->list, GNT_WIDGET(view)->priv.height); - if (!list) - return 0; - while ((list = list->next)) - ++above; - return above; -} - -/** - * XXX: There are quite possibly more than a few bugs here. - */ -int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all) -{ - GList *alllines = g_list_first(view->list); - GList *list, *next, *iter, *inext; - const int text_length = text ? strlen(text) : 0; - int count = 0; - for (list = view->tags; list; list = next) { - GntTextTag *tag = list->data; - next = list->next; - if (strcmp(tag->name, name) == 0) { - int change; - char *before, *after; - - count++; - - before = g_strndup(view->string->str, tag->start); - after = g_strdup(view->string->str + tag->end); - change = (tag->end - tag->start) - text_length; - - g_string_printf(view->string, "%s%s%s", before, text ? text : "", after); - g_free(before); - g_free(after); - - /* Update the offsets of the next tags */ - for (iter = next; iter; iter = iter->next) { - GntTextTag *t = iter->data; - t->start -= change; - t->end -= change; - } - - /* Update the offsets of the segments */ - for (iter = alllines; iter; iter = inext) { - GList *segs, *snext; - GntTextLine *line = iter->data; - inext = iter->next; - - if (!line) { - g_warn_if_reached(); - continue; - } - - for (segs = line->segments; segs; segs = snext) { - GntTextSegment *seg = segs->data; - - if (!line) - break; - - snext = segs->next; - if (seg->start >= tag->end) { - /* The segment is somewhere after the tag */ - seg->start -= change; - seg->end -= change; - } else if (seg->end <= tag->start) { - /* This segment is somewhere in front of the tag */ - } else if (seg->start >= tag->start) { - /* This segment starts in the middle of the tag */ - if (text == NULL) { - free_text_segment(seg, NULL); - line->segments = g_list_delete_link(line->segments, segs); - if (line->segments == NULL) { - free_text_line(line, NULL); - line = NULL; - if (view->list == iter) { - if (inext) - view->list = inext; - else - view->list = iter->prev; - } - alllines = g_list_delete_link(alllines, iter); - } - } else { - /* XXX: (null) */ - seg->start = tag->start; - seg->end = tag->end - change; - } - if (line) - line->length -= change; - /* XXX: Make things work if the tagged text spans over several lines. */ - } else { - /* XXX: handle the rest of the conditions */ - gnt_warning("WTF! This needs to be handled properly!!%s", ""); - } - } - } - if (text == NULL) { - /* Remove the tag */ - view->tags = g_list_delete_link(view->tags, list); - free_tag(tag, NULL); - } else { - tag->end -= change; - } - if (!all) - break; - } - } - gnt_widget_draw(GNT_WIDGET(view)); - return count; -} - -static gboolean -scroll_tv(GntWidget *wid, const char *key, GntTextView *tv) -{ - if (strcmp(key, GNT_KEY_PGUP) == 0) { - gnt_text_view_scroll(tv, -(GNT_WIDGET(tv)->priv.height - 2)); - } else if (strcmp(key, GNT_KEY_PGDOWN) == 0) { - gnt_text_view_scroll(tv, GNT_WIDGET(tv)->priv.height - 2); - } else if (strcmp(key, GNT_KEY_DOWN) == 0) { - gnt_text_view_scroll(tv, 1); - } else if (strcmp(key, GNT_KEY_UP) == 0) { - gnt_text_view_scroll(tv, -1); - } else { - return FALSE; - } - return TRUE; -} - -void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget) -{ - g_signal_connect(G_OBJECT(widget), "key_pressed", G_CALLBACK(scroll_tv), view); -} - -void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag) -{ - view->flags |= flag; -} - -/* Pager and editor setups */ -struct -{ - GntTextView *tv; - char *file; -} pageditor; - - -static void -cleanup_pageditor(void) -{ - unlink(pageditor.file); - g_free(pageditor.file); - - pageditor.file = NULL; - pageditor.tv = NULL; -} - -static void -editor_end_cb(int status, gpointer data) -{ - if (status == 0) { - char *text = NULL; - if (g_file_get_contents(pageditor.file, &text, NULL, NULL)) { - reset_text_view(pageditor.tv); - gnt_text_view_append_text_with_flags(pageditor.tv, text, GNT_TEXT_FLAG_NORMAL); - gnt_text_view_scroll(GNT_TEXT_VIEW(pageditor.tv), 0); - g_free(text); - } - } - cleanup_pageditor(); -} - -static void -pager_end_cb(int status, gpointer data) -{ - cleanup_pageditor(); -} - -static gboolean -check_for_ext_cb(GntWidget *widget, const char *key, GntTextView *view) -{ - static const char *pager = NULL; - static const char *editor = NULL; - char *argv[] = {NULL, NULL, NULL}; - static char path[1024]; - static int len = -1; - FILE *file; - gboolean ret; - gboolean pg; - - if (pager == NULL) { - pager = gnt_key_translate(gnt_style_get_from_name("pager", "key")); - if (pager == NULL) - pager = "\033" "v"; - editor = gnt_key_translate(gnt_style_get_from_name("editor", "key")); - if (editor == NULL) - editor = "\033" "e"; - len = g_snprintf(path, sizeof(path), "%s" G_DIR_SEPARATOR_S "gnt", g_get_tmp_dir()); - } else { - g_snprintf(path + len, sizeof(path) - len, "XXXXXX"); - } - - if (strcmp(key, pager) == 0) { - if (g_object_get_data(G_OBJECT(widget), "pager-for") != view) - return FALSE; - pg = TRUE; - } else if (strcmp(key, editor) == 0) { - if (g_object_get_data(G_OBJECT(widget), "editor-for") != view) - return FALSE; - pg = FALSE; - } else { - return FALSE; - } - - file = fdopen(g_mkstemp(path), "wb"); - if (!file) - return FALSE; - fprintf(file, "%s", view->string->str); - fclose(file); - - pageditor.tv = view; - pageditor.file = g_strdup(path); - - argv[0] = gnt_style_get_from_name(pg ? "pager" : "editor", "path"); - argv[0] = argv[0] ? argv[0] : getenv(pg ? "PAGER" : "EDITOR"); - argv[0] = argv[0] ? argv[0] : (pg ? "less" : "vim"); - argv[1] = path; - ret = gnt_giveup_console(NULL, argv, NULL, NULL, NULL, NULL, pg ? pager_end_cb : editor_end_cb, NULL); - return ret; -} - -void gnt_text_view_attach_pager_widget(GntTextView *view, GntWidget *pager) -{ - g_signal_connect(pager, "key_pressed", G_CALLBACK(check_for_ext_cb), view); - g_object_set_data(G_OBJECT(pager), "pager-for", view); -} - -void gnt_text_view_attach_editor_widget(GntTextView *view, GntWidget *wid) -{ - g_signal_connect(wid, "key_pressed", G_CALLBACK(check_for_ext_cb), view); - g_object_set_data(G_OBJECT(wid), "editor-for", view); -} -
--- a/finch/libgnt/gnttextview.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -/** - * @file gnttextview.h Textview API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_TEXT_VIEW_H -#define GNT_TEXT_VIEW_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" - -#define GNT_TYPE_TEXT_VIEW (gnt_text_view_get_gtype()) -#define GNT_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TEXT_VIEW, GntTextView)) -#define GNT_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TEXT_VIEW, GntTextViewClass)) -#define GNT_IS_TEXT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TEXT_VIEW)) -#define GNT_IS_TEXT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TEXT_VIEW)) -#define GNT_TEXT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TEXT_VIEW, GntTextViewClass)) - -#define GNT_TEXT_VIEW_FLAGS(obj) (GNT_TEXT_VIEW(obj)->priv.flags) -#define GNT_TEXT_VIEW_SET_FLAGS(obj, flags) (GNT_TEXT_VIEW_FLAGS(obj) |= flags) -#define GNT_TEXT_VIEW_UNSET_FLAGS(obj, flags) (GNT_TEXT_VIEW_FLAGS(obj) &= ~(flags)) - -typedef struct _GntTextView GntTextView; -typedef struct _GntTextViewPriv GntTextViewPriv; -typedef struct _GntTextViewClass GntTextViewClass; - -typedef enum -{ - GNT_TEXT_VIEW_NO_SCROLL = 1 << 0, - GNT_TEXT_VIEW_WRAP_CHAR = 1 << 1, - GNT_TEXT_VIEW_TOP_ALIGN = 1 << 2, -} GntTextViewFlag; - -struct _GntTextView -{ - GntWidget parent; - - GString *string; - GList *list; /* List of GntTextLine */ - - GList *tags; /* A list of tags */ - GntTextViewFlag flags; -}; - -typedef enum -{ - GNT_TEXT_FLAG_NORMAL = 0, - GNT_TEXT_FLAG_BOLD = 1 << 0, - GNT_TEXT_FLAG_UNDERLINE = 1 << 1, - GNT_TEXT_FLAG_BLINK = 1 << 2, - GNT_TEXT_FLAG_DIM = 1 << 3, - GNT_TEXT_FLAG_HIGHLIGHT = 1 << 4, -} GntTextFormatFlags; - -struct _GntTextViewClass -{ - GntWidgetClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntTextView. - */ -GType gnt_text_view_get_gtype(void); - -/** - * Create a new textview. - * - * @return The newly created textview. - */ -GntWidget * gnt_text_view_new(void); - -/** - * Scroll the textview. - * @param view The textview to scroll. - * @param scroll scroll > 0 means scroll up, < 0 means scroll down, == 0 means scroll to the end. - */ -void gnt_text_view_scroll(GntTextView *view, int scroll); - -/** - * Append new text in a textview. - * - * @param view The textview. - * @param text The text to append to the textview. - * @param flags The text-flags to apply to the new text. - */ -void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags); - -/** - * Append text in the textview, with some identifier (tag) for the added text. - * - * @param view The textview. - * @param text The text to append. - * @param flags The text-flags to apply to the new text. - * @param tag The tag for the appended text, so it can be changed later (@see gnt_text_view_tag_change) - */ -void gnt_text_view_append_text_with_tag(GntTextView *view, const char *text, GntTextFormatFlags flags, const char *tag); - -/** - * Move the cursor to the beginning of the next line and resets text-attributes. - * It first completes the current line with the current text-attributes. - * - * @param view The textview. - */ -void gnt_text_view_next_line(GntTextView *view); - -/** - * Convert GNT-text formats to ncurses-text attributes. - * - * @param flags The GNT text format. - * - * @return Nucrses text attribute. - */ -chtype gnt_text_format_flag_to_chtype(GntTextFormatFlags flags); - -/** - * Clear the contents of the textview. - * - * @param view The textview. - */ -void gnt_text_view_clear(GntTextView *view); - -/** - * The number of lines below the bottom-most visible line. - * - * @param view The textview. - * - * @return Number of lines below the bottom-most visible line. - */ -int gnt_text_view_get_lines_below(GntTextView *view); - -/** - * The number of lines above the topmost visible line. - * - * @param view The textview. - * - * @return Number of lines above the topmost visible line. - */ -int gnt_text_view_get_lines_above(GntTextView *view); - -/** - * Change the text of a tag. - * - * @param view The textview. - * @param name The name of the tag. - * @param text The new text for the text. If 'text' is @c NULL, the tag is removed. - * @param all @c TRUE if all of the instancess of the tag should be changed, @c FALSE if - * only the first instance should be changed. - * - * @return The number of instances changed. - */ -int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all); - -/** - * Setup hooks so that pressing up/down/page-up/page-down keys when 'widget' is - * in focus scrolls the textview. - * - * @param view The textview. - * @param widget The trigger widget. - */ -void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget); - -/** - * Setup appropriate hooks so that pressing some keys when the 'pager' widget - * is in focus triggers the PAGER to popup with the contents of the textview - * in it. - * - * The default key-combination to trigger the pager is a-v, and the default - * PAGER application is $PAGER. Both can be changed in ~/.gntrc like this: - * - * @code - * [pager] - * key = a-v - * path = /path/to/pager - * @endcode - * - * @param view The textview. - * @param pager The widget to trigger the PAGER. - */ -void gnt_text_view_attach_pager_widget(GntTextView *view, GntWidget *pager); - -/** - * Setup appropriate hooks so that pressing some keys when 'widget' - * is in focus triggers the EDITOR to popup with the contents of the textview - * in it. - * - * The default key-combination to trigger the pager is a-e, and the default - * EDITOR application is $EDITOR. Both can be changed in ~/.gntrc like this: - * - * @code - * [editor] - * key = a-e - * path = /path/to/editor - * @endcode - * - * @param view The textview. - * @param widget The widget to trigger the EDITOR. - */ -void gnt_text_view_attach_editor_widget(GntTextView *view, GntWidget *widget); - -/** - * Set a GntTextViewFlag for the textview widget. - * - * @param view The textview widget - * @param flag The flag to set - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag); - -G_END_DECLS - -#endif /* GNT_TEXT_VIEW_H */
--- a/finch/libgnt/gnttree.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1958 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntmarshal.h" -#include "gntstyle.h" -#include "gnttree.h" -#include "gntutils.h" - -#include <string.h> -#include <ctype.h> - -#define SEARCH_TIMEOUT_S 4 /* 4 secs */ -#define SEARCHING(tree) (tree->priv->search && tree->priv->search->len > 0) - -#define COLUMN_INVISIBLE(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_INVISIBLE) -#define BINARY_DATA(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_BINARY_DATA) -#define RIGHT_ALIGNED(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_RIGHT_ALIGNED) - -enum -{ - PROP_0, - PROP_COLUMNS, - PROP_EXPANDER, -}; - -enum -{ - SIG_SELECTION_CHANGED, - SIG_SCROLLED, - SIG_TOGGLED, - SIG_COLLAPSED, - SIGS, -}; - -struct _GntTreePriv -{ - GString *search; - int search_timeout; - int search_column; - gboolean (*search_func)(GntTree *tree, gpointer key, const char *search, const char *current); - - GCompareFunc compare; - int lastvisible; - int expander_level; -}; - -#define TAB_SIZE 3 - -/* XXX: Make this one into a GObject? - * ... Probably not */ -struct _GntTreeRow -{ - void *key; - void *data; /* XXX: unused */ - - gboolean collapsed; - gboolean choice; /* Is this a choice-box? - If choice is true, then child will be NULL */ - gboolean isselected; - GntTextFormatFlags flags; - int color; - - GntTreeRow *parent; - GntTreeRow *child; - GntTreeRow *next; - GntTreeRow *prev; - - GList *columns; - GntTree *tree; -}; - -struct _GntTreeCol -{ - char *text; - gboolean isbinary; - int span; /* How many columns does it span? */ -}; - -static void tree_selection_changed(GntTree *, GntTreeRow *, GntTreeRow *); -static void _gnt_tree_init_internals(GntTree *tree, int col); - -static GntWidgetClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; - -static void -readjust_columns(GntTree *tree) -{ - int i, col, total; - int width; -#define WIDTH(i) (tree->columns[i].width_ratio ? tree->columns[i].width_ratio : tree->columns[i].width) - gnt_widget_get_size(GNT_WIDGET(tree), &width, NULL); - if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)) - width -= 2; - width -= 1; /* Exclude the scrollbar from the calculation */ - for (i = 0, total = 0; i < tree->ncol ; i++) { - if (tree->columns[i].flags & GNT_TREE_COLUMN_INVISIBLE) - continue; - if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) - width -= WIDTH(i) + (tree->priv->lastvisible != i); - else - total += WIDTH(i) + (tree->priv->lastvisible != i); - } - - if (total == 0) - return; - - for (i = 0; i < tree->ncol; i++) { - if (tree->columns[i].flags & GNT_TREE_COLUMN_INVISIBLE) - continue; - if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) - col = WIDTH(i); - else - col = (WIDTH(i) * width) / total; - gnt_tree_set_col_width(GNT_TREE(tree), i, col); - } -} - -/* Move the item at position old to position new */ -static GList * -g_list_reposition_child(GList *list, int old, int new) -{ - gpointer item = g_list_nth_data(list, old); - list = g_list_remove(list, item); - if (old < new) - new--; /* because the positions would have shifted after removing the item */ - list = g_list_insert(list, item, new); - return list; -} - -static GntTreeRow * -_get_next(GntTreeRow *row, gboolean godeep) -{ - if (row == NULL) - return NULL; - if (godeep && row->child) - return row->child; - if (row->next) - return row->next; - return _get_next(row->parent, FALSE); -} - -static gboolean -row_matches_search(GntTreeRow *row) -{ - GntTree *t = row->tree; - if (t->priv->search && t->priv->search->len > 0) { - GntTreeCol *col = (col = g_list_nth_data(row->columns, t->priv->search_column)) ? col : row->columns->data; - char *one, *two, *z; - if (t->priv->search_func) - return t->priv->search_func(t, row->key, t->priv->search->str, col->text); - one = g_utf8_casefold(col->text, -1); - two = g_utf8_casefold(t->priv->search->str, -1); - z = strstr(one, two); - g_free(one); - g_free(two); - if (z == NULL) - return FALSE; - } - return TRUE; -} - -static GntTreeRow * -get_next(GntTreeRow *row) -{ - if (row == NULL) - return NULL; - while ((row = _get_next(row, !row->collapsed)) != NULL) { - if (row_matches_search(row)) - break; - } - return row; -} - -/* Returns the n-th next row. If it doesn't exist, returns NULL */ -static GntTreeRow * -get_next_n(GntTreeRow *row, int n) -{ - while (row && n--) - row = get_next(row); - return row; -} - -/* Returns the n-th next row. If it doesn't exist, then the last non-NULL node */ -static GntTreeRow * -get_next_n_opt(GntTreeRow *row, int n, int *pos) -{ - GntTreeRow *next = row; - int r = 0; - - if (row == NULL) - return NULL; - - while (row && n--) - { - row = get_next(row); - if (row) - { - next = row; - r++; - } - } - - if (pos) - *pos = r; - - return next; -} - -static GntTreeRow * -get_last_child(GntTreeRow *row) -{ - if (row == NULL) - return NULL; - if (!row->collapsed && row->child) - row = row->child; - else - return row; - - while(row->next) - row = row->next; - return get_last_child(row); -} - -static GntTreeRow * -get_prev(GntTreeRow *row) -{ - if (row == NULL) - return NULL; - while (row) { - if (row->prev) - row = get_last_child(row->prev); - else - row = row->parent; - if (!row || row_matches_search(row)) - break; - } - return row; -} - -static GntTreeRow * -get_prev_n(GntTreeRow *row, int n) -{ - while (row && n--) - row = get_prev(row); - return row; -} - -/* Distance of row from the root */ -/* XXX: This is uber-inefficient */ -static int -get_root_distance(GntTreeRow *row) -{ - if (row == NULL) - return -1; - return get_root_distance(get_prev(row)) + 1; -} - -/* Returns the distance between a and b. - * If a is 'above' b, then the distance is positive */ -static int -get_distance(GntTreeRow *a, GntTreeRow *b) -{ - /* First get the distance from a to the root. - * Then the distance from b to the root. - * Subtract. - * It's not that good, but it works. */ - int ha = get_root_distance(a); - int hb = get_root_distance(b); - - return (hb - ha); -} - -static int -find_depth(GntTreeRow *row) -{ - int dep = -1; - - while (row) - { - dep++; - row = row->parent; - } - - return dep; -} - -static char * -update_row_text(GntTree *tree, GntTreeRow *row) -{ - GString *string = g_string_new(NULL); - GList *iter; - int i; - gboolean notfirst = FALSE; - - for (i = 0, iter = row->columns; i < tree->ncol && iter; i++, iter = iter->next) - { - GntTreeCol *col = iter->data; - const char *text; - int len; - int fl = 0; - gboolean cut = FALSE; - int width; - const char *display; - - if (COLUMN_INVISIBLE(tree, i)) - continue; - - if (BINARY_DATA(tree, i)) - display = ""; - else - display = col->text; - - len = gnt_util_onscreen_width(display, NULL); - - width = tree->columns[i].width; - - if (i == 0) - { - if (row->choice) - { - g_string_append_printf(string, "[%c] ", - row->isselected ? 'X' : ' '); - fl = 4; - } - else if (find_depth(row) < tree->priv->expander_level && row->child) - { - if (row->collapsed) - { - string = g_string_append(string, "+ "); - } - else - { - string = g_string_append(string, "- "); - } - fl = 2; - } - else - { - fl = TAB_SIZE * find_depth(row); - g_string_append_printf(string, "%*s", fl, ""); - } - len += fl; - } else if (notfirst && tree->show_separator) - g_string_append_c(string, '|'); - else - g_string_append_c(string, ' '); - - notfirst = TRUE; - - if (len > width) { - len = MAX(1, width - 1); - cut = TRUE; - } - - if (RIGHT_ALIGNED(tree, i) && len < tree->columns[i].width) { - g_string_append_printf(string, "%*s", width - len - cut, ""); - } - - text = gnt_util_onscreen_width_to_pointer(display, len - fl, NULL); - string = g_string_append_len(string, display, text - display); - if (cut && width > 1) { /* ellipsis */ - if (gnt_ascii_only()) - g_string_append_c(string, '~'); - else - string = g_string_append(string, "\342\200\246"); - len++; - } - - if (!RIGHT_ALIGNED(tree, i) && len < tree->columns[i].width && iter->next) - g_string_append_printf(string, "%*s", width - len, ""); - } - return g_string_free(string, FALSE); -} - -#define NEXT_X x += tree->columns[i].width + (i > 0 ? 1 : 0) - -static void -tree_mark_columns(GntTree *tree, int pos, int y, chtype type) -{ - GntWidget *widget = GNT_WIDGET(tree); - int i; - int x = pos; - gboolean notfirst = FALSE; - - for (i = 0; i < tree->ncol - 1; i++) - { - if (!COLUMN_INVISIBLE(tree, i)) { - notfirst = TRUE; - NEXT_X; - } - if (!COLUMN_INVISIBLE(tree, i+1) && notfirst) - mvwaddch(widget->window, y, x, type); - } -} - -static void -redraw_tree(GntTree *tree) -{ - int start, i; - GntWidget *widget = GNT_WIDGET(tree); - GntTreeRow *row; - int pos, up, down = 0; - int rows, scrcol; - int current = 0; - - if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED)) - return; - - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - pos = 0; - else - pos = 1; - - if (tree->top == NULL) - tree->top = tree->root; - if (tree->current == NULL && tree->root != NULL) { - tree->current = tree->root; - tree_selection_changed(tree, NULL, tree->current); - } - - wbkgd(widget->window, gnt_color_pair(GNT_COLOR_NORMAL)); - - start = 0; - if (tree->show_title) - { - int i; - int x = pos; - - mvwhline(widget->window, pos + 1, pos, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), - widget->priv.width - pos - 1); - mvwhline(widget->window, pos, pos, ' ' | gnt_color_pair(GNT_COLOR_NORMAL), - widget->priv.width - pos - 1); - - for (i = 0; i < tree->ncol; i++) - { - if (COLUMN_INVISIBLE(tree, i)) { - continue; - } - mvwaddnstr(widget->window, pos, x + (x != pos), tree->columns[i].title, tree->columns[i].width); - NEXT_X; - } - if (pos) - { - tree_mark_columns(tree, pos, 0, - (tree->show_separator ? ACS_TTEE : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL)); - tree_mark_columns(tree, pos, widget->priv.height - pos, - (tree->show_separator ? ACS_BTEE : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL)); - } - tree_mark_columns(tree, pos, pos + 1, - (tree->show_separator ? ACS_PLUS : ACS_HLINE) | gnt_color_pair(GNT_COLOR_NORMAL)); - tree_mark_columns(tree, pos, pos, - (tree->show_separator ? ACS_VLINE : ' ') | gnt_color_pair(GNT_COLOR_NORMAL)); - start = 2; - } - - rows = widget->priv.height - pos * 2 - start - 1; - tree->bottom = get_next_n_opt(tree->top, rows, &down); - if (down < rows) - { - tree->top = get_prev_n(tree->bottom, rows); - if (tree->top == NULL) - tree->top = tree->root; - } - - up = get_distance(tree->top, tree->current); - if (up < 0) - tree->top = tree->current; - else if (up >= widget->priv.height - pos) - tree->top = get_prev_n(tree->current, rows); - - if (tree->top && !row_matches_search(tree->top)) - tree->top = get_next(tree->top); - row = tree->top; - scrcol = widget->priv.width - 1 - 2 * pos; /* exclude the borders and the scrollbar */ - - if (tree->current && !row_matches_search(tree->current)) { - GntTreeRow *old = tree->current; - tree->current = tree->top; - tree_selection_changed(tree, old, tree->current); - } - - for (i = start + pos; row && i < widget->priv.height - pos; - i++, row = get_next(row)) - { - char *str; - int wr; - - GntTextFormatFlags flags = row->flags; - int attr = 0; - - if (!row_matches_search(row)) - continue; - str = update_row_text(tree, row); - - if ((wr = gnt_util_onscreen_width(str, NULL)) > scrcol) - { - char *s = (char*)gnt_util_onscreen_width_to_pointer(str, scrcol, &wr); - *s = '\0'; - } - - if (flags & GNT_TEXT_FLAG_BOLD) - attr |= A_BOLD; - if (flags & GNT_TEXT_FLAG_UNDERLINE) - attr |= A_UNDERLINE; - if (flags & GNT_TEXT_FLAG_BLINK) - attr |= A_BLINK; - - if (row == tree->current) - { - current = i; - attr |= A_BOLD; - if (gnt_widget_has_focus(widget)) - attr |= gnt_color_pair(GNT_COLOR_HIGHLIGHT); - else - attr |= gnt_color_pair(GNT_COLOR_HIGHLIGHT_D); - } - else - { - if (flags & GNT_TEXT_FLAG_DIM) - if (row->color) - attr |= (A_DIM | gnt_color_pair(row->color)); - else - attr |= (A_DIM | gnt_color_pair(GNT_COLOR_DISABLED)); - else if (flags & GNT_TEXT_FLAG_HIGHLIGHT) - attr |= (A_DIM | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - else if (row->color) - attr |= gnt_color_pair(row->color); - else - attr |= gnt_color_pair(GNT_COLOR_NORMAL); - } - - wbkgdset(widget->window, '\0' | attr); - mvwaddstr(widget->window, i, pos, C_(str)); - whline(widget->window, ' ', scrcol - wr); - tree->bottom = row; - g_free(str); - tree_mark_columns(tree, pos, i, - (tree->show_separator ? ACS_VLINE : ' ') | attr); - } - - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); - while (i < widget->priv.height - pos) - { - mvwhline(widget->window, i, pos, ' ', - widget->priv.width - pos * 2 - 1); - tree_mark_columns(tree, pos, i, - (tree->show_separator ? ACS_VLINE : ' ')); - i++; - } - - scrcol = widget->priv.width - pos - 1; /* position of the scrollbar */ - rows--; - if (rows > 0) - { - int total = 0; - int showing, position; - - get_next_n_opt(tree->root, g_list_length(tree->list), &total); - showing = rows * rows / MAX(total, 1) + 1; - showing = MIN(rows, showing); - - total -= rows; - up = get_distance(tree->root, tree->top); - down = total - up; - - position = (rows - showing) * up / MAX(1, up + down); - position = MAX((tree->top != tree->root), position); - - if (showing + position > rows) - position = rows - showing; - - if (showing + position == rows && row) - position = MAX(0, rows - 1 - showing); - else if (showing + position < rows && !row) - position = rows - showing; - - position += pos + start + 1; - - mvwvline(widget->window, pos + start + 1, scrcol, - ' ' | gnt_color_pair(GNT_COLOR_NORMAL), rows); - mvwvline(widget->window, position, scrcol, - ACS_CKBOARD | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D), showing); - } - - mvwaddch(widget->window, start + pos, scrcol, - ((tree->top != tree->root) ? ACS_UARROW : ' ') | - gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - - mvwaddch(widget->window, widget->priv.height - pos - 1, scrcol, - (row ? ACS_DARROW : ' ') | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - - /* If there's a search-text, show it in the bottom of the tree */ - if (tree->priv->search && tree->priv->search->len > 0) { - const char *str = gnt_util_onscreen_width_to_pointer(tree->priv->search->str, scrcol - 1, NULL); - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D)); - mvwaddnstr(widget->window, widget->priv.height - pos - 1, pos, - tree->priv->search->str, str - tree->priv->search->str); - } - wmove(widget->window, current, pos); - - gnt_widget_queue_update(widget); -} - -static void -gnt_tree_draw(GntWidget *widget) -{ - GntTree *tree = GNT_TREE(widget); - - redraw_tree(tree); - - GNTDEBUG; -} - -static void -gnt_tree_size_request(GntWidget *widget) -{ - if (widget->priv.height == 0) - widget->priv.height = 10; /* XXX: Why?! */ - if (widget->priv.width == 0) - { - GntTree *tree = GNT_TREE(widget); - int i, width = 0; - width = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); - for (i = 0; i < tree->ncol; i++) - if (!COLUMN_INVISIBLE(tree, i)) { - width = width + tree->columns[i].width; - if (tree->priv->lastvisible != i) - width++; - } - widget->priv.width = width; - } -} - -static void -gnt_tree_map(GntWidget *widget) -{ - GntTree *tree = GNT_TREE(widget); - if (widget->priv.width == 0 || widget->priv.height == 0) - { - gnt_widget_size_request(widget); - } - tree->top = tree->root; - tree->current = tree->root; - GNTDEBUG; -} - -static void -tree_selection_changed(GntTree *tree, GntTreeRow *old, GntTreeRow *current) -{ - g_signal_emit(tree, signals[SIG_SELECTION_CHANGED], 0, old ? old->key : NULL, - current ? current->key : NULL); -} - -static gboolean -action_down(GntBindable *bind, GList *null) -{ - int dist; - GntTree *tree = GNT_TREE(bind); - GntTreeRow *old = tree->current; - GntTreeRow *row = get_next(tree->current); - if (row == NULL) - return FALSE; - tree->current = row; - if ((dist = get_distance(tree->current, tree->bottom)) < 0) - gnt_tree_scroll(tree, -dist); - else - redraw_tree(tree); - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - return TRUE; -} - -static gboolean -action_move_parent(GntBindable *bind, GList *null) -{ - GntTree *tree = GNT_TREE(bind); - GntTreeRow *row = tree->current; - int dist; - - if (!row || !row->parent || SEARCHING(tree)) - return FALSE; - - tree->current = row->parent; - if ((dist = get_distance(tree->current, tree->top)) > 0) - gnt_tree_scroll(tree, -dist); - else - redraw_tree(tree); - tree_selection_changed(tree, row, tree->current); - return TRUE; -} - -static gboolean -action_up(GntBindable *bind, GList *list) -{ - int dist; - GntTree *tree = GNT_TREE(bind); - GntTreeRow *old = tree->current; - GntTreeRow *row = get_prev(tree->current); - if (!row) - return FALSE; - tree->current = row; - if ((dist = get_distance(tree->current, tree->top)) > 0) - gnt_tree_scroll(tree, -dist); - else - redraw_tree(tree); - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - - return TRUE; -} - -static gboolean -action_page_down(GntBindable *bind, GList *null) -{ - GntTree *tree = GNT_TREE(bind); - GntTreeRow *old = tree->current; - GntTreeRow *row = get_next(tree->bottom); - if (row) - { - int dist = get_distance(tree->top, tree->current); - tree->top = tree->bottom; - tree->current = get_next_n_opt(tree->top, dist, NULL); - redraw_tree(tree); - } - else if (tree->current != tree->bottom) - { - tree->current = tree->bottom; - redraw_tree(tree); - } - - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - return TRUE; -} - -static gboolean -action_page_up(GntBindable *bind, GList *null) -{ - GntWidget *widget = GNT_WIDGET(bind); - GntTree *tree = GNT_TREE(bind); - GntTreeRow *row; - GntTreeRow *old = tree->current; - - if (tree->top != tree->root) - { - int dist = get_distance(tree->top, tree->current); - row = get_prev_n(tree->top, widget->priv.height - 1 - - tree->show_title * 2 - 2 * (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER) == 0)); - if (row == NULL) - row = tree->root; - tree->top = row; - tree->current = get_next_n_opt(tree->top, dist, NULL); - redraw_tree(tree); - } - else if (tree->current != tree->top) - { - tree->current = tree->top; - redraw_tree(tree); - } - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - return TRUE; -} - -static void -end_search(GntTree *tree) -{ - if (tree->priv->search) { - g_source_remove(tree->priv->search_timeout); - g_string_free(tree->priv->search, TRUE); - tree->priv->search = NULL; - tree->priv->search_timeout = 0; - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(tree), GNT_WIDGET_DISABLE_ACTIONS); - } -} - -static gboolean -search_timeout(gpointer data) -{ - GntTree *tree = data; - - end_search(tree); - redraw_tree(tree); - - return FALSE; -} - -static gboolean -gnt_tree_key_pressed(GntWidget *widget, const char *text) -{ - GntTree *tree = GNT_TREE(widget); - GntTreeRow *old = tree->current; - - if (text[0] == '\r' || text[0] == '\n') { - end_search(tree); - gnt_widget_activate(widget); - } else if (tree->priv->search) { - gboolean changed = TRUE; - if (g_unichar_isprint(*text)) { - tree->priv->search = g_string_append_c(tree->priv->search, *text); - } else if (g_utf8_collate(text, GNT_KEY_BACKSPACE) == 0) { - if (tree->priv->search->len) - tree->priv->search->str[--tree->priv->search->len] = '\0'; - } else - changed = FALSE; - if (changed) { - redraw_tree(tree); - } else { - gnt_bindable_perform_action_key(GNT_BINDABLE(tree), text); - } - g_source_remove(tree->priv->search_timeout); - tree->priv->search_timeout = g_timeout_add_seconds(SEARCH_TIMEOUT_S, search_timeout, tree); - return TRUE; - } else if (text[0] == ' ' && text[1] == 0) { - /* Space pressed */ - GntTreeRow *row = tree->current; - if (row && row->child) - { - row->collapsed = !row->collapsed; - redraw_tree(tree); - g_signal_emit(tree, signals[SIG_COLLAPSED], 0, row->key, row->collapsed); - } - else if (row && row->choice) - { - row->isselected = !row->isselected; - g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key); - redraw_tree(tree); - } - } else { - return FALSE; - } - - if (old != tree->current) - { - tree_selection_changed(tree, old, tree->current); - } - - return TRUE; -} - -static void -gnt_tree_free_columns(GntTree *tree) -{ - int i; - for (i = 0; i < tree->ncol; i++) { - g_free(tree->columns[i].title); - } - g_free(tree->columns); -} - -static void -gnt_tree_destroy(GntWidget *widget) -{ - GntTree *tree = GNT_TREE(widget); - - end_search(tree); - if (tree->hash) - g_hash_table_destroy(tree->hash); - g_list_free(tree->list); - gnt_tree_free_columns(tree); - g_free(tree->priv); -} - -static gboolean -gnt_tree_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - GntTree *tree = GNT_TREE(widget); - GntTreeRow *old = tree->current; - if (event == GNT_MOUSE_SCROLL_UP) { - action_up(GNT_BINDABLE(widget), NULL); - } else if (event == GNT_MOUSE_SCROLL_DOWN) { - action_down(GNT_BINDABLE(widget), NULL); - } else if (event == GNT_LEFT_MOUSE_DOWN) { - GntTreeRow *row; - GntTree *tree = GNT_TREE(widget); - int pos = 1; - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - pos = 0; - if (tree->show_title) - pos += 2; - pos = y - widget->priv.y - pos; - row = get_next_n(tree->top, pos); - if (row && tree->current != row) { - GntTreeRow *old = tree->current; - tree->current = row; - redraw_tree(tree); - tree_selection_changed(tree, old, tree->current); - } else if (row && row == tree->current) { - if (row->choice) { - row->isselected = !row->isselected; - g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key); - redraw_tree(tree); - } else { - gnt_widget_activate(widget); - } - } - } else { - return FALSE; - } - if (old != tree->current) { - tree_selection_changed(tree, old, tree->current); - } - return TRUE; -} - -static void -gnt_tree_size_changed(GntWidget *widget, int w, int h) -{ - GntTree *tree = GNT_TREE(widget); - if (widget->priv.width <= 0) - return; - - readjust_columns(tree); -} - -static gboolean -start_search(GntBindable *bindable, GList *list) -{ - GntTree *tree = GNT_TREE(bindable); - if (tree->priv->search) - return FALSE; - GNT_WIDGET_SET_FLAGS(GNT_WIDGET(tree), GNT_WIDGET_DISABLE_ACTIONS); - tree->priv->search = g_string_new(NULL); - tree->priv->search_timeout = g_timeout_add_seconds(SEARCH_TIMEOUT_S, search_timeout, tree); - return TRUE; -} - -static gboolean -end_search_action(GntBindable *bindable, GList *list) -{ - GntTree *tree = GNT_TREE(bindable); - if (tree->priv->search == NULL) - return FALSE; - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(tree), GNT_WIDGET_DISABLE_ACTIONS); - end_search(tree); - redraw_tree(tree); - return TRUE; -} - -static gboolean -move_first_action(GntBindable *bind, GList *null) -{ - GntTree *tree = GNT_TREE(bind); - GntTreeRow *row = tree->root; - GntTreeRow *old = tree->current; - if (row && !row_matches_search(row)) - row = get_next(row); - if (row) { - tree->current = row; - redraw_tree(tree); - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - } - - return TRUE; -} - -static gboolean -move_last_action(GntBindable *bind, GList *null) -{ - GntTree *tree = GNT_TREE(bind); - GntTreeRow *old = tree->current; - GntTreeRow *row = tree->bottom; - GntTreeRow *next; - - while ((next = get_next(row))) - row = next; - - if (row) { - tree->current = row; - redraw_tree(tree); - if (old != tree->current) - tree_selection_changed(tree, old, tree->current); - } - - return TRUE; -} - -static void -gnt_tree_set_property(GObject *obj, guint prop_id, const GValue *value, - GParamSpec *spec) -{ - GntTree *tree = GNT_TREE(obj); - switch (prop_id) { - case PROP_COLUMNS: - _gnt_tree_init_internals(tree, g_value_get_int(value)); - break; - case PROP_EXPANDER: - if (tree->priv->expander_level == g_value_get_int(value)) - break; - tree->priv->expander_level = g_value_get_int(value); - g_object_notify(obj, "expander-level"); - default: - break; - } -} - -static void -gnt_tree_get_property(GObject *obj, guint prop_id, GValue *value, - GParamSpec *spec) -{ - GntTree *tree = GNT_TREE(obj); - switch (prop_id) { - case PROP_COLUMNS: - g_value_set_int(value, tree->ncol); - break; - case PROP_EXPANDER: - g_value_set_int(value, tree->priv->expander_level); - break; - default: - break; - } -} - -static void -gnt_tree_class_init(GntTreeClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - GObjectClass *gclass = G_OBJECT_CLASS(klass); - - parent_class = GNT_WIDGET_CLASS(klass); - parent_class->destroy = gnt_tree_destroy; - parent_class->draw = gnt_tree_draw; - parent_class->map = gnt_tree_map; - parent_class->size_request = gnt_tree_size_request; - parent_class->key_pressed = gnt_tree_key_pressed; - parent_class->clicked = gnt_tree_clicked; - parent_class->size_changed = gnt_tree_size_changed; - - gclass->set_property = gnt_tree_set_property; - gclass->get_property = gnt_tree_get_property; - g_object_class_install_property(gclass, - PROP_COLUMNS, - g_param_spec_int("columns", "Columns", - "Number of columns in the tree.", - 1, G_MAXINT, 1, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - g_object_class_install_property(gclass, - PROP_EXPANDER, - g_param_spec_int("expander-level", "Expander level", - "Number of levels to show expander in the tree.", - 0, G_MAXINT, 1, - G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB - ) - ); - - signals[SIG_SELECTION_CHANGED] = - g_signal_new("selection-changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntTreeClass, selection_changed), - NULL, NULL, - gnt_closure_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - signals[SIG_SCROLLED] = - g_signal_new("scrolled", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - signals[SIG_TOGGLED] = - g_signal_new("toggled", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntTreeClass, toggled), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[SIG_COLLAPSED] = - g_signal_new("collapse-toggled", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - gnt_closure_marshal_VOID__POINTER_BOOLEAN, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); - - gnt_bindable_class_register_action(bindable, "move-up", action_up, - GNT_KEY_UP, NULL); - 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_bindable_register_binding(bindable, "move-down", GNT_KEY_CTRL_N, NULL); - gnt_bindable_class_register_action(bindable, "move-parent", action_move_parent, - GNT_KEY_BACKSPACE, NULL); - gnt_bindable_class_register_action(bindable, "page-up", action_page_up, - GNT_KEY_PGUP, NULL); - gnt_bindable_class_register_action(bindable, "page-down", action_page_down, - GNT_KEY_PGDOWN, NULL); - gnt_bindable_class_register_action(bindable, "start-search", start_search, - "/", NULL); - gnt_bindable_class_register_action(bindable, "end-search", end_search_action, - "\033", NULL); - gnt_bindable_class_register_action(bindable, "move-first", move_first_action, - GNT_KEY_HOME, NULL); - gnt_bindable_class_register_action(bindable, "move-last", move_last_action, - GNT_KEY_END, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable); - GNTDEBUG; -} - -static void -gnt_tree_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntTree *tree = GNT_TREE(widget); - tree->show_separator = TRUE; - tree->priv = g_new0(GntTreePriv, 1); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y | - GNT_WIDGET_CAN_TAKE_FOCUS | GNT_WIDGET_NO_SHADOW); - gnt_widget_set_take_focus(widget, TRUE); - widget->priv.minw = 4; - widget->priv.minh = 1; - GNTDEBUG; -} - -/****************************************************************************** - * GntTree API - *****************************************************************************/ -GType -gnt_tree_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntTreeClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_tree_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntTree), - 0, /* n_preallocs */ - gnt_tree_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_WIDGET, - "GntTree", - &info, 0); - } - - return type; -} - -static void -free_tree_col(gpointer data) -{ - GntTreeCol *col = data; - if (!col->isbinary) - g_free(col->text); - g_free(col); -} - -static void -free_tree_row(gpointer data) -{ - GntTreeRow *row = data; - - if (!row) - return; - - g_list_foreach(row->columns, (GFunc)free_tree_col, NULL); - g_list_free(row->columns); - g_free(row); -} - -GntWidget *gnt_tree_new() -{ - return gnt_tree_new_with_columns(1); -} - -void gnt_tree_set_visible_rows(GntTree *tree, int rows) -{ - GntWidget *widget = GNT_WIDGET(tree); - widget->priv.height = rows; - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - widget->priv.height += 2; -} - -int gnt_tree_get_visible_rows(GntTree *tree) -{ - GntWidget *widget = GNT_WIDGET(tree); - int ret = widget->priv.height; - if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER)) - ret -= 2; - return ret; -} - -GList *gnt_tree_get_rows(GntTree *tree) -{ - return tree->list; -} - -void gnt_tree_scroll(GntTree *tree, int count) -{ - GntTreeRow *row; - - if (count < 0) - { - if (get_root_distance(tree->top) == 0) - return; - row = get_prev_n(tree->top, -count); - if (row == NULL) - row = tree->root; - tree->top = row; - } - else - { - get_next_n_opt(tree->bottom, count, &count); - tree->top = get_next_n(tree->top, count); - } - - redraw_tree(tree); - g_signal_emit(tree, signals[SIG_SCROLLED], 0, count); -} - -static gpointer -find_position(GntTree *tree, gpointer key, gpointer parent) -{ - GntTreeRow *row; - - if (tree->priv->compare == NULL) - return NULL; - - if (parent == NULL) - row = tree->root; - else - row = g_hash_table_lookup(tree->hash, parent); - - if (!row) - return NULL; - - if (parent) - row = row->child; - - while (row) - { - if (tree->priv->compare(key, row->key) < 0) - return (row->prev ? row->prev->key : NULL); - if (row->next) - row = row->next; - else - return row->key; - } - return NULL; -} - -void gnt_tree_sort_row(GntTree *tree, gpointer key) -{ - GntTreeRow *row, *q, *s; - int current, newp; - - if (!tree->priv->compare) - return; - - row = g_hash_table_lookup(tree->hash, key); - g_return_if_fail(row != NULL); - - current = g_list_index(tree->list, key); - - if (row->parent) - s = row->parent->child; - else - s = tree->root; - - q = NULL; - while (s) { - if (tree->priv->compare(row->key, s->key) < 0) - break; - q = s; - s = s->next; - } - - /* Move row between q and s */ - if (row == q || row == s) - return; - - if (q == NULL) { - /* row becomes the first child of its parent */ - row->prev->next = row->next; /* row->prev cannot be NULL at this point */ - if (row->next) - row->next->prev = row->prev; - if (row->parent) - row->parent->child = row; - else - tree->root = row; - row->next = s; - s->prev = row; /* s cannot be NULL */ - row->prev = NULL; - newp = g_list_index(tree->list, s) - 1; - } else { - if (row->prev) { - row->prev->next = row->next; - } else { - /* row was the first child of its parent */ - if (row->parent) - row->parent->child = row->next; - else - tree->top = row->next; - } - - if (row->next) - row->next->prev = row->prev; - - q->next = row; - row->prev = q; - if (s) - s->prev = row; - row->next = s; - newp = g_list_index(tree->list, q) + 1; - } - tree->list = g_list_reposition_child(tree->list, current, newp); - - redraw_tree(tree); -} - -GntTreeRow *gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro) -{ - GntTreeRow *pr = NULL; - - if (g_hash_table_lookup(tree->hash, key)) { - gnt_tree_remove(tree, key); - } - - row->tree = tree; - row->key = key; - row->data = NULL; - g_hash_table_replace(tree->hash, key, row); - - if (bigbro == NULL && tree->priv->compare) - { - bigbro = find_position(tree, key, parent); - } - - if (tree->root == NULL) - { - tree->root = row; - tree->list = g_list_prepend(tree->list, key); - } - else - { - int position = 0; - - if (bigbro) - { - pr = g_hash_table_lookup(tree->hash, bigbro); - if (pr) - { - if (pr->next) pr->next->prev = row; - row->next = pr->next; - row->prev = pr; - pr->next = row; - row->parent = pr->parent; - - position = g_list_index(tree->list, bigbro); - } - } - - if (pr == NULL && parent) - { - pr = g_hash_table_lookup(tree->hash, parent); - if (pr) - { - if (pr->child) pr->child->prev = row; - row->next = pr->child; - pr->child = row; - row->parent = pr; - - position = g_list_index(tree->list, parent); - } - } - - if (pr == NULL) - { - GntTreeRow *r = tree->root; - row->next = r; - if (r) r->prev = row; - if (tree->current == tree->root) - tree->current = row; - tree->root = row; - tree->list = g_list_prepend(tree->list, key); - } - else - { - tree->list = g_list_insert(tree->list, key, position + 1); - } - } - redraw_tree(tree); - - return row; -} - -GntTreeRow *gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent) -{ - GntTreeRow *pr = NULL, *br = NULL; - - if (parent) - pr = g_hash_table_lookup(tree->hash, parent); - - if (pr) - br = pr->child; - else - br = tree->root; - - if (br) - { - while (br->next) - br = br->next; - } - - return gnt_tree_add_row_after(tree, key, row, parent, br ? br->key : NULL); -} - -gpointer gnt_tree_get_selection_data(GntTree *tree) -{ - if (tree->current) - return tree->current->key; /* XXX: perhaps we should just get rid of 'data' */ - return NULL; -} - -char *gnt_tree_get_selection_text(GntTree *tree) -{ - if (tree->current) - return update_row_text(tree, tree->current); - return NULL; -} - -GList *gnt_tree_get_row_text_list(GntTree *tree, gpointer key) -{ - GList *list = NULL, *iter; - GntTreeRow *row = key ? g_hash_table_lookup(tree->hash, key) : tree->current; - int i; - - if (!row) - return NULL; - - for (i = 0, iter = row->columns; i < tree->ncol && iter; - i++, iter = iter->next) - { - GntTreeCol *col = iter->data; - list = g_list_append(list, BINARY_DATA(tree, i) ? col->text : g_strdup(col->text)); - } - - return list; -} - -GList *gnt_tree_get_selection_text_list(GntTree *tree) -{ - return gnt_tree_get_row_text_list(tree, NULL); -} - -void gnt_tree_remove(GntTree *tree, gpointer key) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - static int depth = 0; /* Only redraw after all child nodes are removed */ - if (row) - { - gboolean redraw = FALSE; - - if (row->child) { - depth++; - while (row->child) { - gnt_tree_remove(tree, row->child->key); - } - depth--; - } - - if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0) - redraw = TRUE; - - /* Update root/top/current/bottom if necessary */ - if (tree->root == row) - tree->root = get_next(row); - if (tree->top == row) - { - if (tree->top != tree->root) - tree->top = get_prev(row); - else - tree->top = get_next(row); - } - if (tree->current == row) - { - if (tree->current != tree->root) - tree->current = get_prev(row); - else - tree->current = get_next(row); - tree_selection_changed(tree, row, tree->current); - } - if (tree->bottom == row) - { - tree->bottom = get_prev(row); - } - - /* Fix the links */ - if (row->next) - row->next->prev = row->prev; - if (row->parent && row->parent->child == row) - row->parent->child = row->next; - if (row->prev) - row->prev->next = row->next; - - g_hash_table_remove(tree->hash, key); - tree->list = g_list_remove(tree->list, key); - - if (redraw && depth == 0) - { - redraw_tree(tree); - } - } -} - -static gboolean -return_true(gpointer key, gpointer data, gpointer null) -{ - return TRUE; -} - -void gnt_tree_remove_all(GntTree *tree) -{ - tree->root = NULL; - g_hash_table_foreach_remove(tree->hash, (GHRFunc)return_true, tree); - g_list_free(tree->list); - tree->list = NULL; - tree->current = tree->top = tree->bottom = NULL; -} - -int gnt_tree_get_selection_visible_line(GntTree *tree) -{ - return get_distance(tree->top, tree->current) + - !!(GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); -} - -void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text) -{ - GntTreeRow *row; - GntTreeCol *col; - - g_return_if_fail(colno < tree->ncol); - - row = g_hash_table_lookup(tree->hash, key); - if (row) - { - col = g_list_nth_data(row->columns, colno); - if (BINARY_DATA(tree, colno)) { - col->text = (gpointer)text; - } else { - g_free(col->text); - col->text = g_strdup(text ? text : ""); - } - - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED) && - get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0) - redraw_tree(tree); - } -} - -GntTreeRow *gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro) -{ - GntTreeRow *r; - r = g_hash_table_lookup(tree->hash, key); - g_return_val_if_fail(!r || !r->choice, NULL); - - if (bigbro == NULL) { - if (tree->priv->compare) - bigbro = find_position(tree, key, parent); - else { - r = g_hash_table_lookup(tree->hash, parent); - if (!r) - r = tree->root; - else - r = r->child; - if (r) { - while (r->next) - r = r->next; - bigbro = r->key; - } - } - } - row = gnt_tree_add_row_after(tree, key, row, parent, bigbro); - row->choice = TRUE; - - return row; -} - -void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - - if (!row) - return; - g_return_if_fail(row->choice); - - row->isselected = set; - redraw_tree(tree); -} - -gboolean gnt_tree_get_choice(GntTree *tree, void *key) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - - if (!row) - return FALSE; - g_return_val_if_fail(row->choice, FALSE); - - return row->isselected; -} - -void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - if (!row || row->flags == flags) - return; - - row->flags = flags; - redraw_tree(tree); /* XXX: It shouldn't be necessary to redraw the whole darned tree */ -} - -void gnt_tree_set_row_color(GntTree *tree, void *key, int color) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - if (!row || row->color == color) - return; - - row->color = color; - redraw_tree(tree); -} - -void gnt_tree_set_selected(GntTree *tree , void *key) -{ - int dist; - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - if (!row || row == tree->current) - return; - - if (tree->top == NULL) - tree->top = row; - if (tree->bottom == NULL) - tree->bottom = row; - - tree->current = row; - if ((dist = get_distance(tree->current, tree->bottom)) < 0) - gnt_tree_scroll(tree, -dist); - else if ((dist = get_distance(tree->current, tree->top)) > 0) - gnt_tree_scroll(tree, -dist); - else - redraw_tree(tree); - tree_selection_changed(tree, row, tree->current); -} - -static void _gnt_tree_init_internals(GntTree *tree, int col) -{ - gnt_tree_free_columns(tree); - - tree->ncol = col; - tree->hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_tree_row); - tree->columns = g_new0(struct _GntTreeColInfo, col); - tree->priv->lastvisible = col - 1; - while (col--) - { - tree->columns[col].width = 15; - } - tree->list = NULL; - tree->show_title = FALSE; - g_object_notify(G_OBJECT(tree), "columns"); -} - -GntWidget *gnt_tree_new_with_columns(int col) -{ - GntWidget *widget = g_object_new(GNT_TYPE_TREE, - "columns", col, - "expander-level", 1, - NULL); - - return widget; -} - -GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list) -{ - GList *iter; - int i; - GntTreeRow *row = g_new0(GntTreeRow, 1); - - for (i = 0, iter = list; i < tree->ncol && iter; iter = iter->next, i++) - { - GntTreeCol *col = g_new0(GntTreeCol, 1); - col->span = 1; - if (BINARY_DATA(tree, i)) { - col->text = iter->data; - col->isbinary = TRUE; - } else { - col->text = g_strdup(iter->data ? iter->data : ""); - col->isbinary = FALSE; - } - - row->columns = g_list_append(row->columns, col); - } - - return row; -} - -GntTreeRow *gnt_tree_create_row(GntTree *tree, ...) -{ - int i; - va_list args; - GList *list = NULL; - GntTreeRow *row; - - va_start(args, tree); - for (i = 0; i < tree->ncol; i++) - { - list = g_list_append(list, va_arg(args, char *)); - } - va_end(args); - - row = gnt_tree_create_row_from_list(tree, list); - g_list_free(list); - - return row; -} - -void gnt_tree_set_col_width(GntTree *tree, int col, int width) -{ - g_return_if_fail(col < tree->ncol); - - tree->columns[col].width = width; - if (tree->columns[col].width_ratio == 0) - tree->columns[col].width_ratio = width; -} - -void gnt_tree_set_column_title(GntTree *tree, int index, const char *title) -{ - g_free(tree->columns[index].title); - tree->columns[index].title = g_strdup(title); -} - -void gnt_tree_set_column_titles(GntTree *tree, ...) -{ - int i; - va_list args; - - va_start(args, tree); - for (i = 0; i < tree->ncol; i++) - { - const char *title = va_arg(args, const char *); - tree->columns[i].title = g_strdup(title); - } - va_end(args); -} - -void gnt_tree_set_show_title(GntTree *tree, gboolean set) -{ - tree->show_title = set; - GNT_WIDGET(tree)->priv.minh = (set ? 6 : 4); -} - -void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func) -{ - tree->priv->compare = func; -} - -void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - if (row) { - row->collapsed = !expanded; - if (GNT_WIDGET(tree)->window) - gnt_widget_draw(GNT_WIDGET(tree)); - g_signal_emit(tree, signals[SIG_COLLAPSED], 0, key, row->collapsed); - } -} - -void gnt_tree_set_show_separator(GntTree *tree, gboolean set) -{ - tree->show_separator = set; -} - -void gnt_tree_adjust_columns(GntTree *tree) -{ - GntTreeRow *row = tree->root; - int *widths, i, twidth; - - widths = g_new0(int, tree->ncol); - while (row) { - GList *iter; - for (i = 0, iter = row->columns; iter; iter = iter->next, i++) { - GntTreeCol *col = iter->data; - int w = gnt_util_onscreen_width(col->text, NULL); - if (i == 0 && row->choice) - w += 4; - if (i == 0) { - w += find_depth(row) * TAB_SIZE; - } - if (widths[i] < w) - widths[i] = w; - } - row = get_next(row); - } - - twidth = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); - for (i = 0; i < tree->ncol; i++) { - if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) - widths[i] = tree->columns[i].width; - gnt_tree_set_col_width(tree, i, widths[i]); - if (!COLUMN_INVISIBLE(tree, i)) { - twidth = twidth + widths[i]; - if (tree->priv->lastvisible != i) - twidth += 1; - } - } - g_free(widths); - - gnt_widget_set_size(GNT_WIDGET(tree), twidth, -1); -} - -void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd) -{ - g_hash_table_foreach_remove(tree->hash, return_true, NULL); - g_hash_table_destroy(tree->hash); - tree->hash = g_hash_table_new_full(hash, eq, kd, free_tree_row); -} - -static void -set_column_flag(GntTree *tree, int col, GntTreeColumnFlag flag, gboolean set) -{ - if (set) - tree->columns[col].flags |= flag; - else - tree->columns[col].flags &= ~flag; -} - -void gnt_tree_set_column_visible(GntTree *tree, int col, gboolean vis) -{ - g_return_if_fail(col < tree->ncol); - set_column_flag(tree, col, GNT_TREE_COLUMN_INVISIBLE, !vis); - if (vis) { - /* the column is visible */ - if (tree->priv->lastvisible < col) - tree->priv->lastvisible = col; - } else { - if (tree->priv->lastvisible == col) - while (tree->priv->lastvisible) { - tree->priv->lastvisible--; - if (!COLUMN_INVISIBLE(tree, tree->priv->lastvisible)) - break; - } - } - if (GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_MAPPED)) - readjust_columns(tree); -} - -void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res) -{ - g_return_if_fail(col < tree->ncol); - set_column_flag(tree, col, GNT_TREE_COLUMN_FIXED_SIZE, !res); -} - -void gnt_tree_set_column_is_binary(GntTree *tree, int col, gboolean bin) -{ - g_return_if_fail(col < tree->ncol); - set_column_flag(tree, col, GNT_TREE_COLUMN_BINARY_DATA, bin); -} - -void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right) -{ - g_return_if_fail(col < tree->ncol); - set_column_flag(tree, col, GNT_TREE_COLUMN_RIGHT_ALIGNED, right); -} - -void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]) -{ - int i; - for (i = 0; i < tree->ncol && cols[i]; i++) { - tree->columns[i].width_ratio = cols[i]; - } -} - -void gnt_tree_set_search_column(GntTree *tree, int col) -{ - g_return_if_fail(col < tree->ncol); - g_return_if_fail(!BINARY_DATA(tree, col)); - tree->priv->search_column = col; -} - -gboolean gnt_tree_is_searching(GntTree *tree) -{ - return (tree->priv->search != NULL); -} - -void gnt_tree_set_search_function(GntTree *tree, - gboolean (*func)(GntTree *tree, gpointer key, const char *search, const char *current)) -{ - tree->priv->search_func = func; -} - -gpointer gnt_tree_get_parent_key(GntTree *tree, gpointer key) -{ - GntTreeRow *row = g_hash_table_lookup(tree->hash, key); - return (row && row->parent) ? row->parent->key : NULL; -} - -gpointer gnt_tree_row_get_key(GntTree *tree, GntTreeRow *row) -{ - g_return_val_if_fail(row && row->tree == tree, NULL); - return row->key; -} - -GntTreeRow * gnt_tree_row_get_next(GntTree *tree, GntTreeRow *row) -{ - g_return_val_if_fail(row && row->tree == tree, NULL); - return row->next; -} - -GntTreeRow * gnt_tree_row_get_prev(GntTree *tree, GntTreeRow *row) -{ - g_return_val_if_fail(row && row->tree == tree, NULL); - return row->prev; -} - -GntTreeRow * gnt_tree_row_get_child(GntTree *tree, GntTreeRow *row) -{ - g_return_val_if_fail(row && row->tree == tree, NULL); - return row->child; -} - -GntTreeRow * gnt_tree_row_get_parent(GntTree *tree, GntTreeRow *row) -{ - g_return_val_if_fail(row && row->tree == tree, NULL); - return row->parent; -} -
--- a/finch/libgnt/gnttree.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,646 +0,0 @@ -/** - * @file gnttree.h Tree API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_TREE_H -#define GNT_TREE_H - -#include "gntwidget.h" -#include "gnt.h" -#include "gntcolors.h" -#include "gntkeys.h" -#include "gnttextview.h" - -#define GNT_TYPE_TREE (gnt_tree_get_gtype()) -#define GNT_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_TREE, GntTree)) -#define GNT_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_TREE, GntTreeClass)) -#define GNT_IS_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_TREE)) -#define GNT_IS_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_TREE)) -#define GNT_TREE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_TREE, GntTreeClass)) - -typedef struct _GntTree GntTree; -typedef struct _GntTreePriv GntTreePriv; -typedef struct _GntTreeClass GntTreeClass; - -typedef struct _GntTreeRow GntTreeRow; -typedef struct _GntTreeCol GntTreeCol; - -typedef enum _GntTreeColumnFlag { - GNT_TREE_COLUMN_INVISIBLE = 1 << 0, - GNT_TREE_COLUMN_FIXED_SIZE = 1 << 1, - GNT_TREE_COLUMN_BINARY_DATA = 1 << 2, - GNT_TREE_COLUMN_RIGHT_ALIGNED = 1 << 3, -} GntTreeColumnFlag; - -struct _GntTree -{ - GntWidget parent; - - GntTreeRow *current; /* current selection */ - - GntTreeRow *top; /* The topmost visible item */ - GntTreeRow *bottom; /* The bottommost visible item */ - - GntTreeRow *root; /* The root of all evil */ - - GList *list; /* List of GntTreeRow s */ - GHashTable *hash; /* We need this for quickly referencing the rows */ - guint (*hash_func)(gconstpointer); - gboolean (*hash_eq_func)(gconstpointer, gconstpointer); - GDestroyNotify key_destroy; - GDestroyNotify value_destroy; - - int ncol; /* No. of columns */ - struct _GntTreeColInfo - { - int width; - char *title; - int width_ratio; - GntTreeColumnFlag flags; - } *columns; /* Would a GList be better? */ - gboolean show_title; - gboolean show_separator; /* Whether to show column separators */ - - GntTreePriv *priv; -}; - -struct _GntTreeClass -{ - GntWidgetClass parent; - - void (*selection_changed)(GntTreeRow *old, GntTreeRow * current); - void (*toggled)(GntTree *tree, gpointer key); - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return The GType for GntTree - */ -GType gnt_tree_get_gtype(void); - -/** - * Create a tree with one column. - * - * @return The newly created tree - * - * @see gnt_tree_new_with_columns - */ -GntWidget * gnt_tree_new(void); - -/** - * Create a tree with a specified number of columns. - * - * @param columns Number of columns - * - * @return The newly created tree - * - * @see gnt_tree_new - */ -GntWidget * gnt_tree_new_with_columns(int columns); - -/** - * The number of rows the tree should display at a time. - * - * @param tree The tree - * @param rows The number of rows - */ -void gnt_tree_set_visible_rows(GntTree *tree, int rows); - -/** - * Get the number visible rows. - * - * @param tree The tree - * - * @return The number of visible rows - */ -int gnt_tree_get_visible_rows(GntTree *tree); - -/** - * Scroll the contents of the tree. - * - * @param tree The tree - * @param count If positive, the tree will be scrolled down by count rows, - * otherwise, it will be scrolled up by count rows. - */ -void gnt_tree_scroll(GntTree *tree, int count); - -/** - * Insert a row in the tree. - * - * @param tree The tree - * @param key The key for the row - * @param row The row to insert - * @param parent The key for the parent row - * @param bigbro The key for the row to insert the new row after. - * - * @return The inserted row - * - * @see gnt_tree_create_row - * @see gnt_tree_add_row_last - * @see gnt_tree_add_choice - */ -GntTreeRow * gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro); - -/** - * Insert a row at the end of the tree. - * - * @param tree The tree - * @param key The key for the row - * @param row The row to insert - * @param parent The key for the parent row - * - * @return The inserted row - * - * @see gnt_tree_create_row - * @see gnt_tree_add_row_after - * @see gnt_tree_add_choice - */ -GntTreeRow * gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent); - -/** - * Get the key for the selected row. - * - * @param tree The tree - * - * @return The key for the selected row - */ -gpointer gnt_tree_get_selection_data(GntTree *tree); - -/** - * Get the text displayed for the selected row. - * - * @param tree The tree - * - * @return The text, which needs to be freed by the caller - * @see gnt_tree_get_row_text_list - * @see gnt_tree_get_selection_text_list - */ -char * gnt_tree_get_selection_text(GntTree *tree); - -/** - * Get a list of text for a row. - * - * @param tree The tree - * @param key A key corresponding to the row in question. If key - * is @c NULL, the text list for the selected row will - * be returned. - * - * @return A list of texts of a row. The list and its data should be - * freed by the caller. The caller should make sure that if - * any column of the tree contains binary data, it's not freed. - * @see gnt_tree_get_selection_text_list - * @see gnt_tree_get_selection_text - */ -GList * gnt_tree_get_row_text_list(GntTree *tree, gpointer key); - -/** - * Get the key of a row. - * - * @param tree The tree - * @param row The GntTreeRow object - * - * @return The key of the row. - * @since 2.8.0 (gnt), 2.7.2 (pidgin) - */ -gpointer gnt_tree_row_get_key(GntTree *tree, GntTreeRow *row); - -/** - * Get the next row. - * - * @param tree The tree - * @param row The GntTreeRow object - * - * @return The next row. - * @since 2.8.0 (gnt), 2.7.2 (pidgin) - */ -GntTreeRow * gnt_tree_row_get_next(GntTree *tree, GntTreeRow *row); - -/** - * Get the previous row. - * - * @param tree The tree - * @param row The GntTreeRow object - * - * @return The previous row. - * @since 2.8.0 (gnt), 2.7.2 (pidgin) - */ -GntTreeRow * gnt_tree_row_get_prev(GntTree *tree, GntTreeRow *row); - -/** - * Get the child row. - * - * @param tree The tree - * @param row The GntTreeRow object - * - * @return The child row. - * @since 2.8.0 (gnt), 2.7.2 (pidgin) - */ -GntTreeRow * gnt_tree_row_get_child(GntTree *tree, GntTreeRow *row); - -/** - * Get the parent row. - * - * @param tree The tree - * @param row The GntTreeRow object - * - * @return The parent row. - * @since 2.8.0 (gnt), 2.7.2 (pidgin) - */ -GntTreeRow * gnt_tree_row_get_parent(GntTree *tree, GntTreeRow *row); - -/** - * Get a list of text of the current row. - * - * @param tree The tree - * - * @return A list of texts of the currently selected row. The list - * and its data should be freed by the caller. The caller - * should make sure that if any column of the tree contains - * binary data, it's not freed. - * @see gnt_tree_get_row_text_list - * @see gnt_tree_get_selection_text - */ -GList * gnt_tree_get_selection_text_list(GntTree *tree); - -/** - * Returns the list of rows in the tree. - * - * @param tree The tree - * - * @return The list of the rows. The list should not be modified by the caller. - */ -GList *gnt_tree_get_rows(GntTree *tree); - -/** - * Remove a row from the tree. - * - * @param tree The tree - * @param key The key for the row to remove - */ -void gnt_tree_remove(GntTree *tree, gpointer key); - -/** - * Remove all the item from the tree. - * - * @param tree The tree - */ -void gnt_tree_remove_all(GntTree *tree); - -/** - * Get the visible line number of the selected row. - * - * @param tree The tree - * - * @return The line number of the currently selected row - */ -int gnt_tree_get_selection_visible_line(GntTree *tree); - -/** - * Change the text of a column in a row. - * - * @param tree The tree - * @param key The key for the row - * @param colno The index of the column - * @param text The new text - */ -void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text); - -/** - * Add a checkable item in the tree. - * - * @param tree The tree - * @param key The key for the row - * @param row The row to add - * @param parent The parent of the row, or @c NULL - * @param bigbro The row to insert after, or @c NULL - * - * @return The row inserted. - * - * @see gnt_tree_create_row - * @see gnt_tree_create_row_from_list - * @see gnt_tree_add_row_last - * @see gnt_tree_add_row_after - */ -GntTreeRow * gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro); - -/** - * Set whether a checkable item is checked or not. - * - * @param tree The tree - * @param key The key for the row - * @param set @c TRUE if the item should be checked, @c FALSE if not - */ -void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set); - -/** - * Return whether a row is selected or not, where the row is a checkable item. - * - * @param tree The tree - * @param key The key for the row - * - * @return @c TRUE if the row is checked, @c FALSE otherwise. - */ -gboolean gnt_tree_get_choice(GntTree *tree, void *key); - -/** - * Set flags for the text in a row in the tree. - * - * @param tree The tree - * @param key The key for the row - * @param flags The flags to set - */ -void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags); - -/** - * Set color for the text in a row in the tree. - * - * @param tree The tree - * @param key The key for the row - * @param color The color - * @since 2.4.0 - */ -void gnt_tree_set_row_color(GntTree *tree, void *key, int color); - -/** - * Select a row. - * - * @param tree The tree - * @param key The key of the row to select - */ -void gnt_tree_set_selected(GntTree *tree , void *key); - -/** - * Create a row to insert in the tree. - * - * @param tree The tree - * @param ... A string for each column in the tree - * - * @return The row - * - * @see gnt_tree_create_row_from_list - * @see gnt_tree_add_row_after - * @see gnt_tree_add_row_last - * @see gnt_tree_add_choice - */ -GntTreeRow * gnt_tree_create_row(GntTree *tree, ...); - -/** - * Create a row from a list of text. - * - * @param tree The tree - * @param list The list containing the text for each column - * - * @return The row - * - * @see gnt_tree_create_row - * @see gnt_tree_add_row_after - * @see gnt_tree_add_row_last - * @see gnt_tree_add_choice - */ -GntTreeRow * gnt_tree_create_row_from_list(GntTree *tree, GList *list); - -/** - * Set the width of a column in the tree. - * - * @param tree The tree - * @param col The index of the column - * @param width The width for the column - * - * @see gnt_tree_set_column_width_ratio - * @see gnt_tree_set_column_resizable - */ -void gnt_tree_set_col_width(GntTree *tree, int col, int width); - -/** - * Set the title for a column. - * - * @param tree The tree - * @param index The index of the column - * @param title The title for the column - * - * @see gnt_tree_set_column_titles - * @see gnt_tree_set_show_title - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_column_title(GntTree *tree, int index, const char *title); - -/** - * Set the titles of the columns - * - * @param tree The tree - * @param ... One title for each column in the tree - * - * @see gnt_tree_set_column_title - * @see gnt_tree_set_show_title - */ -void gnt_tree_set_column_titles(GntTree *tree, ...); - -/** - * Set whether to display the title of the columns. - * - * @param tree The tree - * @param set If @c TRUE, the column titles are displayed - * - * @see gnt_tree_set_column_title - * @see gnt_tree_set_column_titles - */ -void gnt_tree_set_show_title(GntTree *tree, gboolean set); - -/** - * Set the compare function for sorting the data. - * - * @param tree The tree - * @param func The comparison function, which is used to compare - * the keys - * - * @see gnt_tree_sort_row - */ -void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func); - -/** - * Set whether a row, which has child rows, should be expanded. - * - * @param tree The tree - * @param key The key of the row - * @param expanded Whether to expand the child rows - */ -void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded); - -/** - * Set whether to show column separators. - * - * @param tree The tree - * @param set If @c TRUE, the column separators are displayed - */ -void gnt_tree_set_show_separator(GntTree *tree, gboolean set); - -/** - * Sort a row in the tree. - * - * @param tree The tree - * @param row The row to sort - * - * @see gnt_tree_set_compare_func - */ -void gnt_tree_sort_row(GntTree *tree, void *row); - -/** - * Automatically adjust the width of the columns in the tree. - * - * @param tree The tree - */ -void gnt_tree_adjust_columns(GntTree *tree); - -/** - * Set the hash functions to use to hash, compare and free the keys. - * - * @param tree The tree - * @param hash The hashing function - * @param eq The function to compare keys - * @param kd The function to use to free the keys when a row is removed - * from the tree - */ -void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd); - -/** - * Set whether a column is visible or not. - * This can be useful when, for example, we want to store some data - * which we don't want/need to display. - * - * @param tree The tree - * @param col The index of the column - * @param vis If @c FALSE, the column will not be displayed - */ -void gnt_tree_set_column_visible(GntTree *tree, int col, gboolean vis); - -/** - * Set whether a column can be resized to keep the same ratio when the - * tree is resized. - * - * @param tree The tree - * @param col The index of the column - * @param res If @c FALSE, the column will not be resized when the - * tree is resized - * - * @see gnt_tree_set_col_width - * @see gnt_tree_set_column_width_ratio - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res); - -/** - * Set whether data in a column should be considered as binary data, and - * not as strings. A column containing binary data will be display empty text. - * - * @param tree The tree - * @param col The index of the column - * @param bin @c TRUE if the data for the column is binary - */ -void gnt_tree_set_column_is_binary(GntTree *tree, int col, gboolean bin); - -/** - * Set whether text in a column should be right-aligned. - * - * @param tree The tree - * @param col The index of the column - * @param right @c TRUE if the text in the column should be right aligned - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right); - -/** - * Set column widths to use when calculating column widths after a tree - * is resized. - * - * @param tree The tree - * @param cols Array of widths. The width must have the same number - * of entries as the number of columns in the tree, or - * end with a negative value for a column-width. - * - * @see gnt_tree_set_col_width - * @see gnt_tree_set_column_resizable - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]); - -/** - * Set the column to use for typeahead searching. - * - * @param tree The tree - * @param col The index of the column - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_search_column(GntTree *tree, int col); - -/** - * Check whether the user is currently in the middle of a search. - * - * @param tree The tree - * @return @c TRUE if the user is searching, @c FALSE otherwise. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -gboolean gnt_tree_is_searching(GntTree *tree); - -/** - * Set a custom search function. - * - * @param tree The tree - * @param func The custom search function. The search function is - * sent the tree itself, the key of a row, the search - * string and the content of row in the search column. - * If the function returns @c TRUE, the row is dislayed, - * otherwise it's not. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_tree_set_search_function(GntTree *tree, - gboolean (*func)(GntTree *tree, gpointer key, const char *search, const char *current)); - -/** - * Get the parent key for a row. - * - * @param tree The tree - * @param key The key for the row. - * - * @return The key of the parent row. - * @since 2.4.0 - */ -gpointer gnt_tree_get_parent_key(GntTree *tree, gpointer key); - -G_END_DECLS - -#endif /* GNT_TREE_H */
--- a/finch/libgnt/gntutils.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,503 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "config.h" - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "Utils" - -#include "gntbutton.h" -#include "gntcheckbox.h" -#include "gntcombobox.h" -#include "gntentry.h" -#include "gntlabel.h" -#include "gntline.h" -#include "gnttextview.h" -#include "gnttree.h" -#include "gntutils.h" -#include "gntwindow.h" - -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> - -#ifndef NO_LIBXML -#include <libxml/parser.h> -#include <libxml/tree.h> -#endif - -void gnt_util_get_text_bound(const char *text, int *width, int *height) -{ - const char *s = text, *last; - int count = 1, max = 0; - int len; - - /* XXX: ew ... everyone look away */ - last = s; - if (s) - { - while (*s) - { - if (*s == '\n' || *s == '\r') - { - count++; - len = gnt_util_onscreen_width(last, s); - if (max < len) - max = len; - last = s + 1; - } - s = g_utf8_next_char(s); - } - - len = gnt_util_onscreen_width(last, s); - if (max < len) - max = len; - } - - if (height) - *height = count; - if (width) - *width = max + (count > 1); -} - -int gnt_util_onscreen_width(const char *start, const char *end) -{ - int width = 0; - - if (end == NULL) - end = start + strlen(start); - - while (start < end) { - width += g_unichar_iswide(g_utf8_get_char(start)) ? 2 : 1; - start = g_utf8_next_char(start); - } - return width; -} - -const char *gnt_util_onscreen_width_to_pointer(const char *string, int len, int *w) -{ - int size; - int width = 0; - const char *str = string; - - if (len <= 0) { - len = gnt_util_onscreen_width(string, NULL); - } - - while (width < len && *str) { - size = g_unichar_iswide(g_utf8_get_char(str)) ? 2 : 1; - if (width + size > len) - break; - str = g_utf8_next_char(str); - width += size; - } - if (w) - *w = width; - return str; -} - -char *gnt_util_onscreen_fit_string(const char *string, int maxw) -{ - const char *start, *end; - GString *str; - - if (maxw <= 0) - maxw = getmaxx(stdscr) - 4; - - start = string; - str = g_string_new(NULL); - - while (*start) { - if ((end = strchr(start, '\n')) != NULL || - (end = strchr(start, '\r')) != NULL) { - if (gnt_util_onscreen_width(start, end) > maxw) - end = NULL; - } - if (end == NULL) - end = gnt_util_onscreen_width_to_pointer(start, maxw, NULL); - str = g_string_append_len(str, start, end - start); - if (*end) { - str = g_string_append_c(str, '\n'); - if (*end == '\n' || *end == '\r') - end++; - } - start = end; - } - return g_string_free(str, FALSE); -} - -struct duplicate_fns -{ - GDupFunc key_dup; - GDupFunc value_dup; - GHashTable *table; -}; - -static void -duplicate_values(gpointer key, gpointer value, gpointer data) -{ - struct duplicate_fns *fns = data; - g_hash_table_insert(fns->table, fns->key_dup ? fns->key_dup(key) : key, - fns->value_dup ? fns->value_dup(value) : value); -} - -GHashTable *g_hash_table_duplicate(GHashTable *src, GHashFunc hash, - GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d, - GDupFunc key_dup, GDupFunc value_dup) -{ - GHashTable *dest = g_hash_table_new_full(hash, equal, key_d, value_d); - struct duplicate_fns fns = {key_dup, value_dup, dest}; - g_hash_table_foreach(src, duplicate_values, &fns); - return dest; -} - -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; -} - -typedef struct { - GHashTable *hash; - GntTree *tree; -} BindingView; - -static void -add_binding(gpointer key, gpointer value, gpointer data) -{ - BindingView *bv = data; - GntBindableActionParam *act = value; - const char *name = g_hash_table_lookup(bv->hash, act->action); - if (name && *name) { - const char *k = gnt_key_lookup(key); - if (!k) - k = key; - gnt_tree_add_row_after(bv->tree, (gpointer)k, - gnt_tree_create_row(bv->tree, k, name), NULL, NULL); - } -} - -static void -add_action(gpointer key, gpointer value, gpointer data) -{ - BindingView *bv = data; - g_hash_table_insert(bv->hash, value, key); -} - -GntWidget *gnt_widget_bindings_view(GntWidget *widget) -{ - GntBindable *bind = GNT_BINDABLE(widget); - GntWidget *tree = gnt_tree_new_with_columns(2); - GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind)); - GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal); - BindingView bv = {hash, GNT_TREE(tree)}; - - gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate); - g_hash_table_foreach(klass->actions, add_action, &bv); - g_hash_table_foreach(klass->bindings, add_binding, &bv); - if (GNT_TREE(tree)->list == NULL) { - gnt_widget_destroy(tree); - tree = NULL; - } else - gnt_tree_adjust_columns(bv.tree); - g_hash_table_destroy(hash); - - return tree; -} - -#ifndef NO_LIBXML -static GntWidget * -gnt_widget_from_xmlnode(xmlNode *node, GntWidget **data[], int max) -{ - GntWidget *widget = NULL; - char *name; - char *id, *prop, *content; - int val; - - if (node == NULL || node->name == NULL || node->type != XML_ELEMENT_NODE) - return NULL; - - name = (char*)node->name; - content = (char*)xmlNodeGetContent(node); - if (strcmp(name + 1, "window") == 0 || strcmp(name + 1, "box") == 0) { - xmlNode *ch; - char *title; - gboolean vert = (*name == 'v'); - - if (name[1] == 'w') - widget = gnt_window_box_new(FALSE, vert); - else - widget = gnt_box_new(FALSE, vert); - - title = (char*)xmlGetProp(node, (xmlChar*)"title"); - if (title) { - gnt_box_set_title(GNT_BOX(widget), title); - xmlFree(title); - } - - prop = (char*)xmlGetProp(node, (xmlChar*)"fill"); - if (prop) { - if (sscanf(prop, "%d", &val) == 1) - gnt_box_set_fill(GNT_BOX(widget), !!val); - xmlFree(prop); - } - - prop = (char*)xmlGetProp(node, (xmlChar*)"align"); - if (prop) { - if (sscanf(prop, "%d", &val) == 1) - gnt_box_set_alignment(GNT_BOX(widget), val); - xmlFree(prop); - } - - prop = (char*)xmlGetProp(node, (xmlChar*)"pad"); - if (prop) { - if (sscanf(prop, "%d", &val) == 1) - gnt_box_set_pad(GNT_BOX(widget), val); - xmlFree(prop); - } - - for (ch = node->children; ch; ch=ch->next) - gnt_box_add_widget(GNT_BOX(widget), gnt_widget_from_xmlnode(ch, data, max)); - } else if (strcmp(name, "button") == 0) { - widget = gnt_button_new(content); - } else if (strcmp(name, "label") == 0) { - widget = gnt_label_new(content); - } else if (strcmp(name, "entry") == 0) { - widget = gnt_entry_new(content); - } else if (strcmp(name, "combobox") == 0) { - widget = gnt_combo_box_new(); - } else if (strcmp(name, "checkbox") == 0) { - widget = gnt_check_box_new(content); - } else if (strcmp(name, "tree") == 0) { - widget = gnt_tree_new(); - } else if (strcmp(name, "textview") == 0) { - widget = gnt_text_view_new(); - } else if (strcmp(name + 1, "line") == 0) { - widget = gnt_line_new(*name == 'v'); - } - - xmlFree(content); - - if (widget == NULL) { - gnt_warning("Invalid widget name %s", name); - return NULL; - } - - id = (char*)xmlGetProp(node, (xmlChar*)"id"); - if (id) { - int i; - if (sscanf(id, "%d", &i) == 1 && i >= 0 && i < max) { - *data[i] = widget; - xmlFree(id); - } - } - - prop = (char*)xmlGetProp(node, (xmlChar*)"border"); - if (prop) { - int val; - if (sscanf(prop, "%d", &val) == 1) { - if (val) - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); - else - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); - } - xmlFree(prop); - } - - prop = (char*)xmlGetProp(node, (xmlChar*)"shadow"); - if (prop) { - int val; - if (sscanf(prop, "%d", &val) == 1) { - if (val) - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); - else - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); - } - xmlFree(prop); - } - - return widget; -} -#endif - -void gnt_util_parse_widgets(const char *string, int num, ...) -{ -#ifndef NO_LIBXML - xmlParserCtxtPtr ctxt; - xmlDocPtr doc; - xmlNodePtr node; - va_list list; - GntWidget ***data; - int id; - - ctxt = xmlNewParserCtxt(); - doc = xmlCtxtReadDoc(ctxt, (xmlChar*)string, NULL, NULL, XML_PARSE_NOBLANKS); - - data = g_new0(GntWidget **, num); - - va_start(list, num); - for (id = 0; id < num; id++) - data[id] = va_arg(list, gpointer); - - node = xmlDocGetRootElement(doc); - gnt_widget_from_xmlnode(node, data, num); - - xmlFreeDoc(doc); - xmlFreeParserCtxt(ctxt); - va_end(list); - g_free(data); -#endif -} - -#ifndef NO_LIBXML -static void -util_parse_html_to_tv(xmlNode *node, GntTextView *tv, GntTextFormatFlags flag) -{ - const char *name; - char *content; - xmlNode *ch; - char *url = NULL; - gboolean insert_nl_s = FALSE, insert_nl_e = FALSE; - - if (node == NULL || node->name == NULL || node->type != XML_ELEMENT_NODE) - return; - - name = (char*)node->name; - if (g_ascii_strcasecmp(name, "b") == 0 || - g_ascii_strcasecmp(name, "strong") == 0 || - g_ascii_strcasecmp(name, "i") == 0 || - g_ascii_strcasecmp(name, "blockquote") == 0) { - flag |= GNT_TEXT_FLAG_BOLD; - } else if (g_ascii_strcasecmp(name, "u") == 0) { - flag |= GNT_TEXT_FLAG_UNDERLINE; - } else if (g_ascii_strcasecmp(name, "br") == 0) { - insert_nl_e = TRUE; - } else if (g_ascii_strcasecmp(name, "a") == 0) { - flag |= GNT_TEXT_FLAG_UNDERLINE; - url = (char *)xmlGetProp(node, (xmlChar*)"href"); - } else if (g_ascii_strcasecmp(name, "h1") == 0 || - g_ascii_strcasecmp(name, "h2") == 0 || - g_ascii_strcasecmp(name, "h3") == 0 || - g_ascii_strcasecmp(name, "h4") == 0 || - g_ascii_strcasecmp(name, "h5") == 0 || - g_ascii_strcasecmp(name, "h6") == 0) { - insert_nl_s = TRUE; - insert_nl_e = TRUE; - } else if (g_ascii_strcasecmp(name, "title") == 0) { - insert_nl_s = TRUE; - insert_nl_e = TRUE; - flag |= GNT_TEXT_FLAG_BOLD | GNT_TEXT_FLAG_UNDERLINE; - } else { - /* XXX: Process other possible tags */ - } - - if (insert_nl_s) - gnt_text_view_append_text_with_flags(tv, "\n", flag); - - for (ch = node->children; ch; ch = ch->next) { - if (ch->type == XML_ELEMENT_NODE) { - util_parse_html_to_tv(ch, tv, flag); - } else if (ch->type == XML_TEXT_NODE) { - content = (char*)xmlNodeGetContent(ch); - gnt_text_view_append_text_with_flags(tv, content, flag); - xmlFree(content); - } - } - - if (url) { - char *href = g_strdup_printf(" (%s)", url); - gnt_text_view_append_text_with_flags(tv, href, flag); - g_free(href); - xmlFree(url); - } - - if (insert_nl_e) - gnt_text_view_append_text_with_flags(tv, "\n", flag); -} -#endif - -gboolean gnt_util_parse_xhtml_to_textview(const char *string, GntTextView *tv) -{ -#ifdef NO_LIBXML - return FALSE; -#else - xmlParserCtxtPtr ctxt; - xmlDocPtr doc; - xmlNodePtr node; - GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL; - gboolean ret = FALSE; - - ctxt = xmlNewParserCtxt(); - doc = xmlCtxtReadDoc(ctxt, (xmlChar*)string, NULL, NULL, XML_PARSE_NOBLANKS | XML_PARSE_RECOVER); - if (doc) { - node = xmlDocGetRootElement(doc); - util_parse_html_to_tv(node, tv, flag); - xmlFreeDoc(doc); - ret = TRUE; - } - xmlFreeParserCtxt(ctxt); - return ret; -#endif -} - -/* Setup trigger widget */ -typedef struct { - char *text; - GntWidget *button; -} TriggerButton; - -static void -free_trigger_button(TriggerButton *b) -{ - g_free(b->text); - g_free(b); -} - -static gboolean -key_pressed(GntWidget *widget, const char *text, TriggerButton *trig) -{ - if (text && trig->text && - strcmp(text, trig->text) == 0) { - gnt_widget_activate(trig->button); - return TRUE; - } - return FALSE; -} - -void gnt_util_set_trigger_widget(GntWidget *wid, const char *text, GntWidget *button) -{ - TriggerButton *tb = g_new0(TriggerButton, 1); - tb->text = g_strdup(text); - tb->button = button; - g_signal_connect(G_OBJECT(wid), "key_pressed", G_CALLBACK(key_pressed), tb); - g_signal_connect_swapped(G_OBJECT(button), "destroy", G_CALLBACK(free_trigger_button), tb); -}
--- a/finch/libgnt/gntutils.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/** - * @file gntutils.h Some utility functions - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include <glib.h> - -#include "gnt.h" -#include "gnttextview.h" -#include "gntwidget.h" - -typedef gpointer (*GDupFunc)(gconstpointer data); - -/** - * Compute the width and height required to view the text on the screen. - * - * @param text The text to be displayed. - * @param width The width required is set here, if not @c NULL. - * @param height The height required is set here, if not @c NULL. - */ -void gnt_util_get_text_bound(const char *text, int *width, int *height); - -/* excluding *end */ -/** - * Get the onscreen width of a string, or a substring. - * - * @param start The beginning of the string. - * @param end The end of the string. The width returned is the width - * upto (but not including) end. If end is NULL, then start - * is considered as a @c NULL-terminated string. - * - * @return The on-screen width of the string. - */ -int gnt_util_onscreen_width(const char *start, const char *end); - -/** - * Computes and returns the string after a specific number of onscreen characters. - * - * @param str The string. - * @param len The length to consider. If non-positive, the entire screenlength is used. - * @param w The actual width of the string upto the returned offset, if not @c NULL. - * - * @return The string after len offset. - */ -const char *gnt_util_onscreen_width_to_pointer(const char *str, int len, int *w); - -/** - * Inserts newlines in 'string' where necessary so that its onscreen width is - * no more than 'maxw'. - * - * @param string The string. - * @param maxw The width that the string should fit into. If maxw is <= 0, - * then the available maximum width is used. - * - * @return A newly allocated string that needs to be freed by the caller. - */ -char * gnt_util_onscreen_fit_string(const char *string, int maxw); - -/** - * Duplicate the contents of a hastable. - * - * @param src The source hashtable. - * @param hash The hash-function to use. - * @param equal The hash-equal function to use. - * @param key_d The key-destroy function to use. - * @param value_d The value-destroy function to use. - * @param key_dup The function to use to duplicate the key. - * @param value_dup The function to use to duplicate the value. - * - * @return The new hashtable. - */ -GHashTable * g_hash_table_duplicate(GHashTable *src, GHashFunc hash, GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d, GDupFunc key_dup, GDupFunc value_dup); - -/** - * To be used with g_signal_new. Look in the key_pressed signal-definition in - * gntwidget.c for usage. - * - * @param ihint NA - * @param return_accu NA - * @param handler_return NA - * @param dummy NA - * - * @return NA - */ -gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer dummy); - -/** - * Get a helpful display about the bindings of a widget. - * - * @param widget The widget to get bindings for. - * - * @return Returns a GntTree populated with "key" -> "binding" for the widget. - */ -GntWidget * gnt_widget_bindings_view(GntWidget *widget); - -/** - * Parse widgets from an XML description. For example, - * - * @code - * GntWidget *win, *button; - * gnt_util_parse_widgets("\ - * <vwindow id='0' fill='0' align='2'> \ - * <label>This is a test</label> \ - * <button id='1'>OK</button> \ - * </vwindow>", - * 2, &win, &button); - * @endcode - * - * @param string The XML string. - * @param num The number of widgets to return, followed by 'num' GntWidget ** - */ -void gnt_util_parse_widgets(const char *string, int num, ...); - -/** - * Parse an XHTML string and add it in a GntTextView with - * appropriate text flags. - * - * @param string The XHTML string - * @param tv The GntTextView - * @return @c TRUE if the string was added to the textview properly, @c FALSE otherwise. - * - * @since 2.2.0 - */ -gboolean gnt_util_parse_xhtml_to_textview(const char *string, GntTextView *tv); - -/** - * Make some keypress activate a button when some key is pressed with 'wid' in focus. - * - * @param widget The widget - * @param key The key to trigger the button - * @param button The button to trigger - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_util_set_trigger_widget(GntWidget *widget, const char *key, GntWidget *button); -
--- a/finch/libgnt/gntwidget.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,654 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -/* Stuff brutally ripped from Gflib */ - -#include "gntinternal.h" -#include "gntwidget.h" -#include "gntstyle.h" -#include "gntmarshal.h" -#include "gntutils.h" -#include "gnt.h" - -enum -{ - SIG_DESTROY, - SIG_DRAW, - SIG_HIDE, - SIG_GIVE_FOCUS, - SIG_LOST_FOCUS, - SIG_KEY_PRESSED, - SIG_MAP, - SIG_ACTIVATE, - SIG_EXPOSE, - SIG_SIZE_REQUEST, - SIG_CONFIRM_SIZE, - SIG_SIZE_CHANGED, - SIG_POSITION, - SIG_CLICKED, - SIG_CONTEXT_MENU, - SIGS -}; - -static GObjectClass *parent_class = NULL; -static guint signals[SIGS] = { 0 }; - -static void init_widget(GntWidget *widget); - -static void -gnt_widget_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - widget->priv.name = NULL; - GNTDEBUG; -} - -static void -gnt_widget_map(GntWidget *widget) -{ - /* Get some default size for the widget */ - GNTDEBUG; - g_signal_emit(widget, signals[SIG_MAP], 0); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); -} - -static void -gnt_widget_dispose(GObject *obj) -{ - GntWidget *self = GNT_WIDGET(obj); - g_signal_emit(self, signals[SIG_DESTROY], 0); - parent_class->dispose(obj); - GNTDEBUG; -} - -static void -gnt_widget_focus_change(GntWidget *widget) -{ - if (GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED) - gnt_widget_draw(widget); -} - -static gboolean -gnt_widget_dummy_confirm_size(GntWidget *widget, int width, int height) -{ - gboolean shadow; - if (width < widget->priv.minw || height < widget->priv.minh) - return FALSE; - shadow = gnt_widget_has_shadow(widget); - if (widget->priv.width + shadow != width && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_X)) - return FALSE; - if (widget->priv.height + shadow != height && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_GROW_Y)) - return FALSE; - return TRUE; -} - -static gboolean -context_menu(GntBindable *bind, GList *null) -{ - gboolean ret = FALSE; - g_signal_emit(bind, signals[SIG_CONTEXT_MENU], 0, &ret); - return ret; -} - -static void -gnt_widget_class_init(GntWidgetClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - parent_class = g_type_class_peek_parent(klass); - - obj_class->dispose = gnt_widget_dispose; - - klass->destroy = gnt_widget_destroy; - klass->show = gnt_widget_show; - klass->draw = gnt_widget_draw; - klass->expose = gnt_widget_expose; - klass->map = gnt_widget_map; - klass->lost_focus = gnt_widget_focus_change; - klass->gained_focus = gnt_widget_focus_change; - klass->confirm_size = gnt_widget_dummy_confirm_size; - - klass->key_pressed = NULL; - klass->activate = NULL; - klass->clicked = NULL; - - signals[SIG_DESTROY] = - g_signal_new("destroy", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, destroy), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_GIVE_FOCUS] = - g_signal_new("gained-focus", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, gained_focus), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_LOST_FOCUS] = - g_signal_new("lost-focus", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, lost_focus), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_ACTIVATE] = - g_signal_new("activate", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, activate), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_MAP] = - g_signal_new("map", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, map), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_DRAW] = - g_signal_new("draw", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, draw), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_HIDE] = - g_signal_new("hide", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, hide), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_EXPOSE] = - g_signal_new("expose", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, expose), - NULL, NULL, - gnt_closure_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); - signals[SIG_POSITION] = - g_signal_new("position-set", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, set_position), - NULL, NULL, - gnt_closure_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - signals[SIG_SIZE_REQUEST] = - g_signal_new("size_request", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, size_request), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIG_SIZE_CHANGED] = - g_signal_new("size_changed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, size_changed), - NULL, NULL, - gnt_closure_marshal_VOID__INT_INT, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - signals[SIG_CONFIRM_SIZE] = - g_signal_new("confirm_size", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, confirm_size), - NULL, NULL, - gnt_closure_marshal_BOOLEAN__INT_INT, - G_TYPE_BOOLEAN, 2, G_TYPE_INT, G_TYPE_INT); - signals[SIG_KEY_PRESSED] = - g_signal_new("key_pressed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, key_pressed), - gnt_boolean_handled_accumulator, NULL, - gnt_closure_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, G_TYPE_STRING); - - signals[SIG_CLICKED] = - g_signal_new("clicked", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWidgetClass, clicked), - gnt_boolean_handled_accumulator, NULL, - gnt_closure_marshal_BOOLEAN__INT_INT_INT, - G_TYPE_BOOLEAN, 3, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); - - signals[SIG_CONTEXT_MENU] = - g_signal_new("context-menu", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - gnt_boolean_handled_accumulator, NULL, - gnt_closure_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /* This is relevant for all widgets */ - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "context-menu", context_menu, - GNT_KEY_POPUP, NULL); - gnt_bindable_register_binding(GNT_BINDABLE_CLASS(klass), "context-menu", GNT_KEY_F11, NULL); - gnt_bindable_register_binding(GNT_BINDABLE_CLASS(klass), "context-menu", GNT_KEY_CTRL_X, NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); - GNTDEBUG; -} - -/****************************************************************************** - * GntWidget API - *****************************************************************************/ -GType -gnt_widget_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) { - static const GTypeInfo info = { - sizeof(GntWidgetClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_widget_class_init, - NULL, - NULL, /* class_data */ - sizeof(GntWidget), - 0, /* n_preallocs */ - gnt_widget_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_BINDABLE, - "GntWidget", - &info, G_TYPE_FLAG_ABSTRACT); - } - - return type; -} - -void gnt_widget_set_take_focus(GntWidget *widget, gboolean can) -{ - if (can) - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); - else - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); -} - -/** - * gnt_widget_destroy: - * @obj: The #GntWidget instance. - * - * Emits the "destroy" signal notifying all reference holders that they - * should release @obj. - */ -void -gnt_widget_destroy(GntWidget *obj) -{ - g_return_if_fail(GNT_IS_WIDGET(obj)); - - if(!(GNT_WIDGET_FLAGS(obj) & GNT_WIDGET_DESTROYING)) { - GNT_WIDGET_SET_FLAGS(obj, GNT_WIDGET_DESTROYING); - gnt_widget_hide(obj); - delwin(obj->window); - g_object_run_dispose(G_OBJECT(obj)); - } - GNTDEBUG; -} - -void -gnt_widget_show(GntWidget *widget) -{ - g_return_if_fail(widget != NULL); - - gnt_widget_draw(widget); - gnt_screen_occupy(widget); -} - -void -gnt_widget_draw(GntWidget *widget) -{ - /* Draw the widget */ - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_DRAWING)) - return; - - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_DRAWING); - if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_MAPPED)) { - gnt_widget_map(widget); - } - - if (widget->window == NULL) - { -#if 0 - int x, y, maxx, maxy, w, h; - int oldw, oldh; - gboolean shadow = TRUE; - - if (!gnt_widget_has_shadow(widget)) - shadow = FALSE; - - x = widget->priv.x; - y = widget->priv.y; - w = oldw = widget->priv.width + shadow; - h = oldh = widget->priv.height + shadow; - - getmaxyx(stdscr, maxy, maxx); - maxy -= 1; /* room for the taskbar */ - - x = MAX(0, x); - y = MAX(0, y); - if (x + w >= maxx) - x = MAX(0, maxx - w); - if (y + h >= maxy) - y = MAX(0, maxy - h); - - w = MIN(w, maxx); - h = MIN(h, maxy); - - widget->priv.x = x; - widget->priv.y = y; - if (w != oldw || h != oldh) { - widget->priv.width = w - shadow; - widget->priv.height = h - shadow; - g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh); - } -#else - widget->window = newpad(widget->priv.height + 20, widget->priv.width + 20); /* XXX: */ -#endif - init_widget(widget); - } - - g_signal_emit(widget, signals[SIG_DRAW], 0); - gnt_widget_queue_update(widget); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING); -} - -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_IS_FLAG_SET(widget, GNT_WIDGET_DISABLE_ACTIONS) && - gnt_bindable_perform_action_key(GNT_BINDABLE(widget), keys)) - return TRUE; - - keys = gnt_bindable_remap_keys(GNT_BINDABLE(widget), keys); - g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); - return ret; -} - -gboolean -gnt_widget_clicked(GntWidget *widget, GntMouseEvent event, int x, int y) -{ - gboolean ret; - g_signal_emit(widget, signals[SIG_CLICKED], 0, event, x, y, &ret); - if (!ret && event == GNT_RIGHT_MOUSE_DOWN) - ret = gnt_bindable_perform_action_named(GNT_BINDABLE(widget), "context-menu", NULL); - return ret; -} - -void -gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height) -{ - g_signal_emit(widget, signals[SIG_EXPOSE], 0, x, y, width, height); -} - -void -gnt_widget_hide(GntWidget *widget) -{ - g_signal_emit(widget, signals[SIG_HIDE], 0); - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_NORMAL)); -#if 0 - /* XXX: I have no clue why, but this seemed to be necessary. */ - if (gnt_widget_has_shadow(widget)) - mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height); -#endif - gnt_screen_release(widget); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_MAPPED); -} - -void -gnt_widget_set_position(GntWidget *wid, int x, int y) -{ - g_signal_emit(wid, signals[SIG_POSITION], 0, x, y); - /* XXX: Need to install properties for these and g_object_notify */ - wid->priv.x = x; - wid->priv.y = y; -} - -void -gnt_widget_get_position(GntWidget *wid, int *x, int *y) -{ - if (x) - *x = wid->priv.x; - if (y) - *y = wid->priv.y; -} - -void -gnt_widget_size_request(GntWidget *widget) -{ - g_signal_emit(widget, signals[SIG_SIZE_REQUEST], 0); -} - -void -gnt_widget_get_size(GntWidget *wid, int *width, int *height) -{ - gboolean shadow = TRUE; - if (!gnt_widget_has_shadow(wid)) - shadow = FALSE; - - if (width) - *width = wid->priv.width + shadow; - if (height) - *height = wid->priv.height + shadow; -} - -static void -init_widget(GntWidget *widget) -{ - gboolean shadow = TRUE; - - if (!gnt_widget_has_shadow(widget)) - shadow = FALSE; - - wbkgd(widget->window, gnt_color_pair(GNT_COLOR_NORMAL)); - werase(widget->window); - - if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) - { - /* - This is ugly. */ - /* - What's your point? */ - mvwvline(widget->window, 0, 0, ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL), widget->priv.height); - mvwvline(widget->window, 0, widget->priv.width - 1, - ACS_VLINE | gnt_color_pair(GNT_COLOR_NORMAL), widget->priv.height); - mvwhline(widget->window, widget->priv.height - 1, 0, - ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), widget->priv.width); - mvwhline(widget->window, 0, 0, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), widget->priv.width); - mvwaddch(widget->window, 0, 0, ACS_ULCORNER | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddch(widget->window, 0, widget->priv.width - 1, - ACS_URCORNER | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddch(widget->window, widget->priv.height - 1, 0, - ACS_LLCORNER | gnt_color_pair(GNT_COLOR_NORMAL)); - mvwaddch(widget->window, widget->priv.height - 1, widget->priv.width - 1, - ACS_LRCORNER | gnt_color_pair(GNT_COLOR_NORMAL)); - } - - if (shadow) - { - wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_SHADOW)); - mvwvline(widget->window, 1, widget->priv.width, ' ', widget->priv.height); - mvwhline(widget->window, widget->priv.height, 1, ' ', widget->priv.width); - } -} - -gboolean -gnt_widget_set_size(GntWidget *widget, int width, int height) -{ - gboolean ret = TRUE; - - if (gnt_widget_has_shadow(widget)) - { - width--; - height--; - } - if (width <= 0) - width = widget->priv.width; - if (height <= 0) - height = widget->priv.height; - - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - { - ret = gnt_widget_confirm_size(widget, width, height); - } - - if (ret) - { - gboolean shadow = TRUE; - int oldw, oldh; - - if (!gnt_widget_has_shadow(widget)) - shadow = FALSE; - - oldw = widget->priv.width; - oldh = widget->priv.height; - - widget->priv.width = width; - widget->priv.height = height; - if (width + shadow >= getmaxx(widget->window) || height + shadow >= getmaxy(widget->window)) { - delwin(widget->window); - widget->window = newpad(height + 20, width + 20); - } - - g_signal_emit(widget, signals[SIG_SIZE_CHANGED], 0, oldw, oldh); - - if (widget->window) - { - init_widget(widget); - } - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - init_widget(widget); - else - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_MAPPED); - } - - return ret; -} - -gboolean -gnt_widget_set_focus(GntWidget *widget, gboolean set) -{ - if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_CAN_TAKE_FOCUS)) - return FALSE; - - if (set && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) - { - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); - g_signal_emit(widget, signals[SIG_GIVE_FOCUS], 0); - } - else if (!set && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_HAS_FOCUS)) - { - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_HAS_FOCUS); - g_signal_emit(widget, signals[SIG_LOST_FOCUS], 0); - } - else - return FALSE; - - return TRUE; -} - -void gnt_widget_set_name(GntWidget *widget, const char *name) -{ - g_free(widget->priv.name); - widget->priv.name = g_strdup(name); -} - -const char *gnt_widget_get_name(GntWidget *widget) -{ - return widget->priv.name; -} - -void gnt_widget_activate(GntWidget *widget) -{ - g_signal_emit(widget, signals[SIG_ACTIVATE], 0); -} - -static gboolean -update_queue_callback(gpointer data) -{ - GntWidget *widget = GNT_WIDGET(data); - - if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) - return FALSE; - if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED)) - gnt_screen_update(widget); - g_object_set_data(G_OBJECT(widget), "gnt:queue_update", NULL); - return FALSE; -} - -void gnt_widget_queue_update(GntWidget *widget) -{ - if (widget->window == NULL) - return; - while (widget->parent) - widget = widget->parent; - - if (!g_object_get_data(G_OBJECT(widget), "gnt:queue_update")) - { - int id = g_timeout_add(0, update_queue_callback, widget); - g_object_set_data_full(G_OBJECT(widget), "gnt:queue_update", GINT_TO_POINTER(id), - (GDestroyNotify)g_source_remove); - } -} - -gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height) -{ - gboolean ret = FALSE; - g_signal_emit(widget, signals[SIG_CONFIRM_SIZE], 0, width, height, &ret); - return ret; -} - -void gnt_widget_set_visible(GntWidget *widget, gboolean set) -{ - if (set) - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_INVISIBLE); - else - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_INVISIBLE); -} - -gboolean gnt_widget_has_shadow(GntWidget *widget) -{ - return (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW) && - gnt_style_get_bool(GNT_STYLE_SHADOW, FALSE)); -} -
--- a/finch/libgnt/gntwidget.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,318 +0,0 @@ -/** - * @file gntwidget.h Widget API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_WIDGET_H -#define GNT_WIDGET_H - -#include <stdio.h> -#include <glib.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_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) -#define GNT_WIDGET_SET_FLAGS(obj, flags) (GNT_WIDGET_FLAGS(obj) |= flags) -#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)) - -typedef struct _GntWidget GntWidget; -typedef struct _GntWidgetPriv GntWidgetPriv; -typedef struct _GntWidgetClass GntWidgetClass; - -typedef enum _GntWidgetFlags -{ - GNT_WIDGET_DESTROYING = 1 << 0, - GNT_WIDGET_CAN_TAKE_FOCUS = 1 << 1, - GNT_WIDGET_MAPPED = 1 << 2, - /* XXX: Need to set the following two as properties, and setup a callback whenever these - * get chnaged. */ - GNT_WIDGET_NO_BORDER = 1 << 3, - GNT_WIDGET_NO_SHADOW = 1 << 4, - GNT_WIDGET_HAS_FOCUS = 1 << 5, - GNT_WIDGET_DRAWING = 1 << 6, - GNT_WIDGET_URGENT = 1 << 7, - GNT_WIDGET_GROW_X = 1 << 8, - GNT_WIDGET_GROW_Y = 1 << 9, - GNT_WIDGET_INVISIBLE = 1 << 10, - GNT_WIDGET_TRANSIENT = 1 << 11, - GNT_WIDGET_DISABLE_ACTIONS = 1 << 12, -} GntWidgetFlags; - -/* XXX: This will probably move elsewhere */ -typedef enum _GntMouseEvent -{ - GNT_LEFT_MOUSE_DOWN = 1, - GNT_RIGHT_MOUSE_DOWN, - GNT_MIDDLE_MOUSE_DOWN, - GNT_MOUSE_UP, - GNT_MOUSE_SCROLL_UP, - GNT_MOUSE_SCROLL_DOWN -} GntMouseEvent; - -/* XXX: I'll have to ask grim what he's using this for in guifications. */ -typedef enum _GntParamFlags -{ - GNT_PARAM_SERIALIZABLE = 1 << G_PARAM_USER_SHIFT -} GntParamFlags; - -struct _GntWidgetPriv -{ - int x, y; - int width, height; - GntWidgetFlags flags; - char *name; - - int minw, minh; /* Minimum size for the widget */ -}; - -struct _GntWidget -{ - GntBindable inherit; - - GntWidget *parent; - - GntWidgetPriv priv; - WINDOW *window; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -struct _GntWidgetClass -{ - GntBindableClass parent; - - void (*map)(GntWidget *obj); - void (*show)(GntWidget *obj); /* This will call draw() and take focus (if it can take focus) */ - void (*destroy)(GntWidget *obj); - void (*draw)(GntWidget *obj); /* This will draw the widget */ - void (*hide)(GntWidget *obj); - void (*expose)(GntWidget *widget, int x, int y, int width, int height); - void (*gained_focus)(GntWidget *widget); - void (*lost_focus)(GntWidget *widget); - - void (*size_request)(GntWidget *widget); - gboolean (*confirm_size)(GntWidget *widget, int x, int y); - void (*size_changed)(GntWidget *widget, int w, int h); - void (*set_position)(GntWidget *widget, int x, int y); - gboolean (*key_pressed)(GntWidget *widget, const char *key); - void (*activate)(GntWidget *widget); - gboolean (*clicked)(GntWidget *widget, GntMouseEvent event, int x, int y); - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntWidget. - */ -GType gnt_widget_get_gtype(void); - -/** - * Destroy a widget. - * @param widget The widget to destroy. - */ -void gnt_widget_destroy(GntWidget *widget); - -/** - * Show a widget. This should only be used for toplevel widgets. For the rest - * of the widgets, use #gnt_widget_draw instead. - * - * @param widget The widget to show. - */ -void gnt_widget_show(GntWidget *widget); - -/** - * Draw a widget. - * @param widget The widget to draw. - */ -void gnt_widget_draw(GntWidget *widget); - -/** - * @internal - * Expose part of a widget. - */ -void gnt_widget_expose(GntWidget *widget, int x, int y, int width, int height); - -/** - * Hide a widget. - * @param widget The widget to hide. - */ -void gnt_widget_hide(GntWidget *widget); - -/** - * Get the position of a widget. - * - * @param widget The widget. - * @param x Location to store the x-coordinate of the widget. - * @param y Location to store the y-coordinate of the widget. - */ -void gnt_widget_get_position(GntWidget *widget, int *x, int *y); - -/** - * Set the position of a widget. - * @param widget The widget to reposition. - * @param x The x-coordinate of the widget. - * @param y The x-coordinate of the widget. - */ -void gnt_widget_set_position(GntWidget *widget, int x, int y); - -/** - * Request a widget to calculate its desired size. - * @param widget The widget. - */ -void gnt_widget_size_request(GntWidget *widget); - -/** - * Get the size of a widget. - * @param widget The widget. - * @param width Location to store the width of the widget. - * @param height Location to store the height of the widget. - */ -void gnt_widget_get_size(GntWidget *widget, int *width, int *height); - -/** - * Set the size of a widget. - * - * @param widget The widget to resize. - * @param width The width of the widget. - * @param height The height of the widget. - * - * @return If the widget was resized to the new size. - */ -gboolean gnt_widget_set_size(GntWidget *widget, int width, int height); - -/** - * Confirm a requested a size for a widget. - * - * @param widget The widget. - * @param width The requested width. - * @param height The requested height. - * - * @return @c TRUE if the new size was confirmed, @c FALSE otherwise. - */ -gboolean gnt_widget_confirm_size(GntWidget *widget, int width, int height); - -/** - * Trigger the key-press callbacks for a widget. - * - * @param widget The widget. - * @param keys The keypress on the widget. - * - * @return @c TRUE if the key-press was handled, @c FALSE otherwise. - */ -gboolean gnt_widget_key_pressed(GntWidget *widget, const char *keys); - -/** - * Trigger the 'click' callback of a widget. - * - * @param widget The widget. - * @param event The mouseevent. - * @param x The x-coordinate of the mouse. - * @param y The y-coordinate of the mouse. - * - * @return @c TRUE if the event was handled, @c FALSE otherwise. - */ -gboolean gnt_widget_clicked(GntWidget *widget, GntMouseEvent event, int x, int y); - -/** - * Give or remove focus to a widget. - * @param widget The widget. - * @param set @c TRUE of focus should be given to the widget, @c FALSE if - * focus should be removed. - * - * @return @c TRUE if the focus has been changed, @c FALSE otherwise. - */ -gboolean gnt_widget_set_focus(GntWidget *widget, gboolean set); - -/** - * Activate a widget. This only applies to widgets that can be activated (eg. GntButton) - * @param widget The widget to activate. - */ -void gnt_widget_activate(GntWidget *widget); - -/** - * Set the name of a widget. - * @param widget The widget. - * @param name A new name for the widget. - */ -void gnt_widget_set_name(GntWidget *widget, const char *name); - -/** - * Get the name of a widget. - * @param widget The widget. - * @return The name of the widget. - */ -const char *gnt_widget_get_name(GntWidget *widget); - -/** - * @internal - * Use #gnt_widget_draw instead. - */ -void gnt_widget_queue_update(GntWidget *widget); - -/** - * Set whether a widget can take focus or not. - * - * @param widget The widget. - * @param set @c TRUE if the widget can take focus. - */ -void gnt_widget_set_take_focus(GntWidget *widget, gboolean set); - -/** - * Set the visibility of a widget. - * - * @param widget The widget. - * @param set Whether the widget is visible or not. - */ -void gnt_widget_set_visible(GntWidget *widget, gboolean set); - -/** - * Check whether the widget has shadows. - * - * @param widget The widget. - * - * @return @c TRUE if the widget has shadows. This checks both the user-setting - * and whether the widget can have shadows at all. - */ -gboolean gnt_widget_has_shadow(GntWidget *widget); - -G_END_DECLS - -#endif /* GNT_WIDGET_H */
--- a/finch/libgnt/gntwindow.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,233 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "gntinternal.h" -#include "gntstyle.h" -#include "gntwindow.h" - -#include <string.h> - -struct _GntWindowPriv -{ - GHashTable *accels; /* key => menuitem-id */ - GntWindowFlags flags; -}; - -enum -{ - SIG_WORKSPACE_HIDE, - SIG_WORKSPACE_SHOW, - SIGS, -}; - -static guint signals[SIGS] = { 0 }; - -static GntBoxClass *parent_class = NULL; - -static void (*org_destroy)(GntWidget *widget); - -static gboolean -show_menu(GntBindable *bind, GList *null) -{ - GntWindow *win = GNT_WINDOW(bind); - if (win->menu) { - GntMenu *menu = win->menu; - - gnt_screen_menu_show(menu); - if (menu->type == GNT_MENU_TOPLEVEL) { - GntMenuItem *item; - item = g_list_nth_data(menu->list, menu->selected); - if (item && gnt_menuitem_get_submenu(item)) { - gnt_widget_activate(GNT_WIDGET(menu)); - } - } - return TRUE; - } - return FALSE; -} - -static void -gnt_window_destroy(GntWidget *widget) -{ - GntWindow *window = GNT_WINDOW(widget); - if (window->menu) - gnt_widget_destroy(GNT_WIDGET(window->menu)); - if (window->priv) { - if (window->priv->accels) - g_hash_table_destroy(window->priv->accels); - g_free(window->priv); - } - org_destroy(widget); -} - -static void -gnt_window_class_init(GntWindowClass *klass) -{ - GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass); - GntWidgetClass *wid_class = GNT_WIDGET_CLASS(klass); - parent_class = GNT_BOX_CLASS(klass); - - org_destroy = wid_class->destroy; - wid_class->destroy = gnt_window_destroy; - - signals[SIG_WORKSPACE_HIDE] = - g_signal_new("workspace-hidden", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SIG_WORKSPACE_SHOW] = - g_signal_new("workspace-shown", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - gnt_bindable_class_register_action(bindable, "show-menu", show_menu, - GNT_KEY_CTRL_O, NULL); - gnt_bindable_register_binding(bindable, "show-menu", GNT_KEY_F10, NULL); - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable); - - GNTDEBUG; -} - -static void -gnt_window_init(GTypeInstance *instance, gpointer class) -{ - GntWidget *widget = GNT_WIDGET(instance); - GntWindow *win = GNT_WINDOW(widget); - GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_CAN_TAKE_FOCUS); - win->priv = g_new0(GntWindowPriv, 1); - win->priv->accels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - GNTDEBUG; -} - -/****************************************************************************** - * GntWindow API - *****************************************************************************/ -GType -gnt_window_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) - { - static const GTypeInfo info = { - sizeof(GntWindowClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)gnt_window_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(GntWindow), - 0, /* n_preallocs */ - gnt_window_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_BOX, - "GntWindow", - &info, 0); - } - - return type; -} - -GntWidget *gnt_window_new() -{ - GntWidget *widget = g_object_new(GNT_TYPE_WINDOW, NULL); - - return widget; -} - -GntWidget *gnt_window_box_new(gboolean homo, gboolean vert) -{ - GntWidget *wid = gnt_window_new(); - GntBox *box = GNT_BOX(wid); - - box->homogeneous = homo; - box->vertical = vert; - box->alignment = vert ? GNT_ALIGN_LEFT : GNT_ALIGN_MID; - - return wid; -} - -void -gnt_window_workspace_hiding(GntWindow *window) -{ - if (window->menu) - gnt_widget_hide(GNT_WIDGET(window->menu)); - g_signal_emit(window, signals[SIG_WORKSPACE_HIDE], 0); -} - -void -gnt_window_workspace_showing(GntWindow *window) -{ - g_signal_emit(window, signals[SIG_WORKSPACE_SHOW], 0); -} - -void gnt_window_set_menu(GntWindow *window, GntMenu *menu) -{ - /* If a menu already existed, then destroy that first. */ - const char *name = gnt_widget_get_name(GNT_WIDGET(window)); - if (window->menu) - gnt_widget_destroy(GNT_WIDGET(window->menu)); - window->menu = menu; - if (name && window->priv) { - if (!gnt_style_read_menu_accels(name, window->priv->accels)) { - g_hash_table_destroy(window->priv->accels); - window->priv->accels = NULL; - } - } -} - -const char * gnt_window_get_accel_item(GntWindow *window, const char *key) -{ - if (window->priv->accels) - return g_hash_table_lookup(window->priv->accels, key); - return NULL; -} - -void gnt_window_set_maximize(GntWindow *window, GntWindowFlags maximize) -{ - if (maximize & GNT_WINDOW_MAXIMIZE_X) - window->priv->flags |= GNT_WINDOW_MAXIMIZE_X; - else - window->priv->flags &= ~GNT_WINDOW_MAXIMIZE_X; - - if (maximize & GNT_WINDOW_MAXIMIZE_Y) - window->priv->flags |= GNT_WINDOW_MAXIMIZE_Y; - else - window->priv->flags &= ~GNT_WINDOW_MAXIMIZE_Y; -} - -GntWindowFlags gnt_window_get_maximize(GntWindow *window) -{ - return (window->priv->flags & (GNT_WINDOW_MAXIMIZE_X | GNT_WINDOW_MAXIMIZE_Y)); -} -
--- a/finch/libgnt/gntwindow.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/** - * @file gntwindow.h Window API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNT_WINDOW_H -#define GNT_WINDOW_H - -#include "gnt.h" -#include "gntbox.h" -#include "gntcolors.h" -#include "gntkeys.h" -#include "gntmenu.h" - -#define GNT_TYPE_WINDOW (gnt_window_get_gtype()) -#define GNT_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WINDOW, GntWindow)) -#define GNT_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_WINDOW, GntWindowClass)) -#define GNT_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WINDOW)) -#define GNT_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WINDOW)) -#define GNT_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WINDOW, GntWindowClass)) - -#define GNT_WINDOW_FLAGS(obj) (GNT_WINDOW(obj)->priv.flags) -#define GNT_WINDOW_SET_FLAGS(obj, flags) (GNT_WINDOW_FLAGS(obj) |= flags) -#define GNT_WINDOW_UNSET_FLAGS(obj, flags) (GNT_WINDOW_FLAGS(obj) &= ~(flags)) - -typedef struct _GntWindow GntWindow; -typedef struct _GntWindowPriv GntWindowPriv; -typedef struct _GntWindowClass GntWindowClass; - -typedef enum -{ - GNT_WINDOW_MAXIMIZE_X = 1 << 0, - GNT_WINDOW_MAXIMIZE_Y = 1 << 1, -} GntWindowFlags; - -struct _GntWindow -{ - GntBox parent; - GntMenu *menu; - GntWindowPriv *priv; -}; - -struct _GntWindowClass -{ - GntBoxClass parent; - - void (*gnt_reserved1)(void); - void (*gnt_reserved2)(void); - void (*gnt_reserved3)(void); - void (*gnt_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntWindow. - */ -GType gnt_window_get_gtype(void); - -#define gnt_vwindow_new(homo) gnt_window_box_new(homo, TRUE) -#define gnt_hwindow_new(homo) gnt_window_box_new(homo, FALSE) - -/** - * Create a new window. - * - * @return The newly created window. - */ -GntWidget * gnt_window_new(void); - -/** - * Create a new window. - * - * @param homo @c TRUE if the widgets inside the window should have the same dimensions. - * @param vert @c TRUE if the widgets inside the window should be stacked vertically. - * - * @return The newly created window. - */ -GntWidget * gnt_window_box_new(gboolean homo, gboolean vert); - -/** - * Set the menu for a window. - * - * @param window The window. - * @param menu The menu for the window. - */ -void gnt_window_set_menu(GntWindow *window, GntMenu *menu); - -/** - * Return the id of a menuitem specified to a keystroke. - * - * @param window The window. - * @param key The keystroke. - * - * @return The id of the menuitem bound to the keystroke, or @c NULL. - * - * @since 2.3.0 - */ -const char * gnt_window_get_accel_item(GntWindow *window, const char *key); - -/** - * Maximize a window, either horizontally or vertically, or both. - * - * @param window The window to maximize. - * @param maximize The maximization state of the window. - * - * @since 2.3.0 - */ -void gnt_window_set_maximize(GntWindow *window, GntWindowFlags maximize); - -/** - * Get the maximization state of a window. - * - * @param window The window. - * - * @return The maximization state of the window. - * - * @since 2.3.0 - */ -GntWindowFlags gnt_window_get_maximize(GntWindow *window); - -void gnt_window_workspace_hiding(GntWindow *); -void gnt_window_workspace_showing(GntWindow *); - -G_END_DECLS - -#endif /* GNT_WINDOW_H */
--- a/finch/libgnt/gntwm.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2307 +0,0 @@ -/** - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include "config.h" - -#ifdef USE_PYTHON -#include <Python.h> -#endif - -/* Python.h may define _GNU_SOURCE and _XOPEN_SOURCE_EXTENDED, so protect - * these checks with #ifndef/!defined() */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#if !defined _XOPEN_SOURCE_EXTENDED && (defined(__APPLE__) || defined(__unix__)) && !defined(__FreeBSD__) -#define _XOPEN_SOURCE_EXTENDED -#endif - -#include <glib.h> -#if GLIB_CHECK_VERSION(2,6,0) -# include <glib/gstdio.h> -#else -# include <sys/types.h> -# include <sys/stat.h> -# include <fcntl.h> -# define g_fopen open -#endif -#include <ctype.h> -#include <gmodule.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include "gntinternal.h" -#undef GNT_LOG_DOMAIN -#define GNT_LOG_DOMAIN "WM" - -#include "gntwm.h" -#include "gntstyle.h" -#include "gntmarshal.h" -#include "gnt.h" -#include "gntbox.h" -#include "gntbutton.h" -#include "gntentry.h" -#include "gntfilesel.h" -#include "gntlabel.h" -#include "gntmenu.h" -#include "gnttextview.h" -#include "gnttree.h" -#include "gntutils.h" -#include "gntwindow.h" - -#define IDLE_CHECK_INTERVAL 5 /* 5 seconds */ - -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, - SIG_TERMINAL_REFRESH, - 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 void shift_window(GntWM *wm, GntWidget *widget, int dir); -static gboolean workspace_next(GntBindable *wm, GList *n); -static gboolean workspace_prev(GntBindable *wm, GList *n); - -#ifndef NO_WIDECHAR -static int widestringwidth(wchar_t *wide); -#endif - -static void ensure_normal_mode(GntWM *wm); -static gboolean write_already(gpointer data); -static int write_timeout; -static time_t last_active_time; -static gboolean idle_update; -static GList *act = NULL; /* list of WS with unseen activitiy */ -static gboolean ignore_keys = FALSE; -#ifdef USE_PYTHON -static gboolean started_python = FALSE; -#endif - -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); -} - -void -gnt_wm_copy_win(GntWidget *widget, GntNode *node) -{ - WINDOW *src, *dst; - if (!node) - return; - src = widget->window; - dst = node->window; - copywin(src, dst, node->scroll, 0, 0, 0, getmaxy(dst) - 1, getmaxx(dst) - 1, 0); - - /* Update the hardware cursor */ - if (GNT_IS_WINDOW(widget) || GNT_IS_BOX(widget)) { - GntWidget *active = GNT_BOX(widget)->active; - if (active) { - int curx = active->priv.x + getcurx(active->window); - int cury = active->priv.y + getcury(active->window); - if (wmove(node->window, cury - widget->priv.y, curx - widget->priv.x) != OK) - (void)wmove(node->window, 0, 0); - } - } -} - -/** - * The following is a workaround for a bug in most versions of ncursesw. - * Read about it in: http://article.gmane.org/gmane.comp.lib.ncurses.bugs/2751 - * - * In short, if a panel hides one cell of a multi-cell character, then the rest - * of the characters in that line get screwed. The workaround here is to erase - * any such character preemptively. - * - * Caveat: If a wide character is erased, and the panel above it is moved enough - * to expose the entire character, it is not always redrawn. - */ -static void -work_around_for_ncurses_bug(void) -{ -#ifndef NO_WIDECHAR - PANEL *panel = NULL; - while ((panel = panel_below(panel)) != NULL) { - int sx, ex, sy, ey, w, y; - cchar_t ch; - PANEL *below = panel; - - sx = getbegx(panel->win); - ex = getmaxx(panel->win) + sx; - sy = getbegy(panel->win); - ey = getmaxy(panel->win) + sy; - - while ((below = panel_below(below)) != NULL) { - if (sy > getbegy(below->win) + getmaxy(below->win) || - ey < getbegy(below->win)) - continue; - if (sx > getbegx(below->win) + getmaxx(below->win) || - ex < getbegx(below->win)) - continue; - for (y = MAX(sy, getbegy(below->win)); y <= MIN(ey, getbegy(below->win) + getmaxy(below->win)); y++) { - if (mvwin_wch(below->win, y - getbegy(below->win), sx - 1 - getbegx(below->win), &ch) != OK) - goto right; - w = widestringwidth(ch.chars); - if (w > 1 && (ch.attr & 1)) { - ch.chars[0] = ' '; - ch.attr &= ~ A_CHARTEXT; - mvwadd_wch(below->win, y - getbegy(below->win), sx - 1 - getbegx(below->win), &ch); - touchline(below->win, y - getbegy(below->win), 1); - } -right: - if (mvwin_wch(below->win, y - getbegy(below->win), ex + 1 - getbegx(below->win), &ch) != OK) - continue; - w = widestringwidth(ch.chars); - if (w > 1 && !(ch.attr & 1)) { - ch.chars[0] = ' '; - ch.attr &= ~ A_CHARTEXT; - mvwadd_wch(below->win, y - getbegy(below->win), ex + 1 - getbegx(below->win), &ch); - touchline(below->win, y - getbegy(below->win), 1); - } - } - } - } -#endif -} - -static void -update_act_msg(void) -{ - GntWidget *label; - GList *iter; - static GntWidget *message = NULL; - GString *text = g_string_new("act: "); - if (message) - gnt_widget_destroy(message); - if (!act) - return; - for (iter = act; iter; iter = iter->next) { - GntWS *ws = iter->data; - g_string_append_printf(text, "%s, ", gnt_ws_get_name(ws)); - } - g_string_erase(text, text->len - 2, 2); - message = gnt_vbox_new(FALSE); - label = gnt_label_new_with_format(text->str, GNT_TEXT_FLAG_BOLD | GNT_TEXT_FLAG_HIGHLIGHT); - GNT_WIDGET_UNSET_FLAGS(GNT_BOX(message), GNT_WIDGET_CAN_TAKE_FOCUS); - GNT_WIDGET_SET_FLAGS(GNT_BOX(message), GNT_WIDGET_TRANSIENT); - gnt_box_add_widget(GNT_BOX(message), label); - gnt_widget_set_name(message, "wm-message"); - gnt_widget_set_position(message, 0, 0); - gnt_widget_draw(message); - g_string_free(text, TRUE); -} - -static gboolean -update_screen(GntWM *wm) -{ - if (wm->mode == GNT_KP_MODE_WAIT_ON_CHILD) - return TRUE; - - 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; - } - } - work_around_for_ncurses_bug(); - update_panels(); - doupdate(); - return TRUE; -} - -static gboolean -sanitize_position(GntWidget *widget, int *x, int *y, gboolean m) -{ - int X_MAX = getmaxx(stdscr); - int Y_MAX = getmaxy(stdscr) - 1; - int w, h; - int nx, ny; - gboolean changed = FALSE; - GntWindowFlags flags = GNT_IS_WINDOW(widget) ? - gnt_window_get_maximize(GNT_WINDOW(widget)) : 0; - - gnt_widget_get_size(widget, &w, &h); - if (x) { - if (m && (flags & GNT_WINDOW_MAXIMIZE_X) && *x != 0) { - *x = 0; - changed = TRUE; - } else if (*x + w > X_MAX) { - nx = MAX(0, X_MAX - w); - if (nx != *x) { - *x = nx; - changed = TRUE; - } - } - } - if (y) { - if (m && (flags & GNT_WINDOW_MAXIMIZE_Y) && *y != 0) { - *y = 0; - changed = TRUE; - } else if (*y + h > Y_MAX) { - ny = MAX(0, Y_MAX - h); - if (ny != *y) { - *y = ny; - changed = TRUE; - } - } - } - return changed; -} - -static void -refresh_node(GntWidget *widget, GntNode *node, gpointer m) -{ - int x, y, w, h; - int nw, nh; - - int X_MAX = getmaxx(stdscr); - int Y_MAX = getmaxy(stdscr) - 1; - - GntWindowFlags flags = 0; - - if (m && GNT_IS_WINDOW(widget)) { - flags = gnt_window_get_maximize(GNT_WINDOW(widget)); - } - - gnt_widget_get_position(widget, &x, &y); - gnt_widget_get_size(widget, &w, &h); - - if (sanitize_position(widget, &x, &y, !!m)) - gnt_screen_move_widget(widget, x, y); - - if (flags & GNT_WINDOW_MAXIMIZE_X) - nw = X_MAX; - else - nw = MIN(w, X_MAX); - - if (flags & GNT_WINDOW_MAXIMIZE_Y) - nh = Y_MAX; - else - nh = MIN(h, Y_MAX); - - if (nw != w || nh != h) - gnt_screen_resize_widget(widget, nw, nh); -} - -static void -read_window_positions(GntWM *wm) -{ -#if GLIB_CHECK_VERSION(2,6,0) - GKeyFile *gfile = g_key_file_new(); - char *filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); - GError *error = NULL; - char **keys; - gsize nk; - - if (!g_key_file_load_from_file(gfile, filename, G_KEY_FILE_NONE, &error)) { - gnt_warning("%s", error->message); - g_error_free(error); - g_free(filename); - return; - } - - keys = g_key_file_get_keys(gfile, "positions", &nk, &error); - if (error) { - gnt_warning("%s", error->message); - g_error_free(error); - error = NULL; - } else { - while (nk--) { - char *title = keys[nk]; - gsize l; - char **coords = g_key_file_get_string_list(gfile, "positions", title, &l, NULL); - if (l == 2) { - int x = atoi(coords[0]); - int y = atoi(coords[1]); - GntPosition *p = g_new0(GntPosition, 1); - p->x = x; - p->y = y; - g_hash_table_replace(wm->positions, g_strdup(title + 1), p); - } else { - gnt_warning("Invalid number of arguments (%" G_GSIZE_FORMAT - ") for positioning a window.", l); - } - g_strfreev(coords); - } - g_strfreev(keys); - } - - g_free(filename); - g_key_file_free(gfile); -#endif -} - -static gboolean check_idle(gpointer n) -{ - if (idle_update) { - time(&last_active_time); - idle_update = FALSE; - } - return TRUE; -} - -static void -gnt_wm_init(GTypeInstance *instance, gpointer class) -{ - GntWM *wm = GNT_WM(instance); - wm->workspaces = NULL; - wm->name_places = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - wm->title_places = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - gnt_style_read_workspaces(wm); - if (wm->workspaces == NULL) { - wm->cws = gnt_ws_new("default"); - gnt_wm_add_workspace(wm, wm->cws); - } else { - wm->cws = wm->workspaces->data; - } - wm->event_stack = FALSE; - wm->tagged = NULL; - wm->windows = NULL; - wm->actions = NULL; - wm->nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); - wm->positions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE)) - read_window_positions(wm); - g_timeout_add_seconds(IDLE_CHECK_INTERVAL, check_idle, NULL); - time(&last_active_time); - gnt_wm_switch_workspace(wm, 0); -} - -static void -switch_window(GntWM *wm, int direction, gboolean urgent) -{ - GntWidget *w = NULL, *wid = NULL; - int pos, orgpos; - - if (wm->_list.window || wm->menu) - return; - - if (!wm->cws->ordered || !wm->cws->ordered->next) - return; - - if (wm->mode != GNT_KP_MODE_NORMAL) { - ensure_normal_mode(wm); - } - - w = wm->cws->ordered->data; - orgpos = pos = g_list_index(wm->cws->list, w); - - do { - pos += direction; - - if (pos < 0) { - wid = g_list_last(wm->cws->list)->data; - pos = g_list_length(wm->cws->list) - 1; - } else if ((guint)pos >= g_list_length(wm->cws->list)) { - wid = wm->cws->list->data; - pos = 0; - } else - wid = g_list_nth_data(wm->cws->list, pos); - } while (urgent && !GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT) && pos != orgpos); - - gnt_wm_raise_window(wm, wid); -} - -static gboolean -window_next(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - switch_window(wm, 1, FALSE); - return TRUE; -} - -static gboolean -window_prev(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - switch_window(wm, -1, FALSE); - return TRUE; -} - -static gboolean -switch_window_n(GntBindable *bind, GList *list) -{ - GntWM *wm = GNT_WM(bind); - GList *l; - int n; - - if (!wm->cws->ordered) - return TRUE; - - if (list) - n = GPOINTER_TO_INT(list->data); - else - n = 0; - - if ((l = g_list_nth(wm->cws->list, n)) != NULL) - { - gnt_wm_raise_window(wm, l->data); - } - - return TRUE; -} - -static gboolean -window_scroll_up(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - GntWidget *window; - GntNode *node; - - if (!wm->cws->ordered) - return TRUE; - - window = wm->cws->ordered->data; - node = g_hash_table_lookup(wm->nodes, window); - if (!node) - return TRUE; - - if (node->scroll) { - node->scroll--; - gnt_wm_copy_win(window, node); - update_screen(wm); - } - return TRUE; -} - -static gboolean -window_scroll_down(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - GntWidget *window; - GntNode *node; - int w, h; - - if (!wm->cws->ordered) - return TRUE; - - window = wm->cws->ordered->data; - node = g_hash_table_lookup(wm->nodes, window); - if (!node) - return TRUE; - - gnt_widget_get_size(window, &w, &h); - if (h - node->scroll > getmaxy(node->window)) { - node->scroll++; - gnt_wm_copy_win(window, node); - update_screen(wm); - } - return TRUE; -} - -static gboolean -window_close(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - - if (wm->_list.window) - return TRUE; - - if (wm->cws->ordered) { - gnt_widget_destroy(wm->cws->ordered->data); - ensure_normal_mode(wm); - } - - 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; - ensure_normal_mode(wm); - 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) -{ - GntBindable *sel = gnt_tree_get_selection_data(GNT_TREE(tree)); - - gnt_widget_destroy(wm->_list.window); - - if (!sel) - return; - - if (GNT_IS_WS(sel)) { - gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, sel)); - } else { - gnt_wm_raise_window(wm, GNT_WIDGET(sel)); - } -} - -static void -populate_window_list(GntWM *wm, gboolean workspace) -{ - GList *iter; - GntTree *tree = GNT_TREE(wm->windows->tree); - if (!workspace) { - for (iter = wm->cws->list; iter; iter = iter->next) { - GntBox *box = GNT_BOX(iter->data); - - gnt_tree_add_row_last(tree, box, - gnt_tree_create_row(tree, box->title), NULL); - update_window_in_list(wm, GNT_WIDGET(box)); - } - } else { - GList *ws = wm->workspaces; - for (; ws; ws = ws->next) { - gnt_tree_add_row_last(tree, ws->data, - gnt_tree_create_row(tree, gnt_ws_get_name(GNT_WS(ws->data))), NULL); - for (iter = GNT_WS(ws->data)->list; iter; iter = iter->next) { - GntBox *box = GNT_BOX(iter->data); - - gnt_tree_add_row_last(tree, box, - gnt_tree_create_row(tree, box->title), ws->data); - update_window_in_list(wm, GNT_WIDGET(box)); - } - } - } -} - -static gboolean -window_list_key_pressed(GntWidget *widget, const char *text, GntWM *wm) -{ - if (text[1] == 0 && wm->cws->ordered) { - GntBindable *sel = gnt_tree_get_selection_data(GNT_TREE(widget)); - switch (text[0]) { - case '-': - case ',': - if (GNT_IS_WS(sel)) { - /* reorder the workspace. */ - } else - shift_window(wm, GNT_WIDGET(sel), -1); - break; - case '=': - case '.': - if (GNT_IS_WS(sel)) { - /* reorder the workspace. */ - } else - shift_window(wm, GNT_WIDGET(sel), 1); - break; - default: - return FALSE; - } - gnt_tree_remove_all(GNT_TREE(widget)); - populate_window_list(wm, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "workspace"))); - gnt_tree_set_selected(GNT_TREE(widget), sel); - return TRUE; - } - return FALSE; -} - -static void -list_of_windows(GntWM *wm, gboolean workspace) -{ - GntWidget *tree, *win; - setup__list(wm); - wm->windows = &wm->_list; - - win = wm->windows->window; - tree = wm->windows->tree; - - gnt_box_set_title(GNT_BOX(win), workspace ? "Workspace List" : "Window List"); - - populate_window_list(wm, workspace); - - if (wm->cws->ordered) - gnt_tree_set_selected(GNT_TREE(tree), wm->cws->ordered->data); - else if (workspace) - gnt_tree_set_selected(GNT_TREE(tree), wm->cws); - - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm); - g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(window_list_key_pressed), wm); - g_object_set_data(G_OBJECT(tree), "workspace", GINT_TO_POINTER(workspace)); - - 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); -} - -static gboolean -window_list(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - - if (wm->_list.window || wm->menu) - return TRUE; - - if (!wm->cws->ordered) - return TRUE; - - list_of_windows(wm, FALSE); - - return TRUE; -} - -static void -dump_file_save(GntFileSel *fs, const char *path, const char *f, gpointer n) -{ - FILE *file; - int x, y; - chtype old = 0, now = 0; - struct { - char ascii; - char *unicode; - } unis[] = { - {'q', "─"}, - {'t', "├"}, - {'u', "┤"}, - {'x', "│"}, - {'-', "↑"}, - {'.', "↓"}, - {'l', "┌"}, - {'k', "┐"}, - {'m', "└"}, - {'j', "┘"}, - {'a', "▒"}, - {'n', "┼"}, - {'w', "┬"}, - {'v', "┴"}, - {'\0', NULL} - }; - - gnt_widget_destroy(GNT_WIDGET(fs)); - - if ((file = g_fopen(path, "w+")) == NULL) { - return; - } - - fprintf(file, "<head>\n <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\n</head>\n<body>\n"); - fprintf(file, "<pre>"); - for (y = 0; y < getmaxy(stdscr); y++) { - for (x = 0; x < getmaxx(stdscr); x++) { - char ch[2] = {0, 0}, *print; -#ifdef NO_WIDECHAR - now = mvwinch(curscr, y, x); - ch[0] = now & A_CHARTEXT; - now ^= ch[0]; -#else - cchar_t wch; - char unicode[12]; - mvwin_wch(curscr, y, x, &wch); - now = wch.attr; - ch[0] = (char)(wch.chars[0] & 0xff); -#endif - -#define CHECK(attr, start, end) \ - do \ - { \ - if (now & attr) \ - { \ - if (!(old & attr)) \ - fprintf(file, "%s", start); \ - } \ - else if (old & attr) \ - { \ - fprintf(file, "%s", 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)) - { - short fgp, bgp, r, g, b; - struct - { - int r, g, b; - } fg, bg; - - if (pair_content(PAIR_NUMBER(now & A_COLOR), &fgp, &bgp) != OK) { - fgp = -1; - bgp = -1; - } - if (fgp == -1) - fgp = COLOR_BLACK; - if (bgp == -1) - bgp = COLOR_WHITE; - if (now & A_REVERSE) - { - short tmp = fgp; - fgp = bgp; - bgp = tmp; - } - if (color_content(fgp, &r, &g, &b) != OK) { - r = g = b = 0; - } - fg.r = r; fg.b = b; fg.g = g; - if (color_content(bgp, &r, &g, &b) != OK) { - r = g = b = 255; - } - 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); - } - print = ch; -#ifndef NO_WIDECHAR - if (wch.chars[0] > 255) { - snprintf(unicode, sizeof(unicode), "&#x%x;", (unsigned int)wch.chars[0]); - print = unicode; - } -#endif - if (now & A_ALTCHARSET) - { - int u; - for (u = 0; unis[u].ascii; u++) { - if (ch[0] == unis[u].ascii) { - print = unis[u].unicode; - break; - } - } - if (!unis[u].ascii) - print = " "; - } - if (ch[0] == '&') - fprintf(file, "&"); - else if (ch[0] == '<') - fprintf(file, "<"); - else if (ch[0] == '>') - fprintf(file, ">"); - else - fprintf(file, "%s", print); - old = now; - } - fprintf(file, "</span>\n"); - old = 0; - } - fprintf(file, "</pre>\n</body>"); - fclose(file); -} - -static void -dump_file_cancel(GntWidget *w, GntFileSel *fs) -{ - gnt_widget_destroy(GNT_WIDGET(fs)); -} - -static gboolean -dump_screen(GntBindable *b, GList *null) -{ - GntWidget *window = gnt_file_sel_new(); - GntFileSel *sel = GNT_FILE_SEL(window); - - g_object_set(G_OBJECT(window), "vertical", TRUE, NULL); - gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Please enter the filename to save the screenshot.")); - gnt_box_set_title(GNT_BOX(window), "Save Screenshot..."); - - gnt_file_sel_set_suggested_filename(sel, "dump.html"); - g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(dump_file_save), NULL); - g_signal_connect(G_OBJECT(sel->cancel), "activate", G_CALLBACK(dump_file_cancel), sel); - gnt_widget_show(window); - return TRUE; -} - -static void -shift_window(GntWM *wm, GntWidget *widget, int dir) -{ - GList *all = wm->cws->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->cws->list = all; - gnt_ws_draw_taskbar(wm->cws, FALSE); - if (wm->cws->ordered) { - GntWidget *w = wm->cws->ordered->data; - GntNode *node = g_hash_table_lookup(wm->nodes, w); - top_panel(node->panel); - update_panels(); - doupdate(); - } -} - -static gboolean -shift_left(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - if (wm->_list.window) - return TRUE; - - if(!wm->cws->ordered) - return FALSE; - - shift_window(wm, wm->cws->ordered->data, -1); - return TRUE; -} - -static gboolean -shift_right(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - - if (wm->_list.window) - return TRUE; - - if(!wm->cws->ordered) - return FALSE; - - shift_window(wm, wm->cws->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); - int n; - 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); - n = g_list_length(wm->acts); - gnt_widget_set_size(tree, 0, n); - gnt_widget_set_position(win, 0, getmaxy(stdscr) - 3 - n); - - 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 = string ? gnt_util_onscreen_width(string, NULL) : 1; - 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, GntWM *wm) -{ - 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)); - - gnt_wm_copy_win(win, g_hash_table_lookup(wm->nodes, win)); - update_screen(wm); -} - -static void -ensure_normal_mode(GntWM *wm) -{ - if (wm->mode != GNT_KP_MODE_NORMAL) { - if (wm->cws->ordered) - window_reverse(wm->cws->ordered->data, FALSE, wm); - wm->mode = GNT_KP_MODE_NORMAL; - } -} - -static gboolean -start_move(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - if (wm->_list.window || wm->menu) - return TRUE; - if (!wm->cws->ordered) - return TRUE; - - wm->mode = GNT_KP_MODE_MOVE; - window_reverse(GNT_WIDGET(wm->cws->ordered->data), TRUE, wm); - - 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->cws->ordered) - return TRUE; - - wm->mode = GNT_KP_MODE_RESIZE; - window_reverse(GNT_WIDGET(wm->cws->ordered->data), TRUE, wm); - - return TRUE; -} - -static gboolean -wm_quit(GntBindable *bindable, GList *list) -{ - GntWM *wm = GNT_WM(bindable); - if (write_timeout) - write_already(wm); - 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); - GList *iter; - - endwin(); - refresh(); - - g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, GINT_TO_POINTER(TRUE)); - g_signal_emit(wm, signals[SIG_TERMINAL_REFRESH], 0); - - for (iter = g_list_last(wm->cws->ordered); iter; iter = iter->prev) { - GntWidget *w = iter->data; - GntNode *node = g_hash_table_lookup(wm->nodes, w); - top_panel(node->panel); - } - - gnt_ws_draw_taskbar(wm->cws, TRUE); - update_screen(wm); - curs_set(0); /* endwin resets the cursor to normal */ - - return TRUE; -} - -static gboolean -toggle_clipboard(GntBindable *bindable, GList *n) -{ - static GntWidget *clip; - gchar *text; - if (clip) { - gnt_widget_destroy(clip); - clip = NULL; - return TRUE; - } - text = gnt_get_clipboard_string(); - clip = gnt_hwindow_new(FALSE); - GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_TRANSIENT); - GNT_WIDGET_SET_FLAGS(clip, GNT_WIDGET_NO_BORDER); - gnt_box_set_pad(GNT_BOX(clip), 0); - gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(" ")); - gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(text)); - gnt_box_add_widget(GNT_BOX(clip), gnt_label_new(" ")); - gnt_widget_set_position(clip, 0, 0); - gnt_widget_draw(clip); - g_free(text); - return TRUE; -} - -static void remove_tag(gpointer wid, gpointer wim) -{ - GntWM *wm = GNT_WM(wim); - GntWidget *w = GNT_WIDGET(wid); - wm->tagged = g_list_remove(wm->tagged, w); - mvwhline(w->window, 0, 1, ACS_HLINE | gnt_color_pair(GNT_COLOR_NORMAL), 3); - gnt_widget_draw(w); -} - -static gboolean -tag_widget(GntBindable *b, GList *params) -{ - GntWM *wm = GNT_WM(b); - GntWidget *widget; - - if (!wm->cws->ordered) - return FALSE; - widget = wm->cws->ordered->data; - - if (g_list_find(wm->tagged, widget)) { - remove_tag(widget, wm); - return TRUE; - } - - wm->tagged = g_list_prepend(wm->tagged, widget); - wbkgdset(widget->window, ' ' | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - mvwprintw(widget->window, 0, 1, "[T]"); - gnt_widget_draw(widget); - return TRUE; -} - -static void -widget_move_ws(gpointer wid, gpointer w) -{ - GntWM *wm = GNT_WM(w); - gnt_wm_widget_move_workspace(wm, wm->cws, GNT_WIDGET(wid)); -} - -static gboolean -place_tagged(GntBindable *b, GList *params) -{ - GntWM *wm = GNT_WM(b); - g_list_foreach(wm->tagged, widget_move_ws, wm); - g_list_foreach(wm->tagged, remove_tag, wm); - g_list_free(wm->tagged); - wm->tagged = NULL; - return TRUE; -} - -static gboolean -workspace_list(GntBindable *b, GList *params) -{ - GntWM *wm = GNT_WM(b); - - if (wm->_list.window || wm->menu) - return TRUE; - - list_of_windows(wm, TRUE); - - return TRUE; -} - -static gboolean -workspace_new(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - GntWS *ws = gnt_ws_new(NULL); - gnt_wm_add_workspace(wm, ws); - gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, ws)); - return TRUE; -} - -static gboolean -ignore_keys_start(GntBindable *bindable, GList *n) -{ - GntWM *wm = GNT_WM(bindable); - - if(!wm->menu && !wm->_list.window && wm->mode == GNT_KP_MODE_NORMAL){ - ignore_keys = TRUE; - return TRUE; - } - return FALSE; -} - -static gboolean -ignore_keys_end(GntBindable *bindable, GList *n) -{ - if (ignore_keys) { - ignore_keys = FALSE; - return TRUE; - } - return FALSE; -} - -static gboolean -window_next_urgent(GntBindable *bindable, GList *n) -{ - GntWM *wm = GNT_WM(bindable); - switch_window(wm, 1, TRUE); - return TRUE; -} - -static gboolean -window_prev_urgent(GntBindable *bindable, GList *n) -{ - GntWM *wm = GNT_WM(bindable); - switch_window(wm, -1, TRUE); - return TRUE; -} - -#ifdef USE_PYTHON -static void -python_script_selected(GntFileSel *fs, const char *path, const char *f, gpointer n) -{ - char *dir = g_path_get_dirname(path); - FILE *file = fopen(path, "r"); - PyObject *pp = PySys_GetObject("path"); -#if PY_MAJOR_VERSION >= 3 - PyObject *dirobj = PyUnicode_FromString(dir); -#else - PyObject *dirobj = PyString_FromString(dir); -#endif - - PyList_Insert(pp, 0, dirobj); - Py_DECREF(dirobj); - PyRun_SimpleFile(file, path); - fclose(file); - - if (PyErr_Occurred()) { - PyErr_Print(); - } - g_free(dir); - - gnt_widget_destroy(GNT_WIDGET(fs)); -} - -static gboolean -run_python(GntBindable *bindable, GList *n) -{ - GntWidget *window = gnt_file_sel_new(); - GntFileSel *sel = GNT_FILE_SEL(window); - - g_object_set(G_OBJECT(window), "vertical", TRUE, NULL); - gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Please select the python script you want to run.")); - gnt_box_set_title(GNT_BOX(window), "Select Python Script..."); - - g_signal_connect(G_OBJECT(sel), "file_selected", G_CALLBACK(python_script_selected), NULL); - g_signal_connect_swapped(G_OBJECT(sel->cancel), "activate", G_CALLBACK(gnt_widget_destroy), sel); - gnt_widget_show(window); - return TRUE; -} -#endif /* USE_PYTHON */ - -static gboolean -help_for_bindable(GntWM *wm, GntBindable *bindable) -{ - gboolean ret = TRUE; - GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable); - - if (klass->help_window) { - gnt_wm_raise_window(wm, GNT_WIDGET(klass->help_window)); - } else { - ret = gnt_bindable_build_help_window(bindable); - } - return ret; -} - -static gboolean -help_for_wm(GntBindable *bindable, GList *null) -{ - return help_for_bindable(GNT_WM(bindable),bindable); -} - -static gboolean -help_for_window(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - GntWidget *widget; - - if(!wm->cws->ordered) - return FALSE; - - widget = wm->cws->ordered->data; - - return help_for_bindable(wm,GNT_BINDABLE(widget)); -} - -static gboolean -help_for_widget(GntBindable *bindable, GList *null) -{ - GntWM *wm = GNT_WM(bindable); - GntWidget *widget; - - if (!wm->cws->ordered) - return TRUE; - - widget = wm->cws->ordered->data; - if (!GNT_IS_BOX(widget)) - return TRUE; - - return help_for_bindable(wm, GNT_BINDABLE(GNT_BOX(widget)->active)); -} - -static void -accumulate_windows(gpointer window, gpointer node, gpointer p) -{ - GList *list = *(GList**)p; - list = g_list_prepend(list, window); - *(GList**)p = list; -} - -static void -gnt_wm_destroy(GObject *obj) -{ - GntWM *wm = GNT_WM(obj); - GList *list = NULL; - g_hash_table_foreach(wm->nodes, accumulate_windows, &list); - g_list_foreach(list, (GFunc)gnt_widget_destroy, NULL); - g_list_free(list); - g_hash_table_destroy(wm->nodes); - wm->nodes = NULL; - - while (wm->workspaces) { - g_object_unref(wm->workspaces->data); - wm->workspaces = g_list_delete_link(wm->workspaces, wm->workspaces); - } -#ifdef USE_PYTHON - if (started_python) { - Py_Finalize(); - started_python = FALSE; - } -#endif -} - -static void -gnt_wm_class_init(GntWMClass *klass) -{ - int i; - GObjectClass *gclass = G_OBJECT_CLASS(klass); - char key[32]; - - gclass->dispose = gnt_wm_destroy; - - 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); - - signals[SIG_TERMINAL_REFRESH] = - g_signal_new("terminal-refresh", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GntWMClass, terminal_refresh), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - 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_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-down", window_scroll_down, - "\033" GNT_KEY_CTRL_J, NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-up", window_scroll_up, - "\033" GNT_KEY_CTRL_K, NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-widget", help_for_widget, - "\033" "/", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-new", workspace_new, - GNT_KEY_F9, NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-next", workspace_next, - "\033" ">", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-prev", workspace_prev, - "\033" "<", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-tag", tag_widget, - "\033" "t", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "place-tagged", place_tagged, - "\033" "T", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-list", workspace_list, - "\033" "s", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-clipboard", toggle_clipboard, - "\033" "C", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-wm", help_for_wm, - "\033" "\\", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-window", help_for_window, - "\033" "|", NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "ignore-keys-start", ignore_keys_start, - NULL, NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "ignore-keys-end", ignore_keys_end, - "\033" GNT_KEY_CTRL_G, NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-next-urgent", window_next_urgent, - "\033" "\t", NULL); - snprintf(key, sizeof(key), "\033%s", GNT_KEY_BACK_TAB); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-prev-urgent", window_prev_urgent, - key[1] ? key : NULL, NULL); -#ifdef USE_PYTHON - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "run-python", run_python, - GNT_KEY_F3, NULL); - if (!Py_IsInitialized()) { -#if PY_MAJOR_VERSION >= 3 - wchar_t *name; - size_t len; - len = mbstowcs(NULL, "gnt", 0); - name = g_new(wchar_t, len + 1); - mbstowcs(name, "gnt", len + 1); - Py_SetProgramName(name); - g_free(name); -#else - Py_SetProgramName("gnt"); -#endif - Py_Initialize(); - started_python = TRUE; - } -#endif - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); - - /* Make sure Alt+x are detected properly. */ - for (i = '0'; i <= '9'; i++) { - char str[] = "\033X"; - str[1] = i; - gnt_keys_add_combination(str); - } - - 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 */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_BINDABLE, - "GntWM", - &info, 0); - } - - return type; -} - -void -gnt_wm_add_workspace(GntWM *wm, GntWS *ws) -{ - wm->workspaces = g_list_append(wm->workspaces, ws); -} - -gboolean -gnt_wm_switch_workspace(GntWM *wm, gint n) -{ - GntWS *s = g_list_nth_data(wm->workspaces, n); - if (!s) - return FALSE; - - if (wm->_list.window) { - gnt_widget_destroy(wm->_list.window); - } - ensure_normal_mode(wm); - gnt_ws_hide(wm->cws, wm->nodes); - wm->cws = s; - gnt_ws_show(wm->cws, wm->nodes); - - gnt_ws_draw_taskbar(wm->cws, TRUE); - update_screen(wm); - if (wm->cws->ordered) { - gnt_wm_raise_window(wm, wm->cws->ordered->data); - } - - if (act && g_list_find(act, wm->cws)) { - act = g_list_remove(act, wm->cws); - update_act_msg(); - } - return TRUE; -} - -gboolean -gnt_wm_switch_workspace_prev(GntWM *wm) -{ - int n = g_list_index(wm->workspaces, wm->cws); - return gnt_wm_switch_workspace(wm, --n); -} - -gboolean -gnt_wm_switch_workspace_next(GntWM *wm) -{ - int n = g_list_index(wm->workspaces, wm->cws); - return gnt_wm_switch_workspace(wm, ++n); -} - -static gboolean -workspace_next(GntBindable *wm, GList *n) -{ - return gnt_wm_switch_workspace_next(GNT_WM(wm)); -} - -static gboolean -workspace_prev(GntBindable *wm, GList *n) -{ - return gnt_wm_switch_workspace_prev(GNT_WM(wm)); -} - -void -gnt_wm_widget_move_workspace(GntWM *wm, GntWS *neww, GntWidget *widget) -{ - GntWS *oldw = gnt_wm_widget_find_workspace(wm, widget); - GntNode *node; - if (!oldw || oldw == neww) - return; - node = g_hash_table_lookup(wm->nodes, widget); - if (node && node->ws == neww) - return; - - if (node) - node->ws = neww; - - gnt_ws_remove_widget(oldw, widget); - gnt_ws_add_widget(neww, widget); - if (neww == wm->cws) { - gnt_ws_widget_show(widget, wm->nodes); - } else { - gnt_ws_widget_hide(widget, wm->nodes); - } -} - -static gint widget_in_workspace(gconstpointer workspace, gconstpointer wid) -{ - GntWS *s = (GntWS *)workspace; - if (s->list && g_list_find(s->list, wid)) - return 0; - return 1; -} - -GntWS *gnt_wm_widget_find_workspace(GntWM *wm, GntWidget *widget) -{ - GList *l = g_list_find_custom(wm->workspaces, widget, widget_in_workspace); - if (l) - return l->data; - return NULL; -} - -static void free_workspaces(gpointer data, gpointer n) -{ - GntWS *s = data; - g_free(s->name); -} - -void gnt_wm_set_workspaces(GntWM *wm, GList *workspaces) -{ - g_list_foreach(wm->workspaces, free_workspaces, NULL); - wm->workspaces = workspaces; - gnt_wm_switch_workspace(wm, 0); -} - -static void -update_window_in_list(GntWM *wm, GntWidget *wid) -{ - GntTextFormatFlags flag = 0; - - if (wm->windows == NULL) - return; - - if (wm->cws->ordered && wid == wm->cws->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 gboolean -match_title(gpointer title, gpointer n, gpointer wid_title) -{ - /* XXX: do any regex magic here. */ - if (g_strrstr((gchar *)wid_title, (gchar *)title)) - return TRUE; - return FALSE; -} - -#if !GLIB_CHECK_VERSION(2,4,0) -struct -{ - gpointer data; - gpointer value; -} table_find_data; - -static void -table_find_helper(gpointer key, gpointer value, gpointer data) -{ - GHRFunc func = data; - if (func(key, value, table_find_data.data)) - table_find_data.value = value; -} - -static gpointer -g_hash_table_find(GHashTable * table, GHRFunc func, gpointer data) -{ - table_find_data.data = data; - table_find_data.value = NULL; - g_hash_table_foreach(table, table_find_helper, func); - return table_find_data.value; -} -#endif - -static GntWS * -new_widget_find_workspace(GntWM *wm, GntWidget *widget) -{ - GntWS *ret = NULL; - const gchar *name, *title; - title = GNT_BOX(widget)->title; - if (title) - ret = g_hash_table_find(wm->title_places, match_title, (gpointer)title); - if (ret) - return ret; - name = gnt_widget_get_name(widget); - if (name) - ret = g_hash_table_find(wm->name_places, match_title, (gpointer)name); - return ret ? ret : wm->cws; -} - -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; - node->scroll = 0; - - g_hash_table_replace(wm->nodes, widget, node); - - refresh_node(widget, node, GINT_TO_POINTER(TRUE)); - - transient = !!GNT_WIDGET_IS_FLAG_SET(node->me, GNT_WIDGET_TRANSIENT); - -#if 1 - { - int x, y, w, h, maxx, maxy; - gboolean shadow = TRUE; - - if (!gnt_widget_has_shadow(widget)) - shadow = FALSE; - x = widget->priv.x; - y = widget->priv.y; - w = widget->priv.width + shadow; - h = widget->priv.height + shadow; - - maxx = getmaxx(stdscr); - maxy = getmaxy(stdscr) - 1; /* room for the taskbar */ - maxx = MAX(0, maxx); - maxy = MAX(0, maxy); - - x = MAX(0, x); - y = MAX(0, y); - if (x + w >= maxx) - x = MAX(0, maxx - w); - if (y + h >= maxy) - y = MAX(0, maxy - h); - - w = MIN(w, maxx); - h = MIN(h, maxy); - node->window = newwin(h, w, y, x); - gnt_wm_copy_win(widget, node); - } -#endif - - node->panel = new_panel(node->window); - set_panel_userptr(node->panel, node); - - if (!transient) { - GntWS *ws = wm->cws; - if (node->me != wm->_list.window) { - if (GNT_IS_BOX(widget)) { - ws = new_widget_find_workspace(wm, widget); - } - node->ws = ws; - ws->list = g_list_append(ws->list, widget); - ws->ordered = g_list_append(ws->ordered, widget); - } - - if (wm->event_stack || node->me == wm->_list.window || - node->me == ws->ordered->data) { - gnt_wm_raise_window(wm, node->me); - } else { - bottom_panel(node->panel); /* New windows should not grab focus */ - gnt_widget_set_focus(node->me, FALSE); - gnt_widget_set_urgent(node->me); - if (wm->cws != ws) - gnt_ws_widget_hide(widget, wm->nodes); - } - } -} - -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; - } - - if (GNT_IS_BOX(widget)) { - const char *title = GNT_BOX(widget)->title; - GntPosition *p = NULL; - if (title && (p = g_hash_table_lookup(wm->positions, title)) != NULL) { - sanitize_position(widget, &p->x, &p->y, TRUE); - gnt_widget_set_position(widget, p->x, p->y); - mvwin(widget->window, p->y, p->x); - } - } - - 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), - g_object_get_data(G_OBJECT(wm->windows->tree), "workspace") ? wm->cws : NULL); - update_window_in_list(wm, widget); - } - } - - gnt_ws_draw_taskbar(wm->cws, FALSE); - update_screen(wm); -} - -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) -{ - GntWS *s; - int pos; - gboolean transient = !!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT); - - s = gnt_wm_widget_find_workspace(wm, widget); - - if (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); - } - - if (s) { - pos = g_list_index(s->list, widget); - - if (pos != -1) { - s->list = g_list_remove(s->list, widget); - s->ordered = g_list_remove(s->ordered, widget); - - if (s->ordered && wm->cws == s) - gnt_wm_raise_window(wm, s->ordered->data); - } - } else if (transient && wm->cws && wm->cws->ordered) { - gnt_wm_update_window(wm, wm->cws->ordered->data); - } - - gnt_ws_draw_taskbar(wm->cws, FALSE); - update_screen(wm); -} - -time_t gnt_wm_get_idle_time() -{ - return time(NULL) - last_active_time; -} - -gboolean gnt_wm_process_input(GntWM *wm, const char *keys) -{ - gboolean ret = FALSE; - - keys = gnt_bindable_remap_keys(GNT_BINDABLE(wm), keys); - - idle_update = TRUE; - if(ignore_keys){ - if(keys && !strcmp(keys, "\033" GNT_KEY_CTRL_G)){ - if(gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)){ - return TRUE; - } - } - return wm->cws->ordered ? gnt_widget_key_pressed(GNT_WIDGET(wm->cws->ordered->data), keys) : FALSE; - } - - if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) { - return TRUE; - } - - /* Do some manual checking */ - if (wm->cws->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->cws->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, wm); - return TRUE; - } - } 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, wm); - return TRUE; - } - } - if (strcmp(keys, "\r") == 0 || strcmp(keys, "\033") == 0) { - window_reverse(widget, FALSE, wm); - wm->mode = GNT_KP_MODE_NORMAL; - } - return 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); - return TRUE; - } - } 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 TRUE; - } - - if (wm->menu) - ret = gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); - else if (wm->_list.window) - ret = gnt_widget_key_pressed(wm->_list.window, keys); - else if (wm->cws->ordered) { - GntWidget *win = wm->cws->ordered->data; - if (GNT_IS_WINDOW(win)) { - GntMenu *menu = GNT_WINDOW(win)->menu; - if (menu) { - const char *id = gnt_window_get_accel_item(GNT_WINDOW(win), keys); - if (id) { - GntMenuItem *item = gnt_menu_get_item(menu, id); - if (item) - ret = gnt_menuitem_activate(item); - } - } - } - if (!ret) - ret = gnt_widget_key_pressed(win, keys); - } - return ret; -} - -static void -gnt_wm_win_resized(GntWM *wm, GntNode *node) -{ - /*refresh_node(node->me, node, NULL);*/ -} - -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; - int maxx, maxy; - - 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); - - maxx = getmaxx(stdscr); - maxy = getmaxy(stdscr) - 1; - height = MIN(height, maxy); - width = MIN(width, maxx); - wresize(node->window, height, width); - replace_panel(node->panel, node->window); - - g_signal_emit(wm, signals[SIG_RESIZED], 0, node); - - show_panel(node->panel); - update_screen(wm); -} - -static void -write_gdi(gpointer key, gpointer value, gpointer data) -{ - GntPosition *p = value; - fprintf(data, ".%s = %d;%d\n", (char *)key, p->x, p->y); -} - -static gboolean -write_already(gpointer data) -{ - GntWM *wm = data; - FILE *file; - char *filename; - - filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); - - file = fopen(filename, "wb"); - if (file == NULL) { - gnt_warning("error opening file (%s) to save positions", filename); - } else { - fprintf(file, "[positions]\n"); - g_hash_table_foreach(wm->positions, write_gdi, file); - fclose(file); - } - - g_free(filename); - g_source_remove(write_timeout); - write_timeout = 0; - return FALSE; -} - -static void -write_positions_to_file(GntWM *wm) -{ - if (write_timeout) { - g_source_remove(write_timeout); - } - write_timeout = g_timeout_add_seconds(10, write_already, 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); - if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE) && GNT_IS_BOX(widget) && - !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { - const char *title = GNT_BOX(widget)->title; - if (title) { - GntPosition *p = g_new0(GntPosition, 1); - GntWidget *wid = node->me; - p->x = wid->priv.x; - p->y = wid->priv.y; - g_hash_table_replace(wm->positions, g_strdup(title), p); - write_positions_to_file(wm); - } - } - - 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->cws->ordered->data != widget) { - GntWidget *w = wm->cws->ordered->data; - wm->cws->ordered = g_list_bring_to_front(wm->cws->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); - } - gnt_ws_draw_taskbar(wm->cws, FALSE); - update_screen(wm); -} - -void gnt_wm_update_window(GntWM *wm, GntWidget *widget) -{ - GntNode *node = NULL; - GntWS *ws; - - while (widget->parent) - widget = widget->parent; - if (!GNT_IS_MENU(widget)) { - if (!GNT_IS_BOX(widget)) - return; - gnt_box_sync_children(GNT_BOX(widget)); - } - - ws = gnt_wm_widget_find_workspace(wm, 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); - - if (ws == wm->cws || GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { - gnt_wm_copy_win(widget, node); - gnt_ws_draw_taskbar(wm->cws, FALSE); - update_screen(wm); - } else if (ws && ws != wm->cws && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_URGENT)) { - if (!act || (act && !g_list_find(act, ws))) - act = g_list_prepend(act, ws); - update_act_msg(); - } -} - -gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget) -{ - gboolean ret = TRUE; - idle_update = 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) -{ - GntWS *ws = gnt_wm_widget_find_workspace(wm, widget); - if (wm->cws != ws) - gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, ws)); - if (widget != wm->cws->ordered->data) { - GntWidget *wid = wm->cws->ordered->data; - wm->cws->ordered = g_list_bring_to_front(wm->cws->ordered, widget); - gnt_widget_set_focus(wid, FALSE); - gnt_widget_draw(wid); - } - gnt_widget_set_focus(widget, TRUE); - gnt_widget_draw(widget); - g_signal_emit(wm, signals[SIG_GIVE_FOCUS], 0, widget); -} - -void gnt_wm_set_event_stack(GntWM *wm, gboolean set) -{ - wm->event_stack = set; -} - -
--- a/finch/libgnt/gntwm.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -/** - * @file gntwm.h Window-manager API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNTWM_H -#define GNTWM_H - -#include "gntwidget.h" -#include "gntmenu.h" -#include "gntws.h" - -#include <panel.h> -#include <time.h> - -#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 _GntKeyPressMode -{ - GNT_KP_MODE_NORMAL, - GNT_KP_MODE_RESIZE, - GNT_KP_MODE_MOVE, - GNT_KP_MODE_WAIT_ON_CHILD -} GntKeyPressMode; - -typedef struct _GntNode -{ - GntWidget *me; - - WINDOW *window; - int scroll; - PANEL *panel; - GntWS *ws; -} GntNode; - -typedef struct _GntWM GntWM; - -typedef struct _GntPosition -{ - int x; - int y; -} GntPosition; - -/** - * An application can register actions which will show up in a 'start-menu' like popup - */ -typedef struct _GntAction -{ - const char *label; - void (*callback)(void); -} GntAction; - -struct _GntWM -{ - GntBindable inherit; - - GMainLoop *loop; - - GList *workspaces; - GList *tagged; /* tagged windows */ - GntWS *cws; - - struct { - GntWidget *window; - GntWidget *tree; - } _list, - *windows, /* Window-list window */ - *actions; /* Action-list window */ - - GHashTable *nodes; /* GntWidget -> GntNode */ - GHashTable *name_places; /* window name -> ws*/ - GHashTable *title_places; /* window title -> ws */ - - 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; - - GHashTable *positions; - - void *res1; - void *res2; - void *res3; - void *res4; -}; - -typedef struct _GntWMClass GntWMClass; - -struct _GntWMClass -{ - 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)(GntWM *wm, GntWidget *win); - - /* The WM may want to confirm a size for a window first */ - gboolean (*window_resize_confirm)(GntWM *wm, GntWidget *win, int *w, int *h); - - void (*window_resized)(GntWM *wm, GntNode *node); - - /* The WM may want to confirm the position of a window */ - gboolean (*window_move_confirm)(GntWM *wm, GntWidget *win, int *x, int *y); - - 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)(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. - */ - gboolean (*key_pressed)(GntWM *wm, const char *key); - - 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)(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. - */ - /*GList *(*window_list)();*/ - - /* This is invoked whenever the terminal window is resized, or the - * screen session is attached to a new terminal. (ie, from the - * SIGWINCH callback) - */ - void (*terminal_refresh)(GntWM *wm); - - void (*res1)(void); - void (*res2)(void); - void (*res3)(void); -}; - -G_BEGIN_DECLS - -/** - * @return GType for GntWM. - */ -GType gnt_wm_get_gtype(void); - -/** - * Add a workspace. - * @param wm The window-manager. - * @param ws The workspace to add. - */ -void gnt_wm_add_workspace(GntWM *wm, GntWS *ws); - -/** - * Switch to a workspace. - * @param wm The window-manager. - * @param n Index of the workspace to switch to. - * - * @return @c TRUE if the switch was successful. - */ -gboolean gnt_wm_switch_workspace(GntWM *wm, gint n); - -/** - * Switch to the previous workspace from the current one. - * @param wm The window-manager. - */ -gboolean gnt_wm_switch_workspace_prev(GntWM *wm); - -/** - * Switch to the next workspace from the current one. - * @param wm The window-manager. - */ -gboolean gnt_wm_switch_workspace_next(GntWM *wm); - -/** - * Move a window to a specific workspace. - * @param wm The window manager. - * @param neww The new workspace. - * @param widget The widget to move. - */ -void gnt_wm_widget_move_workspace(GntWM *wm, GntWS *neww, GntWidget *widget); - -/** - * Set the list of workspaces . - * @param wm The window manager. - * @param workspaces The list of workspaces. - */ -void gnt_wm_set_workspaces(GntWM *wm, GList *workspaces); - -/** - * Find the workspace that contains a specific widget. - * @param wm The window-manager. - * @param widget The widget to find. - * @return The workspace that has the widget. - */ -GntWS *gnt_wm_widget_find_workspace(GntWM *wm, GntWidget *widget); - -/** - * Process a new window. - * - * @param wm The window-manager. - * @param widget The new window. - */ -void gnt_wm_new_window(GntWM *wm, GntWidget *widget); - -/** - * Decorate a window. - * @param wm The window-manager. - * @param widget The widget to decorate. - */ -void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget); - -/** - * Close a window. - * @param wm The window-manager. - * @param widget The window to close. - */ -void gnt_wm_window_close(GntWM *wm, GntWidget *widget); - -/** - * Process input. - * - * @param wm The window-manager. - * @param string The input string to process. - * - * @return @c TRUE of the string was processed, @c FALSE otherwise. - */ -gboolean gnt_wm_process_input(GntWM *wm, const char *string); - -/** - * Process a click event. - * @param wm The window manager. - * @param event The mouse event. - * @param x The x-coordinate of the mouse. - * @param y The y-coordinate of the mouse. - * @param widget The widget under the mouse. - * - * @return @c TRUE if the event was handled, @c FALSE otherwise. - */ -gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget); - -/** - * Resize a window. - * @param wm The window manager. - * @param widget The window to resize. - * @param width The desired width of the window. - * @param height The desired height of the window. - */ -void gnt_wm_resize_window(GntWM *wm, GntWidget *widget, int width, int height); - -/** - * Move a window. - * @param wm The window manager. - * @param widget The window to move. - * @param x The desired x-coordinate of the window. - * @param y The desired y-coordinate of the window. - */ -void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y); - -/** - * Update a window. - * @param wm The window-manager. - * @param widget The window to update. - */ -void gnt_wm_update_window(GntWM *wm, GntWidget *widget); - -/** - * Raise a window. - * @param wm The window-manager. - * @param widget The window to raise. - */ -void gnt_wm_raise_window(GntWM *wm, GntWidget *widget); - -/** - * @internal - */ -void gnt_wm_set_event_stack(GntWM *wm, gboolean set); - -/** - * @internal - */ -void gnt_wm_copy_win(GntWidget *widget, GntNode *node); - -/** - * @return The idle time of the user. - */ -time_t gnt_wm_get_idle_time(void); - -G_END_DECLS -#endif
--- a/finch/libgnt/gntws.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#include <gmodule.h> - -#include "gntinternal.h" -#include "gntbox.h" -#include "gntwidget.h" -#include "gntwindow.h" -#include "gntwm.h" -#include "gntws.h" - -static void -widget_hide(gpointer data, gpointer nodes) -{ - GntWidget *widget = GNT_WIDGET(data); - GntNode *node = g_hash_table_lookup(nodes, widget); - if (GNT_IS_WINDOW(widget)) - gnt_window_workspace_hiding(GNT_WINDOW(widget)); - if (node) - hide_panel(node->panel); -} - -static void -widget_show(gpointer data, gpointer nodes) -{ - GntNode *node = g_hash_table_lookup(nodes, data); - GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(data), GNT_WIDGET_INVISIBLE); - if (node) { - show_panel(node->panel); - gnt_wm_copy_win(GNT_WIDGET(data), node); - } -} - -void -gnt_ws_draw_taskbar(GntWS *ws, gboolean reposition) -{ - static WINDOW *taskbar = NULL; - GList *iter; - int n, width = 0; - int i; - - if (gnt_is_refugee()) - return; - - g_return_if_fail(ws != NULL); - - 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' | gnt_color_pair(GNT_COLOR_NORMAL)); - werase(taskbar); - - n = g_list_length(ws->list); - if (n) - width = getmaxx(stdscr) / n; - - for (i = 0, iter = ws->list; iter; iter = iter->next, i++) { - GntWidget *w = iter->data; - int color; - const char *title; - - if (w == ws->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' | gnt_color_pair(color)); - if (iter->next) - mvwhline(taskbar, 0, width * i, ' ' | gnt_color_pair(color), width); - else - mvwhline(taskbar, 0, width * i, ' ' | gnt_color_pair(color), getmaxx(stdscr) - width * i); - title = GNT_BOX(w)->title; - mvwprintw(taskbar, 0, width * i, "%s", title ? C_(title) : "<gnt>"); - if (i) - mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | gnt_color_pair(GNT_COLOR_NORMAL)); - } - wrefresh(taskbar); -} - -static void -gnt_ws_init(GTypeInstance *instance, gpointer class) -{ - GntWS *ws = GNT_WS(instance); - ws->list = NULL; - ws->ordered = NULL; - ws->name = NULL; -} - -void gnt_ws_add_widget(GntWS *ws, GntWidget* wid) -{ - GntWidget *oldfocus; - oldfocus = ws->ordered ? ws->ordered->data : NULL; - ws->list = g_list_append(ws->list, wid); - ws->ordered = g_list_prepend(ws->ordered, wid); - if (oldfocus) - gnt_widget_set_focus(oldfocus, FALSE); -} - -void gnt_ws_remove_widget(GntWS *ws, GntWidget* wid) -{ - ws->list = g_list_remove(ws->list, wid); - ws->ordered = g_list_remove(ws->ordered, wid); -} - -void -gnt_ws_set_name(GntWS *ws, const gchar *name) -{ - g_free(ws->name); - ws->name = g_strdup(name); -} - -void -gnt_ws_hide(GntWS *ws, GHashTable *nodes) -{ - g_list_foreach(ws->ordered, widget_hide, nodes); -} - -void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes) -{ - widget_hide(widget, nodes); -} - -void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes) -{ - widget_show(widget, nodes); -} - -void -gnt_ws_show(GntWS *ws, GHashTable *nodes) -{ - GList *l; - for (l = g_list_last(ws->ordered); l; l = g_list_previous(l)) - widget_show(l->data, nodes); -} - -GType -gnt_ws_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) { - static const GTypeInfo info = { - sizeof(GntWSClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, - /*(GClassInitFunc)gnt_ws_class_init,*/ - NULL, - NULL, /* class_data */ - sizeof(GntWS), - 0, /* n_preallocs */ - gnt_ws_init, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static(GNT_TYPE_BINDABLE, - "GntWS", - &info, 0); - } - - return type; -} - -GntWS *gnt_ws_new(const char *name) -{ - GntWS *ws = GNT_WS(g_object_new(GNT_TYPE_WS, NULL)); - ws->name = g_strdup(name ? name : "(noname)"); - return ws; -} - -const char * gnt_ws_get_name(GntWS *ws) -{ - return ws->name; -} -
--- a/finch/libgnt/gntws.h Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,180 +0,0 @@ -/** - * @file gntws.h Workspace API - * @ingroup gnt - */ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -#ifndef GNTWS_H -#define GNTWS_H - -#include "gntwidget.h" - -#include <panel.h> - -#define GNT_TYPE_WS (gnt_ws_get_gtype()) -#define GNT_WS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WS, GntWS)) -#define GNT_IS_WS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WS)) -#define GNT_IS_WS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WS)) -#define GNT_WS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WS, GntWSClass)) - -typedef struct _GntWS GntWS; - -struct _GntWS -{ - GntBindable inherit; - char *name; - GList *list; - GList *ordered; - gpointer ui_data; - - void *res1; - void *res2; - void *res3; - void *res4; -}; - -typedef struct _GntWSClass GntWSClass; - -struct _GntWSClass -{ - GntBindableClass parent; - - void (*draw_taskbar)(GntWS *ws, gboolean ); - - void (*res1)(void); - void (*res2)(void); - void (*res3)(void); - void (*res4)(void); -}; - -G_BEGIN_DECLS - -/** - * @return The GType for GntWS. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -GType gnt_ws_get_gtype(void); - -/** - * Create a new workspace with the specified name. - * - * @param name The desired name of the workspace, or @c NULL. - * - * @return The newly created workspace. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -GntWS *gnt_ws_new(const char *name); - -/** - * Set the name of a workspace. - * - * @param ws The workspace to rename. - * @param name The new name of the workspace. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_set_name(GntWS *ws, const gchar *name); - -/** - * Add a widget to a workspace. - * - * @param ws The workspace. - * @param widget The widget to add. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_add_widget(GntWS *ws, GntWidget *widget); - -/** - * Remove a widget from a workspace. - * - * @param ws The workspace - * @param widget The widget to remove from the workspace. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_remove_widget(GntWS *ws, GntWidget *widget); - -/** - * Hide a widget in a workspace. - * - * @param widget The widget to hide. - * @param nodes A hashtable containing information about the widgets. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes); - -/** - * Show a widget in a workspace. - * - * @param widget The widget to show. - * @param nodes A hashtable containing information about the widgets. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes); - -/** - * Draw the taskbar in a workspace. - * - * @param ws The workspace. - * @param reposition Whether the workspace should reposition the taskbar. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_draw_taskbar(GntWS *ws, gboolean reposition); - -/** - * Hide a workspace. - * - * @param ws The workspace to hide. - * @param table A hashtable containing information about the widgets. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_hide(GntWS *ws, GHashTable *table); - -/** - * Show a workspace. - * - * @param ws The workspace to hide. - * @param table A hashtable containing information about the widgets. - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -void gnt_ws_show(GntWS *ws, GHashTable *table); - -/** - * Get the name of a workspace. - * - * @param ws The workspace. - * @return The name of the workspace (can be @c NULL). - * - * @since 2.0.0 (gnt), 2.1.0 (pidgin) - */ -const char * gnt_ws_get_name(GntWS *ws); - -#endif
--- a/finch/libgnt/test.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -#include "gntbutton.h" -#include "gnt.h" -#include "gntkeys.h" -#include "gnttree.h" -#include "gntbox.h" - -static gboolean -key_pressed(GntWidget *widget, const char *text, gpointer null) -{ - GntWidget *w = null; - GntWidget *box = gnt_box_new(FALSE, FALSE); - GntWidget *label = gnt_label_new("so wassup!!"); - - gnt_box_add_widget(GNT_BOX(box), label); - GNT_WIDGET_UNSET_FLAGS(box, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - gnt_box_set_title(GNT_BOX(box), "This is a test"); - - gnt_widget_show(box); -#if 0 - - gnt_widget_set_focus(w, TRUE); - - /* XXX: This is to just test stuff */ - if (text[0] == 27) - { - if (strcmp(text+1, GNT_KEY_LEFT) == 0 && w->priv.x) - (w->priv.x)--; - else if (strcmp(text+1, GNT_KEY_RIGHT) == 0) - (w->priv.x)++; - else if (strcmp(text+1, GNT_KEY_UP) == 0 && w->priv.y) - (w->priv.y)--; - else if (strcmp(text+1, GNT_KEY_DOWN) == 0) - (w->priv.y)++; - } - - gnt_widget_draw(w); -#endif - - return FALSE; -} - -static void -button1(GntWidget *widget, gpointer null) -{ - printf("OLAAA"); - gnt_widget_destroy(null); -} - -static void -button2(GntWidget *widget, gpointer null) -{ - printf("BOOYAA"); -} - -static gboolean -w_scroll(GntWidget *tree) -{ - g_return_val_if_fail(GNT_IS_TREE(tree), FALSE); - gnt_tree_scroll(GNT_TREE(tree), 1); - /*wscrl(tree->window, 1);*/ - /*box(tree->window, ACS_VLINE, ACS_HLINE);*/ - /*wrefresh(tree->window);*/ - /*char *s = 0;*/ - /**s = 'a';*/ - return TRUE; -} - -int main() -{ - gnt_init(); - - GntWidget *widget = gnt_button_new("Button 1"); - GntWidget *widget2 = gnt_button_new("Button 2 has a longish text with a UTF-8 thing …"); - GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\nSo this is, like,\nthe third line!! \\o/"); - GntWidget *vbox, *hbox, *tree; - WINDOW *test; - - box(stdscr, 0, 0); - wrefresh(stdscr); - - vbox = gnt_box_new(FALSE, FALSE); - hbox = gnt_box_new(FALSE, TRUE); - - gnt_widget_set_name(vbox, "vbox"); - gnt_widget_set_name(hbox, "hbox"); - gnt_widget_set_name(widget, "widget"); - gnt_widget_set_name(widget2, "widget2"); - - gnt_box_add_widget(GNT_BOX(vbox), widget); - gnt_box_add_widget(GNT_BOX(vbox), widget2); - - gnt_box_add_widget(GNT_BOX(hbox), label); - /*gnt_box_add_widget(GNT_BOX(hbox), vbox);*/ - - gnt_box_add_widget(GNT_BOX(hbox), gnt_entry_new("a")); - - tree = gnt_tree_new(); - gnt_box_add_widget(GNT_BOX(hbox), tree); - - gnt_tree_add_row_after(GNT_TREE(tree), "a", "a", NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "c", "c", NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "d", "d", NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "e", "e", "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "b", "b", "d", NULL); - - GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - gnt_box_set_title(GNT_BOX(hbox), "111111111111111111111111111111111111111111111111111111111111111This is the title …"); - - /*gnt_widget_set_take_focus(vbox, TRUE);*/ - /*gnt_widget_set_take_focus(hbox, TRUE);*/ - /*gnt_widget_set_position(hbox, 10, 10);*/ - - gnt_widget_show(hbox); - - g_signal_connect(hbox, "key_pressed", G_CALLBACK(key_pressed), tree); - g_signal_connect(widget, "activate", G_CALLBACK(button1), hbox); - g_signal_connect(widget2, "activate", G_CALLBACK(button2), hbox); - - /*g_timeout_add(1000, (GSourceFunc)w_scroll, tree);*/ - - gnt_main(); - - return 0; -} -
--- a/finch/libgnt/test/Makefile Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -CC=gcc -CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE -I/usr/include/ncursesw/ -LDFLAGS=`pkg-config --libs gobject-2.0 gmodule-2.0 gnt` -pg - -EXAMPLES=combo focus tv multiwin keys menu parse - -all: - make examples - -clean: - rm -f $(EXAMPLES) *.so wm - -WM: wm - for i in $(EXAMPLES); do gcc -shared $(CFLAGS) -USTANDALONE $(LDFLAGS) $${i}.c -o $${i}.so ; done - -examples: $(EXAMPLES)
--- a/finch/libgnt/test/combo.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -#include <gnt.h> -#include <gntbox.h> -#include <gntbutton.h> -#include <gntcheckbox.h> -#include <gntcombobox.h> -#include <gntentry.h> -#include <gntlabel.h> -#include <gntslider.h> - -static void -button_activated(GntWidget *b, GntComboBox *combo) -{ - GntWidget *w = b->parent; - - gnt_box_add_widget(GNT_BOX(w), - gnt_label_new(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)))); - fprintf(stderr, "%s\n", gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))); - gnt_box_readjust(GNT_BOX(w->parent)); -} - -static void -update_label(GntSlider *slider, int current_value, GntEntry *entry) -{ - char value[256]; - g_snprintf(value, sizeof(value), "%d/%d", current_value, slider->max); - /*gnt_label_set_text(label, value);*/ - /*gnt_widget_draw(GNT_WIDGET(label));*/ - gnt_entry_set_text(entry, value); -} - -int main() -{ - GntWidget *box, *combo, *button; - GntWidget *hbox; - -#ifdef STANDALONE - freopen(".error", "w", stderr); - gnt_init(); -#endif - - box = gnt_box_new(FALSE, TRUE); - gnt_widget_set_name(box, "box"); - gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID); - gnt_box_set_pad(GNT_BOX(box), 0); - - gnt_box_set_toplevel(GNT_BOX(box), TRUE); - gnt_box_set_title(GNT_BOX(box), "Checkbox"); - - hbox = gnt_box_new(FALSE, FALSE); - gnt_box_set_pad(GNT_BOX(hbox), 0); - gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); - gnt_widget_set_name(hbox, "upper"); - - combo = gnt_combo_box_new(); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "1", "1"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "2", "2"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "3", "3abcdefghijklmnopqrstuvwxyz"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "4", "4"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "5", "5"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "6", "6"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "7", "7"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "8", "8"); - gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "9", "9"); - - GntWidget *l = gnt_label_new("Select"); - gnt_box_add_widget(GNT_BOX(hbox), l); - gnt_widget_set_size(l, 0, 1); - gnt_box_add_widget(GNT_BOX(hbox), combo); - - gnt_box_add_widget(GNT_BOX(box), hbox); - - hbox = gnt_box_new(TRUE, FALSE); - gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); - gnt_widget_set_name(hbox, "lower"); - - button = gnt_button_new("OK"); - gnt_box_add_widget(GNT_BOX(hbox), button); - g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(button_activated), combo); - - gnt_box_add_widget(GNT_BOX(box), hbox); - - gnt_box_add_widget(GNT_BOX(box), gnt_check_box_new("check box")); - - GntWidget *e = gnt_entry_new(NULL); - gnt_box_add_widget(GNT_BOX(box), e); - - GntWidget *slider = gnt_slider_new(TRUE, 0, 100); - gnt_slider_set_value(GNT_SLIDER(slider), 50); - gnt_box_add_widget(GNT_BOX(box), slider); - g_signal_connect(G_OBJECT(slider), "changed", G_CALLBACK(update_label), e); - gnt_slider_reflect_label(GNT_SLIDER(slider), GNT_LABEL(l)); - - gnt_widget_show(box); - - gnt_widget_show(gnt_file_sel_new()); - -#ifdef STANDALONE - gnt_main(); - - gnt_quit(); -#endif - - return 0; -} -
--- a/finch/libgnt/test/file.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#include "gnt.h" -#include "gntfilesel.h" - -static void -file_selected(GntFileSel *sel, const char *path, const char *filename) -{ - g_printerr("%s %s\n", path, filename); -} - -int main() -{ - freopen(".error", "w", stderr); - fprintf(stdout, "\x1b]1;\x07\x1b]2;TEST\x07"); - gnt_init(); - - GntWidget *w = gnt_file_sel_new(); - gnt_file_sel_set_current_location(GNT_FILE_SEL(w), "/home/"); - gnt_file_sel_set_dirs_only(GNT_FILE_SEL(w), TRUE); - gnt_file_sel_set_multi_select(GNT_FILE_SEL(w), TRUE); - gnt_widget_show(w); - - g_signal_connect(G_OBJECT(w), "file_selected", G_CALLBACK(file_selected), NULL); - - gnt_main(); - - gnt_quit(); - return 0; -} -
--- a/finch/libgnt/test/focus.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -#include "gntbutton.h" -#include "gnt.h" -#include "gntkeys.h" -#include "gnttree.h" -#include "gntbox.h" -#include "gntentry.h" -#include "gntlabel.h" - -static void -toggled(GntWidget *tree, gpointer key, gpointer null) -{ - GntWidget *w = gnt_box_new(FALSE, FALSE); - - gnt_box_set_toplevel(GNT_BOX(w), TRUE); - - gnt_box_add_widget(GNT_BOX(w), - gnt_label_new(gnt_tree_get_choice(GNT_TREE(tree), key) ? "Selected" : "NOT")); - gnt_widget_show(w); -} - -int main() -{ -#ifdef STANDALONE - freopen(".error", "w", stderr); - gnt_init(); -#endif - - GntWidget *label = gnt_label_new("So wassup dudes and dudettes!!\u4e0a1\u6d772\u67003\u4f4e4\u67085\nSo this is, like,\nthe third line!! \\o/"); - GntWidget *vbox, *hbox, *tree, *box, *button; - WINDOW *test; - - vbox = gnt_box_new(FALSE, FALSE); - hbox = gnt_box_new(FALSE, TRUE); - gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); - - gnt_widget_set_name(vbox, "vbox"); - gnt_widget_set_name(hbox, "hbox"); - - gnt_box_add_widget(GNT_BOX(hbox), label); - - GntWidget *entry = gnt_entry_new("a"); - gnt_widget_set_name(entry, "entry"); - gnt_box_add_widget(GNT_BOX(hbox), entry); - - box = gnt_box_new(FALSE, FALSE); - tree = gnt_tree_new(); - gnt_tree_set_compare_func(GNT_TREE(tree), g_utf8_collate); - gnt_widget_set_name(tree, "tree"); - gnt_box_add_widget(GNT_BOX(box), tree); - gnt_box_add_widget(GNT_BOX(hbox), box); - - gnt_tree_add_row_after(GNT_TREE(tree), "c", gnt_tree_create_row(GNT_TREE(tree), "c"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "a", gnt_tree_create_row(GNT_TREE(tree), "a"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "z", gnt_tree_create_row(GNT_TREE(tree), "z"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "y", gnt_tree_create_row(GNT_TREE(tree), "y"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "g", gnt_tree_create_row(GNT_TREE(tree), "g"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "x", gnt_tree_create_row(GNT_TREE(tree), "x"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "k", gnt_tree_create_row(GNT_TREE(tree), "k"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e"), "a", NULL); - gnt_tree_add_choice(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b"), "d", NULL); - - GNT_WIDGET_UNSET_FLAGS(hbox, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); - gnt_box_set_title(GNT_BOX(hbox), "\u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 \u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 ……\u4e0a\u6d77\u6700\u4f4e\u6708\u5de5 …"); - - g_signal_connect(G_OBJECT(tree), "toggled", G_CALLBACK(toggled), NULL); - - button = gnt_button_new("one"); - gnt_widget_set_name(button, "one"); - gnt_box_add_widget(GNT_BOX(vbox), button); - - button = gnt_button_new("two"); - gnt_widget_set_name(button, "two"); - gnt_box_add_widget(GNT_BOX(vbox), button); - - button = gnt_button_new("three"); - gnt_widget_set_name(button, "three"); - gnt_box_add_widget(GNT_BOX(vbox), button); - - gnt_box_add_widget(GNT_BOX(hbox), vbox); - - gnt_widget_show(hbox); - -#ifdef STANDALONE - gnt_main(); - - gnt_quit(); -#endif - - return 0; -} -
--- a/finch/libgnt/test/key.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -#include <ncurses.h> - -int main() -{ - int ch; - - initscr(); - noecho(); - cbreak(); - refresh(); - - WINDOW *win = newpad(20, 30); - box(win, 0, 0); - prefresh(win, 0, 0, 0, 0, 19, 29); - doupdate(); - - while ((ch = getch())) { - printw("%d ", ch); - refresh(); - } - - endwin(); - return 0; -} -
--- a/finch/libgnt/test/keys.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -#include <gnt.h> -#include <gntbox.h> -#include <gntentry.h> -#include <gntlabel.h> - -static gboolean -print_keycode(GntEntry *entry, const char *text, gpointer null) -{ - char *s = g_strdup_printf("%s ", text); - gnt_entry_set_text(entry, s); - g_free(s); - if (text[0] == 27) - { - if (strncmp(text + 1, "[M ", 3) == 0) - { - int x = (unsigned)text[4]; - int y = (unsigned)text[5]; - if (x < 0) x += 256; - if (y < 0) y += 256; - x -= 33; - y -= 33; - s = g_strdup_printf("ldown %d %d", x, y); - gnt_entry_set_text(entry, s); - g_free(s); - } - else if (strncmp(text + 1, "[M#", 3) == 0) - gnt_entry_set_text(entry, "up"); - else - return FALSE; - return TRUE; - } - else - return TRUE; -} - -int main() -{ - GntWidget *window, *entry; - - gnt_init(); - - freopen(".error", "w", stderr); - - window = gnt_hbox_new(FALSE); - gnt_box_set_toplevel(GNT_BOX(window), TRUE); - - gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Press any key: ")); - - entry = gnt_entry_new(NULL); - gnt_box_add_widget(GNT_BOX(window), entry); - g_signal_connect(G_OBJECT(entry), "key_pressed", G_CALLBACK(print_keycode), NULL); - - gnt_widget_set_position(window, getmaxx(stdscr) / 2 - 12, getmaxy(stdscr) / 2 - 3); - gnt_widget_show(window); - - gnt_main(); - gnt_quit(); - return 0; -} -
--- a/finch/libgnt/test/menu.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -#include "gnt.h" -#include "gntbox.h" -#include "gntlabel.h" -#include "gntmenu.h" -#include "gntmenuitem.h" -#include "gntwindow.h" - -void dothis(GntMenuItem *item, gpointer null) -{ - GntWidget *w = gnt_vbox_new(FALSE); - gnt_box_set_toplevel(GNT_BOX(w), TRUE); - gnt_box_add_widget(GNT_BOX(w), - gnt_label_new("Callback to a menuitem")); - gnt_widget_show(w); -} - -int main() -{ - freopen(".error", "w", stderr); - gnt_init(); - - GntWidget *menu = gnt_menu_new(GNT_MENU_TOPLEVEL); - GObject *item = gnt_menuitem_new("File"); - - gnt_menu_add_item(GNT_MENU(menu), GNT_MENU_ITEM(item)); - - item = gnt_menuitem_new("Edit"); - gnt_menu_add_item(GNT_MENU(menu), GNT_MENU_ITEM(item)); - - item = gnt_menuitem_new("Help"); - gnt_menu_add_item(GNT_MENU(menu), GNT_MENU_ITEM(item)); - - GntWidget *sub = gnt_menu_new(GNT_MENU_POPUP); - gnt_menuitem_set_submenu(GNT_MENU_ITEM(item), GNT_MENU(sub)); - - item = gnt_menuitem_new("Online Helpasd"); - gnt_menuitem_set_trigger(GNT_MENU_ITEM(item), 'h'); - gnt_menu_add_item(GNT_MENU(sub), GNT_MENU_ITEM(item)); - - item = gnt_menuitem_new("Online Help"); - gnt_menuitem_set_trigger(GNT_MENU_ITEM(item), 'h'); - gnt_menu_add_item(GNT_MENU(sub), GNT_MENU_ITEM(item)); - - item = gnt_menuitem_new("About"); - gnt_menuitem_set_trigger(GNT_MENU_ITEM(item), 'a'); - gnt_menu_add_item(GNT_MENU(sub), GNT_MENU_ITEM(item)); - - sub = gnt_menu_new(GNT_MENU_POPUP); - gnt_menuitem_set_submenu(GNT_MENU_ITEM(item), GNT_MENU(sub)); - - item = gnt_menuitem_new("Online Help"); - gnt_menuitem_set_trigger(GNT_MENU_ITEM(item), 'O'); - gnt_menu_add_item(GNT_MENU(sub), GNT_MENU_ITEM(item)); - gnt_menuitem_set_callback(GNT_MENU_ITEM(item), dothis, NULL); - - gnt_screen_menu_show(menu); - - GntWidget *win = gnt_window_new(); - gnt_box_add_widget(GNT_BOX(win), - gnt_label_new("...")); - gnt_box_set_title(GNT_BOX(win), "Title"); - gnt_window_set_menu(GNT_WINDOW(win), GNT_MENU(menu)); - gnt_widget_show(win); - - gnt_main(); - - gnt_quit(); - - return 0; -} -
--- a/finch/libgnt/test/multiwin.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -#include "gnt.h" -#include "gntbutton.h" -#include "gntentry.h" -#include "gntkeys.h" -#include "gntlabel.h" -#include "gnttree.h" -#include "gntbox.h" - -gboolean show(GntWidget *w) -{ - return FALSE; -} - -int main() -{ -#ifdef STANDALONE - freopen(".error", "w", stderr); - gnt_init(); -#endif - - GntWidget *hbox, *tree, *box2; - - hbox = gnt_box_new(FALSE, TRUE); - box2 = gnt_box_new(FALSE, TRUE); - - gnt_widget_set_name(hbox, "hbox"); - gnt_widget_set_name(box2, "box2"); - - tree = gnt_tree_new_with_columns(3); - gnt_tree_set_search_column(GNT_TREE(tree), 1); - GNT_WIDGET_SET_FLAGS(tree, GNT_WIDGET_NO_BORDER); - gnt_tree_set_column_titles(GNT_TREE(tree), "12345678901234567890", "column 2", "column3"); - gnt_tree_set_show_title(GNT_TREE(tree), TRUE); - gnt_widget_set_name(tree, "tree"); - gnt_box_add_widget(GNT_BOX(hbox), tree); - - gnt_box_set_toplevel(GNT_BOX(hbox), TRUE); - gnt_box_set_title(GNT_BOX(hbox), "Testing the tree widget"); - - gnt_box_set_toplevel(GNT_BOX(box2), TRUE); - gnt_box_set_title(GNT_BOX(box2), "On top"); - - gnt_box_add_widget(GNT_BOX(box2), gnt_label_new("asdasd")); - gnt_box_add_widget(GNT_BOX(box2), gnt_entry_new(NULL)); - - gnt_widget_show(hbox); - gnt_widget_set_position(box2, 80, 40); - gnt_widget_show(box2); - - gnt_tree_add_row_after(GNT_TREE(tree), "a", - gnt_tree_create_row(GNT_TREE(tree), "alaskdjfkashfashfah kfalkdhflsiafhlasf", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "c", - gnt_tree_create_row(GNT_TREE(tree), "casdgertqhyeqgasfeytwfga fg arf agfwa ", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e", " long text", "a2"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b", "this is", "a2"), "d", NULL); - - gnt_tree_add_choice(GNT_TREE(tree), "1", gnt_tree_create_row(GNT_TREE(tree), "1", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "2", gnt_tree_create_row(GNT_TREE(tree), "2", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "3", gnt_tree_create_row(GNT_TREE(tree), "3", " long text", "a2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "4", gnt_tree_create_row(GNT_TREE(tree), "4", " long text", "a2"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "5", gnt_tree_create_row(GNT_TREE(tree), "5", " long text", "a2"), "d", NULL); - - gnt_tree_add_row_after(GNT_TREE(tree), "6", gnt_tree_create_row(GNT_TREE(tree), "6", " long text", "a2"), "4", NULL); - - int i; - for (i = 110; i < 430; i++) - { - char *s; - s = g_strdup_printf("%d", i); /* XXX: yes, leaking */ - gnt_tree_add_row_after(GNT_TREE(tree), s, gnt_tree_create_row(GNT_TREE(tree), s, " long text", "a2"), "4", NULL); - } - - gnt_tree_set_row_flags(GNT_TREE(tree), "e", GNT_TEXT_FLAG_DIM); - - gnt_tree_set_selected(GNT_TREE(tree), "2"); - - g_timeout_add(5000, (GSourceFunc)show, box2); - -#ifdef STANDALONE - gnt_main(); - - gnt_quit(); -#endif - - return 0; -} -
--- a/finch/libgnt/test/parse.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -#include "gntutils.h" - -int main() -{ - GntWidget *win, *button; - - gnt_init(); - - gnt_util_parse_widgets("<vwindow id='0' fill='0' align='2'><label>This is a test.</label><button id='1'>OK</button></vwindow>", 2, &win, &button); - g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win); - gnt_widget_show(win); - - gnt_main(); - - gnt_quit(); - return 0; -} -
--- a/finch/libgnt/test/tv.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -#include "gntbutton.h" -#include "gnt.h" -#include "gntkeys.h" -#include "gnttree.h" -#include "gntbox.h" -#include "gntentry.h" -#include "gnttextview.h" -#include "gntutils.h" - -static gboolean -key_pressed(GntWidget *w, const char *key, GntWidget *view) -{ - if (key[0] == '\r' && key[1] == 0) - { - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), - gnt_entry_get_text(GNT_ENTRY(w)), - GNT_TEXT_FLAG_UNDERLINE | GNT_TEXT_FLAG_HIGHLIGHT); - gnt_entry_add_to_history(GNT_ENTRY(w), gnt_entry_get_text(GNT_ENTRY(w))); - gnt_text_view_next_line(GNT_TEXT_VIEW(view)); - gnt_entry_clear(GNT_ENTRY(w)); - if (gnt_text_view_get_lines_below(GNT_TEXT_VIEW(view)) <= 1) - gnt_text_view_scroll(GNT_TEXT_VIEW(view), 0); - gnt_entry_remove_suggest(GNT_ENTRY(w), "acb"); - - return TRUE; - } - else if (strcmp(key, "\033" "e") == 0) - { - if (fork() == 0) { - endwin(); - printf("%s\n", GNT_TEXT_VIEW(view)->string->str); - fflush(stdout); - getch(); - refresh(); - exit(0); - } - } - else if (key[0] == 27) - { - if (strcmp(key, GNT_KEY_UP) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(view), -1); - else if (strcmp(key, GNT_KEY_DOWN) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(view), 1); - else - return FALSE; - return TRUE; - } - - return FALSE; -} - -static void -completion_cb(GntEntry *entry, const char *start, const char *end) -{ - if (start == entry->start) - gnt_widget_key_pressed(GNT_WIDGET(entry), ": "); -} - -int main() -{ - GntWidget *hbox, *entry, *view; - -#ifdef STANDALONE - freopen(".error", "w", stderr); - - gnt_init(); -#endif - - hbox = gnt_box_new(FALSE, TRUE); - gnt_widget_set_name(hbox, "hbox"); - gnt_box_set_toplevel(GNT_BOX(hbox), TRUE); - gnt_box_set_fill(GNT_BOX(hbox), FALSE); - gnt_box_set_title(GNT_BOX(hbox), "Textview test"); - gnt_box_set_alignment(GNT_BOX(hbox), GNT_ALIGN_MID); - - entry = gnt_entry_new(NULL); - gnt_widget_set_name(entry, "entry"); - GNT_WIDGET_SET_FLAGS(entry, GNT_WIDGET_CAN_TAKE_FOCUS); - - g_signal_connect(G_OBJECT(entry), "completion", G_CALLBACK(completion_cb), NULL); - - gnt_entry_set_word_suggest(GNT_ENTRY(entry), TRUE); - gnt_entry_set_always_suggest(GNT_ENTRY(entry), FALSE); - gnt_entry_add_suggest(GNT_ENTRY(entry), "a"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "ab"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "abe"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "abc"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "abcde"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "abcd"); - gnt_entry_add_suggest(GNT_ENTRY(entry), "acb"); - - view = gnt_text_view_new(); - gnt_widget_set_name(view, "view"); - - gnt_widget_set_size(view, 20, 15); - gnt_widget_set_size(entry, 20, 1); - - gnt_box_add_widget(GNT_BOX(hbox), view); - gnt_box_add_widget(GNT_BOX(hbox), entry); - gnt_box_add_widget(GNT_BOX(hbox), gnt_button_new("OK")); - - gnt_widget_show(hbox); - - gnt_entry_set_history_length(GNT_ENTRY(entry), -1); - gnt_text_view_attach_pager_widget(GNT_TEXT_VIEW(view), entry); - g_signal_connect_after(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), view); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "\n", GNT_TEXT_FLAG_NORMAL); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 1st line\n", GNT_TEXT_FLAG_NORMAL); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 2nd line\n", GNT_TEXT_FLAG_NORMAL); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 3rd line\n", GNT_TEXT_FLAG_NORMAL | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); - - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "plugins: ", GNT_TEXT_FLAG_BOLD); - gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(view), "this is the 4th line\n", GNT_TEXT_FLAG_NORMAL); - - gnt_util_parse_xhtml_to_textview("<p><b>Ohoy hoy!!</b><br/><p>I think this is going to</p> <u> WORK!!! </u><a href='www.google.com'>check this out!!</a></p>", GNT_TEXT_VIEW(view)); - -#ifdef STANDALONE - gnt_main(); - - gnt_quit(); -#endif - - return 0; -} -
--- a/finch/libgnt/test/wm.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -#include <gmodule.h> - -#include <gnt.h> -#include <gntbox.h> -#include <gntentry.h> -#include <gntlabel.h> - -static gboolean -key_pressed(GntEntry *entry, const char *text, gpointer null) -{ - if (*text != '\r') - return FALSE; - - { - const char *cmd; - void *handle; - void (*func)(); - - cmd = gnt_entry_get_text(entry); - handle = g_module_open(cmd, G_MODULE_BIND_LOCAL); - if (handle && g_module_symbol(handle, "main", (gpointer)&func)) - { - char *argv[] = {cmd, NULL}; - gnt_entry_clear(entry); - func(1, argv); - } - else - { - GntWidget *widget = gnt_vbox_new(FALSE); - gnt_box_set_toplevel(GNT_BOX(widget), TRUE); - gnt_box_set_title(GNT_BOX(widget), "Error"); - gnt_box_add_widget(GNT_BOX(widget), gnt_label_new("Could not execute.")); - gnt_box_add_widget(GNT_BOX(widget), gnt_label_new(g_module_error())); - - gnt_widget_show(widget); - } - } - - return TRUE; -} - -int main() -{ - GntWidget *window, *entry; - - freopen(".error", "w", stderr); - - gnt_init(); - - window = gnt_hbox_new(FALSE); - - gnt_box_add_widget(GNT_BOX(window), gnt_label_new("Command")); - - entry = gnt_entry_new(NULL); - g_signal_connect(G_OBJECT(entry), "key_pressed", G_CALLBACK(key_pressed), NULL); - gnt_box_add_widget(GNT_BOX(window), entry); - - gnt_widget_set_position(window, 0, getmaxy(stdscr) - 2); - gnt_widget_show(window); - - gnt_main(); - - gnt_quit(); - - return 0; -} -
--- a/finch/libgnt/wms/Makefile.am Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -wms = irssi.la -if PURPLE_AVAILABLE -# These custom wms depend on libpurple -purple_wms = s.la -else -purple_wms = -endif - -s_la_LDFLAGS = -module -avoid-version -irssi_la_LDFLAGS = -module -avoid-version - -plugin_LTLIBRARIES = \ - $(wms) \ - $(purple_wms) - -plugindir = $(libdir)/gnt - -irssi_la_SOURCES = irssi.c -irssi_la_LIBADD = \ - $(GLIB_LIBS) \ - ../libgnt.la - -s_la_SOURCES = s.c -s_la_LIBADD = \ - $(GLIB_LIBS) \ - ../libgnt.la \ - $(top_builddir)/libpurple/libpurple.la - -EXTRA_DIST = - -AM_CPPFLAGS = \ - -DDATADIR=\"$(datadir)\" \ - -I$(top_srcdir)/libpurple \ - -I$(top_srcdir)/finch \ - -I$(top_srcdir)/finch/libgnt \ - $(DEBUG_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GNT_CFLAGS) \ - $(PLUGIN_CFLAGS) -
--- a/finch/libgnt/wms/irssi.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,395 +0,0 @@ -/* - * GNT - The GLib Ncurses Toolkit - * - * GNT is the legal property of its developers, whose names are too numerous - * to list here. Please refer to the COPYRIGHT file distributed with this - * source distribution. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA - */ - -/** - * 1. Buddylist is aligned on the left. - * 2. The rest of the screen is split into MxN grid for conversation windows. - * - M = split-h in ~/.gntrc:[irssi] - * - N = split-v in ~/.gntrc:[irssi] - * - Press alt-shift-k/j/l/h to move the selected window to the frame - * above/below/left/right of the current frame. - * 3. All the other windows are always centered. - */ -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include "gntinternal.h" - -#include "gnt.h" -#include "gntbox.h" -#include "gntmenu.h" -#include "gntstyle.h" -#include "gntwm.h" -#include "gntwindow.h" -#include "gntlabel.h" - -#define TYPE_IRSSI (irssi_get_gtype()) - -typedef struct _Irssi -{ - GntWM inherit; - int vert; - int horiz; - - /* This is changed whenever the buddylist is opened/closed or resized. */ - int buddylistwidth; -} Irssi; - -typedef struct _IrssiClass -{ - GntWMClass inherit; -} IrssiClass; - -GType irssi_get_gtype(void); -void gntwm_init(GntWM **wm); - -static void (*org_new_window)(GntWM *wm, GntWidget *win); - -static void -get_xywh_for_frame(Irssi *irssi, int hor, int vert, int *x, int *y, int *w, int *h) -{ - int width, height, rx, ry; - - width = (getmaxx(stdscr) - irssi->buddylistwidth) / irssi->horiz; - height = (getmaxy(stdscr) - 1) / irssi->vert; - - if (width) { - rx = irssi->buddylistwidth; - } else { - rx = 0; - width = getmaxx(stdscr) / irssi->horiz; - } - if (hor) - rx += hor * width; - if (rx) - rx++; - - ry = 0; - if (vert) - ry += vert * height + 1; - - if (x) *x = rx; - if (y) *y = ry; - if (w) { - *w = (hor == irssi->horiz - 1) ? (getmaxx(stdscr) - rx) : (width - 1); - } - if (h) { - *h = (vert == irssi->vert - 1) ? (getmaxy(stdscr) - 1 - ry) : (height - !!vert); - } -} - -static void -draw_line_separators(Irssi *irssi) -{ - int x, y; - int width, height; - - wclear(stdscr); - /* Draw the separator for the buddylist */ - if (irssi->buddylistwidth) - mvwvline(stdscr, 0, irssi->buddylistwidth, - ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), getmaxy(stdscr) - 1); - - /* Now the separators for the conversation windows */ - width = (getmaxx(stdscr) - irssi->buddylistwidth) / irssi->horiz; - height = (getmaxy(stdscr) - 1) / irssi->vert; - for (x = 1; x < irssi->horiz; x++) { - mvwvline(stdscr, 0, irssi->buddylistwidth + x * width, - ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), getmaxy(stdscr) - 1); - } - - for (y = 1; y < irssi->vert; y++) { - mvwhline(stdscr, y * height, irssi->buddylistwidth + 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), - getmaxx(stdscr) - irssi->buddylistwidth); - for (x = 1; x < irssi->horiz; x++) { - mvwaddch(stdscr, y * height, x * width + irssi->buddylistwidth, ACS_PLUS | COLOR_PAIR(GNT_COLOR_NORMAL)); - } - if (irssi->buddylistwidth) - mvwaddch(stdscr, y * height, irssi->buddylistwidth, ACS_LTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); - } -} - -static gboolean -is_budddylist(GntWidget *win) -{ - const char *name = gnt_widget_get_name(win); - if (name && strcmp(name, "buddylist") == 0) - return TRUE; - return FALSE; -} - -static void -remove_border_set_position_size(GntWM *wm, GntWidget *win, int x, int y, int w, int h) -{ - gnt_box_set_toplevel(GNT_BOX(win), FALSE); - GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_CAN_TAKE_FOCUS); - - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); - gnt_widget_set_size(win, (w < 0) ? -1 : w + 2, h + 2); -} - -static void -irssi_new_window(GntWM *wm, GntWidget *win) -{ - const char *name; - int x, y, w, h; - - name = gnt_widget_get_name(win); - if (!name || !strstr(name, "conversation-window")) { - if (!GNT_IS_MENU(win) && !GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) { - if ((!name || strcmp(name, "buddylist"))) { - gnt_widget_get_size(win, &w, &h); - x = (getmaxx(stdscr) - w) / 2; - y = (getmaxy(stdscr) - h) / 2; - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); - } else { - gnt_window_set_maximize(GNT_WINDOW(win), GNT_WINDOW_MAXIMIZE_Y); - remove_border_set_position_size(wm, win, 0, 0, -1, getmaxy(stdscr) - 1); - gnt_widget_get_size(win, &((Irssi*)wm)->buddylistwidth, NULL); - draw_line_separators((Irssi*)wm); - } - } - org_new_window(wm, win); - return; - } - - /* The window we have here is a conversation window. */ - - /* XXX: There should be some way to remember which frame a conversation window - * was in the last time. Perhaps save them in some ~/.gntpositionirssi or some - * such. */ - get_xywh_for_frame((Irssi*)wm, 0, 0, &x, &y, &w, &h); - remove_border_set_position_size(wm, win, x, y, w, h); - org_new_window(wm, win); -} - -static void -irssi_window_resized(GntWM *wm, GntNode *node) -{ - if (!is_budddylist(node->me)) - return; - - gnt_widget_get_size(node->me, &((Irssi*)wm)->buddylistwidth, NULL); - draw_line_separators((Irssi*)wm); -} - -static gboolean -irssi_close_window(GntWM *wm, GntWidget *win) -{ - if (is_budddylist(win)) - ((Irssi*)wm)->buddylistwidth = 0; - return FALSE; -} - -static gboolean -update_conv_window_title(GntNode *node) -{ - char title[256]; - int x, y; - snprintf(title, sizeof(title), "%d: %s", - GPOINTER_TO_INT(g_object_get_data(G_OBJECT(node->me), "irssi-index")) + 1, - GNT_BOX(node->me)->title); - - getyx(node->window, y, x); - wbkgdset(node->window, '\0' | COLOR_PAIR(gnt_widget_has_focus(node->me) ? GNT_COLOR_TITLE : GNT_COLOR_TITLE_D)); - mvwaddstr(node->window, 0, 0, title); - (void)wmove(node->window, y, x); - if (!gnt_is_refugee()) { - update_panels(); - doupdate(); - } - return FALSE; -} - -static void -irssi_update_window(GntWM *wm, GntNode *node) -{ - GntWidget *win = node->me; - const char *name = gnt_widget_get_name(win); - if (!name || !GNT_IS_BOX(win) || !strstr(name, "conversation-window")) - return; - g_object_set_data(G_OBJECT(win), "irssi-index", GINT_TO_POINTER(g_list_index(wm->cws->list, win))); - g_timeout_add(0, (GSourceFunc)update_conv_window_title, node); -} - -static void -find_window_position(Irssi *irssi, GntWidget *win, int *h, int *v) -{ - int x, y; - int width, height; - - gnt_widget_get_position(win, &x, &y); - width = (getmaxx(stdscr) - irssi->buddylistwidth) / irssi->horiz; - height = (getmaxy(stdscr) - 1) / irssi->vert; - - if (h) - *h = width ? (x - irssi->buddylistwidth) / width : x / (getmaxx(stdscr) / irssi->horiz); - if (v) - *v = y / height; -} - -static gboolean -move_direction(GntBindable *bindable, GList *list) -{ - GntWM *wm = GNT_WM(bindable); - Irssi *irssi = (Irssi*)wm; - int vert, hor; - int x, y, w, h; - GntWidget *win; - - if (wm->cws->ordered == NULL || is_budddylist(win = GNT_WIDGET(wm->cws->ordered->data))) - return FALSE; - - find_window_position(irssi, win, &hor, &vert); - - switch (GPOINTER_TO_INT(list->data)) { - case 'k': - vert = MAX(0, vert - 1); - break; - case 'j': - vert = MIN(vert + 1, irssi->vert - 1); - break; - case 'l': - hor = MIN(hor + 1, irssi->horiz - 1); - break; - case 'h': - hor = MAX(0, hor - 1); - break; - } - get_xywh_for_frame(irssi, hor, vert, &x, &y, &w, &h); - gnt_wm_move_window(wm, win, x, y); - gnt_wm_resize_window(wm, win, w, h); - return TRUE; -} - -static void -refresh_window(GntWidget *widget, GntNode *node, Irssi *irssi) -{ - int vert, hor; - int x, y, w, h; - const char *name; - - if (!GNT_IS_WINDOW(widget)) - return; - - if (is_budddylist(widget)) { - return; - } - - name = gnt_widget_get_name(widget); - if (name && strstr(name, "conversation-window")) { - int cx, cy, cw, ch; - gnt_widget_get_position(widget, &cx, &cy); - gnt_widget_get_size(widget, &cw, &ch); - find_window_position(irssi, widget, &hor, &vert); - get_xywh_for_frame(irssi, hor, vert, &x, &y, &w, &h); - if (x != cx || y != cy) - gnt_wm_move_window(GNT_WM(irssi), widget, x, y); - if (w != cw || h != ch) - gnt_wm_resize_window(GNT_WM(irssi), widget, w, h); - } -} - -static void -irssi_terminal_refresh(GntWM *wm) -{ - draw_line_separators((Irssi*)wm); - g_hash_table_foreach(wm->nodes, (GHFunc)refresh_window, wm); -} - -static void -irssi_class_init(IrssiClass *klass) -{ - GntWMClass *pclass = GNT_WM_CLASS(klass); - - org_new_window = pclass->new_window; - - pclass->new_window = irssi_new_window; - pclass->window_resized = irssi_window_resized; - pclass->close_window = irssi_close_window; - pclass->window_update = irssi_update_window; - pclass->terminal_refresh = irssi_terminal_refresh; - - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "move-up", move_direction, - "\033" "K", GINT_TO_POINTER('k'), NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "move-down", move_direction, - "\033" "J", GINT_TO_POINTER('j'), NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "move-right", move_direction, - "\033" "L", GINT_TO_POINTER('l'), NULL); - gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "move-left", move_direction, - "\033" "H", GINT_TO_POINTER('h'), NULL); - - gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); - GNTDEBUG; -} - -void gntwm_init(GntWM **wm) -{ - char *style = NULL; - Irssi *irssi; - - irssi = g_object_new(TYPE_IRSSI, NULL); - *wm = GNT_WM(irssi); - - style = gnt_style_get_from_name("irssi", "split-v"); - irssi->vert = style ? atoi(style) : 1; - g_free(style); - - style = gnt_style_get_from_name("irssi", "split-h"); - irssi->horiz = style ? atoi(style) : 1; - g_free(style); - - irssi->vert = MAX(irssi->vert, 1); - irssi->horiz = MAX(irssi->horiz, 1); - - irssi->buddylistwidth = 0; -} - -GType irssi_get_gtype(void) -{ - static GType type = 0; - - if(type == 0) { - static const GTypeInfo info = { - sizeof(IrssiClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc)irssi_class_init, - NULL, - NULL, /* class_data */ - sizeof(Irssi), - 0, /* n_preallocs */ - NULL, /* instance_init */ - NULL - }; - - type = g_type_register_static(GNT_TYPE_WM, - "GntIrssi", - &info, 0); - } - - return type; -} -
--- a/finch/libgnt/wms/s.c Tue Jul 23 12:47:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,225 +0,0 @@ -#include "internal.h" - -#include <string.h> -#include <sys/types.h> - -#include "gnt.h" -#include "gntbox.h" -#include "gntmenu.h" -#include "gntstyle.h" -#include "gntwm.h" -#include "gntwindow.h" -#include "gntlabel.h" - -#include "blist.h" - -#define TYPE_S (s_get_gtype()) - -#ifdef _S -#undef _S -#endif - -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 void -envelope_buddylist(GntWidget *win) -{ - int w, h; - gnt_widget_get_size(win, &w, &h); - wresize(win->window, h, w + 1); - mvwvline(win->window, 0, w, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL), h); - touchwin(win->window); -} - -static void -envelope_normal_window(GntWidget *win) -{ - int w, h; - - if (GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT)) - return; - - gnt_widget_get_size(win, &w, &h); - wbkgdset(win->window, ' ' | COLOR_PAIR(GNT_COLOR_NORMAL)); - mvwprintw(win->window, 0, w - 4, "[X]"); -} - -static void -s_decorate_window(GntWM *wm, GntWidget *win) -{ - const char *name; - - name = gnt_widget_get_name(win); - if (name && strcmp(name, "buddylist") == 0) { - envelope_buddylist(win); - } else { - envelope_normal_window(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)) { - getmaxyx(stdscr, maxy, maxx); - - gnt_widget_get_position(win, &x, &y); - gnt_widget_get_size(win, &w, &h); - - 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; - blist = TRUE; - - gnt_box_set_toplevel(GNT_BOX(win), FALSE); - GNT_WIDGET_SET_FLAGS(win, GNT_WIDGET_CAN_TAKE_FOCUS); - - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); - - gnt_widget_set_size(win, -1, h + 2); /* XXX: Why is the +2 needed here? -- sadrul */ - } else if (!GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) { - const char *title = GNT_BOX(win)->title; - if (title == NULL || !g_hash_table_lookup(wm->positions, title)) { - /* 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); - - if (blist) - gnt_wm_raise_window(wm, win); -} - -static GntWidget * -find_widget(GntWM *wm, const char *wname) -{ - GList *iter = wm->cws->list; - for (; iter; iter = iter->next) { - GntWidget *widget = iter->data; - const char *name = gnt_widget_get_name(widget); - if (name && strcmp(name, wname) == 0) { - return widget; - } - } - return NULL; -} - -static gboolean -s_mouse_clicked(GntWM *wm, GntMouseEvent event, int cx, int cy, GntWidget *widget) -{ - int x, y, w, h; - - if (!widget) - return FALSE; - /* 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; - - gnt_widget_get_position(widget, &x, &y); - gnt_widget_get_size(widget, &w, &h); - - if (cy == y && cx == x + w - 3) { - gnt_widget_destroy(widget); - return TRUE; - } - - return FALSE; -} - -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 - purple_blist_show(); - return TRUE; -} - -static void -s_class_init(SClass *klass) -{ - GntWMClass *pclass = GNT_WM_CLASS(klass); - - org_new_window = pclass->new_window; - - 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); -} - -GType s_get_gtype(void) -{ - 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; -} -
--- a/finch/plugins/Makefile.am Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/plugins/Makefile.am Sat Jul 27 03:23:16 2019 +0000 @@ -28,11 +28,11 @@ gntgf_la_CFLAGS = $(X11_CFLAGS) gntclipboard_la_LIBADD = $(GLIB_LIBS) $(X11_LIBS) -gntgf_la_LIBADD = $(GLIB_LIBS) $(X11_LIBS) $(top_builddir)/finch/libgnt/libgnt.la +gntgf_la_LIBADD = $(GLIB_LIBS) $(X11_LIBS) $(LIBGNT_LIBS) gnthistory_la_LIBADD = $(GLIB_LIBS) gntlastlog_la_LIBADD = $(GLIB_LIBS) gnttinyurl_la_LIBADD = $(GLIB_LIBS) -grouping_la_LIBADD = $(GLIB_LIBS) $(top_builddir)/finch/libgnt/libgnt.la +grouping_la_LIBADD = $(GLIB_LIBS) $(LIBGNT_LIBS) endif # PLUGINS @@ -44,7 +44,7 @@ -I$(top_srcdir)/libpurple \ -I$(top_srcdir) \ -I$(top_srcdir)/finch \ - -I$(top_srcdir)/finch/libgnt \ + $(LIBGNT_CFLAGS) \ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(GNT_CFLAGS) \
--- a/finch/plugins/gntgf.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/plugins/gntgf.c Sat Jul 27 03:23:16 2019 +0000 @@ -179,8 +179,8 @@ #endif window = gnt_vbox_new(FALSE); - GNT_WIDGET_SET_FLAGS(window, GNT_WIDGET_TRANSIENT); - GNT_WIDGET_UNSET_FLAGS(window, GNT_WIDGET_NO_BORDER); + gnt_widget_set_transient(window, TRUE); + gnt_widget_set_has_border(window, TRUE); va_start(args, fmt); str = g_strdup_vprintf(fmt, args);
--- a/finch/plugins/lastlog.c Tue Jul 23 12:47:17 2019 +0200 +++ b/finch/plugins/lastlog.c Sat Jul 27 03:23:16 2019 +0000 @@ -42,16 +42,21 @@ { if (key[0] == 27) { - if (purple_strequal(key, GNT_KEY_DOWN)) + if (purple_strequal(key, GNT_KEY_DOWN)) { gnt_text_view_scroll(view, 1); - else if (purple_strequal(key, GNT_KEY_UP)) + } else if (purple_strequal(key, GNT_KEY_UP)) { gnt_text_view_scroll(view, -1); - else if (purple_strequal(key, GNT_KEY_PGDOWN)) - gnt_text_view_scroll(view, wid->priv.height - 2); - else if (purple_strequal(key, GNT_KEY_PGUP)) - gnt_text_view_scroll(view, -(wid->priv.height - 2)); - else + } else if (purple_strequal(key, GNT_KEY_PGDOWN)) { + int height = 0; + gnt_widget_get_size(wid, NULL, &height); + gnt_text_view_scroll(view, height - 2); + } else if (purple_strequal(key, GNT_KEY_PGUP)) { + int height = 0; + gnt_widget_get_size(wid, NULL, &height); + gnt_text_view_scroll(view, -(height - 2)); + } else { return FALSE; + } return TRUE; } return FALSE; @@ -61,7 +66,8 @@ lastlog_cb(PurpleConversation *conv, const char *cmd, char **args, char **error, gpointer null) { FinchConv *ggconv = conv->ui_data; - char **strings = g_strsplit(GNT_TEXT_VIEW(ggconv->tv)->string->str, "\n", 0); + char **strings = g_strsplit(gnt_text_view_get_text(GNT_TEXT_VIEW(ggconv->tv)), + "\n", 0); GntWidget *win, *tv; int i, j;
--- a/libpurple/media.c Tue Jul 23 12:47:17 2019 +0200 +++ b/libpurple/media.c Sat Jul 27 03:23:16 2019 +0000 @@ -349,6 +349,11 @@ priv->manager = NULL; } + if (priv->conference_type) { + g_free(priv->conference_type); + priv->conference_type = NULL; + } + G_OBJECT_CLASS(parent_class)->dispose(media); }
--- a/libpurple/mediamanager.c Tue Jul 23 12:47:17 2019 +0200 +++ b/libpurple/mediamanager.c Sat Jul 27 03:23:16 2019 +0000 @@ -2190,8 +2190,9 @@ name = gst_device_get_display_name(device); device_class = gst_device_get_device_class(device); - for (i = manager->priv->elements; i && !done; i = i->next) { + for (i = manager->priv->elements; i && !done;) { PurpleMediaElementInfo *info = i->data; + GList *next = i->next; GstDevice *device2; device2 = g_object_get_data(G_OBJECT(info), "gst-device"); @@ -2222,6 +2223,7 @@ g_free(name2); g_free(device_class2); } + i = next; } g_free(name);
--- a/libpurple/plugins/ssl/ssl-gnutls.c Tue Jul 23 12:47:17 2019 +0200 +++ b/libpurple/plugins/ssl/ssl-gnutls.c Sat Jul 27 03:23:16 2019 +0000 @@ -712,13 +712,13 @@ /* Next, we'll simply yank the entire contents of the file into memory */ /* TODO: Should I worry about very large files here? */ - g_return_val_if_fail( - g_file_get_contents(filename, - &buf, - &buf_sz, - NULL /* No error checking for now */ - ), - NULL); + if (!g_file_get_contents(filename, + &buf, + &buf_sz, + NULL /* No error checking for now */ + )) { + return NULL; + } /* Load the datum struct */ dt.data = (unsigned char *) buf;
--- a/pidgin.spec.in Tue Jul 23 12:47:17 2019 +0200 +++ b/pidgin.spec.in Sat Jul 27 03:23:16 2019 +0000 @@ -291,7 +291,6 @@ %if 0%{?_without_text:1} rm -f $RPM_BUILD_ROOT%{_mandir}/man1/finch.* rm -rf $RPM_BUILD_ROOT%{_bindir}/finch -rm -f $RPM_BUILD_ROOT%{_libdir}/libgnt.so.* %endif %find_lang %{name} @@ -456,20 +455,12 @@ %doc %{_mandir}/man1/finch.* %{_bindir}/finch -%{_libdir}/libgnt.so.* -%{_libdir}/gnt/irssi.so -%{_libdir}/gnt/s.so %files -n finch-devel %defattr(-, root, root) %dir %{_includedir}/finch %{_includedir}/finch/*.h -# libgnt -%dir %{_includedir}/gnt -%{_includedir}/gnt/*.h %{_libdir}/pkgconfig/finch.pc -%{_libdir}/pkgconfig/gnt.pc -%{_libdir}/libgnt.so %endif
--- a/pidgin/gtkconv.c Tue Jul 23 12:47:17 2019 +0200 +++ b/pidgin/gtkconv.c Sat Jul 27 03:23:16 2019 +0000 @@ -8173,7 +8173,7 @@ pidgin_conversations_set_tab_colors(void) { /* Set default tab colors */ - GString *str = g_string_new(NULL); + GString *str; GtkSettings *settings = gtk_settings_get_default(); GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now; struct { @@ -8195,6 +8195,8 @@ return; } + str = g_string_new(NULL); + for (iter = 0; styles[iter].stylename; iter++) { now = gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE); if (parent == now ||
--- a/pidgin/gtkmedia.c Tue Jul 23 12:47:17 2019 +0200 +++ b/pidgin/gtkmedia.c Sat Jul 27 03:23:16 2019 +0000 @@ -510,6 +510,11 @@ gtkmedia->priv->remote_videos = NULL; } + if (gtkmedia->priv->screenname) { + g_free(gtkmedia->priv->screenname); + gtkmedia->priv->screenname = NULL; + } + G_OBJECT_CLASS(parent_class)->dispose(media); }
--- a/po/POTFILES.in Tue Jul 23 12:47:17 2019 +0200 +++ b/po/POTFILES.in Sat Jul 27 03:23:16 2019 +0000 @@ -18,20 +18,6 @@ finch/gntsound.c finch/gntstatus.c finch/gntui.c -finch/libgnt/gntbox.c -finch/libgnt/gntbutton.c -finch/libgnt/gntcheckbox.c -finch/libgnt/gntcolors.c -finch/libgnt/gntcombobox.c -finch/libgnt/gntentry.c -finch/libgnt/gntkeys.c -finch/libgnt/gntlabel.c -finch/libgnt/gntline.c -finch/libgnt/gntstyle.c -finch/libgnt/gnttextview.c -finch/libgnt/gnttree.c -finch/libgnt/gntutils.c -finch/libgnt/gntwidget.c finch/plugins/gntclipboard.c finch/plugins/gntgf.c finch/plugins/gnthistory.c