aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c439
1 files changed, 387 insertions, 52 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 220c45e648c..348355d2b5b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -97,17 +97,23 @@ Boston, MA 02111-1307, USA. */
97#include <unistd.h> 97#include <unistd.h>
98#endif 98#endif
99 99
100#ifdef USE_GTK
101#include "gtkutil.h"
102#endif
103
100#ifdef USE_LUCID 104#ifdef USE_LUCID
101extern int xlwmenu_window_p P_ ((Widget w, Window window)); 105extern int xlwmenu_window_p P_ ((Widget w, Window window));
102extern void xlwmenu_redisplay P_ ((Widget)); 106extern void xlwmenu_redisplay P_ ((Widget));
103#endif 107#endif
104 108
105#ifdef USE_X_TOOLKIT 109#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
106 110
107extern void free_frame_menubar P_ ((struct frame *)); 111extern void free_frame_menubar P_ ((struct frame *));
108extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *, 112extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
109 int)); 113 int));
114#endif
110 115
116#ifdef USE_X_TOOLKIT
111#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES) 117#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
112#define HACK_EDITRES 118#define HACK_EDITRES
113extern void _XEditResCheckMessages (); 119extern void _XEditResCheckMessages ();
@@ -138,7 +144,7 @@ extern void _XEditResCheckMessages ();
138 144
139#endif /* USE_X_TOOLKIT */ 145#endif /* USE_X_TOOLKIT */
140 146
141#ifndef USE_X_TOOLKIT 147#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
142#define x_any_window_to_frame x_window_to_frame 148#define x_any_window_to_frame x_window_to_frame
143#define x_top_window_to_frame x_window_to_frame 149#define x_top_window_to_frame x_window_to_frame
144#endif 150#endif
@@ -520,6 +526,12 @@ static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
520 unsigned long *)); 526 unsigned long *));
521static void x_check_fullscreen P_ ((struct frame *)); 527static void x_check_fullscreen P_ ((struct frame *));
522static void x_check_fullscreen_move P_ ((struct frame *)); 528static void x_check_fullscreen_move P_ ((struct frame *));
529static int handle_one_xevent P_ ((struct x_display_info *,
530 XEvent *,
531 struct input_event **,
532 int *,
533 int *));
534
523 535
524/* Flush display of frame F, or of all frames if F is null. */ 536/* Flush display of frame F, or of all frames if F is null. */
525 537
@@ -4330,6 +4342,7 @@ x_draw_image_glyph_string (s)
4330 4342
4331 height = s->height - 2 * box_line_vwidth; 4343 height = s->height - 2 * box_line_vwidth;
4332 4344
4345
4333 /* Fill background with face under the image. Do it only if row is 4346 /* Fill background with face under the image. Do it only if row is
4334 taller than image or if image has a clip mask to reduce 4347 taller than image or if image has a clip mask to reduce
4335 flickering. */ 4348 flickering. */
@@ -7074,7 +7087,7 @@ note_mouse_highlight (f, x, y)
7074 struct buffer *b; 7087 struct buffer *b;
7075 7088
7076 /* When a menu is active, don't highlight because this looks odd. */ 7089 /* When a menu is active, don't highlight because this looks odd. */
7077#ifdef USE_X_TOOLKIT 7090#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
7078 if (popup_activated ()) 7091 if (popup_activated ())
7079 return; 7092 return;
7080#endif 7093#endif
@@ -8399,7 +8412,7 @@ static void
8399x_process_timeouts (timer) 8412x_process_timeouts (timer)
8400 struct atimer *timer; 8413 struct atimer *timer;
8401{ 8414{
8402 if (toolkit_scroll_bar_interaction || popup_activated_flag) 8415 if (toolkit_scroll_bar_interaction || popup_activated ())
8403 { 8416 {
8404 BLOCK_INPUT; 8417 BLOCK_INPUT;
8405 while (XtAppPending (Xt_app_con) & XtIMTimer) 8418 while (XtAppPending (Xt_app_con) & XtIMTimer)
@@ -8494,10 +8507,6 @@ static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *,
8494 int, int, int)); 8507 int, int, int));
8495 8508
8496 8509
8497/* Id of action hook installed for scroll bars. */
8498
8499static XtActionHookId action_hook_id;
8500
8501/* Lisp window being scrolled. Set when starting to interact with 8510/* Lisp window being scrolled. Set when starting to interact with
8502 a toolkit scroll bar, reset to nil when ending the interaction. */ 8511 a toolkit scroll bar, reset to nil when ending the interaction. */
8503 8512
@@ -8510,6 +8519,11 @@ static int last_scroll_bar_part;
8510/* Whether this is an Xaw with arrow-scrollbars. This should imply 8519/* Whether this is an Xaw with arrow-scrollbars. This should imply
8511 that movements of 1/20 of the screen size are mapped to up/down. */ 8520 that movements of 1/20 of the screen size are mapped to up/down. */
8512 8521
8522#ifndef USE_GTK
8523/* Id of action hook installed for scroll bars. */
8524
8525static XtActionHookId action_hook_id;
8526
8513static Boolean xaw3d_arrow_scroll; 8527static Boolean xaw3d_arrow_scroll;
8514 8528
8515/* Whether the drag scrolling maintains the mouse at the top of the 8529/* Whether the drag scrolling maintains the mouse at the top of the
@@ -8562,6 +8576,7 @@ xt_action_hook (widget, client_data, action_name, event, params,
8562 toolkit_scroll_bar_interaction = 0; 8576 toolkit_scroll_bar_interaction = 0;
8563 } 8577 }
8564} 8578}
8579#endif /* not USE_GTK */
8565 8580
8566/* A vector of windows used for communication between 8581/* A vector of windows used for communication between
8567 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */ 8582 x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
@@ -8655,7 +8670,11 @@ x_scroll_bar_to_input_event (event, ievent)
8655 ievent->kind = SCROLL_BAR_CLICK_EVENT; 8670 ievent->kind = SCROLL_BAR_CLICK_EVENT;
8656 ievent->frame_or_window = window; 8671 ievent->frame_or_window = window;
8657 ievent->arg = Qnil; 8672 ievent->arg = Qnil;
8673#ifdef USE_GTK
8674 ievent->timestamp = CurrentTime;
8675#else
8658 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f)); 8676 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
8677#endif
8659 ievent->part = ev->data.l[1]; 8678 ievent->part = ev->data.l[1];
8660 ievent->code = ev->data.l[2]; 8679 ievent->code = ev->data.l[2];
8661 ievent->x = make_number ((int) ev->data.l[3]); 8680 ievent->x = make_number ((int) ev->data.l[3]);
@@ -8749,8 +8768,80 @@ xm_scroll_callback (widget, client_data, call_data)
8749} 8768}
8750 8769
8751 8770
8752#else /* !USE_MOTIF, i.e. Xaw. */ 8771#else /* !USE_MOTIF, i.e. Xaw or GTK */
8772#ifdef USE_GTK
8773/* Scroll bar callback for Gtk scroll bars. WIDGET is the scroll
8774 bar adjustment widget. DATA is a pointer to the scroll_bar structure. */
8775
8776static void
8777xg_scroll_callback (widget, data)
8778 GtkWidget *widget;
8779 gpointer data;
8780{
8781 struct scroll_bar *bar = (struct scroll_bar *) data;
8782 gdouble previous;
8783 gdouble position;
8784 gdouble *p;
8785 int diff;
8786
8787 int part = -1, whole = 0, portion = 0;
8788 GtkAdjustment *adj = GTK_ADJUSTMENT (widget);
8789
8790 if (xg_ignore_gtk_scrollbar) return;
8791
8792 position = gtk_adjustment_get_value (adj);
8793
8794 p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
8795 if (! p)
8796 {
8797 p = (gdouble*) xmalloc (sizeof (gdouble));
8798 *p = XG_SB_MIN;
8799 g_object_set_data (G_OBJECT (widget), XG_LAST_SB_DATA, p);
8800 }
8801
8802 previous = *p;
8803 *p = position;
8804
8805 diff = (int) (position - previous);
8806
8807 if (diff == (int) adj->step_increment)
8808 {
8809 part = scroll_bar_down_arrow;
8810 bar->dragging = Qnil;
8811 }
8812 else if (-diff == (int) adj->step_increment)
8813 {
8814 part = scroll_bar_up_arrow;
8815 bar->dragging = Qnil;
8816 }
8817 else if (diff == (int) adj->page_increment)
8818 {
8819 part = scroll_bar_below_handle;
8820 bar->dragging = Qnil;
8821 }
8822 else if (-diff == (int) adj->page_increment)
8823 {
8824 part = scroll_bar_above_handle;
8825 bar->dragging = Qnil;
8826 }
8827 else
8828 {
8829 part = scroll_bar_handle;
8830 whole = adj->upper - adj->page_size;
8831 portion = min (position, whole);
8832 bar->dragging = make_number (portion);
8833 }
8834
8835 if (part >= 0)
8836 {
8837 xg_ignore_next_thumb = 1;
8838 window_being_scrolled = bar->window;
8839 last_scroll_bar_part = part;
8840 x_send_scroll_bar_event (bar->window, part, portion, whole);
8841 }
8842}
8753 8843
8844#else /* not USE_GTK */
8754 8845
8755/* Xaw scroll bar callback. Invoked when the thumb is dragged. 8846/* Xaw scroll bar callback. Invoked when the thumb is dragged.
8756 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the 8847 WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
@@ -8833,13 +8924,30 @@ xaw_scroll_callback (widget, client_data, call_data)
8833 x_send_scroll_bar_event (bar->window, part, position, height); 8924 x_send_scroll_bar_event (bar->window, part, position, height);
8834} 8925}
8835 8926
8836 8927#endif /* not USE_GTK */
8837#endif /* not USE_MOTIF */ 8928#endif /* not USE_MOTIF */
8838 8929
8930#define SCROLL_BAR_NAME "verticalScrollBar"
8839 8931
8840/* Create the widget for scroll bar BAR on frame F. Record the widget 8932/* Create the widget for scroll bar BAR on frame F. Record the widget
8841 and X window of the scroll bar in BAR. */ 8933 and X window of the scroll bar in BAR. */
8842 8934
8935#ifdef USE_GTK
8936static void
8937x_create_toolkit_scroll_bar (f, bar)
8938 struct frame *f;
8939 struct scroll_bar *bar;
8940{
8941 char *scroll_bar_name = SCROLL_BAR_NAME;
8942
8943 BLOCK_INPUT;
8944 xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
8945 scroll_bar_name);
8946 UNBLOCK_INPUT;
8947}
8948
8949#else /* not USE_GTK */
8950
8843static void 8951static void
8844x_create_toolkit_scroll_bar (f, bar) 8952x_create_toolkit_scroll_bar (f, bar)
8845 struct frame *f; 8953 struct frame *f;
@@ -8849,7 +8957,7 @@ x_create_toolkit_scroll_bar (f, bar)
8849 Widget widget; 8957 Widget widget;
8850 Arg av[20]; 8958 Arg av[20];
8851 int ac = 0; 8959 int ac = 0;
8852 char *scroll_bar_name = "verticalScrollBar"; 8960 char *scroll_bar_name = SCROLL_BAR_NAME;
8853 unsigned long pixel; 8961 unsigned long pixel;
8854 8962
8855 BLOCK_INPUT; 8963 BLOCK_INPUT;
@@ -9022,11 +9130,22 @@ x_create_toolkit_scroll_bar (f, bar)
9022 9130
9023 UNBLOCK_INPUT; 9131 UNBLOCK_INPUT;
9024} 9132}
9133#endif /* not USE_GTK */
9025 9134
9026 9135
9027/* Set the thumb size and position of scroll bar BAR. We are currently 9136/* Set the thumb size and position of scroll bar BAR. We are currently
9028 displaying PORTION out of a whole WHOLE, and our position POSITION. */ 9137 displaying PORTION out of a whole WHOLE, and our position POSITION. */
9029 9138
9139#ifdef USE_GTK
9140static void
9141x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9142 struct scroll_bar *bar;
9143 int portion, position, whole;
9144{
9145 xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
9146}
9147
9148#else /* not USE_GTK */
9030static void 9149static void
9031x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) 9150x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9032 struct scroll_bar *bar; 9151 struct scroll_bar *bar;
@@ -9149,6 +9268,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
9149 9268
9150 UNBLOCK_INPUT; 9269 UNBLOCK_INPUT;
9151} 9270}
9271#endif /* not USE_GTK */
9152 9272
9153#endif /* USE_TOOLKIT_SCROLL_BARS */ 9273#endif /* USE_TOOLKIT_SCROLL_BARS */
9154 9274
@@ -9237,6 +9357,15 @@ x_scroll_bar_create (w, top, left, width, height)
9237 /* Map the window/widget. */ 9357 /* Map the window/widget. */
9238#ifdef USE_TOOLKIT_SCROLL_BARS 9358#ifdef USE_TOOLKIT_SCROLL_BARS
9239 { 9359 {
9360#ifdef USE_GTK
9361 xg_update_scrollbar_pos (f,
9362 SCROLL_BAR_X_WINDOW (bar),
9363 top,
9364 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9365 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9366 max (height, 1));
9367 xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
9368#else /* not USE_GTK */
9240 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar); 9369 Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
9241 XtConfigureWidget (scroll_bar, 9370 XtConfigureWidget (scroll_bar,
9242 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, 9371 left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
@@ -9244,6 +9373,7 @@ x_scroll_bar_create (w, top, left, width, height)
9244 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, 9373 width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9245 max (height, 1), 0); 9374 max (height, 1), 0);
9246 XtMapWidget (scroll_bar); 9375 XtMapWidget (scroll_bar);
9376#endif /* not USE_GTK */
9247 } 9377 }
9248#else /* not USE_TOOLKIT_SCROLL_BARS */ 9378#else /* not USE_TOOLKIT_SCROLL_BARS */
9249 XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); 9379 XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
@@ -9378,7 +9508,11 @@ x_scroll_bar_remove (bar)
9378 BLOCK_INPUT; 9508 BLOCK_INPUT;
9379 9509
9380#ifdef USE_TOOLKIT_SCROLL_BARS 9510#ifdef USE_TOOLKIT_SCROLL_BARS
9511#ifdef USE_GTK
9512 xg_remove_scroll_bar (f, SCROLL_BAR_X_WINDOW (bar));
9513#else /* not USE_GTK */
9381 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); 9514 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
9515#endif /* not USE_GTK */
9382#else 9516#else
9383 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); 9517 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
9384#endif 9518#endif
@@ -9472,20 +9606,30 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
9472 9606
9473#ifdef USE_TOOLKIT_SCROLL_BARS 9607#ifdef USE_TOOLKIT_SCROLL_BARS
9474 9608
9609#ifdef USE_GTK
9610 if (mask)
9611 xg_update_scrollbar_pos (f,
9612 SCROLL_BAR_X_WINDOW (bar),
9613 top,
9614 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9615 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9616 max (height, 1));
9617#else /* not USE_GTK */
9618
9475 /* Since toolkit scroll bars are smaller than the space reserved 9619 /* Since toolkit scroll bars are smaller than the space reserved
9476 for them on the frame, we have to clear "under" them. */ 9620 for them on the frame, we have to clear "under" them. */
9477 if (width > 0 && height > 0) 9621 if (width > 0 && height > 0)
9478 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 9622 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
9479 left, top, width, height, False); 9623 left, top, width, height, False);
9480
9481 /* Move/size the scroll bar widget. */ 9624 /* Move/size the scroll bar widget. */
9482 if (mask) 9625 if (mask)
9483 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar), 9626 XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
9484 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, 9627 sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
9485 top, 9628 top,
9486 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, 9629 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
9487 max (height, 1), 0); 9630 max (height, 1), 0);
9488 9631
9632#endif /* not USE_GTK */
9489#else /* not USE_TOOLKIT_SCROLL_BARS */ 9633#else /* not USE_TOOLKIT_SCROLL_BARS */
9490 9634
9491 /* Clear areas not covered by the scroll bar because of 9635 /* Clear areas not covered by the scroll bar because of
@@ -10070,6 +10214,41 @@ enum
10070 X_EVENT_DROP 10214 X_EVENT_DROP
10071}; 10215};
10072 10216
10217#ifdef USE_GTK
10218static struct x_display_info *current_dpyinfo;
10219static struct input_event **current_bufp;
10220static int *current_numcharsp;
10221static int current_count;
10222static int current_finish;
10223
10224/* This is the filter function invoked by the GTK event loop.
10225 It is invoked before the XEvent is translated to a GdkEvent,
10226 so we have a chanse to act on the event before GTK. */
10227static GdkFilterReturn
10228event_handler_gdk (gxev, ev, data)
10229 GdkXEvent *gxev;
10230 GdkEvent *ev;
10231 gpointer data;
10232{
10233 XEvent *xev = (XEvent*)gxev;
10234
10235 if (current_numcharsp)
10236 current_count += handle_one_xevent (current_dpyinfo,
10237 xev,
10238 current_bufp,
10239 current_numcharsp,
10240 &current_finish);
10241 else
10242 x_dispatch_event (xev, GDK_DISPLAY ());
10243
10244 if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
10245 return GDK_FILTER_REMOVE;
10246
10247 return GDK_FILTER_CONTINUE;
10248}
10249#endif /* USE_GTK */
10250
10251
10073/* Handles the XEvent EVENT on display DPYINFO. 10252/* Handles the XEvent EVENT on display DPYINFO.
10074 10253
10075 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events. 10254 *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -10079,7 +10258,7 @@ enum
10079 Events representing keys are stored in buffer *BUFP_R, 10258 Events representing keys are stored in buffer *BUFP_R,
10080 which can hold up to *NUMCHARSP characters. 10259 which can hold up to *NUMCHARSP characters.
10081 We return the number of characters stored into the buffer. */ 10260 We return the number of characters stored into the buffer. */
10082 10261
10083static int 10262static int
10084handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish) 10263handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10085 struct x_display_info *dpyinfo; 10264 struct x_display_info *dpyinfo;
@@ -10097,7 +10276,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10097 XEvent event = *eventp; 10276 XEvent event = *eventp;
10098 10277
10099 *finish = X_EVENT_NORMAL; 10278 *finish = X_EVENT_NORMAL;
10100 10279
10101 switch (event.type) 10280 switch (event.type)
10102 { 10281 {
10103 case ClientMessage: 10282 case ClientMessage:
@@ -10514,8 +10693,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
10514 case KeyPress: 10693 case KeyPress:
10515 10694
10516 /* Dispatch KeyPress events when in menu. */ 10695 /* Dispatch KeyPress events when in menu. */
10517 if (popup_activated_flag) 10696 if (popup_activated ())
10518 goto OTHER; 10697 goto OTHER;
10698
10519 f = x_any_window_to_frame (dpyinfo, event.xkey.window); 10699 f = x_any_window_to_frame (dpyinfo, event.xkey.window);
10520 10700
10521 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) 10701 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
@@ -11080,6 +11260,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11080 if (f) 11260 if (f)
11081 { 11261 {
11082#ifndef USE_X_TOOLKIT 11262#ifndef USE_X_TOOLKIT
11263#ifdef USE_GTK
11264 xg_resize_widgets (f, event.xconfigure.width,
11265 event.xconfigure.height);
11266#else /* not USE_GTK */
11083 /* If there is a pending resize for fullscreen, don't 11267 /* If there is a pending resize for fullscreen, don't
11084 do this one, the right one will come later. 11268 do this one, the right one will come later.
11085 The toolkit version doesn't seem to need this, but we 11269 The toolkit version doesn't seem to need this, but we
@@ -11108,20 +11292,31 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11108 SET_FRAME_GARBAGED (f); 11292 SET_FRAME_GARBAGED (f);
11109 cancel_mouse_face (f); 11293 cancel_mouse_face (f);
11110 } 11294 }
11295#endif /* not USE_GTK */
11111#endif 11296#endif
11112 11297
11113 f->output_data.x->pixel_width = event.xconfigure.width; 11298 f->output_data.x->pixel_width = event.xconfigure.width;
11114 f->output_data.x->pixel_height = event.xconfigure.height; 11299 f->output_data.x->pixel_height = event.xconfigure.height;
11115 11300
11301#ifdef USE_GTK
11302 /* GTK creates windows but doesn't map them.
11303 Only get real positions and check fullscreen when mapped. */
11304 if (FRAME_GTK_OUTER_WIDGET (f)
11305 && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
11306 {
11307#endif
11116 /* What we have now is the position of Emacs's own window. 11308 /* What we have now is the position of Emacs's own window.
11117 Convert that to the position of the window manager window. */ 11309 Convert that to the position of the window manager window. */
11118 x_real_positions (f, &f->output_data.x->left_pos, 11310 x_real_positions (f, &f->output_data.x->left_pos,
11119 &f->output_data.x->top_pos); 11311 &f->output_data.x->top_pos);
11120 11312
11121 x_check_fullscreen_move(f); 11313 x_check_fullscreen_move (f);
11122 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT) 11314 if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
11123 f->output_data.x->want_fullscreen &= 11315 f->output_data.x->want_fullscreen &=
11124 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH); 11316 ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
11317#ifdef USE_GTK
11318 }
11319#endif
11125#ifdef HAVE_X_I18N 11320#ifdef HAVE_X_I18N
11126 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) 11321 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
11127 xic_set_statusarea (f); 11322 xic_set_statusarea (f);
@@ -11137,8 +11332,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11137 } 11332 }
11138 goto OTHER; 11333 goto OTHER;
11139 11334
11140 case ButtonPress:
11141 case ButtonRelease: 11335 case ButtonRelease:
11336 case ButtonPress:
11142 { 11337 {
11143 /* If we decide we want to generate an event to be seen 11338 /* If we decide we want to generate an event to be seen
11144 by the rest of Emacs, we put it here. */ 11339 by the rest of Emacs, we put it here. */
@@ -11179,7 +11374,10 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11179 if (!tool_bar_p) 11374 if (!tool_bar_p)
11180 if (!dpyinfo->x_focus_frame 11375 if (!dpyinfo->x_focus_frame
11181 || f == dpyinfo->x_focus_frame) 11376 || f == dpyinfo->x_focus_frame)
11182 construct_mouse_click (&emacs_event, &event, f); 11377 {
11378 if (! popup_activated ())
11379 construct_mouse_click (&emacs_event, &event, f);
11380 }
11183 } 11381 }
11184 else 11382 else
11185 { 11383 {
@@ -11207,9 +11405,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11207 last_tool_bar_item = -1; 11405 last_tool_bar_item = -1;
11208 } 11406 }
11209 else 11407 else
11210 { 11408 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
11211 dpyinfo->grabbed &= ~(1 << event.xbutton.button);
11212 }
11213 11409
11214 if (numchars >= 1 && emacs_event.kind != NO_EVENT) 11410 if (numchars >= 1 && emacs_event.kind != NO_EVENT)
11215 { 11411 {
@@ -11219,14 +11415,19 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11219 numchars--; 11415 numchars--;
11220 } 11416 }
11221 11417
11222#ifdef USE_X_TOOLKIT 11418#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
11223 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window); 11419 f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
11224 /* For a down-event in the menu bar, 11420 /* For a down-event in the menu bar,
11225 don't pass it to Xt right now. 11421 don't pass it to Xt right now.
11226 Instead, save it away 11422 Instead, save it away
11227 and we will pass it to Xt from kbd_buffer_get_event. 11423 and we will pass it to Xt from kbd_buffer_get_event.
11228 That way, we can run some Lisp code first. */ 11424 That way, we can run some Lisp code first. */
11229 if (f && event.type == ButtonPress 11425 if (
11426#ifdef USE_GTK
11427 ! popup_activated ()
11428 &&
11429#endif
11430 f && event.type == ButtonPress
11230 /* Verify the event is really within the menu bar 11431 /* Verify the event is really within the menu bar
11231 and not just sent to it due to grabbing. */ 11432 and not just sent to it due to grabbing. */
11232 && event.xbutton.x >= 0 11433 && event.xbutton.x >= 0
@@ -11237,6 +11438,9 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11237 { 11438 {
11238 SET_SAVED_BUTTON_EVENT; 11439 SET_SAVED_BUTTON_EVENT;
11239 XSETFRAME (last_mouse_press_frame, f); 11440 XSETFRAME (last_mouse_press_frame, f);
11441#ifdef USE_GTK
11442 *finish = X_EVENT_DROP;
11443#endif
11240 } 11444 }
11241 else if (event.type == ButtonPress) 11445 else if (event.type == ButtonPress)
11242 { 11446 {
@@ -11260,7 +11464,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11260#endif /* USE_MOTIF */ 11464#endif /* USE_MOTIF */
11261 else 11465 else
11262 goto OTHER; 11466 goto OTHER;
11263#endif /* USE_X_TOOLKIT */ 11467#endif /* USE_X_TOOLKIT || USE_GTK */
11264 } 11468 }
11265 break; 11469 break;
11266 11470
@@ -11297,7 +11501,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
11297 } 11501 }
11298 11502
11299 goto ret; 11503 goto ret;
11300 11504
11301 out: 11505 out:
11302 *finish = X_EVENT_GOTO_OUT; 11506 *finish = X_EVENT_GOTO_OUT;
11303 11507
@@ -11427,6 +11631,31 @@ XTread_socket (sd, bufp, numchars, expected)
11427 UNBLOCK_INPUT; 11631 UNBLOCK_INPUT;
11428#endif 11632#endif
11429 11633
11634#ifdef USE_GTK
11635 /* For GTK we must use the GTK event loop. But XEvents gets passed
11636 to our filter function above, and then to the big event switch.
11637 We use a bunch of globals to communicate with our filter function,
11638 that is kind of ugly, but it works. */
11639 current_dpyinfo = dpyinfo;
11640
11641 while (gtk_events_pending ())
11642 {
11643 static int nr = 0;
11644 current_count = count;
11645 current_numcharsp = &numchars;
11646 current_bufp = &bufp;
11647
11648 gtk_main_iteration ();
11649
11650 count = current_count;
11651 current_bufp = 0;
11652 current_numcharsp = 0;
11653
11654 if (current_finish == X_EVENT_GOTO_OUT)
11655 goto out;
11656 }
11657
11658#else /* not USE_GTK */
11430 while (XPending (dpyinfo->display)) 11659 while (XPending (dpyinfo->display))
11431 { 11660 {
11432 int finish; 11661 int finish;
@@ -11457,6 +11686,7 @@ XTread_socket (sd, bufp, numchars, expected)
11457 if (finish == X_EVENT_GOTO_OUT) 11686 if (finish == X_EVENT_GOTO_OUT)
11458 goto out; 11687 goto out;
11459 } 11688 }
11689#endif /* USE_GTK */
11460 } 11690 }
11461 11691
11462 out:; 11692 out:;
@@ -12922,11 +13152,7 @@ x_calc_absolute_position (f)
12922 if (! ((flags & XNegative) || (flags & YNegative))) 13152 if (! ((flags & XNegative) || (flags & YNegative)))
12923 return; 13153 return;
12924 13154
12925#ifdef USE_X_TOOLKIT 13155 this_window = FRAME_OUTER_WINDOW (f);
12926 this_window = XtWindow (f->output_data.x->widget);
12927#else
12928 this_window = FRAME_X_WINDOW (f);
12929#endif
12930 13156
12931 /* Find the position of the outside upper-left corner of 13157 /* Find the position of the outside upper-left corner of
12932 the inner window, with respect to the outer window. 13158 the inner window, with respect to the outer window.
@@ -13057,13 +13283,8 @@ x_set_offset (f, xoff, yoff, change_gravity)
13057 } 13283 }
13058#endif 13284#endif
13059 13285
13060#ifdef USE_X_TOOLKIT 13286 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
13061 XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget), 13287 modified_left, modified_top);
13062 modified_left, modified_top);
13063#else /* not USE_X_TOOLKIT */
13064 XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
13065 modified_left, modified_top);
13066#endif /* not USE_X_TOOLKIT */
13067 UNBLOCK_INPUT; 13288 UNBLOCK_INPUT;
13068} 13289}
13069 13290
@@ -13249,7 +13470,12 @@ x_set_window_size (f, change_gravity, cols, rows)
13249{ 13470{
13250 BLOCK_INPUT; 13471 BLOCK_INPUT;
13251 13472
13252#ifdef USE_X_TOOLKIT 13473#ifdef USE_GTK
13474 if (FRAME_GTK_WIDGET (f))
13475 xg_frame_set_char_size (f, cols, rows);
13476 else
13477 x_set_window_size_1 (f, change_gravity, cols, rows);
13478#elif USE_X_TOOLKIT
13253 13479
13254 if (f->output_data.x->widget != NULL) 13480 if (f->output_data.x->widget != NULL)
13255 { 13481 {
@@ -13445,7 +13671,11 @@ x_make_frame_visible (f)
13445 /* This was XtPopup, but that did nothing for an iconified frame. */ 13671 /* This was XtPopup, but that did nothing for an iconified frame. */
13446 XtMapWidget (f->output_data.x->widget); 13672 XtMapWidget (f->output_data.x->widget);
13447#else /* not USE_X_TOOLKIT */ 13673#else /* not USE_X_TOOLKIT */
13674#ifdef USE_GTK
13675 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
13676#else
13448 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 13677 XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
13678#endif /* not USE_GTK */
13449#endif /* not USE_X_TOOLKIT */ 13679#endif /* not USE_X_TOOLKIT */
13450#if 0 /* This seems to bring back scroll bars in the wrong places 13680#if 0 /* This seems to bring back scroll bars in the wrong places
13451 if the window configuration has changed. They seem 13681 if the window configuration has changed. They seem
@@ -13596,6 +13826,14 @@ x_make_frame_invisible (f)
13596 by hand again (they have already done that once for this window.) */ 13826 by hand again (they have already done that once for this window.) */
13597 x_wm_set_size_hint (f, (long) 0, 1); 13827 x_wm_set_size_hint (f, (long) 0, 1);
13598 13828
13829#ifdef USE_GTK
13830 if (FRAME_GTK_OUTER_WIDGET (f))
13831 {
13832 gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
13833 goto out;
13834 }
13835#endif
13836
13599#ifdef HAVE_X11R4 13837#ifdef HAVE_X11R4
13600 13838
13601 if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window, 13839 if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
@@ -13630,6 +13868,7 @@ x_make_frame_invisible (f)
13630 XUnmapWindow (FRAME_X_DISPLAY (f), window); 13868 XUnmapWindow (FRAME_X_DISPLAY (f), window);
13631#endif /* ! defined (HAVE_X11R4) */ 13869#endif /* ! defined (HAVE_X11R4) */
13632 13870
13871 out:
13633 /* We can't distinguish this from iconification 13872 /* We can't distinguish this from iconification
13634 just by the event that we get from the server. 13873 just by the event that we get from the server.
13635 So we can't win using the usual strategy of letting 13874 So we can't win using the usual strategy of letting
@@ -13669,6 +13908,22 @@ x_iconify_frame (f)
13669 if (!NILP (type)) 13908 if (!NILP (type))
13670 x_bitmap_icon (f, type); 13909 x_bitmap_icon (f, type);
13671 13910
13911#ifdef USE_GTK
13912 if (FRAME_GTK_OUTER_WIDGET (f))
13913 {
13914 if (! FRAME_VISIBLE_P (f))
13915 gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
13916
13917 gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
13918 f->iconified = 1;
13919 f->visible = 1;
13920 f->async_iconified = 1;
13921 f->async_visible = 0;
13922 UNBLOCK_INPUT;
13923 return;
13924 }
13925#endif
13926
13672#ifdef USE_X_TOOLKIT 13927#ifdef USE_X_TOOLKIT
13673 13928
13674 if (! FRAME_VISIBLE_P (f)) 13929 if (! FRAME_VISIBLE_P (f))
@@ -13803,6 +14058,18 @@ x_free_frame_resources (f)
13803 14058
13804 free_frame_menubar (f); 14059 free_frame_menubar (f);
13805#else /* !USE_X_TOOLKIT */ 14060#else /* !USE_X_TOOLKIT */
14061
14062#ifdef USE_GTK
14063 /* In the GTK version, tooltips are normal X
14064 frames. We must check and free both types. */
14065 if (FRAME_GTK_OUTER_WIDGET (f))
14066 {
14067 gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
14068 FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
14069 FRAME_GTK_OUTER_WIDGET (f) = 0;
14070 }
14071#endif /* USE_GTK */
14072
13806 if (FRAME_X_WINDOW (f)) 14073 if (FRAME_X_WINDOW (f))
13807 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f)); 14074 XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
13808#endif /* !USE_X_TOOLKIT */ 14075#endif /* !USE_X_TOOLKIT */
@@ -13888,8 +14155,10 @@ x_destroy_window (f)
13888 FLAGS is the flags word to use--or 0 meaning preserve the flags 14155 FLAGS is the flags word to use--or 0 meaning preserve the flags
13889 that the window now has. 14156 that the window now has.
13890 If USER_POSITION is nonzero, we set the USPosition 14157 If USER_POSITION is nonzero, we set the USPosition
13891 flag (this is useful when FLAGS is 0). */ 14158 flag (this is useful when FLAGS is 0).
14159 The GTK version is in gtkutils.c */
13892 14160
14161#ifndef USE_GTK
13893void 14162void
13894x_wm_set_size_hint (f, flags, user_position) 14163x_wm_set_size_hint (f, flags, user_position)
13895 struct frame *f; 14164 struct frame *f;
@@ -13902,10 +14171,9 @@ x_wm_set_size_hint (f, flags, user_position)
13902 Arg al[2]; 14171 Arg al[2];
13903 int ac = 0; 14172 int ac = 0;
13904 Dimension widget_width, widget_height; 14173 Dimension widget_width, widget_height;
13905 Window window = XtWindow (f->output_data.x->widget); 14174#endif
13906#else /* not USE_X_TOOLKIT */ 14175
13907 Window window = FRAME_X_WINDOW (f); 14176 Window window = FRAME_OUTER_WINDOW (f);
13908#endif /* not USE_X_TOOLKIT */
13909 14177
13910 /* Setting PMaxSize caused various problems. */ 14178 /* Setting PMaxSize caused various problems. */
13911 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */; 14179 size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
@@ -14032,6 +14300,7 @@ x_wm_set_size_hint (f, flags, user_position)
14032 XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints); 14300 XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
14033#endif 14301#endif
14034} 14302}
14303#endif /* not USE_GTK */
14035 14304
14036/* Used for IconicState or NormalState */ 14305/* Used for IconicState or NormalState */
14037 14306
@@ -14063,7 +14332,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
14063 Pixmap icon_pixmap; 14332 Pixmap icon_pixmap;
14064 14333
14065#ifndef USE_X_TOOLKIT 14334#ifndef USE_X_TOOLKIT
14066 Window window = FRAME_X_WINDOW (f); 14335 Window window = FRAME_OUTER_WINDOW (f);
14067#endif 14336#endif
14068 14337
14069 if (pixmap_id > 0) 14338 if (pixmap_id > 0)
@@ -14864,6 +15133,67 @@ x_term_init (display_name, xrm_option, resource_name)
14864 x_initialized = 1; 15133 x_initialized = 1;
14865 } 15134 }
14866 15135
15136#ifdef USE_GTK
15137 {
15138#define NUM_ARGV 10
15139 int argc;
15140 char *argv[NUM_ARGV];
15141 char **argv2 = argv;
15142 GdkAtom atom;
15143
15144 /* GTK 2.0 can only handle one display, GTK 2.2 can handle more
15145 than one, but this remains to be implemented. */
15146 if (x_initialized > 1)
15147 return 0;
15148
15149 x_initialized++;
15150
15151 for (argc = 0; argc < NUM_ARGV; ++argc)
15152 argv[argc] = 0;
15153
15154 argc = 0;
15155 argv[argc++] = initial_argv[0];
15156
15157 if (! NILP (display_name))
15158 {
15159 argv[argc++] = "--display";
15160 argv[argc++] = SDATA (display_name);
15161 }
15162
15163 argv[argc++] = "--name";
15164 argv[argc++] = resource_name;
15165
15166 gtk_init (&argc, &argv2);
15167
15168 /* gtk_init does set_locale. We must fix locale after calling it. */
15169 fixup_locale ();
15170 xg_initialize ();
15171
15172 dpy = GDK_DISPLAY ();
15173
15174 /* NULL window -> events for all windows go to our function */
15175 gdk_window_add_filter (NULL, event_handler_gdk, NULL);
15176
15177 /* Load our own gtkrc if it exists. */
15178 {
15179 struct gcpro gcpro1, gcpro2;
15180 char *file = "~/.emacs.d/gtkrc";
15181 Lisp_Object s, abs_file;
15182
15183 GCPRO2 (str, abs_file);
15184 s = make_string (file, strlen (file));
15185 abs_file = Fexpand_file_name(s, Qnil);
15186
15187 if (! NILP (abs_file) && Ffile_readable_p (abs_file))
15188 gtk_rc_parse (SDATA (abs_file));
15189
15190 UNGCPRO;
15191 }
15192
15193 XSetErrorHandler (x_error_handler);
15194 XSetIOErrorHandler (x_io_error_quitter);
15195 }
15196#else /* not USE_GTK */
14867#ifdef USE_X_TOOLKIT 15197#ifdef USE_X_TOOLKIT
14868 /* weiner@footloose.sps.mot.com reports that this causes 15198 /* weiner@footloose.sps.mot.com reports that this causes
14869 errors with X11R5: 15199 errors with X11R5:
@@ -14904,6 +15234,7 @@ x_term_init (display_name, xrm_option, resource_name)
14904#endif 15234#endif
14905 dpy = XOpenDisplay (SDATA (display_name)); 15235 dpy = XOpenDisplay (SDATA (display_name));
14906#endif /* not USE_X_TOOLKIT */ 15236#endif /* not USE_X_TOOLKIT */
15237#endif /* not USE_GTK*/
14907 15238
14908 /* Detect failure. */ 15239 /* Detect failure. */
14909 if (dpy == 0) 15240 if (dpy == 0)
@@ -15363,9 +15694,11 @@ x_initialize ()
15363#endif 15694#endif
15364 15695
15365#ifdef USE_TOOLKIT_SCROLL_BARS 15696#ifdef USE_TOOLKIT_SCROLL_BARS
15697#ifndef USE_GTK
15366 xaw3d_arrow_scroll = False; 15698 xaw3d_arrow_scroll = False;
15367 xaw3d_pick_top = True; 15699 xaw3d_pick_top = True;
15368#endif 15700#endif
15701#endif
15369 15702
15370 /* Note that there is no real way portable across R3/R4 to get the 15703 /* Note that there is no real way portable across R3/R4 to get the
15371 original error handler. */ 15704 original error handler. */
@@ -15445,6 +15778,8 @@ Otherwise, value is a symbol describing the X toolkit. */);
15445 Vx_toolkit_scroll_bars = intern ("motif"); 15778 Vx_toolkit_scroll_bars = intern ("motif");
15446#elif defined HAVE_XAW3D 15779#elif defined HAVE_XAW3D
15447 Vx_toolkit_scroll_bars = intern ("xaw3d"); 15780 Vx_toolkit_scroll_bars = intern ("xaw3d");
15781#elif USE_GTK
15782 Vx_toolkit_scroll_bars = intern ("gtk");
15448#else 15783#else
15449 Vx_toolkit_scroll_bars = intern ("xaw"); 15784 Vx_toolkit_scroll_bars = intern ("xaw");
15450#endif 15785#endif