diff options
author | Jan Djärv <jan.h.d@swipnet.se> | 2003-11-16 16:05:24 +0000 |
---|---|---|
committer | Jan Djärv <jan.h.d@swipnet.se> | 2003-11-16 16:05:24 +0000 |
commit | 810f2256ba03de93679ae73c02512f0da0fd1c7b (patch) | |
tree | 7d140900a63b082cbfb00d296c3b5eb30e398080 /src/xterm.c | |
parent | 0bdd0f79978c5f7e6a94cde0e5fc94040de3ca66 (diff) | |
download | emacs-810f2256ba03de93679ae73c02512f0da0fd1c7b.tar.gz |
Implement multiple display handling for GTK.
Diffstat (limited to 'src/xterm.c')
-rw-r--r-- | src/xterm.c | 212 |
1 files changed, 123 insertions, 89 deletions
diff --git a/src/xterm.c b/src/xterm.c index 85beb00eb52..a5f6c959cec 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -357,7 +357,7 @@ static void x_flush P_ ((struct frame *f)); static void x_update_begin P_ ((struct frame *)); static void x_update_window_begin P_ ((struct window *)); static void x_after_update_window_line P_ ((struct glyph_row *)); -static struct scroll_bar *x_window_to_scroll_bar P_ ((Window)); +static struct scroll_bar *x_window_to_scroll_bar P_ ((Display *, Window)); static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, @@ -3777,7 +3777,9 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) /* If not, is it one of our scroll bars? */ if (! f1) { - struct scroll_bar *bar = x_window_to_scroll_bar (win); + struct scroll_bar *bar; + + bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win); if (bar) { @@ -3848,18 +3850,20 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) /* Scroll bar support. */ -/* Given an X window ID, find the struct scroll_bar which manages it. +/* Given an X window ID and a DISPLAY, find the struct scroll_bar which + manages it. This can be called in GC, so we have to make sure to strip off mark bits. */ static struct scroll_bar * -x_window_to_scroll_bar (window_id) +x_window_to_scroll_bar (display, window_id) + Display *display; Window window_id; { Lisp_Object tail; #ifdef USE_GTK - window_id = (Window) xg_get_scroll_id_for_window (window_id); + window_id = (Window) xg_get_scroll_id_for_window (display, window_id); #endif /* USE_GTK */ for (tail = Vframe_list; @@ -3873,6 +3877,9 @@ x_window_to_scroll_bar (window_id) if (! GC_FRAMEP (frame)) abort (); + if (FRAME_X_DISPLAY (XFRAME (frame)) != display) + continue; + /* Scan this frame's scroll bar list for a scroll bar with the right window ID. */ condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame)); @@ -5669,7 +5676,6 @@ x_filter_event (dpyinfo, event) #endif #ifdef USE_GTK -static struct x_display_info *current_dpyinfo; static struct input_event **current_bufp; static int *current_numcharsp; static int current_count; @@ -5684,26 +5690,34 @@ event_handler_gdk (gxev, ev, data) GdkEvent *ev; gpointer data; { - XEvent *xev = (XEvent*)gxev; + XEvent *xev = (XEvent *) gxev; if (current_numcharsp) { + struct x_display_info *dpyinfo; + + dpyinfo = x_display_info_for_display (xev->xany.display); + #ifdef HAVE_X_I18N /* Filter events for the current X input method. GTK calls XFilterEvent but not for key press and release, so we do it here. */ if (xev->type == KeyPress || xev->type == KeyRelease) - if (x_filter_event (current_dpyinfo, xev)) + if (dpyinfo && x_filter_event (dpyinfo, xev)) return GDK_FILTER_REMOVE; #endif - current_count += handle_one_xevent (current_dpyinfo, - xev, - current_bufp, - current_numcharsp, - ¤t_finish); + + if (! dpyinfo) + current_finish = X_EVENT_NORMAL; + else + current_count += handle_one_xevent (dpyinfo, + xev, + current_bufp, + current_numcharsp, + ¤t_finish); } else - current_finish = x_dispatch_event (xev, GDK_DISPLAY ()); + current_finish = x_dispatch_event (xev, xev->xany.display); if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP) return GDK_FILTER_REMOVE; @@ -6043,7 +6057,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) /* Dispatch event to the widget. */ goto OTHER; #else /* not USE_TOOLKIT_SCROLL_BARS */ - bar = x_window_to_scroll_bar (event.xexpose.window); + bar = x_window_to_scroll_bar (event.xexpose.display, + event.xexpose.window); if (bar) x_scroll_bar_expose (bar, &event); @@ -6669,7 +6684,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) /* Window will be selected only when it is not selected now and last mouse movement event was not in it. Minibuffer window will be selected iff it is active. */ - if (WINDOWP(window) + if (WINDOWP (window) && !EQ (window, last_window) && !EQ (window, selected_window) && numchars > 0) @@ -6688,7 +6703,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) { #ifndef USE_TOOLKIT_SCROLL_BARS struct scroll_bar *bar - = x_window_to_scroll_bar (event.xmotion.window); + = x_window_to_scroll_bar (event.xmotion.display, + event.xmotion.window); if (bar) x_scroll_bar_note_movement (bar, &event); @@ -6851,7 +6867,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) else { struct scroll_bar *bar - = x_window_to_scroll_bar (event.xbutton.window); + = x_window_to_scroll_bar (event.xbutton.display, + event.xbutton.window); #ifdef USE_TOOLKIT_SCROLL_BARS /* Make the "Ctrl-Mouse-2 splits window" work for toolkit @@ -7012,9 +7029,7 @@ x_dispatch_event (event, display) EVENT_INIT (*bufpp); bufpp = bufp; - for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) - if (dpyinfo->display == display) - break; + dpyinfo = x_display_info_for_display (display); if (dpyinfo) { @@ -7116,30 +7131,7 @@ XTread_socket (sd, bufp, numchars, expected) UNBLOCK_INPUT; #endif -#ifdef USE_GTK - /* For GTK we must use the GTK event loop. But XEvents gets passed - to our filter function above, and then to the big event switch. - We use a bunch of globals to communicate with our filter function, - that is kind of ugly, but it works. */ - current_dpyinfo = dpyinfo; - - while (gtk_events_pending ()) - { - current_count = count; - current_numcharsp = &numchars; - current_bufp = &bufp; - - gtk_main_iteration (); - - count = current_count; - current_bufp = 0; - current_numcharsp = 0; - - if (current_finish == X_EVENT_GOTO_OUT) - goto out; - } - -#else /* not USE_GTK */ +#ifndef USE_GTK while (XPending (dpyinfo->display)) { int finish; @@ -7162,8 +7154,35 @@ XTread_socket (sd, bufp, numchars, expected) if (finish == X_EVENT_GOTO_OUT) goto out; } -#endif /* USE_GTK */ +#endif /* not USE_GTK */ + } + +#ifdef USE_GTK + + /* For GTK we must use the GTK event loop. But XEvents gets passed + to our filter function above, and then to the big event switch. + We use a bunch of globals to communicate with our filter function, + that is kind of ugly, but it works. + + There is no way to do one display at the time, GTK just does events + from all displays. */ + + while (gtk_events_pending ()) + { + current_count = count; + current_numcharsp = &numchars; + current_bufp = &bufp; + + gtk_main_iteration (); + + count = current_count; + current_bufp = 0; + current_numcharsp = 0; + + if (current_finish == X_EVENT_GOTO_OUT) + break; } +#endif /* USE_GTK */ out:; @@ -7482,13 +7501,13 @@ x_bitmap_icon (f, file) if (STRINGP (file)) { #ifdef USE_GTK - /* Use gtk_window_set_icon_from_file() if available, + /* Use gtk_window_set_icon_from_file () if available, It's not restricted to bitmaps */ - if (xg_set_icon(f, file)) + if (xg_set_icon (f, file)) return 0; #endif /* USE_GTK */ bitmap_id = x_create_bitmap_from_file (f, file); - x_create_bitmap_mask(f, bitmap_id); + x_create_bitmap_mask (f, bitmap_id); } else { @@ -7498,7 +7517,7 @@ x_bitmap_icon (f, file) FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id = x_create_bitmap_from_data (f, gnu_bits, gnu_width, gnu_height); - x_create_bitmap_mask(f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id); + x_create_bitmap_mask (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id); } /* The first time we create the GNU bitmap and mask, @@ -7767,6 +7786,11 @@ x_connection_closed (dpy, error_message) } #endif +#ifdef USE_GTK + if (dpyinfo) + xg_display_close (dpyinfo->display); +#endif + /* Indicate that this display is dead. */ if (dpyinfo) dpyinfo->display = 0; @@ -10211,60 +10235,65 @@ x_term_init (display_name, xrm_option, resource_name) char **argv2 = argv; GdkAtom atom; - /* GTK 2.0 can only handle one display, GTK 2.2 can handle more - than one, but this remains to be implemented. */ - if (x_initialized > 1) - error ("Sorry, the GTK port can only handle one display."); - ++x_initialized; - - for (argc = 0; argc < NUM_ARGV; ++argc) - argv[argc] = 0; + if (x_initialized++ > 1) + { + /* Opening another display. If xg_display_open returns less + than zero, we are probably on GTK 2.0, which can only handle + one display. GTK 2.2 or later can handle more than one. */ + if (xg_display_open (SDATA (display_name), &dpy) < 0) + error ("Sorry, this version of GTK can only handle one display"); + } + else + { + for (argc = 0; argc < NUM_ARGV; ++argc) + argv[argc] = 0; - argc = 0; - argv[argc++] = initial_argv[0]; + argc = 0; + argv[argc++] = initial_argv[0]; - if (! NILP (display_name)) - { - argv[argc++] = "--display"; - argv[argc++] = SDATA (display_name); - } + if (! NILP (display_name)) + { + argv[argc++] = "--display"; + argv[argc++] = SDATA (display_name); + } - argv[argc++] = "--name"; - argv[argc++] = resource_name; + argv[argc++] = "--name"; + argv[argc++] = resource_name; #ifdef HAVE_X11R5 - XSetLocaleModifiers (""); + XSetLocaleModifiers (""); #endif - gtk_init (&argc, &argv2); + gtk_init (&argc, &argv2); - /* gtk_init does set_locale. We must fix locale after calling it. */ - fixup_locale (); - xg_initialize (); + /* gtk_init does set_locale. We must fix locale after calling it. */ + fixup_locale (); + xg_initialize (); - dpy = GDK_DISPLAY (); + dpy = GDK_DISPLAY (); - /* NULL window -> events for all windows go to our function */ - gdk_window_add_filter (NULL, event_handler_gdk, NULL); + /* NULL window -> events for all windows go to our function */ + gdk_window_add_filter (NULL, event_handler_gdk, NULL); - /* Load our own gtkrc if it exists. */ - { - struct gcpro gcpro1, gcpro2; - char *file = "~/.emacs.d/gtkrc"; - Lisp_Object s, abs_file; + /* Load our own gtkrc if it exists. */ + { + struct gcpro gcpro1, gcpro2; + char *file = "~/.emacs.d/gtkrc"; + Lisp_Object s, abs_file; - GCPRO2 (s, abs_file); - s = make_string (file, strlen (file)); - abs_file = Fexpand_file_name(s, Qnil); + GCPRO2 (s, abs_file); + s = make_string (file, strlen (file)); + abs_file = Fexpand_file_name (s, Qnil); - if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file))) - gtk_rc_parse (SDATA (abs_file)); + if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file))) + gtk_rc_parse (SDATA (abs_file)); - UNGCPRO; - } + UNGCPRO; + } - XSetErrorHandler (x_error_handler); - XSetIOErrorHandler (x_io_error_quitter); + XSetErrorHandler (x_error_handler); + XSetIOErrorHandler (x_io_error_quitter); + } } #else /* not USE_GTK */ #ifdef USE_X_TOOLKIT @@ -10385,6 +10414,11 @@ x_term_init (display_name, xrm_option, resource_name) x_find_modifier_meanings (dpyinfo); /* Get the scroll bar cursor. */ +#ifdef USE_GTK + /* We must create a GTK cursor, it is required for GTK widgets. */ + dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display); +#endif /* USE_GTK */ + dpyinfo->vertical_scroll_bar_cursor = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); |