home *** CD-ROM | disk | FTP | other *** search
- To: vim-dev@vim.org
- Subject: Patch 5.6a.018
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- ------------
-
- Note: I received a number of fixes for the GTK version from Marcin Dalecki. I
- found these important enough to include. But since this is more than a small
- change, I'll give this another week before releasing 5.6. A few functions
- were moved, which made patch quite big, even though not that much really
- changed.
-
-
- Patch 5.6a.018
- Problem: GTK GUI: submenu priority doesn't work.
- Help dialog could be destroyed too soon.
- When closing a dialog window (e.g. the "ATTENTION" one), Vim would
- just hang.
- When GTK theme is changed, Vim doesn't adjust to the new colors.
- Argument for ":promptfind" isn't used.
- Solution: Fixed the mentioned problems.
- Made the dialogs look&feel nicer.
- Moved functions to avoid the need for a forward declaration.
- Fixed reentrancy of the file browser dialog.
- Added drag&drop support for GNOME.
- Init the text for the Find/replace dialog from the last used
- search string. Set "match whole word" toggle button correctly.
- Made repeat rate for drag outside of window depend on the
- distance from the window. (Marcin Dalecki)
- Made the drag in Visual mode actually work.
- Removed recursiveness protection from gui_mch_get_rgb(), it might
- cause more trouble than it solves.
- Files: src/ex_docmd.c, src/gui_gtk.c, src/gui_gtk_x11.c, src/ui.c,
- src/proto/ui.pro, src/misc2.c
-
-
- *** ../vim-5.6a.17/src/ex_docmd.c Wed Dec 29 12:11:01 1999
- --- src/ex_docmd.c Sat Jan 8 13:45:47 2000
- ***************
- *** 5941,5947 ****
- }
- }
-
- ! #if defined(USE_GUI_MSWIN) || defined(USE_GUI_BEOS) || defined(macintosh) || defined(PROTO)
- /*
- * Handle a file drop. The code is here because a drop is *nearly* like an
- * :args command, but not quite (we have a list of exact filenames, so we
- --- 5941,5948 ----
- }
- }
-
- ! #if defined(USE_GUI_MSWIN) || defined(USE_GUI_BEOS) || defined(macintosh) \
- ! || defined(USE_GUI_GTK) || defined(PROTO)
- /*
- * Handle a file drop. The code is here because a drop is *nearly* like an
- * :args command, but not quite (we have a list of exact filenames, so we
- ***************
- *** 5949,5958 ****
- * code is very similar to :args and hence needs access to a lot of the static
- * functions in this file.
- *
- - * Arguments:
- - * FILEC => the number of files dropped
- - * FILEV => the list of files dropped
- - *
- * The list should be allocated using vim_alloc(), as should each item in the
- * list. This function takes over responsibility for freeing the list.
- *
- --- 5950,5955 ----
- ***************
- *** 5966,5973 ****
-
- void
- handle_drop(filec, filev, split)
- ! int filec;
- ! char_u **filev;
- int split; /* force splitting the window */
- {
- EXARG ea;
- --- 5963,5970 ----
-
- void
- handle_drop(filec, filev, split)
- ! int filec; /* the number of files dropped */
- ! char_u **filev; /* the list of files dropped */
- int split; /* force splitting the window */
- {
- EXARG ea;
- *** ../vim-5.6a.17/src/gui_gtk.c Mon Dec 20 09:59:10 1999
- --- src/gui_gtk.c Sat Jan 8 21:11:02 2000
- ***************
- *** 19,24 ****
- --- 19,29 ----
- * :-) <dalecki@cs.net.pl> (My native language is polish and I speak
- * native grade german too. I'm living in GĂ·ttingen.de.)
- * --mdcki"
- + *
- + *
- + * Although some #ifdefs suggest that GTK 1.0 is supported, it isn't. The
- + * code requires GTK version 1.1.16 or later. Stuff for older versions will
- + * be removed some time.
- */
-
- #include "gui_gtk_f.h"
- ***************
- *** 92,115 ****
- #define FR_REPLACE 4
- #define FR_REPLACEALL 5
-
- -
- - #if defined(USE_BROWSE) || defined(PROTO)
- - static void browse_ok_cb(GtkWidget * widget, gpointer cbdata);
- - static void browse_cancel_cb(GtkWidget * widget, gpointer cbdata);
- - static gboolean browse_destroy_cb(GtkWidget * widget);
- - #endif
- -
- - #ifdef GUI_DIALOG
- - static void butproc(GtkWidget * widget, gpointer data);
- - #endif
- -
- static void entry_activate_cb(GtkWidget *widget, GtkWidget *with);
- static void entry_changed_cb(GtkWidget *entry, GtkWidget *dialog);
- static void find_direction_cb(GtkWidget *widget, gpointer data);
- ! static void find_replace_cb(GtkWidget *widget, gint flags);
- static void exact_match_cb(GtkWidget *widget, gpointer data);
- static void repl_dir_cb(GtkWidget * widget, gpointer data);
- - static void find_replace_dialog_create(int do_replace);
-
- #ifdef USE_TOOLBAR
- static void get_pixmap(char *menuname, GdkPixmap **pixmap, GdkBitmap **mask);
- --- 97,108 ----
- #define FR_REPLACE 4
- #define FR_REPLACEALL 5
-
- static void entry_activate_cb(GtkWidget *widget, GtkWidget *with);
- static void entry_changed_cb(GtkWidget *entry, GtkWidget *dialog);
- static void find_direction_cb(GtkWidget *widget, gpointer data);
- ! static void find_replace_cb(GtkWidget *widget, unsigned int flags);
- static void exact_match_cb(GtkWidget *widget, gpointer data);
- static void repl_dir_cb(GtkWidget * widget, gpointer data);
-
- #ifdef USE_TOOLBAR
- static void get_pixmap(char *menuname, GdkPixmap **pixmap, GdkBitmap **mask);
- ***************
- *** 120,127 ****
- #endif
-
- #if defined(WANT_MENU) || defined(PROTO)
- - static void gui_mch_recurse_tearoffs(VimMenu *menu, int val);
- - static void menu_item_cb(GtkWidget *widget, gpointer data);
-
- /*
- * Only use accelerators when gtk_menu_ensure_uline_accel_group() is
- --- 113,118 ----
- ***************
- *** 133,138 ****
- --- 124,130 ----
- # define GTK_USE_ACCEL
- # endif
- #endif
- +
- /*
- * Create a highly customized menu item by hand instead of by using:
- *
- ***************
- *** 192,198 ****
- * additional underscores.
- */
- name = g_new(char, strlen((char *)menu->name) + num + 1);
- ! for (num = 0, tmp = (char *)menu->name; *tmp; tmp++) {
- /* actext has been added above, stop at the TAB */
- if (*tmp == TAB)
- break;
- --- 184,190 ----
- * additional underscores.
- */
- name = g_new(char, strlen((char *)menu->name) + num + 1);
- ! for (num = 0, tmp = (char *)menu->name; *tmp; ++tmp) {
- /* actext has been added above, stop at the TAB */
- if (*tmp == TAB)
- break;
- ***************
- *** 285,294 ****
- if (parent == NULL)
- gtk_menu_bar_insert(GTK_MENU_BAR(gui.menubar), menu->id, idx);
- else {
- - #ifdef GTK_HAVE_FEATURES_1_1_0
- /* since the tearoff should always appear first, increment idx */
- ++idx;
- - #endif
- gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx);
- }
-
- --- 277,284 ----
- ***************
- *** 314,319 ****
- --- 304,319 ----
- #endif
- }
-
- + /*ARGSUSED*/
- + static void
- + menu_item_activate(GtkWidget * widget, gpointer data)
- + {
- + gui_menu_cb((VimMenu *) data);
- +
- + /* make sure the menu action is taken immediately */
- + if (gtk_main_level() > 0)
- + gtk_main_quit();
- + }
-
- /*ARGSUSED*/
- void
- ***************
- *** 337,343 ****
- (char *)(menu->strings[MENU_INDEX_TIP]),
- (char *)(menu->dname),
- gtk_pixmap_new(pixmap, mask),
- ! GTK_SIGNAL_FUNC(menu_item_cb),
- (gpointer)menu,
- idx);
- }
- --- 337,343 ----
- (char *)(menu->strings[MENU_INDEX_TIP]),
- (char *)(menu->dname),
- gtk_pixmap_new(pixmap, mask),
- ! GTK_SIGNAL_FUNC(menu_item_activate),
- (gpointer)menu,
- idx);
- }
- ***************
- *** 351,372 ****
- if (parent->submenu_id == 0)
- return;
-
- if (is_menu_separator(menu->name)) {
- ! /* just add it */
- menu->id = gtk_menu_item_new();
- gtk_widget_show(menu->id);
- ! gtk_menu_append(GTK_MENU(parent->submenu_id), menu->id);
-
- ! return; /* that's all */
- }
-
- menu_item_new(menu, parent->submenu_id, FALSE);
- gtk_widget_show(menu->id);
- ! gtk_menu_append(GTK_MENU(parent->submenu_id), menu->id);
-
- if (menu->id != 0)
- gtk_signal_connect(GTK_OBJECT(menu->id), "activate",
- ! GTK_SIGNAL_FUNC(menu_item_cb), (gpointer) menu);
- }
- #endif
-
- --- 351,375 ----
- if (parent->submenu_id == 0)
- return;
-
- + /* make place for the possible tearoff handle item */
- + ++idx;
- if (is_menu_separator(menu->name)) {
- ! /* Separator: Just add it */
- menu->id = gtk_menu_item_new();
- gtk_widget_show(menu->id);
- ! gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx);
-
- ! return;
- }
-
- + /* Add textual menu item. */
- menu_item_new(menu, parent->submenu_id, FALSE);
- gtk_widget_show(menu->id);
- ! gtk_menu_insert(GTK_MENU(parent->submenu_id), menu->id, idx);
-
- if (menu->id != 0)
- gtk_signal_connect(GTK_OBJECT(menu->id), "activate",
- ! GTK_SIGNAL_FUNC(menu_item_activate), (gpointer) menu);
- }
- #endif
-
- ***************
- *** 426,432 ****
-
- *pixmap = NULL;
- *mask = NULL;
- ! if (strncmp(menuname, "BuiltIn", 7) == 0) {
- if (isdigit((int)menuname[7]) && isdigit((int)menuname[8])) {
- builtin_num = atoi(menuname + 7);
- pixmap_create_by_num(builtin_num, pixmap, mask);
- --- 429,435 ----
-
- *pixmap = NULL;
- *mask = NULL;
- ! if (strncmp(menuname, "BuiltIn", (size_t)7) == 0) {
- if (isdigit((int)menuname[7]) && isdigit((int)menuname[8])) {
- builtin_num = atoi(menuname + 7);
- pixmap_create_by_num(builtin_num, pixmap, mask);
- ***************
- *** 549,565 ****
- gtk_form_move_resize(GTK_FORM(gui.formwin), gui.drawarea, x, y, w, h);
- }
-
- - #if 0
- - /*
- - * Nothing to be done here, since we have started to manage our windows with
- - * abstract management widgets, which is much better in fact.
- - */
- - /*ARGSUSED*/
- - void
- - gui_mch_set_menu_pos(int x, int y, int w, int h)
- - {
- - }
- - #endif
-
- #if defined(WANT_MENU) || defined(PROTO)
- /*
- --- 552,557 ----
- ***************
- *** 571,577 ****
- {
- #if 0
- VimMenu *menu;
- ! /* FIXME: imeplemnt this later */
- for (menu = root_menu; menu != NULL; menu = menu->next)
- if (menu->id != 0)
- XtVaSetValues(menu->id,
- --- 563,569 ----
- {
- #if 0
- VimMenu *menu;
- ! /* FIXME: implement this later */
- for (menu = root_menu; menu != NULL; menu = menu->next)
- if (menu->id != 0)
- XtVaSetValues(menu->id,
- ***************
- *** 580,600 ****
- #endif
- }
-
- void
- gui_mch_toggle_tearoffs(int enable)
- {
- ! gui_mch_recurse_tearoffs(root_menu, enable);
- }
- #endif
-
-
- #ifdef USE_TOOLBAR
- /*
- ! * seems like there's a hole in the GTK Toolbar API: there's no provision for
- ! * removing an item from the toolbar!
- */
- static void
- ! gui_gtk_toolbar_remove_item_by_text(GtkToolbar *tb, const char *text)
- {
- GtkContainer *container;
- GList *childl;
- --- 572,615 ----
- #endif
- }
-
- +
- + static void
- + recurse_tearoffs(VimMenu * menu, int val)
- + {
- + #ifdef GTK_HAVE_FEATURES_1_1_0
- + while (menu != NULL) {
- + if (!popup_menu(menu->name)) {
- + if (menu->submenu_id != 0) {
- + if (val)
- + gtk_widget_show(menu->tearoff_handle);
- + else
- + gtk_widget_hide(menu->tearoff_handle);
- + }
- + recurse_tearoffs(menu->children, val);
- + }
- + menu = menu->next;
- + }
- + #endif
- + }
- +
- +
- void
- gui_mch_toggle_tearoffs(int enable)
- {
- ! recurse_tearoffs(root_menu, enable);
- }
- #endif
-
-
- #ifdef USE_TOOLBAR
- +
- /*
- ! * Seems like there's a hole in the GTK Toolbar API: there's no provision for
- ! * removing an item from the toolbar. Therefore I need to resort to going
- ! * really deeply into the internal widget structures.
- */
- static void
- ! toolbar_remove_item_by_text(GtkToolbar *tb, const char *text)
- {
- GtkContainer *container;
- GList *childl;
- ***************
- *** 637,648 ****
- {
- #ifdef USE_TOOLBAR
- if (menu->parent && toolbar_menu(menu->parent->name)) {
- ! #if 0
- ! /* FIXME: this isn't in GTK yet, but will be. for now, use the alternative */
- ! gtk_toolbar_remove_item(GTK_TOOLBAR(gui.toolbar),
- ! GTK_TOOLBAR_DATA_TEXT, menu->dname);
- ! #endif
- ! gui_gtk_toolbar_remove_item_by_text(GTK_TOOLBAR(gui.toolbar),
- (const char *)menu->dname);
- return;
- }
- --- 652,658 ----
- {
- #ifdef USE_TOOLBAR
- if (menu->parent && toolbar_menu(menu->parent->name)) {
- ! toolbar_remove_item_by_text(GTK_TOOLBAR(gui.toolbar),
- (const char *)menu->dname);
- return;
- }
- ***************
- *** 716,724 ****
- value = adjustment->value;
-
- /*
- ! * We just ignore the dragging argument, since otherwise
- ! * the scrollbar size will not be adjusted properly in
- ! * synthetic scrolls.
- */
- gui_drag_scrollbar(sb, value, FALSE);
- if (gtk_main_level() > 0)
- --- 726,733 ----
- value = adjustment->value;
-
- /*
- ! * We just ignore the dragging argument, since otherwise the scrollbar
- ! * size will not be adjusted properly in synthetic scrolls.
- */
- gui_drag_scrollbar(sb, value, FALSE);
- if (gtk_main_level() > 0)
- ***************
- *** 768,773 ****
- --- 777,831 ----
- * Implementation of the file selector related stuff
- */
-
- + /*ARGSUSED*/
- + static void
- + browse_ok_cb(GtkWidget *widget, gpointer cbdata)
- + {
- + Gui *vw = (Gui *)cbdata;
- +
- + if (vw->browse_fname != NULL)
- + g_free(vw->browse_fname);
- +
- + vw->browse_fname = (char_u *)g_strdup(gtk_file_selection_get_filename(
- + GTK_FILE_SELECTION(vw->filedlg)));
- + gtk_widget_hide(vw->filedlg);
- + if (gtk_main_level() > 0)
- + gtk_main_quit();
- + }
- +
- + /*ARGSUSED*/
- + static void
- + browse_cancel_cb(GtkWidget *widget, gpointer cbdata)
- + {
- + Gui *vw = (Gui *)cbdata;
- +
- + if (vw->browse_fname != NULL)
- + {
- + g_free(vw->browse_fname);
- + vw->browse_fname = NULL;
- + }
- + gtk_widget_hide(vw->filedlg);
- + if (gtk_main_level() > 0)
- + gtk_main_quit();
- + }
- +
- + /*ARGSUSED*/
- + static gboolean
- + browse_destroy_cb(GtkWidget * widget)
- + {
- + if (gui.browse_fname != NULL)
- + {
- + g_free(gui.browse_fname);
- + gui.browse_fname = NULL;
- + }
- + gui.filedlg = NULL;
- +
- + if (gtk_main_level() > 0)
- + gtk_main_quit();
- +
- + return FALSE;
- + }
- +
- /*
- * Put up a file requester.
- * Returns the selected name in allocated memory, or NULL for Cancel.
- ***************
- *** 793,804 ****
- if (!gui.filedlg)
- {
- gui.filedlg = gtk_file_selection_new((const gchar *)title);
- - fs = GTK_FILE_SELECTION(gui.filedlg);
- #ifdef GTK_HAVE_FEATURES_1_1_4
- gtk_window_set_modal(GTK_WINDOW(gui.filedlg), TRUE);
- gtk_window_set_transient_for(GTK_WINDOW(gui.filedlg),
- GTK_WINDOW(gui.mainwin));
- #endif
- gtk_container_border_width(GTK_CONTAINER(fs), 4);
- gtk_file_selection_hide_fileop_buttons(fs);
-
- --- 851,863 ----
- if (!gui.filedlg)
- {
- gui.filedlg = gtk_file_selection_new((const gchar *)title);
- #ifdef GTK_HAVE_FEATURES_1_1_4
- gtk_window_set_modal(GTK_WINDOW(gui.filedlg), TRUE);
- gtk_window_set_transient_for(GTK_WINDOW(gui.filedlg),
- GTK_WINDOW(gui.mainwin));
- #endif
- + fs = GTK_FILE_SELECTION(gui.filedlg);
- +
- gtk_container_border_width(GTK_CONTAINER(fs), 4);
- gtk_file_selection_hide_fileop_buttons(fs);
-
- ***************
- *** 834,926 ****
- if (gui.browse_fname == NULL)
- return NULL;
- return vim_strsave(gui.browse_fname);
- ! } /* gui_mch_browse */
-
- ! /*ARGSUSED*/
- ! static void
- ! browse_ok_cb(GtkWidget *widget, gpointer cbdata)
- ! {
- ! Gui *vw = (Gui *)cbdata;
-
- ! if (vw->browse_fname != NULL)
- ! g_free(vw->browse_fname);
-
- ! vw->browse_fname = (char_u *)g_strdup(gtk_file_selection_get_filename(
- ! GTK_FILE_SELECTION(vw->filedlg)));
- ! gtk_widget_hide(vw->filedlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- ! }
-
- ! /*ARGSUSED*/
- static void
- ! browse_cancel_cb(GtkWidget *widget, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
- !
- ! if (vw->browse_fname != NULL)
- ! {
- ! g_free(vw->browse_fname);
- ! vw->browse_fname = NULL;
- ! }
- ! gtk_widget_hide(vw->filedlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
-
- /*ARGSUSED*/
- ! static gboolean
- ! browse_destroy_cb(GtkWidget * widget)
- {
- ! if (gui.browse_fname != NULL)
- ! {
- ! g_free(gui.browse_fname);
- ! gui.browse_fname = NULL;
- ! }
- ! gui.filedlg = NULL;
-
- ! /* This is needed to get out of gtk_main? */
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
-
- ! return FALSE;
- }
-
- - #endif /* USE_BROWSE */
- -
- - #ifdef GUI_DIALOG
- -
- - static int dialogStatus;
- - static GtkWidget *dialogbb = NULL;
- -
- /* ARGSUSED */
- int
- ! gui_mch_dialog(int type,
- ! char_u * title,
- ! char_u * message,
- ! char_u * buttons,
- ! int dfltbutton)
- {
- ! char_u *buts;
- ! char_u *p, *next;
- int butcount;
-
- ! GtkWidget *vbox = NULL;
- ! GtkWidget *table = NULL;
- GtkWidget *pixmap;
- ! GtkWidget *dialogmessage = NULL;
- ! GtkWidget *action_area = NULL;
- ! GtkWidget *separator = NULL;
-
- GdkPixmap *icon = NULL;
- GdkBitmap *mask = NULL;
- char **icon_data = NULL;
-
- #define MAXBUT 10
- ! GtkWidget *dialogButton[MAXBUT];
-
- if (title == NULL)
- ! title = (char_u *) "Vim dialog";
-
- if ((type < 0) || (type > VIM_LAST_TYPE))
- type = VIM_GENERIC;
- --- 893,975 ----
- if (gui.browse_fname == NULL)
- return NULL;
- return vim_strsave(gui.browse_fname);
- ! }
-
- ! #endif /* USE_BROWSE */
-
- ! #ifdef GUI_DIALOG
-
- ! typedef struct _ButtonData {
- ! int *status;
- ! int index;
- ! GtkWidget *dialog;
- ! } ButtonData;
- !
- ! typedef struct _CancelData {
- ! int *status;
- ! GtkWidget *dialog;
- ! } CancelData;
-
- ! /* ARGSUSED */
- static void
- ! dlg_button_clicked(GtkWidget * widget, ButtonData *data)
- {
- ! *(data->status) = data->index + 1;
- ! gtk_widget_destroy(data->dialog);
- }
-
- + /*
- + * This makes the Escape key equivalent to the cancel button.
- + */
- +
- /*ARGSUSED*/
- ! static int
- ! dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
- {
- ! if (event->keyval != GDK_Escape)
- ! return FALSE;
-
- ! /* The result value of 0 from a dialog is signaling cancelation. */
- ! *(data->status) = 0;
- ! gtk_widget_destroy(data->dialog);
-
- ! return TRUE;
- }
-
- /* ARGSUSED */
- int
- ! gui_mch_dialog(int type, /* type of dialog */
- ! char_u * title, /* title of dialog */
- ! char_u * message, /* message text */
- ! char_u * buttons, /* names of buttons */
- ! int def_but) /* default button */
- {
- ! char_u *names;
- ! char_u *p;
- int butcount;
- + int dialog_status = -1;
-
- ! GtkWidget *dialog;
- ! GtkWidget *frame;
- ! GtkWidget *vbox;
- ! GtkWidget *table;
- GtkWidget *pixmap;
- ! GtkWidget *dialogmessage;
- ! GtkWidget *action_area;
- ! GtkWidget *sub_area;
- ! GtkWidget *separator;
-
- GdkPixmap *icon = NULL;
- GdkBitmap *mask = NULL;
- char **icon_data = NULL;
-
- #define MAXBUT 10
- ! GtkWidget *button[MAXBUT];
- ! ButtonData data[MAXBUT];
- ! CancelData cancel_data;
-
- if (title == NULL)
- ! title = (char_u *) "Vim dialog...";
-
- if ((type < 0) || (type > VIM_LAST_TYPE))
- type = VIM_GENERIC;
- ***************
- *** 928,943 ****
- /* if our pointer is currently hidden, then we should show it. */
- gui_mch_mousehide(FALSE);
-
- ! dialogbb = gtk_window_new(GTK_WINDOW_DIALOG);
- ! gtk_window_set_title(GTK_WINDOW(dialogbb), (const gchar *)title);
- ! gtk_window_position(GTK_WINDOW(dialogbb), GTK_WIN_POS_MOUSE);
- #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_window_set_transient_for(GTK_WINDOW(dialogbb), GTK_WINDOW(gui.mainwin));
- #endif
- ! gtk_grab_add(dialogbb);
-
- vbox = gtk_vbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(dialogbb), vbox);
- gtk_widget_show(vbox);
-
- table = gtk_table_new(1, 3, FALSE);
- --- 977,1007 ----
- /* if our pointer is currently hidden, then we should show it. */
- gui_mch_mousehide(FALSE);
-
- ! dialog = gtk_window_new(GTK_WINDOW_DIALOG);
- ! gtk_window_set_title(GTK_WINDOW(dialog), (const gchar *)title);
- ! gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
- #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui.mainwin));
- #endif
- ! gtk_widget_realize(dialog);
- ! gdk_window_set_decorations(dialog->window, GDK_DECOR_BORDER);
- ! gdk_window_set_functions(dialog->window, GDK_FUNC_MOVE);
- !
- ! cancel_data.status = &dialog_status;
- ! cancel_data.dialog = dialog;
- ! gtk_signal_connect_after(GTK_OBJECT(dialog), "key_press_event",
- ! GTK_SIGNAL_FUNC(dlg_key_press_event),
- ! (gpointer) &cancel_data);
- !
- ! gtk_grab_add(dialog);
- !
- ! /* this makes it look beter on Motif style window managers */
- ! frame = gtk_frame_new(NULL);
- ! gtk_container_add(GTK_CONTAINER(dialog), frame);
- ! gtk_widget_show(frame);
-
- vbox = gtk_vbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(frame), vbox);
- gtk_widget_show(vbox);
-
- table = gtk_table_new(1, 3, FALSE);
- ***************
- *** 968,974 ****
- icon_data = generic_xpm;
- };
- icon = gdk_pixmap_colormap_create_from_xpm_d(NULL,
- ! gtk_widget_get_colormap(dialogbb),
- &mask, NULL, icon_data);
- if (icon) {
- pixmap = gtk_pixmap_new(icon, mask);
- --- 1032,1038 ----
- icon_data = generic_xpm;
- };
- icon = gdk_pixmap_colormap_create_from_xpm_d(NULL,
- ! gtk_widget_get_colormap(dialog),
- &mask, NULL, icon_data);
- if (icon) {
- pixmap = gtk_pixmap_new(icon, mask);
- ***************
- *** 976,1006 ****
- gtk_table_attach_defaults(GTK_TABLE(table), pixmap, 0, 1, 0, 1);
- gtk_widget_show(pixmap);
- }
- /* Add label */
- dialogmessage = gtk_label_new((const gchar *)message);
- gtk_table_attach_defaults(GTK_TABLE(table), dialogmessage, 1, 2, 0, 1);
- gtk_widget_show(dialogmessage);
-
- - /* for some reason this doesn't work properly under kwm */
- - /* gdk_window_set_decorations(dialogbb->window, GDK_DECOR_BORDER);
- - * gdk_window_set_functions(dialogbb->window, 0);
- - */
- -
- action_area = gtk_hbox_new(FALSE, 0);
- gtk_container_border_width(GTK_CONTAINER(action_area), 4);
- gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0);
- gtk_widget_show(action_area);
-
- /* make a copy, so that we can insert NULs */
- ! buts = vim_strsave(buttons);
- ! if (buts == NULL)
- return -1;
-
- /*
- * Create the buttons.
- */
- ! p = buts;
- for (butcount = 0; butcount < MAXBUT; ++butcount) {
- for (next = p; *next; ++next) {
- if (*next == DLG_HOTKEY_CHAR)
- mch_memmove(next, next + 1, STRLEN(next));
- --- 1040,1073 ----
- gtk_table_attach_defaults(GTK_TABLE(table), pixmap, 0, 1, 0, 1);
- gtk_widget_show(pixmap);
- }
- +
- /* Add label */
- dialogmessage = gtk_label_new((const gchar *)message);
- gtk_table_attach_defaults(GTK_TABLE(table), dialogmessage, 1, 2, 0, 1);
- gtk_widget_show(dialogmessage);
-
- action_area = gtk_hbox_new(FALSE, 0);
- gtk_container_border_width(GTK_CONTAINER(action_area), 4);
- gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0);
- gtk_widget_show(action_area);
-
- + sub_area = gtk_hbox_new(TRUE, 0);
- + gtk_container_set_border_width(GTK_CONTAINER(sub_area), 0);
- + gtk_box_pack_start(GTK_BOX(action_area), sub_area, FALSE, TRUE, 0);
- + gtk_widget_show(sub_area);
- +
- /* make a copy, so that we can insert NULs */
- ! names = vim_strsave(buttons);
- ! if (names == NULL)
- return -1;
-
- /*
- * Create the buttons.
- */
- ! p = names;
- for (butcount = 0; butcount < MAXBUT; ++butcount) {
- + char_u *next;
- +
- for (next = p; *next; ++next) {
- if (*next == DLG_HOTKEY_CHAR)
- mch_memmove(next, next + 1, STRLEN(next));
- ***************
- *** 1010,1066 ****
- }
- }
-
- ! dialogButton[butcount] = gtk_button_new_with_label((const gchar *)p);
- ! GTK_WIDGET_SET_FLAGS(dialogButton[butcount], GTK_CAN_DEFAULT);
- ! gtk_widget_show(dialogButton[butcount]);
- ! gtk_signal_connect(GTK_OBJECT(dialogButton[butcount]),
- (const char *)"clicked",
- ! GTK_SIGNAL_FUNC(butproc), GINT_TO_POINTER(butcount));
-
- if (*next == NUL) {
- ! gtk_box_pack_end(GTK_BOX(action_area), dialogButton[butcount],
- ! FALSE, FALSE, 0);
- break;
- } else {
- ! gtk_box_pack_start(GTK_BOX(action_area), dialogButton[butcount],
- ! FALSE, FALSE, 0);
- }
- p = next;
- }
- ! ++butcount;
- ! vim_free(buts);
- ! if (dfltbutton < 1)
- ! dfltbutton = 1;
- ! if (dfltbutton > butcount)
- ! dfltbutton = butcount;
- ! /* XtVaSetValues(dialogbb, XmNdefaultButton, dialogButton[dfltbutton - 1], NULL); */
-
- ! gtk_widget_grab_focus(dialogButton[dfltbutton - 1]);
- ! gtk_widget_grab_default(dialogButton[dfltbutton - 1]);
-
- separator = gtk_hseparator_new();
- gtk_box_pack_end(GTK_BOX(vbox), separator, FALSE, TRUE, 0);
- gtk_widget_show(separator);
-
- ! dialogStatus = -1;
- ! gtk_widget_show(dialogbb);
- ! while (dialogbb) /* stay here until dialog goes away */
- gtk_main_iteration_do(TRUE);
-
- ! return dialogStatus;
- }
-
- - /* ARGSUSED */
- - static void
- - butproc(GtkWidget * widget, gpointer data)
- - {
- - dialogStatus = (GPOINTER_TO_INT(data)) + 1;
- -
- - gtk_widget_destroy(dialogbb);
- - dialogbb = NULL;
- - if (gtk_main_level() > 0)
- - gtk_main_quit();
- - }
-
- #endif /* GUI_DIALOG */
-
- --- 1077,1131 ----
- }
- }
-
- ! button[butcount] = gtk_button_new_with_label((const gchar *)p);
- ! GTK_WIDGET_SET_FLAGS(button[butcount], GTK_CAN_DEFAULT);
- ! gtk_widget_show(button[butcount]);
- !
- ! data[butcount].status = &dialog_status;
- ! data[butcount].index = butcount;
- ! data[butcount].dialog = dialog;
- ! gtk_signal_connect(GTK_OBJECT(button[butcount]),
- (const char *)"clicked",
- ! GTK_SIGNAL_FUNC(dlg_button_clicked),
- ! (gpointer) &data[butcount]);
-
- if (*next == NUL) {
- ! gtk_box_pack_end(GTK_BOX(action_area), button[butcount],
- ! FALSE, TRUE, 0);
- break;
- } else {
- ! gtk_box_pack_start(GTK_BOX(sub_area), button[butcount],
- ! TRUE, TRUE, 0);
- }
- p = next;
- }
- ! vim_free(names);
- !
- ! --def_but; /* 1 is first button */
- ! if (def_but < 0)
- ! def_but = 0;
- ! if (def_but > butcount)
- ! def_but = butcount;
-
- ! gtk_widget_grab_focus(button[def_but]);
- ! gtk_widget_grab_default(button[def_but]);
-
- separator = gtk_hseparator_new();
- gtk_box_pack_end(GTK_BOX(vbox), separator, FALSE, TRUE, 0);
- gtk_widget_show(separator);
-
- ! dialog_status = -1;
- ! gtk_widget_show(dialog);
- !
- ! /* loop here until the dialog goes away */
- ! while (dialog_status == -1 && GTK_WIDGET_VISIBLE(dialog))
- gtk_main_iteration_do(TRUE);
-
- ! if (dialog_status < 0)
- ! dialog_status = 0;
- ! return dialog_status;
- }
-
-
- #endif /* GUI_DIALOG */
-
- ***************
- *** 1069,1081 ****
- gui_mch_show_popupmenu(VimMenu * menu)
- {
- gtk_menu_popup(GTK_MENU(menu->submenu_id),
- ! NULL, NULL, NULL, NULL, 3, GDK_CURRENT_TIME);
- }
- #endif
-
-
- /*
- ! * Don't create it twice!
- */
-
- typedef struct _SharedFindReplace {
- --- 1134,1146 ----
- gui_mch_show_popupmenu(VimMenu * menu)
- {
- gtk_menu_popup(GTK_MENU(menu->submenu_id),
- ! NULL, NULL, NULL, NULL, 3, (guint32)GDK_CURRENT_TIME);
- }
- #endif
-
-
- /*
- ! * We don't create it twice.
- */
-
- typedef struct _SharedFindReplace {
- ***************
- *** 1090,1165 ****
- GtkWidget *all; /* 'Replace All' action button */
- } SharedFindReplace;
-
- ! static SharedFindReplace find_widgets;
- ! static SharedFindReplace repl_widgets;
- !
-
- ! /*ARGSUSED*/
- ! void
- ! gui_mch_find_dialog(char_u * arg)
- {
- ! find_replace_dialog_create(FALSE);
- ! }
- !
-
- ! /*ARGSUSED*/
- ! void
- ! gui_mch_replace_dialog(char_u * arg)
- ! {
- ! find_replace_dialog_create(TRUE);
- ! }
-
-
- ! /*
- ! * Synchronize all gui elements, which are dependant upon the
- ! * main text font used. Those are in esp. the find/replace dialogs.
- ! * If You don't understand why this should be needed, please try to
- ! * search for "piΩ╢µ" in iso8859-2.
- ! */
- ! void gui_gtk_synch_fonts(void)
- ! {
- ! SharedFindReplace *frdp;
- ! int do_replace;
-
- ! /* OK this loop is a bit tricky... */
- ! for (do_replace = 0; do_replace <= 1; ++do_replace) {
- ! frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
- ! if (frdp->dialog) {
- ! GtkStyle *style;
-
- ! /* synch the font with whats used by the text itself */
- ! style = gtk_style_copy(gtk_widget_get_style(frdp->what));
- ! gdk_font_unref(style->font);
- ! style->font = gui.norm_font;
- ! gdk_font_ref(style->font);
- ! gtk_widget_set_style(frdp->what, style);
- ! gtk_style_unref(style);
- ! if (do_replace) {
- ! style = gtk_style_copy(gtk_widget_get_style(frdp->with));
- ! gdk_font_unref(style->font);
- ! style->font = gui.norm_font;
- ! gdk_font_ref(style->font);
- ! gtk_widget_set_style(frdp->with, style);
- ! gtk_style_unref(style);
- ! }
- ! }
- ! }
- }
-
- static void
- ! find_replace_dialog_create(int do_replace)
- {
- ! GtkWidget *hbox; /* main top down box */
- ! GtkWidget *actionarea;
- ! GtkWidget *table;
- ! GtkWidget *tmp;
- ! GtkWidget *vbox;
- ! gboolean sensitive;
- SharedFindReplace *frdp;
- ! char *entry_text;
-
- frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
-
- if (frdp->dialog) {
- gui_gtk_synch_fonts();
- if (!GTK_WIDGET_VISIBLE(frdp->dialog)) {
- --- 1155,1238 ----
- GtkWidget *all; /* 'Replace All' action button */
- } SharedFindReplace;
-
- ! static SharedFindReplace find_widgets = { NULL };
- ! static SharedFindReplace repl_widgets = { NULL };
-
- ! /* ARGSUSED */
- ! static int
- ! find_key_press_event(GtkWidget * widget,
- ! GdkEventKey * event,
- ! SharedFindReplace * frdp)
- {
- ! /* If the user is holding one of the key modifiers we will just bail out,
- ! * thus preserving the possibility of normal focus traversal.
- ! */
- ! if (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))
- ! return FALSE;
-
- ! /* the scape key synthesizes a cancellation action */
- ! if (event->keyval == GDK_Escape) {
- ! find_replace_cb(widget, FR_DIALOGTERM);
- ! gtk_widget_hide(frdp->dialog);
-
- + return TRUE;
- + }
-
- ! /* block traversal resulting from those keys */
- ! if (event->keyval == GDK_Left || event->keyval == GDK_Right)
- ! return TRUE;
-
- ! /* It would be delightfull if it where possible to do search history
- ! * operations on the K_UP and K_DOWN keys here.
- ! */
-
- ! return FALSE;
- }
-
- static void
- ! find_replace_dialog_create(char_u *arg, int do_replace)
- {
- ! GtkWidget *frame;
- ! GtkWidget *hbox; /* main top down box */
- ! GtkWidget *actionarea;
- ! GtkWidget *table;
- ! GtkWidget *tmp;
- ! GtkWidget *vbox;
- ! gboolean sensitive;
- SharedFindReplace *frdp;
- ! char_u *entry_text = arg;
- ! gboolean exact_word = FALSE;
-
- frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
-
- + /*
- + * If the argument is emtpy, get the last used search pattern. If it is
- + * surrounded by "\<..\>" remove that and set the "exact_word" toggle
- + * button.
- + */
- + if (*entry_text == NUL)
- + entry_text = last_search_pat();
- + if (entry_text != NULL)
- + {
- + entry_text = vim_strsave(entry_text);
- + if (entry_text != NULL)
- + {
- + int len = STRLEN(entry_text);
- +
- + if (len >= 4
- + && STRNCMP(entry_text, "\\<", 2) == 0
- + && STRNCMP(entry_text + len - 2, "\\>", 2) == 0)
- + {
- + exact_word = TRUE;
- + mch_memmove(entry_text, entry_text + 2, (size_t)(len - 4));
- + entry_text[len - 4] = NUL;
- + }
- + }
- + }
- +
- + /*
- + * If the dialog already exists, just raise it.
- + */
- if (frdp->dialog) {
- gui_gtk_synch_fonts();
- if (!GTK_WIDGET_VISIBLE(frdp->dialog)) {
- ***************
- *** 1167,1174 ****
- --- 1240,1254 ----
- gtk_widget_show(frdp->dialog);
- }
-
- + if (entry_text != NULL)
- + {
- + gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text);
- + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->exact),
- + exact_word);
- + }
- gdk_window_raise(frdp->dialog->window);
-
- + vim_free(entry_text);
- return;
- }
-
- ***************
- *** 1182,1190 ****
- }
-
- gtk_window_position(GTK_WINDOW(frdp->dialog), GTK_WIN_POS_MOUSE);
-
- hbox = gtk_hbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(frdp->dialog), hbox);
-
- if (do_replace)
- table = gtk_table_new(1024, 4, FALSE);
- --- 1262,1279 ----
- }
-
- gtk_window_position(GTK_WINDOW(frdp->dialog), GTK_WIN_POS_MOUSE);
- + gtk_widget_realize(frdp->dialog);
- + gdk_window_set_decorations(frdp->dialog->window,
- + GDK_DECOR_TITLE | GDK_DECOR_BORDER | GDK_DECOR_RESIZEH);
- + gdk_window_set_functions(frdp->dialog->window,
- + GDK_FUNC_RESIZE | GDK_FUNC_MOVE);
- +
- + /* this makes it look beter on Motif style window managers */
- + frame = gtk_frame_new(NULL);
- + gtk_container_add(GTK_CONTAINER(frdp->dialog), frame);
-
- hbox = gtk_hbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(frame), hbox);
-
- if (do_replace)
- table = gtk_table_new(1024, 4, FALSE);
- ***************
- *** 1198,1208 ****
- gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 0, 1,
- GTK_FILL, GTK_EXPAND, 2, 2);
- frdp->what = gtk_entry_new();
- ! entry_text = gtk_entry_get_text(GTK_ENTRY(frdp->what));
- ! sensitive = (strlen(entry_text) != 0);
- ! gtk_entry_set_text(GTK_ENTRY(frdp->what), entry_text);
- gtk_signal_connect(GTK_OBJECT(frdp->what), "changed",
- GTK_SIGNAL_FUNC(entry_changed_cb), frdp->dialog);
- gtk_table_attach(GTK_TABLE(table), frdp->what, 1, 1024, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2);
-
- --- 1287,1300 ----
- gtk_table_attach(GTK_TABLE(table), tmp, 0, 1, 0, 1,
- GTK_FILL, GTK_EXPAND, 2, 2);
- frdp->what = gtk_entry_new();
- ! sensitive = (entry_text != NULL && STRLEN(entry_text) != 0);
- ! if (entry_text != NULL)
- ! gtk_entry_set_text(GTK_ENTRY(frdp->what), (char *)entry_text);
- gtk_signal_connect(GTK_OBJECT(frdp->what), "changed",
- GTK_SIGNAL_FUNC(entry_changed_cb), frdp->dialog);
- + gtk_signal_connect_after(GTK_OBJECT(frdp->what), "key_press_event",
- + GTK_SIGNAL_FUNC(find_key_press_event),
- + (gpointer) frdp);
- gtk_table_attach(GTK_TABLE(table), frdp->what, 1, 1024, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2);
-
- ***************
- *** 1215,1220 ****
- --- 1307,1315 ----
- gtk_signal_connect(GTK_OBJECT(frdp->with), "activate",
- GTK_SIGNAL_FUNC(find_replace_cb),
- (gpointer) FR_R_FINDNEXT);
- + gtk_signal_connect_after(GTK_OBJECT(frdp->with), "key_press_event",
- + GTK_SIGNAL_FUNC(find_key_press_event),
- + (gpointer) frdp);
- gtk_table_attach(GTK_TABLE(table), frdp->with, 1, 1024, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, 2, 2);
-
- ***************
- *** 1235,1241 ****
-
- /* exact match only button */
- frdp->exact = gtk_check_button_new_with_label("Match exact word only");
- ! gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->exact), FALSE);
- gtk_signal_connect(GTK_OBJECT(frdp->exact), "clicked",
- GTK_SIGNAL_FUNC(exact_match_cb), NULL);
- if (do_replace)
- --- 1330,1336 ----
-
- /* exact match only button */
- frdp->exact = gtk_check_button_new_with_label("Match exact word only");
- ! gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(frdp->exact), exact_word);
- gtk_signal_connect(GTK_OBJECT(frdp->exact), "clicked",
- GTK_SIGNAL_FUNC(exact_match_cb), NULL);
- if (do_replace)
- ***************
- *** 1256,1262 ****
- gtk_container_border_width(GTK_CONTAINER(vbox), 0);
- gtk_container_add(GTK_CONTAINER(tmp), vbox);
-
- ! /* 'up' and 'down' buttons */
- frdp->up = gtk_radio_button_new_with_label(NULL, "Up");
- gtk_box_pack_start(GTK_BOX(vbox), frdp->up, TRUE, TRUE, 0);
- frdp->down = gtk_radio_button_new_with_label(
- --- 1351,1357 ----
- gtk_container_border_width(GTK_CONTAINER(vbox), 0);
- gtk_container_add(GTK_CONTAINER(tmp), vbox);
-
- ! /* 'Up' and 'Down' buttons */
- frdp->up = gtk_radio_button_new_with_label(NULL, "Up");
- gtk_box_pack_start(GTK_BOX(vbox), frdp->up, TRUE, TRUE, 0);
- frdp->down = gtk_radio_button_new_with_label(
- ***************
- *** 1281,1287 ****
- }
- gtk_box_pack_end(GTK_BOX(hbox), actionarea, FALSE, FALSE, 0);
-
- ! /* 'find next' button */
- frdp->find = gtk_button_new_with_label("Find Next");
- gtk_widget_set_sensitive(frdp->find, sensitive);
- if (do_replace)
- --- 1376,1382 ----
- }
- gtk_box_pack_end(GTK_BOX(hbox), actionarea, FALSE, FALSE, 0);
-
- ! /* 'Find Next' button */
- frdp->find = gtk_button_new_with_label("Find Next");
- gtk_widget_set_sensitive(frdp->find, sensitive);
- if (do_replace)
- ***************
- *** 1297,1303 ****
- gtk_widget_grab_default(frdp->find);
-
- if (do_replace) {
- ! /* 'replace' button */
- frdp->replace = gtk_button_new_with_label("Replace");
- gtk_widget_set_sensitive(frdp->replace, sensitive);
- GTK_WIDGET_SET_FLAGS(frdp->replace, GTK_CAN_DEFAULT);
- --- 1392,1398 ----
- gtk_widget_grab_default(frdp->find);
-
- if (do_replace) {
- ! /* 'Replace' button */
- frdp->replace = gtk_button_new_with_label("Replace");
- gtk_widget_set_sensitive(frdp->replace, sensitive);
- GTK_WIDGET_SET_FLAGS(frdp->replace, GTK_CAN_DEFAULT);
- ***************
- *** 1306,1312 ****
- GTK_SIGNAL_FUNC(find_replace_cb),
- (gpointer) FR_REPLACE);
-
- ! /* 'replace all' button */
- frdp->all = gtk_button_new_with_label("Replace All");
- gtk_widget_set_sensitive(frdp->all, sensitive);
- GTK_WIDGET_SET_FLAGS(frdp->all, GTK_CAN_DEFAULT);
- --- 1401,1407 ----
- GTK_SIGNAL_FUNC(find_replace_cb),
- (gpointer) FR_REPLACE);
-
- ! /* 'Replace All' button */
- frdp->all = gtk_button_new_with_label("Replace All");
- gtk_widget_set_sensitive(frdp->all, sensitive);
- GTK_WIDGET_SET_FLAGS(frdp->all, GTK_CAN_DEFAULT);
- ***************
- *** 1316,1322 ****
- (gpointer) FR_REPLACEALL);
- }
-
- ! /* 'cancel' button */
- tmp = gtk_button_new_with_label("Cancel");
- GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
- gtk_box_pack_end(GTK_BOX(actionarea), tmp, FALSE, FALSE, 0);
- --- 1411,1417 ----
- (gpointer) FR_REPLACEALL);
- }
-
- ! /* 'Cancel' button */
- tmp = gtk_button_new_with_label("Cancel");
- GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
- gtk_box_pack_end(GTK_BOX(actionarea), tmp, FALSE, FALSE, 0);
- ***************
- *** 1340,1350 ****
- gui_gtk_synch_fonts();
-
- gtk_widget_show_all(frdp->dialog);
- }
-
- /*
- * Convenience function.
- ! * creates a button with a label, and packs it into the box specified by the
- * parameter 'parent'.
- */
- GtkWidget *
- --- 1435,1499 ----
- gui_gtk_synch_fonts();
-
- gtk_widget_show_all(frdp->dialog);
- +
- + vim_free(entry_text);
- + }
- +
- + void
- + gui_mch_find_dialog(char_u * arg)
- + {
- + find_replace_dialog_create(arg, FALSE);
- + }
- +
- +
- + void
- + gui_mch_replace_dialog(char_u * arg)
- + {
- + find_replace_dialog_create(arg, TRUE);
- + }
- +
- +
- + /*
- + * Synchronize all gui elements, which are dependant upon the
- + * main text font used. Those are in esp. the find/replace dialogs.
- + * If You don't understand why this should be needed, please try to
- + * search for "piΩ╢µ" in iso8859-2.
- + */
- + void
- + gui_gtk_synch_fonts(void)
- + {
- + SharedFindReplace *frdp;
- + int do_replace;
- +
- + /* OK this loop is a bit tricky... */
- + for (do_replace = 0; do_replace <= 1; ++do_replace) {
- + frdp = (do_replace) ? (&repl_widgets) : (&find_widgets);
- + if (frdp->dialog) {
- + GtkStyle *style;
- +
- + /* synch the font with whats used by the text itself */
- + style = gtk_style_copy(gtk_widget_get_style(frdp->what));
- + gdk_font_unref(style->font);
- + style->font = gui.norm_font;
- + gdk_font_ref(style->font);
- + gtk_widget_set_style(frdp->what, style);
- + gtk_style_unref(style);
- + if (do_replace) {
- + style = gtk_style_copy(gtk_widget_get_style(frdp->with));
- + gdk_font_unref(style->font);
- + style->font = gui.norm_font;
- + gdk_font_ref(style->font);
- + gtk_widget_set_style(frdp->with, style);
- + gtk_style_unref(style);
- + }
- + }
- + }
- }
-
- +
- /*
- * Convenience function.
- ! * Creates a button with a label, and packs it into the box specified by the
- * parameter 'parent'.
- */
- GtkWidget *
- ***************
- *** 1355,1362 ****
- GtkWidget *parent,
- int connect_object,
- gboolean expand,
- ! gboolean fill
- ! )
- {
- GtkWidget *tmp;
-
- --- 1504,1510 ----
- GtkWidget *parent,
- int connect_object,
- gboolean expand,
- ! gboolean fill)
- {
- GtkWidget *tmp;
-
- ***************
- *** 1374,1418 ****
-
- /*** private function definitions ***/
-
- - #ifdef WANT_MENU
- - static void
- - gui_mch_recurse_tearoffs(VimMenu * menu, int val)
- - {
- - #ifdef GTK_HAVE_FEATURES_1_1_0
- - while (menu != NULL) {
- - if (!popup_menu(menu->name)) {
- - if (menu->submenu_id != 0) {
- - if (val)
- - gtk_widget_show(menu->tearoff_handle);
- - else
- - gtk_widget_hide(menu->tearoff_handle);
- - }
- - gui_mch_recurse_tearoffs(menu->children, val);
- - }
- - menu = menu->next;
- - }
- - #endif
- - }
- -
- - /*ARGSUSED*/
- - static void
- - menu_item_cb(GtkWidget * widget, gpointer data)
- - {
- - gui_menu_cb((VimMenu *) data);
- -
- - /* make sure the menu action is taken immediately */
- - if (gtk_main_level() > 0)
- - gtk_main_quit();
- - }
- - #endif
- -
- -
- /*
- * Callback for actions of the find and replace dialogs
- */
- /*ARGSUSED*/
- static void
- ! find_replace_cb(GtkWidget * widget, gint flags)
- {
- char *find_text, *repl_text, *cmd;
- gboolean direction_down = TRUE;
- --- 1522,1533 ----
-
- /*** private function definitions ***/
-
- /*
- * Callback for actions of the find and replace dialogs
- */
- /*ARGSUSED*/
- static void
- ! find_replace_cb(GtkWidget * widget, unsigned int flags)
- {
- char *find_text, *repl_text, *cmd;
- gboolean direction_down = TRUE;
- ***************
- *** 1519,1525 ****
- }
-
- g_free(cmd);
- ! } /* find_replace_cb */
-
- /* our usual callback function */
- /*ARGSUSED*/
- --- 1634,1640 ----
- }
-
- g_free(cmd);
- ! }
-
- /* our usual callback function */
- /*ARGSUSED*/
- ***************
- *** 1615,1631 ****
- }
- }
-
- !
- ! static void helpfind_ok(GtkWidget *wgt, gpointer cbdata);
- ! static void helpfind_entry_changed(GtkWidget *entry, gpointer cbdata);
-
- static GtkWidget *helpfind = NULL;
- static GtkWidget *help_entry = NULL;
-
- ! void
- ! do_helpfind()
- {
- ! GtkWidget *vbox, *hbox, *tmp;
-
- if (!gui.in_use)
- {
- --- 1730,1808 ----
- }
- }
-
- ! /*
- ! * Handling of the nice additional asynchronous little help topic requester.
- ! */
-
- static GtkWidget *helpfind = NULL;
- static GtkWidget *help_entry = NULL;
- + static int help_ok_sensitive = FALSE;
-
- ! static void
- ! helpfind_entry_changed(GtkWidget *entry, gpointer cbdata)
- {
- ! GtkWidget *ok = (GtkWidget *)cbdata;
- ! char *txt = gtk_entry_get_text(GTK_ENTRY(entry));
- !
- ! if (txt == NULL || *txt == NUL)
- ! return;
- !
- ! gtk_widget_set_sensitive(ok, strlen(txt));
- ! gtk_widget_grab_default(ok);
- ! help_ok_sensitive = TRUE;
- ! }
- !
- ! /*ARGSUSED*/
- ! static void
- ! helpfind_ok(GtkWidget *wgt, gpointer cbdata)
- ! {
- ! char *txt, *cmd;
- ! GtkEntry *entry = GTK_ENTRY(cbdata);
- !
- ! if ((txt = gtk_entry_get_text(entry)) == NULL)
- ! return;
- !
- ! /* When the OK button isn't sensitive, hitting CR means cancel. */
- ! if (help_ok_sensitive)
- ! {
- ! if ((cmd = (char *)alloc(strlen(txt) + 8)) == NULL)
- ! return;
- !
- ! /* use CTRL-\ CTRL-N to get Vim into Normal mode first */
- ! g_snprintf(cmd, (gulong)(strlen(txt) + 7), "\034\016:h %s\r", txt);
- ! add_to_input_buf((char_u *)cmd, STRLEN(cmd));
- ! vim_free(cmd);
- ! }
- !
- ! /* Don't destroy this dialogue just hide it from the users view.
- ! * Reuse it later */
- ! gtk_widget_hide(helpfind);
- !
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- ! }
- !
- ! /*ARGSUSED*/
- ! static void
- ! helpfind_cancel(GtkWidget *wgt, gpointer cbdata)
- ! {
- ! /* Don't destroy this dialogue just hide it from the users view.
- ! * Reuse it later */
- ! gtk_widget_hide(helpfind);
- !
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- ! }
- !
- ! void
- ! do_helpfind(void)
- ! {
- ! GtkWidget *frame;
- ! GtkWidget *vbox;
- ! GtkWidget *hbox;
- ! GtkWidget *tmp;
- ! GtkWidget *action_area;
- ! GtkWidget *sub_area;
-
- if (!gui.in_use)
- {
- ***************
- *** 1650,1735 ****
- gtk_window_set_transient_for(GTK_WINDOW(helpfind), GTK_WINDOW(gui.mainwin));
- #endif
- gtk_window_position(GTK_WINDOW(helpfind), GTK_WIN_POS_MOUSE);
- ! gtk_window_set_title(GTK_WINDOW(helpfind), "VIM - Help on what?");
- gtk_signal_connect(GTK_OBJECT(helpfind), "destroy",
- GTK_SIGNAL_FUNC(gtk_widget_destroyed), &helpfind);
-
- ! vbox = gtk_vbox_new(FALSE, 6);
- ! gtk_container_add(GTK_CONTAINER(helpfind), vbox);
- ! gtk_container_border_width(GTK_CONTAINER(helpfind), 6);
-
- hbox = gtk_hbox_new(FALSE, 6);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
-
- ! tmp = gtk_label_new("Topic: ");
- gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 0);
-
- help_entry = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(hbox), help_entry, TRUE, TRUE, 0);
-
- ! tmp = gtk_hseparator_new();
- ! gtk_box_pack_start(GTK_BOX(vbox), tmp, FALSE, TRUE, 0);
-
- ! hbox = gtk_hbutton_box_new();
- ! gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_EDGE);
- ! gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 0);
- ! gtk_container_border_width(GTK_CONTAINER(hbox), 0);
- ! gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
- !
- ! tmp = gui_gtk_button_new_with_label("Ok",
- ! GTK_SIGNAL_FUNC(helpfind_ok),
- ! help_entry, hbox, FALSE, FALSE, FALSE);
- gtk_signal_connect(GTK_OBJECT(help_entry), "changed",
- GTK_SIGNAL_FUNC(helpfind_entry_changed), tmp);
- gtk_signal_connect(GTK_OBJECT(help_entry), "activate",
- GTK_SIGNAL_FUNC(helpfind_ok), help_entry);
- gtk_widget_set_sensitive(tmp, FALSE);
- GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
-
- ! tmp = gui_gtk_button_new_with_label("Cancel",
- ! GTK_SIGNAL_FUNC(gtk_widget_destroy),
- ! helpfind, hbox, TRUE, FALSE, FALSE);
- ! GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
- ! gtk_widget_grab_default(tmp);
-
- gtk_widget_grab_focus(help_entry);
- gtk_widget_show_all(helpfind);
- - }
- -
- -
- - static void
- - helpfind_entry_changed(GtkWidget *entry, gpointer cbdata)
- - {
- - GtkWidget *ok = (GtkWidget *)cbdata;
- - char *txt = gtk_entry_get_text(GTK_ENTRY(entry));
- -
- - if (txt == NULL)
- - return;
- -
- - gtk_widget_set_sensitive(ok, strlen(txt));
- - }
- -
- -
- - /*ARGSUSED*/
- - static void
- - helpfind_ok(GtkWidget *wgt, gpointer cbdata)
- - {
- - char *txt, *cmd;
- - GtkEntry *entry = GTK_ENTRY(cbdata);
- -
- - if ((txt = gtk_entry_get_text(entry)) == NULL)
- - return;
- -
- - if ((cmd = (char *)alloc(strlen(txt) + 8)) == NULL)
- - return;
- -
- - /* use CTRL-\ CTRL-N to get Vim into Normal mode first */
- - g_snprintf(cmd, (gulong)(strlen(txt) + 7), "\034\016:h %s\r", txt);
- - add_to_input_buf((char_u *)cmd, STRLEN(cmd));
- -
- - gtk_widget_destroy(helpfind);
- - vim_free(cmd);
- -
- - if (gtk_main_level() > 0)
- - gtk_main_quit();
- }
- --- 1827,1888 ----
- gtk_window_set_transient_for(GTK_WINDOW(helpfind), GTK_WINDOW(gui.mainwin));
- #endif
- gtk_window_position(GTK_WINDOW(helpfind), GTK_WIN_POS_MOUSE);
- ! gtk_window_set_title(GTK_WINDOW(helpfind), "VIM - Help on...");
- !
- ! gtk_widget_realize(helpfind);
- ! gdk_window_set_decorations(helpfind->window,
- ! GDK_DECOR_BORDER | GDK_DECOR_TITLE);
- ! gdk_window_set_functions(helpfind->window, GDK_FUNC_MOVE);
- !
- gtk_signal_connect(GTK_OBJECT(helpfind), "destroy",
- GTK_SIGNAL_FUNC(gtk_widget_destroyed), &helpfind);
-
- ! /* this makes it look beter on Motif style window managers */
- ! frame = gtk_frame_new(NULL);
- ! gtk_container_add(GTK_CONTAINER(helpfind), frame);
- ! gtk_widget_show(frame);
- !
- ! vbox = gtk_vbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(frame), vbox);
-
- hbox = gtk_hbox_new(FALSE, 6);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
- + gtk_container_border_width(GTK_CONTAINER(hbox), 6);
-
- ! tmp = gtk_label_new("Topic:");
- gtk_box_pack_start(GTK_BOX(hbox), tmp, TRUE, TRUE, 0);
-
- help_entry = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(hbox), help_entry, TRUE, TRUE, 0);
-
- ! action_area = gtk_hbox_new(FALSE, 0);
- ! gtk_container_set_border_width(GTK_CONTAINER(action_area), 4);
- ! gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0);
-
- ! sub_area = gtk_hbox_new(TRUE, 0);
- ! gtk_container_set_border_width(GTK_CONTAINER(sub_area), 0);
- ! gtk_box_pack_end(GTK_BOX(action_area), sub_area, FALSE, TRUE, 0);
- !
- ! tmp = gui_gtk_button_new_with_label("Cancel",
- ! GTK_SIGNAL_FUNC(helpfind_cancel),
- ! help_entry, sub_area, TRUE, TRUE, TRUE);
- ! GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
- ! gtk_widget_grab_default(tmp);
- !
- ! tmp = gui_gtk_button_new_with_label("OK",
- ! GTK_SIGNAL_FUNC(helpfind_ok),
- ! help_entry, sub_area, FALSE, TRUE, TRUE);
- gtk_signal_connect(GTK_OBJECT(help_entry), "changed",
- GTK_SIGNAL_FUNC(helpfind_entry_changed), tmp);
- gtk_signal_connect(GTK_OBJECT(help_entry), "activate",
- GTK_SIGNAL_FUNC(helpfind_ok), help_entry);
- gtk_widget_set_sensitive(tmp, FALSE);
- + help_ok_sensitive = FALSE;
- GTK_WIDGET_SET_FLAGS(tmp, GTK_CAN_DEFAULT);
-
- ! tmp = gtk_hseparator_new();
- ! gtk_box_pack_end(GTK_BOX(vbox), tmp, FALSE, TRUE, 0);
-
- gtk_widget_grab_focus(help_entry);
- gtk_widget_show_all(helpfind);
- }
- *** ../vim-5.6a.17/src/gui_gtk_x11.c Wed Dec 29 12:11:01 1999
- --- src/gui_gtk_x11.c Sat Jan 8 21:15:25 2000
- ***************
- *** 19,24 ****
- --- 19,29 ----
- * :-) <dalecki@cs.net.pl> (My native language is polish and I speak
- * native grade german too. I'm living in GĂ·ttingen.de.)
- * --mdcki"
- + *
- + *
- + * Although some #ifdefs suggest that GTK 1.0 is supported, it isn't. The
- + * code requires GTK version 1.1.16 or later. Stuff for older versions will
- + * be removed some time.
- */
-
- #include "vim.h"
- ***************
- *** 36,46 ****
-
- /* slection distinguishers */
- enum {
- ! SEL_TYPE_NONE,
- SELECTION_STRING,
- SELECTION_CLIPBOARD
- };
-
- /* This is the single only fixed width font in X11, which seems to be present
- * on all servers and available in all the variants we need.
- *
- --- 41,69 ----
-
- /* slection distinguishers */
- enum {
- ! SELECTION_TYPE_NONE,
- SELECTION_STRING,
- SELECTION_CLIPBOARD
- };
-
- + /*
- + * Enable DND feature. Disable this if it causes problems.
- + */
- + #define GTK_DND
- +
- + #ifdef GTK_DND
- + /* DND specification constants. */
- + enum {
- + TARGET_STRING
- + };
- +
- + static GtkTargetEntry target_table[] = {
- + { "STRING", 0, TARGET_STRING },
- + { "text/plain", 0, TARGET_STRING }
- + };
- + static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
- + #endif
- +
- /* This is the single only fixed width font in X11, which seems to be present
- * on all servers and available in all the variants we need.
- *
- ***************
- *** 50,78 ****
-
- #define DFLT_FONT "-adobe-courier-medium-r-normal-*-14-*-*-*-m-*-*-*"
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! static void font_sel_ok(GtkWidget *wgt, gpointer cbdata);
- ! static void font_sel_cancel(GtkWidget *wgt, gpointer cbdata);
- ! static void font_sel_destroy(GtkWidget *wgt, gpointer cbdata);
- ! #endif
- !
- ! static gint expose_event(GtkWidget * widget, GdkEventExpose * event);
- ! static gint button_press_event(GtkWidget * widget, GdkEventButton * event);
- ! static gint button_release_event(GtkWidget * widget, GdkEventButton * event);
- ! static gint motion_notify_event(GtkWidget * widget, GdkEventMotion * event);
- ! static void destroy_callback(void);
- ! static int delete_event_cb(GtkWidget *wgt, gpointer cbdata);
-
- /*
- ! * If of the atom used to communicate save yourself from the X11 session
- ! * manager. There is no need to move this into the GUI struct, since this
- ! * should be always constant.
- */
- ! GdkAtom save_yourself_atom = GDK_NONE;
-
- /*
- * Keycodes recognized by vim.
- - * we will be using the techniques described here later for real work.
- */
- static struct special_key {
- guint key_sym;
- --- 73,93 ----
-
- #define DFLT_FONT "-adobe-courier-medium-r-normal-*-14-*-*-*-m-*-*-*"
-
- ! /*
- ! * Atom used to communicate save yourself from the X11 session manager. There
- ! * is no need to move this into the GUI struct, since this should be always
- ! * constant.
- ! */
- ! static GdkAtom save_yourself_atom = GDK_NONE;
-
- /*
- ! * Atom used to recognize requests for on the fly GTK+ style configuration
- ! * changes.
- */
- ! static GdkAtom reread_rcfiles_atom = GDK_NONE;
-
- /*
- * Keycodes recognized by vim.
- */
- static struct special_key {
- guint key_sym;
- ***************
- *** 306,311 ****
- --- 321,357 ----
- #endif
-
- /*
- + * Redraw the corresponding portions of the screen.
- + */
- + /*ARGSUSED*/
- + static gint
- + expose_event(GtkWidget * widget, GdkEventExpose * event)
- + {
- + out_flush(); /* make sure all output has been processed */
- + gui_redraw(event->area.x, event->area.y,
- + event->area.width, event->area.height);
- +
- + /* Clear the border areas if needed */
- + if (event->area.x < FILL_X(0))
- + gdk_window_clear_area(gui.drawarea->window, 0, 0, FILL_X(0), 0);
- + if (event->area.y < FILL_Y(0))
- + gdk_window_clear_area(gui.drawarea->window, 0, 0, 0, FILL_Y(0));
- + if (event->area.x > FILL_X(Columns))
- + gdk_window_clear_area(gui.drawarea->window,
- + FILL_X((int)Columns), 0, 0, 0);
- + if (event->area.y > FILL_Y(Rows))
- + gdk_window_clear_area(gui.drawarea->window, 0, FILL_Y((int)Rows), 0, 0);
- +
- + return FALSE;
- + }
- +
- +
- + /****************************************************************************
- + * Focus handlers:
- + */
- +
- +
- + /*
- * This is a simple state machine:
- * BLINK_NONE not blinking at all
- * BLINK_OFF blinking, cursor is not shown
- ***************
- *** 347,364 ****
-
- /*ARGSUSED*/
- static gint
- ! gui_gtk_blink_cb(gpointer data)
- {
- if (blink_state == BLINK_ON) {
- gui_undraw_cursor();
- blink_state = BLINK_OFF;
- ! blink_timer = gtk_timeout_add(blink_offtime,
- ! (GtkFunction) gui_gtk_blink_cb, NULL);
- } else {
- gui_update_cursor(TRUE, FALSE);
- blink_state = BLINK_ON;
- ! blink_timer = gtk_timeout_add(blink_ontime,
- ! (GtkFunction) gui_gtk_blink_cb, NULL);
- }
-
- return FALSE; /* don't happen again */
- --- 393,410 ----
-
- /*ARGSUSED*/
- static gint
- ! blink_cb(gpointer data)
- {
- if (blink_state == BLINK_ON) {
- gui_undraw_cursor();
- blink_state = BLINK_OFF;
- ! blink_timer = gtk_timeout_add((guint32)blink_offtime,
- ! (GtkFunction) blink_cb, NULL);
- } else {
- gui_update_cursor(TRUE, FALSE);
- blink_state = BLINK_ON;
- ! blink_timer = gtk_timeout_add((guint32)blink_ontime,
- ! (GtkFunction) blink_cb, NULL);
- }
-
- return FALSE; /* don't happen again */
- ***************
- *** 375,382 ****
- gtk_timeout_remove(blink_timer);
- /* Only switch blinking on if none of the times is zero */
- if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) {
- ! blink_timer = gtk_timeout_add(blink_waittime,
- ! (GtkFunction) gui_gtk_blink_cb, NULL);
- blink_state = BLINK_ON;
- gui_update_cursor(TRUE, FALSE);
- }
- --- 421,428 ----
- gtk_timeout_remove(blink_timer);
- /* Only switch blinking on if none of the times is zero */
- if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) {
- ! blink_timer = gtk_timeout_add((guint32)blink_waittime,
- ! (GtkFunction) blink_cb, NULL);
- blink_state = BLINK_ON;
- gui_update_cursor(TRUE, FALSE);
- }
- ***************
- *** 437,451 ****
- }
-
-
- /*ARGSUSED*/
- static gint
- key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer data)
- {
- - #ifdef USE_XIM
- char_u string[256], string2[256];
- - #else
- - char_u string[3], string2[3];
- - #endif
- guint key_sym;
- int len;
- int i;
- --- 483,497 ----
- }
-
-
- + /****************************************************************************
- + * Main keyboard handler:
- + */
- +
- /*ARGSUSED*/
- static gint
- key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer data)
- {
- char_u string[256], string2[256];
- guint key_sym;
- int len;
- int i;
- ***************
- *** 571,576 ****
- --- 617,628 ----
- return TRUE;
- }
-
- +
- + /****************************************************************************
- + * Selection handlers:
- + */
- +
- +
- /*ARGSUSED*/
- static gint
- selection_clear_event(GtkWidget * widget, GdkEventSelection * event)
- ***************
- *** 647,653 ****
- clip_get_selection();
-
- /* get the selection from the * register */
- ! motion_type = clip_convert_selection(&string, (long_u *)&length);
- if (motion_type < 0)
- return;
-
- --- 699,705 ----
- clip_get_selection();
-
- /* get the selection from the * register */
- ! motion_type = clip_convert_selection(&string, &length);
- if (motion_type < 0)
- return;
-
- ***************
- *** 655,661 ****
- if (info == SELECTION_CLIPBOARD)
- length++;
-
- ! result = (char_u *)malloc(2 * length);
- if (result == NULL)
- {
- vim_free(string);
- --- 707,713 ----
- if (info == SELECTION_CLIPBOARD)
- length++;
-
- ! result = lalloc((long_u)(2 * length), FALSE);
- if (result == NULL)
- {
- vim_free(string);
- ***************
- *** 676,682 ****
- selection_data->type = selection_data->target;
- selection_data->format = 8; /* 8 bits per char */
-
- ! gtk_selection_data_set(selection_data, type, 8, result, length);
- vim_free(string);
- vim_free(result);
- }
- --- 728,734 ----
- selection_data->type = selection_data->target;
- selection_data->format = 8; /* 8 bits per char */
-
- ! gtk_selection_data_set(selection_data, type, 8, result, (gint)length);
- vim_free(string);
- vim_free(result);
- }
- ***************
- *** 771,2916 ****
- return OK;
- }
-
- /*
- ! * Setup the window icon after the main window has bee realized.
- */
- ! /*ARGSUSED*/
- ! static void
- ! mainwin_realize(GtkWidget *widget)
- {
- ! /* If you get an error message here, you still need to unpack the runtime
- ! * archive! */
- ! #include "../runtime/vim32x32.xpm"
- ! static GdkPixmap *icon = NULL;
- ! static GdkBitmap *icon_mask = NULL;
-
- ! if (!icon)
- ! icon = gdk_pixmap_create_from_xpm_d(gui.mainwin->window,
- ! &icon_mask, NULL, magick);
- ! gdk_window_set_icon(gui.mainwin->window, NULL, icon, icon_mask);
- }
-
- /*
- ! * After the drawing area comes up, we calculate all colors and create the
- ! * dummy blank cursor.
- ! *
- ! * Don't try to set any VIM scrollbar sizes anywhere here. I'm relying on the
- ! * fact that the main VIM engine doesn't take them into account anywhere.
- */
- ! static void
- ! drawarea_realize_cb(GtkWidget *widget)
- {
- ! char blank_data[] = {0x0};
- ! GdkPixmap *blank_mask;
- ! GdkColor color;
- ! GtkWidget *sbar;
-
- ! #ifdef USE_XIM
- ! xim_init();
- ! #endif
- ! gui_mch_new_colors();
-
- ! blank_mask = gdk_bitmap_create_from_data(NULL, blank_data, 1, 1);
- ! gdk_color_white(gdk_colormap_get_system(), &color);
- ! gui.blank_pointer = gdk_cursor_new_from_pixmap(blank_mask, blank_mask,
- ! &color, &color, 0, 0);
- ! gdk_bitmap_unref(blank_mask);
- ! if (gui.pointer_hidden)
- ! gdk_window_set_cursor(widget->window, gui.blank_pointer);
-
- ! /* get the actual size of the scrollbars, if they are realized */
- ! sbar = firstwin->w_scrollbars[SBAR_LEFT].id;
- ! if (!sbar || (!gui.which_scrollbars[SBAR_LEFT]
- ! && firstwin->w_scrollbars[SBAR_RIGHT].id))
- ! sbar = firstwin->w_scrollbars[SBAR_RIGHT].id;
- ! if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.width)
- ! gui.scrollbar_width = sbar->allocation.width;
-
- ! sbar = gui.bottom_sbar.id;
- ! if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.height)
- ! gui.scrollbar_height = sbar->allocation.height;
- }
-
- ! /*
- ! * Initialise the X GUI. Create all the windows, set up all the call-backs etc.
- ! * Returns OK for success, FAIL when the GUI can't be started.
- ! */
- ! int
- ! gui_mch_init()
- {
- ! GtkWidget *vbox;
-
- ! /* Uncomment this to enable synchronous mode for debugging */
- ! /* XSynchronize(gui.dpy, True); */
-
- ! /* Initialize values */
- ! gui.rev_video = FALSE;
- ! gui.border_width = 2;
- ! gui.scrollbar_width = SB_DEFAULT_WIDTH;
- ! gui.scrollbar_height = SB_DEFAULT_WIDTH;
- ! gui.fgcolor = g_new0(GdkColor, 1);
- ! gui.bgcolor = g_new0(GdkColor, 1);
-
- ! #ifdef WANT_MENU
- ! /* Don't change the menu height values used in gui.c at runtime */
- ! gui.menu_height_fixed = TRUE;
- ! #endif
-
- ! /* Set default foreground and background colours. */
- ! gui.norm_pixel = gui.def_norm_pixel;
- ! gui.back_pixel = gui.def_back_pixel;
-
- ! gui.mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- ! gtk_window_set_policy(GTK_WINDOW(gui.mainwin), TRUE, TRUE, TRUE);
- ! gtk_container_border_width(GTK_CONTAINER(gui.mainwin), 0);
- ! gtk_widget_set_events(gui.mainwin, GDK_VISIBILITY_NOTIFY_MASK);
- ! (void)gtk_signal_connect(GTK_OBJECT(gui.mainwin), "delete_event",
- ! GTK_SIGNAL_FUNC(delete_event_cb), NULL);
-
- ! /* Add an icon to the main window. For fun and convenience of the user. */
- ! if (vim_strchr(p_go, GO_ICON) != NULL)
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "realize",
- ! GTK_SIGNAL_FUNC(mainwin_realize), NULL);
-
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! /* FIXME: this should eventually get the accelgroup of the gui.mainwin */
- ! gui.accel_group = gtk_accel_group_get_default();
- ! #endif
-
- ! vbox = gtk_vbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(gui.mainwin), vbox);
- ! gtk_widget_show(vbox);
-
- ! #ifdef WANT_MENU
- ! /* create the menubar and handle */
- ! gui.menubar = gtk_menu_bar_new();
- ! gtk_widget_show(gui.menubar);
- ! gtk_box_pack_start(GTK_BOX(vbox), gui.menubar, FALSE, TRUE, 0);
- ! #endif
-
- ! #ifdef USE_TOOLBAR
- ! /* create the toolbar */
- ! if (p_toolbar) {
- ! if (strstr((const char *)p_toolbar, "text")
- ! && strstr((const char *)p_toolbar, "icons"))
- ! gui.toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
- ! GTK_TOOLBAR_BOTH);
- ! else if (strstr((const char *)p_toolbar, "text"))
- ! gui.toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
- ! GTK_TOOLBAR_TEXT);
- ! else
- ! gui.toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
- ! GTK_TOOLBAR_ICONS);
- ! } else
- ! gui.toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
- ! GTK_TOOLBAR_ICONS);
-
- ! gtk_widget_show(gui.toolbar);
- ! # ifdef GTK_HAVE_FEATURES_1_1_0
- ! /* some aesthetics on the toolbar */
- ! gtk_toolbar_set_button_relief(GTK_TOOLBAR(gui.toolbar), GTK_RELIEF_NONE);
- ! # endif
- ! gtk_container_border_width(GTK_CONTAINER(gui.toolbar), 1);
- ! gtk_box_pack_start(GTK_BOX(vbox), gui.toolbar, FALSE, TRUE, 0);
- ! #endif
-
- ! gui.formwin = gtk_form_new();
- ! gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0);
- ! gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK);
-
- - gui.drawarea = gtk_drawing_area_new();
- -
- - /* Determine which events we will filter. */
- - gtk_widget_set_events(gui.drawarea,
- - GDK_EXPOSURE_MASK |
- - GDK_ENTER_NOTIFY_MASK |
- - GDK_LEAVE_NOTIFY_MASK |
- - GDK_BUTTON_PRESS_MASK |
- - GDK_BUTTON_RELEASE_MASK |
- - GDK_POINTER_MOTION_MASK |
- - GDK_POINTER_MOTION_HINT_MASK);
- - gtk_widget_show(gui.drawarea);
- - gtk_form_put(GTK_FORM(gui.formwin), gui.drawarea, 0, 0);
- - gtk_widget_show(gui.formwin);
- - gtk_box_pack_start(GTK_BOX(vbox), gui.formwin, TRUE, TRUE, 0);
- -
- - gtk_signal_connect(GTK_OBJECT(gui.mainwin), "key_press_event",
- - (GtkSignalFunc) key_press_event, NULL);
- - gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
- - GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
-
- ! /* Check if reverse video needs to be applied (on Sun it's done by X) */
- ! if (gui.rev_video && gui_mch_get_lightness(gui.back_pixel)
- ! > gui_mch_get_lightness(gui.norm_pixel)) {
- ! gui.norm_pixel = gui.def_back_pixel;
- ! gui.back_pixel = gui.def_norm_pixel;
- ! gui.def_norm_pixel = gui.norm_pixel;
- ! gui.def_back_pixel = gui.back_pixel;
- ! }
- ! gui.visibility = GDK_VISIBILITY_UNOBSCURED;
- ! clipboard.atom = gdk_atom_intern("_VIM_TEXT", FALSE);
- ! save_yourself_atom = gdk_atom_intern("WM_SAVE_YOURSELF", FALSE);
-
- /*
- ! * Start out by adding the configured border width into the border offset.
- */
- ! gui.border_offset = gui.border_width;
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "visibility_notify_event",
- ! GTK_SIGNAL_FUNC(visibility_event), NULL);
- ! #endif
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "expose_event",
- ! GTK_SIGNAL_FUNC(expose_event), NULL);
-
- ! /*
- ! * Only install these enter/leave callbacks when 'p' in 'guioptions'.
- ! * Only needed for some window managers.
- ! */
- ! if (vim_strchr(p_go, GO_POINTER) != NULL) {
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "leave_notify_event",
- ! GTK_SIGNAL_FUNC(leave_notify_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "enter_notify_event",
- ! GTK_SIGNAL_FUNC(enter_notify_event), NULL);
- }
-
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event",
- ! GTK_SIGNAL_FUNC(focus_out_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event",
- ! GTK_SIGNAL_FUNC(focus_in_event), NULL);
- !
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event",
- ! GTK_SIGNAL_FUNC(motion_notify_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_press_event",
- ! GTK_SIGNAL_FUNC(button_press_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_release_event",
- ! GTK_SIGNAL_FUNC(button_release_event), NULL);
-
- ! /*
- ! * Add selection handler functions.
- ! */
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_clear_event",
- ! GTK_SIGNAL_FUNC(selection_clear_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_received",
- ! GTK_SIGNAL_FUNC(selection_received_event), NULL);
-
- ! /* gtk_selection_add_target() is not in GTK 1.1.2 */
- ! #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_selection_add_target(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING, SELECTION_STRING);
- ! gtk_selection_add_target(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! clipboard.atom, SELECTION_CLIPBOARD);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_get",
- ! GTK_SIGNAL_FUNC(selection_get_event), NULL);
- ! #else
- ! gtk_selection_add_handler(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING, selection_handler, NULL);
- ! gtk_selection_add_handler(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! clipboard.atom, selection_handler, NULL);
- ! #endif
-
- ! /* Pretend we don't have input focus, we will get an event if we do. */
- ! gui.in_focus = FALSE;
-
- ! return OK;
- }
-
- !
- ! /*
- ! * Called when the foreground or background color has been changed.
- ! */
- ! void
- ! gui_mch_new_colors()
- {
- ! /* This used to change the graphics contexts directly but we are currently
- ! * manipulating them where desired.
- ! */
- ! if (gui.drawarea && gui.drawarea->window) {
- ! GdkColor color;
- ! color.pixel = gui.back_pixel;
- ! gdk_window_set_background(gui.drawarea->window, &color);
- }
- }
-
- - #ifdef GTK_HAVE_FEATURES_1_1_6
- - # define USE_GEOMETRY_FOR_HINTS 1
- - #endif
-
- static void
- ! update_window_manager_hints(void)
- ! {
- ! int width;
- ! int height;
- ! #ifdef USE_GEOMETRY_FOR_HINTS
- ! GdkGeometry geometry;
- ! GdkWindowHints geometry_mask;
-
- ! /* This also needs to be done when the main window isn't there yet,
- ! * otherwise the hints don't work. */
- ! width = gui_get_base_width();
- ! height = gui_get_base_height();
-
- ! geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC|GDK_HINT_MIN_SIZE;
- ! geometry.width_inc = gui.char_width;
- ! geometry.height_inc = gui.char_height;
- ! geometry.base_width = width;
- ! geometry.base_height = height;
- ! geometry.min_width = width + MIN_COLUMNS * gui.char_width;
- ! geometry.min_height = height + MIN_LINES * gui.char_height;
- ! gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin,
- ! &geometry, geometry_mask);
- ! #else
- ! XSizeHints size_hints;
-
- ! /* Don't set the size until the main window is really there */
- ! if (!GTK_WIDGET_REALIZED(gui.mainwin))
- ! return;
-
- ! width = gui_get_base_width();
- ! height = gui_get_base_height();
-
- ! /* The hints don't automatically take the menubar and toolbar into
- ! * account. Need to add their height here, if they are visible. */
- ! # ifdef USE_TOOLBAR
- ! if (gui.toolbar && GTK_WIDGET_REALIZED(gui.toolbar)
- ! && GTK_WIDGET_VISIBLE(gui.toolbar))
- ! height += gui.toolbar->allocation.height;
- ! # endif
- ! # ifdef WANT_MENU
- ! if (gui.menubar && GTK_WIDGET_REALIZED(gui.menubar)
- ! && GTK_WIDGET_VISIBLE(gui.menubar))
- ! height += gui.menubar->allocation.height;
- ! # endif
-
- /*
- ! * Argh!!! Once again we need to deal with an ommission in GTK+ by
- ! * resorting to direct Xlib calls. Fortunatly I know how to do it :-).
- */
- ! size_hints.flags = (PResizeInc | PBaseSize | PMinSize | PSize);
- ! size_hints.width_inc = gui.char_width;
- ! size_hints.height_inc = gui.char_height;
- ! size_hints.base_width = width;
- ! size_hints.base_height = height;
- ! size_hints.min_width = width + MIN_COLUMNS * gui.char_width;
- ! size_hints.min_height = height + MIN_LINES * gui.char_height;
-
- ! /* This is only needed for "older" window managers. See a corresposning
- ! * comment in the X11 headers. */
- ! size_hints.width = width + Columns * gui.char_width;
- ! size_hints.height = height + Rows * gui.char_height;
-
- ! XSetWMNormalHints(GDK_DISPLAY(),
- ! GDK_WINDOW_XWINDOW(gui.mainwin->window),
- ! &size_hints);
- ! #endif /* USE_GEOMETRY_FOR_HINTS */
- }
-
- /*
- ! * This signal informs us about the need to rearrange our subwidgets.
- */
- /*ARGSUSED*/
- ! static gint
- ! form_configure_event(GtkWidget * widget, GdkEventConfigure * event)
- {
- ! gtk_form_freeze(GTK_FORM(gui.formwin));
- ! gui_resize_window(event->width, event->height);
- ! gtk_form_thaw(GTK_FORM(gui.formwin));
- !
- ! return TRUE;
- ! }
-
- ! /*ARGSUSED*/
- ! static gint
- ! client_event_cb(GtkWidget *widget, GdkEventClient *event)
- ! {
- ! if (event->message_type == save_yourself_atom ) {
- ! out_flush();
- ! ml_sync_all(FALSE, FALSE); /* preserve all swap files */
- ! return TRUE;
- ! }
- ! return FALSE;
- }
-
- /*
- ! * Open the GUI window which was created by a call to gui_mch_init().
- */
- ! int
- ! gui_mch_open()
- {
- ! int x = -1, y = -1;
- !
- ! /* Determine user specified geometry, if present. */
- ! if (gui.geom) {
- ! int mask;
- ! unsigned w, h;
- !
- ! mask = XParseGeometry((char *)gui.geom, &x, &y, &w, &h);
- ! if (mask & WidthValue)
- ! Columns = w;
- ! if (mask & HeightValue)
- ! Rows = h;
- ! if (mask & (XValue | YValue))
- ! gtk_widget_set_uposition(gui.mainwin, x, y);
- ! g_free(gui.geom);
- ! gui.geom = NULL;
- ! }
- !
- ! gtk_form_set_size(GTK_FORM(gui.formwin),
- ! gui_get_base_width() + Columns * gui.char_width,
- ! gui_get_base_height() + Rows * gui.char_height);
- ! update_window_manager_hints();
- !
- ! if (found_reverse_arg )
- ! {
- ! gui.def_norm_pixel = gui_mch_get_color("White");
- ! gui.def_back_pixel = gui_mch_get_color("Black");
- ! }
- ! else
- ! {
- ! gui.def_norm_pixel = gui_mch_get_color("Black");
- ! gui.def_back_pixel = gui_mch_get_color("White");
- ! }
- !
- ! /* Get the colors from the "Normal" and "Menu" group (set in syntax.c or
- ! * in a vimrc file)
- ! */
- ! set_normal_colors();
- !
- ! /* Check that none of the colors are the same as the background color */
- ! gui_check_colors();
- !
- ! /* Get the colors for the highlight groups (gui_check_colors() might have
- ! * changed them).
- ! */
- ! highlight_gui_started(); /* re-init colors and fonts */
- !
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy",
- ! GTK_SIGNAL_FUNC(destroy_callback), NULL);
-
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "client_event",
- ! GTK_SIGNAL_FUNC(client_event_cb), NULL);
- ! #ifdef HANGUL_INPUT
- ! hangul_keyboard_set();
- #endif
-
- ! /*
- ! * Notify the fixed area about the need to resize the contents of the
- ! * gui.formwin, which we use for random positioning of the included
- ! * components.
- ! *
- ! * We connect this signal deferred finally after anything is in place,
- ! * since this is intended to handle resizements coming from the window
- ! * manager upon us and should not interfere with what VIM is requesting
- ! * upon startup.
- ! */
- ! gtk_signal_connect(GTK_OBJECT(gui.formwin), "configure_event",
- ! GTK_SIGNAL_FUNC(form_configure_event), NULL);
-
- ! gtk_widget_show(gui.mainwin);
-
- ! return OK;
- }
-
- !
- /*ARGSUSED*/
- ! void
- ! gui_mch_exit(int rc)
- {
- ! gtk_exit(0);
- }
-
- /*
- ! * Get the position of the top left corner of the window.
- */
- int
- ! gui_mch_get_winpos(int *x, int *y)
- {
- ! /* For some people this must be gdk_window_get_origin() for a correct
- ! * result. Where is the documentation! */
- ! #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gdk_window_get_root_origin(gui.mainwin->window, x, y);
- ! #else
- ! gdk_window_get_origin(gui.mainwin->window, x, y);
- ! #endif
- ! return OK;
- ! }
-
- ! /*
- ! * Set the position of the top left corner of the window to the given
- ! * coordinates.
- ! */
- ! void
- ! gui_mch_set_winpos(int x, int y)
- ! {
- ! gdk_window_move(gui.mainwin->window, x, y);
- ! }
-
- ! /*
- ! * Set the windows size.
- ! */
- ! /*ARGSUSED*/
- ! void
- ! gui_mch_set_winsize(int width, int height,
- ! int min_width, int min_height,
- ! int base_width, int base_height)
- ! {
- ! gtk_form_set_size(GTK_FORM(gui.formwin), width, height);
-
- ! /* give GTK+ a chance to put all widget's into place */
- ! gui_mch_update();
-
- ! /* this will cause the proper resizement to happen too */
- ! update_window_manager_hints();
- ! }
-
-
- - /*
- - * The screen size is used to make sure the initial window doesn't get bigger
- - * then the screen. This subtracts some room for menubar, toolbar and window
- - * decoreations.
- - */
- - void
- - gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
- - {
- - *screen_w = gdk_screen_width();
- - /* Subtract 'guihearroom' from the height to allow some room for the
- - * window manager (task list and window title bar). */
- - *screen_h = gdk_screen_height() - p_ghr;
-
- ! /*
- ! * FIXME: dirty trick: Because the gui_get_base_height() doesn't include
- ! * the toolbar and menubar for GTK, we subtract them from the screen
- ! * hight, so that the window size can be made to fit on the screen.
- ! * This should be completely changed later.
- ! */
- ! #ifdef USE_TOOLBAR
- ! if (gui.toolbar && GTK_WIDGET_REALIZED(gui.toolbar)
- ! && GTK_WIDGET_VISIBLE(gui.toolbar))
- ! *screen_h -= gui.toolbar->allocation.height;
- ! #endif
- ! #ifdef WANT_MENU
- ! if (gui.menubar && GTK_WIDGET_REALIZED(gui.menubar)
- ! && GTK_WIDGET_VISIBLE(gui.menubar))
- ! *screen_h -= gui.menubar->allocation.height;
- #endif
- - }
-
- ! #if defined(WANT_MENU) || defined(PROTO)
- ! void
- ! gui_mch_enable_menu(int flag)
- ! {
- ! if (flag)
- ! gtk_widget_show(gui.menubar);
- ! else
- ! gtk_widget_hide(gui.menubar);
-
- ! update_window_manager_hints();
- ! }
- #endif
-
- !
- ! #if defined(USE_TOOLBAR) || defined(PROTO)
- ! void
- ! gui_mch_show_toolbar(int showit)
- ! {
- ! if (gui.toolbar == NULL)
- ! return;
- !
- ! if (!showit) {
- ! if (GTK_WIDGET_VISIBLE(gui.toolbar)) {
- ! gtk_widget_hide(gui.toolbar);
- ! /* wait util this gets done on the server side. */
- ! update_window_manager_hints();
- ! }
- ! } else {
- ! g_assert(p_toolbar != NULL);
- if (strstr((const char *)p_toolbar, "text")
- ! && strstr((const char *)p_toolbar, "icons")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_BOTH);
- ! } else if (strstr((const char *)p_toolbar, "text")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_TEXT);
- ! } else if (strstr((const char *)p_toolbar, "icons")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_ICONS);
- ! }
- !
- ! if (strstr((const char *)p_toolbar, "tooltips"))
- ! gtk_toolbar_set_tooltips(GTK_TOOLBAR(gui.toolbar), TRUE);
- else
- ! gtk_toolbar_set_tooltips(GTK_TOOLBAR(gui.toolbar), FALSE);
-
- ! /*
- ! * Black on white will catch the attention of the user more likely then
- ! * black on grey. However due to errors / omissions in GTK+-1.1.5 this
- ! * ceased to work properly. I had been looking after it and there seems
- ! * to be no easy fix for it there. (--mdcki)
- ! *
- ! * This problem still applies for GTK+-1.2.3. (--mdcki)
- ! * And I didn't find any current example where the tooltip colors
- ! * would have need changed correctly.
- ! */
- ! gtk_tooltips_set_colors(GTK_TOOLBAR(gui.toolbar)->tooltips,
- ! &gui.toolbar->style->white,
- ! &gui.toolbar->style->black);
- ! if (!GTK_WIDGET_VISIBLE(gui.toolbar)) {
- ! gtk_widget_show(gui.toolbar);
- ! update_window_manager_hints();
- ! }
- ! }
- ! }
- #endif
-
-
- ! #ifdef USE_FONTSET
- ! static GuiFont
- ! gui_mch_get_fontset(char_u * name, int report_error)
- ! {
- ! GdkFont *font;
-
- ! if (!gui.in_use || name == NULL)
- ! return (GuiFont) 0;
-
- ! font = gdk_fontset_load((gchar *) name);
-
- ! if (font == NULL) {
- ! if (report_error)
- ! EMSG2("Unknown fontset: %s", name);
- ! return (GuiFont) 0;
- }
-
- ! /* reference this font as beeing in use */
- ! gdk_font_ref(font);
-
- ! return (GuiFont) font;
- ! }
- #endif
-
- ! /*
- ! * Initialise vim to use the font with the given name.
- ! * Return FAIL if the font could not be loaded, OK otherwise.
- ! */
- ! int
- ! gui_mch_init_font(char_u * font_name)
- ! {
- ! GdkFont *font = NULL;
- ! char *chunk[28], *sdup, *tmp;
- ! int len, i;
- !
- ! #ifdef USE_FONTSET
- ! {
- ! static char_u *dflt_fontset = NULL;
- !
- ! if (gui.fontset)
- ! {
- ! /* If fontset is active, VIM treat all the font as a fontset. */
- ! if (font_name == NULL || vim_strchr(font_name, ',') == NULL)
- ! font_name = dflt_fontset;
- ! font = gui_mch_get_fontset(font_name, FALSE);
- ! if (font == NULL)
- ! return FAIL;
- ! }
- ! else if (font_name == NULL && *p_guifontset)
- ! {
- ! font = gui_mch_get_fontset(p_guifontset, FALSE);
- ! if (font)
- ! {
- ! font_name = p_guifontset;
- ! dflt_fontset = alloc(STRLEN(p_guifontset) + 1);
- ! STRCPY(dflt_fontset, p_guifontset);
- ! }
- ! }
- }
-
- ! if (font == NULL)
- ! #endif
- ! {
- ! /*
- ! * If none of the fonts in 'font' could be loaded, try the default,
- ! * which should be present on all X11 servers.
- ! */
- ! if (font_name == NULL)
- ! font_name = (char_u *) DFLT_FONT;
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! if (STRCMP(font_name, "*") == 0) {
- ! /*
- ! * Request for a font handling dialog.
- ! * Not quite sure we should handle this here...
- ! */
- ! /*
- ! * NOTE about font selection widget: this can easily be backported
- ! * to gtk-1.0.x.
- ! */
- ! if (!gui.fontdlg)
- ! {
- ! GtkFontSelectionDialog *fsd = NULL;
-
- ! gui.fontdlg = gtk_font_selection_dialog_new("Font Selection");
- ! fsd = GTK_FONT_SELECTION_DIALOG(gui.fontdlg);
- ! if (p_guifont != NULL)
- ! gtk_font_selection_dialog_set_font_name(fsd,
- ! (char *)p_guifont);
- ! # ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_window_set_modal(GTK_WINDOW(gui.fontdlg), TRUE);
- ! gtk_window_set_transient_for(GTK_WINDOW(gui.fontdlg),
- ! GTK_WINDOW(gui.mainwin));
- ! # endif
- ! gtk_signal_connect(GTK_OBJECT(gui.fontdlg), "destroy",
- ! GTK_SIGNAL_FUNC(font_sel_destroy), &gui);
- ! gtk_signal_connect(GTK_OBJECT(fsd->ok_button), "clicked",
- ! GTK_SIGNAL_FUNC(font_sel_ok), &gui);
- ! gtk_signal_connect(GTK_OBJECT(fsd->cancel_button), "clicked",
- ! GTK_SIGNAL_FUNC(font_sel_cancel), &gui);
- ! }
- ! if (gui.fontname)
- ! {
- ! g_free(gui.fontname);
- ! gui.fontname = NULL;
- ! }
- ! gtk_window_position(GTK_WINDOW(gui.fontdlg), GTK_WIN_POS_MOUSE);
- ! gtk_widget_show(gui.fontdlg);
- ! # ifdef GTK_HAVE_FEATURES_1_1_4
- ! {
- ! static gchar *spacings[] = {"c", "m", NULL};
-
- ! /* In GTK 1.2.3 this must be after the gtk_widget_show() call,
- ! * otherwise everything is blocked for ten seconds. */
- ! gtk_font_selection_dialog_set_filter(
- ! GTK_FONT_SELECTION_DIALOG(gui.fontdlg),
- ! GTK_FONT_FILTER_BASE,
- ! GTK_FONT_ALL, NULL, NULL,
- ! NULL, NULL, spacings, NULL);
- ! }
- ! # endif
-
- ! while (gui.fontdlg && GTK_WIDGET_VISIBLE(gui.fontdlg))
- ! gtk_main_iteration_do(TRUE);
-
- ! if (gui.fontname == NULL)
- ! return FAIL;
- ! vim_free(p_guifont);
- ! p_guifont = vim_strsave(gui.fontname);
- ! font_name = p_guifont;
- ! }
- ! #endif
- ! if (font == NULL)
- ! font = gui_mch_get_font(font_name, FALSE);
-
- - if (font == NULL)
- - return FAIL;
- - }
-
- ! if (gui.norm_font != 0)
- ! gdk_font_unref(font);
- ! gui.norm_font = font;
- ! #ifdef USE_FONTSET
- ! if (font->type == GDK_FONT_FONTSET)
- ! {
- ! gui.fontset = (GuiFont) font;
- ! gui.char_width = gdk_string_width(font, " ");
- }
- ! else
- #endif
- - {
- - gui.char_width = ((XFontStruct *)
- - GDK_FONT_XFONT(font))->max_bounds.width;
- - }
-
- ! gui.char_height = font->ascent + font->descent;
- ! gui.char_ascent = font->ascent;
-
- ! /* Set the fontname, which will be used for information purposes */
- ! hl_set_font_name(font_name);
-
- ! if (font->type != GDK_FONT_FONTSET)
- ! {
- ! /* There is only one excuse I can give for the following attempt
- ! * to manage font styles:
- ! *
- ! * I HATE THE BRAIN DEAD WAY X11 IS HANDLING FONTS (--mdcki)
- ! */
- ! if ((sdup = g_strdup((const char *)font_name)) == NULL)
- ! return FAIL;
-
- ! /* slipt up the whole */
- ! i = 0;
- ! for (tmp = sdup; *tmp != '\0'; ++tmp)
- ! if (*tmp == '-')
- ! {
- ! *tmp = '\0';
- ! chunk[i] = tmp + 1;
- ! ++i;
- ! }
-
- ! g_free(sdup);
-
- ! if (i == 14)
- ! {
- ! char *bold_name = NULL;
- ! char *ital_name = NULL;
- ! char *italbold_name = NULL;
-
- ! /* font name was compleate */
- ! len = strlen((const char *)font_name) + 32;
- ! bold_name = (char *)alloc(len);
- ! ital_name = (char *)alloc(len);
- ! italbold_name = (char *)alloc(len);
- ! if (bold_name == NULL || ital_name == NULL || italbold_name == NULL)
- ! {
- ! vim_free(bold_name);
- ! vim_free(ital_name);
- ! vim_free(italbold_name);
- ! return FAIL;
- ! }
-
- ! *bold_name = '\0';
- ! *ital_name = '\0';
- ! *italbold_name = '\0';
-
- ! for (i = 0; i < 14; ++i)
- ! {
- ! strcat(bold_name, "-");
- ! strcat(ital_name, "-");
- ! strcat(italbold_name, "-");
- ! strcat(bold_name, (i != 2) ? chunk[i] : "bold");
- ! strcat(ital_name, (i != 3) ? chunk[i] : "o");
-
- ! if (i != 2 && i != 3)
- ! strcat(italbold_name, chunk[i]);
- ! else
- ! {
- ! if (i == 2)
- ! strcat(italbold_name, "bold");
- ! else if (i == 3)
- ! strcat(italbold_name, "o");
- ! }
- ! }
-
- ! font = gui_mch_get_font((char_u *)bold_name, FALSE);
- ! if (font != NULL)
- ! gui.bold_font = font;
- ! else if (gui.bold_font)
- ! {
- ! gdk_font_unref(gui.bold_font);
- ! gui.bold_font = NULL;
- ! }
-
- ! font = gui_mch_get_font((char_u *)ital_name, FALSE);
- ! if (font != NULL)
- ! gui.ital_font = font;
- ! else if (gui.ital_font)
- ! {
- ! gdk_font_unref(gui.ital_font);
- ! gui.ital_font = NULL;
- ! }
-
- ! font = gui_mch_get_font((char_u *)italbold_name, FALSE);
- ! if (font != NULL)
- ! gui.boldital_font = font;
- ! else if (gui.boldital_font)
- ! {
- ! gdk_font_unref(gui.boldital_font);
- ! gui.boldital_font = NULL;
- ! }
-
- - vim_free(bold_name);
- - vim_free(ital_name);
- - vim_free(italbold_name);
- - }
- - }
-
- ! /* Synchronize the fonts used in user input dialogs, since otherwise
- ! * search/replace will be esp annoyig in case of international font usage.
- ! */
- ! gui_gtk_synch_fonts();
-
- ! #ifdef USE_XIM
- ! /* Adjust input management behaviour to the capabilities of the new
- ! * fontset */
- ! xim_decide_input_style();
- ! if (xim_get_status_area_height())
- ! {
- ! /* Status area is required. Just create the empty label so that
- ! * mainwin will allocate the extra space for status area. */
- ! GtkWidget *label = gtk_label_new(" ");
-
- ! gtk_widget_set_usize(label, 20, gui.char_height + 2);
- ! gtk_box_pack_end(GTK_BOX(GTK_BIN(gui.mainwin)->child), label,
- ! FALSE, FALSE, 0);
- ! gtk_widget_show(label);
- }
- - #endif
-
- ! /* Preserve the logical dimensions of the screen. */
- update_window_manager_hints();
-
- ! return OK;
- ! }
-
-
- ! GuiFont
- ! gui_mch_get_font(char_u * name, int report_error)
- ! {
- ! GdkFont *font;
-
- ! if (!gui.in_use || name == NULL) /* can't do this when GUI not running */
- ! return (GuiFont) 0;
-
- ! #ifdef USE_FONTSET
- ! if (gui.fontset)
- ! /* If fontset is active, VIM treat all the font as a fontset */
- ! return gui_mch_get_fontset(name, report_error);
- ! else if (vim_strchr(name, ','))
- ! return (GuiFont)0;
- #endif
-
- ! font = gdk_font_load((const gchar *) name);
-
- ! if (font == NULL) {
- ! if (report_error)
- ! EMSG2("Unknown font: %s", name);
- ! return (GuiFont) 0;
- ! }
-
- ! /* reference this font as beeing in use */
- ! gdk_font_ref(font);
- ! if (((XFontStruct *) GDK_FONT_XFONT(font))->max_bounds.width
- ! != ((XFontStruct *) GDK_FONT_XFONT(font))->min_bounds.width) {
- ! EMSG2("Font \"%s\" is not fixed-width", name);
- ! gdk_font_unref(font);
-
- ! return (GuiFont) 0;
- ! }
- ! return (GuiFont) font;
- }
-
- ! /*
- ! * Set the current text font.
- ! * Since we create all GC on demand, we use just gui.current_font to
- ! * indicate the desired current font.
- ! */
- void
- ! gui_mch_set_font(GuiFont font)
- {
- ! gui.current_font = font;
- }
-
- - #if 0 /* not used */
- /*
- ! * Return TRUE if the two fonts given are equivalent.
- */
- int
- ! gui_mch_same_font(GuiFont f1, GuiFont f2)
- {
- ! return gdk_font_equal((GdkFont *) f1, (GdkFont *) f2);
- ! }
- #endif
-
- /*
- ! * If a font is not going to be used, free its structure.
- */
- void
- ! gui_mch_free_font(GuiFont font)
- {
- ! if (font)
- ! gdk_font_unref((GdkFont *) font);
- }
-
- -
- /*
- ! * Return the Pixel value (color) for the given color name. This routine was
- ! * pretty much taken from example code in the Silicon Graphics OSF/Motif
- ! * Programmer's Guide.
- ! * Return -1 for error.
- */
- ! GuiColor
- ! gui_mch_get_color(char_u * name)
- {
- ! int i;
- ! static char *(vimnames[][2]) =
- ! {
- ! /* A number of colors that some X11 systems don't have */
- ! {"LightRed", "#FFA0A0"},
- ! {"LightGreen", "#80FF80"},
- ! {"LightMagenta", "#FFA0FF"},
- ! {"DarkCyan", "#008080"},
- ! {"DarkBlue", "#0000C0"},
- ! {"DarkRed", "#C00000"},
- ! {"DarkMagenta", "#C000C0"},
- ! {"DarkGrey", "#C0C0C0"},
- ! {NULL, NULL}
- ! };
- !
- ! if (!gui.in_use) /* can't do this when GUI not running */
- ! return (GuiColor)(-1);
- !
- ! while (name != NULL) {
- ! GdkColor color;
- !
- ! if (gdk_color_parse((const gchar *)name, &color)) {
- ! GdkColormap *colormap;
- ! colormap = gtk_widget_get_colormap(gui.drawarea);
- ! gdk_color_alloc(colormap, &color);
-
- ! return (GuiColor) color.pixel;
- ! }
- ! /* add a few builtin names */
- ! for (i = 0;; ++i) {
- ! if (vimnames[i][0] == NULL) {
- ! name = NULL;
- ! break;
- ! }
- ! if (STRICMP(name, vimnames[i][0]) == 0) {
- ! name = (char_u *) vimnames[i][1];
- ! break;
- ! }
- ! }
- ! }
-
- ! return (GuiColor)(-1);
- }
-
- - /*
- - * Set the current text foreground color.
- - */
- - void
- - gui_mch_set_fg_color(GuiColor color)
- - {
- - gui.fgcolor->pixel = (Pixel) color;
- - }
-
- /*
- ! * Set the current text background color.
- */
- void
- ! gui_mch_set_bg_color(GuiColor color)
- {
- ! gui.bgcolor->pixel = (Pixel) color;
- }
-
- ! /*
- ! * Use the blank mouse pointer or not.
- ! *
- ! * hide: TRUE = use blank ptr, FALSE = use parent ptr
- ! */
- void
- ! gui_mch_mousehide(int hide)
- {
- ! if (gui.pointer_hidden != hide) {
- ! if (gui.drawarea->window && gui.blank_pointer) {
- ! if (hide)
- ! gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer);
- ! else
- ! gdk_window_set_cursor(gui.drawarea->window, NULL);
- ! }
- ! gui.pointer_hidden = hide;
- ! }
- }
-
- void
- ! gui_mch_draw_string(int row, int col, char_u * s, int len, int flags)
- {
- ! GdkGC *gc;
- !
- ! if (gui.current_font == NULL || gui.drawarea->window == NULL)
- return;
-
- ! #if defined(USE_FONTSET) && defined(MULTI_BYTE)
- ! if (gui.fontset)
- ! {
- ! if (col > 0 && mb_isbyte1(LinePointers[row], col - 1))
- ! {
- ! col++;
- ! len--;
- ! s++;
- }
- - if (len == 1 && IsLeadByte(*s))
- - len = 2;
- - }
- - #endif
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- !
- ! if (flags & DRAW_TRANSP) {
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col), TEXT_Y(row),
- ! (const gchar *)s, len);
- ! } else {
- ! int width;
- ! int height;
- ! width = gdk_text_width(gui.current_font, (const gchar *)s, len);
- ! height = gui.char_height;
- !
- ! gdk_gc_set_foreground(gc, gui.bgcolor);
- ! gdk_draw_rectangle(gui.drawarea->window,
- ! gc,
- ! TRUE,
- ! FILL_X(col), FILL_Y(row), width, height);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col), TEXT_Y(row),
- ! (const gchar *)s, len);
- ! }
- !
- ! /* redraw the contents with an offset of 1 to emulate bold */
- ! if (flags & DRAW_BOLD) {
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col) + 1, TEXT_Y(row),
- ! (const gchar *)s, len);
- ! }
- !
- ! if (flags & DRAW_UNDERL) {
- ! gdk_draw_line(gui.drawarea->window,
- ! gc, FILL_X(col),
- ! FILL_Y(row + 1) - 1, FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
- ! }
- ! gdk_gc_destroy(gc);
- ! }
- !
- ! /*
- ! * Return OK if the key with the termcap name "name" is supported.
- ! */
- ! int
- ! gui_mch_haskey(char_u * name)
- ! {
- ! int i;
- !
- ! for (i = 0; special_keys[i].key_sym != 0; i++)
- ! if (name[0] == special_keys[i].code0 &&
- ! name[1] == special_keys[i].code1)
- ! return OK;
- ! return FAIL;
- ! }
-
- ! #if defined(WANT_TITLE) || defined(PROTO)
- ! /*
- ! * Return the text window-id and display. Only required for X-based GUI's
- ! */
- ! int
- ! gui_get_x11_windis(Window * win, Display ** dis)
- ! {
- ! /*
- ! * This is currently only used by the code which is handling the
- ! * window manager title of this program.
- ! */
- ! *dis = GDK_DISPLAY();
- ! if (gui.mainwin->window) {
- ! *win = GDK_WINDOW_XWINDOW(gui.mainwin->window);
- ! return OK;
- }
- - *win = 0;
- - return FAIL;
- }
- #endif
-
- - void
- - gui_mch_beep()
- - {
- - gdk_beep();
- - }
-
- ! void
- ! gui_mch_flash()
- {
- ! GdkGCValues values;
- ! GdkGC *invert_gc;
- ! GdkColor foreground;
- ! GdkColor background;
- !
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
- ! background.pixel = gui.norm_pixel ^ gui.back_pixel;
-
- ! values.foreground = foreground;
- ! values.background = background;
- ! values.function = GDK_XOR;
- ! invert_gc = gdk_gc_new_with_values(gui.drawarea->window,
- ! &values,
- ! GDK_GC_FOREGROUND |
- ! GDK_GC_BACKGROUND |
- ! GDK_GC_FUNCTION);
- ! gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
-
- ! /* Do a visual beep by changing back and forth in some undetermined way,
- ! * the foreground and background colors. This is due to the fact that
- ! * there can't be really any prediction about the effects of XOR on
- ! * arbitrary X11 servers. However this seems to be enought for what we
- ! * intend it to do.
- ! */
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! 0, 0,
- ! FILL_X((int) Columns) + gui.border_offset,
- ! FILL_Y((int) Rows) + gui.border_offset);
-
- ! gdk_flush();
- ! ui_delay(20L, TRUE); /* wait 1/50 of a second */
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! 0, 0,
- ! FILL_X((int) Columns) + gui.border_offset,
- ! FILL_Y((int) Rows) + gui.border_offset);
-
- ! gdk_gc_destroy(invert_gc);
- }
-
- /*
- ! * Invert a rectangle from row r, column c, for nr rows and nc columns.
- */
- ! void
- ! gui_mch_invert_rectangle(int r, int c, int nr, int nc)
- {
- ! GdkGCValues values;
- ! GdkGC *invert_gc;
- ! GdkColor foreground;
- ! GdkColor background;
-
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
- ! background.pixel = gui.norm_pixel ^ gui.back_pixel;
-
- ! values.foreground = foreground;
- ! values.background = background;
- ! values.function = GDK_XOR;
- ! invert_gc = gdk_gc_new_with_values(gui.drawarea->window,
- ! &values,
- ! GDK_GC_FOREGROUND |
- ! GDK_GC_BACKGROUND |
- ! GDK_GC_FUNCTION);
- ! gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! FILL_X(c), FILL_Y(r),
- ! (nc) * gui.char_width, (nr) * gui.char_height);
- ! gdk_gc_destroy(invert_gc);
- }
-
- ! /*
- ! * Iconify the GUI window.
- ! */
- ! void
- ! gui_mch_iconify()
- {
- ! XIconifyWindow(GDK_DISPLAY(),
- ! GDK_WINDOW_XWINDOW(gui.mainwin->window),
- ! DefaultScreen(GDK_DISPLAY()));
- }
-
- /*
- ! * Draw a cursor without focus.
- */
- ! void
- ! gui_mch_draw_hollow_cursor(GuiColor color)
- {
- ! GdkGC *gc;
-
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! gui_mch_set_fg_color(color);
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! #if defined(USE_FONTSET) && defined(MULTI_BYTE)
- ! if (gui.fontset)
- {
- ! if (IsLeadByte(LinePointers[gui.row][gui.col])
- ! # ifdef HANGUL_INPUT
- ! || composing_hangul
- # endif
- ! )
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! 2*gui.char_width - 1, gui.char_height - 1);
- ! else
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! gui.char_width - 1, gui.char_height - 1);
- }
- else
- #endif
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! gui.char_width - 1, gui.char_height - 1);
- ! gdk_gc_destroy(gc);
- ! }
-
- ! /*
- ! * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
- ! * color "color".
- ! */
- ! void
- ! gui_mch_draw_part_cursor(int w, int h, GuiColor color)
- ! {
- ! GdkGC *gc;
-
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! gui_mch_set_fg_color(color);
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! TRUE,
- ! #ifdef RIGHTLEFT
- ! /* vertical line should be on the right of current point */
- ! State != CMDLINE && curwin->w_p_rl ? FILL_X(gui.col + 1) - w :
- ! #endif
- ! FILL_X(gui.col),
- ! FILL_Y(gui.row) + gui.char_height - h,
- ! w, h);
- ! gdk_gc_destroy(gc);
- ! }
-
- ! #ifndef GTK_HAVE_FEATURES_1_1_0
- ! static gint
- ! idle_function(GtkWidget * label)
- ! {
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
-
- ! return FALSE;
- }
- - #endif
-
-
- ! /*
- ! * Catch up with any queued X11 events. This may put keyboard input into the
- ! * input buffer, call resize call-backs, trigger timers etc. If there is
- ! * nothing in the X11 event queue (& no timers pending), then we return
- ! * immediately.
- ! */
- ! void
- ! gui_mch_update()
- {
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! while (gtk_events_pending() && !vim_is_input_buf_full())
- ! gtk_main_iteration_do(FALSE);
- ! #else
- ! int pending;
-
- ! /* Somehow the above loop hangs on GTK 1.0.6. Use the idle_function() to
- ! * work around this weird problem. */
- ! while (((pending = gtk_events_pending()) > 1) && !vim_is_input_buf_full())
- ! gtk_main_iteration();
-
- ! if ((pending == 1) && !vim_is_input_buf_full()) {
- ! gtk_idle_add((GtkFunction)idle_function, gui.mainwin);
- ! gtk_main_iteration_do(FALSE);
- ! }
- #endif
- - }
-
- ! static gint
- ! input_timer_cb(gpointer data)
- ! {
- ! int *timed_out = (int *) data;
-
- ! /* Just inform the caller about the accurence of it */
- ! *timed_out = TRUE;
-
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
-
- ! return FALSE; /* don't happen again */
- }
-
- /*
- ! * GUI input routine called by gui_wait_for_chars(). Waits for a character
- ! * from the keyboard.
- ! * wtime == -1 Wait forever.
- ! * wtime == 0 This should never happen.
- ! * wtime > 0 Wait wtime milliseconds for a character.
- ! * Returns OK if a character was found to be available within the given time,
- ! * or FAIL otherwise.
- */
- ! int
- ! gui_mch_wait_for_chars(long wtime)
- {
- ! int focus;
- ! guint timer;
- !
- ! static int timed_out;
- !
- ! timed_out = FALSE;
- !
- ! /* this timeout makes sure that we will return if no characters arrived in
- ! * time */
- !
- ! if (wtime > 0)
- ! timer = gtk_timeout_add(wtime, input_timer_cb, &timed_out);
- ! else
- ! timer = 0;
- !
- ! focus = gui.in_focus;
- !
- ! do {
- ! /* Stop or start blinking when focus changes */
- ! if (gui.in_focus != focus) {
- ! if (gui.in_focus)
- ! gui_mch_start_blink();
- ! else
- ! gui_mch_stop_blink();
- ! focus = gui.in_focus;
- ! }
- !
- ! /*
- ! * Loop in GTK+ processing until a timeout or input occurs.
- ! */
- ! gtk_main();
- !
- ! /* Got char, return immediately */
- ! if (!vim_is_input_buf_empty()) {
- ! if (timer != 0 && !timed_out)
- ! gtk_timeout_remove(timer);
- ! return OK;
- ! }
- ! } while (wtime < 0 || !timed_out);
- !
- ! /*
- ! * Flush all eventually pending (drawing) events.
- ! */
- ! gui_mch_update();
- !
- ! return FAIL;
- }
-
- !
- ! /****************************************************************************
- ! * Output drawing routines.
- ! ****************************************************************************/
- !
- !
- ! /* Flush any output to the screen */
- ! void
- ! gui_mch_flush()
- {
- ! gdk_flush();
- }
-
- /*
- ! * Clear a rectangular region of the screen from text pos (row1, col1) to
- ! * (row2, col2) inclusive.
- */
- void
- ! gui_mch_clear_block(int row1, int col1, int row2, int col2)
- {
- ! GdkGC *gc;
- ! GdkColor color;
-
- - if (gui.drawarea->window == NULL)
- - return;
-
- ! color.pixel = gui.back_pixel;
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, &color);
-
- ! /*
- ! * Clear one extra pixel at the right, for when bold characters have
- ! * spilled over to the next column. This can erase part of the next
- ! * character however in the usage context of this function it will be
- ! * overriden immediately by the correct character again.
- ! */
-
- ! gdk_draw_rectangle(gui.drawarea->window, gc, TRUE,
- ! FILL_X(col1), FILL_Y(row1),
- ! (col2 - col1 + 1) * gui.char_width + 1,
- ! (row2 - row1 + 1) * gui.char_height);
- ! gdk_gc_destroy(gc);
- ! }
-
- ! void
- ! gui_mch_clear_all(void)
- ! {
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! gdk_window_clear(gui.drawarea->window);
- }
-
- /*
- ! * Scroll the text between gui.scroll_region_top & gui.scroll_region_bot by the
- ! * number of lines given. Positive scrolls down (text goes up) and negative
- ! * scrolls up (text goes down).
- */
- ! static void check_copy_area(void)
- {
- ! XEvent event;
- ! XGraphicsExposeEvent *gevent;
- !
- ! if (gui.visibility != GDK_VISIBILITY_PARTIAL)
- ! return;
- !
- ! gdk_flush();
- !
- ! /* Wait to check whether the scroll worked or not */
- ! for (;;) {
- ! if (XCheckTypedEvent(GDK_DISPLAY(), NoExpose, &event))
- ! return; /* The scroll worked. */
-
- ! if (XCheckTypedEvent(GDK_DISPLAY(), GraphicsExpose, &event)) {
- ! gevent = (XGraphicsExposeEvent *) & event;
- ! gui_redraw(gevent->x, gevent->y, gevent->width, gevent->height);
- ! if (gevent->count == 0)
- ! return; /* This was the last expose event */
- ! }
- ! gdk_flush();
- ! }
- }
-
- /*
- ! * Delete the given number of lines from the given row, scrolling up any
- ! * text further down within the scroll region.
- */
- void
- ! gui_mch_delete_lines(int row, int num_lines)
- {
- ! if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
- ! return; /* Can't see the window */
- !
- ! if (num_lines <= 0)
- ! return;
- !
- ! if (row + num_lines > gui.scroll_region_bot) {
- ! /* Scrolled out of region, just blank the lines out */
- ! gui_clear_block(row, 0, gui.scroll_region_bot, (int) Columns - 1);
- ! } else {
- ! GdkGC *gc;
- !
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_gc_set_background(gc, gui.bgcolor);
- !
- ! /* copy one extra pixel, for when bold has spilled over */
- ! gdk_window_copy_area(gui.drawarea->window, gc,
- ! FILL_X(0), FILL_Y(row),
- ! gui.drawarea->window,
- ! FILL_X(0), FILL_Y(row + num_lines),
- ! gui.char_width * (int) Columns + 1,
- ! gui.char_height *
- ! (gui.scroll_region_bot - row - num_lines + 1));
- ! gdk_gc_destroy(gc);
- !
- ! /* Update gui.cursor_row if the cursor scrolled or copied over */
- ! if (gui.cursor_row >= row) {
- ! if (gui.cursor_row < row + num_lines)
- ! gui.cursor_is_valid = FALSE;
- ! else if (gui.cursor_row <= gui.scroll_region_bot)
- ! gui.cursor_row -= num_lines;
- }
- ! gui_clear_block(gui.scroll_region_bot - num_lines + 1, 0,
- ! gui.scroll_region_bot, (int) Columns - 1);
- ! check_copy_area();
- }
- }
-
- - /*
- - * Insert the given number of lines before the given row, scrolling down any
- - * following text within the scroll region.
- - */
- void
- ! gui_mch_insert_lines(int row, int num_lines)
- {
- ! if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
- ! return; /* Can't see the window */
-
- ! if (num_lines <= 0)
- return;
-
- ! if (row + num_lines > gui.scroll_region_bot) {
- ! /* Scrolled out of region, just blank the lines out */
- ! gui_clear_block(row, 0, gui.scroll_region_bot, (int) Columns - 1);
- } else {
- ! GdkGC *gc;
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_gc_set_background(gc, gui.bgcolor);
-
- ! /* copy one extra pixel, for when bold has spilled over */
- ! gdk_window_copy_area(gui.drawarea->window, gc,
- ! FILL_X(0), FILL_Y(row + num_lines),
- ! gui.drawarea->window,
- ! FILL_X(0), FILL_Y(row),
- ! gui.char_width * (int) Columns + 1,
- ! gui.char_height *
- ! (gui.scroll_region_bot - row - num_lines + 1));
- ! gdk_gc_destroy(gc);
-
- ! /* Update gui.cursor_row if the cursor scrolled or copied over */
- ! if (gui.cursor_row >= gui.row) {
- ! if (gui.cursor_row <= gui.scroll_region_bot - num_lines)
- ! gui.cursor_row += num_lines;
- ! else if (gui.cursor_row <= gui.scroll_region_bot)
- ! gui.cursor_is_valid = FALSE;
- ! }
- ! gui_clear_block(row, 0, row + num_lines - 1, (int) Columns - 1);
- ! check_copy_area();
- }
- }
-
- /*
- ! * X Selection stuff, for cutting and pasting text to other windows.
- */
- ! void
- ! clip_mch_request_selection()
- {
- ! /* First try to get the content of our own special clipboard. */
- ! received_selection = RS_NONE;
- ! (void)gtk_selection_convert(gui.drawarea,
- ! GDK_SELECTION_PRIMARY, clipboard.atom,
- ! GDK_CURRENT_TIME);
- ! while (received_selection == RS_NONE)
- ! gtk_main(); /* wait for selection_received_event */
-
- ! if (received_selection == RS_FAIL)
- ! {
- ! /* Now try to get it out of the usual string selection. */
- ! received_selection = RS_NONE;
- ! (void)gtk_selection_convert(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING,
- ! GDK_CURRENT_TIME);
- ! while (received_selection == RS_NONE)
- ! gtk_main(); /* wait for selection_received_event */
- }
- }
-
- void
- ! clip_mch_lose_selection()
- {
- ! gtk_selection_owner_set(gui.drawarea,
- ! GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
- ! gui_mch_update();
- }
-
- /*
- ! * Check whatever we allready own the selection
- */
- ! int
- ! clip_mch_own_selection()
- {
- ! #if 0
- ! return gdk_selection_owner_get(
- ! GDK_SELECTION_PRIMARY) == gui.drawarea->window;
- ! #else
- ! /* At this point we always already own the clipboard */
-
- ! return OK;
- ! #endif
- }
-
- /*
- ! * Send the current selection to the clipboard.
- */
- void
- ! clip_mch_set_selection()
- {
- ! gtk_selection_owner_set(gui.drawarea,
- ! GDK_SELECTION_PRIMARY,
- ! GDK_CURRENT_TIME);
- ! gui_mch_update();
- }
-
- -
- - #if defined(WANT_MENU) || defined(PROTO)
- /*
- ! * Make a menu item appear either active or not active (grey or not grey).
- */
- void
- ! gui_mch_menu_grey(VimMenu * menu, int grey)
- {
- ! if (menu->id == 0)
- return;
-
- ! gui_mch_menu_hidden(menu, FALSE);
- ! gtk_widget_set_sensitive(menu->id, !grey);
-
- ! gui_mch_update();
- }
-
- /*
- ! * Make menu item hidden or not hidden.
- */
- void
- ! gui_mch_menu_hidden(VimMenu * menu, int hidden)
- {
- ! if (menu->id == 0)
- return;
-
- ! if (hidden) {
- ! if (GTK_WIDGET_VISIBLE(menu->id))
- ! gtk_widget_hide(menu->id);
- ! } else {
- ! if (!GTK_WIDGET_VISIBLE(menu->id))
- ! gtk_widget_show(menu->id);
- ! }
-
- ! gui_mch_update();
- }
-
- ! /*
- ! * This is called after setting all the menus to grey/hidden or not.
- ! */
- ! void
- ! gui_mch_draw_menubar()
- {
- ! /* just make sure that the visual changes get effect immediately */
- ! gui_mch_update();
- }
- #endif
-
- /*
- ! * Scrollbar stuff.
- */
- void
- ! gui_mch_enable_scrollbar(GuiScrollbar * sb, int flag)
- {
- ! if (sb->id == 0)
- ! return;
- ! if (flag)
- ! gtk_widget_show(sb->id);
- ! else
- ! gtk_widget_hide(sb->id);
- ! update_window_manager_hints();
- }
-
-
- /*
- ! * Return the lightness of a pixel. White is 255.
- ! *
- ! * FIXME: port it compleatly to GDK.
- */
- int
- ! gui_mch_get_lightness(GuiColor pixel)
- {
- ! XColor xc;
- ! GdkColormap *colormap;
-
- ! colormap = gtk_widget_get_colormap(gui.mainwin);
- ! xc.pixel = pixel;
- ! XQueryColor(GDK_DISPLAY(), GDK_COLORMAP_XCOLORMAP(colormap), &xc);
-
- ! return (int) (xc.red * 3 + xc.green * 6 + xc.blue) / (10 * 256);
- }
-
- - #if (defined(SYNTAX_HL) && defined(WANT_EVAL)) || defined(PROTO)
- /*
- ! * Return the RGB value of a pixel as "#RRGGBB".
- ! *
- ! * FIXME: It should be possible to avoid any direct usage of Xlib. Use gdk
- ! * instead!
- */
- ! char_u *
- ! gui_mch_get_rgb(GuiColor pixel)
- {
- ! XColor xc;
- ! GdkColormap *colormap;
- ! static char_u retval[10];
- ! static int prevent_congestion = 0; /* Reduce the race! */
-
- ! while (prevent_congestion)
- ! /* shouldn't we do something here? */;
-
- ! ++prevent_congestion;
- ! colormap = gtk_widget_get_colormap(gui.mainwin);
-
- ! xc.pixel = pixel;
- ! XQueryColor(GDK_DISPLAY(), GDK_COLORMAP_XCOLORMAP(colormap), &xc);
-
- ! sprintf((char *) retval, "#%02x%02x%02x",
- ! (unsigned) xc.red >> 8,
- ! (unsigned) xc.green >> 8,
- ! (unsigned) xc.blue >> 8);
- ! /* hope the following is atomic enought (99.999%) */
- ! --prevent_congestion;
-
- ! /* WOAH!!! Returning pointer to static string! */
- ! return retval;
- }
- - #endif
-
- /*
- ! * Get current y mouse coordinate in text window.
- ! * Return -1 when unknown.
- */
- ! int
- ! gui_mch_get_mouse_x(void)
- {
- ! int winx, winy;
- ! GdkModifierType mask;
-
- ! if (gdk_window_get_pointer(gui.drawarea->window, &winx, &winy, &mask)) {
- ! if (gui.which_scrollbars[SBAR_LEFT])
- ! return winx;
- ! return winx;
- ! }
- ! return -1;
- ! }
-
- ! int
- ! gui_mch_get_mouse_y(void)
- ! {
- ! int winx, winy;
- ! GdkModifierType mask;
-
- ! if (gdk_window_get_pointer(gui.drawarea->window, &winx, &winy, &mask))
- ! return winy;
- ! return -1;
- }
-
- void
- ! gui_mch_setmouse(int x, int y)
- {
- ! /* Sorry for that, but we can't avoid it, since there seems to be
- ! no internal GDK mechanism present to accomplish this */
- ! XWarpPointer(GDK_DISPLAY(), (Window) 0,
- ! GDK_WINDOW_XWINDOW(gui.drawarea->window), 0, 0, 0, 0, x, y);
- ! }
-
-
- ! /*** private function defintions ***/
-
- ! /* redraw the corresponding portions of the screen */
- ! /*ARGSUSED*/
- ! static gint
- ! expose_event(GtkWidget * widget, GdkEventExpose * event)
- ! {
- ! out_flush(); /* make sure all output has been processed */
- ! gui_redraw(event->area.x, event->area.y,
- ! event->area.width, event->area.height);
-
- ! /* Clear the border areas if needed */
- ! if (event->area.x < FILL_X(0))
- ! gdk_window_clear_area(gui.drawarea->window, 0, 0, FILL_X(0), 0);
- ! if (event->area.y < FILL_Y(0))
- ! gdk_window_clear_area(gui.drawarea->window, 0, 0, 0, FILL_Y(0));
- ! if (event->area.x > FILL_X(Columns))
- ! gdk_window_clear_area(gui.drawarea->window,
- ! FILL_X((int)Columns), 0, 0, 0);
- ! if (event->area.y > FILL_Y(Rows))
- ! gdk_window_clear_area(gui.drawarea->window, 0, FILL_Y((int)Rows), 0, 0);
-
- ! return FALSE;
- }
-
- - static guint mouse_click_timer = 0;
- - static int mouse_timed_out = TRUE;
- -
- /*
- ! * Timer used to recognize multiple clicks of the mouse button
- */
- ! static gint
- ! mouse_click_timer_cb(gpointer data)
- {
- ! /* we don't use this information currently */
- ! int *timed_out = (int *) data;
- !
- ! *timed_out = TRUE;
- ! return FALSE; /* don't happen again */
- ! }
-
- ! /*
- ! * Mouse button handling. Note please that we are capturing multiple click's by
- ! * our own timeout mechanis instead of the one provided by GTK+ istelf. This is
- ! * due to the way the generic VIM code is recognizing multiple clicks.
- ! */
- ! /*ARGSUSED*/
- ! static gint
- ! button_press_event(GtkWidget * widget, GdkEventButton * event)
- ! {
- ! int button;
- ! int repeated_click = FALSE;
- ! int x, y;
- ! int_u vim_modifiers;
-
- ! /*
- ! * Don't let additional events about multiple clicks send by GTK to us
- ! * after the inital button press event confuse us.
- ! */
- ! if (event->type != GDK_BUTTON_PRESS)
- ! return FALSE;
-
- ! x = event->x;
- ! y = event->y;
-
-
- ! /* Handle multiple clicks */
- ! if (!mouse_timed_out && mouse_click_timer) {
- ! gtk_timeout_remove(mouse_click_timer);
- ! mouse_click_timer = 0;
- ! repeated_click = TRUE;
- }
-
- ! mouse_timed_out = FALSE;
- ! mouse_click_timer = gtk_timeout_add(p_mouset,
- ! mouse_click_timer_cb, &mouse_timed_out);
-
- ! switch (event->button)
- {
- ! case 1:
- ! button = MOUSE_LEFT;
- ! break;
- ! case 2:
- ! button = MOUSE_MIDDLE;
- ! break;
- ! case 3:
- ! button = MOUSE_RIGHT;
- ! break;
- ! case 4:
- ! button = MOUSE_4;
- ! break;
- ! case 5:
- ! button = MOUSE_5;
- ! break;
- ! default:
- ! return FALSE; /* Unknown button */
- }
-
- ! vim_modifiers = 0x0;
- ! if (event->state & GDK_SHIFT_MASK)
- ! vim_modifiers |= MOUSE_SHIFT;
- ! if (event->state & GDK_CONTROL_MASK)
- ! vim_modifiers |= MOUSE_CTRL;
- ! if (event->state & GDK_MOD1_MASK)
- ! vim_modifiers |= MOUSE_ALT;
-
- ! gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit(); /* make sure the above will be handled immediately */
-
- ! return TRUE;
- }
-
- - static guint motion_repeat_timer = 0;
- -
- /*
- ! * Timer used to recognize multiple clicks of the mouse button
- */
- ! /*ARGSUSED*/
- ! static gint
- ! motion_repeat_timer_cb(gpointer data)
- {
- ! gint x, y;
- ! GdkModifierType state;
- ! GdkEventMotion event;
- !
- ! gdk_window_get_pointer(gui.drawarea->window, &x, &y, &state);
- !
- ! if (!(state & (GDK_BUTTON1_MASK | GDK_BUTTON3_MASK)))
- ! return FALSE;
- !
- ! /* Fake a motion event. */
- ! event.is_hint = 0;
- ! event.x = x;
- ! event.y = y;
- ! event.state = state;
-
- - /* FIXME: argh! for some unknown reason this doesn't lead to nice
- - * autoscrolling and automatic extension of the selection area. However
- - * the autorepeating works nice already. We need certainly to investigate
- - * this further.
- - *
- - * BTW: It doesn't work properly in the motif version too. So maybe we need
- - * to look at how it's done in the Windows version again...
- - *
- - * I'm assuming that this is somehow related to the gui_mouse_moved
- - * stuff...
- - */
-
- ! motion_notify_event(gui.drawarea, &event);
-
- ! /* Don't happen again. We will get reinstalled in the synthetic
- ! * event if needed - thus repeating should still work.
- ! */
-
- ! return FALSE;
- }
-
- ! /*ARGSUSED*/
- ! static gint
- ! button_release_event(GtkWidget * widget, GdkEventButton * event)
- {
- ! int x, y;
- ! int_u vim_modifiers;
-
- ! /* Remove any motion "mashine gun" timers used for automatic further
- ! extension of allocation areas if outside of the applications window
- ! area .*/
- ! if (motion_repeat_timer) {
- ! gtk_timeout_remove(motion_repeat_timer);
- ! motion_repeat_timer = 0;
- }
-
- ! x = event->x;
- ! y = event->y;
- !
- ! vim_modifiers = 0x0;
- ! if (event->state & GDK_SHIFT_MASK)
- ! vim_modifiers |= MOUSE_SHIFT;
- ! if (event->state & GDK_CONTROL_MASK)
- ! vim_modifiers |= MOUSE_CTRL;
- ! if (event->state & GDK_MOD1_MASK)
- ! vim_modifiers |= MOUSE_ALT;
- !
- ! gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, vim_modifiers);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit(); /* make sure it will be handled immediately */
- !
- ! return TRUE;
- }
-
- !
- ! /*ARGSUSED*/
- ! static gint
- ! motion_notify_event(GtkWidget * widget, GdkEventMotion * event)
- {
- ! gint x, y;
- ! GdkModifierType state;
- ! int_u vim_modifiers;
- ! int button;
- !
- ! if (event->is_hint)
- ! gdk_window_get_pointer(event->window, &x, &y, &state);
- ! else {
- ! x = event->x;
- ! y = event->y;
- ! state = event->state;
- ! }
- ! button = (event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
- ! GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
- ! GDK_BUTTON5_MASK))
- ! ? MOUSE_DRAG : ' ';
- !
- ! /* If our pointer is currently hidden, then we should show it. */
- ! gui_mch_mousehide(FALSE);
- !
- ! /* Just moving the rodent above the drawing area without
- ! any button beeing pressed. */
- ! if (button != MOUSE_DRAG) {
- ! gui_mouse_moved(y);
- ! return TRUE;
- ! }
- !
- ! vim_modifiers = 0x0;
- ! if (state & GDK_SHIFT_MASK)
- ! vim_modifiers |= MOUSE_SHIFT;
- ! if (state & GDK_CONTROL_MASK)
- ! vim_modifiers |= MOUSE_CTRL;
- ! if (state & GDK_MOD1_MASK)
- ! vim_modifiers |= MOUSE_ALT;
- !
- ! /* inform the editor egine about the occurence of this event */
- ! gui_send_mouse_event(button, x, y, FALSE, vim_modifiers);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- !
- ! /*
- ! * Auto repeat timer handling.
- ! */
- ! if (x < 0 || y < 0
- ! || x >= gui.drawarea->allocation.width
- ! || y >= gui.drawarea->allocation.height) {
- !
- ! /* just in case remove stale timers */
- ! if (motion_repeat_timer)
- ! gtk_timeout_remove(motion_repeat_timer);
- ! /* shoot again */
- ! motion_repeat_timer = gtk_timeout_add(100,
- ! motion_repeat_timer_cb, NULL);
- ! }
- !
- ! return TRUE; /* handled */
- }
-
- /*
- ! * Callback routine for the "delete_event" signal on the toplevel window.
- ! * Tries to vim gracefully, or refuses to exit with changed buffers.
- */
- ! /*ARGSUSED*/
- ! static int
- ! delete_event_cb(GtkWidget *wgt, gpointer cbdata)
- {
- ! gui_window_closed();
- ! return TRUE;
- }
-
- /*
- ! * Function called when window already closed.
- ! * We can't do much more here than to trying to preserve what had been done,
- ! * since the window is already inevitably going away.
- */
- ! static void
- ! destroy_callback(void)
- {
- ! /* preserve files and exit */
- ! preserve_exit();
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- /*
- ! * Get a font structure for highlighting.
- ! * "cbdata" is a pointer to the global gui structure.
- */
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_ok(GtkWidget *wgt, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
- ! GtkFontSelectionDialog *fs = (GtkFontSelectionDialog *)vw->fontdlg;
-
- ! if (vw->fontname)
- ! g_free(vw->fontname);
-
- ! vw->fontname = (char_u *)g_strdup(
- ! gtk_font_selection_dialog_get_font_name(fs));
- ! gtk_widget_hide(vw->fontdlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
-
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_cancel(GtkWidget *wgt, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
-
- ! gtk_widget_hide(vw->fontdlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
-
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_destroy(GtkWidget *wgt, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
-
- ! vw->fontdlg = NULL;
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
- - #endif
- --- 823,3120 ----
- return OK;
- }
-
- +
- + /****************************************************************************
- + * Mouse handling callbacks
- + */
- +
- +
- + static guint mouse_click_timer = 0;
- + static int mouse_timed_out = TRUE;
- +
- /*
- ! * Timer used to recognize multiple clicks of the mouse button
- */
- ! static gint
- ! mouse_click_timer_cb(gpointer data)
- {
- ! /* we don't use this information currently */
- ! int *timed_out = (int *) data;
-
- ! *timed_out = TRUE;
- ! return FALSE; /* don't happen again */
- }
-
- + static guint motion_repeat_timer = 0;
- + static int motion_repeat_offset = FALSE;
- +
- + static gint motion_notify_event(GtkWidget *, GdkEventMotion *);
- +
- /*
- ! * Timer used to recognize multiple clicks of the mouse button.
- */
- ! /*ARGSUSED*/
- ! static gint
- ! motion_repeat_timer_cb(gpointer data)
- {
- ! gint x, y;
- ! GdkModifierType state;
- ! GdkEventMotion event;
-
- ! gdk_window_get_pointer(gui.drawarea->window, &x, &y, &state);
-
- ! if (!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
- ! GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
- ! GDK_BUTTON5_MASK)))
- ! {
- ! motion_repeat_timer = 0;
- ! return FALSE;
- ! }
-
- ! /* If there already is a mouse click in the input buffer, wait another
- ! * time (otherwise we would create a backlog of clicks) */
- ! if (vim_used_in_input_buf() > 10)
- ! return TRUE;
-
- ! motion_repeat_timer = 0;
- !
- ! /* Fake a motion event.
- ! * Trick: Pretend the mouse moved to the next character on every other
- ! * event, otherwise drag events will be discarded, because they are still
- ! * in the same character. */
- ! event.is_hint = FALSE;
- ! if (motion_repeat_offset)
- ! {
- ! event.x = x + gui.char_width;
- ! motion_repeat_offset = FALSE;
- ! }
- ! else
- ! {
- ! event.x = x;
- ! motion_repeat_offset = TRUE;
- ! }
- ! event.y = y;
- ! event.state = state;
- ! motion_notify_event(gui.drawarea, &event);
- !
- ! /* Don't happen again. We will get reinstalled in the synthetic event if
- ! * needed - thus repeating should still work.
- ! */
- ! return FALSE;
- }
-
- ! /*ARGSUSED*/
- ! static gint
- ! motion_notify_event(GtkWidget * widget, GdkEventMotion * event)
- {
- ! gint x, y;
- ! GdkModifierType state;
- ! int_u vim_modifiers;
- ! int button;
-
- ! if (event->is_hint)
- ! gdk_window_get_pointer(event->window, &x, &y, &state);
- ! else {
- ! x = event->x;
- ! y = event->y;
- ! state = event->state;
- ! }
-
- ! button = (event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
- ! GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
- ! GDK_BUTTON5_MASK))
- ! ? MOUSE_DRAG : ' ';
-
- ! /* If our pointer is currently hidden, then we should show it. */
- ! gui_mch_mousehide(FALSE);
-
- ! /* Just moving the rodent above the drawing area without any button beeing
- ! * pressed. */
- ! if (button != MOUSE_DRAG) {
- ! gui_mouse_moved(y);
- ! return TRUE;
- ! }
-
- ! /* translate modifier coding between the main engine and GTK */
- ! vim_modifiers = 0x0;
- ! if (state & GDK_SHIFT_MASK)
- ! vim_modifiers |= MOUSE_SHIFT;
- ! if (state & GDK_CONTROL_MASK)
- ! vim_modifiers |= MOUSE_CTRL;
- ! if (state & GDK_MOD1_MASK)
- ! vim_modifiers |= MOUSE_ALT;
-
- ! /* inform the editor egine about the occurence of this event */
- ! gui_send_mouse_event(button, x, y, FALSE, vim_modifiers);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
-
- + /*
- + * Auto repeat timer handling.
- + */
- + if (x < 0 || y < 0
- + || x >= gui.drawarea->allocation.width
- + || y >= gui.drawarea->allocation.height) {
-
- ! int dx;
- ! int dy;
- ! int offshoot;
- ! int delay = 10;
-
- ! /* Calculate the maximal distance of the cursor from the drawing area.
- ! * (offshoot can't become negative here!).
- ! */
- ! dx = x < 0 ? -x : x - gui.drawarea->allocation.width;
- ! dy = y < 0 ? -y : y - gui.drawarea->allocation.height;
-
- ! offshoot = dx > dy ? dx : dy;
-
- ! /* Make a linearly declaying timer delay with a threshold of 5 at a
- ! * distance of 127 pixels from the main window.
- ! *
- ! * One could think endlessly about the most ergonomic variant here.
- ! * For example it could make sense to calculate the distance from the
- ! * drags start instead...
- ! *
- ! * Maybe a parabolic interpolation would suite us better here too...
- ! */
- ! if (offshoot > 127) {
- ! /* 5 appears to be somehow near to my perceptual limits :-). */
- ! delay = 5;
- ! } else {
- ! delay = (130 * (127 - offshoot)) / 127 + 5;
- ! }
-
- ! /* shoot again */
- ! if (!motion_repeat_timer)
- ! motion_repeat_timer = gtk_timeout_add((guint32)delay,
- ! motion_repeat_timer_cb, NULL);
- ! }
-
- ! return TRUE; /* handled */
- ! }
-
-
- ! /*
- ! * Mouse button handling. Note please that we are capturing multiple click's
- ! * by our own timeout mechanism instead of the one provided by GTK+ istelf.
- ! * This is due to the way the generic VIM code is recognizing multiple clicks.
- ! */
- ! /*ARGSUSED*/
- ! static gint
- ! button_press_event(GtkWidget * widget, GdkEventButton * event)
- ! {
- ! int button;
- ! int repeated_click = FALSE;
- ! int x, y;
- ! int_u vim_modifiers;
-
- /*
- ! * Don't let additional events about multiple clicks send by GTK to us
- ! * after the inital button press event confuse us.
- */
- ! if (event->type != GDK_BUTTON_PRESS)
- ! return FALSE;
-
- ! x = event->x;
- ! y = event->y;
-
- ! /* Handle multiple clicks */
- ! if (!mouse_timed_out && mouse_click_timer) {
- ! gtk_timeout_remove(mouse_click_timer);
- ! mouse_click_timer = 0;
- ! repeated_click = TRUE;
- }
-
- ! mouse_timed_out = FALSE;
- ! mouse_click_timer = gtk_timeout_add((guint32)p_mouset,
- ! mouse_click_timer_cb, &mouse_timed_out);
-
- ! switch (event->button) {
- ! case 1:
- ! button = MOUSE_LEFT;
- ! break;
- ! case 2:
- ! button = MOUSE_MIDDLE;
- ! break;
- ! case 3:
- ! button = MOUSE_RIGHT;
- ! break;
- ! case 4:
- ! button = MOUSE_4;
- ! break;
- ! case 5:
- ! button = MOUSE_5;
- ! break;
- ! default:
- ! return FALSE; /* Unknown button */
- ! }
-
- ! vim_modifiers = 0x0;
- ! if (event->state & GDK_SHIFT_MASK)
- ! vim_modifiers |= MOUSE_SHIFT;
- ! if (event->state & GDK_CONTROL_MASK)
- ! vim_modifiers |= MOUSE_CTRL;
- ! if (event->state & GDK_MOD1_MASK)
- ! vim_modifiers |= MOUSE_ALT;
-
- ! gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit(); /* make sure the above will be handled immediately */
-
- ! return TRUE;
- }
-
- ! /*ARGSUSED*/
- ! static gint
- ! button_release_event(GtkWidget * widget, GdkEventButton * event)
- {
- ! int x, y;
- ! int_u vim_modifiers;
- !
- ! /* Remove any motion "mashine gun" timers used for automatic further
- ! extension of allocation areas if outside of the applications window
- ! area .*/
- ! if (motion_repeat_timer) {
- ! gtk_timeout_remove(motion_repeat_timer);
- ! motion_repeat_timer = 0;
- }
- +
- + x = event->x;
- + y = event->y;
- +
- + vim_modifiers = 0x0;
- + if (event->state & GDK_SHIFT_MASK)
- + vim_modifiers |= MOUSE_SHIFT;
- + if (event->state & GDK_CONTROL_MASK)
- + vim_modifiers |= MOUSE_CTRL;
- + if (event->state & GDK_MOD1_MASK)
- + vim_modifiers |= MOUSE_ALT;
- +
- + gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, vim_modifiers);
- + if (gtk_main_level() > 0)
- + gtk_main_quit(); /* make sure it will be handled immediately */
- +
- + return TRUE;
- }
-
-
- + #ifdef GTK_DND
- + /****************************************************************************
- + * Drag aNd Drop support handlers.
- + */
- +
- + /*
- + * DND receiver.
- + */
- + /*ARGSUSED*/
- static void
- ! drag_data_received(GtkWidget *widget, GdkDragContext *context,
- ! gint x, gint y,
- ! GtkSelectionData *data,
- ! guint info, guint time)
- ! {
- ! char_u **fnames;
- ! int redo_dirs = FALSE;
- ! int i;
- ! int n;
- ! char *start;
- ! char *stop;
- ! char *copy;
- ! int nfiles;
- ! GdkModifierType current_modifiers;
- !
- ! /* Get the current modifier state for proper distinguishment between
- ! * different operations later. */
- ! current_modifiers = 0;
- ! gdk_window_get_pointer(NULL, NULL, NULL, ¤t_modifiers);
- !
- ! /* guard against trash */
- ! if (((data->length <= 0) && (data->format != 8))
- ! || (((char *)data->data)[data->length] != '\0')) {
- ! gtk_drag_finish(context, FALSE, FALSE, time);
-
- ! return;
- ! }
-
- ! /* Count how meny items there may be there and normalize
- ! * delimiters.
- ! */
- ! n = 1;
- ! copy = strdup((char *)data->data);
- ! for (i = 0; i < data->length; ++i) {
- ! if (copy[i] == '\n')
- ! ++n;
- ! else if(copy[i] == '\r') {
- ! copy[i] = '\n';
- ! ++n;
- ! }
- ! }
-
- ! fnames = (char_u **) alloc((n + 1) * sizeof(char_u *));
-
- ! start = copy;
- ! stop = copy;
- ! nfiles = 0;
- ! for (i = 0; i < n; ++i) {
- ! stop = strchr(start, '\n');
- ! if (stop)
- ! *stop = '\0';
- !
- ! if (!strlen(start))
- ! continue;
- !
- ! if (strncmp(start, "file:", 5)) {
- ! int j;
- !
- ! free(copy);
- ! for (j = 0; j < nfiles; ++j)
- ! free(fnames[j]);
- ! gtk_drag_finish(context, FALSE, FALSE, time);
-
- ! return;
- ! }
- !
- ! if (!strncmp(start, "file://localhost", 16)) {
- ! fnames[nfiles] = (char_u *)strdup(start + 16);
- ! ++nfiles;
- ! } else {
- ! fnames[nfiles] = (char_u *)strdup(start + 5);
- ! ++nfiles;
- ! }
- ! start = stop + 2;
- ! }
- ! free(copy);
- !
- ! /* accept */
- ! gtk_drag_finish (context, TRUE, FALSE, time);
-
- /*
- ! * Handle dropping a directory on Vim.
- */
- ! if (nfiles == 1) {
- ! if (mch_isdir(fnames[0])) {
- ! if (mch_chdir((char *)fnames[0]) == 0) {
- ! free(fnames[0]);
- ! fnames[0] = NULL;
- ! redo_dirs = TRUE;
- ! }
- ! }
- ! } else {
- ! /* Ignore any directories */
- ! for (i = 0; i < nfiles; ++i) {
- ! if (mch_isdir(fnames[i])) {
- ! free(fnames[i]);
- ! fnames[i] = NULL;
- ! }
- ! }
- ! }
-
- ! if (current_modifiers & GDK_SHIFT_MASK) {
- ! /* Shift held down, change to first file's directory */
- ! if (fnames[0] != NULL && vim_chdirfile(fnames[0]) == 0)
- ! redo_dirs = TRUE;
- ! }
-
- ! /* Handle the drop, :edit or :split to get to the file */
- ! handle_drop(nfiles, fnames, current_modifiers & GDK_CONTROL_MASK);
- !
- ! if (redo_dirs)
- ! shorten_fnames(TRUE);
- !
- ! /* Update the screen display */
- ! update_screen(NOT_VALID);
- ! setcursor();
- ! out_flush();
- }
- + #endif /* GTK_DND */
-
- /*
- ! * Setup the window icon after the main window has bee realized.
- */
- /*ARGSUSED*/
- ! static void
- ! mainwin_realize(GtkWidget *widget)
- {
- ! /* If you get an error message here, you still need to unpack the runtime
- ! * archive! */
- ! #include "../runtime/vim32x32.xpm"
- ! static GdkPixmap *icon = NULL;
- ! static GdkBitmap *icon_mask = NULL;
-
- ! if (!icon)
- ! icon = gdk_pixmap_create_from_xpm_d(gui.mainwin->window,
- ! &icon_mask, NULL, magick);
- ! gdk_window_set_icon(gui.mainwin->window, NULL, icon, icon_mask);
- }
-
- /*
- ! * After the drawing area comes up, we calculate all colors and create the
- ! * dummy blank cursor.
- ! *
- ! * Don't try to set any VIM scrollbar sizes anywhere here. I'm relying on the
- ! * fact that the main VIM engine doesn't take them into account anywhere.
- */
- ! static void
- ! drawarea_realize_cb(GtkWidget *widget)
- {
- ! char blank_data[] = {0x0};
- ! GdkPixmap *blank_mask;
- ! GdkColor color;
- ! GtkWidget *sbar;
-
- ! #ifdef USE_XIM
- ! xim_init();
- #endif
- + gui_mch_new_colors();
-
- ! blank_mask = gdk_bitmap_create_from_data(NULL, blank_data, 1, 1);
- ! gdk_color_white(gdk_colormap_get_system(), &color);
- ! gui.blank_pointer = gdk_cursor_new_from_pixmap(blank_mask, blank_mask,
- ! &color, &color, 0, 0);
- ! gdk_bitmap_unref(blank_mask);
- ! if (gui.pointer_hidden)
- ! gdk_window_set_cursor(widget->window, gui.blank_pointer);
-
- ! /* get the actual size of the scrollbars, if they are realized */
- ! sbar = firstwin->w_scrollbars[SBAR_LEFT].id;
- ! if (!sbar || (!gui.which_scrollbars[SBAR_LEFT]
- ! && firstwin->w_scrollbars[SBAR_RIGHT].id))
- ! sbar = firstwin->w_scrollbars[SBAR_RIGHT].id;
- ! if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.width)
- ! gui.scrollbar_width = sbar->allocation.width;
-
- ! sbar = gui.bottom_sbar.id;
- ! if (sbar && GTK_WIDGET_REALIZED(sbar) && sbar->allocation.height)
- ! gui.scrollbar_height = sbar->allocation.height;
- }
-
- ! /*
- ! * Callback routine for the "delete_event" signal on the toplevel window.
- ! * Tries to vim gracefully, or refuses to exit with changed buffers.
- ! */
- /*ARGSUSED*/
- ! static int
- ! delete_event_cb(GtkWidget *wgt, gpointer cbdata)
- {
- ! gui_window_closed();
- ! return TRUE;
- }
-
- /*
- ! * Initialise the X GUI. Create all the windows, set up all the call-backs etc.
- ! * Returns OK for success, FAIL when the GUI can't be started.
- */
- int
- ! gui_mch_init()
- {
- ! GtkWidget *vbox;
-
- ! /* Initialize values */
- ! gui.rev_video = FALSE;
- ! gui.border_width = 2;
- ! gui.scrollbar_width = SB_DEFAULT_WIDTH;
- ! gui.scrollbar_height = SB_DEFAULT_WIDTH;
- ! gui.fgcolor = g_new0(GdkColor, 1);
- ! gui.bgcolor = g_new0(GdkColor, 1);
-
- ! #ifdef WANT_MENU
- ! /* Don't change the menu height values used in gui.c at runtime */
- ! gui.menu_height_fixed = TRUE;
- ! #endif
-
- ! /* Set default foreground and background colours. */
- ! gui.norm_pixel = gui.def_norm_pixel;
- ! gui.back_pixel = gui.def_back_pixel;
-
- ! gui.mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- ! gtk_window_set_policy(GTK_WINDOW(gui.mainwin), TRUE, TRUE, TRUE);
- ! gtk_container_border_width(GTK_CONTAINER(gui.mainwin), 0);
- ! gtk_widget_set_events(gui.mainwin, GDK_VISIBILITY_NOTIFY_MASK);
- ! (void)gtk_signal_connect(GTK_OBJECT(gui.mainwin), "delete_event",
- ! GTK_SIGNAL_FUNC(delete_event_cb), NULL);
-
- + /* Add an icon to the main window. For fun and convenience of the user. */
- + if (vim_strchr(p_go, GO_ICON) != NULL)
- + gtk_signal_connect(GTK_OBJECT(gui.mainwin), "realize",
- + GTK_SIGNAL_FUNC(mainwin_realize), NULL);
-
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! /* FIXME: this should eventually get the accelgroup of the gui.mainwin */
- ! gui.accel_group = gtk_accel_group_get_default();
- #endif
-
- ! vbox = gtk_vbox_new(FALSE, 0);
- ! gtk_container_add(GTK_CONTAINER(gui.mainwin), vbox);
- ! gtk_widget_show(vbox);
-
- ! #ifdef WANT_MENU
- ! /* create the menubar and handle */
- ! gui.menubar = gtk_menu_bar_new();
- ! gtk_widget_show(gui.menubar);
- ! gtk_box_pack_start(GTK_BOX(vbox), gui.menubar, FALSE, TRUE, 0);
- #endif
-
- ! #ifdef USE_TOOLBAR
- ! /* create the toolbar */
- ! if (p_toolbar) {
- if (strstr((const char *)p_toolbar, "text")
- ! && strstr((const char *)p_toolbar, "icons"))
- ! gui.toolbar =
- ! gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
- ! else if (strstr((const char *)p_toolbar, "text"))
- ! gui.toolbar =
- ! gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_TEXT);
- else
- ! gui.toolbar =
- ! gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
- ! } else
- ! gui.toolbar =
- ! gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
-
- ! gtk_widget_show(gui.toolbar);
- ! # ifdef GTK_HAVE_FEATURES_1_1_0
- ! /* some aesthetics on the toolbar */
- ! gtk_toolbar_set_button_relief(GTK_TOOLBAR(gui.toolbar), GTK_RELIEF_NONE);
- ! # endif
- ! gtk_container_border_width(GTK_CONTAINER(gui.toolbar), 1);
- ! gtk_box_pack_start(GTK_BOX(vbox), gui.toolbar, FALSE, TRUE, 0);
- #endif
-
- + gui.formwin = gtk_form_new();
- + gtk_container_border_width(GTK_CONTAINER(gui.formwin), 0);
- + gtk_widget_set_events(gui.formwin, GDK_EXPOSURE_MASK);
-
- ! gui.drawarea = gtk_drawing_area_new();
-
- ! /* Determine which events we will filter. */
- ! gtk_widget_set_events(gui.drawarea,
- ! GDK_EXPOSURE_MASK |
- ! GDK_ENTER_NOTIFY_MASK |
- ! GDK_LEAVE_NOTIFY_MASK |
- ! GDK_BUTTON_PRESS_MASK |
- ! GDK_BUTTON_RELEASE_MASK |
- ! GDK_POINTER_MOTION_MASK |
- ! GDK_POINTER_MOTION_HINT_MASK);
-
- ! gtk_widget_show(gui.drawarea);
- ! gtk_form_put(GTK_FORM(gui.formwin), gui.drawarea, 0, 0);
- ! gtk_widget_show(gui.formwin);
- ! gtk_box_pack_start(GTK_BOX(vbox), gui.formwin, TRUE, TRUE, 0);
-
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "key_press_event",
- ! (GtkSignalFunc) key_press_event, NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "realize",
- ! GTK_SIGNAL_FUNC(drawarea_realize_cb), NULL);
- !
- ! /* Check if reverse video needs to be applied (on Sun it's done by X) */
- ! if (gui.rev_video && gui_mch_get_lightness(gui.back_pixel)
- ! > gui_mch_get_lightness(gui.norm_pixel)) {
- ! gui.norm_pixel = gui.def_back_pixel;
- ! gui.back_pixel = gui.def_norm_pixel;
- ! gui.def_norm_pixel = gui.norm_pixel;
- ! gui.def_back_pixel = gui.back_pixel;
- }
- + gui.visibility = GDK_VISIBILITY_UNOBSCURED;
- + clipboard.atom = gdk_atom_intern("_VIM_TEXT", FALSE);
- + save_yourself_atom = gdk_atom_intern("WM_SAVE_YOURSELF", FALSE);
- + reread_rcfiles_atom = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
-
- ! /*
- ! * Start out by adding the configured border width into the border offset.
- ! */
- ! gui.border_offset = gui.border_width;
-
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "visibility_notify_event",
- ! GTK_SIGNAL_FUNC(visibility_event), NULL);
- #endif
- + gtk_signal_connect(GTK_OBJECT(gui.drawarea), "expose_event",
- + GTK_SIGNAL_FUNC(expose_event), NULL);
-
- ! /*
- ! * Only install these enter/leave callbacks when 'p' in 'guioptions'.
- ! * Only needed for some window managers.
- ! */
- ! if (vim_strchr(p_go, GO_POINTER) != NULL) {
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "leave_notify_event",
- ! GTK_SIGNAL_FUNC(leave_notify_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "enter_notify_event",
- ! GTK_SIGNAL_FUNC(enter_notify_event), NULL);
- }
-
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_out_event",
- ! GTK_SIGNAL_FUNC(focus_out_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "focus_in_event",
- ! GTK_SIGNAL_FUNC(focus_in_event), NULL);
-
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "motion_notify_event",
- ! GTK_SIGNAL_FUNC(motion_notify_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_press_event",
- ! GTK_SIGNAL_FUNC(button_press_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "button_release_event",
- ! GTK_SIGNAL_FUNC(button_release_event), NULL);
-
- ! /*
- ! * Add selection handler functions.
- ! */
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_clear_event",
- ! GTK_SIGNAL_FUNC(selection_clear_event), NULL);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_received",
- ! GTK_SIGNAL_FUNC(selection_received_event), NULL);
-
- ! /* gtk_selection_add_target() is not in GTK 1.1.2 */
- ! #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_selection_add_target(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING, SELECTION_STRING);
- ! gtk_selection_add_target(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! clipboard.atom, SELECTION_CLIPBOARD);
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "selection_get",
- ! GTK_SIGNAL_FUNC(selection_get_event), NULL);
- ! #else
- ! gtk_selection_add_handler(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING, selection_handler, NULL);
- ! gtk_selection_add_handler(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! clipboard.atom, selection_handler, NULL);
- ! #endif
-
- ! /* Pretend we don't have input focus, we will get an event if we do. */
- ! gui.in_focus = FALSE;
-
- ! return OK;
- ! }
-
-
- ! /*
- ! * Called when the foreground or background color has been changed.
- ! */
- ! void
- ! gui_mch_new_colors()
- ! {
- ! /* This used to change the graphics contexts directly but we are currently
- ! * manipulating them where desired.
- ! */
- ! if (gui.drawarea && gui.drawarea->window) {
- ! GdkColor color;
- ! color.pixel = gui.back_pixel;
- ! gdk_window_set_background(gui.drawarea->window, &color);
- }
- ! }
- !
- ! #ifdef GTK_HAVE_FEATURES_1_1_6
- ! # define USE_GEOMETRY_FOR_HINTS 1
- #endif
-
- ! static void
- ! update_window_manager_hints(void)
- ! {
- ! int width;
- ! int height;
- ! #ifdef USE_GEOMETRY_FOR_HINTS
- ! GdkGeometry geometry;
- ! GdkWindowHints geometry_mask;
-
- ! /* This also needs to be done when the main window isn't there yet,
- ! * otherwise the hints don't work. */
- ! width = gui_get_base_width();
- ! height = gui_get_base_height();
-
- ! geometry_mask = GDK_HINT_BASE_SIZE|GDK_HINT_RESIZE_INC|GDK_HINT_MIN_SIZE;
- ! geometry.width_inc = gui.char_width;
- ! geometry.height_inc = gui.char_height;
- ! geometry.base_width = width;
- ! geometry.base_height = height;
- ! geometry.min_width = width + MIN_COLUMNS * gui.char_width;
- ! geometry.min_height = height + MIN_LINES * gui.char_height;
- ! gtk_window_set_geometry_hints(GTK_WINDOW(gui.mainwin), gui.formwin,
- ! &geometry, geometry_mask);
- ! #else
- ! XSizeHints size_hints;
-
- ! /* Don't set the size until the main window is really there */
- ! if (!GTK_WIDGET_REALIZED(gui.mainwin))
- ! return;
-
- ! width = gui_get_base_width();
- ! height = gui_get_base_height();
-
- ! /* The hints don't automatically take the menubar and toolbar into
- ! * account. Need to add their height here, if they are visible. */
- ! # ifdef USE_TOOLBAR
- ! if (gui.toolbar && GTK_WIDGET_REALIZED(gui.toolbar)
- ! && GTK_WIDGET_VISIBLE(gui.toolbar))
- ! height += gui.toolbar->allocation.height;
- ! # endif
- ! # ifdef WANT_MENU
- ! if (gui.menubar && GTK_WIDGET_REALIZED(gui.menubar)
- ! && GTK_WIDGET_VISIBLE(gui.menubar))
- ! height += gui.menubar->allocation.height;
- ! # endif
-
- ! /*
- ! * Argh!!! Once again we need to deal with an ommission in GTK+ by
- ! * resorting to direct Xlib calls. Fortunatly I know how to do it :-).
- ! */
- ! size_hints.flags = (PResizeInc | PBaseSize | PMinSize | PSize);
- ! size_hints.width_inc = gui.char_width;
- ! size_hints.height_inc = gui.char_height;
- ! size_hints.base_width = width;
- ! size_hints.base_height = height;
- ! size_hints.min_width = width + MIN_COLUMNS * gui.char_width;
- ! size_hints.min_height = height + MIN_LINES * gui.char_height;
-
- ! /* This is only needed for "older" window managers. See a corresposning
- ! * comment in the X11 headers. */
- ! size_hints.width = width + Columns * gui.char_width;
- ! size_hints.height = height + Rows * gui.char_height;
-
- ! XSetWMNormalHints(GDK_DISPLAY(),
- ! GDK_WINDOW_XWINDOW(gui.mainwin->window),
- ! &size_hints);
- ! #endif /* USE_GEOMETRY_FOR_HINTS */
- ! }
-
- ! /*
- ! * This signal informs us about the need to rearrange our subwidgets.
- ! */
- ! /*ARGSUSED*/
- ! static gint
- ! form_configure_event(GtkWidget * widget, GdkEventConfigure * event)
- ! {
- ! gtk_form_freeze(GTK_FORM(gui.formwin));
- ! gui_resize_window(event->width, event->height);
- ! gtk_form_thaw(GTK_FORM(gui.formwin));
-
- ! return TRUE;
- ! }
-
- ! /*
- ! * X11 based inter client communication handler.
- ! */
- ! /*ARGSUSED*/
- ! static gint
- ! client_event_cb(GtkWidget *widget, GdkEventClient *event)
- ! {
- ! if (event->message_type == save_yourself_atom ) {
- ! out_flush();
- ! ml_sync_all(FALSE, FALSE); /* preserve all swap files */
- ! return TRUE;
- ! } else if (event->message_type == reread_rcfiles_atom) {
- ! gui_mch_new_colors();
- ! return TRUE;
- ! }
- ! return FALSE;
- ! }
-
- ! /*
- ! * Function called when window already closed.
- ! * We can't do much more here than to trying to preserve what had been done,
- ! * since the window is already inevitably going away.
- ! */
- ! static void
- ! destroy_callback(void)
- ! {
- ! /* preserve files and exit */
- ! preserve_exit();
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- ! }
-
-
- ! /*
- ! * Open the GUI window which was created by a call to gui_mch_init().
- ! */
- ! int
- ! gui_mch_open()
- ! {
- ! int x = -1, y = -1;
-
- ! /* Determine user specified geometry, if present. */
- ! if (gui.geom) {
- ! int mask;
- ! unsigned w, h;
-
- ! mask = XParseGeometry((char *)gui.geom, &x, &y, &w, &h);
- ! if (mask & WidthValue)
- ! Columns = w;
- ! if (mask & HeightValue)
- ! Rows = h;
- ! if (mask & (XValue | YValue))
- ! gtk_widget_set_uposition(gui.mainwin, x, y);
- ! g_free(gui.geom);
- ! gui.geom = NULL;
- }
-
- ! gtk_form_set_size(GTK_FORM(gui.formwin),
- ! (guint)(gui_get_base_width() + Columns * gui.char_width),
- ! (guint)(gui_get_base_height() + Rows * gui.char_height));
- update_window_manager_hints();
-
- ! if (found_reverse_arg )
- ! {
- ! gui.def_norm_pixel = gui_mch_get_color((char_u *)"White");
- ! gui.def_back_pixel = gui_mch_get_color((char_u *)"Black");
- ! }
- ! else
- ! {
- ! gui.def_norm_pixel = gui_mch_get_color((char_u *)"Black");
- ! gui.def_back_pixel = gui_mch_get_color((char_u *)"White");
- ! }
-
- + /* Get the colors from the "Normal" and "Menu" group (set in syntax.c or
- + * in a vimrc file)
- + */
- + set_normal_colors();
-
- ! /* Check that none of the colors are the same as the background color */
- ! gui_check_colors();
-
- ! /* Get the colors for the highlight groups (gui_check_colors() might have
- ! * changed them).
- ! */
- ! highlight_gui_started(); /* re-init colors and fonts */
-
- ! gtk_signal_connect(GTK_OBJECT(gui.mainwin), "destroy",
- ! GTK_SIGNAL_FUNC(destroy_callback), NULL);
- !
- ! /* Make this run after any internal handling of the client event happaned
- ! * to make sure that all changes implicated by it are already in place and
- ! * we thus can make our own adjustments.
- ! */
- ! gtk_signal_connect_after(GTK_OBJECT(gui.mainwin), "client_event",
- ! GTK_SIGNAL_FUNC(client_event_cb), NULL);
- ! #ifdef HANGUL_INPUT
- ! hangul_keyboard_set();
- #endif
-
- ! /*
- ! * Notify the fixed area about the need to resize the contents of the
- ! * gui.formwin, which we use for random positioning of the included
- ! * components.
- ! *
- ! * We connect this signal deferred finally after anything is in place,
- ! * since this is intended to handle resizements coming from the window
- ! * manager upon us and should not interfere with what VIM is requesting
- ! * upon startup.
- ! */
- ! gtk_signal_connect(GTK_OBJECT(gui.formwin), "configure_event",
- ! GTK_SIGNAL_FUNC(form_configure_event), NULL);
-
- ! #ifdef GTK_DND
- ! /*
- ! * Set up for receiving DND items.
- ! */
- ! gtk_drag_dest_set(gui.drawarea,
- ! GTK_DEST_DEFAULT_ALL,
- ! target_table, n_targets,
- ! GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
- ! gtk_signal_connect(GTK_OBJECT(gui.drawarea), "drag_data_received",
- ! GTK_SIGNAL_FUNC(drag_data_received), NULL);
- ! #endif
-
- ! gtk_widget_show(gui.mainwin);
- !
- ! return OK;
- }
-
- !
- ! /*ARGSUSED*/
- void
- ! gui_mch_exit(int rc)
- {
- ! gtk_exit(0);
- }
-
- /*
- ! * Get the position of the top left corner of the window.
- */
- int
- ! gui_mch_get_winpos(int *x, int *y)
- {
- ! /* For some people this must be gdk_window_get_origin() for a correct
- ! * result. Where is the documentation! */
- ! #ifdef GTK_HAVE_FEATURES_1_1_4
- ! gdk_window_get_root_origin(gui.mainwin->window, x, y);
- ! #else
- ! gdk_window_get_origin(gui.mainwin->window, x, y);
- #endif
- + return OK;
- + }
-
- /*
- ! * Set the position of the top left corner of the window to the given
- ! * coordinates.
- */
- void
- ! gui_mch_set_winpos(int x, int y)
- {
- ! gdk_window_move(gui.mainwin->window, x, y);
- }
-
- /*
- ! * Set the windows size.
- */
- ! /*ARGSUSED*/
- ! void
- ! gui_mch_set_winsize(int width, int height,
- ! int min_width, int min_height,
- ! int base_width, int base_height)
- {
- ! gtk_form_set_size(GTK_FORM(gui.formwin), width, height);
-
- ! /* give GTK+ a chance to put all widget's into place */
- ! gui_mch_update();
-
- ! /* this will cause the proper resizement to happen too */
- ! update_window_manager_hints();
- }
-
-
- /*
- ! * The screen size is used to make sure the initial window doesn't get bigger
- ! * then the screen. This subtracts some room for menubar, toolbar and window
- ! * decoreations.
- */
- void
- ! gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
- {
- ! *screen_w = gdk_screen_width();
- ! /* Subtract 'guihearroom' from the height to allow some room for the
- ! * window manager (task list and window title bar). */
- ! *screen_h = gdk_screen_height() - p_ghr;
- !
- ! /*
- ! * FIXME: dirty trick: Because the gui_get_base_height() doesn't include
- ! * the toolbar and menubar for GTK, we subtract them from the screen
- ! * hight, so that the window size can be made to fit on the screen.
- ! * This should be completely changed later.
- ! */
- ! #ifdef USE_TOOLBAR
- ! if (gui.toolbar && GTK_WIDGET_REALIZED(gui.toolbar)
- ! && GTK_WIDGET_VISIBLE(gui.toolbar))
- ! *screen_h -= gui.toolbar->allocation.height;
- ! #endif
- ! #ifdef WANT_MENU
- ! if (gui.menubar && GTK_WIDGET_REALIZED(gui.menubar)
- ! && GTK_WIDGET_VISIBLE(gui.menubar))
- ! *screen_h -= gui.menubar->allocation.height;
- ! #endif
- }
-
- ! #if defined(WANT_MENU) || defined(PROTO)
- void
- ! gui_mch_enable_menu(int flag)
- {
- ! if (flag)
- ! gtk_widget_show(gui.menubar);
- ! else
- ! gtk_widget_hide(gui.menubar);
- !
- ! update_window_manager_hints();
- }
- + #endif
- +
-
- + #if defined(USE_TOOLBAR) || defined(PROTO)
- void
- ! gui_mch_show_toolbar(int showit)
- {
- ! if (gui.toolbar == NULL)
- return;
-
- ! if (!showit) {
- ! if (GTK_WIDGET_VISIBLE(gui.toolbar)) {
- ! gtk_widget_hide(gui.toolbar);
- ! /* wait util this gets done on the server side. */
- ! update_window_manager_hints();
- ! }
- ! } else {
- ! g_assert(p_toolbar != NULL);
- ! if (strstr((const char *)p_toolbar, "text")
- ! && strstr((const char *)p_toolbar, "icons")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_BOTH);
- ! } else if (strstr((const char *)p_toolbar, "text")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_TEXT);
- ! } else if (strstr((const char *)p_toolbar, "icons")) {
- ! gtk_toolbar_set_style(GTK_TOOLBAR(gui.toolbar), GTK_TOOLBAR_ICONS);
- }
-
- ! if (!GTK_WIDGET_VISIBLE(gui.toolbar)) {
- ! gtk_widget_show(gui.toolbar);
- ! update_window_manager_hints();
- ! }
-
- ! if (strstr((const char *)p_toolbar, "tooltips"))
- ! gtk_toolbar_set_tooltips(GTK_TOOLBAR(gui.toolbar), TRUE);
- ! else
- ! gtk_toolbar_set_tooltips(GTK_TOOLBAR(gui.toolbar), FALSE);
- }
- }
- #endif
-
-
- ! #ifdef USE_FONTSET
- ! static GuiFont
- ! gui_mch_get_fontset(char_u * name, int report_error)
- {
- ! GdkFont *font;
-
- ! if (!gui.in_use || name == NULL)
- ! return (GuiFont) 0;
-
- ! font = gdk_fontset_load((gchar *) name);
-
- ! if (font == NULL) {
- ! if (report_error)
- ! EMSG2("Unknown fontset: %s", name);
- ! return (GuiFont) 0;
- ! }
-
- ! /* reference this font as beeing in use */
- ! gdk_font_ref(font);
-
- ! return (GuiFont) font;
- }
- + #endif
-
- + #ifdef GTK_HAVE_FEATURES_1_1_0
- /*
- ! * Get a font structure for highlighting.
- ! * "cbdata" is a pointer to the global gui structure.
- */
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_ok(GtkWidget *wgt, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
- ! GtkFontSelectionDialog *fs = (GtkFontSelectionDialog *)vw->fontdlg;
-
- ! if (vw->fontname)
- ! g_free(vw->fontname);
-
- ! vw->fontname = (char_u *)g_strdup(
- ! gtk_font_selection_dialog_get_font_name(fs));
- ! gtk_widget_hide(vw->fontdlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- ! }
-
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_cancel(GtkWidget *wgt, gpointer cbdata)
- ! {
- ! Gui *vw = (Gui *)cbdata;
- !
- ! gtk_widget_hide(vw->fontdlg);
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
-
- ! /*ARGSUSED*/
- ! static void
- ! font_sel_destroy(GtkWidget *wgt, gpointer cbdata)
- {
- ! Gui *vw = (Gui *)cbdata;
- !
- ! vw->fontdlg = NULL;
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- }
- + #endif
-
- /*
- ! * Initialise vim to use the font with the given name.
- ! * Return FAIL if the font could not be loaded, OK otherwise.
- */
- ! int
- ! gui_mch_init_font(char_u * font_name)
- {
- ! GdkFont *font = NULL;
- ! char *chunk[28], *sdup, *tmp;
- ! int len, i;
-
- ! #ifdef USE_FONTSET
- ! {
- ! static char_u *dflt_fontset = NULL;
-
- ! if (gui.fontset)
- ! {
- ! /* If fontset is active, VIM treat all the font as a fontset. */
- ! if (font_name == NULL || vim_strchr(font_name, ',') == NULL)
- ! font_name = dflt_fontset;
- ! font = gui_mch_get_fontset(font_name, FALSE);
- ! if (font == NULL)
- ! return FAIL;
- ! }
- ! else if (font_name == NULL && *p_guifontset)
- ! {
- ! font = gui_mch_get_fontset(p_guifontset, FALSE);
- ! if (font)
- ! {
- ! font_name = p_guifontset;
- ! dflt_fontset = alloc(STRLEN(p_guifontset) + 1);
- ! STRCPY(dflt_fontset, p_guifontset);
- ! }
- ! }
- ! }
-
- ! if (font == NULL)
- ! #endif
- {
- ! /*
- ! * If none of the fonts in 'font' could be loaded, try the default,
- ! * which should be present on all X11 servers.
- ! */
- ! if (font_name == NULL)
- ! font_name = (char_u *) DFLT_FONT;
- !
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! if (STRCMP(font_name, "*") == 0) {
- ! /*
- ! * Request for a font handling dialog.
- ! * Not quite sure we should handle this here...
- ! */
- ! /*
- ! * NOTE about font selection widget: this can easily be backported
- ! * to gtk-1.0.x.
- ! */
- ! if (!gui.fontdlg)
- ! {
- ! GtkFontSelectionDialog *fsd = NULL;
- !
- ! gui.fontdlg = gtk_font_selection_dialog_new("Font Selection");
- ! fsd = GTK_FONT_SELECTION_DIALOG(gui.fontdlg);
- ! if (p_guifont != NULL)
- ! gtk_font_selection_dialog_set_font_name(fsd,
- ! (char *)p_guifont);
- ! # ifdef GTK_HAVE_FEATURES_1_1_4
- ! gtk_window_set_modal(GTK_WINDOW(gui.fontdlg), TRUE);
- ! gtk_window_set_transient_for(GTK_WINDOW(gui.fontdlg),
- ! GTK_WINDOW(gui.mainwin));
- # endif
- ! gtk_signal_connect(GTK_OBJECT(gui.fontdlg), "destroy",
- ! GTK_SIGNAL_FUNC(font_sel_destroy), &gui);
- ! gtk_signal_connect(GTK_OBJECT(fsd->ok_button), "clicked",
- ! GTK_SIGNAL_FUNC(font_sel_ok), &gui);
- ! gtk_signal_connect(GTK_OBJECT(fsd->cancel_button), "clicked",
- ! GTK_SIGNAL_FUNC(font_sel_cancel), &gui);
- ! }
- ! if (gui.fontname)
- ! {
- ! g_free(gui.fontname);
- ! gui.fontname = NULL;
- ! }
- ! gtk_window_position(GTK_WINDOW(gui.fontdlg), GTK_WIN_POS_MOUSE);
- ! gtk_widget_show(gui.fontdlg);
- ! # ifdef GTK_HAVE_FEATURES_1_1_4
- ! {
- ! static gchar *spacings[] = {"c", "m", NULL};
- !
- ! /* In GTK 1.2.3 this must be after the gtk_widget_show() call,
- ! * otherwise everything is blocked for ten seconds. */
- ! gtk_font_selection_dialog_set_filter(
- ! GTK_FONT_SELECTION_DIALOG(gui.fontdlg),
- ! GTK_FONT_FILTER_BASE,
- ! GTK_FONT_ALL, NULL, NULL,
- ! NULL, NULL, spacings, NULL);
- ! }
- ! # endif
- !
- ! while (gui.fontdlg && GTK_WIDGET_VISIBLE(gui.fontdlg))
- ! gtk_main_iteration_do(TRUE);
- !
- ! if (gui.fontname == NULL)
- ! return FAIL;
- ! vim_free(p_guifont);
- ! p_guifont = vim_strsave(gui.fontname);
- ! font_name = p_guifont;
- ! }
- ! #endif
- ! if (font == NULL)
- ! font = gui_mch_get_font(font_name, FALSE);
- !
- ! if (font == NULL)
- ! return FAIL;
- ! }
- !
- ! if (gui.norm_font != 0)
- ! gdk_font_unref(font);
- ! gui.norm_font = font;
- ! #ifdef USE_FONTSET
- ! if (font->type == GDK_FONT_FONTSET)
- ! {
- ! gui.fontset = (GuiFont) font;
- ! gui.char_width = gdk_string_width(font, " ");
- }
- else
- #endif
- ! {
- ! gui.char_width = ((XFontStruct *)
- ! GDK_FONT_XFONT(font))->max_bounds.width;
- ! }
-
- ! gui.char_height = font->ascent + font->descent;
- ! gui.char_ascent = font->ascent;
-
- ! /* Set the fontname, which will be used for information purposes */
- ! hl_set_font_name(font_name);
-
- ! if (font->type != GDK_FONT_FONTSET)
- ! {
- ! /* There is only one excuse I can give for the following attempt
- ! * to manage font styles:
- ! *
- ! * I HATE THE BRAIN DEAD WAY X11 IS HANDLING FONTS (--mdcki)
- ! */
- ! if ((sdup = g_strdup((const char *)font_name)) == NULL)
- ! return FAIL;
-
- ! /* slipt up the whole */
- ! i = 0;
- ! for (tmp = sdup; *tmp != '\0'; ++tmp)
- ! if (*tmp == '-')
- ! {
- ! *tmp = '\0';
- ! chunk[i] = tmp + 1;
- ! ++i;
- ! }
- !
- ! g_free(sdup);
- !
- ! if (i == 14)
- ! {
- ! char *bold_name = NULL;
- ! char *ital_name = NULL;
- ! char *italbold_name = NULL;
- !
- ! /* font name was compleate */
- ! len = strlen((const char *)font_name) + 32;
- ! bold_name = (char *)alloc(len);
- ! ital_name = (char *)alloc(len);
- ! italbold_name = (char *)alloc(len);
- ! if (bold_name == NULL || ital_name == NULL || italbold_name == NULL)
- ! {
- ! vim_free(bold_name);
- ! vim_free(ital_name);
- ! vim_free(italbold_name);
- ! return FAIL;
- ! }
- !
- ! *bold_name = '\0';
- ! *ital_name = '\0';
- ! *italbold_name = '\0';
- !
- ! for (i = 0; i < 14; ++i)
- ! {
- ! strcat(bold_name, "-");
- ! strcat(ital_name, "-");
- ! strcat(italbold_name, "-");
- ! strcat(bold_name, (i != 2) ? chunk[i] : "bold");
- ! strcat(ital_name, (i != 3) ? chunk[i] : "o");
- !
- ! if (i != 2 && i != 3)
- ! strcat(italbold_name, chunk[i]);
- ! else
- ! {
- ! if (i == 2)
- ! strcat(italbold_name, "bold");
- ! else if (i == 3)
- ! strcat(italbold_name, "o");
- ! }
- ! }
- !
- ! font = gui_mch_get_font((char_u *)bold_name, FALSE);
- ! if (font != NULL)
- ! gui.bold_font = font;
- ! else if (gui.bold_font)
- ! {
- ! gdk_font_unref(gui.bold_font);
- ! gui.bold_font = NULL;
- ! }
- !
- ! font = gui_mch_get_font((char_u *)ital_name, FALSE);
- ! if (font != NULL)
- ! gui.ital_font = font;
- ! else if (gui.ital_font)
- ! {
- ! gdk_font_unref(gui.ital_font);
- ! gui.ital_font = NULL;
- ! }
- !
- ! font = gui_mch_get_font((char_u *)italbold_name, FALSE);
- ! if (font != NULL)
- ! gui.boldital_font = font;
- ! else if (gui.boldital_font)
- ! {
- ! gdk_font_unref(gui.boldital_font);
- ! gui.boldital_font = NULL;
- ! }
- !
- ! vim_free(bold_name);
- ! vim_free(ital_name);
- ! vim_free(italbold_name);
- ! }
- ! }
- !
- ! /* Synchronize the fonts used in user input dialogs, since otherwise
- ! * search/replace will be esp annoyig in case of international font usage.
- ! */
- ! gui_gtk_synch_fonts();
- !
- ! #ifdef USE_XIM
- ! /* Adjust input management behaviour to the capabilities of the new
- ! * fontset */
- ! xim_decide_input_style();
- ! if (xim_get_status_area_height())
- ! {
- ! /* Status area is required. Just create the empty label so that
- ! * mainwin will allocate the extra space for status area. */
- ! GtkWidget *label = gtk_label_new(" ");
- !
- ! gtk_widget_set_usize(label, 20, gui.char_height + 2);
- ! gtk_box_pack_end(GTK_BOX(GTK_BIN(gui.mainwin)->child), label,
- ! FALSE, FALSE, 0);
- ! gtk_widget_show(label);
- ! }
- ! #endif
-
- ! /* Preserve the logical dimensions of the screen. */
- ! update_window_manager_hints();
-
- ! return OK;
- }
-
-
- ! GuiFont
- ! gui_mch_get_font(char_u * name, int report_error)
- {
- ! GdkFont *font;
-
- ! if (!gui.in_use || name == NULL) /* can't do this when GUI not running */
- ! return (GuiFont) 0;
-
- ! #ifdef USE_FONTSET
- ! if (gui.fontset)
- ! /* If fontset is active, VIM treat all the font as a fontset */
- ! return gui_mch_get_fontset(name, report_error);
- ! else if (vim_strchr(name, ','))
- ! return (GuiFont)0;
- #endif
-
- ! font = gdk_font_load((const gchar *) name);
-
- ! if (font == NULL) {
- ! if (report_error)
- ! EMSG2("Unknown font: %s", name);
- ! return (GuiFont) 0;
- ! }
-
- ! /* reference this font as beeing in use */
- ! gdk_font_ref(font);
- ! if (((XFontStruct *) GDK_FONT_XFONT(font))->max_bounds.width
- ! != ((XFontStruct *) GDK_FONT_XFONT(font))->min_bounds.width) {
- ! EMSG2("Font \"%s\" is not fixed-width", name);
- ! gdk_font_unref(font);
-
- ! return (GuiFont) 0;
- ! }
- ! return (GuiFont) font;
- }
-
- /*
- ! * Set the current text font.
- ! * Since we create all GC on demand, we use just gui.current_font to
- ! * indicate the desired current font.
- */
- ! void
- ! gui_mch_set_font(GuiFont font)
- {
- ! gui.current_font = font;
- }
-
- ! #if 0 /* not used */
- ! /*
- ! * Return TRUE if the two fonts given are equivalent.
- ! */
- ! int
- ! gui_mch_same_font(GuiFont f1, GuiFont f2)
- {
- ! return gdk_font_equal((GdkFont *) f1, (GdkFont *) f2);
- }
- + #endif
-
- /*
- ! * If a font is not going to be used, free its structure.
- */
- void
- ! gui_mch_free_font(GuiFont font)
- {
- ! if (font)
- ! gdk_font_unref((GdkFont *) font);
- ! }
-
-
- ! /*
- ! * Return the Pixel value (color) for the given color name. This routine was
- ! * pretty much taken from example code in the Silicon Graphics OSF/Motif
- ! * Programmer's Guide.
- ! * Return -1 for error.
- ! */
- ! GuiColor
- ! gui_mch_get_color(char_u * name)
- ! {
- ! int i;
- ! static char *(vimnames[][2]) =
- ! {
- ! /* A number of colors that some X11 systems don't have */
- ! {"LightRed", "#FFA0A0"},
- ! {"LightGreen", "#80FF80"},
- ! {"LightMagenta", "#FFA0FF"},
- ! {"DarkCyan", "#008080"},
- ! {"DarkBlue", "#0000C0"},
- ! {"DarkRed", "#C00000"},
- ! {"DarkMagenta", "#C000C0"},
- ! {"DarkGrey", "#C0C0C0"},
- ! {NULL, NULL}
- ! };
-
- ! if (!gui.in_use) /* can't do this when GUI not running */
- ! return (GuiColor)(-1);
-
- ! while (name != NULL) {
- ! GdkColor color;
-
- ! if (gdk_color_parse((const gchar *)name, &color)) {
- ! GdkColormap *colormap;
- ! colormap = gtk_widget_get_colormap(gui.drawarea);
- ! gdk_color_alloc(colormap, &color);
-
- ! return (GuiColor) color.pixel;
- ! }
- ! /* add a few builtin names */
- ! for (i = 0;; ++i) {
- ! if (vimnames[i][0] == NULL) {
- ! name = NULL;
- ! break;
- ! }
- ! if (STRICMP(name, vimnames[i][0]) == 0) {
- ! name = (char_u *) vimnames[i][1];
- ! break;
- ! }
- ! }
- ! }
-
- ! return (GuiColor)(-1);
- }
-
- /*
- ! * Set the current text foreground color.
- */
- ! void
- ! gui_mch_set_fg_color(GuiColor color)
- {
- ! gui.fgcolor->pixel = (Pixel) color;
- ! }
-
- ! /*
- ! * Set the current text background color.
- ! */
- ! void
- ! gui_mch_set_bg_color(GuiColor color)
- ! {
- ! gui.bgcolor->pixel = (Pixel) color;
- }
-
- /*
- ! * Use the blank mouse pointer or not.
- ! *
- ! * hide: TRUE = use blank ptr, FALSE = use parent ptr
- */
- void
- ! gui_mch_mousehide(int hide)
- {
- ! if (gui.pointer_hidden != hide) {
- ! if (gui.drawarea->window && gui.blank_pointer) {
- ! if (hide)
- ! gdk_window_set_cursor(gui.drawarea->window, gui.blank_pointer);
- ! else
- ! gdk_window_set_cursor(gui.drawarea->window, NULL);
- }
- ! gui.pointer_hidden = hide;
- }
- }
-
- void
- ! gui_mch_draw_string(int row, int col, char_u * s, int len, int flags)
- {
- ! GdkGC *gc;
-
- ! if (gui.current_font == NULL || gui.drawarea->window == NULL)
- return;
-
- ! #if defined(USE_FONTSET) && defined(MULTI_BYTE)
- ! if (gui.fontset)
- ! {
- ! if (col > 0 && mb_isbyte1(LinePointers[row], col - 1))
- ! {
- ! col++;
- ! len--;
- ! s++;
- ! }
- ! if (len == 1 && IsLeadByte(*s))
- ! len = 2;
- ! }
- ! #endif
- !
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- !
- ! if (flags & DRAW_TRANSP) {
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col), TEXT_Y(row),
- ! (const gchar *)s, len);
- } else {
- ! int width;
- ! int height;
- ! width = gdk_text_width(gui.current_font, (const gchar *)s, len);
- ! height = gui.char_height;
-
- ! gdk_gc_set_foreground(gc, gui.bgcolor);
- ! gdk_draw_rectangle(gui.drawarea->window,
- ! gc,
- ! TRUE,
- ! FILL_X(col), FILL_Y(row), width, height);
- gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col), TEXT_Y(row),
- ! (const gchar *)s, len);
- ! }
-
- ! /* redraw the contents with an offset of 1 to emulate bold */
- ! if (flags & DRAW_BOLD) {
- ! gdk_draw_text(gui.drawarea->window,
- ! gui.current_font,
- ! gc,
- ! TEXT_X(col) + 1, TEXT_Y(row),
- ! (const gchar *)s, len);
- ! }
-
- ! if (flags & DRAW_UNDERL) {
- ! gdk_draw_line(gui.drawarea->window,
- ! gc, FILL_X(col),
- ! FILL_Y(row + 1) - 1, FILL_X(col + len) - 1, FILL_Y(row + 1) - 1);
- }
- + gdk_gc_destroy(gc);
- }
-
- /*
- ! * Return OK if the key with the termcap name "name" is supported.
- */
- ! int
- ! gui_mch_haskey(char_u * name)
- {
- ! int i;
-
- ! for (i = 0; special_keys[i].key_sym != 0; i++)
- ! if (name[0] == special_keys[i].code0 &&
- ! name[1] == special_keys[i].code1)
- ! return OK;
- ! return FAIL;
- ! }
- !
- ! #if defined(WANT_TITLE) || defined(PROTO)
- ! /*
- ! * Return the text window-id and display. Only required for X-based GUI's
- ! */
- ! int
- ! gui_get_x11_windis(Window * win, Display ** dis)
- ! {
- ! /*
- ! * This is currently only used by the code which is handling the
- ! * window manager title of this program.
- ! */
- ! *dis = GDK_DISPLAY();
- ! if (gui.mainwin->window) {
- ! *win = GDK_WINDOW_XWINDOW(gui.mainwin->window);
- ! return OK;
- }
- + *win = 0;
- + return FAIL;
- }
- + #endif
-
- void
- ! gui_mch_beep()
- {
- ! gdk_beep();
- ! }
- !
- ! void
- ! gui_mch_flash()
- ! {
- ! GdkGCValues values;
- ! GdkGC *invert_gc;
- ! GdkColor foreground;
- ! GdkColor background;
- !
- ! if (gui.drawarea->window == NULL)
- ! return;
- !
- ! foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
- ! background.pixel = gui.norm_pixel ^ gui.back_pixel;
- !
- ! values.foreground = foreground;
- ! values.background = background;
- ! values.function = GDK_XOR;
- ! invert_gc = gdk_gc_new_with_values(gui.drawarea->window,
- ! &values,
- ! GDK_GC_FOREGROUND |
- ! GDK_GC_BACKGROUND |
- ! GDK_GC_FUNCTION);
- ! gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- !
- ! /* Do a visual beep by changing back and forth in some undetermined way,
- ! * the foreground and background colors. This is due to the fact that
- ! * there can't be really any prediction about the effects of XOR on
- ! * arbitrary X11 servers. However this seems to be enought for what we
- ! * intend it to do.
- ! */
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! 0, 0,
- ! FILL_X((int) Columns) + gui.border_offset,
- ! FILL_Y((int) Rows) + gui.border_offset);
- !
- ! gdk_flush();
- ! ui_delay(20L, TRUE); /* wait 1/50 of a second */
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! 0, 0,
- ! FILL_X((int) Columns) + gui.border_offset,
- ! FILL_Y((int) Rows) + gui.border_offset);
- !
- ! gdk_gc_destroy(invert_gc);
- }
-
- /*
- ! * Invert a rectangle from row r, column c, for nr rows and nc columns.
- */
- ! void
- ! gui_mch_invert_rectangle(int r, int c, int nr, int nc)
- {
- ! GdkGCValues values;
- ! GdkGC *invert_gc;
- ! GdkColor foreground;
- ! GdkColor background;
-
- ! if (gui.drawarea->window == NULL)
- ! return;
- !
- ! foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
- ! background.pixel = gui.norm_pixel ^ gui.back_pixel;
- !
- ! values.foreground = foreground;
- ! values.background = background;
- ! values.function = GDK_XOR;
- ! invert_gc = gdk_gc_new_with_values(gui.drawarea->window,
- ! &values,
- ! GDK_GC_FOREGROUND |
- ! GDK_GC_BACKGROUND |
- ! GDK_GC_FUNCTION);
- ! gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_draw_rectangle(gui.drawarea->window, invert_gc,
- ! TRUE,
- ! FILL_X(c), FILL_Y(r),
- ! (nc) * gui.char_width, (nr) * gui.char_height);
- ! gdk_gc_destroy(invert_gc);
- }
-
- /*
- ! * Iconify the GUI window.
- */
- void
- ! gui_mch_iconify()
- {
- ! XIconifyWindow(GDK_DISPLAY(),
- ! GDK_WINDOW_XWINDOW(gui.mainwin->window),
- ! DefaultScreen(GDK_DISPLAY()));
- }
-
- /*
- ! * Draw a cursor without focus.
- */
- void
- ! gui_mch_draw_hollow_cursor(GuiColor color)
- {
- ! GdkGC *gc;
- !
- ! if (gui.drawarea->window == NULL)
- return;
-
- ! gui_mch_set_fg_color(color);
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! #if defined(USE_FONTSET) && defined(MULTI_BYTE)
- ! if (gui.fontset)
- ! {
- ! if (IsLeadByte(LinePointers[gui.row][gui.col])
- ! # ifdef HANGUL_INPUT
- ! || composing_hangul
- ! # endif
- ! )
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! 2*gui.char_width - 1, gui.char_height - 1);
- ! else
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! gui.char_width - 1, gui.char_height - 1);
- ! }
- ! else
- ! #endif
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! FALSE,
- ! FILL_X(gui.col), FILL_Y(gui.row),
- ! gui.char_width - 1, gui.char_height - 1);
- ! gdk_gc_destroy(gc);
- }
-
- /*
- ! * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
- ! * color "color".
- */
- void
- ! gui_mch_draw_part_cursor(int w, int h, GuiColor color)
- {
- ! GdkGC *gc;
- !
- ! if (gui.drawarea->window == NULL)
- return;
-
- ! gui_mch_set_fg_color(color);
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_draw_rectangle(gui.drawarea->window, gc,
- ! TRUE,
- ! #ifdef RIGHTLEFT
- ! /* vertical line should be on the right of current point */
- ! State != CMDLINE && curwin->w_p_rl ? FILL_X(gui.col + 1) - w :
- ! #endif
- ! FILL_X(gui.col),
- ! FILL_Y(gui.row) + gui.char_height - h,
- ! w, h);
- ! gdk_gc_destroy(gc);
- }
-
- ! #ifndef GTK_HAVE_FEATURES_1_1_0
- ! static gint
- ! idle_function(GtkWidget * label)
- {
- ! if (gtk_main_level() > 0)
- ! gtk_main_quit();
- !
- ! return FALSE;
- }
- #endif
-
- +
- /*
- ! * Catch up with any queued X11 events. This may put keyboard input into the
- ! * input buffer, call resize call-backs, trigger timers etc. If there is
- ! * nothing in the X11 event queue (& no timers pending), then we return
- ! * immediately.
- */
- void
- ! gui_mch_update()
- {
- ! #ifdef GTK_HAVE_FEATURES_1_1_0
- ! while (gtk_events_pending() && !vim_is_input_buf_full())
- ! gtk_main_iteration_do(FALSE);
- ! #else
- ! int pending;
- !
- ! /* Somehow the above loop hangs on GTK 1.0.6. Use the idle_function() to
- ! * work around this weird problem. */
- ! while (((pending = gtk_events_pending()) > 1) && !vim_is_input_buf_full())
- ! gtk_main_iteration();
- !
- ! if ((pending == 1) && !vim_is_input_buf_full()) {
- ! gtk_idle_add((GtkFunction)idle_function, gui.mainwin);
- ! gtk_main_iteration_do(FALSE);
- ! }
- ! #endif
- }
-
- + static gint
- + input_timer_cb(gpointer data)
- + {
- + int *timed_out = (int *) data;
- +
- + /* Just inform the caller about the accurence of it */
- + *timed_out = TRUE;
- +
- + if (gtk_main_level() > 0)
- + gtk_main_quit();
- +
- + return FALSE; /* don't happen again */
- + }
-
- /*
- ! * GUI input routine called by gui_wait_for_chars(). Waits for a character
- ! * from the keyboard.
- ! * wtime == -1 Wait forever.
- ! * wtime == 0 This should never happen.
- ! * wtime > 0 Wait wtime milliseconds for a character.
- ! * Returns OK if a character was found to be available within the given time,
- ! * or FAIL otherwise.
- */
- int
- ! gui_mch_wait_for_chars(long wtime)
- {
- ! int focus;
- ! guint timer;
-
- ! static int timed_out;
-
- ! timed_out = FALSE;
- !
- ! /* this timeout makes sure that we will return if no characters arrived in
- ! * time */
- !
- ! if (wtime > 0)
- ! timer = gtk_timeout_add((guint32)wtime, input_timer_cb, &timed_out);
- ! else
- ! timer = 0;
- !
- ! focus = gui.in_focus;
- !
- ! do {
- ! /* Stop or start blinking when focus changes */
- ! if (gui.in_focus != focus) {
- ! if (gui.in_focus)
- ! gui_mch_start_blink();
- ! else
- ! gui_mch_stop_blink();
- ! focus = gui.in_focus;
- ! }
- !
- ! /*
- ! * Loop in GTK+ processing until a timeout or input occurs.
- ! */
- ! gtk_main();
- !
- ! /* Got char, return immediately */
- ! if (!vim_is_input_buf_empty()) {
- ! if (timer != 0 && !timed_out)
- ! gtk_timeout_remove(timer);
- ! return OK;
- ! }
- ! } while (wtime < 0 || !timed_out);
- !
- ! /*
- ! * Flush all eventually pending (drawing) events.
- ! */
- ! gui_mch_update();
- !
- ! return FAIL;
- ! }
- !
- !
- ! /****************************************************************************
- ! * Output drawing routines.
- ! ****************************************************************************/
- !
- !
- ! /* Flush any output to the screen */
- ! void
- ! gui_mch_flush()
- ! {
- ! gdk_flush();
- }
-
- /*
- ! * Clear a rectangular region of the screen from text pos (row1, col1) to
- ! * (row2, col2) inclusive.
- */
- ! void
- ! gui_mch_clear_block(int row1, int col1, int row2, int col2)
- {
- ! GdkGC *gc;
- ! GdkColor color;
- !
- ! if (gui.drawarea->window == NULL)
- ! return;
- !
- ! color.pixel = gui.back_pixel;
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, &color);
-
- ! /*
- ! * Clear one extra pixel at the right, for when bold characters have
- ! * spilled over to the next column. This can erase part of the next
- ! * character however in the usage context of this function it will be
- ! * overriden immediately by the correct character again.
- ! */
-
- ! gdk_draw_rectangle(gui.drawarea->window, gc, TRUE,
- ! FILL_X(col1), FILL_Y(row1),
- ! (col2 - col1 + 1) * gui.char_width + 1,
- ! (row2 - row1 + 1) * gui.char_height);
- ! gdk_gc_destroy(gc);
- ! }
-
- ! void
- ! gui_mch_clear_all(void)
- ! {
- ! if (gui.drawarea->window == NULL)
- ! return;
-
- ! gdk_window_clear(gui.drawarea->window);
- }
-
- /*
- ! * Scroll the text between gui.scroll_region_top & gui.scroll_region_bot by the
- ! * number of lines given. Positive scrolls down (text goes up) and negative
- ! * scrolls up (text goes down).
- */
- ! static void check_copy_area(void)
- {
- ! XEvent event;
- ! XGraphicsExposeEvent *gevent;
-
- ! if (gui.visibility != GDK_VISIBILITY_PARTIAL)
- ! return;
-
- ! gdk_flush();
- !
- ! /* Wait to check whether the scroll worked or not. */
- ! for (;;) {
- ! if (XCheckTypedEvent(GDK_DISPLAY(), NoExpose, &event))
- ! return; /* The scroll worked. */
-
- ! if (XCheckTypedEvent(GDK_DISPLAY(), GraphicsExpose, &event)) {
- ! gevent = (XGraphicsExposeEvent *) & event;
- ! gui_redraw(gevent->x, gevent->y, gevent->width, gevent->height);
- ! if (gevent->count == 0)
- ! return; /* This was the last expose event */
- ! }
- ! gdk_flush();
- ! }
- }
-
- + /*
- + * Delete the given number of lines from the given row, scrolling up any
- + * text further down within the scroll region.
- + */
- void
- ! gui_mch_delete_lines(int row, int num_lines)
- {
- ! if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
- ! return; /* Can't see the window */
-
- + if (num_lines <= 0)
- + return;
-
- ! if (row + num_lines > gui.scroll_region_bot) {
- ! /* Scrolled out of region, just blank the lines out */
- ! gui_clear_block(row, 0, gui.scroll_region_bot, (int) Columns - 1);
- ! } else {
- ! GdkGC *gc;
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_gc_set_background(gc, gui.bgcolor);
-
- ! /* copy one extra pixel, for when bold has spilled over */
- ! gdk_window_copy_area(gui.drawarea->window, gc,
- ! FILL_X(0), FILL_Y(row),
- ! gui.drawarea->window,
- ! FILL_X(0), FILL_Y(row + num_lines),
- ! gui.char_width * (int) Columns + 1,
- ! gui.char_height *
- ! (gui.scroll_region_bot - row - num_lines + 1));
- ! gdk_gc_destroy(gc);
-
- ! /* Update gui.cursor_row if the cursor scrolled or copied over */
- ! if (gui.cursor_row >= row) {
- ! if (gui.cursor_row < row + num_lines)
- ! gui.cursor_is_valid = FALSE;
- ! else if (gui.cursor_row <= gui.scroll_region_bot)
- ! gui.cursor_row -= num_lines;
- ! }
- ! gui_clear_block(gui.scroll_region_bot - num_lines + 1, 0,
- ! gui.scroll_region_bot, (int) Columns - 1);
- ! check_copy_area();
- ! }
- }
-
- /*
- ! * Insert the given number of lines before the given row, scrolling down any
- ! * following text within the scroll region.
- */
- ! void
- ! gui_mch_insert_lines(int row, int num_lines)
- {
- ! if (gui.visibility == GDK_VISIBILITY_FULLY_OBSCURED)
- ! return; /* Can't see the window */
-
- ! if (num_lines <= 0)
- ! return;
-
- ! if (row + num_lines > gui.scroll_region_bot) {
- ! /* Scrolled out of region, just blank the lines out */
- ! gui_clear_block(row, 0, gui.scroll_region_bot, (int) Columns - 1);
- ! } else {
- ! GdkGC *gc;
-
- ! gc = gdk_gc_new(gui.drawarea->window);
- ! gdk_gc_set_exposures(gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
- ! gdk_gc_set_foreground(gc, gui.fgcolor);
- ! gdk_gc_set_background(gc, gui.bgcolor);
-
- + /* copy one extra pixel, for when bold has spilled over */
- + gdk_window_copy_area(gui.drawarea->window, gc,
- + FILL_X(0), FILL_Y(row + num_lines),
- + gui.drawarea->window,
- + FILL_X(0), FILL_Y(row),
- + gui.char_width * (int) Columns + 1,
- + gui.char_height *
- + (gui.scroll_region_bot - row - num_lines + 1));
- + gdk_gc_destroy(gc);
-
- ! /* Update gui.cursor_row if the cursor scrolled or copied over */
- ! if (gui.cursor_row >= gui.row) {
- ! if (gui.cursor_row <= gui.scroll_region_bot - num_lines)
- ! gui.cursor_row += num_lines;
- ! else if (gui.cursor_row <= gui.scroll_region_bot)
- ! gui.cursor_is_valid = FALSE;
- ! }
- ! gui_clear_block(row, 0, row + num_lines - 1, (int) Columns - 1);
- ! check_copy_area();
- }
- + }
-
- ! /*
- ! * X Selection stuff, for cutting and pasting text to other windows.
- ! */
- ! void
- ! clip_mch_request_selection()
- ! {
- ! /* First try to get the content of our own special clipboard. */
- ! received_selection = RS_NONE;
- ! (void)gtk_selection_convert(gui.drawarea,
- ! GDK_SELECTION_PRIMARY, clipboard.atom,
- ! (guint32)GDK_CURRENT_TIME);
- ! while (received_selection == RS_NONE)
- ! gtk_main(); /* wait for selection_received_event */
-
- ! if (received_selection == RS_FAIL)
- {
- ! /* Now try to get it out of the usual string selection. */
- ! received_selection = RS_NONE;
- ! (void)gtk_selection_convert(gui.drawarea, GDK_SELECTION_PRIMARY,
- ! GDK_TARGET_STRING,
- ! (guint32)GDK_CURRENT_TIME);
- ! while (received_selection == RS_NONE)
- ! gtk_main(); /* wait for selection_received_event */
- }
- + }
-
- ! void
- ! clip_mch_lose_selection()
- ! {
- ! gtk_selection_owner_set(gui.drawarea,
- ! GDK_SELECTION_PRIMARY, (guint32)GDK_CURRENT_TIME);
- ! gui_mch_update();
- ! }
-
- ! /*
- ! * Check whatever we allready own the selection.
- ! */
- ! int
- ! clip_mch_own_selection()
- ! {
- ! #if 0
- ! return gdk_selection_owner_get(
- ! GDK_SELECTION_PRIMARY) == gui.drawarea->window;
- ! #else
- ! /* At this point we always already own the clipboard */
-
- ! return OK;
- ! #endif
- }
-
- /*
- ! * Send the current selection to the clipboard.
- */
- ! void
- ! clip_mch_set_selection()
- {
- ! gtk_selection_owner_set(gui.drawarea,
- ! GDK_SELECTION_PRIMARY,
- ! (guint32)GDK_CURRENT_TIME);
- ! gui_mch_update();
- ! }
-
-
- ! #if defined(WANT_MENU) || defined(PROTO)
- ! /*
- ! * Make a menu item appear either active or not active (grey or not grey).
- ! */
- ! void
- ! gui_mch_menu_grey(VimMenu * menu, int grey)
- ! {
- ! if (menu->id == 0)
- ! return;
-
- ! gui_mch_menu_hidden(menu, FALSE);
- ! gtk_widget_set_sensitive(menu->id, !grey);
-
- ! gui_mch_update();
- }
-
- ! /*
- ! * Make menu item hidden or not hidden.
- ! */
- ! void
- ! gui_mch_menu_hidden(VimMenu * menu, int hidden)
- {
- ! if (menu->id == 0)
- ! return;
-
- ! if (hidden) {
- ! if (GTK_WIDGET_VISIBLE(menu->id))
- ! gtk_widget_hide(menu->id);
- ! } else {
- ! if (!GTK_WIDGET_VISIBLE(menu->id))
- ! gtk_widget_show(menu->id);
- }
-
- ! gui_mch_update();
- }
-
- ! /*
- ! * This is called after setting all the menus to grey/hidden or not.
- ! */
- ! void
- ! gui_mch_draw_menubar()
- {
- ! /* just make sure that the visual changes get effect immediately */
- ! gui_mch_update();
- }
- + #endif
-
- /*
- ! * Scrollbar stuff.
- */
- ! void
- ! gui_mch_enable_scrollbar(GuiScrollbar * sb, int flag)
- {
- ! if (sb->id == 0)
- ! return;
- ! if (flag)
- ! gtk_widget_show(sb->id);
- ! else
- ! gtk_widget_hide(sb->id);
- ! update_window_manager_hints();
- }
-
- +
- /*
- ! * Return the lightness of a pixel. White is 255.
- */
- ! int
- ! gui_mch_get_lightness(GuiColor pixel)
- {
- ! XColor xc;
- ! GdkColormap *colormap;
- !
- ! colormap = gtk_widget_get_colormap(gui.mainwin);
- ! xc.pixel = pixel;
- !
- ! /* FIXME: this is crap in terms of actual accuracy */
- ! XQueryColor(GDK_DISPLAY(), GDK_COLORMAP_XCOLORMAP(colormap), &xc);
- !
- ! return (int) (xc.red * 3 + xc.green * 6 + xc.blue) / (10 * 256);
- }
-
- ! #if (defined(SYNTAX_HL) && defined(WANT_EVAL)) || defined(PROTO)
- !
- /*
- ! * Return the RGB value of a pixel as "#RRGGBB".
- ! *
- ! * Unfortunately there appears to be no way to accomplish this entierly
- ! * without resorting to native X11 functions.
- */
- ! char_u *
- ! gui_mch_get_rgb(GuiColor pixel)
- {
- ! XColor xc;
- ! GdkColormap *colormap;
- ! static char_u retval[10];
-
- ! colormap = gtk_widget_get_colormap(gui.mainwin);
-
- ! xc.pixel = pixel;
- ! XQueryColor(GDK_DISPLAY(), GDK_COLORMAP_XCOLORMAP(colormap), &xc);
- !
- ! sprintf((char *) retval, "#%02x%02x%02x",
- ! (unsigned) xc.red >> 8,
- ! (unsigned) xc.green >> 8,
- ! (unsigned) xc.blue >> 8);
- !
- ! /* WOAH!!! Returning pointer to static string! Could be overwritten when
- ! * this function is called recursively (e.g., when some event occurs). */
- ! return retval;
- }
- + #endif
-
- ! /*
- ! * Get current y mouse coordinate in text window.
- ! * Return -1 when unknown.
- ! */
- ! int
- ! gui_mch_get_mouse_x(void)
- {
- ! int winx, winy;
- ! GdkModifierType mask;
-
- ! gdk_window_get_pointer(gui.drawarea->window, &winx, &winy, &mask);
- ! return winx;
- }
-
- ! int
- ! gui_mch_get_mouse_y(void)
- {
- ! int winx, winy;
- ! GdkModifierType mask;
-
- ! gdk_window_get_pointer(gui.drawarea->window, &winx, &winy, &mask);
- ! return winy;
- ! }
- !
- ! void
- ! gui_mch_setmouse(int x, int y)
- ! {
- ! /* Sorry for the Xlib call, but we can't avoid it, since there is no
- ! * internal GDK mechanism present to accomplish this.
- ! */
- ! XWarpPointer(GDK_DISPLAY(), (Window) 0,
- ! GDK_WINDOW_XWINDOW(gui.drawarea->window), 0, 0, 0, 0, x, y);
- }
- *** ../vim-5.6a.17/src/ui.c Mon Dec 20 09:59:15 1999
- --- src/ui.c Sat Jan 8 20:56:28 2000
- ***************
- *** 1156,1161 ****
- --- 1156,1169 ----
- }
- #endif
-
- + #if defined(USE_GUI_GTK) || defined(PROTO)
- + int
- + vim_used_in_input_buf()
- + {
- + return inbufcount;
- + }
- + #endif
- +
- /* Add the given bytes to the input buffer */
- void
- add_to_input_buf(s, len)
- *** ../vim-5.6a.17/src/proto/ui.pro Mon Dec 20 09:58:55 1999
- --- src/proto/ui.pro Sat Jan 8 20:56:32 2000
- ***************
- *** 30,35 ****
- --- 30,36 ----
- int vim_is_input_buf_full __ARGS((void));
- int vim_is_input_buf_empty __ARGS((void));
- int vim_free_in_input_buf __ARGS((void));
- + int vim_used_in_input_buf __ARGS((void));
- void add_to_input_buf __ARGS((char_u *s, int len));
- void push_raw_key __ARGS((char_u *s, int len));
- void trash_input_buf __ARGS((void));
- *** ../vim-5.6a.17/src/misc2.c Thu Dec 23 11:13:43 1999
- --- src/misc2.c Sat Jan 8 21:27:11 2000
- ***************
- *** 2031,2037 ****
- return State;
- }
-
- ! #if defined(MKSESSION) || defined(MSWIN) || defined(PROTO)
- /*
- * Change to a file's directory.
- */
- --- 2031,2037 ----
- return State;
- }
-
- ! #if defined(MKSESSION) || defined(MSWIN) || defined(USE_GUI_GTK) || defined(PROTO)
- /*
- * Change to a file's directory.
- */
- *** ../vim-5.6a.17/src/version.c Sat Jan 8 22:58:58 2000
- --- src/version.c Sat Jan 8 22:58:33 2000
- ***************
- *** 420,421 ****
- --- 420,423 ----
- { /* Add new patch number below this line */
- + /**/
- + 18,
- /**/
-
- --
- hundred-and-one symptoms of being an internet addict:
- 79. All of your most erotic dreams have a scrollbar at the right side.
-
- --/-/---- Bram Moolenaar ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\--
- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /
-