comparison src/xterm.c @ 1720:4f5e3ac5d822

* frame.h (struct frame): New fields `can_have_scrollbars' and `has_vertical_scrollbars'. (FRAME_CAN_HAVE_SCROLLBARS, FRAME_HAS_VERTICAL_SCROLLBARS): New accessors, for both the MULTI_FRAME and non-MULTI_FRAME. (VERTICAL_SCROLLBAR_WIDTH, WINDOW_VERTICAL_SCROLLBAR, WINDOW_VERTICAL_SCROLLBAR_COLUMN, WINDOW_VERTICAL_SCROLLBAR_HEIGHT): New macros. * window.h (struct window): New field `vertical_scrollbar'. * xterm.h (struct x_display): vertical_scrollbars, judge_timestamp, vertical_scrollbar_extra: New fields. (struct scrollbar): New struct. (VERTICAL_SCROLLBAR_PIXEL_WIDTH, VERTICAL_SCROLLBAR_PIXEL_HEIGHT, VERTICAL_SCROLLBAR_LEFT_BORDER, VERTICAL_SCROLLBAR_RIGHT_BORDER, VERTICAL_SCROLLBAR_TOP_BORDER, VERTICAL_SCROLLBAR_BOTTOM_BORDER, CHAR_TO_PIXEL_WIDTH, CHAR_TO_PIXEL_HEIGHT, PIXEL_TO_CHAR_WIDTH, PIXEL_TO_CHAR_HEIGHT): New accessors and macros. * frame.c (make_frame): Initialize the `can_have_scrollbars' and `has_vertical_scrollbars' fields of the frame. * term.c (term_init): Note that TERMCAP terminals don't support scrollbars. (mouse_position_hook): Document new args. (set_vertical_scrollbar_hook, condemn_scrollbars_hook, redeem_scrollbar_hook, judge_scrollbars_hook): New hooks. * termhooks.h: Declare and document them. (enum scrollbar_part): New type. (struct input_event): Describe the new form of the scrollbar_click event type. Change `part' from a Lisp_Object to an enum scrollbar_part. Add a new field `scrollbar'. * keyboard.c (kbd_buffer_get_event): Pass appropriate new parameters to *mouse_position_hook, and make_lispy_movement. * xfns.c (x_set_vertical_scrollbar): New function. (x_figure_window_size): Use new macros to calculate frame size. (Fx_create_frame): Note that X Windows frames do support scroll bars. Default to "yes". * xterm.c: #include <X11/cursorfont.h> and "window.h". (x_vertical_scrollbar_cursor): New variable. (x_term_init): Initialize it. (last_mouse_bar, last_mouse_bar_frame, last_mouse_part, last_mouse_scroll_range_start, last_mouse_scroll_range_end): New variables. (XTmouse_position): Use them to return scrollbar movement events. Take new arguments, for that purpose. (x_window_to_scrollbar, x_scrollbar_create, x_scrollbar_set_handle, x_scrollbar_remove, x_scrollbar_move, XTset_scrollbar, XTcondemn_scrollbars, XTredeem_scrollbar, XTjudge_scrollbars, x_scrollbar_expose, x_scrollbar_background_expose, x_scrollbar_handle_click, x_scrollbar_handle_motion): New functions to implement scrollbars. (x_term_init): Set the termhooks.h hooks to point to them. (x_set_window_size): Use new macros to calculate frame size. Set vertical_scrollbar_extra field. (x_make_frame_visible): Use the frame accessor FRAME_HAS_VERTICAL_SCROLLBARS to decide if we need to map the frame's subwindows as well. (XTread_socket): Use new size-calculation macros from xterm.h when processing ConfigureNotify events. (x_wm_set_size_hint): Use PIXEL_TO_CHAR_WIDTH and PIXEL_TO_CHAR_HEIGHT macros. * ymakefile (xdisp.o): This now depends on termhooks.h. (xterm.o): This now depends on window.h. * xterm.h (struct x_display): Delete v_scrollbar, v_thumbup, v_thumbdown, v_slider, h_scrollbar, h_thumbup, h_thumbdown, h_slider, v_scrollbar_width, h_scrollbar_height fields. * keyboard.c (Qvscrollbar_part, Qvslider_part, Qvthumbup_part, Qvthumbdown_part, Qhscrollbar_part, Qhslider_part, Qhthumbup_part, Qhthumbdown_part, Qscrollbar_click): Deleted; part of an obsolete interface. (head_table): Removed from here as well. (syms_of_keyboard): And here. * keyboard.h: And here. (POSN_SCROLLBAR_BUTTON): Removed. * xscrollbar.h: File removed - no longer necessary. * xfns.c: Don't #include it any more. (Qhorizontal_scroll_bar, Qvertical_scroll_bar): Deleted. (syms_of_xfns): Don't initialize or staticpro them. (gray_bits): Salvaged from xscrollbar.h. (x_window_to_scrollbar): Deleted. (x_set_horizontal_scrollbar): Deleted. (enum x_frame_parm, x_frame_parms): Remove references to x_set_horizontal_scrollbar. (x_set_foreground_color, x_set_background_color, x_set_border_pixel): Remove special code to support scrollbars. (Fx_create_frame): Remove old scrollbar setup code. (install_vertical_scrollbar, install_horizontal_scrollbar, adjust_scrollbars, x_resize_scrollbars): Deleted. * xterm.c (construct_mouse_click): This doesn't need to take care of scrollbar clicks anymore. (XTread_socket): Remove old code to support scrollbars. Call new functions instead for events which occur in scrollbar windows. (XTupdate_end): Remove call to adjust_scrollbars; the main redisplay code takes care of that now. (enum window_type): Deleted. * ymakefile: Note that xfns.o no longer depends on xscrollbar.h. * xterm.c (x_set_mouse_position): Clip mouse position to be within frame. * xterm.c: Adjust the first line of each page to have a reasonable description. This makes pages-directory more useful. * xterm.c (x_do_pending_expose): Declare this routine only if HAVE_X11 is not #defined; X11 doesn't need it. (XTread_socket): Protect call to x_do_pending_expose with `#ifdef HAVE_X11'. * xterm.c (notice_mouse_movement): Deleted; obsolete and unused. Properly handle focus shift events, so the cursor is filled and hollow at the appropriate times, even in titleless windows. * xterm.c (x_focus_event_frame): New variable. (XTread_socket): When we receive a FocusIn event that's not NotifyPointer, record the frame in x_focus_event_frame. When we receive a FocusOut event that's not NotifyPointer, clear it. When we get a LeaveNotify event, don't take it seriously if we still have focus. * xterm.c (XTread_socket): Remove special code in EnterNotify case to handle scrollbars and fake mouse motion events. Change the meaning of focus redirection to make switching windows work properly. Fredirect_frame_focus has the details. * frame.h (focus_frame): Doc fix. [not MULTI_FRAME] (FRAME_FOCUS_FRAME): Make this Qnil, which indicates no focus redirection, instead of zero, which is selected_frame. * frame.c (make_frame): Initialize f->focus_frame to Qnil, rather than making it point to frame itself. (Fselect_frame): If changing the selected frame from FOO to BAR, make all redirections to FOO shift to BAR as well. Doc fix. (Fredirect_frame_focus): Doc fix. Accept nil as a valid redirection, not just as a default for FRAME. (Fframe_focus): Doc fix. * keyboard.c (kbd_buffer_store_event, kbd_buffer_get_event): Deal with focus redirections being nil. * xterm.c (XTframe_rehighlight): Doc fix. Deal with focus redirections being nil. * xterm.c (x_error_quitter): Just abort, so we can look at the core to see what happened. It's a pain to remember that you can't assign to FRAME->visible. Let's change all references to the `visible' member of struct frame to use the accessor macros, and then write a setter for the `visible' field that does the right thing. * frame.h (FRAME_VISIBLE_P): Make this not an l-value. (FRAME_SET_VISIBLE): New macro. * frame.c (make_terminal_frame, Fdelete_frame): Use FRAME_SET_VISIBLE. (Fframe_visible_p, Fvisible_frame_list): Use FRAME_VISIBLE_P and FRAME_ICONIFIED_P. * dispnew.c (Fredraw_display): Use the FRAME_VISIBLE_P and FRAME_GARBAGED_P accessors. * xdisp.c (redisplay): Use the FRAME_VISIBLE_P accessor. * xfns.c (x_set_foreground_color, x_set_background_color, x_set_cursor_color, x_set_border_pixel, x_set_icon_type): Use the FRAME_VISIBLE_P accessor. (Fx_create_frame): Use FRAME_SET_VISIBILITY. * xterm.c (clear_cursor, x_display_bar_cursor, x_display_box_cursor): Use FRAME_SET_VISIBILITY.
author Jim Blandy <jimb@redhat.com>
date Thu, 24 Dec 1992 06:21:14 +0000
parents 452ba03935d7
children d738d3690836
comparison
equal deleted inserted replaced
1719:48f539ac6921 1720:4f5e3ac5d822
36 #include <signal.h> 36 #include <signal.h>
37 37
38 /* This may include sys/types.h, and that somehow loses 38 /* This may include sys/types.h, and that somehow loses
39 if this is not done before the other system files. */ 39 if this is not done before the other system files. */
40 #include "xterm.h" 40 #include "xterm.h"
41 #include <X11/cursorfont.h>
41 42
42 #ifndef USG 43 #ifndef USG
43 /* Load sys/types.h if not already loaded. 44 /* Load sys/types.h if not already loaded.
44 In some systems loading it twice is suicidal. */ 45 In some systems loading it twice is suicidal. */
45 #ifndef makedev 46 #ifndef makedev
87 #endif /* ! 0 */ 88 #endif /* ! 0 */
88 #include "gnu.h" 89 #include "gnu.h"
89 #include "frame.h" 90 #include "frame.h"
90 #include "disptab.h" 91 #include "disptab.h"
91 #include "buffer.h" 92 #include "buffer.h"
93 #include "window.h"
92 94
93 #ifdef HAVE_X11 95 #ifdef HAVE_X11
94 #define XMapWindow XMapRaised /* Raise them when mapping. */ 96 #define XMapWindow XMapRaised /* Raise them when mapping. */
95 #else /* ! defined (HAVE_X11) */ 97 #else /* ! defined (HAVE_X11) */
96 #include <X/Xkeyboard.h> 98 #include <X/Xkeyboard.h>
103 #define min(a,b) ((a)<(b) ? (a) : (b)) 105 #define min(a,b) ((a)<(b) ? (a) : (b))
104 #define max(a,b) ((a)>(b) ? (a) : (b)) 106 #define max(a,b) ((a)>(b) ? (a) : (b))
105 107
106 /* Nonzero means we must reprint all windows 108 /* Nonzero means we must reprint all windows
107 because 1) we received an ExposeWindow event 109 because 1) we received an ExposeWindow event
108 or 2) we received too many ExposeRegion events to record. */ 110 or 2) we received too many ExposeRegion events to record.
109 111
112 This is never needed under X11. */
110 static int expose_all_windows; 113 static int expose_all_windows;
111 114
112 /* Nonzero means we must reprint all icon windows. */ 115 /* Nonzero means we must reprint all icon windows. */
113 116
114 static int expose_all_icons; 117 static int expose_all_icons;
156 Lisp_Object invocation_name; 159 Lisp_Object invocation_name;
157 160
158 /* This is the X connection that we are using. */ 161 /* This is the X connection that we are using. */
159 162
160 Display *x_current_display; 163 Display *x_current_display;
164
165 /* The cursor to use for vertical scrollbars on x_current_display. */
166 static Cursor x_vertical_scrollbar_cursor;
161 167
162 /* Frame being updated by update_frame. */ 168 /* Frame being updated by update_frame. */
163 /* This is set by XTupdate_begin and looked at by all the 169 /* This is set by XTupdate_begin and looked at by all the
164 XT functions. It is zero while not inside an update. 170 XT functions. It is zero while not inside an update.
165 In that case, the XT functions assume that `selected_frame' 171 In that case, the XT functions assume that `selected_frame'
166 is the frame to apply to. */ 172 is the frame to apply to. */
167 173
168 static struct frame *updating_frame; 174 static struct frame *updating_frame;
169 175
170 /* The frame (if any) which has the X window that has keyboard focus. 176 /* The frame (if any) which has the X window that has keyboard focus.
171 Zero if none. This is examined by Ffocus_frame in frame.c. */ 177 Zero if none. This is examined by Ffocus_frame in frame.c. Note
178 that a mere EnterNotify event can set this; if you need to know the
179 last frame specified in a FocusIn or FocusOut event, use
180 x_focus_event_frame. */
172 struct frame *x_focus_frame; 181 struct frame *x_focus_frame;
182
183 /* The last frame mentioned in a FocusIn or FocusOut event. This is
184 separate from x_focus_frame, because whether or not LeaveNotify
185 events cause us to lose focus depends on whether or not we have
186 received a FocusIn event for it. */
187 struct frame *x_focus_event_frame;
173 188
174 /* The frame which currently has the visual highlight, and should get 189 /* The frame which currently has the visual highlight, and should get
175 keyboard input (other sorts of input have the frame encoded in the 190 keyboard input (other sorts of input have the frame encoded in the
176 event). It points to the X focus frame's selected window's 191 event). It points to the X focus frame's selected window's
177 frame. It differs from x_focus_frame when we're using a global 192 frame. It differs from x_focus_frame when we're using a global
258 void dumpborder (); 273 void dumpborder ();
259 static int XTcursor_to (); 274 static int XTcursor_to ();
260 static int XTclear_end_of_line (); 275 static int XTclear_end_of_line ();
261 276
262 277
263 /* These hooks are called by update_frame at the beginning and end 278 /* Starting and ending updates.
279
280 These hooks are called by update_frame at the beginning and end
264 of a frame update. We record in `updating_frame' the identity 281 of a frame update. We record in `updating_frame' the identity
265 of the frame being updated, so that the XT... functions do not 282 of the frame being updated, so that the XT... functions do not
266 need to take a frame as argument. Most of the XT... functions 283 need to take a frame as argument. Most of the XT... functions
267 should never be called except during an update, the only exceptions 284 should never be called except during an update, the only exceptions
268 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */ 285 being XTcursor_to, XTwrite_char and XTreassert_line_highlight. */
287 dumpqueue (); 304 dumpqueue ();
288 #endif /* HAVE_X11 */ 305 #endif /* HAVE_X11 */
289 UNBLOCK_INPUT; 306 UNBLOCK_INPUT;
290 } 307 }
291 308
309 #ifndef HAVE_X11
292 static void x_do_pending_expose (); 310 static void x_do_pending_expose ();
311 #endif
293 312
294 static 313 static
295 XTupdate_end (f) 314 XTupdate_end (f)
296 struct frame *f; 315 struct frame *f;
297 { 316 {
302 abort (); 321 abort ();
303 322
304 BLOCK_INPUT; 323 BLOCK_INPUT;
305 #ifndef HAVE_X11 324 #ifndef HAVE_X11
306 dumpqueue (); 325 dumpqueue ();
326 x_do_pending_expose ();
307 #endif /* HAVE_X11 */ 327 #endif /* HAVE_X11 */
308 adjust_scrollbars (f);
309 x_do_pending_expose ();
310 328
311 x_display_cursor (f, 1); 329 x_display_cursor (f, 1);
312 330
313 updating_frame = 0; 331 updating_frame = 0;
314 XFlushQueue (); 332 XFlushQueue ();
354 XTreset_terminal_modes () 372 XTreset_terminal_modes ()
355 { 373 {
356 /* XTclear_frame (); */ 374 /* XTclear_frame (); */
357 } 375 }
358 376
359 /* Set the nominal cursor position of the frame: 377 /* Set the nominal cursor position of the frame.
360 where display update commands will take effect. 378 This is where display update commands will take effect.
361 This does not affect the place where the cursor-box is displayed. */ 379 This does not affect the place where the cursor-box is displayed. */
362 380
363 static int 381 static int
364 XTcursor_to (row, col) 382 XTcursor_to (row, col)
365 register int row, col; 383 register int row, col;
522 left += len * FONT_WIDTH (font); 540 left += len * FONT_WIDTH (font);
523 } 541 }
524 } 542 }
525 #endif /* ! 0 */ 543 #endif /* ! 0 */
526 544
527 /* Output some text at the nominal frame cursor position, 545 /* Output some text at the nominal frame cursor position.
528 advancing the cursor over the text. 546 Advance the cursor over the text.
529 Output LEN glyphs at START. 547 Output LEN glyphs at START.
530 548
531 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight, 549 `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
532 controls the pixel values used for foreground and background. */ 550 controls the pixel values used for foreground and background. */
533 551
575 curs_x += len; 593 curs_x += len;
576 594
577 UNBLOCK_INPUT; 595 UNBLOCK_INPUT;
578 } 596 }
579 597
580 /* Erase the current text line from the nominal cursor position (inclusive) 598 /* Clear to the end of the line.
599 Erase the current text line from the nominal cursor position (inclusive)
581 to column FIRST_UNUSED (exclusive). The idea is that everything 600 to column FIRST_UNUSED (exclusive). The idea is that everything
582 from FIRST_UNUSED onward is already erased. */ 601 from FIRST_UNUSED onward is already erased. */
583 602
584 static int 603 static int
585 XTclear_end_of_line (first_unused) 604 XTclear_end_of_line (first_unused)
756 XFlushQueue (); 775 XFlushQueue ();
757 UNBLOCK_INPUT; 776 UNBLOCK_INPUT;
758 } 777 }
759 } 778 }
760 779
761 /* Insert and delete character are not supposed to be used 780 /* Insert and delete character.
762 because we are supposed to turn off the feature of using them. */ 781 These are not supposed to be used because we are supposed to turn
782 off the feature of using them. */
763 783
764 static 784 static
765 XTinsert_glyphs (start, len) 785 XTinsert_glyphs (start, len)
766 register char *start; 786 register char *start;
767 register int len; 787 register int len;
792 flexlines = updating_frame->height; 812 flexlines = updating_frame->height;
793 else 813 else
794 flexlines = n; 814 flexlines = n;
795 } 815 }
796 816
797 /* Perform an insert-lines operation, inserting N lines 817 /* Perform an insert-lines operation.
798 at a vertical position curs_y. */ 818 Insert N lines at a vertical position curs_y. */
799 819
800 static void 820 static void
801 stufflines (n) 821 stufflines (n)
802 register int n; 822 register int n;
803 { 823 {
953 scraplines (-n); 973 scraplines (-n);
954 XFlushQueue (); 974 XFlushQueue ();
955 UNBLOCK_INPUT; 975 UNBLOCK_INPUT;
956 } 976 }
957 977
978 /* Support routines for exposure events. */
958 static void clear_cursor (); 979 static void clear_cursor ();
959 980
960 /* Output into a rectangle of an X-window (for frame F) 981 /* Output into a rectangle of an X-window (for frame F)
961 the characters in f->phys_lines that overlap that rectangle. 982 the characters in f->phys_lines that overlap that rectangle.
962 TOP and LEFT are the position of the upper left corner of the rectangle. 983 TOP and LEFT are the position of the upper left corner of the rectangle.
1070 } 1091 }
1071 XFlushQueue (); 1092 XFlushQueue ();
1072 } 1093 }
1073 #endif /* HAVE_X11 */ 1094 #endif /* HAVE_X11 */
1074 1095
1075 /* Process all expose events that are pending. 1096 /* Process all expose events that are pending, for X10.
1076 Redraws the cursor if necessary on any frame that 1097 Redraws the cursor if necessary on any frame that
1077 is not in the process of being updated with update_frame. */ 1098 is not in the process of being updated with update_frame. */
1078 1099
1100 #ifndef HAVE_X11
1079 static void 1101 static void
1080 x_do_pending_expose () 1102 x_do_pending_expose ()
1081 { 1103 {
1082 int mask; 1104 int mask;
1083 struct frame *f; 1105 struct frame *f;
1137 ; 1159 ;
1138 #else /* ! defined (HAVE_X11) */ 1160 #else /* ! defined (HAVE_X11) */
1139 dumpqueue (); 1161 dumpqueue ();
1140 #endif /* ! defined (HAVE_X11) */ 1162 #endif /* ! defined (HAVE_X11) */
1141 } 1163 }
1164 #endif
1142 1165
1143 #ifdef HAVE_X11 1166 #ifdef HAVE_X11
1144 static void 1167 static void
1145 frame_highlight (frame) 1168 frame_highlight (frame)
1146 struct frame *frame; 1169 struct frame *frame;
1243 1266
1244 XTframe_rehighlight (); 1267 XTframe_rehighlight ();
1245 } 1268 }
1246 1269
1247 1270
1248 /* The focus has changed, or we have make a frame's selected window 1271 /* The focus has changed, or we have redirected a frame's focus to
1249 point to a window on a different frame (this happens with global 1272 another frame (this happens when a frame uses a surrogate
1250 minibuffer frames). Shift the highlight as appropriate. */ 1273 minibuffer frame). Shift the highlight as appropriate. */
1251 static void 1274 static void
1252 XTframe_rehighlight () 1275 XTframe_rehighlight ()
1253 { 1276 {
1254 struct frame *old_highlight = x_highlight_frame; 1277 struct frame *old_highlight = x_highlight_frame;
1255 1278
1256 if (x_focus_frame) 1279 if (x_focus_frame)
1257 { 1280 {
1258 x_highlight_frame = XFRAME (FRAME_FOCUS_FRAME (x_focus_frame)); 1281 x_highlight_frame =
1259 if (x_highlight_frame->display.nothing == 0) 1282 ((XTYPE (FRAME_FOCUS_FRAME (x_focus_frame)) == Lisp_Frame)
1260 XSET (FRAME_FOCUS_FRAME (x_focus_frame), Lisp_Frame, 1283 ? XFRAME (FRAME_FOCUS_FRAME (x_focus_frame))
1261 (x_highlight_frame = x_focus_frame)); 1284 : x_focus_frame);
1285 if (! FRAME_LIVE_P (x_highlight_frame))
1286 {
1287 FRAME_FOCUS_FRAME (x_focus_frame) = Qnil;
1288 x_highlight_frame = x_focus_frame;
1289 }
1262 } 1290 }
1263 else 1291 else
1264 x_highlight_frame = 0; 1292 x_highlight_frame = 0;
1265 1293
1266 if (x_highlight_frame != old_highlight) 1294 if (x_highlight_frame != old_highlight)
1269 frame_unhighlight (old_highlight); 1297 frame_unhighlight (old_highlight);
1270 if (x_highlight_frame) 1298 if (x_highlight_frame)
1271 frame_highlight (x_highlight_frame); 1299 frame_highlight (x_highlight_frame);
1272 } 1300 }
1273 } 1301 }
1274
1275 enum window_type
1276 {
1277 no_window,
1278 scrollbar_window,
1279 text_window,
1280 };
1281
1282 /* Position of the mouse in characters */
1283 unsigned int x_mouse_x, x_mouse_y;
1284
1285 /* Offset in buffer of character under the pointer, or 0. */
1286 extern int mouse_buffer_offset;
1287
1288 extern int buffer_posn_from_coords ();
1289
1290 /* Symbols from xfns.c to denote the different parts of a window. */
1291 extern Lisp_Object Qmodeline_part, Qtext_part;
1292
1293 #if 0
1294 /* Set *RESULT to an emacs input_event corresponding to MOTION_EVENT.
1295 F is the frame in which the event occurred.
1296
1297 WINDOW_TYPE says whether the event happened in a scrollbar window
1298 or a text window, affecting the format of the event created.
1299
1300 PART specifies which part of the scrollbar the event happened in,
1301 if WINDOW_TYPE == scrollbar_window.
1302
1303 If the mouse is over the same character as the last time we checked,
1304 don't return an event; set result->kind to no_event. */
1305
1306 static void
1307 notice_mouse_movement (result, motion_event, f, window_type, part)
1308 struct input_event *result;
1309 XMotionEvent motion_event;
1310 struct frame *f;
1311 int window_type;
1312 Lisp_Object part;
1313 {
1314 int x, y, root_x, root_y, pix_x, pix_y;
1315 unsigned int keys_and_buttons;
1316 Window w, root_window;
1317
1318 /* Unless we decide otherwise below, return a non-event. */
1319 result->kind = no_event;
1320
1321 if (XQueryPointer (x_current_display,
1322 FRAME_X_WINDOW (f),
1323 &root_window, &w,
1324 &root_x, &root_y, &pix_x, &pix_y,
1325 &keys_and_buttons)
1326 == False)
1327 return;
1328
1329 #if 0
1330 if (w == None) /* Mouse no longer in window. */
1331 return Qnil;
1332 #endif /* ! 0 */
1333
1334 pixel_to_glyph_translation (f, pix_x, pix_y, &x, &y);
1335 if (x == x_mouse_x && y == x_mouse_y)
1336 return;
1337
1338 x_mouse_x = x;
1339 x_mouse_y = y;
1340
1341 /* What sort of window are we in now? */
1342 if (window_type == text_window) /* Text part */
1343 {
1344 int modeline_p;
1345
1346 Vmouse_window = window_from_coordinates (f, x, y, &modeline_p);
1347
1348 if (XTYPE (Vmouse_window) == Lisp_Window)
1349 mouse_buffer_offset
1350 = buffer_posn_from_coords (XWINDOW (Vmouse_window), x, y);
1351 else
1352 mouse_buffer_offset = 0;
1353
1354 if (EQ (Vmouse_window, Qnil))
1355 Vmouse_frame_part = Qnil;
1356 else if (modeline_p)
1357 Vmouse_frame_part = Qmodeline_part;
1358 else
1359 Vmouse_frame_part = Qtext_part;
1360
1361 result->kind = window_sys_event;
1362 result->code = Qmouse_moved;
1363
1364 return;
1365 }
1366 else if (window_type == scrollbar_window) /* Scrollbar */
1367 {
1368 Vmouse_window = f->selected_window;
1369 mouse_buffer_offset = 0;
1370 Vmouse_frame_part = part;
1371
1372 result->kind = window_sys_event;
1373 result->code = Qmouse_moved;
1374
1375 return;
1376 }
1377
1378 return;
1379 }
1380 #endif /* ! 0 */
1381
1382 1302
1383 /* Mouse clicks and mouse movement. Rah. */ 1303 /* Mouse clicks and mouse movement. Rah. */
1384 #ifdef HAVE_X11 1304 #ifdef HAVE_X11
1385 1305
1386 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return 1306 /* Given a pixel position (PIX_X, PIX_Y) on the frame F, return
1529 return ( ((state & (ShiftMask | x_shift_lock_mask)) ? shift_modifier : 0) 1449 return ( ((state & (ShiftMask | x_shift_lock_mask)) ? shift_modifier : 0)
1530 | ((state & ControlMask) ? ctrl_modifier : 0) 1450 | ((state & ControlMask) ? ctrl_modifier : 0)
1531 | ((state & x_meta_mod_mask) ? meta_modifier : 0)); 1451 | ((state & x_meta_mod_mask) ? meta_modifier : 0));
1532 } 1452 }
1533 1453
1534 extern struct frame *x_window_to_scrollbar ();
1535 extern Lisp_Object Vmouse_event;
1536
1537 /* Prepare a mouse-event in *RESULT for placement in the input queue. 1454 /* Prepare a mouse-event in *RESULT for placement in the input queue.
1538 1455
1539 If the event is a button press, then note that we have grabbed 1456 If the event is a button press, then note that we have grabbed
1540 the mouse. 1457 the mouse. */
1541
1542 If PART and PREFIX are 0, then the event occurred in the text part;
1543 otherwise it happened in a scrollbar. */
1544 1458
1545 static Lisp_Object 1459 static Lisp_Object
1546 construct_mouse_click (result, event, f, part, prefix) 1460 construct_mouse_click (result, event, f)
1547 struct input_event *result; 1461 struct input_event *result;
1548 XButtonEvent *event; 1462 XButtonEvent *event;
1549 struct frame *f; 1463 struct frame *f;
1550 int prefix; 1464 {
1551 Lisp_Object part; 1465 /* Make the event type no_event; we'll change that when we decide
1552 {
1553 /* Initialize those fields text and scrollbar clicks hold in common.
1554 Make the event type no_event; we'll change that when we decide
1555 otherwise. */ 1466 otherwise. */
1556 result->kind = no_event; 1467 result->kind = mouse_click;
1557 XSET (result->code, Lisp_Int, event->button); 1468 XSET (result->code, Lisp_Int, event->button - Button1);
1558 result->timestamp = event->time; 1469 result->timestamp = event->time;
1559 result->modifiers = (x_convert_modifiers (event->state) 1470 result->modifiers = (x_convert_modifiers (event->state)
1560 | (event->type == ButtonRelease 1471 | (event->type == ButtonRelease
1561 ? up_modifier 1472 ? up_modifier
1562 : down_modifier)); 1473 : down_modifier));
1573 x_mouse_grabbed &= ~(1 << event->button); 1484 x_mouse_grabbed &= ~(1 << event->button);
1574 if (!x_mouse_grabbed) 1485 if (!x_mouse_grabbed)
1575 Vmouse_depressed = Qnil; 1486 Vmouse_depressed = Qnil;
1576 } 1487 }
1577 1488
1578 if (! NILP (part)) /* Scrollbar event */ 1489 {
1579 { 1490 int row, column;
1580 int pos, len; 1491
1581 1492 pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL);
1582 pos = event->y - (f->display.x->v_scrollbar_width - 2); 1493 XFASTINT (result->x) = column;
1583 x_mouse_x = pos; 1494 XFASTINT (result->y) = row;
1584 len = ((FONT_HEIGHT (f->display.x->font) * f->height) 1495 result->frame = f;
1585 + f->display.x->internal_border_width 1496 }
1586 - (2 * (f->display.x->v_scrollbar_width - 2)));
1587 x_mouse_y = len;
1588
1589 result->kind = scrollbar_click;
1590 result->part = part;
1591 XSET (result->x, Lisp_Int, (f->display.x->top_pos - event->y));
1592 XSET (result->y, Lisp_Int, f->display.x->pixel_height);
1593 result->frame = f;
1594 }
1595 else /* Text Window Event */
1596 {
1597 int row, column;
1598
1599 pixel_to_glyph_coords (f, event->x, event->y, &column, &row, NULL);
1600 result->kind = mouse_click;
1601 XFASTINT (result->x) = column;
1602 XFASTINT (result->y) = row;
1603 result->frame = f;
1604 }
1605 } 1497 }
1606 1498
1607 1499
1608 /* Mouse movement. Rah. 1500 /* Mouse movement. Rah.
1609 1501
1626 1518
1627 /* Where the mouse was last time we reported a mouse event. */ 1519 /* Where the mouse was last time we reported a mouse event. */
1628 static FRAME_PTR last_mouse_frame; 1520 static FRAME_PTR last_mouse_frame;
1629 static XRectangle last_mouse_glyph; 1521 static XRectangle last_mouse_glyph;
1630 1522
1523 /* If the last-checked mouse motion was in a scrollbar, this is that
1524 scrollbar, the part being dragged, and the limits it is moving in.
1525 Otherwise, this is zero. */
1526 static struct scrollbar *last_mouse_bar;
1527 static FRAME_PTR last_mouse_bar_frame;
1528 static enum scrollbar_part last_mouse_part;
1529 static int last_mouse_scroll_range_start;
1530 static int last_mouse_scroll_range_end;
1531
1631 /* This is a hack. We would really prefer that XTmouse_position would 1532 /* This is a hack. We would really prefer that XTmouse_position would
1632 return the time associated with the position it returns, but there 1533 return the time associated with the position it returns, but there
1633 doesn't seem to be any way to wrest the timestamp from the server 1534 doesn't seem to be any way to wrest the timestamp from the server
1634 along with the position query. So, we just keep track of the time 1535 along with the position query. So, we just keep track of the time
1635 of the last movement we received, and return that in hopes that 1536 of the last movement we received, and return that in hopes that
1677 position. This also calls XQueryPointer, which will cause the 1578 position. This also calls XQueryPointer, which will cause the
1678 server to give us another MotionNotify when the mouse moves again. 1579 server to give us another MotionNotify when the mouse moves again.
1679 */ 1580 */
1680 1581
1681 static void 1582 static void
1682 XTmouse_position (f, x, y, time) 1583 XTmouse_position (f, bar, part, x, y, time)
1683 FRAME_PTR *f; 1584 FRAME_PTR *f;
1585 struct scrollbar **bar;
1586 enum scrollbar_part *part;
1684 Lisp_Object *x, *y; 1587 Lisp_Object *x, *y;
1685 unsigned long *time; 1588 unsigned long *time;
1686 { 1589 {
1687 int ix, iy, dummy; 1590 int ix, iy, dummy;
1688 Display *d = x_current_display; 1591 Display *d = x_current_display;
1722 /* When XQueryPointer returns False, the pointer isn't in guess 1625 /* When XQueryPointer returns False, the pointer isn't in guess
1723 anymore, but root is the root window of the frame we should 1626 anymore, but root is the root window of the frame we should
1724 try instead. */ 1627 try instead. */
1725 guess = root; 1628 guess = root;
1726 1629
1727 *f = last_mouse_frame = x_window_to_frame (guess); 1630 if (last_mouse_bar)
1728 if (! *f) 1631 {
1729 *x = *y = Qnil; 1632 *f = last_mouse_bar_frame;
1633 *bar = last_mouse_bar;
1634 *part = last_mouse_part;
1635
1636 if (iy < last_mouse_scroll_range_start)
1637 iy = last_mouse_scroll_range_start;
1638 if (iy > last_mouse_scroll_range_end)
1639 iy = last_mouse_scroll_range_end;
1640 XSETINT (*x, iy - last_mouse_scroll_range_start);
1641 XSETINT (*y, (last_mouse_scroll_range_end
1642 - last_mouse_scroll_range_start));
1643 }
1730 else 1644 else
1731 { 1645 {
1732 pixel_to_glyph_coords (*f, ix, iy, &ix, &iy, &last_mouse_glyph); 1646 *f = last_mouse_frame = x_window_to_frame (guess);
1733 XSET (*x, Lisp_Int, ix); 1647 if (! *f)
1734 XSET (*y, Lisp_Int, iy); 1648 *x = *y = Qnil;
1649 else
1650 {
1651 pixel_to_glyph_coords (*f, ix, iy, &ix, &iy, &last_mouse_glyph);
1652 XSET (*x, Lisp_Int, ix);
1653 XSET (*y, Lisp_Int, iy);
1654 }
1735 } 1655 }
1736 1656
1737 mouse_moved = 0; 1657 mouse_moved = 0;
1658 last_mouse_bar = 0;
1738 1659
1739 /* I don't know how to find the time for the last movement; it seems 1660 /* I don't know how to find the time for the last movement; it seems
1740 like XQueryPointer ought to return it, but it doesn't. So, we'll 1661 like XQueryPointer ought to return it, but it doesn't. So, we'll
1741 return the time of the last MotionNotify event we received. Note 1662 return the time of the last MotionNotify event we received. Note
1742 that the use of motion hints means that this isn't guaranteed to 1663 that the use of motion hints means that this isn't guaranteed to
1748 1669
1749 #else /* ! defined (HAVE_X11) */ 1670 #else /* ! defined (HAVE_X11) */
1750 #define XEvent XKeyPressedEvent 1671 #define XEvent XKeyPressedEvent
1751 #endif /* ! defined (HAVE_X11) */ 1672 #endif /* ! defined (HAVE_X11) */
1752 1673
1674 /* Scrollbar support. */
1675
1676 /* Map an X window that implements a scroll bar to the struct
1677 scrollbar representing it. */
1678 static struct scrollbar *
1679 x_window_to_scrollbar (window_id)
1680 Window window_id;
1681 {
1682 Lisp_Object tail, frame;
1683 struct frame *f;
1684
1685 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
1686 {
1687 struct scrollbar *bar;
1688 Lisp_Object frame = XCONS (tail)->car;
1689
1690 /* All elements of Vframe_list should be frames. */
1691 if (XTYPE (frame) != Lisp_Frame)
1692 abort ();
1693
1694 /* Scan this frame's scrollbar list for a scrollbar with the
1695 right window ID. */
1696 for (bar = XFRAME (frame)->display.x->vertical_scrollbars;
1697 bar;
1698 bar = bar->next)
1699 if (bar->window == window_id)
1700 return bar;
1701 }
1702
1703 return 0;
1704 }
1705
1706
1707 /* Open a new X window to serve as a scrollbar. */
1708 static struct scrollbar *
1709 x_scrollbar_create (frame, top, left, width, height)
1710 FRAME_PTR frame;
1711 int top, left, width, height;
1712 {
1713 struct x_display *d = frame->display.x;
1714
1715 /* We can't signal a malloc error from within redisplay, so call
1716 malloc instead of xmalloc. */
1717 struct scrollbar *bar =
1718 (struct scrollbar *) malloc (sizeof (struct scrollbar));
1719
1720 if (! bar)
1721 return 0;
1722
1723 BLOCK_INPUT;
1724
1725 {
1726 XSetWindowAttributes a;
1727 unsigned long mask;
1728
1729 a.background_pixel = d->background_pixel;
1730 a.border_pixel = d->foreground_pixel;
1731 a.event_mask = (KeyPressMask
1732 | ButtonPressMask | ButtonReleaseMask
1733 | ButtonMotionMask);
1734 a.cursor = x_vertical_scrollbar_cursor;
1735
1736 mask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
1737
1738 bar->window =
1739 XCreateWindow (x_current_display, FRAME_X_WINDOW (frame),
1740
1741 /* Position and size of scrollbar. */
1742 top, left, width, height,
1743
1744 /* Border width, depth, class, and visual. */
1745 1, CopyFromParent, CopyFromParent, CopyFromParent,
1746
1747 /* Attributes. */
1748 mask, &a);
1749 }
1750
1751 bar->frame = frame;
1752 bar->top = top;
1753 bar->left = left;
1754 bar->width = width;
1755 bar->height = height;
1756 bar->start = bar->end = 0;
1757 bar->judge_timestamp = d->judge_timestamp;
1758 bar->dragging = -1;
1759
1760 /* Add bar to its frame's list of scroll bars. */
1761 bar->next = d->vertical_scrollbars;
1762 d->vertical_scrollbars = bar;
1763
1764 XMapWindow (x_current_display, bar->window);
1765
1766 UNBLOCK_INPUT;
1767 }
1768
1769 /* Draw BAR's handle in the proper position. */
1770 static void
1771 x_scrollbar_set_handle (bar, start, end)
1772 struct scrollbar *bar;
1773 int start, end;
1774 {
1775 BLOCK_INPUT;
1776
1777 {
1778 int inside_width = (bar->width
1779 - VERTICAL_SCROLLBAR_LEFT_BORDER
1780 - VERTICAL_SCROLLBAR_RIGHT_BORDER);
1781 int inside_height = (bar->height
1782 - VERTICAL_SCROLLBAR_TOP_BORDER
1783 - VERTICAL_SCROLLBAR_BOTTOM_BORDER);
1784
1785 /* Make sure the values are reasonable, and try to preserve
1786 the distance between start and end. */
1787 if (end < start)
1788 end = start;
1789 if (start < VERTICAL_SCROLLBAR_TOP_BORDER)
1790 {
1791 end = VERTICAL_SCROLLBAR_TOP_BORDER + (end - start);
1792 start = VERTICAL_SCROLLBAR_TOP_BORDER;
1793 }
1794 if (end > bar->height - VERTICAL_SCROLLBAR_BOTTOM_BORDER)
1795 {
1796 start = ((bar->height - VERTICAL_SCROLLBAR_BOTTOM_BORDER)
1797 - (end - start));
1798 end = bar->height - VERTICAL_SCROLLBAR_BOTTOM_BORDER;
1799 }
1800 if (start < VERTICAL_SCROLLBAR_TOP_BORDER)
1801 start = VERTICAL_SCROLLBAR_TOP_BORDER;
1802
1803 /* Draw the empty space above the handle. */
1804 XClearArea (x_current_display, bar->window,
1805
1806 /* x, y, width, height, and exposures. */
1807 VERTICAL_SCROLLBAR_LEFT_BORDER,
1808 VERTICAL_SCROLLBAR_TOP_BORDER,
1809 inside_width + 1, start + 1,
1810 False);
1811
1812 /* Draw the handle itself. */
1813 XFillRectangle (x_current_display, bar->window,
1814 bar->frame->display.x->normal_gc,
1815
1816 /* x, y, width, height */
1817 VERTICAL_SCROLLBAR_LEFT_BORDER, start,
1818 inside_width, (end - start) + 1);
1819
1820
1821 /* Draw the empty space below the handle. */
1822 XClearArea (x_current_display, bar->window,
1823
1824 /* x, y, width, height, and exposures. */
1825 VERTICAL_SCROLLBAR_LEFT_BORDER,
1826 VERTICAL_SCROLLBAR_TOP_BORDER + end,
1827 inside_width + 1, (inside_height - end) + 1,
1828 False);
1829
1830 bar->start = start;
1831 bar->end = end;
1832 }
1833
1834 UNBLOCK_INPUT;
1835 }
1836
1837 /* Remove the scrollbar BAR. */
1838 static void
1839 x_scrollbar_remove (bar)
1840 struct scrollbar *bar;
1841 {
1842 BLOCK_INPUT;
1843
1844 /* Remove bar from the frame's list. */
1845 {
1846 struct scrollbar **ptr;
1847
1848 for (ptr = &bar->frame->display.x->vertical_scrollbars;
1849 *ptr;
1850 ptr = &(*ptr)->next)
1851 if (*ptr == bar)
1852 {
1853 *ptr = bar->next;
1854 break;
1855 }
1856 }
1857
1858 /* Destroy the window. */
1859 XDestroyWindow (x_current_display, bar->window);
1860
1861 /* Free the storage. */
1862 free (bar);
1863
1864 UNBLOCK_INPUT;
1865 }
1866
1867 static void
1868 x_scrollbar_move (bar, top, left, width, height)
1869 struct scrollbar *bar;
1870 int top, left, width, height;
1871 {
1872 BLOCK_INPUT;
1873
1874 {
1875 XWindowChanges wc;
1876 unsigned int mask = 0;
1877
1878 wc.x = left;
1879 wc.y = top;
1880 wc.width = width;
1881 wc.height = height;
1882
1883 if (left != bar->left) mask |= CWX;
1884 if (top != bar->top) mask |= CWY;
1885 if (width != bar->width) mask |= CWWidth;
1886 if (height != bar->height) mask |= CWHeight;
1887
1888 XConfigureWindow (x_current_display, bar->window, mask, &wc);
1889 }
1890
1891 UNBLOCK_INPUT;
1892 }
1893
1894 /* Set BAR to be the vertical scroll bar for WINDOW. Set its handle
1895 to indicate that we are displaying PORTION characters out of a
1896 total of WHOLE characters, starting at POSITION. Return BAR. If
1897 BAR is zero, create a new scrollbar and return a pointer to it. */
1898 static struct scrollbar *
1899 XTset_scrollbar (bar, window, portion, whole, position)
1900 struct scrollbar *bar;
1901 struct window *window;
1902 int portion, whole, position;
1903 {
1904 FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
1905 struct x_display *d = f->display.x;
1906 int top = XINT (window->top);
1907 int left = WINDOW_VERTICAL_SCROLLBAR_COLUMN (window);
1908 int height = WINDOW_VERTICAL_SCROLLBAR_HEIGHT (window);
1909
1910 /* Where should this scrollbar be, pixelwise? */
1911 int pixel_top = (d->internal_border_width + top * FONT_HEIGHT (d->font));
1912 int pixel_left = (d->internal_border_width + left * FONT_WIDTH (d->font));
1913 int pixel_width = VERTICAL_SCROLLBAR_PIXEL_WIDTH (f);
1914 int pixel_height = VERTICAL_SCROLLBAR_PIXEL_HEIGHT (f, height);
1915
1916 /* Does the scrollbar exist yet? */
1917 if (! bar)
1918 bar = x_scrollbar_create (f,
1919 pixel_top, pixel_left,
1920 pixel_width, pixel_height);
1921 else
1922 /* It may just need to be moved and resized. */
1923 x_scrollbar_move (bar, pixel_top, pixel_left, pixel_width, pixel_height);
1924
1925 /* Set the scrollbar's current state, unless we're currently being
1926 dragged. */
1927
1928 if (bar && bar->dragging == -1)
1929 {
1930 int inside_height = (pixel_height
1931 - VERTICAL_SCROLLBAR_TOP_BORDER
1932 - VERTICAL_SCROLLBAR_BOTTOM_BORDER);
1933 int start = (position * inside_height) / whole;
1934 int end = ((position + portion) * inside_height) / whole;
1935
1936 x_scrollbar_set_handle (bar, start, end);
1937 }
1938
1939 return bar;
1940 }
1941
1942 /* The following three hooks are used when we're doing a thorough
1943 redisplay of the frame. We don't explicitly know which scrollbars
1944 are going to be deleted, because keeping track of when windows go
1945 away is a real pain - can you say set-window-configuration?
1946 Instead, we just assert at the beginning of redisplay that *all*
1947 scrollbars are to be removed, and then save scrollbars from the
1948 firey pit when we actually redisplay their window. */
1949
1950 /* Arrange for all scrollbars on FRAME to be removed at the next call
1951 to `*judge_scrollbars_hook'. A scrollbar may be spared if
1952 `*redeem_scrollbar_hook' is applied to it before the judgement. */
1953 static void
1954 XTcondemn_scrollbars (frame)
1955 FRAME_PTR frame;
1956 {
1957 /* Any scrollbars which don't get caught up to this will be deleted. */
1958 frame->display.x->judge_timestamp++;
1959 }
1960
1961 /* Unmark BAR for deletion in this judgement cycle. */
1962 static void
1963 XTredeem_scrollbar (bar)
1964 struct scrollbar *bar;
1965 {
1966 bar->judge_timestamp = bar->frame->display.x->judge_timestamp;
1967 }
1968
1969 /* Remove all scrollbars on FRAME that haven't been saved since the
1970 last call to `*condemn_scrollbars_hook'. */
1971 static void
1972 XTjudge_scrollbars(frame)
1973 FRAME_PTR frame;
1974 {
1975 int judge_timestamp = frame->display.x->judge_timestamp;
1976 struct scrollbar *bar, *next;
1977
1978 for (bar = frame->display.x->vertical_scrollbars; bar; bar = next)
1979 {
1980 next = bar->next;
1981 if (bar->judge_timestamp < judge_timestamp)
1982 x_scrollbar_remove (bar);
1983 }
1984 }
1985
1986
1987 /* Handle an Expose or GraphicsExpose event on a scrollbar. */
1988 static void
1989 x_scrollbar_expose (bar, event)
1990 struct scrollbar *bar;
1991 XEvent *event;
1992 {
1993 BLOCK_INPUT;
1994
1995 x_scrollbar_set_handle (bar, bar->start, bar->end);
1996
1997 /* Draw the extra-thick border on the right. */
1998 XFillRectangle (x_current_display, bar->window,
1999 bar->frame->display.x->normal_gc,
2000
2001 /* x, y, width, height */
2002 bar->width - VERTICAL_SCROLLBAR_RIGHT_BORDER, 0,
2003 VERTICAL_SCROLLBAR_RIGHT_BORDER, bar->height + 1);
2004
2005 UNBLOCK_INPUT;
2006 }
2007
2008 /* Handle an exposure event which might be over the extra scrollbar space. */
2009 static void
2010 x_scrollbar_background_expose (frame, event)
2011 FRAME_PTR frame;
2012 XEvent *event;
2013 {
2014 /* Where is the extra scrollbar space, anyway? */
2015 int width = VERTICAL_SCROLLBAR_PIXEL_WIDTH (frame);
2016 int height = PIXEL_HEIGHT (frame);
2017 int x = PIXEL_WIDTH (frame) - width;
2018 int y = 0;
2019
2020 BLOCK_INPUT;
2021
2022 /* Clear it out. */
2023 XClearArea (x_current_display, FRAME_X_WINDOW (frame),
2024
2025 /* x, y, width, height, expose */
2026 x, y, width+1, height+1, False);
2027
2028 /* Draw the border. */
2029 XDrawRectangle (x_current_display, FRAME_X_WINDOW (frame),
2030 frame->display.x->normal_gc,
2031 x, y, width, height);
2032
2033 /* Draw the extra-thick border on the right edge. */
2034 XFillRectangle (x_current_display, FRAME_X_WINDOW (frame),
2035 frame->display.x->normal_gc,
2036 x + width - VERTICAL_SCROLLBAR_RIGHT_BORDER, 0,
2037 VERTICAL_SCROLLBAR_RIGHT_BORDER, height + 1);
2038
2039 UNBLOCK_INPUT;
2040 }
2041
2042 /* Handle a mouse click on the scrollbar BAR. If *EMACS_EVENT's kind
2043 is set to something other than no_event, it is enqueued. */
2044 static void
2045 x_scrollbar_handle_click (bar, event, emacs_event)
2046 struct scrollbar *bar;
2047 XEvent *event;
2048 struct input_event *emacs_event;
2049 {
2050 emacs_event->kind = scrollbar_click;
2051 XSETINT (emacs_event->code, event->xbutton.button - Button1);
2052 emacs_event->modifiers =
2053 (x_convert_modifiers (event->xbutton.state)
2054 | (event->type == ButtonRelease
2055 ? up_modifier
2056 : down_modifier));
2057 emacs_event->part =
2058 ((event->xbutton.x < bar->start) ? scrollbar_above_handle
2059 : (event->xbutton.x < bar->end) ? scrollbar_handle
2060 : scrollbar_below_handle);
2061 emacs_event->scrollbar = bar;
2062
2063 if (event->xbutton.y < VERTICAL_SCROLLBAR_TOP_BORDER)
2064 event->xbutton.y = VERTICAL_SCROLLBAR_TOP_BORDER;
2065 if (event->xbutton.y > bar->height - VERTICAL_SCROLLBAR_BOTTOM_BORDER)
2066 event->xbutton.y = bar->height - VERTICAL_SCROLLBAR_BOTTOM_BORDER;
2067 XSETINT (emacs_event->x,
2068 event->xbutton.y - VERTICAL_SCROLLBAR_TOP_BORDER);
2069 XSETINT (emacs_event->y,
2070 (bar->height
2071 - VERTICAL_SCROLLBAR_TOP_BORDER
2072 - VERTICAL_SCROLLBAR_BOTTOM_BORDER));
2073
2074 emacs_event->frame = bar->frame;
2075 emacs_event->timestamp = event->xbutton.time;
2076
2077 if (event->type == ButtonPress
2078 && emacs_event->part == scrollbar_handle)
2079 bar->dragging = event->xbutton.x - bar->start;
2080 else
2081 {
2082 int new_start = event->xbutton.x - bar->dragging;
2083 int new_end = new_start + (bar->end - bar->start);
2084
2085 x_scrollbar_set_handle (bar, new_start, new_end);
2086 bar->dragging = -1;
2087 }
2088 }
2089
2090
2091 /* Handle some mouse motion while someone is dragging the scrollbar. */
2092 static void
2093 x_scrollbar_handle_motion (bar, event)
2094 struct scrollbar *bar;
2095 XEvent *event;
2096 {
2097 last_mouse_movement_time = event->xmotion.time;
2098
2099 mouse_moved = 1;
2100 last_mouse_bar = bar;
2101 last_mouse_bar_frame = bar->frame;
2102 last_mouse_part = (bar->dragging == -1 ? scrollbar_handle
2103 : (event->xbutton.x < bar->start) ? scrollbar_above_handle
2104 : (event->xbutton.x < bar->end) ? scrollbar_handle
2105 : scrollbar_below_handle);
2106 last_mouse_scroll_range_start = bar->top + VERTICAL_SCROLLBAR_TOP_BORDER;
2107 last_mouse_scroll_range_end = (bar->top
2108 + bar->height
2109 - VERTICAL_SCROLLBAR_BOTTOM_BORDER);
2110
2111 /* If we're dragging the bar, display it. */
2112 if (bar->dragging != -1)
2113 {
2114 /* Where should the handle be now? */
2115 int new_start = event->xmotion.x - bar->dragging;
2116
2117 if (new_start != bar->start)
2118 {
2119 int new_end = new_start + (bar->end - bar->start);
2120
2121 x_scrollbar_set_handle (bar, new_start, new_end);
2122 }
2123 }
2124
2125 /* Call XQueryPointer so we'll get an event the next time the mouse
2126 moves and we can see *still* on the same position. */
2127 {
2128 int dummy;
2129
2130 XQueryPointer (event->xmotion.display, event->xmotion.window,
2131 (Window *) &dummy, (Window *) &dummy,
2132 &dummy, &dummy, &dummy, &dummy,
2133 (unsigned int *) &dummy);
2134 }
2135 }
2136
2137
2138
2139 /* The main X event-reading loop - XTread_socket. */
1753 2140
1754 /* Timestamp of enter window event. This is only used by XTread_socket, 2141 /* Timestamp of enter window event. This is only used by XTread_socket,
1755 but we have to put it out here, since static variables within functions 2142 but we have to put it out here, since static variables within functions
1756 sometimes don't work. */ 2143 sometimes don't work. */
1757 static Time enter_timestamp; 2144 static Time enter_timestamp;
1929 f->async_visible = 1; 2316 f->async_visible = 1;
1930 f->async_iconified = 0; 2317 f->async_iconified = 0;
1931 SET_FRAME_GARBAGED (f); 2318 SET_FRAME_GARBAGED (f);
1932 } 2319 }
1933 else 2320 else
1934 dumprectangle (x_window_to_frame (event.xexpose.window), 2321 {
1935 event.xexpose.x, event.xexpose.y, 2322 dumprectangle (x_window_to_frame (event.xexpose.window),
1936 event.xexpose.width, event.xexpose.height); 2323 event.xexpose.x, event.xexpose.y,
2324 event.xexpose.width, event.xexpose.height);
2325 x_scrollbar_background_expose (f, &event);
2326 }
2327 }
2328 else
2329 {
2330 struct scrollbar *bar
2331 = x_window_to_scrollbar (event.xexpose.window);
2332
2333 if (bar)
2334 x_scrollbar_expose (bar, &event);
1937 } 2335 }
1938 break; 2336 break;
1939 2337
1940 case GraphicsExpose: /* This occurs when an XCopyArea's 2338 case GraphicsExpose: /* This occurs when an XCopyArea's
1941 source area was obscured or not 2339 source area was obscured or not
1942 available.*/ 2340 available.*/
1943 dumprectangle (x_window_to_frame (event.xgraphicsexpose.drawable), 2341 f = x_window_to_frame (event.xgraphicsexpose.drawable);
1944 event.xgraphicsexpose.x, event.xgraphicsexpose.y, 2342 if (f)
1945 event.xgraphicsexpose.width, 2343 {
1946 event.xgraphicsexpose.height); 2344 dumprectangle (f,
2345 event.xgraphicsexpose.x, event.xgraphicsexpose.y,
2346 event.xgraphicsexpose.width,
2347 event.xgraphicsexpose.height);
2348 x_scrollbar_background_expose (f, &event);
2349 }
1947 break; 2350 break;
1948 2351
1949 case NoExpose: /* This occurs when an XCopyArea's 2352 case NoExpose: /* This occurs when an XCopyArea's
1950 source area was completely 2353 source area was completely
1951 available */ 2354 available */
1998 abort (); 2401 abort ();
1999 #endif /* ! defined (HAVE_X11) */ 2402 #endif /* ! defined (HAVE_X11) */
2000 2403
2001 #ifdef HAVE_X11 2404 #ifdef HAVE_X11
2002 case UnmapNotify: 2405 case UnmapNotify:
2003 { 2406 f = x_window_to_frame (event.xunmap.window);
2004 XWMHints *hints; 2407 if (f) /* F may no longer exist if
2005
2006 f = x_window_to_frame (event.xunmap.window);
2007 if (f) /* F may no longer exist if
2008 the frame was deleted. */ 2408 the frame was deleted. */
2009 { 2409 {
2010 /* While a frame is unmapped, display generation is 2410 /* While a frame is unmapped, display generation is
2011 disabled; you don't want to spend time updating a 2411 disabled; you don't want to spend time updating a
2012 display that won't ever be seen. */ 2412 display that won't ever be seen. */
2013 f->async_visible = 0; 2413 f->async_visible = 0;
2014 x_mouse_x = x_mouse_y = -1; 2414 }
2015 }
2016 }
2017 break; 2415 break;
2018 2416
2019 case MapNotify: 2417 case MapNotify:
2020 f = x_window_to_frame (event.xmap.window); 2418 f = x_window_to_frame (event.xmap.window);
2021 if (f) 2419 if (f)
2044 #endif /* ! defined (HAVE_X11) */ 2442 #endif /* ! defined (HAVE_X11) */
2045 2443
2046 #ifdef HAVE_X11 2444 #ifdef HAVE_X11
2047 case KeyPress: 2445 case KeyPress:
2048 f = x_window_to_frame (event.xkey.window); 2446 f = x_window_to_frame (event.xkey.window);
2447
2049 if (f != 0) 2448 if (f != 0)
2050 { 2449 {
2051 KeySym keysym; 2450 KeySym keysym;
2052 char copy_buffer[80]; 2451 char copy_buffer[80];
2053 int modifiers = event.xkey.state; 2452 int modifiers = event.xkey.state;
2163 } 2562 }
2164 break; 2563 break;
2165 #endif /* ! defined (HAVE_X11) */ 2564 #endif /* ! defined (HAVE_X11) */
2166 2565
2167 #ifdef HAVE_X11 2566 #ifdef HAVE_X11
2567
2568 /* Here's a possible interpretation of the whole
2569 FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a
2570 FocusIn event, you have to get a FocusOut event before you
2571 relinquish the focus. If you haven't received a FocusIn event,
2572 then a mere LeaveNotify is enough to free you. */
2573
2168 case EnterNotify: 2574 case EnterNotify:
2169 f = x_window_to_frame (event.xcrossing.window); 2575 f = x_window_to_frame (event.xcrossing.window);
2170 2576
2171 if (event.xcrossing.detail == NotifyInferior) /* Left Scrollbar */ 2577 if (event.xcrossing.focus) /* Entered Window */
2172 ;
2173 else if (event.xcrossing.focus) /* Entered Window */
2174 { 2578 {
2175 /* If we decide we want to generate an event to be seen
2176 by the rest of Emacs, we put it here. */
2177 struct input_event emacs_event;
2178 emacs_event.kind = no_event;
2179
2180 /* Avoid nasty pop/raise loops. */ 2579 /* Avoid nasty pop/raise loops. */
2181 if (f && (!(f->auto_raise) 2580 if (f && (!(f->auto_raise)
2182 || !(f->auto_lower) 2581 || !(f->auto_lower)
2183 || (event.xcrossing.time - enter_timestamp) > 500)) 2582 || (event.xcrossing.time - enter_timestamp) > 500))
2184 { 2583 {
2185 x_new_focus_frame (f); 2584 x_new_focus_frame (f);
2186 enter_timestamp = event.xcrossing.time; 2585 enter_timestamp = event.xcrossing.time;
2187 } 2586 }
2188 #if 0
2189 else if ((f = x_window_to_scrollbar (event.xcrossing.window,
2190 &part, &prefix)))
2191 /* Fake a motion event */
2192 notice_mouse_movement (&emacs_event,
2193 event.xmotion, f, scrollbar_window,
2194 part);
2195 #endif /* ! 0 */
2196
2197 #if 0
2198 if (! EQ (Vx_send_mouse_movement_events, Qnil)
2199 && numchars >= 1
2200 && emacs_event.kind != no_event)
2201 {
2202 bcopy (&emacs_event, bufp, sizeof (struct input_event));
2203 bufp++;
2204 count++;
2205 numchars--;
2206 }
2207 #endif /* ! 0 */
2208 } 2587 }
2209 else if (f == x_focus_frame) 2588 else if (f == x_focus_frame)
2210 x_new_focus_frame (0); 2589 x_new_focus_frame (0);
2211 #if 0
2212 else if (f = x_window_to_frame (event.xcrossing.window))
2213 x_mouse_frame = f;
2214 #endif /* ! 0 */
2215 2590
2216 break; 2591 break;
2217 2592
2218 case FocusIn: 2593 case FocusIn:
2219 f = x_window_to_frame (event.xfocus.window); 2594 f = x_window_to_frame (event.xfocus.window);
2595 if (event.xfocus.detail != NotifyPointer)
2596 x_focus_event_frame = f;
2220 if (f) 2597 if (f)
2221 x_new_focus_frame (f); 2598 x_new_focus_frame (f);
2222 break; 2599 break;
2223 2600
2601
2224 case LeaveNotify: 2602 case LeaveNotify:
2225 if (event.xcrossing.detail != NotifyInferior 2603 f = x_window_to_frame (event.xcrossing.window);
2226 && event.xcrossing.subwindow == None 2604
2227 && event.xcrossing.mode == NotifyNormal) 2605 if (event.xcrossing.focus)
2228 { 2606 {
2229 f = x_window_to_frame (event.xcrossing.window); 2607 if (! x_focus_event_frame)
2230 2608 x_new_focus_frame (0);
2231 if (event.xcrossing.focus) 2609 else
2232 x_new_focus_frame (f); 2610 x_new_focus_frame (f);
2233 else if (f == x_focus_frame) 2611 }
2612 else
2613 {
2614 if (f == x_focus_event_frame)
2615 x_focus_event_frame = 0;
2616 if (f == x_focus_frame)
2234 x_new_focus_frame (0); 2617 x_new_focus_frame (0);
2235 } 2618 }
2236 break; 2619 break;
2237 2620
2238 case FocusOut: 2621 case FocusOut:
2239 f = x_window_to_frame (event.xfocus.window); 2622 f = x_window_to_frame (event.xfocus.window);
2623 if (event.xfocus.detail != NotifyPointer
2624 && f == x_focus_event_frame)
2625 x_focus_event_frame = 0;
2240 if (f && f == x_focus_frame) 2626 if (f && f == x_focus_frame)
2241 x_new_focus_frame (0); 2627 x_new_focus_frame (0);
2242 break; 2628 break;
2243 2629
2244 #else /* ! defined (HAVE_X11) */ 2630 #else /* ! defined (HAVE_X11) */
2281 case MotionNotify: 2667 case MotionNotify:
2282 { 2668 {
2283 f = x_window_to_frame (event.xmotion.window); 2669 f = x_window_to_frame (event.xmotion.window);
2284 if (f) 2670 if (f)
2285 note_mouse_position (f, &event.xmotion); 2671 note_mouse_position (f, &event.xmotion);
2286 #if 0 2672 else
2287 else if ((f = x_window_to_scrollbar (event.xmotion.window,
2288 &part, &prefix)))
2289 { 2673 {
2290 What should go here? 2674 struct scrollbar *bar =
2675 x_window_to_scrollbar (event.xmotion.window);
2676
2677 if (bar)
2678 x_scrollbar_handle_motion (bar, &event);
2291 } 2679 }
2292 #endif /* ! 0 */
2293 } 2680 }
2294 break; 2681 break;
2295 2682
2296 case ConfigureNotify: 2683 case ConfigureNotify:
2297 { 2684 {
2298 int rows, columns; 2685 int rows, columns;
2299 f = x_window_to_frame (event.xconfigure.window); 2686 f = x_window_to_frame (event.xconfigure.window);
2300 if (!f) 2687 if (!f)
2301 break; 2688 break;
2302 2689
2303 columns = ((event.xconfigure.width - 2690 columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width);
2304 (2 * f->display.x->internal_border_width) 2691 rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height);
2305 - f->display.x->v_scrollbar_width)
2306 / FONT_WIDTH (f->display.x->font));
2307 rows = ((event.xconfigure.height -
2308 (2 * f->display.x->internal_border_width)
2309 - f->display.x->h_scrollbar_height)
2310 / FONT_HEIGHT (f->display.x->font));
2311 2692
2312 /* Even if the number of character rows and columns has 2693 /* Even if the number of character rows and columns has
2313 not changed, the font size may have changed, so we need 2694 not changed, the font size may have changed, so we need
2314 to check the pixel dimensions as well. */ 2695 to check the pixel dimensions as well. */
2315 if (columns != f->width 2696 if (columns != f->width
2316 || rows != f->height 2697 || rows != f->height
2317 || event.xconfigure.width != f->display.x->pixel_width 2698 || event.xconfigure.width != f->display.x->pixel_width
2318 || event.xconfigure.height != f->display.x->pixel_height) 2699 || event.xconfigure.height != f->display.x->pixel_height)
2319 { 2700 {
2320 change_frame_size (f, rows, columns, 0, 1); 2701 change_frame_size (f, rows, columns, 0, 1);
2321 x_resize_scrollbars (f);
2322 SET_FRAME_GARBAGED (f); 2702 SET_FRAME_GARBAGED (f);
2323 } 2703 }
2324 2704
2325 f->display.x->pixel_width = event.xconfigure.width; 2705 f->display.x->pixel_width = event.xconfigure.width;
2326 f->display.x->pixel_height = event.xconfigure.height; 2706 f->display.x->pixel_height = event.xconfigure.height;
2337 struct input_event emacs_event; 2717 struct input_event emacs_event;
2338 emacs_event.kind = no_event; 2718 emacs_event.kind = no_event;
2339 2719
2340 f = x_window_to_frame (event.xbutton.window); 2720 f = x_window_to_frame (event.xbutton.window);
2341 if (f) 2721 if (f)
2342 if (!x_focus_frame || (f == x_focus_frame)) 2722 {
2343 construct_mouse_click (&emacs_event, 2723 if (!x_focus_frame || (f == x_focus_frame))
2344 &event, f, Qnil, 0); 2724 construct_mouse_click (&emacs_event,
2345 else 2725 &event, f, Qnil, 0);
2346 continue; 2726 }
2347 else 2727 else
2348 if ((f = x_window_to_scrollbar (event.xbutton.window, 2728 {
2349 &part, &prefix))) 2729 struct scrollbar *bar =
2350 { 2730 x_window_to_scrollbar (event.xbutton.window);
2351 if (!x_focus_frame || (selected_frame == x_focus_frame)) 2731
2352 construct_mouse_click (&emacs_event, 2732 if (bar)
2353 &event, f, part, prefix); 2733 x_scrollbar_handle_click (bar, &event, &emacs_event);
2354 else 2734 }
2355 continue;
2356 }
2357 2735
2358 if (numchars >= 1 && emacs_event.kind != no_event) 2736 if (numchars >= 1 && emacs_event.kind != no_event)
2359 { 2737 {
2360 bcopy (&emacs_event, bufp, sizeof (struct input_event)); 2738 bcopy (&emacs_event, bufp, sizeof (struct input_event));
2361 bufp++; 2739 bufp++;
2450 kill (getpid (), SIGHUP); 2828 kill (getpid (), SIGHUP);
2451 } 2829 }
2452 #endif /* ! defined (HAVE_SELECT) */ 2830 #endif /* ! defined (HAVE_SELECT) */
2453 #endif /* ! 0 */ 2831 #endif /* ! 0 */
2454 2832
2833 #ifndef HAVE_X11
2455 if (updating_frame == 0) 2834 if (updating_frame == 0)
2456 x_do_pending_expose (); 2835 x_do_pending_expose ();
2836 #endif
2457 2837
2458 UNBLOCK_INPUT; 2838 UNBLOCK_INPUT;
2459 return count; 2839 return count;
2460 } 2840 }
2461 2841
2523 } 2903 }
2524 } 2904 }
2525 #endif /* HAVE_X11 */ 2905 #endif /* HAVE_X11 */
2526 2906
2527 2907
2908 /* Drawing the cursor. */
2909
2910
2528 /* Draw a hollow box cursor. Don't change the inside of the box. */ 2911 /* Draw a hollow box cursor. Don't change the inside of the box. */
2529 2912
2530 static void 2913 static void
2531 x_draw_box (f) 2914 x_draw_box (f)
2532 struct frame *f; 2915 struct frame *f;
2571 clear_cursor (f) 2954 clear_cursor (f)
2572 struct frame *f; 2955 struct frame *f;
2573 { 2956 {
2574 int mask; 2957 int mask;
2575 2958
2576 if (! f->visible 2959 if (! FRAME_VISIBLE_P (f)
2577 || f->phys_cursor_x < 0) 2960 || f->phys_cursor_x < 0)
2578 return; 2961 return;
2579 2962
2580 #ifdef HAVE_X11 2963 #ifdef HAVE_X11
2581 x_display_cursor (f, 0); 2964 x_display_cursor (f, 0);
2606 register int phys_y = f->phys_cursor_y; 2989 register int phys_y = f->phys_cursor_y;
2607 register int x1; 2990 register int x1;
2608 register int y1; 2991 register int y1;
2609 register int y2; 2992 register int y2;
2610 2993
2611 if (! f->visible || (! on && f->phys_cursor_x < 0)) 2994 if (! FRAME_VISIBLE_P (f) || (! on && f->phys_cursor_x < 0))
2612 return; 2995 return;
2613 2996
2614 #ifdef HAVE_X11 2997 #ifdef HAVE_X11
2615 if (phys_x >= 0 && 2998 if (phys_x >= 0 &&
2616 (!on || phys_x != f->cursor_x || phys_y != f->cursor_y)) 2999 (!on || phys_x != f->cursor_x || phys_y != f->cursor_y))
2683 { 3066 {
2684 curs_x = FRAME_CURSOR_X (f); 3067 curs_x = FRAME_CURSOR_X (f);
2685 curs_y = FRAME_CURSOR_Y (f); 3068 curs_y = FRAME_CURSOR_Y (f);
2686 } 3069 }
2687 3070
2688 if (! f->visible) 3071 if (! FRAME_VISIBLE_P (f))
2689 return; 3072 return;
2690 3073
2691 /* If cursor is off and we want it off, return quickly. */ 3074 /* If cursor is off and we want it off, return quickly. */
2692 if (!on && f->phys_cursor_x < 0) 3075 if (!on && f->phys_cursor_x < 0)
2693 return; 3076 return;
2948 Display *display; 3331 Display *display;
2949 XErrorEvent *error; 3332 XErrorEvent *error;
2950 { 3333 {
2951 char buf[256]; 3334 char buf[256];
2952 3335
3336 /* While we're testing Emacs 19, we'll just dump core whenever we
3337 get an X error, so we can figure out why it happened. */
3338 abort ();
3339
2953 /* Note that there is no real way portable across R3/R4 to get the 3340 /* Note that there is no real way portable across R3/R4 to get the
2954 original error handler. */ 3341 original error handler. */
2955 3342
2956 XGetErrorText (display, error->error_code, buf, sizeof (buf)); 3343 XGetErrorText (display, error->error_code, buf, sizeof (buf));
2957 fprintf (stderr, "X protocol error: %s on protocol request %d\n", 3344 fprintf (stderr, "X protocol error: %s on protocol request %d\n",
3039 fprintf (stderr, "Lib call: %d\n", ++x_wire_count); 3426 fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
3040 } 3427 }
3041 #endif /* ! 0 */ 3428 #endif /* ! 0 */
3042 3429
3043 3430
3431 /* Changing the font of the frame. */
3432
3044 /* Set the font of the x-window specified by frame F 3433 /* Set the font of the x-window specified by frame F
3045 to the font named NEWNAME. This is safe to use 3434 to the font named NEWNAME. This is safe to use
3046 even before F has an actual x-window. */ 3435 even before F has an actual x-window. */
3047 3436
3048 #ifdef HAVE_X11 3437 #ifdef HAVE_X11
3169 3558
3170 return 0; 3559 return 0;
3171 } 3560 }
3172 #endif /* ! defined (HAVE_X11) */ 3561 #endif /* ! defined (HAVE_X11) */
3173 3562
3563 /* X Window sizes and positions. */
3564
3174 x_calc_absolute_position (f) 3565 x_calc_absolute_position (f)
3175 struct frame *f; 3566 struct frame *f;
3176 { 3567 {
3177 #ifdef HAVE_X11 3568 #ifdef HAVE_X11
3178 if (f->display.x->left_pos < 0) 3569 if (f->display.x->left_pos < 0)
3225 int ibw = f->display.x->internal_border_width; 3616 int ibw = f->display.x->internal_border_width;
3226 3617
3227 BLOCK_INPUT; 3618 BLOCK_INPUT;
3228 3619
3229 check_frame_size (f, &rows, &cols); 3620 check_frame_size (f, &rows, &cols);
3230 pixelwidth = (cols * FONT_WIDTH (f->display.x->font) + 2 * ibw 3621 f->display.x->vertical_scrollbar_extra =
3231 + f->display.x->v_scrollbar_width); 3622 (FRAME_HAS_VERTICAL_SCROLLBARS (f)
3232 pixelheight = (rows * FONT_HEIGHT (f->display.x->font) + 2 * ibw 3623 ? VERTICAL_SCROLLBAR_PIXEL_WIDTH (f)
3233 + f->display.x->h_scrollbar_height); 3624 : 0);
3625 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
3626 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
3234 3627
3235 #ifdef HAVE_X11 3628 #ifdef HAVE_X11
3236 x_wm_set_size_hint (f, 0); 3629 x_wm_set_size_hint (f, 0);
3237 #endif /* ! defined (HAVE_X11) */ 3630 #endif /* ! defined (HAVE_X11) */
3238 XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight); 3631 XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
3259 2 * f->display.x->internal_border_width, 3652 2 * f->display.x->internal_border_width,
3260 FONT_WIDTH (f->display.x->font), FONT_HEIGHT (f->display.x->font)); 3653 FONT_WIDTH (f->display.x->font), FONT_HEIGHT (f->display.x->font));
3261 } 3654 }
3262 #endif /* HAVE_X11 */ 3655 #endif /* HAVE_X11 */
3263 3656
3657 /* Mouse warping, focus shifting, raising and lowering. */
3264 3658
3265 x_set_mouse_position (f, x, y) 3659 x_set_mouse_position (f, x, y)
3266 struct frame *f; 3660 struct frame *f;
3267 int x, y; 3661 int x, y;
3268 { 3662 {
3269 int pix_x, pix_y; 3663 int pix_x, pix_y;
3270 3664
3271 x_raise_frame (f); 3665 x_raise_frame (f);
3272 3666
3273 if (x < 0) 3667 pix_x = (f->display.x->internal_border_width
3274 pix_x = (FRAME_WIDTH (f) 3668 + x * FONT_WIDTH (f->display.x->font)
3275 * FONT_WIDTH (f->display.x->font) 3669 + FONT_WIDTH (f->display.x->font) / 2);
3276 + 2 * f->display.x->internal_border_width 3670 pix_y = (f->display.x->internal_border_width
3277 + f->display.x->v_scrollbar_width) / 2; 3671 + y * FONT_HEIGHT (f->display.x->font)
3278 else 3672 + FONT_HEIGHT (f->display.x->font) / 2);
3279 pix_x = x * FONT_WIDTH (f->display.x->font) + 2; /* add 2 pixels to each 3673
3280 dimension to move the 3674 if (pix_x < 0) pix_x = 0;
3281 mouse into the char 3675 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
3282 cell */ 3676
3283 3677 if (pix_y < 0) pix_y = 0;
3284 if (y < 0) 3678 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
3285 pix_y = (FRAME_HEIGHT (f)
3286 * FONT_HEIGHT (f->display.x->font)
3287 + 2 * f->display.x->internal_border_width
3288 + f->display.x->h_scrollbar_height) / 2;
3289 else
3290 pix_y = y * FONT_HEIGHT (f->display.x->font) + 2;
3291 3679
3292 BLOCK_INPUT; 3680 BLOCK_INPUT;
3293 x_mouse_x = x;
3294 x_mouse_y = y;
3295 3681
3296 XWarpMousePointer (FRAME_X_WINDOW (f), pix_x, pix_y); 3682 XWarpMousePointer (FRAME_X_WINDOW (f), pix_x, pix_y);
3297 UNBLOCK_INPUT; 3683 UNBLOCK_INPUT;
3298 } 3684 }
3299 3685
3366 #ifdef HAVE_X11 3752 #ifdef HAVE_X11
3367 if (! EQ (Vx_no_window_manager, Qt)) 3753 if (! EQ (Vx_no_window_manager, Qt))
3368 x_wm_set_window_state (f, NormalState); 3754 x_wm_set_window_state (f, NormalState);
3369 3755
3370 XMapWindow (XDISPLAY FRAME_X_WINDOW (f)); 3756 XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
3371 if (f->display.x->v_scrollbar != 0 || f->display.x->h_scrollbar != 0) 3757 if (FRAME_HAS_VERTICAL_SCROLLBARS (f))
3372 XMapSubwindows (x_current_display, FRAME_X_WINDOW (f)); 3758 XMapSubwindows (x_current_display, FRAME_X_WINDOW (f));
3373 #else /* ! defined (HAVE_X11) */ 3759 #else /* ! defined (HAVE_X11) */
3374 XMapWindow (XDISPLAY FRAME_X_WINDOW (f)); 3760 XMapWindow (XDISPLAY FRAME_X_WINDOW (f));
3375 if (f->display.x->icon_desc != 0) 3761 if (f->display.x->icon_desc != 0)
3376 XUnmapWindow (f->display.x->icon_desc); 3762 XUnmapWindow (f->display.x->icon_desc);
3533 x_focus_frame = 0; 3919 x_focus_frame = 0;
3534 if (f == x_highlight_frame) 3920 if (f == x_highlight_frame)
3535 x_highlight_frame = 0; 3921 x_highlight_frame = 0;
3536 } 3922 }
3537 3923
3924 /* Manage event queues for X10. */
3925
3538 #ifndef HAVE_X11 3926 #ifndef HAVE_X11
3539 3927
3540 /* Manage event queues. 3928 /* Manage event queues.
3541 3929
3542 This code is only used by the X10 support. 3930 This code is only used by the X10 support.
3605 { 3993 {
3606 return queue_event_count (&x_mouse_queue); 3994 return queue_event_count (&x_mouse_queue);
3607 } 3995 }
3608 #endif /* HAVE_X11 */ 3996 #endif /* HAVE_X11 */
3609 3997
3998 /* Setting window manager hints. */
3999
3610 #ifdef HAVE_X11 4000 #ifdef HAVE_X11
3611 4001
3612 x_wm_set_size_hint (f, prompting) 4002 x_wm_set_size_hint (f, prompting)
3613 struct frame *f; 4003 struct frame *f;
3614 long prompting; 4004 long prompting;
3624 size_hints.y = f->display.x->top_pos; 4014 size_hints.y = f->display.x->top_pos;
3625 size_hints.height = PIXEL_HEIGHT (f); 4015 size_hints.height = PIXEL_HEIGHT (f);
3626 size_hints.width = PIXEL_WIDTH (f); 4016 size_hints.width = PIXEL_WIDTH (f);
3627 size_hints.width_inc = FONT_WIDTH (f->display.x->font); 4017 size_hints.width_inc = FONT_WIDTH (f->display.x->font);
3628 size_hints.height_inc = FONT_HEIGHT (f->display.x->font); 4018 size_hints.height_inc = FONT_HEIGHT (f->display.x->font);
3629 size_hints.max_width = 4019 size_hints.max_width = PIXEL_TO_CHAR_WIDTH (f, x_screen_width);
3630 (x_screen_width - ((2 * f->display.x->internal_border_width) 4020 size_hints.max_height = PIXEL_TO_CHAR_HEIGHT (f, x_screen_height);
3631 + f->display.x->v_scrollbar_width)); 4021
3632 size_hints.max_height =
3633 (x_screen_height - ((2 * f->display.x->internal_border_width)
3634 + f->display.x->h_scrollbar_height));
3635 { 4022 {
3636 int base_width, base_height; 4023 int base_width, base_height;
3637 4024
3638 base_width = ((2 * f->display.x->internal_border_width) 4025 base_width = CHAR_TO_PIXEL_WIDTH (f, 0);
3639 + f->display.x->v_scrollbar_width); 4026 base_height = CHAR_TO_PIXEL_HEIGHT (f, 0);
3640 base_height = ((2 * f->display.x->internal_border_width)
3641 + f->display.x->h_scrollbar_height);
3642 4027
3643 { 4028 {
3644 int min_rows = 0, min_cols = 0; 4029 int min_rows = 0, min_cols = 0;
3645 check_frame_size (f, &min_rows, &min_cols); 4030 check_frame_size (f, &min_rows, &min_cols);
3646 4031
3729 4114
3730 XSetWMHints (x_current_display, window, &f->display.x->wm_hints); 4115 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
3731 } 4116 }
3732 4117
3733 4118
4119 /* Initialization. */
4120
3734 void 4121 void
3735 x_term_init (display_name) 4122 x_term_init (display_name)
3736 char *display_name; 4123 char *display_name;
3737 { 4124 {
3738 Lisp_Object frame; 4125 Lisp_Object frame;
3782 sprintf (x_id_name, "%s@%s", XSTRING (invocation_name)->data, hostname); 4169 sprintf (x_id_name, "%s@%s", XSTRING (invocation_name)->data, hostname);
3783 } 4170 }
3784 4171
3785 /* Figure out which modifier bits mean what. */ 4172 /* Figure out which modifier bits mean what. */
3786 x_find_modifier_meanings (); 4173 x_find_modifier_meanings ();
3787 4174
4175 /* Get the scrollbar cursor. */
4176 x_vertical_scrollbar_cursor =
4177 XCreateFontCursor (x_current_display, XC_sb_v_double_arrow);
4178
3788 /* Watch for PropertyNotify events on the root window; we use them 4179 /* Watch for PropertyNotify events on the root window; we use them
3789 to figure out when to invalidate our cache of the cut buffers. */ 4180 to figure out when to invalidate our cache of the cut buffers. */
3790 x_watch_cut_buffer_cache (); 4181 x_watch_cut_buffer_cache ();
3791 4182
3792 dup2 (ConnectionNumber (x_current_display), 0); 4183 dup2 (ConnectionNumber (x_current_display), 0);
3837 update_end_hook = XTupdate_end; 4228 update_end_hook = XTupdate_end;
3838 set_terminal_window_hook = XTset_terminal_window; 4229 set_terminal_window_hook = XTset_terminal_window;
3839 read_socket_hook = XTread_socket; 4230 read_socket_hook = XTread_socket;
3840 cursor_to_hook = XTcursor_to; 4231 cursor_to_hook = XTcursor_to;
3841 reassert_line_highlight_hook = XTreassert_line_highlight; 4232 reassert_line_highlight_hook = XTreassert_line_highlight;
4233 mouse_position_hook = XTmouse_position;
3842 frame_rehighlight_hook = XTframe_rehighlight; 4234 frame_rehighlight_hook = XTframe_rehighlight;
3843 mouse_position_hook = XTmouse_position; 4235 set_vertical_scrollbar_hook = XTset_scrollbar;
4236 condemn_scrollbars_hook = XTcondemn_scrollbars;
4237 redeem_scrollbar_hook = XTredeem_scrollbar;
4238 judge_scrollbars_hook = XTjudge_scrollbars;
3844 4239
3845 scroll_region_ok = 1; /* we'll scroll partial frames */ 4240 scroll_region_ok = 1; /* we'll scroll partial frames */
3846 char_ins_del_ok = 0; /* just as fast to write the line */ 4241 char_ins_del_ok = 0; /* just as fast to write the line */
3847 line_ins_del_ok = 1; /* we'll just blt 'em */ 4242 line_ins_del_ok = 1; /* we'll just blt 'em */
3848 fast_clear_end_of_line = 1; /* X does this well */ 4243 fast_clear_end_of_line = 1; /* X does this well */