comparison src/xterm.c @ 53069:1218a42792ea

Implement multiple display handling for GTK.
author Jan Djärv <jan.h.d@swipnet.se>
date Sun, 16 Nov 2003 16:05:24 +0000
parents 4835b200fafe
children bf86de5f6d07
comparison
equal deleted inserted replaced
53068:6c9f84d07fa3 53069:1218a42792ea
355 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); 355 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
356 static void x_flush P_ ((struct frame *f)); 356 static void x_flush P_ ((struct frame *f));
357 static void x_update_begin P_ ((struct frame *)); 357 static void x_update_begin P_ ((struct frame *));
358 static void x_update_window_begin P_ ((struct window *)); 358 static void x_update_window_begin P_ ((struct window *));
359 static void x_after_update_window_line P_ ((struct glyph_row *)); 359 static void x_after_update_window_line P_ ((struct glyph_row *));
360 static struct scroll_bar *x_window_to_scroll_bar P_ ((Window)); 360 static struct scroll_bar *x_window_to_scroll_bar P_ ((Display *, Window));
361 static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, 361 static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
362 enum scroll_bar_part *, 362 enum scroll_bar_part *,
363 Lisp_Object *, Lisp_Object *, 363 Lisp_Object *, Lisp_Object *,
364 unsigned long *)); 364 unsigned long *));
365 static void x_check_fullscreen P_ ((struct frame *)); 365 static void x_check_fullscreen P_ ((struct frame *));
3775 x_uncatch_errors (FRAME_X_DISPLAY (*fp), count); 3775 x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
3776 3776
3777 /* If not, is it one of our scroll bars? */ 3777 /* If not, is it one of our scroll bars? */
3778 if (! f1) 3778 if (! f1)
3779 { 3779 {
3780 struct scroll_bar *bar = x_window_to_scroll_bar (win); 3780 struct scroll_bar *bar;
3781
3782 bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win);
3781 3783
3782 if (bar) 3784 if (bar)
3783 { 3785 {
3784 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 3786 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3785 win_x = parent_x; 3787 win_x = parent_x;
3846 Scroll bars 3848 Scroll bars
3847 ***********************************************************************/ 3849 ***********************************************************************/
3848 3850
3849 /* Scroll bar support. */ 3851 /* Scroll bar support. */
3850 3852
3851 /* Given an X window ID, find the struct scroll_bar which manages it. 3853 /* Given an X window ID and a DISPLAY, find the struct scroll_bar which
3854 manages it.
3852 This can be called in GC, so we have to make sure to strip off mark 3855 This can be called in GC, so we have to make sure to strip off mark
3853 bits. */ 3856 bits. */
3854 3857
3855 static struct scroll_bar * 3858 static struct scroll_bar *
3856 x_window_to_scroll_bar (window_id) 3859 x_window_to_scroll_bar (display, window_id)
3860 Display *display;
3857 Window window_id; 3861 Window window_id;
3858 { 3862 {
3859 Lisp_Object tail; 3863 Lisp_Object tail;
3860 3864
3861 #ifdef USE_GTK 3865 #ifdef USE_GTK
3862 window_id = (Window) xg_get_scroll_id_for_window (window_id); 3866 window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
3863 #endif /* USE_GTK */ 3867 #endif /* USE_GTK */
3864 3868
3865 for (tail = Vframe_list; 3869 for (tail = Vframe_list;
3866 XGCTYPE (tail) == Lisp_Cons; 3870 XGCTYPE (tail) == Lisp_Cons;
3867 tail = XCDR (tail)) 3871 tail = XCDR (tail))
3870 3874
3871 frame = XCAR (tail); 3875 frame = XCAR (tail);
3872 /* All elements of Vframe_list should be frames. */ 3876 /* All elements of Vframe_list should be frames. */
3873 if (! GC_FRAMEP (frame)) 3877 if (! GC_FRAMEP (frame))
3874 abort (); 3878 abort ();
3879
3880 if (FRAME_X_DISPLAY (XFRAME (frame)) != display)
3881 continue;
3875 3882
3876 /* Scan this frame's scroll bar list for a scroll bar with the 3883 /* Scan this frame's scroll bar list for a scroll bar with the
3877 right window ID. */ 3884 right window ID. */
3878 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame)); 3885 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
3879 for (bar = FRAME_SCROLL_BARS (XFRAME (frame)); 3886 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
5667 return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None); 5674 return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
5668 } 5675 }
5669 #endif 5676 #endif
5670 5677
5671 #ifdef USE_GTK 5678 #ifdef USE_GTK
5672 static struct x_display_info *current_dpyinfo;
5673 static struct input_event **current_bufp; 5679 static struct input_event **current_bufp;
5674 static int *current_numcharsp; 5680 static int *current_numcharsp;
5675 static int current_count; 5681 static int current_count;
5676 static int current_finish; 5682 static int current_finish;
5677 5683
5682 event_handler_gdk (gxev, ev, data) 5688 event_handler_gdk (gxev, ev, data)
5683 GdkXEvent *gxev; 5689 GdkXEvent *gxev;
5684 GdkEvent *ev; 5690 GdkEvent *ev;
5685 gpointer data; 5691 gpointer data;
5686 { 5692 {
5687 XEvent *xev = (XEvent*)gxev; 5693 XEvent *xev = (XEvent *) gxev;
5688 5694
5689 if (current_numcharsp) 5695 if (current_numcharsp)
5690 { 5696 {
5697 struct x_display_info *dpyinfo;
5698
5699 dpyinfo = x_display_info_for_display (xev->xany.display);
5700
5691 #ifdef HAVE_X_I18N 5701 #ifdef HAVE_X_I18N
5692 /* Filter events for the current X input method. 5702 /* Filter events for the current X input method.
5693 GTK calls XFilterEvent but not for key press and release, 5703 GTK calls XFilterEvent but not for key press and release,
5694 so we do it here. */ 5704 so we do it here. */
5695 if (xev->type == KeyPress || xev->type == KeyRelease) 5705 if (xev->type == KeyPress || xev->type == KeyRelease)
5696 if (x_filter_event (current_dpyinfo, xev)) 5706 if (dpyinfo && x_filter_event (dpyinfo, xev))
5697 return GDK_FILTER_REMOVE; 5707 return GDK_FILTER_REMOVE;
5698 #endif 5708 #endif
5699 current_count += handle_one_xevent (current_dpyinfo, 5709
5700 xev, 5710 if (! dpyinfo)
5701 current_bufp, 5711 current_finish = X_EVENT_NORMAL;
5702 current_numcharsp, 5712 else
5703 &current_finish); 5713 current_count += handle_one_xevent (dpyinfo,
5714 xev,
5715 current_bufp,
5716 current_numcharsp,
5717 &current_finish);
5704 } 5718 }
5705 else 5719 else
5706 current_finish = x_dispatch_event (xev, GDK_DISPLAY ()); 5720 current_finish = x_dispatch_event (xev, xev->xany.display);
5707 5721
5708 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP) 5722 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
5709 return GDK_FILTER_REMOVE; 5723 return GDK_FILTER_REMOVE;
5710 5724
5711 return GDK_FILTER_CONTINUE; 5725 return GDK_FILTER_CONTINUE;
6041 6055
6042 #ifdef USE_TOOLKIT_SCROLL_BARS 6056 #ifdef USE_TOOLKIT_SCROLL_BARS
6043 /* Dispatch event to the widget. */ 6057 /* Dispatch event to the widget. */
6044 goto OTHER; 6058 goto OTHER;
6045 #else /* not USE_TOOLKIT_SCROLL_BARS */ 6059 #else /* not USE_TOOLKIT_SCROLL_BARS */
6046 bar = x_window_to_scroll_bar (event.xexpose.window); 6060 bar = x_window_to_scroll_bar (event.xexpose.display,
6061 event.xexpose.window);
6047 6062
6048 if (bar) 6063 if (bar)
6049 x_scroll_bar_expose (bar, &event); 6064 x_scroll_bar_expose (bar, &event);
6050 #ifdef USE_X_TOOLKIT 6065 #ifdef USE_X_TOOLKIT
6051 else 6066 else
6667 0, 0, 0, 0); 6682 0, 0, 0, 0);
6668 6683
6669 /* Window will be selected only when it is not selected now and 6684 /* Window will be selected only when it is not selected now and
6670 last mouse movement event was not in it. Minibuffer window 6685 last mouse movement event was not in it. Minibuffer window
6671 will be selected iff it is active. */ 6686 will be selected iff it is active. */
6672 if (WINDOWP(window) 6687 if (WINDOWP (window)
6673 && !EQ (window, last_window) 6688 && !EQ (window, last_window)
6674 && !EQ (window, selected_window) 6689 && !EQ (window, selected_window)
6675 && numchars > 0) 6690 && numchars > 0)
6676 { 6691 {
6677 bufp->kind = SELECT_WINDOW_EVENT; 6692 bufp->kind = SELECT_WINDOW_EVENT;
6686 } 6701 }
6687 else 6702 else
6688 { 6703 {
6689 #ifndef USE_TOOLKIT_SCROLL_BARS 6704 #ifndef USE_TOOLKIT_SCROLL_BARS
6690 struct scroll_bar *bar 6705 struct scroll_bar *bar
6691 = x_window_to_scroll_bar (event.xmotion.window); 6706 = x_window_to_scroll_bar (event.xmotion.display,
6707 event.xmotion.window);
6692 6708
6693 if (bar) 6709 if (bar)
6694 x_scroll_bar_note_movement (bar, &event); 6710 x_scroll_bar_note_movement (bar, &event);
6695 #endif /* USE_TOOLKIT_SCROLL_BARS */ 6711 #endif /* USE_TOOLKIT_SCROLL_BARS */
6696 6712
6849 } 6865 }
6850 } 6866 }
6851 else 6867 else
6852 { 6868 {
6853 struct scroll_bar *bar 6869 struct scroll_bar *bar
6854 = x_window_to_scroll_bar (event.xbutton.window); 6870 = x_window_to_scroll_bar (event.xbutton.display,
6871 event.xbutton.window);
6855 6872
6856 #ifdef USE_TOOLKIT_SCROLL_BARS 6873 #ifdef USE_TOOLKIT_SCROLL_BARS
6857 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit 6874 /* Make the "Ctrl-Mouse-2 splits window" work for toolkit
6858 scroll bars. */ 6875 scroll bars. */
6859 if (bar && event.xbutton.state & ControlMask) 6876 if (bar && event.xbutton.state & ControlMask)
7010 7027
7011 for (bufpp = bufp; bufpp != bufp + 10; bufpp++) 7028 for (bufpp = bufp; bufpp != bufp + 10; bufpp++)
7012 EVENT_INIT (*bufpp); 7029 EVENT_INIT (*bufpp);
7013 bufpp = bufp; 7030 bufpp = bufp;
7014 7031
7015 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) 7032 dpyinfo = x_display_info_for_display (display);
7016 if (dpyinfo->display == display)
7017 break;
7018 7033
7019 if (dpyinfo) 7034 if (dpyinfo)
7020 { 7035 {
7021 int i, events; 7036 int i, events;
7022 events = handle_one_xevent (dpyinfo, 7037 events = handle_one_xevent (dpyinfo,
7114 BLOCK_INPUT; 7129 BLOCK_INPUT;
7115 count += x_session_check_input (bufp, &numchars); 7130 count += x_session_check_input (bufp, &numchars);
7116 UNBLOCK_INPUT; 7131 UNBLOCK_INPUT;
7117 #endif 7132 #endif
7118 7133
7119 #ifdef USE_GTK 7134 #ifndef USE_GTK
7120 /* For GTK we must use the GTK event loop. But XEvents gets passed
7121 to our filter function above, and then to the big event switch.
7122 We use a bunch of globals to communicate with our filter function,
7123 that is kind of ugly, but it works. */
7124 current_dpyinfo = dpyinfo;
7125
7126 while (gtk_events_pending ())
7127 {
7128 current_count = count;
7129 current_numcharsp = &numchars;
7130 current_bufp = &bufp;
7131
7132 gtk_main_iteration ();
7133
7134 count = current_count;
7135 current_bufp = 0;
7136 current_numcharsp = 0;
7137
7138 if (current_finish == X_EVENT_GOTO_OUT)
7139 goto out;
7140 }
7141
7142 #else /* not USE_GTK */
7143 while (XPending (dpyinfo->display)) 7135 while (XPending (dpyinfo->display))
7144 { 7136 {
7145 int finish; 7137 int finish;
7146 7138
7147 XNextEvent (dpyinfo->display, &event); 7139 XNextEvent (dpyinfo->display, &event);
7160 &finish); 7152 &finish);
7161 7153
7162 if (finish == X_EVENT_GOTO_OUT) 7154 if (finish == X_EVENT_GOTO_OUT)
7163 goto out; 7155 goto out;
7164 } 7156 }
7157 #endif /* not USE_GTK */
7158 }
7159
7160 #ifdef USE_GTK
7161
7162 /* For GTK we must use the GTK event loop. But XEvents gets passed
7163 to our filter function above, and then to the big event switch.
7164 We use a bunch of globals to communicate with our filter function,
7165 that is kind of ugly, but it works.
7166
7167 There is no way to do one display at the time, GTK just does events
7168 from all displays. */
7169
7170 while (gtk_events_pending ())
7171 {
7172 current_count = count;
7173 current_numcharsp = &numchars;
7174 current_bufp = &bufp;
7175
7176 gtk_main_iteration ();
7177
7178 count = current_count;
7179 current_bufp = 0;
7180 current_numcharsp = 0;
7181
7182 if (current_finish == X_EVENT_GOTO_OUT)
7183 break;
7184 }
7165 #endif /* USE_GTK */ 7185 #endif /* USE_GTK */
7166 }
7167 7186
7168 out:; 7187 out:;
7169 7188
7170 /* On some systems, an X bug causes Emacs to get no more events 7189 /* On some systems, an X bug causes Emacs to get no more events
7171 when the window is destroyed. Detect that. (1994.) */ 7190 when the window is destroyed. Detect that. (1994.) */
7480 f->output_data.x->icon_bitmap = 0; 7499 f->output_data.x->icon_bitmap = 0;
7481 7500
7482 if (STRINGP (file)) 7501 if (STRINGP (file))
7483 { 7502 {
7484 #ifdef USE_GTK 7503 #ifdef USE_GTK
7485 /* Use gtk_window_set_icon_from_file() if available, 7504 /* Use gtk_window_set_icon_from_file () if available,
7486 It's not restricted to bitmaps */ 7505 It's not restricted to bitmaps */
7487 if (xg_set_icon(f, file)) 7506 if (xg_set_icon (f, file))
7488 return 0; 7507 return 0;
7489 #endif /* USE_GTK */ 7508 #endif /* USE_GTK */
7490 bitmap_id = x_create_bitmap_from_file (f, file); 7509 bitmap_id = x_create_bitmap_from_file (f, file);
7491 x_create_bitmap_mask(f, bitmap_id); 7510 x_create_bitmap_mask (f, bitmap_id);
7492 } 7511 }
7493 else 7512 else
7494 { 7513 {
7495 /* Create the GNU bitmap and mask if necessary. */ 7514 /* Create the GNU bitmap and mask if necessary. */
7496 if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0) 7515 if (FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id < 0)
7497 { 7516 {
7498 FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id 7517 FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id
7499 = x_create_bitmap_from_data (f, gnu_bits, 7518 = x_create_bitmap_from_data (f, gnu_bits,
7500 gnu_width, gnu_height); 7519 gnu_width, gnu_height);
7501 x_create_bitmap_mask(f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id); 7520 x_create_bitmap_mask (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
7502 } 7521 }
7503 7522
7504 /* The first time we create the GNU bitmap and mask, 7523 /* The first time we create the GNU bitmap and mask,
7505 this increments the ref-count one extra time. 7524 this increments the ref-count one extra time.
7506 As a result, the GNU bitmap and mask are never freed. 7525 As a result, the GNU bitmap and mask are never freed.
7763 extern void (*fatal_error_signal_hook) P_ ((void)); 7782 extern void (*fatal_error_signal_hook) P_ ((void));
7764 fatal_error_signal_hook = x_fatal_error_signal; 7783 fatal_error_signal_hook = x_fatal_error_signal;
7765 XtCloseDisplay (dpy); 7784 XtCloseDisplay (dpy);
7766 fatal_error_signal_hook = NULL; 7785 fatal_error_signal_hook = NULL;
7767 } 7786 }
7787 #endif
7788
7789 #ifdef USE_GTK
7790 if (dpyinfo)
7791 xg_display_close (dpyinfo->display);
7768 #endif 7792 #endif
7769 7793
7770 /* Indicate that this display is dead. */ 7794 /* Indicate that this display is dead. */
7771 if (dpyinfo) 7795 if (dpyinfo)
7772 dpyinfo->display = 0; 7796 dpyinfo->display = 0;
10209 int argc; 10233 int argc;
10210 char *argv[NUM_ARGV]; 10234 char *argv[NUM_ARGV];
10211 char **argv2 = argv; 10235 char **argv2 = argv;
10212 GdkAtom atom; 10236 GdkAtom atom;
10213 10237
10214 /* GTK 2.0 can only handle one display, GTK 2.2 can handle more 10238 if (x_initialized++ > 1)
10215 than one, but this remains to be implemented. */
10216 if (x_initialized > 1)
10217 error ("Sorry, the GTK port can only handle one display.");
10218 ++x_initialized;
10219
10220 for (argc = 0; argc < NUM_ARGV; ++argc)
10221 argv[argc] = 0;
10222
10223 argc = 0;
10224 argv[argc++] = initial_argv[0];
10225
10226 if (! NILP (display_name))
10227 { 10239 {
10228 argv[argc++] = "--display"; 10240 /* Opening another display. If xg_display_open returns less
10229 argv[argc++] = SDATA (display_name); 10241 than zero, we are probably on GTK 2.0, which can only handle
10242 one display. GTK 2.2 or later can handle more than one. */
10243 if (xg_display_open (SDATA (display_name), &dpy) < 0)
10244 error ("Sorry, this version of GTK can only handle one display");
10245 }
10246 else
10247 {
10248 for (argc = 0; argc < NUM_ARGV; ++argc)
10249 argv[argc] = 0;
10250
10251 argc = 0;
10252 argv[argc++] = initial_argv[0];
10253
10254 if (! NILP (display_name))
10255 {
10256 argv[argc++] = "--display";
10257 argv[argc++] = SDATA (display_name);
10258 }
10259
10260 argv[argc++] = "--name";
10261 argv[argc++] = resource_name;
10262
10263 #ifdef HAVE_X11R5
10264 XSetLocaleModifiers ("");
10265 #endif
10266
10267 gtk_init (&argc, &argv2);
10268
10269 /* gtk_init does set_locale. We must fix locale after calling it. */
10270 fixup_locale ();
10271 xg_initialize ();
10272
10273 dpy = GDK_DISPLAY ();
10274
10275 /* NULL window -> events for all windows go to our function */
10276 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
10277
10278 /* Load our own gtkrc if it exists. */
10279 {
10280 struct gcpro gcpro1, gcpro2;
10281 char *file = "~/.emacs.d/gtkrc";
10282 Lisp_Object s, abs_file;
10283
10284 GCPRO2 (s, abs_file);
10285 s = make_string (file, strlen (file));
10286 abs_file = Fexpand_file_name (s, Qnil);
10287
10288 if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
10289 gtk_rc_parse (SDATA (abs_file));
10290
10291 UNGCPRO;
10292 }
10293
10294 XSetErrorHandler (x_error_handler);
10295 XSetIOErrorHandler (x_io_error_quitter);
10230 } 10296 }
10231
10232 argv[argc++] = "--name";
10233 argv[argc++] = resource_name;
10234
10235 #ifdef HAVE_X11R5
10236 XSetLocaleModifiers ("");
10237 #endif
10238
10239 gtk_init (&argc, &argv2);
10240
10241 /* gtk_init does set_locale. We must fix locale after calling it. */
10242 fixup_locale ();
10243 xg_initialize ();
10244
10245 dpy = GDK_DISPLAY ();
10246
10247 /* NULL window -> events for all windows go to our function */
10248 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
10249
10250 /* Load our own gtkrc if it exists. */
10251 {
10252 struct gcpro gcpro1, gcpro2;
10253 char *file = "~/.emacs.d/gtkrc";
10254 Lisp_Object s, abs_file;
10255
10256 GCPRO2 (s, abs_file);
10257 s = make_string (file, strlen (file));
10258 abs_file = Fexpand_file_name(s, Qnil);
10259
10260 if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
10261 gtk_rc_parse (SDATA (abs_file));
10262
10263 UNGCPRO;
10264 }
10265
10266 XSetErrorHandler (x_error_handler);
10267 XSetIOErrorHandler (x_io_error_quitter);
10268 } 10297 }
10269 #else /* not USE_GTK */ 10298 #else /* not USE_GTK */
10270 #ifdef USE_X_TOOLKIT 10299 #ifdef USE_X_TOOLKIT
10271 /* weiner@footloose.sps.mot.com reports that this causes 10300 /* weiner@footloose.sps.mot.com reports that this causes
10272 errors with X11R5: 10301 errors with X11R5:
10383 10412
10384 /* Figure out which modifier bits mean what. */ 10413 /* Figure out which modifier bits mean what. */
10385 x_find_modifier_meanings (dpyinfo); 10414 x_find_modifier_meanings (dpyinfo);
10386 10415
10387 /* Get the scroll bar cursor. */ 10416 /* Get the scroll bar cursor. */
10417 #ifdef USE_GTK
10418 /* We must create a GTK cursor, it is required for GTK widgets. */
10419 dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
10420 #endif /* USE_GTK */
10421
10388 dpyinfo->vertical_scroll_bar_cursor 10422 dpyinfo->vertical_scroll_bar_cursor
10389 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow); 10423 = XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
10390 10424
10391 xrdb = x_load_resources (dpyinfo->display, xrm_option, 10425 xrdb = x_load_resources (dpyinfo->display, xrm_option,
10392 resource_name, EMACS_CLASS); 10426 resource_name, EMACS_CLASS);