1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
43 /* Macros max and min defined in lisp.h conflict with those in
44 precompiled header Carbon.h. */
48 #include <Carbon/Carbon.h>
50 #define free unexec_free
52 #define malloc unexec_malloc
54 #define realloc unexec_realloc
56 #define min(a, b) ((a) < (b) ? (a) : (b))
58 #define max(a, b) ((a) > (b) ? (a) : (b))
60 #define init_process emacs_init_process
61 #else /* not MAC_OSX */
62 #include <Quickdraw.h>
63 #include <ToolUtils.h>
67 #include <Resources.h>
69 #include <TextUtils.h>
72 #if defined (__MRC__) || (__MSL__ >= 0x6000)
73 #include <ControlDefinitions.h>
80 #endif /* not MAC_OSX */
94 #include "dispextern.h"
96 #include "termhooks.h"
103 #include "intervals.h"
104 #include "composite.h"
107 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
110 /* Fringe bitmaps. */
112 enum fringe_bitmap_type
115 LEFT_TRUNCATION_BITMAP
,
116 RIGHT_TRUNCATION_BITMAP
,
117 OVERLAY_ARROW_BITMAP
,
118 CONTINUED_LINE_BITMAP
,
119 CONTINUATION_LINE_BITMAP
,
123 /* Bitmap drawn to indicate lines not displaying text if
124 `indicate-empty-lines' is non-nil. */
129 static unsigned char zv_bits
[] = {
130 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
131 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
132 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
133 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
134 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
135 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
136 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
137 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
139 /* An arrow like this: `<-'. */
142 #define left_height 8
143 static unsigned char left_bits
[] = {
144 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
146 /* Right truncation arrow bitmap `->'. */
148 #define right_width 8
149 #define right_height 8
150 static unsigned char right_bits
[] = {
151 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
153 /* Marker for continued lines. */
155 #define continued_width 8
156 #define continued_height 8
157 static unsigned char continued_bits
[] = {
158 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
160 /* Marker for continuation lines. */
162 #define continuation_width 8
163 #define continuation_height 8
164 static unsigned char continuation_bits
[] = {
165 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
167 /* Overlay arrow bitmap. */
173 static unsigned char ov_bits
[] = {
174 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
176 /* A triangular arrow. */
179 static unsigned char ov_bits
[] = {
180 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
183 extern Lisp_Object Qhelp_echo
;
186 /* Non-nil means Emacs uses toolkit scroll bars. */
188 Lisp_Object Vx_toolkit_scroll_bars
;
190 /* If a string, XTread_socket generates an event to display that string.
191 (The display is done in read_char.) */
193 static Lisp_Object help_echo
;
194 static Lisp_Object help_echo_window
;
195 static Lisp_Object help_echo_object
;
196 static int help_echo_pos
;
198 /* Temporary variable for XTread_socket. */
200 static Lisp_Object previous_help_echo
;
202 /* Non-zero means that a HELP_EVENT has been generated since Emacs
205 static int any_help_event_p
;
207 /* Non-zero means autoselect window with the mouse cursor. */
209 int x_autoselect_window_p
;
211 /* Non-zero means draw block and hollow cursor as wide as the glyph
212 under it. For example, if a block cursor is over a tab, it will be
213 drawn as wide as that tab on the display. */
215 int x_stretch_cursor_p
;
217 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
219 int x_use_underline_position_properties
;
221 /* This is a chain of structures for all the X displays currently in
224 struct x_display_info
*x_display_list
;
226 /* This is a list of cons cells, each of the form (NAME
227 . FONT-LIST-CACHE), one for each element of x_display_list and in
228 the same order. NAME is the name of the frame. FONT-LIST-CACHE
229 records previous values returned by x-list-fonts. */
231 Lisp_Object x_display_name_list
;
233 /* This is display since Mac does not support multiple ones. */
234 struct mac_display_info one_mac_display_info
;
236 /* Frame being updated by update_frame. This is declared in term.c.
237 This is set by update_begin and looked at by all the XT functions.
238 It is zero while not inside an update. In that case, the XT
239 functions assume that `selected_frame' is the frame to apply to. */
241 extern struct frame
*updating_frame
;
243 extern int waiting_for_input
;
245 /* This is a frame waiting to be auto-raised, within XTread_socket. */
247 struct frame
*pending_autoraise_frame
;
249 /* Nominal cursor position -- where to draw output.
250 HPOS and VPOS are window relative glyph matrix coordinates.
251 X and Y are window relative pixel coordinates. */
253 struct cursor_pos output_cursor
;
255 /* Non-zero means user is interacting with a toolkit scroll bar. */
257 static int toolkit_scroll_bar_interaction
;
261 Formerly, we used PointerMotionHintMask (in standard_event_mask)
262 so that we would have to call XQueryPointer after each MotionNotify
263 event to ask for another such event. However, this made mouse tracking
264 slow, and there was a bug that made it eventually stop.
266 Simply asking for MotionNotify all the time seems to work better.
268 In order to avoid asking for motion events and then throwing most
269 of them away or busy-polling the server for mouse positions, we ask
270 the server for pointer motion hints. This means that we get only
271 one event per group of mouse movements. "Groups" are delimited by
272 other kinds of events (focus changes and button clicks, for
273 example), or by XQueryPointer calls; when one of these happens, we
274 get another MotionNotify event the next time the mouse moves. This
275 is at least as efficient as getting motion events when mouse
276 tracking is on, and I suspect only negligibly worse when tracking
279 /* Where the mouse was last time we reported a mouse event. */
281 FRAME_PTR last_mouse_frame
;
282 static Rect last_mouse_glyph
;
283 static Lisp_Object last_mouse_press_frame
;
285 /* The scroll bar in which the last X motion event occurred.
287 If the last X motion event occurred in a scroll bar, we set this so
288 XTmouse_position can know whether to report a scroll bar motion or
291 If the last X motion event didn't occur in a scroll bar, we set
292 this to Qnil, to tell XTmouse_position to return an ordinary motion
295 static Lisp_Object last_mouse_scroll_bar
;
297 /* This is a hack. We would really prefer that XTmouse_position would
298 return the time associated with the position it returns, but there
299 doesn't seem to be any way to wrest the time-stamp from the server
300 along with the position query. So, we just keep track of the time
301 of the last movement we received, and return that in hopes that
302 it's somewhat accurate. */
304 static Time last_mouse_movement_time
;
306 enum mouse_tracking_type
{
308 mouse_tracking_mouse_movement
,
309 mouse_tracking_scroll_bar
312 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
314 struct scroll_bar
*tracked_scroll_bar
= NULL
;
316 /* Incremented by XTread_socket whenever it really tries to read
320 static int volatile input_signal_count
;
322 static int input_signal_count
;
325 /* Used locally within XTread_socket. */
327 static int x_noop_count
;
329 /* Initial values of argv and argc. */
331 extern char **initial_argv
;
332 extern int initial_argc
;
334 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
336 /* Tells if a window manager is present or not. */
338 extern Lisp_Object Vx_no_window_manager
;
340 extern Lisp_Object Qface
, Qmouse_face
;
344 /* A mask of extra modifier bits to put into every keyboard char. */
346 extern int extra_keyboard_modifiers
;
348 static Lisp_Object Qvendor_specific_keysyms
;
351 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
354 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
358 QDGlobals qd
; /* QuickDraw global information structure. */
362 /* Enumeration for overriding/changing the face to use for drawing
363 glyphs in x_draw_glyphs. */
365 enum draw_glyphs_face
375 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
376 struct mac_display_info
*mac_display_info_for_display (Display
*);
377 static void x_update_window_end
P_ ((struct window
*, int, int));
378 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
379 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
380 int *, int *, Lisp_Object
));
381 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
382 int *, int *, int *, int *, int));
383 static void set_output_cursor
P_ ((struct cursor_pos
*));
384 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
385 int *, int *, int *, int));
386 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
387 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
388 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
389 static void x_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
390 static void show_mouse_face
P_ ((struct x_display_info
*,
391 enum draw_glyphs_face
));
392 static int cursor_in_mouse_face_p
P_ ((struct window
*));
393 static int clear_mouse_face
P_ ((struct mac_display_info
*));
394 static int x_io_error_quitter
P_ ((Display
*));
395 int x_catch_errors
P_ ((Display
*));
396 void x_uncatch_errors
P_ ((Display
*, int));
397 void x_lower_frame
P_ ((struct frame
*));
398 void x_scroll_bar_clear
P_ ((struct frame
*));
399 int x_had_errors_p
P_ ((Display
*));
400 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
401 void x_raise_frame
P_ ((struct frame
*));
402 void x_set_window_size
P_ ((struct frame
*, int, int, int));
403 void x_wm_set_window_state
P_ ((struct frame
*, int));
404 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
405 void mac_initialize
P_ ((void));
406 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
407 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
408 enum text_cursor_kinds x_specified_cursor_type
P_ ((Lisp_Object
, int *));
409 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
411 enum draw_glyphs_face
));
412 static void x_update_end
P_ ((struct frame
*));
413 static void XTframe_up_to_date
P_ ((struct frame
*));
414 static void XTreassert_line_highlight
P_ ((int, int));
415 static void x_change_line_highlight
P_ ((int, int, int, int));
416 static void XTset_terminal_modes
P_ ((void));
417 static void XTreset_terminal_modes
P_ ((void));
418 static void XTcursor_to
P_ ((int, int, int, int));
419 static void x_write_glyphs
P_ ((struct glyph
*, int));
420 static void x_clear_end_of_line
P_ ((int));
421 static void x_clear_frame
P_ ((void));
422 static void x_clear_cursor
P_ ((struct window
*));
423 static void frame_highlight
P_ ((struct frame
*));
424 static void frame_unhighlight
P_ ((struct frame
*));
425 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
426 static void XTframe_rehighlight
P_ ((struct frame
*));
427 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
428 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
429 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
430 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
431 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
432 static int expose_window_tree
P_ ((struct window
*, Rect
*));
433 static int expose_window
P_ ((struct window
*, Rect
*));
434 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
435 Rect
*, enum glyph_row_area
));
436 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
438 void x_display_cursor (struct window
*, int, int, int, int, int);
439 void x_update_cursor
P_ ((struct frame
*, int));
440 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
441 static void x_update_window_cursor
P_ ((struct window
*, int));
442 static void x_erase_phys_cursor
P_ ((struct window
*));
443 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
444 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
445 enum fringe_bitmap_type
, int left_p
));
446 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
448 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
449 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
450 static void notice_overwritten_cursor
P_ ((struct window
*,
452 int, int, int, int));
453 static void x_flush
P_ ((struct frame
*f
));
454 static void x_update_begin
P_ ((struct frame
*));
455 static void x_update_window_begin
P_ ((struct window
*));
456 static void x_draw_vertical_border
P_ ((struct window
*));
457 static void x_after_update_window_line
P_ ((struct glyph_row
*));
458 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
459 static void x_produce_stretch_glyph
P_ ((struct it
*));
461 static void activate_scroll_bars (FRAME_PTR
);
462 static void deactivate_scroll_bars (FRAME_PTR
);
464 extern int image_ascent (struct image
*, struct face
*);
465 void x_set_offset (struct frame
*, int, int, int);
466 int x_bitmap_icon (struct frame
*, Lisp_Object
);
467 void x_make_frame_visible (struct frame
*);
469 extern void window_scroll (Lisp_Object
, int, int, int);
471 /* Defined in macmenu.h. */
472 extern void menubar_selection_callback (FRAME_PTR
, int);
473 extern void set_frame_menubar (FRAME_PTR
, int, int);
475 /* X display function emulation */
477 /* Structure borrowed from Xlib.h to represent two-byte characters in
486 XFreePixmap (display
, pixmap
)
490 PixMap
*p
= (PixMap
*) pixmap
;
497 /* Set foreground color for subsequent QuickDraw commands. Assume
498 graphic port has already been set. */
501 mac_set_forecolor (unsigned long color
)
505 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
506 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
507 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
509 RGBForeColor (&fg_color
);
513 /* Set background color for subsequent QuickDraw commands. Assume
514 graphic port has already been set. */
517 mac_set_backcolor (unsigned long color
)
521 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
522 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
523 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
525 RGBBackColor (&bg_color
);
528 /* Set foreground and background color for subsequent QuickDraw
529 commands. Assume that the graphic port has already been set. */
532 mac_set_colors (GC gc
)
534 mac_set_forecolor (gc
->foreground
);
535 mac_set_backcolor (gc
->background
);
538 /* Mac version of XDrawLine. */
541 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
547 #if TARGET_API_MAC_CARBON
548 SetPort (GetWindowPort (w
));
559 /* Mac version of XClearArea. */
562 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
566 unsigned int width
, height
;
569 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
573 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
574 xgc
.background
= mwp
->x_compatible
.background_pixel
;
576 #if TARGET_API_MAC_CARBON
577 SetPort (GetWindowPort (w
));
582 mac_set_colors (&xgc
);
583 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
588 /* Mac version of XClearWindow. */
591 XClearWindow (display
, w
)
595 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
598 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
599 xgc
.background
= mwp
->x_compatible
.background_pixel
;
601 #if TARGET_API_MAC_CARBON
602 SetPort (GetWindowPort (w
));
607 mac_set_colors (&xgc
);
609 #if TARGET_API_MAC_CARBON
613 GetWindowPortBounds (w
, &r
);
616 #else /* not TARGET_API_MAC_CARBON */
617 EraseRect (&(w
->portRect
));
618 #endif /* not TARGET_API_MAC_CARBON */
622 /* Mac replacement for XCopyArea. */
625 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
634 #if TARGET_API_MAC_CARBON
635 SetPort (GetWindowPort (w
));
641 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
643 #if TARGET_API_MAC_CARBON
647 LockPortBits (GetWindowPort (w
));
648 pmh
= GetPortPixMap (GetWindowPort (w
));
649 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
650 UnlockPortBits (GetWindowPort (w
));
652 #else /* not TARGET_API_MAC_CARBON */
653 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
654 #endif /* not TARGET_API_MAC_CARBON */
658 /* Mac replacement for XSetClipRectangles. */
661 mac_set_clip_rectangle (display
, w
, r
)
666 #if TARGET_API_MAC_CARBON
667 SetPort (GetWindowPort (w
));
676 /* Mac replacement for XSetClipMask. */
679 mac_reset_clipping (display
, w
)
685 #if TARGET_API_MAC_CARBON
686 SetPort (GetWindowPort (w
));
691 SetRect (&r
, -32767, -32767, 32767, 32767);
696 /* Mac replacement for XCreateBitmapFromBitmapData. */
699 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
704 int bytes_per_row
, i
, j
;
706 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
707 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
708 if (!bitmap
->baseAddr
)
711 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
712 for (i
= 0; i
< h
; i
++)
713 for (j
= 0; j
< w
; j
++)
714 if (BitTst (bits
, i
* w
+ j
))
715 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
717 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
722 mac_free_bitmap (bitmap
)
725 xfree (bitmap
->baseAddr
);
728 /* Mac replacement for XFillRectangle. */
731 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
736 unsigned int width
, height
;
740 #if TARGET_API_MAC_CARBON
741 SetPort (GetWindowPort (w
));
747 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
749 PaintRect (&r
); /* using foreground color of gc */
753 /* Mac replacement for XDrawRectangle: dest is a window. */
756 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
761 unsigned int width
, height
;
765 #if TARGET_API_MAC_CARBON
766 SetPort (GetWindowPort (w
));
772 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
774 FrameRect (&r
); /* using foreground color of gc */
778 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
781 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
786 unsigned int width
, height
;
788 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
791 #if TARGET_API_MAC_CARBON
792 SetPort (GetWindowPort (w
));
798 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
800 FrameRect (&r
); /* using foreground color of gc */
806 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
813 int nchars
, mode
, bytes_per_char
;
815 #if TARGET_API_MAC_CARBON
816 SetPort (GetWindowPort (w
));
823 TextFont (gc
->font
->mac_fontnum
);
824 TextSize (gc
->font
->mac_fontsize
);
825 TextFace (gc
->font
->mac_fontface
);
829 DrawText (buf
, 0, nchars
* bytes_per_char
);
833 /* Mac replacement for XDrawString. */
836 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
844 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
848 /* Mac replacement for XDrawString16. */
851 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
859 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
864 /* Mac replacement for XDrawImageString. */
867 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
875 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
879 /* Mac replacement for XDrawString16. */
882 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
890 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
895 /* Mac replacement for XCopyArea: dest must be window. */
898 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
905 unsigned int width
, height
;
910 #if TARGET_API_MAC_CARBON
911 SetPort (GetWindowPort (dest
));
918 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
919 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
921 #if TARGET_API_MAC_CARBON
925 LockPortBits (GetWindowPort (dest
));
926 pmh
= GetPortPixMap (GetWindowPort (dest
));
927 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
928 UnlockPortBits (GetWindowPort (dest
));
930 #else /* not TARGET_API_MAC_CARBON */
931 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
932 #endif /* not TARGET_API_MAC_CARBON */
937 /* Convert a pair of local coordinates to global (screen) coordinates.
938 Assume graphic port has been properly set. */
940 local_to_global_coord (short *h
, short *v
)
954 /* Mac replacement for XCopyArea: used only for scrolling. */
957 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
962 unsigned int width
, height
;
965 #if TARGET_API_MAC_CARBON
966 Rect gw_r
, src_r
, dest_r
;
969 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
970 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
972 SetPort (GetWindowPort (w
));
974 ForeColor (blackColor
);
975 BackColor (whiteColor
);
977 LockPortBits (GetWindowPort (w
));
978 pmh
= GetPortPixMap (GetWindowPort (w
));
979 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
980 UnlockPortBits (GetWindowPort (w
));
983 #else /* not TARGET_API_MAC_CARBON */
991 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
992 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
995 /* Need to use global coordinates and screenBits since src and dest
996 areas overlap in general. */
997 local_to_global_coord (&src_r
.left
, &src_r
.top
);
998 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
999 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
1000 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
1002 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
1004 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1005 color mapping in CopyBits. Otherwise, it will be slow. */
1006 ForeColor (blackColor
);
1007 BackColor (whiteColor
);
1008 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1010 mac_set_colors (gc
);
1012 #endif /* not TARGET_API_MAC_CARBON */
1016 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1019 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1026 unsigned int width
, height
;
1030 int src_right
= ((PixMap
*) src
)->bounds
.right
;
1031 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
1032 int w
= src_right
- src_x
;
1033 int h
= src_bottom
- src_y
;
1035 mac_set_colors (gc
);
1037 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
1038 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
1040 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
1044 /* Mac replacement for XChangeGC. */
1047 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1050 if (mask
& GCForeground
)
1051 gc
->foreground
= xgcv
->foreground
;
1052 if (mask
& GCBackground
)
1053 gc
->background
= xgcv
->background
;
1055 gc
->font
= xgcv
->font
;
1059 /* Mac replacement for XCreateGC. */
1062 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1065 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1066 bzero (gc
, sizeof (XGCValues
));
1068 XChangeGC (ignore
, gc
, mask
, xgcv
);
1074 /* Used in xfaces.c. */
1077 XFreeGC (display
, gc
)
1085 /* Mac replacement for XGetGCValues. */
1088 XGetGCValues (void* ignore
, XGCValues
*gc
,
1089 unsigned long mask
, XGCValues
*xgcv
)
1091 XChangeGC (ignore
, xgcv
, mask
, gc
);
1095 /* Mac replacement for XSetForeground. */
1098 XSetForeground (display
, gc
, color
)
1101 unsigned long color
;
1103 gc
->foreground
= color
;
1107 /* Mac replacement for XSetFont. */
1110 XSetFont (display
, gc
, font
)
1120 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1121 int *direction
,int *font_ascent
,
1122 int *font_descent
, XCharStruct
*cs
)
1124 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1128 /* x_sync is a no-op on Mac. */
1136 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1137 Calls to XFlush should be unnecessary because the X output buffer
1138 is flushed automatically as needed by calls to XPending,
1139 XNextEvent, or XWindowEvent according to the XFlush man page.
1140 XTread_socket calls XPending. Removing XFlush improves
1143 #if TARGET_API_MAC_CARBON
1144 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1146 #define XFlush(DISPLAY) (void) 0
1149 /* Flush display of frame F, or of all frames if F is null. */
1155 #if TARGET_API_MAC_CARBON
1159 Lisp_Object rest
, frame
;
1160 FOR_EACH_FRAME (rest
, frame
)
1161 x_flush (XFRAME (frame
));
1163 else if (FRAME_X_P (f
))
1164 XFlush (FRAME_MAC_DISPLAY (f
));
1166 #endif /* TARGET_API_MAC_CARBON */
1171 /* Return the struct mac_display_info corresponding to DPY. There's
1174 struct mac_display_info
*
1175 mac_display_info_for_display (dpy
)
1178 return &one_mac_display_info
;
1183 /***********************************************************************
1184 Starting and ending an update
1185 ***********************************************************************/
1187 /* Start an update of frame F. This function is installed as a hook
1188 for update_begin, i.e. it is called when update_begin is called.
1189 This function is called prior to calls to x_update_window_begin for
1190 each window being updated. */
1196 /* Nothing to do. */
1200 /* Start update of window W. Set the global variable updated_window
1201 to the window being updated and set output_cursor to the cursor
1205 x_update_window_begin (w
)
1208 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1209 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1212 set_output_cursor (&w
->cursor
);
1216 if (f
== display_info
->mouse_face_mouse_frame
)
1218 /* Don't do highlighting for mouse motion during the update. */
1219 display_info
->mouse_face_defer
= 1;
1221 /* If F needs to be redrawn, simply forget about any prior mouse
1223 if (FRAME_GARBAGED_P (f
))
1224 display_info
->mouse_face_window
= Qnil
;
1226 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1227 their mouse_face_p flag set, which means that they are always
1228 unequal to rows in a desired matrix which never have that
1229 flag set. So, rows containing mouse-face glyphs are never
1230 scrolled, and we don't have to switch the mouse highlight off
1231 here to prevent it from being scrolled. */
1233 /* Can we tell that this update does not affect the window
1234 where the mouse highlight is? If so, no need to turn off.
1235 Likewise, don't do anything if the frame is garbaged;
1236 in that case, the frame's current matrix that we would use
1237 is all wrong, and we will redisplay that line anyway. */
1238 if (!NILP (display_info
->mouse_face_window
)
1239 && w
== XWINDOW (display_info
->mouse_face_window
))
1243 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1244 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1247 if (i
< w
->desired_matrix
->nrows
)
1248 clear_mouse_face (display_info
);
1257 /* Draw a vertical window border to the right of window W if W doesn't
1258 have vertical scroll bars. */
1261 x_draw_vertical_border (w
)
1264 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1266 /* Redraw borders between horizontally adjacent windows. Don't
1267 do it for frames with vertical scroll bars because either the
1268 right scroll bar of a window, or the left scroll bar of its
1269 neighbor will suffice as a border. */
1270 if (!WINDOW_RIGHTMOST_P (w
)
1271 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1275 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1276 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1279 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1280 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1285 /* End update of window W (which is equal to updated_window).
1287 Draw vertical borders between horizontally adjacent windows, and
1288 display W's cursor if CURSOR_ON_P is non-zero.
1290 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1291 glyphs in mouse-face were overwritten. In that case we have to
1292 make sure that the mouse-highlight is properly redrawn.
1294 W may be a menu bar pseudo-window in case we don't have X toolkit
1295 support. Such windows don't have a cursor, so don't display it
1299 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1301 int cursor_on_p
, mouse_face_overwritten_p
;
1303 struct mac_display_info
*dpyinfo
1304 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1306 if (!w
->pseudo_window_p
)
1311 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1313 output_cursor
.x
, output_cursor
.y
);
1315 x_draw_vertical_border (w
);
1319 /* If a row with mouse-face was overwritten, arrange for
1320 XTframe_up_to_date to redisplay the mouse highlight. */
1321 if (mouse_face_overwritten_p
)
1323 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1324 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1325 dpyinfo
->mouse_face_window
= Qnil
;
1329 /* Unhide the caret. This won't actually show the cursor, unless it
1330 was visible before the corresponding call to HideCaret in
1331 x_update_window_begin. */
1332 if (w32_use_visible_system_caret
)
1333 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1336 updated_window
= NULL
;
1340 /* End update of frame F. This function is installed as a hook in
1347 /* Reset the background color of Mac OS Window to that of the frame after
1348 update so that it is used by Mac Toolbox to clear the update region before
1349 an update event is generated. */
1350 #if TARGET_API_MAC_CARBON
1351 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1353 SetPort (FRAME_MAC_WINDOW (f
));
1356 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1358 /* Mouse highlight may be displayed again. */
1359 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1362 XFlush (FRAME_MAC_DISPLAY (f
));
1367 /* This function is called from various places in xdisp.c whenever a
1368 complete update has been performed. The global variable
1369 updated_window is not available here. */
1372 XTframe_up_to_date (f
)
1377 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1379 if (dpyinfo
->mouse_face_deferred_gc
1380 || f
== dpyinfo
->mouse_face_mouse_frame
)
1383 if (dpyinfo
->mouse_face_mouse_frame
)
1384 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1385 dpyinfo
->mouse_face_mouse_x
,
1386 dpyinfo
->mouse_face_mouse_y
);
1387 dpyinfo
->mouse_face_deferred_gc
= 0;
1394 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1395 arrow bitmaps, or clear the fringes if no bitmaps are required
1396 before DESIRED_ROW is made current. The window being updated is
1397 found in updated_window. This function is called from
1398 update_window_line only if it is known that there are differences
1399 between bitmaps to be drawn between current row and DESIRED_ROW. */
1402 x_after_update_window_line (desired_row
)
1403 struct glyph_row
*desired_row
;
1405 struct window
*w
= updated_window
;
1411 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1414 x_draw_row_fringe_bitmaps (w
, desired_row
);
1418 /* When a window has disappeared, make sure that no rest of
1419 full-width rows stays visible in the internal border. Could
1420 check here if updated_window is the leftmost/rightmost window,
1421 but I guess it's not worth doing since vertically split windows
1422 are almost never used, internal border is rarely set, and the
1423 overhead is very small. */
1424 if (windows_or_buffers_changed
1425 && desired_row
->full_width_p
1426 && (f
= XFRAME (w
->frame
),
1427 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1429 && (height
= desired_row
->visible_height
,
1432 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1433 /* Internal border is drawn below the tool bar. */
1434 if (WINDOWP (f
->tool_bar_window
)
1435 && w
== XWINDOW (f
->tool_bar_window
))
1440 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1441 0, y
, width
, height
, 0);
1442 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1443 f
->output_data
.mac
->pixel_width
- width
, y
,
1451 /* Draw the bitmap WHICH in one of the left or right fringes of
1452 window W. ROW is the glyph row for which to display the bitmap; it
1453 determines the vertical position at which the bitmap has to be
1457 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1459 struct glyph_row
*row
;
1460 enum fringe_bitmap_type which
;
1463 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1464 Display
*display
= FRAME_MAC_DISPLAY (f
);
1465 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1466 int x
, y
, wd
, h
, dy
;
1468 unsigned char *bits
;
1471 GC gc
= f
->output_data
.mac
->normal_gc
;
1474 /* Must clip because of partially visible lines. */
1475 x_clip_to_row (w
, row
, gc
, 1);
1477 /* Convert row to frame coordinates. */
1478 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1482 case NO_FRINGE_BITMAP
:
1487 case LEFT_TRUNCATION_BITMAP
:
1493 case OVERLAY_ARROW_BITMAP
:
1499 case RIGHT_TRUNCATION_BITMAP
:
1505 case CONTINUED_LINE_BITMAP
:
1506 wd
= continued_width
;
1507 h
= continued_height
;
1508 bits
= continued_bits
;
1511 case CONTINUATION_LINE_BITMAP
:
1512 wd
= continuation_width
;
1513 h
= continuation_height
;
1514 bits
= continuation_bits
;
1517 case ZV_LINE_BITMAP
:
1519 h
= zv_height
- (y
% zv_period
);
1520 bits
= zv_bits
+ (y
% zv_period
);
1527 /* Clip bitmap if too high. */
1528 if (h
> row
->height
)
1531 /* Set dy to the offset in the row to start drawing the bitmap. */
1532 dy
= (row
->height
- h
) / 2;
1534 /* Draw the bitmap. */
1535 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1536 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1538 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1543 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1544 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1545 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1547 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1548 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1550 /* If W has a vertical border to its left, don't draw over it. */
1551 int border
= ((XFASTINT (w
->left
) > 0
1552 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1554 b1
= (window_box_left (w
, -1)
1555 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1557 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1562 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1563 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1564 x
= (window_box_right (w
, -1)
1565 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1566 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1568 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1570 b1
= window_box_right (w
, -1);
1571 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1577 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1579 gcv
.foreground
= face
->background
;
1581 #if 0 /* MAC_TODO: stipple */
1582 /* In case the same realized face is used for fringes and
1583 for something displayed in the text (e.g. face `region' on
1584 mono-displays, the fill style may have been changed to
1585 FillSolid in x_draw_glyph_string_background. */
1587 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1589 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1592 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1595 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1598 row
->visible_height
);
1600 #if 0 /* MAC_TODO: stipple */
1602 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1606 if (which
== NO_FRINGE_BITMAP
)
1608 mac_reset_clipping (display
, window
);
1612 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1613 gcv
.foreground
= face
->foreground
;
1614 gcv
.background
= face
->background
;
1616 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1618 mac_free_bitmap (&bitmap
);
1619 mac_reset_clipping (display
, window
);
1623 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1624 function with input blocked. */
1627 x_draw_row_fringe_bitmaps (w
, row
)
1629 struct glyph_row
*row
;
1631 struct frame
*f
= XFRAME (w
->frame
);
1632 enum fringe_bitmap_type bitmap
;
1634 xassert (interrupt_input_blocked
);
1636 /* If row is completely invisible, because of vscrolling, we
1637 don't have to draw anything. */
1638 if (row
->visible_height
<= 0)
1641 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1643 /* Decide which bitmap to draw in the left fringe. */
1644 if (row
->overlay_arrow_p
)
1645 bitmap
= OVERLAY_ARROW_BITMAP
;
1646 else if (row
->truncated_on_left_p
)
1647 bitmap
= LEFT_TRUNCATION_BITMAP
;
1648 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1649 bitmap
= CONTINUATION_LINE_BITMAP
;
1650 else if (row
->indicate_empty_line_p
)
1651 bitmap
= ZV_LINE_BITMAP
;
1653 bitmap
= NO_FRINGE_BITMAP
;
1655 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1658 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1660 /* Decide which bitmap to draw in the right fringe. */
1661 if (row
->truncated_on_right_p
)
1662 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1663 else if (row
->continued_p
)
1664 bitmap
= CONTINUED_LINE_BITMAP
;
1665 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1666 bitmap
= ZV_LINE_BITMAP
;
1668 bitmap
= NO_FRINGE_BITMAP
;
1670 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1675 /* This is called when starting Emacs and when restarting after
1676 suspend. When starting Emacs, no window is mapped. And nothing
1677 must be done to Emacs's own window if it is suspended (though that
1681 XTset_terminal_modes ()
1685 /* This is called when exiting or suspending Emacs. Exiting will make
1686 the windows go away, and suspending requires no action. */
1689 XTreset_terminal_modes ()
1695 /***********************************************************************
1697 ***********************************************************************/
1699 /* Set the global variable output_cursor to CURSOR. All cursor
1700 positions are relative to updated_window. */
1703 set_output_cursor (cursor
)
1704 struct cursor_pos
*cursor
;
1706 output_cursor
.hpos
= cursor
->hpos
;
1707 output_cursor
.vpos
= cursor
->vpos
;
1708 output_cursor
.x
= cursor
->x
;
1709 output_cursor
.y
= cursor
->y
;
1713 /* Set a nominal cursor position.
1715 HPOS and VPOS are column/row positions in a window glyph matrix. X
1716 and Y are window text area relative pixel positions.
1718 If this is done during an update, updated_window will contain the
1719 window that is being updated and the position is the future output
1720 cursor position for that window. If updated_window is null, use
1721 selected_window and display the cursor at the given position. */
1724 XTcursor_to (vpos
, hpos
, y
, x
)
1725 int vpos
, hpos
, y
, x
;
1729 /* If updated_window is not set, work on selected_window. */
1733 w
= XWINDOW (selected_window
);
1735 /* Set the output cursor. */
1736 output_cursor
.hpos
= hpos
;
1737 output_cursor
.vpos
= vpos
;
1738 output_cursor
.x
= x
;
1739 output_cursor
.y
= y
;
1741 /* If not called as part of an update, really display the cursor.
1742 This will also set the cursor position of W. */
1743 if (updated_window
== NULL
)
1746 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1747 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1754 /***********************************************************************
1756 ***********************************************************************/
1758 /* Function prototypes of this page. */
1760 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1764 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1765 int, XChar2b
*, int));
1766 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1767 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1768 static void x_append_glyph
P_ ((struct it
*));
1769 static void x_append_composite_glyph
P_ ((struct it
*));
1770 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1772 static void x_produce_glyphs
P_ ((struct it
*));
1773 static void x_produce_image_glyph
P_ ((struct it
*it
));
1776 /* Return a pointer to per-char metric information in FONT of a
1777 character pointed by B which is a pointer to an XChar2b. */
1779 #define PER_CHAR_METRIC(font, b) \
1781 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1782 + (((font)->min_byte1 || (font)->max_byte1) \
1783 ? (((b)->byte1 - (font)->min_byte1) \
1784 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1786 : &((font)->max_bounds))
1789 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1790 is not contained in the font. */
1792 static INLINE XCharStruct
*
1793 x_per_char_metric (font
, char2b
)
1797 /* The result metric information. */
1798 XCharStruct
*pcm
= NULL
;
1800 xassert (font
&& char2b
);
1802 if (font
->per_char
!= NULL
)
1804 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1806 /* min_char_or_byte2 specifies the linear character index
1807 corresponding to the first element of the per_char array,
1808 max_char_or_byte2 is the index of the last character. A
1809 character with non-zero CHAR2B->byte1 is not in the font.
1810 A character with byte2 less than min_char_or_byte2 or
1811 greater max_char_or_byte2 is not in the font. */
1812 if (char2b
->byte1
== 0
1813 && char2b
->byte2
>= font
->min_char_or_byte2
1814 && char2b
->byte2
<= font
->max_char_or_byte2
)
1815 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1819 /* If either min_byte1 or max_byte1 are nonzero, both
1820 min_char_or_byte2 and max_char_or_byte2 are less than
1821 256, and the 2-byte character index values corresponding
1822 to the per_char array element N (counting from 0) are:
1824 byte1 = N/D + min_byte1
1825 byte2 = N\D + min_char_or_byte2
1829 D = max_char_or_byte2 - min_char_or_byte2 + 1
1830 / = integer division
1831 \ = integer modulus */
1832 if (char2b
->byte1
>= font
->min_byte1
1833 && char2b
->byte1
<= font
->max_byte1
1834 && char2b
->byte2
>= font
->min_char_or_byte2
1835 && char2b
->byte2
<= font
->max_char_or_byte2
)
1837 pcm
= (font
->per_char
1838 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1839 * (char2b
->byte1
- font
->min_byte1
))
1840 + (char2b
->byte2
- font
->min_char_or_byte2
));
1846 /* If the per_char pointer is null, all glyphs between the first
1847 and last character indexes inclusive have the same
1848 information, as given by both min_bounds and max_bounds. */
1849 if (char2b
->byte2
>= font
->min_char_or_byte2
1850 && char2b
->byte2
<= font
->max_char_or_byte2
)
1851 pcm
= &font
->max_bounds
;
1854 return ((pcm
== NULL
1855 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1860 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1861 the two-byte form of C. Encoding is returned in *CHAR2B. */
1864 x_encode_char (c
, char2b
, font_info
)
1867 struct font_info
*font_info
;
1869 int charset
= CHAR_CHARSET (c
);
1870 XFontStruct
*font
= font_info
->font
;
1872 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1873 This may be either a program in a special encoder language or a
1875 if (font_info
->font_encoder
)
1877 /* It's a program. */
1878 struct ccl_program
*ccl
= font_info
->font_encoder
;
1880 if (CHARSET_DIMENSION (charset
) == 1)
1882 ccl
->reg
[0] = charset
;
1883 ccl
->reg
[1] = char2b
->byte2
;
1887 ccl
->reg
[0] = charset
;
1888 ccl
->reg
[1] = char2b
->byte1
;
1889 ccl
->reg
[2] = char2b
->byte2
;
1892 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1894 /* We assume that MSBs are appropriately set/reset by CCL
1896 if (font
->max_byte1
== 0) /* 1-byte font */
1897 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1899 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1901 else if (font_info
->encoding
[charset
])
1903 /* Fixed encoding scheme. See fontset.h for the meaning of the
1904 encoding numbers. */
1905 int enc
= font_info
->encoding
[charset
];
1907 if ((enc
== 1 || enc
== 2)
1908 && CHARSET_DIMENSION (charset
) == 2)
1909 char2b
->byte1
|= 0x80;
1911 if (enc
== 1 || enc
== 3)
1912 char2b
->byte2
|= 0x80;
1918 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1919 char2b
->byte1
= sjis1
;
1920 char2b
->byte2
= sjis2
;
1926 /* Get face and two-byte form of character C in face FACE_ID on frame
1927 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1928 means we want to display multibyte text. Value is a pointer to a
1929 realized face that is ready for display. */
1931 static INLINE
struct face
*
1932 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1938 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1942 /* Unibyte case. We don't have to encode, but we have to make
1943 sure to use a face suitable for unibyte. */
1946 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1947 face
= FACE_FROM_ID (f
, face_id
);
1949 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1951 /* Case of ASCII in a face known to fit ASCII. */
1957 int c1
, c2
, charset
;
1959 /* Split characters into bytes. If c2 is -1 afterwards, C is
1960 really a one-byte character so that byte1 is zero. */
1961 SPLIT_CHAR (c
, charset
, c1
, c2
);
1963 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1965 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1967 /* Maybe encode the character in *CHAR2B. */
1968 if (face
->font
!= NULL
)
1970 struct font_info
*font_info
1971 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1973 x_encode_char (c
, char2b
, font_info
);
1977 /* Make sure X resources of the face are allocated. */
1978 xassert (face
!= NULL
);
1979 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1985 /* Get face and two-byte form of character glyph GLYPH on frame F.
1986 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1987 a pointer to a realized face that is ready for display. */
1989 static INLINE
struct face
*
1990 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1992 struct glyph
*glyph
;
1998 xassert (glyph
->type
== CHAR_GLYPH
);
1999 face
= FACE_FROM_ID (f
, glyph
->face_id
);
2004 if (!glyph
->multibyte_p
)
2006 /* Unibyte case. We don't have to encode, but we have to make
2007 sure to use a face suitable for unibyte. */
2009 char2b
->byte2
= glyph
->u
.ch
;
2011 else if (glyph
->u
.ch
< 128
2012 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
2014 /* Case of ASCII in a face known to fit ASCII. */
2016 char2b
->byte2
= glyph
->u
.ch
;
2020 int c1
, c2
, charset
;
2022 /* Split characters into bytes. If c2 is -1 afterwards, C is
2023 really a one-byte character so that byte1 is zero. */
2024 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
2026 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
2028 char2b
->byte1
= 0, char2b
->byte2
= c1
;
2030 /* Maybe encode the character in *CHAR2B. */
2031 if (charset
!= CHARSET_ASCII
)
2033 struct font_info
*font_info
2034 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2037 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
2040 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2045 /* Make sure X resources of the face are allocated. */
2046 xassert (face
!= NULL
);
2047 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2052 /* Store one glyph for IT->char_to_display in IT->glyph_row.
2053 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2059 struct glyph
*glyph
;
2060 enum glyph_row_area area
= it
->area
;
2062 xassert (it
->glyph_row
);
2063 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
2065 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2066 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2068 glyph
->charpos
= CHARPOS (it
->position
);
2069 glyph
->object
= it
->object
;
2070 glyph
->pixel_width
= it
->pixel_width
;
2071 glyph
->voffset
= it
->voffset
;
2072 glyph
->type
= CHAR_GLYPH
;
2073 glyph
->multibyte_p
= it
->multibyte_p
;
2074 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2075 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2076 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2077 || it
->phys_descent
> it
->descent
);
2078 glyph
->padding_p
= 0;
2079 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
2080 glyph
->face_id
= it
->face_id
;
2081 glyph
->u
.ch
= it
->char_to_display
;
2082 ++it
->glyph_row
->used
[area
];
2086 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
2087 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2090 x_append_composite_glyph (it
)
2093 struct glyph
*glyph
;
2094 enum glyph_row_area area
= it
->area
;
2096 xassert (it
->glyph_row
);
2098 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2099 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2101 glyph
->charpos
= CHARPOS (it
->position
);
2102 glyph
->object
= it
->object
;
2103 glyph
->pixel_width
= it
->pixel_width
;
2104 glyph
->voffset
= it
->voffset
;
2105 glyph
->type
= COMPOSITE_GLYPH
;
2106 glyph
->multibyte_p
= it
->multibyte_p
;
2107 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2108 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2109 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2110 || it
->phys_descent
> it
->descent
);
2111 glyph
->padding_p
= 0;
2112 glyph
->glyph_not_available_p
= 0;
2113 glyph
->face_id
= it
->face_id
;
2114 glyph
->u
.cmp_id
= it
->cmp_id
;
2115 ++it
->glyph_row
->used
[area
];
2120 /* Change IT->ascent and IT->height according to the setting of
2124 take_vertical_position_into_account (it
)
2129 if (it
->voffset
< 0)
2130 /* Increase the ascent so that we can display the text higher
2132 it
->ascent
+= abs (it
->voffset
);
2134 /* Increase the descent so that we can display the text lower
2136 it
->descent
+= it
->voffset
;
2141 /* Produce glyphs/get display metrics for the image IT is loaded with.
2142 See the description of struct display_iterator in dispextern.h for
2143 an overview of struct display_iterator. */
2146 x_produce_image_glyph (it
)
2152 xassert (it
->what
== IT_IMAGE
);
2154 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2155 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2158 /* Make sure X resources of the face and image are loaded. */
2159 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2160 prepare_image_for_display (it
->f
, img
);
2162 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2163 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2164 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2168 if (face
->box
!= FACE_NO_BOX
)
2170 if (face
->box_line_width
> 0)
2172 it
->ascent
+= face
->box_line_width
;
2173 it
->descent
+= face
->box_line_width
;
2176 if (it
->start_of_box_run_p
)
2177 it
->pixel_width
+= abs (face
->box_line_width
);
2178 if (it
->end_of_box_run_p
)
2179 it
->pixel_width
+= abs (face
->box_line_width
);
2182 take_vertical_position_into_account (it
);
2186 struct glyph
*glyph
;
2187 enum glyph_row_area area
= it
->area
;
2189 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2190 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2192 glyph
->charpos
= CHARPOS (it
->position
);
2193 glyph
->object
= it
->object
;
2194 glyph
->pixel_width
= it
->pixel_width
;
2195 glyph
->voffset
= it
->voffset
;
2196 glyph
->type
= IMAGE_GLYPH
;
2197 glyph
->multibyte_p
= it
->multibyte_p
;
2198 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2199 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2200 glyph
->overlaps_vertically_p
= 0;
2201 glyph
->padding_p
= 0;
2202 glyph
->glyph_not_available_p
= 0;
2203 glyph
->face_id
= it
->face_id
;
2204 glyph
->u
.img_id
= img
->id
;
2205 ++it
->glyph_row
->used
[area
];
2211 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2212 of the glyph, WIDTH and HEIGHT are the width and height of the
2213 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2214 ascent of the glyph (0 <= ASCENT <= 1). */
2217 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2223 struct glyph
*glyph
;
2224 enum glyph_row_area area
= it
->area
;
2226 xassert (ascent
>= 0 && ascent
<= 1);
2228 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2229 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2231 glyph
->charpos
= CHARPOS (it
->position
);
2232 glyph
->object
= object
;
2233 glyph
->pixel_width
= width
;
2234 glyph
->voffset
= it
->voffset
;
2235 glyph
->type
= STRETCH_GLYPH
;
2236 glyph
->multibyte_p
= it
->multibyte_p
;
2237 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2238 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2239 glyph
->overlaps_vertically_p
= 0;
2240 glyph
->padding_p
= 0;
2241 glyph
->glyph_not_available_p
= 0;
2242 glyph
->face_id
= it
->face_id
;
2243 glyph
->u
.stretch
.ascent
= height
* ascent
;
2244 glyph
->u
.stretch
.height
= height
;
2245 ++it
->glyph_row
->used
[area
];
2250 /* Produce a stretch glyph for iterator IT. IT->object is the value
2251 of the glyph property displayed. The value must be a list
2252 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2255 1. `:width WIDTH' specifies that the space should be WIDTH *
2256 canonical char width wide. WIDTH may be an integer or floating
2259 2. `:relative-width FACTOR' specifies that the width of the stretch
2260 should be computed from the width of the first character having the
2261 `glyph' property, and should be FACTOR times that width.
2263 3. `:align-to HPOS' specifies that the space should be wide enough
2264 to reach HPOS, a value in canonical character units.
2266 Exactly one of the above pairs must be present.
2268 4. `:height HEIGHT' specifies that the height of the stretch produced
2269 should be HEIGHT, measured in canonical character units.
2271 5. `:relative-height FACTOR' specifies that the height of the
2272 stretch should be FACTOR times the height of the characters having
2275 Either none or exactly one of 4 or 5 must be present.
2277 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2278 of the stretch should be used for the ascent of the stretch.
2279 ASCENT must be in the range 0 <= ASCENT <= 100. */
2282 ((INTEGERP (X) || FLOATP (X)) \
2288 x_produce_stretch_glyph (it
)
2291 /* (space :width WIDTH :height HEIGHT. */
2293 extern Lisp_Object Qspace
;
2295 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2296 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2297 extern Lisp_Object QCalign_to
;
2298 Lisp_Object prop
, plist
;
2299 double width
= 0, height
= 0, ascent
= 0;
2300 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2301 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2303 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2305 /* List should start with `space'. */
2306 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2307 plist
= XCDR (it
->object
);
2309 /* Compute the width of the stretch. */
2310 if (prop
= Fplist_get (plist
, QCwidth
),
2312 /* Absolute width `:width WIDTH' specified and valid. */
2313 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2314 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2317 /* Relative width `:relative-width FACTOR' specified and valid.
2318 Compute the width of the characters having the `glyph'
2321 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2324 if (it
->multibyte_p
)
2326 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2327 - IT_BYTEPOS (*it
));
2328 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2331 it2
.c
= *p
, it2
.len
= 1;
2333 it2
.glyph_row
= NULL
;
2334 it2
.what
= IT_CHARACTER
;
2335 x_produce_glyphs (&it2
);
2336 width
= NUMVAL (prop
) * it2
.pixel_width
;
2338 else if (prop
= Fplist_get (plist
, QCalign_to
),
2340 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2342 /* Nothing specified -> width defaults to canonical char width. */
2343 width
= CANON_X_UNIT (it
->f
);
2345 /* Compute height. */
2346 if (prop
= Fplist_get (plist
, QCheight
),
2348 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2349 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2351 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2353 height
= FONT_HEIGHT (font
);
2355 /* Compute percentage of height used for ascent. If
2356 `:ascent ASCENT' is present and valid, use that. Otherwise,
2357 derive the ascent from the font in use. */
2358 if (prop
= Fplist_get (plist
, QCascent
),
2359 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2360 ascent
= NUMVAL (prop
) / 100.0;
2362 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2371 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2372 if (!STRINGP (object
))
2373 object
= it
->w
->buffer
;
2374 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2377 it
->pixel_width
= width
;
2378 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2379 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2382 if (face
->box
!= FACE_NO_BOX
)
2384 if (face
->box_line_width
> 0)
2386 it
->ascent
+= face
->box_line_width
;
2387 it
->descent
+= face
->box_line_width
;
2390 if (it
->start_of_box_run_p
)
2391 it
->pixel_width
+= abs (face
->box_line_width
);
2392 if (it
->end_of_box_run_p
)
2393 it
->pixel_width
+= abs (face
->box_line_width
);
2396 take_vertical_position_into_account (it
);
2399 /* Return proper value to be used as baseline offset of font that has
2400 ASCENT and DESCENT to draw characters by the font at the vertical
2401 center of the line of frame F.
2403 Here, out task is to find the value of BOFF in the following figure;
2405 -------------------------+-----------+-
2406 -+-+---------+-+ | |
2408 | | | | F_ASCENT F_HEIGHT
2411 | | |-|-+------+-----------|------- baseline
2413 | |---------|-+-+ | |
2415 -+-+---------+-+ F_DESCENT |
2416 -------------------------+-----------+-
2418 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2419 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2420 DESCENT = FONT->descent
2421 HEIGHT = FONT_HEIGHT (FONT)
2422 F_DESCENT = (F->output_data.x->font->descent
2423 - F->output_data.x->baseline_offset)
2424 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2427 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2428 (FONT_DESCENT (FONT) \
2429 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2430 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2431 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2433 /* Produce glyphs/get display metrics for the display element IT is
2434 loaded with. See the description of struct display_iterator in
2435 dispextern.h for an overview of struct display_iterator. */
2438 x_produce_glyphs (it
)
2441 it
->glyph_not_available_p
= 0;
2443 if (it
->what
== IT_CHARACTER
)
2447 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2449 int font_not_found_p
;
2450 struct font_info
*font_info
;
2451 int boff
; /* baseline offset */
2452 /* We may change it->multibyte_p upon unibyte<->multibyte
2453 conversion. So, save the current value now and restore it
2456 Note: It seems that we don't have to record multibyte_p in
2457 struct glyph because the character code itself tells if or
2458 not the character is multibyte. Thus, in the future, we must
2459 consider eliminating the field `multibyte_p' in the struct
2462 int saved_multibyte_p
= it
->multibyte_p
;
2464 /* Maybe translate single-byte characters to multibyte, or the
2466 it
->char_to_display
= it
->c
;
2467 if (!ASCII_BYTE_P (it
->c
))
2469 if (unibyte_display_via_language_environment
2470 && SINGLE_BYTE_CHAR_P (it
->c
)
2472 || !NILP (Vnonascii_translation_table
)))
2474 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2475 it
->multibyte_p
= 1;
2476 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2477 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2479 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2480 && !it
->multibyte_p
)
2482 it
->multibyte_p
= 1;
2483 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2484 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2488 /* Get font to use. Encode IT->char_to_display. */
2489 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2490 it
->face_id
, &char2b
,
2494 /* When no suitable font found, use the default font. */
2495 font_not_found_p
= font
== NULL
;
2496 if (font_not_found_p
)
2498 font
= FRAME_FONT (it
->f
);
2499 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2504 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2505 boff
= font_info
->baseline_offset
;
2506 if (font_info
->vertical_centering
)
2507 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2510 if (it
->char_to_display
>= ' '
2511 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2513 /* Either unibyte or ASCII. */
2518 pcm
= x_per_char_metric (font
, &char2b
);
2519 it
->ascent
= FONT_BASE (font
) + boff
;
2520 it
->descent
= FONT_DESCENT (font
) - boff
;
2524 it
->phys_ascent
= pcm
->ascent
+ boff
;
2525 it
->phys_descent
= pcm
->descent
- boff
;
2526 it
->pixel_width
= pcm
->width
;
2530 it
->glyph_not_available_p
= 1;
2531 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2532 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2533 it
->pixel_width
= FONT_WIDTH (font
);
2536 /* If this is a space inside a region of text with
2537 `space-width' property, change its width. */
2538 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2540 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2542 /* If face has a box, add the box thickness to the character
2543 height. If character has a box line to the left and/or
2544 right, add the box line width to the character's width. */
2545 if (face
->box
!= FACE_NO_BOX
)
2547 int thick
= face
->box_line_width
;
2551 it
->ascent
+= thick
;
2552 it
->descent
+= thick
;
2557 if (it
->start_of_box_run_p
)
2558 it
->pixel_width
+= thick
;
2559 if (it
->end_of_box_run_p
)
2560 it
->pixel_width
+= thick
;
2563 /* If face has an overline, add the height of the overline
2564 (1 pixel) and a 1 pixel margin to the character height. */
2565 if (face
->overline_p
)
2568 take_vertical_position_into_account (it
);
2570 /* If we have to actually produce glyphs, do it. */
2575 /* Translate a space with a `space-width' property
2576 into a stretch glyph. */
2577 double ascent
= (double) FONT_BASE (font
)
2578 / FONT_HEIGHT (font
);
2579 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2580 it
->ascent
+ it
->descent
, ascent
);
2583 x_append_glyph (it
);
2585 /* If characters with lbearing or rbearing are displayed
2586 in this line, record that fact in a flag of the
2587 glyph row. This is used to optimize X output code. */
2588 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2589 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2592 else if (it
->char_to_display
== '\n')
2594 /* A newline has no width but we need the height of the line. */
2595 it
->pixel_width
= 0;
2597 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2598 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2600 if (face
->box
!= FACE_NO_BOX
2601 && face
->box_line_width
> 0)
2603 it
->ascent
+= face
->box_line_width
;
2604 it
->descent
+= face
->box_line_width
;
2607 else if (it
->char_to_display
== '\t')
2609 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2610 int x
= it
->current_x
+ it
->continuation_lines_width
;
2611 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2613 /* If the distance from the current position to the next tab
2614 stop is less than a canonical character width, use the
2615 tab stop after that. */
2616 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2617 next_tab_x
+= tab_width
;
2619 it
->pixel_width
= next_tab_x
- x
;
2621 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2622 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2626 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2627 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2628 it
->ascent
+ it
->descent
, ascent
);
2633 /* A multi-byte character. Assume that the display width of the
2634 character is the width of the character multiplied by the
2635 width of the font. */
2637 /* If we found a font, this font should give us the right
2638 metrics. If we didn't find a font, use the frame's
2639 default font and calculate the width of the character
2640 from the charset width; this is what old redisplay code
2642 pcm
= x_per_char_metric (font
, &char2b
);
2643 if (font_not_found_p
|| !pcm
)
2645 int charset
= CHAR_CHARSET (it
->char_to_display
);
2647 it
->glyph_not_available_p
= 1;
2648 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2649 * CHARSET_WIDTH (charset
));
2650 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2651 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2655 it
->pixel_width
= pcm
->width
;
2656 it
->phys_ascent
= pcm
->ascent
+ boff
;
2657 it
->phys_descent
= pcm
->descent
- boff
;
2659 && (pcm
->lbearing
< 0
2660 || pcm
->rbearing
> pcm
->width
))
2661 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2664 it
->ascent
= FONT_BASE (font
) + boff
;
2665 it
->descent
= FONT_DESCENT (font
) - boff
;
2666 if (face
->box
!= FACE_NO_BOX
)
2668 int thick
= face
->box_line_width
;
2672 it
->ascent
+= thick
;
2673 it
->descent
+= thick
;
2678 if (it
->start_of_box_run_p
)
2679 it
->pixel_width
+= thick
;
2680 if (it
->end_of_box_run_p
)
2681 it
->pixel_width
+= thick
;
2684 /* If face has an overline, add the height of the overline
2685 (1 pixel) and a 1 pixel margin to the character height. */
2686 if (face
->overline_p
)
2689 take_vertical_position_into_account (it
);
2692 x_append_glyph (it
);
2694 it
->multibyte_p
= saved_multibyte_p
;
2696 else if (it
->what
== IT_COMPOSITION
)
2698 /* Note: A composition is represented as one glyph in the
2699 glyph matrix. There are no padding glyphs. */
2702 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2704 int font_not_found_p
;
2705 struct font_info
*font_info
;
2706 int boff
; /* baseline offset */
2707 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2709 /* Maybe translate single-byte characters to multibyte. */
2710 it
->char_to_display
= it
->c
;
2711 if (unibyte_display_via_language_environment
2712 && SINGLE_BYTE_CHAR_P (it
->c
)
2715 && !NILP (Vnonascii_translation_table
))))
2717 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2720 /* Get face and font to use. Encode IT->char_to_display. */
2721 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2722 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2723 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2724 it
->face_id
, &char2b
, it
->multibyte_p
);
2727 /* When no suitable font found, use the default font. */
2728 font_not_found_p
= font
== NULL
;
2729 if (font_not_found_p
)
2731 font
= FRAME_FONT (it
->f
);
2732 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2737 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2738 boff
= font_info
->baseline_offset
;
2739 if (font_info
->vertical_centering
)
2740 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2743 /* There are no padding glyphs, so there is only one glyph to
2744 produce for the composition. Important is that pixel_width,
2745 ascent and descent are the values of what is drawn by
2746 draw_glyphs (i.e. the values of the overall glyphs composed). */
2749 /* If we have not yet calculated pixel size data of glyphs of
2750 the composition for the current face font, calculate them
2751 now. Theoretically, we have to check all fonts for the
2752 glyphs, but that requires much time and memory space. So,
2753 here we check only the font of the first glyph. This leads
2754 to incorrect display very rarely, and C-l (recenter) can
2755 correct the display anyway. */
2756 if (cmp
->font
!= (void *) font
)
2758 /* Ascent and descent of the font of the first character of
2759 this composition (adjusted by baseline offset). Ascent
2760 and descent of overall glyphs should not be less than
2761 them respectively. */
2762 int font_ascent
= FONT_BASE (font
) + boff
;
2763 int font_descent
= FONT_DESCENT (font
) - boff
;
2764 /* Bounding box of the overall glyphs. */
2765 int leftmost
, rightmost
, lowest
, highest
;
2766 int i
, width
, ascent
, descent
;
2768 cmp
->font
= (void *) font
;
2770 /* Initialize the bounding box. */
2771 pcm
= x_per_char_metric (font
, &char2b
);
2775 ascent
= pcm
->ascent
;
2776 descent
= pcm
->descent
;
2780 width
= FONT_WIDTH (font
);
2781 ascent
= FONT_BASE (font
);
2782 descent
= FONT_DESCENT (font
);
2786 lowest
= - descent
+ boff
;
2787 highest
= ascent
+ boff
;
2791 && font_info
->default_ascent
2792 && CHAR_TABLE_P (Vuse_default_ascent
)
2793 && !NILP (Faref (Vuse_default_ascent
,
2794 make_number (it
->char_to_display
))))
2795 highest
= font_info
->default_ascent
+ boff
;
2797 /* Draw the first glyph at the normal position. It may be
2798 shifted to right later if some other glyphs are drawn at
2800 cmp
->offsets
[0] = 0;
2801 cmp
->offsets
[1] = boff
;
2803 /* Set cmp->offsets for the remaining glyphs. */
2804 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2806 int left
, right
, btm
, top
;
2807 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2808 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2810 face
= FACE_FROM_ID (it
->f
, face_id
);
2811 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2816 font
= FRAME_FONT (it
->f
);
2817 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2823 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2824 boff
= font_info
->baseline_offset
;
2825 if (font_info
->vertical_centering
)
2826 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2829 pcm
= x_per_char_metric (font
, &char2b
);
2833 ascent
= pcm
->ascent
;
2834 descent
= pcm
->descent
;
2838 width
= FONT_WIDTH (font
);
2843 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2845 /* Relative composition with or without
2847 left
= (leftmost
+ rightmost
- width
) / 2;
2848 btm
= - descent
+ boff
;
2849 if (font_info
&& font_info
->relative_compose
2850 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2851 || NILP (Faref (Vignore_relative_composition
,
2852 make_number (ch
)))))
2855 if (- descent
>= font_info
->relative_compose
)
2856 /* One extra pixel between two glyphs. */
2858 else if (ascent
<= 0)
2859 /* One extra pixel between two glyphs. */
2860 btm
= lowest
- 1 - ascent
- descent
;
2865 /* A composition rule is specified by an integer
2866 value that encodes global and new reference
2867 points (GREF and NREF). GREF and NREF are
2868 specified by numbers as below:
2876 ---3---4---5--- baseline
2878 6---7---8 -- descent
2880 int rule
= COMPOSITION_RULE (cmp
, i
);
2881 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2883 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2884 grefx
= gref
% 3, nrefx
= nref
% 3;
2885 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2888 + grefx
* (rightmost
- leftmost
) / 2
2889 - nrefx
* width
/ 2);
2890 btm
= ((grefy
== 0 ? highest
2892 : grefy
== 2 ? lowest
2893 : (highest
+ lowest
) / 2)
2894 - (nrefy
== 0 ? ascent
+ descent
2895 : nrefy
== 1 ? descent
- boff
2897 : (ascent
+ descent
) / 2));
2900 cmp
->offsets
[i
* 2] = left
;
2901 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2903 /* Update the bounding box of the overall glyphs. */
2904 right
= left
+ width
;
2905 top
= btm
+ descent
+ ascent
;
2906 if (left
< leftmost
)
2908 if (right
> rightmost
)
2916 /* If there are glyphs whose x-offsets are negative,
2917 shift all glyphs to the right and make all x-offsets
2921 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2922 cmp
->offsets
[i
* 2] -= leftmost
;
2923 rightmost
-= leftmost
;
2926 cmp
->pixel_width
= rightmost
;
2927 cmp
->ascent
= highest
;
2928 cmp
->descent
= - lowest
;
2929 if (cmp
->ascent
< font_ascent
)
2930 cmp
->ascent
= font_ascent
;
2931 if (cmp
->descent
< font_descent
)
2932 cmp
->descent
= font_descent
;
2935 it
->pixel_width
= cmp
->pixel_width
;
2936 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2937 it
->descent
= it
->phys_descent
= cmp
->descent
;
2939 if (face
->box
!= FACE_NO_BOX
)
2941 int thick
= face
->box_line_width
;
2945 it
->ascent
+= thick
;
2946 it
->descent
+= thick
;
2951 if (it
->start_of_box_run_p
)
2952 it
->pixel_width
+= thick
;
2953 if (it
->end_of_box_run_p
)
2954 it
->pixel_width
+= thick
;
2957 /* If face has an overline, add the height of the overline
2958 (1 pixel) and a 1 pixel margin to the character height. */
2959 if (face
->overline_p
)
2962 take_vertical_position_into_account (it
);
2965 x_append_composite_glyph (it
);
2967 else if (it
->what
== IT_IMAGE
)
2968 x_produce_image_glyph (it
);
2969 else if (it
->what
== IT_STRETCH
)
2970 x_produce_stretch_glyph (it
);
2972 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2973 because this isn't true for images with `:ascent 100'. */
2974 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2975 if (it
->area
== TEXT_AREA
)
2976 it
->current_x
+= it
->pixel_width
;
2978 it
->descent
+= it
->extra_line_spacing
;
2980 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2981 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2982 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2983 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2987 /* Estimate the pixel height of the mode or top line on frame F.
2988 FACE_ID specifies what line's height to estimate. */
2991 x_estimate_mode_line_height (f
, face_id
)
2993 enum face_id face_id
;
2995 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2997 /* This function is called so early when Emacs starts that the face
2998 cache and mode line face are not yet initialized. */
2999 if (FRAME_FACE_CACHE (f
))
3001 struct face
*face
= FACE_FROM_ID (f
, face_id
);
3005 height
= FONT_HEIGHT (face
->font
);
3006 if (face
->box_line_width
> 0)
3007 height
+= 2 * face
->box_line_width
;
3015 /***********************************************************************
3017 ***********************************************************************/
3019 /* A sequence of glyphs to be drawn in the same face.
3021 This data structure is not really completely X specific, so it
3022 could possibly, at least partially, be useful for other systems. It
3023 is currently not part of the external redisplay interface because
3024 it's not clear what other systems will need. */
3028 /* X-origin of the string. */
3031 /* Y-origin and y-position of the base line of this string. */
3034 /* The width of the string, not including a face extension. */
3037 /* The width of the string, including a face extension. */
3038 int background_width
;
3040 /* The height of this string. This is the height of the line this
3041 string is drawn in, and can be different from the height of the
3042 font the string is drawn in. */
3045 /* Number of pixels this string overwrites in front of its x-origin.
3046 This number is zero if the string has an lbearing >= 0; it is
3047 -lbearing, if the string has an lbearing < 0. */
3050 /* Number of pixels this string overwrites past its right-most
3051 nominal x-position, i.e. x + width. Zero if the string's
3052 rbearing is <= its nominal width, rbearing - width otherwise. */
3055 /* The frame on which the glyph string is drawn. */
3058 /* The window on which the glyph string is drawn. */
3061 /* X display and window for convenience. */
3065 /* The glyph row for which this string was built. It determines the
3066 y-origin and height of the string. */
3067 struct glyph_row
*row
;
3069 /* The area within row. */
3070 enum glyph_row_area area
;
3072 /* Characters to be drawn, and number of characters. */
3076 /* A face-override for drawing cursors, mouse face and similar. */
3077 enum draw_glyphs_face hl
;
3079 /* Face in which this string is to be drawn. */
3082 /* Font in which this string is to be drawn. */
3085 /* Font info for this string. */
3086 struct font_info
*font_info
;
3088 /* Non-null means this string describes (part of) a composition.
3089 All characters from char2b are drawn composed. */
3090 struct composition
*cmp
;
3092 /* Index of this glyph string's first character in the glyph
3093 definition of CMP. If this is zero, this glyph string describes
3094 the first character of a composition. */
3097 /* 1 means this glyph strings face has to be drawn to the right end
3098 of the window's drawing area. */
3099 unsigned extends_to_end_of_line_p
: 1;
3101 /* 1 means the background of this string has been drawn. */
3102 unsigned background_filled_p
: 1;
3104 /* 1 means glyph string must be drawn with 16-bit functions. */
3105 unsigned two_byte_p
: 1;
3107 /* 1 means that the original font determined for drawing this glyph
3108 string could not be loaded. The member `font' has been set to
3109 the frame's default font in this case. */
3110 unsigned font_not_found_p
: 1;
3112 /* 1 means that the face in which this glyph string is drawn has a
3114 unsigned stippled_p
: 1;
3116 /* 1 means only the foreground of this glyph string must be drawn,
3117 and we should use the physical height of the line this glyph
3118 string appears in as clip rect. */
3119 unsigned for_overlaps_p
: 1;
3121 /* The GC to use for drawing this glyph string. */
3124 /* A pointer to the first glyph in the string. This glyph
3125 corresponds to char2b[0]. Needed to draw rectangles if
3126 font_not_found_p is 1. */
3127 struct glyph
*first_glyph
;
3129 /* Image, if any. */
3132 struct glyph_string
*next
, *prev
;
3139 x_dump_glyph_string (s
)
3140 struct glyph_string
*s
;
3142 fprintf (stderr
, "glyph string\n");
3143 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
3144 s
->x
, s
->y
, s
->width
, s
->height
);
3145 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
3146 fprintf (stderr
, " hl = %d\n", s
->hl
);
3147 fprintf (stderr
, " left overhang = %d, right = %d\n",
3148 s
->left_overhang
, s
->right_overhang
);
3149 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
3150 fprintf (stderr
, " extends to end of line = %d\n",
3151 s
->extends_to_end_of_line_p
);
3152 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
3153 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
3156 #endif /* GLYPH_DEBUG */
3160 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
3161 struct glyph_string
**,
3162 struct glyph_string
*,
3163 struct glyph_string
*));
3164 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
3165 struct glyph_string
**,
3166 struct glyph_string
*,
3167 struct glyph_string
*));
3168 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3169 struct glyph_string
**,
3170 struct glyph_string
*));
3171 static int x_left_overwritten
P_ ((struct glyph_string
*));
3172 static int x_left_overwriting
P_ ((struct glyph_string
*));
3173 static int x_right_overwritten
P_ ((struct glyph_string
*));
3174 static int x_right_overwriting
P_ ((struct glyph_string
*));
3175 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3177 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3178 XChar2b
*, struct window
*,
3180 enum glyph_row_area
, int,
3181 enum draw_glyphs_face
));
3182 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3183 enum glyph_row_area
, int, int,
3184 enum draw_glyphs_face
, int));
3185 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3186 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3187 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3189 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3190 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3191 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3192 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3193 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3194 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3195 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3196 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3197 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3199 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3200 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
3201 unsigned long *, double, int));*/
3202 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3203 double, int, unsigned long));
3204 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3205 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3206 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3207 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3208 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3209 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3210 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3212 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3213 int, int, int, int, Rect
*));
3214 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3215 int, int, int, Rect
*));
3216 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3217 enum glyph_row_area
));
3218 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3220 enum glyph_row_area
, int, int));
3223 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3227 /* Append the list of glyph strings with head H and tail T to the list
3228 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3231 x_append_glyph_string_lists (head
, tail
, h
, t
)
3232 struct glyph_string
**head
, **tail
;
3233 struct glyph_string
*h
, *t
;
3247 /* Prepend the list of glyph strings with head H and tail T to the
3248 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3252 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3253 struct glyph_string
**head
, **tail
;
3254 struct glyph_string
*h
, *t
;
3268 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3269 Set *HEAD and *TAIL to the resulting list. */
3272 x_append_glyph_string (head
, tail
, s
)
3273 struct glyph_string
**head
, **tail
;
3274 struct glyph_string
*s
;
3276 s
->next
= s
->prev
= NULL
;
3277 x_append_glyph_string_lists (head
, tail
, s
, s
);
3281 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3286 struct glyph_string
*s
;
3288 if (s
->font
== FRAME_FONT (s
->f
)
3289 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3290 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3292 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3295 /* Cursor on non-default face: must merge. */
3299 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3300 xgcv
.foreground
= s
->face
->background
;
3302 /* If the glyph would be invisible, try a different foreground. */
3303 if (xgcv
.foreground
== xgcv
.background
)
3304 xgcv
.foreground
= s
->face
->foreground
;
3305 if (xgcv
.foreground
== xgcv
.background
)
3306 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3307 if (xgcv
.foreground
== xgcv
.background
)
3308 xgcv
.foreground
= s
->face
->foreground
;
3310 /* Make sure the cursor is distinct from text in this face. */
3311 if (xgcv
.background
== s
->face
->background
3312 && xgcv
.foreground
== s
->face
->foreground
)
3314 xgcv
.background
= s
->face
->foreground
;
3315 xgcv
.foreground
= s
->face
->background
;
3318 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3319 xgcv
.font
= s
->font
;
3320 mask
= GCForeground
| GCBackground
| GCFont
;
3322 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3323 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3326 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3327 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3329 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3334 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3337 x_set_mouse_face_gc (s
)
3338 struct glyph_string
*s
;
3343 /* What face has to be used last for the mouse face? */
3344 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3345 face
= FACE_FROM_ID (s
->f
, face_id
);
3347 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3349 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3350 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3352 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3353 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3354 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3356 /* If font in this face is same as S->font, use it. */
3357 if (s
->font
== s
->face
->font
)
3358 s
->gc
= s
->face
->gc
;
3361 /* Otherwise construct scratch_cursor_gc with values from FACE
3366 xgcv
.background
= s
->face
->background
;
3367 xgcv
.foreground
= s
->face
->foreground
;
3368 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3369 xgcv
.font
= s
->font
;
3370 mask
= GCForeground
| GCBackground
| GCFont
;
3372 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3373 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3376 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3377 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3379 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3382 xassert (s
->gc
!= 0);
3386 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3387 Faces to use in the mode line have already been computed when the
3388 matrix was built, so there isn't much to do, here. */
3391 x_set_mode_line_face_gc (s
)
3392 struct glyph_string
*s
;
3394 s
->gc
= s
->face
->gc
;
3398 /* Set S->gc of glyph string S for drawing that glyph string. Set
3399 S->stippled_p to a non-zero value if the face of S has a stipple
3403 x_set_glyph_string_gc (s
)
3404 struct glyph_string
*s
;
3406 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3408 if (s
->hl
== DRAW_NORMAL_TEXT
)
3410 s
->gc
= s
->face
->gc
;
3411 s
->stippled_p
= s
->face
->stipple
!= 0;
3413 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3415 x_set_mode_line_face_gc (s
);
3416 s
->stippled_p
= s
->face
->stipple
!= 0;
3418 else if (s
->hl
== DRAW_CURSOR
)
3420 x_set_cursor_gc (s
);
3423 else if (s
->hl
== DRAW_MOUSE_FACE
)
3425 x_set_mouse_face_gc (s
);
3426 s
->stippled_p
= s
->face
->stipple
!= 0;
3428 else if (s
->hl
== DRAW_IMAGE_RAISED
3429 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3431 s
->gc
= s
->face
->gc
;
3432 s
->stippled_p
= s
->face
->stipple
!= 0;
3436 s
->gc
= s
->face
->gc
;
3437 s
->stippled_p
= s
->face
->stipple
!= 0;
3440 /* GC must have been set. */
3441 xassert (s
->gc
!= 0);
3445 /* Return in *R the clipping rectangle for glyph string S. */
3448 x_get_glyph_string_clip_rect (s
, r
)
3449 struct glyph_string
*s
;
3452 int r_height
, r_width
;
3454 if (s
->row
->full_width_p
)
3456 /* Draw full-width. X coordinates are relative to S->w->left. */
3457 int canon_x
= CANON_X_UNIT (s
->f
);
3459 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3460 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3462 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3464 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3465 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3469 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3471 /* Unless displaying a mode or menu bar line, which are always
3472 fully visible, clip to the visible part of the row. */
3473 if (s
->w
->pseudo_window_p
)
3474 r_height
= s
->row
->visible_height
;
3476 r_height
= s
->height
;
3480 /* This is a text line that may be partially visible. */
3481 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3482 r_width
= window_box_width (s
->w
, s
->area
);
3483 r_height
= s
->row
->visible_height
;
3486 /* If S draws overlapping rows, it's sufficient to use the top and
3487 bottom of the window for clipping because this glyph string
3488 intentionally draws over other lines. */
3489 if (s
->for_overlaps_p
)
3491 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3492 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3496 /* Don't use S->y for clipping because it doesn't take partially
3497 visible lines into account. For example, it can be negative for
3498 partially visible lines at the top of a window. */
3499 if (!s
->row
->full_width_p
3500 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3501 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3503 r
->top
= max (0, s
->row
->y
);
3505 /* If drawing a tool-bar window, draw it over the internal border
3506 at the top of the window. */
3507 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3508 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3511 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3513 r
->bottom
= r
->top
+ r_height
;
3514 r
->right
= r
->left
+ r_width
;
3518 /* Set clipping for output of glyph string S. S may be part of a mode
3519 line or menu if we don't have X toolkit support. */
3522 x_set_glyph_string_clipping (s
)
3523 struct glyph_string
*s
;
3526 x_get_glyph_string_clip_rect (s
, &r
);
3527 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3531 /* Compute left and right overhang of glyph string S. If S is a glyph
3532 string for a composition, assume overhangs don't exist. */
3535 x_compute_glyph_string_overhangs (s
)
3536 struct glyph_string
*s
;
3539 && s
->first_glyph
->type
== CHAR_GLYPH
)
3542 int direction
, font_ascent
, font_descent
;
3543 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3544 &font_ascent
, &font_descent
, &cs
);
3545 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3546 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3551 /* Compute overhangs and x-positions for glyph string S and its
3552 predecessors, or successors. X is the starting x-position for S.
3553 BACKWARD_P non-zero means process predecessors. */
3556 x_compute_overhangs_and_x (s
, x
, backward_p
)
3557 struct glyph_string
*s
;
3565 x_compute_glyph_string_overhangs (s
);
3575 x_compute_glyph_string_overhangs (s
);
3584 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3585 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3586 assumed to be zero. */
3589 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3590 struct glyph
*glyph
;
3596 if (glyph
->type
== CHAR_GLYPH
)
3600 struct font_info
*font_info
;
3604 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3606 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3608 && (pcm
= x_per_char_metric (font
, &char2b
)))
3610 if (pcm
->rbearing
> pcm
->width
)
3611 *right
= pcm
->rbearing
- pcm
->width
;
3612 if (pcm
->lbearing
< 0)
3613 *left
= -pcm
->lbearing
;
3619 /* Return the index of the first glyph preceding glyph string S that
3620 is overwritten by S because of S's left overhang. Value is -1
3621 if no glyphs are overwritten. */
3624 x_left_overwritten (s
)
3625 struct glyph_string
*s
;
3629 if (s
->left_overhang
)
3632 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3633 int first
= s
->first_glyph
- glyphs
;
3635 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3636 x
-= glyphs
[i
].pixel_width
;
3647 /* Return the index of the first glyph preceding glyph string S that
3648 is overwriting S because of its right overhang. Value is -1 if no
3649 glyph in front of S overwrites S. */
3652 x_left_overwriting (s
)
3653 struct glyph_string
*s
;
3656 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3657 int first
= s
->first_glyph
- glyphs
;
3661 for (i
= first
- 1; i
>= 0; --i
)
3664 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3667 x
-= glyphs
[i
].pixel_width
;
3674 /* Return the index of the last glyph following glyph string S that is
3675 not overwritten by S because of S's right overhang. Value is -1 if
3676 no such glyph is found. */
3679 x_right_overwritten (s
)
3680 struct glyph_string
*s
;
3684 if (s
->right_overhang
)
3687 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3688 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3689 int end
= s
->row
->used
[s
->area
];
3691 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3692 x
+= glyphs
[i
].pixel_width
;
3701 /* Return the index of the last glyph following glyph string S that
3702 overwrites S because of its left overhang. Value is negative
3703 if no such glyph is found. */
3706 x_right_overwriting (s
)
3707 struct glyph_string
*s
;
3710 int end
= s
->row
->used
[s
->area
];
3711 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3712 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3716 for (i
= first
; i
< end
; ++i
)
3719 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3722 x
+= glyphs
[i
].pixel_width
;
3729 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3732 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3733 struct glyph_string
*s
;
3738 xgcv
.foreground
= s
->gc
->background
;
3739 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3743 /* Draw the background of glyph_string S. If S->background_filled_p
3744 is non-zero don't draw it. FORCE_P non-zero means draw the
3745 background even if it wouldn't be drawn normally. This is used
3746 when a string preceding S draws into the background of S, or S
3747 contains the first component of a composition. */
3750 x_draw_glyph_string_background (s
, force_p
)
3751 struct glyph_string
*s
;
3754 /* Nothing to do if background has already been drawn or if it
3755 shouldn't be drawn in the first place. */
3756 if (!s
->background_filled_p
)
3758 int box_line_width
= max (s
->face
->box_line_width
, 0);
3760 #if 0 /* MAC_TODO: stipple */
3763 /* Fill background with a stipple pattern. */
3764 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3765 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3766 s
->y
+ box_line_width
,
3767 s
->background_width
,
3768 s
->height
- 2 * box_line_width
);
3769 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3770 s
->background_filled_p
= 1;
3774 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3775 || s
->font_not_found_p
3776 || s
->extends_to_end_of_line_p
3779 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3780 s
->background_width
,
3781 s
->height
- 2 * box_line_width
);
3782 s
->background_filled_p
= 1;
3788 /* Draw the foreground of glyph string S. */
3791 x_draw_glyph_string_foreground (s
)
3792 struct glyph_string
*s
;
3796 /* If first glyph of S has a left box line, start drawing the text
3797 of S to the right of that box line. */
3798 if (s
->face
->box
!= FACE_NO_BOX
3799 && s
->first_glyph
->left_box_line_p
)
3800 x
= s
->x
+ abs (s
->face
->box_line_width
);
3804 /* Draw characters of S as rectangles if S's font could not be
3806 if (s
->font_not_found_p
)
3808 for (i
= 0; i
< s
->nchars
; ++i
)
3810 struct glyph
*g
= s
->first_glyph
+ i
;
3811 mac_draw_rectangle (s
->display
, s
->window
,
3812 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3814 x
+= g
->pixel_width
;
3819 char *char1b
= (char *) s
->char2b
;
3820 int boff
= s
->font_info
->baseline_offset
;
3822 if (s
->font_info
->vertical_centering
)
3823 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3825 /* If we can use 8-bit functions, condense S->char2b. */
3827 for (i
= 0; i
< s
->nchars
; ++i
)
3828 char1b
[i
] = s
->char2b
[i
].byte2
;
3830 /* Draw text with XDrawString if background has already been
3831 filled. Otherwise, use XDrawImageString. (Note that
3832 XDrawImageString is usually faster than XDrawString.) Always
3833 use XDrawImageString when drawing the cursor so that there is
3834 no chance that characters under a box cursor are invisible. */
3835 if (s
->for_overlaps_p
3836 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3838 /* Draw characters with 16-bit or 8-bit functions. */
3840 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3841 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3843 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3844 s
->ybase
- boff
, char1b
, s
->nchars
);
3849 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3850 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3852 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3853 s
->ybase
- boff
, char1b
, s
->nchars
);
3858 /* Draw the foreground of composite glyph string S. */
3861 x_draw_composite_glyph_string_foreground (s
)
3862 struct glyph_string
*s
;
3866 /* If first glyph of S has a left box line, start drawing the text
3867 of S to the right of that box line. */
3868 if (s
->face
->box
!= FACE_NO_BOX
3869 && s
->first_glyph
->left_box_line_p
)
3870 x
= s
->x
+ abs (s
->face
->box_line_width
);
3874 /* S is a glyph string for a composition. S->gidx is the index of
3875 the first character drawn for glyphs of this composition.
3876 S->gidx == 0 means we are drawing the very first character of
3877 this composition. */
3879 /* Draw a rectangle for the composition if the font for the very
3880 first character of the composition could not be loaded. */
3881 if (s
->font_not_found_p
)
3884 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3885 s
->width
- 1, s
->height
- 1);
3889 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3890 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3891 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3892 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3898 #ifdef USE_X_TOOLKIT
3900 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3903 /* Return the frame on which widget WIDGET is used.. Abort if frame
3904 cannot be determined. */
3906 static struct frame
*
3907 x_frame_of_widget (widget
)
3910 struct x_display_info
*dpyinfo
;
3914 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3916 /* Find the top-level shell of the widget. Note that this function
3917 can be called when the widget is not yet realized, so XtWindow
3918 (widget) == 0. That's the reason we can't simply use
3919 x_any_window_to_frame. */
3920 while (!XtIsTopLevelShell (widget
))
3921 widget
= XtParent (widget
);
3923 /* Look for a frame with that top-level widget. Allocate the color
3924 on that frame to get the right gamma correction value. */
3925 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3926 if (GC_FRAMEP (XCAR (tail
))
3927 && (f
= XFRAME (XCAR (tail
)),
3928 (f
->output_data
.nothing
!= 1
3929 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3930 && f
->output_data
.x
->widget
== widget
)
3937 /* Allocate the color COLOR->pixel on the screen and display of
3938 widget WIDGET in colormap CMAP. If an exact match cannot be
3939 allocated, try the nearest color available. Value is non-zero
3940 if successful. This is called from lwlib. */
3943 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3948 struct frame
*f
= x_frame_of_widget (widget
);
3949 return x_alloc_nearest_color (f
, cmap
, color
);
3953 #endif /* USE_X_TOOLKIT */
3955 #if 0 /* MAC_TODO */
3957 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3958 CMAP. If an exact match can't be allocated, try the nearest color
3959 available. Value is non-zero if successful. Set *COLOR to the
3963 x_alloc_nearest_color (f
, cmap
, color
)
3968 Display
*display
= FRAME_X_DISPLAY (f
);
3969 Screen
*screen
= FRAME_X_SCREEN (f
);
3972 gamma_correct (f
, color
);
3973 rc
= XAllocColor (display
, cmap
, color
);
3976 /* If we got to this point, the colormap is full, so we're going
3977 to try to get the next closest color. The algorithm used is
3978 a least-squares matching, which is what X uses for closest
3979 color matching with StaticColor visuals. */
3981 unsigned long nearest_delta
= ~0;
3982 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3983 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3985 for (i
= 0; i
< ncells
; ++i
)
3987 XQueryColors (display
, cmap
, cells
, ncells
);
3989 for (nearest
= i
= 0; i
< ncells
; ++i
)
3991 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3992 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3993 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3994 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3996 if (delta
< nearest_delta
)
3999 nearest_delta
= delta
;
4003 color
->red
= cells
[nearest
].red
;
4004 color
->green
= cells
[nearest
].green
;
4005 color
->blue
= cells
[nearest
].blue
;
4006 rc
= XAllocColor (display
, cmap
, color
);
4009 #ifdef DEBUG_X_COLORS
4011 register_color (color
->pixel
);
4012 #endif /* DEBUG_X_COLORS */
4018 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
4019 It's necessary to do this instead of just using PIXEL directly to
4020 get color reference counts right. */
4023 x_copy_color (f
, pixel
)
4025 unsigned long pixel
;
4029 color
.pixel
= pixel
;
4031 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4032 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4034 #ifdef DEBUG_X_COLORS
4035 register_color (pixel
);
4041 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
4042 It's necessary to do this instead of just using PIXEL directly to
4043 get color reference counts right. */
4046 x_copy_dpy_color (dpy
, cmap
, pixel
)
4049 unsigned long pixel
;
4053 color
.pixel
= pixel
;
4055 XQueryColor (dpy
, cmap
, &color
);
4056 XAllocColor (dpy
, cmap
, &color
);
4058 #ifdef DEBUG_X_COLORS
4059 register_color (pixel
);
4064 #endif /* MAC_TODO */
4066 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
4067 or DELTA. Try a color with RGB values multiplied by FACTOR first.
4068 If this produces the same color as COLOR, try a color where all RGB
4069 values have DELTA added. Return the allocated color in *COLOR.
4070 DISPLAY is the X display, CMAP is the colormap to operate on.
4071 Value is non-zero if successful. */
4074 mac_alloc_lighter_color (f
, color
, factor
, delta
)
4076 unsigned long *color
;
4082 /* Change RGB values by specified FACTOR. Avoid overflow! */
4083 xassert (factor
>= 0);
4084 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
4085 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
4086 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
4088 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
4089 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
4090 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
4092 /* MAC_TODO: Map to palette and retry with delta if same? */
4093 /* MAC_TODO: Free colors (if using palette)? */
4104 /* Set up the foreground color for drawing relief lines of glyph
4105 string S. RELIEF is a pointer to a struct relief containing the GC
4106 with which lines will be drawn. Use a color that is FACTOR or
4107 DELTA lighter or darker than the relief's background which is found
4108 in S->f->output_data.x->relief_background. If such a color cannot
4109 be allocated, use DEFAULT_PIXEL, instead. */
4112 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
4114 struct relief
*relief
;
4117 unsigned long default_pixel
;
4120 struct mac_output
*di
= f
->output_data
.mac
;
4121 unsigned long mask
= GCForeground
;
4122 unsigned long pixel
;
4123 unsigned long background
= di
->relief_background
;
4124 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4126 /* MAC_TODO: Free colors (if using palette)? */
4128 /* Allocate new color. */
4129 xgcv
.foreground
= default_pixel
;
4131 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
4133 relief
->allocated_p
= 1;
4134 xgcv
.foreground
= relief
->pixel
= pixel
;
4137 if (relief
->gc
== 0)
4139 #if 0 /* MAC_TODO: stipple */
4140 xgcv
.stipple
= dpyinfo
->gray
;
4143 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
4146 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
4150 /* Set up colors for the relief lines around glyph string S. */
4153 x_setup_relief_colors (s
)
4154 struct glyph_string
*s
;
4156 struct mac_output
*di
= s
->f
->output_data
.mac
;
4157 unsigned long color
;
4159 if (s
->face
->use_box_color_for_shadows_p
)
4160 color
= s
->face
->box_color
;
4165 /* Get the background color of the face. */
4166 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
4167 color
= xgcv
.background
;
4170 if (di
->white_relief
.gc
== 0
4171 || color
!= di
->relief_background
)
4173 di
->relief_background
= color
;
4174 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
4175 WHITE_PIX_DEFAULT (s
->f
));
4176 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4177 BLACK_PIX_DEFAULT (s
->f
));
4182 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4183 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4184 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4185 relief. LEFT_P non-zero means draw a relief on the left side of
4186 the rectangle. RIGHT_P non-zero means draw a relief on the right
4187 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4191 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4192 raised_p
, left_p
, right_p
, clip_rect
)
4194 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4201 gc
= f
->output_data
.mac
->white_relief
.gc
;
4203 gc
= f
->output_data
.mac
->black_relief
.gc
;
4204 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4207 for (i
= 0; i
< width
; ++i
)
4208 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4209 left_x
+ i
* left_p
, top_y
+ i
,
4210 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4214 for (i
= 0; i
< width
; ++i
)
4215 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4216 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4218 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4220 gc
= f
->output_data
.mac
->black_relief
.gc
;
4222 gc
= f
->output_data
.mac
->white_relief
.gc
;
4223 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4227 for (i
= 0; i
< width
; ++i
)
4228 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4229 left_x
+ i
* left_p
, bottom_y
- i
,
4230 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4234 for (i
= 0; i
< width
; ++i
)
4235 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4236 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4238 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4242 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4243 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4244 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4245 left side of the rectangle. RIGHT_P non-zero means draw a line
4246 on the right side of the rectangle. CLIP_RECT is the clipping
4247 rectangle to use when drawing. */
4250 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4251 left_p
, right_p
, clip_rect
)
4252 struct glyph_string
*s
;
4253 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4258 xgcv
.foreground
= s
->face
->box_color
;
4259 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4262 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4263 left_x
, top_y
, right_x
- left_x
, width
);
4267 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4268 left_x
, top_y
, width
, bottom_y
- top_y
);
4271 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4272 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4276 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4277 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4279 mac_reset_clipping (s
->display
, s
->window
);
4283 /* Draw a box around glyph string S. */
4286 x_draw_glyph_string_box (s
)
4287 struct glyph_string
*s
;
4289 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4290 int left_p
, right_p
;
4291 struct glyph
*last_glyph
;
4294 last_x
= window_box_right (s
->w
, s
->area
);
4295 if (s
->row
->full_width_p
4296 && !s
->w
->pseudo_window_p
)
4298 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4299 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4300 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4303 /* The glyph that may have a right box line. */
4304 last_glyph
= (s
->cmp
|| s
->img
4306 : s
->first_glyph
+ s
->nchars
- 1);
4308 width
= abs (s
->face
->box_line_width
);
4309 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4311 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4313 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4315 bottom_y
= top_y
+ s
->height
- 1;
4317 left_p
= (s
->first_glyph
->left_box_line_p
4318 || (s
->hl
== DRAW_MOUSE_FACE
4320 || s
->prev
->hl
!= s
->hl
)));
4321 right_p
= (last_glyph
->right_box_line_p
4322 || (s
->hl
== DRAW_MOUSE_FACE
4324 || s
->next
->hl
!= s
->hl
)));
4326 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4328 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4329 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4330 left_p
, right_p
, &clip_rect
);
4333 x_setup_relief_colors (s
);
4334 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4335 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4340 /* Draw foreground of image glyph string S. */
4343 x_draw_image_foreground (s
)
4344 struct glyph_string
*s
;
4347 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4349 /* If first glyph of S has a left box line, start drawing it to the
4350 right of that line. */
4351 if (s
->face
->box
!= FACE_NO_BOX
4352 && s
->first_glyph
->left_box_line_p
)
4353 x
= s
->x
+ abs (s
->face
->box_line_width
);
4357 /* If there is a margin around the image, adjust x- and y-position
4359 x
+= s
->img
->hmargin
;
4360 y
+= s
->img
->vmargin
;
4364 #if 0 /* MAC_TODO: image mask */
4367 /* We can't set both a clip mask and use XSetClipRectangles
4368 because the latter also sets a clip mask. We also can't
4369 trust on the shape extension to be available
4370 (XShapeCombineRegion). So, compute the rectangle to draw
4372 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4375 XRectangle clip_rect
, image_rect
, r
;
4377 xgcv
.clip_mask
= s
->img
->mask
;
4378 xgcv
.clip_x_origin
= x
;
4379 xgcv
.clip_y_origin
= y
;
4380 xgcv
.function
= GXcopy
;
4381 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4383 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4386 image_rect
.width
= s
->img
->width
;
4387 image_rect
.height
= s
->img
->height
;
4388 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4389 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4390 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4393 #endif /* MAC_TODO */
4395 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4396 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4398 /* When the image has a mask, we can expect that at
4399 least part of a mouse highlight or a block cursor will
4400 be visible. If the image doesn't have a mask, make
4401 a block cursor visible by drawing a rectangle around
4402 the image. I believe it's looking better if we do
4403 nothing here for mouse-face. */
4404 if (s
->hl
== DRAW_CURSOR
)
4406 int r
= s
->img
->relief
;
4408 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4409 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4414 /* Draw a rectangle if image could not be loaded. */
4415 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4416 s
->img
->width
- 1, s
->img
->height
- 1);
4421 /* Draw a relief around the image glyph string S. */
4424 x_draw_image_relief (s
)
4425 struct glyph_string
*s
;
4427 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4430 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4432 /* If first glyph of S has a left box line, start drawing it to the
4433 right of that line. */
4434 if (s
->face
->box
!= FACE_NO_BOX
4435 && s
->first_glyph
->left_box_line_p
)
4436 x
= s
->x
+ abs (s
->face
->box_line_width
);
4440 /* If there is a margin around the image, adjust x- and y-position
4442 x
+= s
->img
->hmargin
;
4443 y
+= s
->img
->vmargin
;
4445 if (s
->hl
== DRAW_IMAGE_SUNKEN
4446 || s
->hl
== DRAW_IMAGE_RAISED
)
4448 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4449 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4453 thick
= abs (s
->img
->relief
);
4454 raised_p
= s
->img
->relief
> 0;
4459 x1
= x
+ s
->img
->width
+ thick
- 1;
4460 y1
= y
+ s
->img
->height
+ thick
- 1;
4462 x_setup_relief_colors (s
);
4463 x_get_glyph_string_clip_rect (s
, &r
);
4464 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4468 /* Draw the foreground of image glyph string S to PIXMAP. */
4471 x_draw_image_foreground_1 (s
, pixmap
)
4472 struct glyph_string
*s
;
4476 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4478 /* If first glyph of S has a left box line, start drawing it to the
4479 right of that line. */
4480 if (s
->face
->box
!= FACE_NO_BOX
4481 && s
->first_glyph
->left_box_line_p
)
4482 x
= abs (s
->face
->box_line_width
);
4486 /* If there is a margin around the image, adjust x- and y-position
4488 x
+= s
->img
->hmargin
;
4489 y
+= s
->img
->vmargin
;
4493 #if 0 /* MAC_TODO: image mask */
4496 /* We can't set both a clip mask and use XSetClipRectangles
4497 because the latter also sets a clip mask. We also can't
4498 trust on the shape extension to be available
4499 (XShapeCombineRegion). So, compute the rectangle to draw
4501 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4505 xgcv
.clip_mask
= s
->img
->mask
;
4506 xgcv
.clip_x_origin
= x
;
4507 xgcv
.clip_y_origin
= y
;
4508 xgcv
.function
= GXcopy
;
4509 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4511 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4512 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4513 XSetClipMask (s
->display
, s
->gc
, None
);
4516 #endif /* MAC_TODO */
4518 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4519 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4521 /* When the image has a mask, we can expect that at
4522 least part of a mouse highlight or a block cursor will
4523 be visible. If the image doesn't have a mask, make
4524 a block cursor visible by drawing a rectangle around
4525 the image. I believe it's looking better if we do
4526 nothing here for mouse-face. */
4527 if (s
->hl
== DRAW_CURSOR
)
4529 int r
= s
->img
->relief
;
4531 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
4532 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4537 /* Draw a rectangle if image could not be loaded. */
4538 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4539 s
->img
->width
- 1, s
->img
->height
- 1);
4543 /* Draw part of the background of glyph string S. X, Y, W, and H
4544 give the rectangle to draw. */
4547 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4548 struct glyph_string
*s
;
4551 #if 0 /* MAC_TODO: stipple */
4554 /* Fill background with a stipple pattern. */
4555 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4556 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4557 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4560 #endif /* MAC_TODO */
4561 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4565 /* Draw image glyph string S.
4568 s->x +-------------------------
4571 | +-------------------------
4574 | | +-------------------
4580 x_draw_image_glyph_string (s
)
4581 struct glyph_string
*s
;
4584 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4585 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4589 height
= s
->height
- 2 * box_line_vwidth
;
4591 /* Fill background with face under the image. Do it only if row is
4592 taller than image or if image has a clip mask to reduce
4594 s
->stippled_p
= s
->face
->stipple
!= 0;
4595 if (height
> s
->img
->height
4598 #if 0 /* TODO: image mask */
4601 || s
->img
->pixmap
== 0
4602 || s
->width
!= s
->background_width
)
4604 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4605 x
= s
->x
+ box_line_hwidth
;
4609 y
= s
->y
+ box_line_vwidth
;
4610 #if 0 /* TODO: image mask */
4613 /* Create a pixmap as large as the glyph string. Fill it
4614 with the background color. Copy the image to it, using
4615 its mask. Copy the temporary pixmap to the display. */
4616 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4617 int depth
= DefaultDepthOfScreen (screen
);
4619 /* Create a pixmap as large as the glyph string. */
4620 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4621 s
->background_width
,
4624 /* Don't clip in the following because we're working on the
4626 XSetClipMask (s
->display
, s
->gc
, None
);
4628 /* Fill the pixmap with the background color/stipple. */
4631 /* Fill background with a stipple pattern. */
4632 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4633 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4634 0, 0, s
->background_width
, s
->height
);
4635 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4640 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4642 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4643 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4644 0, 0, s
->background_width
, s
->height
);
4645 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4650 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4652 s
->background_filled_p
= 1;
4655 /* Draw the foreground. */
4658 x_draw_image_foreground_1 (s
, pixmap
);
4659 x_set_glyph_string_clipping (s
);
4660 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4661 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4662 mac_reset_clipping (s
->display
, s
->window
);
4663 XFreePixmap (s
->display
, pixmap
);
4666 x_draw_image_foreground (s
);
4668 /* If we must draw a relief around the image, do it. */
4670 || s
->hl
== DRAW_IMAGE_RAISED
4671 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4672 x_draw_image_relief (s
);
4676 /* Draw stretch glyph string S. */
4679 x_draw_stretch_glyph_string (s
)
4680 struct glyph_string
*s
;
4682 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4683 s
->stippled_p
= s
->face
->stipple
!= 0;
4685 if (s
->hl
== DRAW_CURSOR
4686 && !x_stretch_cursor_p
)
4688 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4689 as wide as the stretch glyph. */
4690 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4693 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4695 /* Clear rest using the GC of the original non-cursor face. */
4696 if (width
< s
->background_width
)
4698 GC gc
= s
->face
->gc
;
4699 int x
= s
->x
+ width
, y
= s
->y
;
4700 int w
= s
->background_width
- width
, h
= s
->height
;
4703 if (s
->row
->mouse_face_p
4704 && cursor_in_mouse_face_p (s
->w
))
4706 x_set_mouse_face_gc (s
);
4712 x_get_glyph_string_clip_rect (s
, &r
);
4713 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4715 #if 0 /* MAC_TODO: stipple */
4716 if (s
->face
->stipple
)
4718 /* Fill background with a stipple pattern. */
4719 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4720 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4721 XSetFillStyle (s
->display
, gc
, FillSolid
);
4724 #endif /* MAC_TODO */
4727 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4728 XSetForeground (s
->display
, gc
, xgcv
.background
);
4729 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4730 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4733 mac_reset_clipping (s
->display
, s
->window
);
4736 else if (!s
->background_filled_p
)
4737 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4740 s
->background_filled_p
= 1;
4744 /* Draw glyph string S. */
4747 x_draw_glyph_string (s
)
4748 struct glyph_string
*s
;
4750 int relief_drawn_p
= 0;
4752 /* If S draws into the background of its successor, draw the
4753 background of the successor first so that S can draw into it.
4754 This makes S->next use XDrawString instead of XDrawImageString. */
4755 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4757 xassert (s
->next
->img
== NULL
);
4758 x_set_glyph_string_gc (s
->next
);
4759 x_set_glyph_string_clipping (s
->next
);
4760 x_draw_glyph_string_background (s
->next
, 1);
4764 /* Set up S->gc, set clipping and draw S. */
4765 x_set_glyph_string_gc (s
);
4767 /* Draw relief (if any) in advance for char/composition so that the
4768 glyph string can be drawn over it. */
4769 if (!s
->for_overlaps_p
4770 && s
->face
->box
!= FACE_NO_BOX
4771 && (s
->first_glyph
->type
== CHAR_GLYPH
4772 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4775 x_set_glyph_string_clipping (s
);
4776 x_draw_glyph_string_background (s
, 1);
4777 x_draw_glyph_string_box (s
);
4778 x_set_glyph_string_clipping (s
);
4782 x_set_glyph_string_clipping (s
);
4784 switch (s
->first_glyph
->type
)
4787 x_draw_image_glyph_string (s
);
4791 x_draw_stretch_glyph_string (s
);
4795 if (s
->for_overlaps_p
)
4796 s
->background_filled_p
= 1;
4798 x_draw_glyph_string_background (s
, 0);
4799 x_draw_glyph_string_foreground (s
);
4802 case COMPOSITE_GLYPH
:
4803 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4804 s
->background_filled_p
= 1;
4806 x_draw_glyph_string_background (s
, 1);
4807 x_draw_composite_glyph_string_foreground (s
);
4814 if (!s
->for_overlaps_p
)
4816 /* Draw underline. */
4817 if (s
->face
->underline_p
)
4819 unsigned long h
= 1;
4820 unsigned long dy
= s
->height
- h
;
4822 if (s
->face
->underline_defaulted_p
)
4823 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4828 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4829 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4830 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4832 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4836 /* Draw overline. */
4837 if (s
->face
->overline_p
)
4839 unsigned long dy
= 0, h
= 1;
4841 if (s
->face
->overline_color_defaulted_p
)
4842 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4847 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4848 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4849 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4851 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4855 /* Draw strike-through. */
4856 if (s
->face
->strike_through_p
)
4858 unsigned long h
= 1;
4859 unsigned long dy
= (s
->height
- h
) / 2;
4861 if (s
->face
->strike_through_color_defaulted_p
)
4862 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4867 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4868 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4869 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4871 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4876 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4877 x_draw_glyph_string_box (s
);
4880 /* Reset clipping. */
4881 mac_reset_clipping (s
->display
, s
->window
);
4885 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4886 struct face
**, int));
4889 /* Fill glyph string S with composition components specified by S->cmp.
4891 FACES is an array of faces for all components of this composition.
4892 S->gidx is the index of the first component for S.
4893 OVERLAPS_P non-zero means S should draw the foreground only, and
4894 use its physical height for clipping.
4896 Value is the index of a component not in S. */
4899 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4900 struct glyph_string
*s
;
4901 struct face
**faces
;
4908 s
->for_overlaps_p
= overlaps_p
;
4910 s
->face
= faces
[s
->gidx
];
4911 s
->font
= s
->face
->font
;
4912 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4914 /* For all glyphs of this composition, starting at the offset
4915 S->gidx, until we reach the end of the definition or encounter a
4916 glyph that requires the different face, add it to S. */
4918 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4921 /* All glyph strings for the same composition has the same width,
4922 i.e. the width set for the first component of the composition. */
4924 s
->width
= s
->first_glyph
->pixel_width
;
4926 /* If the specified font could not be loaded, use the frame's
4927 default font, but record the fact that we couldn't load it in
4928 the glyph string so that we can draw rectangles for the
4929 characters of the glyph string. */
4930 if (s
->font
== NULL
)
4932 s
->font_not_found_p
= 1;
4933 s
->font
= FRAME_FONT (s
->f
);
4936 /* Adjust base line for subscript/superscript text. */
4937 s
->ybase
+= s
->first_glyph
->voffset
;
4939 xassert (s
->face
&& s
->face
->gc
);
4941 /* This glyph string must always be drawn with 16-bit functions. */
4944 return s
->gidx
+ s
->nchars
;
4948 /* Fill glyph string S from a sequence of character glyphs.
4950 FACE_ID is the face id of the string. START is the index of the
4951 first glyph to consider, END is the index of the last + 1.
4952 OVERLAPS_P non-zero means S should draw the foreground only, and
4953 use its physical height for clipping.
4955 Value is the index of the first glyph not in S. */
4958 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4959 struct glyph_string
*s
;
4961 int start
, end
, overlaps_p
;
4963 struct glyph
*glyph
, *last
;
4965 int glyph_not_available_p
;
4967 xassert (s
->f
== XFRAME (s
->w
->frame
));
4968 xassert (s
->nchars
== 0);
4969 xassert (start
>= 0 && end
> start
);
4971 s
->for_overlaps_p
= overlaps_p
;
4972 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4973 last
= s
->row
->glyphs
[s
->area
] + end
;
4974 voffset
= glyph
->voffset
;
4976 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4979 && glyph
->type
== CHAR_GLYPH
4980 && glyph
->voffset
== voffset
4981 /* Same face id implies same font, nowadays. */
4982 && glyph
->face_id
== face_id
4983 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4987 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4988 s
->char2b
+ s
->nchars
,
4990 s
->two_byte_p
= two_byte_p
;
4992 xassert (s
->nchars
<= end
- start
);
4993 s
->width
+= glyph
->pixel_width
;
4997 s
->font
= s
->face
->font
;
4998 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5000 /* If the specified font could not be loaded, use the frame's font,
5001 but record the fact that we couldn't load it in
5002 S->font_not_found_p so that we can draw rectangles for the
5003 characters of the glyph string. */
5004 if (s
->font
== NULL
|| glyph_not_available_p
)
5006 s
->font_not_found_p
= 1;
5007 s
->font
= FRAME_FONT (s
->f
);
5010 /* Adjust base line for subscript/superscript text. */
5011 s
->ybase
+= voffset
;
5013 xassert (s
->face
&& s
->face
->gc
);
5014 return glyph
- s
->row
->glyphs
[s
->area
];
5018 /* Fill glyph string S from image glyph S->first_glyph. */
5021 x_fill_image_glyph_string (s
)
5022 struct glyph_string
*s
;
5024 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
5025 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
5027 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
5028 s
->font
= s
->face
->font
;
5029 s
->width
= s
->first_glyph
->pixel_width
;
5031 /* Adjust base line for subscript/superscript text. */
5032 s
->ybase
+= s
->first_glyph
->voffset
;
5036 /* Fill glyph string S from a sequence of stretch glyphs.
5038 ROW is the glyph row in which the glyphs are found, AREA is the
5039 area within the row. START is the index of the first glyph to
5040 consider, END is the index of the last + 1.
5042 Value is the index of the first glyph not in S. */
5045 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
5046 struct glyph_string
*s
;
5047 struct glyph_row
*row
;
5048 enum glyph_row_area area
;
5051 struct glyph
*glyph
, *last
;
5052 int voffset
, face_id
;
5054 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
5056 glyph
= s
->row
->glyphs
[s
->area
] + start
;
5057 last
= s
->row
->glyphs
[s
->area
] + end
;
5058 face_id
= glyph
->face_id
;
5059 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
5060 s
->font
= s
->face
->font
;
5061 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5062 s
->width
= glyph
->pixel_width
;
5063 voffset
= glyph
->voffset
;
5067 && glyph
->type
== STRETCH_GLYPH
5068 && glyph
->voffset
== voffset
5069 && glyph
->face_id
== face_id
);
5071 s
->width
+= glyph
->pixel_width
;
5073 /* Adjust base line for subscript/superscript text. */
5074 s
->ybase
+= voffset
;
5077 return glyph
- s
->row
->glyphs
[s
->area
];
5081 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
5082 of XChar2b structures for S; it can't be allocated in
5083 x_init_glyph_string because it must be allocated via `alloca'. W
5084 is the window on which S is drawn. ROW and AREA are the glyph row
5085 and area within the row from which S is constructed. START is the
5086 index of the first glyph structure covered by S. HL is a
5087 face-override for drawing S. */
5090 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
5091 struct glyph_string
*s
;
5094 struct glyph_row
*row
;
5095 enum glyph_row_area area
;
5097 enum draw_glyphs_face hl
;
5099 bzero (s
, sizeof *s
);
5101 s
->f
= XFRAME (w
->frame
);
5102 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
5103 s
->window
= FRAME_MAC_WINDOW (s
->f
);
5108 s
->first_glyph
= row
->glyphs
[area
] + start
;
5109 s
->height
= row
->height
;
5110 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5112 /* Display the internal border below the tool-bar window. */
5113 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
5114 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
5116 s
->ybase
= s
->y
+ row
->ascent
;
5120 /* Set background width of glyph string S. START is the index of the
5121 first glyph following S. LAST_X is the right-most x-position + 1
5122 in the drawing area. */
5125 x_set_glyph_string_background_width (s
, start
, last_x
)
5126 struct glyph_string
*s
;
5130 /* If the face of this glyph string has to be drawn to the end of
5131 the drawing area, set S->extends_to_end_of_line_p. */
5132 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
5134 if (start
== s
->row
->used
[s
->area
]
5135 && s
->area
== TEXT_AREA
5136 && ((s
->hl
== DRAW_NORMAL_TEXT
5137 && (s
->row
->fill_line_p
5138 || s
->face
->background
!= default_face
->background
5139 || s
->face
->stipple
!= default_face
->stipple
5140 || s
->row
->mouse_face_p
))
5141 || s
->hl
== DRAW_MOUSE_FACE
5142 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
5143 && s
->row
->fill_line_p
)))
5144 s
->extends_to_end_of_line_p
= 1;
5146 /* If S extends its face to the end of the line, set its
5147 background_width to the distance to the right edge of the drawing
5149 if (s
->extends_to_end_of_line_p
)
5150 s
->background_width
= last_x
- s
->x
+ 1;
5152 s
->background_width
= s
->width
;
5156 /* Add a glyph string for a stretch glyph to the list of strings
5157 between HEAD and TAIL. START is the index of the stretch glyph in
5158 row area AREA of glyph row ROW. END is the index of the last glyph
5159 in that glyph row area. X is the current output position assigned
5160 to the new glyph string constructed. HL overrides that face of the
5161 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5162 is the right-most x-position of the drawing area. */
5164 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
5165 and below -- keep them on one line. */
5166 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5169 s = (struct glyph_string *) alloca (sizeof *s); \
5170 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5171 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
5172 x_append_glyph_string (&HEAD, &TAIL, s); \
5178 /* Add a glyph string for an image glyph to the list of strings
5179 between HEAD and TAIL. START is the index of the image glyph in
5180 row area AREA of glyph row ROW. END is the index of the last glyph
5181 in that glyph row area. X is the current output position assigned
5182 to the new glyph string constructed. HL overrides that face of the
5183 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5184 is the right-most x-position of the drawing area. */
5186 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5189 s = (struct glyph_string *) alloca (sizeof *s); \
5190 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5191 x_fill_image_glyph_string (s); \
5192 x_append_glyph_string (&HEAD, &TAIL, s); \
5199 /* Add a glyph string for a sequence of character glyphs to the list
5200 of strings between HEAD and TAIL. START is the index of the first
5201 glyph in row area AREA of glyph row ROW that is part of the new
5202 glyph string. END is the index of the last glyph in that glyph row
5203 area. X is the current output position assigned to the new glyph
5204 string constructed. HL overrides that face of the glyph; e.g. it
5205 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
5206 right-most x-position of the drawing area. */
5208 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5214 c = (ROW)->glyphs[AREA][START].u.ch; \
5215 face_id = (ROW)->glyphs[AREA][START].face_id; \
5217 s = (struct glyph_string *) alloca (sizeof *s); \
5218 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5219 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5220 x_append_glyph_string (&HEAD, &TAIL, s); \
5222 START = x_fill_glyph_string (s, face_id, START, END, \
5228 /* Add a glyph string for a composite sequence to the list of strings
5229 between HEAD and TAIL. START is the index of the first glyph in
5230 row area AREA of glyph row ROW that is part of the new glyph
5231 string. END is the index of the last glyph in that glyph row area.
5232 X is the current output position assigned to the new glyph string
5233 constructed. HL overrides that face of the glyph; e.g. it is
5234 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5235 x-position of the drawing area. */
5237 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5239 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5240 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5241 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5242 struct composition *cmp = composition_table[cmp_id]; \
5243 int glyph_len = cmp->glyph_len; \
5245 struct face **faces; \
5246 struct glyph_string *first_s = NULL; \
5249 base_face = base_face->ascii_face; \
5250 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5251 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5252 /* At first, fill in `char2b' and `faces'. */ \
5253 for (n = 0; n < glyph_len; n++) \
5255 int c = COMPOSITION_GLYPH (cmp, n); \
5256 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5257 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5258 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5259 this_face_id, char2b + n, 1); \
5262 /* Make glyph_strings for each glyph sequence that is drawable by \
5263 the same face, and append them to HEAD/TAIL. */ \
5264 for (n = 0; n < cmp->glyph_len;) \
5266 s = (struct glyph_string *) alloca (sizeof *s); \
5267 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5268 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5276 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5284 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5285 of AREA of glyph row ROW on window W between indices START and END.
5286 HL overrides the face for drawing glyph strings, e.g. it is
5287 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5288 x-positions of the drawing area.
5290 This is an ugly monster macro construct because we must use alloca
5291 to allocate glyph strings (because x_draw_glyphs can be called
5294 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5297 HEAD = TAIL = NULL; \
5298 while (START < END) \
5300 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5301 switch (first_glyph->type) \
5304 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5305 TAIL, HL, X, LAST_X, \
5309 case COMPOSITE_GLYPH: \
5310 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5311 HEAD, TAIL, HL, X, LAST_X,\
5315 case STRETCH_GLYPH: \
5316 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5317 HEAD, TAIL, HL, X, LAST_X); \
5321 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5322 TAIL, HL, X, LAST_X); \
5329 x_set_glyph_string_background_width (s, START, LAST_X); \
5336 /* Draw glyphs between START and END in AREA of ROW on window W,
5337 starting at x-position X. X is relative to AREA in W. HL is a
5338 face-override with the following meaning:
5340 DRAW_NORMAL_TEXT draw normally
5341 DRAW_CURSOR draw in cursor face
5342 DRAW_MOUSE_FACE draw in mouse face.
5343 DRAW_INVERSE_VIDEO draw in mode line face
5344 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5345 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5347 If OVERLAPS_P is non-zero, draw only the foreground of characters
5348 and clip to the physical height of ROW.
5350 Value is the x-position reached, relative to AREA of W. */
5353 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5356 struct glyph_row
*row
;
5357 enum glyph_row_area area
;
5359 enum draw_glyphs_face hl
;
5362 struct glyph_string
*head
, *tail
;
5363 struct glyph_string
*s
;
5364 int last_x
, area_width
;
5368 /* Let's rather be paranoid than getting a SEGV. */
5369 end
= min (end
, row
->used
[area
]);
5370 start
= max (0, start
);
5371 start
= min (end
, start
);
5373 /* Translate X to frame coordinates. Set last_x to the right
5374 end of the drawing area. */
5375 if (row
->full_width_p
)
5377 /* X is relative to the left edge of W, without scroll bars
5379 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5380 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5383 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5384 last_x
= window_left_x
+ area_width
;
5386 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5388 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5389 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5395 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5396 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5400 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5401 area_width
= window_box_width (w
, area
);
5402 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5405 /* Build a doubly-linked list of glyph_string structures between
5406 head and tail from what we have to draw. Note that the macro
5407 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5408 the reason we use a separate variable `i'. */
5410 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5413 x_reached
= tail
->x
+ tail
->background_width
;
5417 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5418 the row, redraw some glyphs in front or following the glyph
5419 strings built above. */
5420 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5423 struct glyph_string
*h
, *t
;
5425 /* Compute overhangs for all glyph strings. */
5426 for (s
= head
; s
; s
= s
->next
)
5427 x_compute_glyph_string_overhangs (s
);
5429 /* Prepend glyph strings for glyphs in front of the first glyph
5430 string that are overwritten because of the first glyph
5431 string's left overhang. The background of all strings
5432 prepended must be drawn because the first glyph string
5434 i
= x_left_overwritten (head
);
5438 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5439 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5442 x_compute_overhangs_and_x (t
, head
->x
, 1);
5443 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5446 /* Prepend glyph strings for glyphs in front of the first glyph
5447 string that overwrite that glyph string because of their
5448 right overhang. For these strings, only the foreground must
5449 be drawn, because it draws over the glyph string at `head'.
5450 The background must not be drawn because this would overwrite
5451 right overhangs of preceding glyphs for which no glyph
5453 i
= x_left_overwriting (head
);
5456 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5457 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5459 for (s
= h
; s
; s
= s
->next
)
5460 s
->background_filled_p
= 1;
5461 x_compute_overhangs_and_x (t
, head
->x
, 1);
5462 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5465 /* Append glyphs strings for glyphs following the last glyph
5466 string tail that are overwritten by tail. The background of
5467 these strings has to be drawn because tail's foreground draws
5469 i
= x_right_overwritten (tail
);
5472 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5473 DRAW_NORMAL_TEXT
, x
, last_x
,
5475 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5476 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5479 /* Append glyph strings for glyphs following the last glyph
5480 string tail that overwrite tail. The foreground of such
5481 glyphs has to be drawn because it writes into the background
5482 of tail. The background must not be drawn because it could
5483 paint over the foreground of following glyphs. */
5484 i
= x_right_overwriting (tail
);
5487 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5488 DRAW_NORMAL_TEXT
, x
, last_x
,
5490 for (s
= h
; s
; s
= s
->next
)
5491 s
->background_filled_p
= 1;
5492 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5493 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5497 /* Draw all strings. */
5498 for (s
= head
; s
; s
= s
->next
)
5499 x_draw_glyph_string (s
);
5501 if (area
== TEXT_AREA
5502 && !row
->full_width_p
5503 /* When drawing overlapping rows, only the glyph strings'
5504 foreground is drawn, which doesn't erase a cursor
5508 int x0
= head
? head
->x
: x
;
5509 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5511 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5512 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5514 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5516 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5517 x0
-= left_area_width
;
5518 x1
-= left_area_width
;
5521 notice_overwritten_cursor (w
, area
, x0
, x1
,
5522 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5525 /* Value is the x-position up to which drawn, relative to AREA of W.
5526 This doesn't include parts drawn because of overhangs. */
5527 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5528 if (!row
->full_width_p
)
5530 if (area
> LEFT_MARGIN_AREA
)
5531 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5532 if (area
> TEXT_AREA
)
5533 x_reached
-= window_box_width (w
, TEXT_AREA
);
5540 /* Fix the display of area AREA of overlapping row ROW in window W. */
5543 x_fix_overlapping_area (w
, row
, area
)
5545 struct glyph_row
*row
;
5546 enum glyph_row_area area
;
5552 if (area
== LEFT_MARGIN_AREA
)
5554 else if (area
== TEXT_AREA
)
5555 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5557 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5558 + window_box_width (w
, TEXT_AREA
));
5560 for (i
= 0; i
< row
->used
[area
];)
5562 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5564 int start
= i
, start_x
= x
;
5568 x
+= row
->glyphs
[area
][i
].pixel_width
;
5571 while (i
< row
->used
[area
]
5572 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5574 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5575 DRAW_NORMAL_TEXT
, 1);
5579 x
+= row
->glyphs
[area
][i
].pixel_width
;
5588 /* Output LEN glyphs starting at START at the nominal cursor position.
5589 Advance the nominal cursor over the text. The global variable
5590 updated_window contains the window being updated, updated_row is
5591 the glyph row being updated, and updated_area is the area of that
5592 row being updated. */
5595 x_write_glyphs (start
, len
)
5596 struct glyph
*start
;
5601 xassert (updated_window
&& updated_row
);
5606 hpos
= start
- updated_row
->glyphs
[updated_area
];
5607 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5608 updated_row
, updated_area
,
5610 DRAW_NORMAL_TEXT
, 0);
5614 /* Advance the output cursor. */
5615 output_cursor
.hpos
+= len
;
5616 output_cursor
.x
= x
;
5620 /* Insert LEN glyphs from START at the nominal cursor position. */
5623 x_insert_glyphs (start
, len
)
5624 struct glyph
*start
;
5629 int line_height
, shift_by_width
, shifted_region_width
;
5630 struct glyph_row
*row
;
5631 struct glyph
*glyph
;
5632 int frame_x
, frame_y
, hpos
;
5634 xassert (updated_window
&& updated_row
);
5637 f
= XFRAME (WINDOW_FRAME (w
));
5639 /* Get the height of the line we are in. */
5641 line_height
= row
->height
;
5643 /* Get the width of the glyphs to insert. */
5645 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5646 shift_by_width
+= glyph
->pixel_width
;
5648 /* Get the width of the region to shift right. */
5649 shifted_region_width
= (window_box_width (w
, updated_area
)
5654 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5655 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5657 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5658 f
->output_data
.mac
->normal_gc
,
5660 shifted_region_width
, line_height
,
5661 frame_x
+ shift_by_width
, frame_y
);
5663 /* Write the glyphs. */
5664 hpos
= start
- row
->glyphs
[updated_area
];
5665 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5666 DRAW_NORMAL_TEXT
, 0);
5668 /* Advance the output cursor. */
5669 output_cursor
.hpos
+= len
;
5670 output_cursor
.x
+= shift_by_width
;
5675 /* Delete N glyphs at the nominal cursor position. Not implemented
5686 /* Erase the current text line from the nominal cursor position
5687 (inclusive) to pixel column TO_X (exclusive). The idea is that
5688 everything from TO_X onward is already erased.
5690 TO_X is a pixel position relative to updated_area of
5691 updated_window. TO_X == -1 means clear to the end of this area. */
5694 x_clear_end_of_line (to_x
)
5698 struct window
*w
= updated_window
;
5699 int max_x
, min_y
, max_y
;
5700 int from_x
, from_y
, to_y
;
5702 xassert (updated_window
&& updated_row
);
5703 f
= XFRAME (w
->frame
);
5705 if (updated_row
->full_width_p
)
5707 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5708 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5709 && !w
->pseudo_window_p
)
5710 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5713 max_x
= window_box_width (w
, updated_area
);
5714 max_y
= window_text_bottom_y (w
);
5716 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5717 of window. For TO_X > 0, truncate to end of drawing area. */
5723 to_x
= min (to_x
, max_x
);
5725 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5727 /* Notice if the cursor will be cleared by this operation. */
5728 if (!updated_row
->full_width_p
)
5729 notice_overwritten_cursor (w
, updated_area
,
5730 output_cursor
.x
, -1,
5732 MATRIX_ROW_BOTTOM_Y (updated_row
));
5734 from_x
= output_cursor
.x
;
5736 /* Translate to frame coordinates. */
5737 if (updated_row
->full_width_p
)
5739 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5740 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5744 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5745 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5748 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5749 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5750 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5752 /* Prevent inadvertently clearing to end of the X window. */
5753 if (to_x
> from_x
&& to_y
> from_y
)
5756 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5757 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5764 /* Clear entire frame. If updating_frame is non-null, clear that
5765 frame. Otherwise clear the selected frame. */
5775 f
= SELECTED_FRAME ();
5777 /* Clearing the frame will erase any cursor, so mark them all as no
5779 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5780 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5781 output_cursor
.x
= -1;
5783 /* We don't set the output cursor here because there will always
5784 follow an explicit cursor_to. */
5786 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5788 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5789 /* We have to clear the scroll bars, too. If we have changed
5790 colors or something like that, then they should be notified. */
5791 x_scroll_bar_clear (f
);
5794 XFlush (FRAME_MAC_DISPLAY (f
));
5800 /* Invert the middle quarter of the frame for .15 sec. */
5802 /* We use the select system call to do the waiting, so we have to make
5803 sure it's available. If it isn't, we just won't do visual bells. */
5805 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5807 /* Subtract the `struct timeval' values X and Y, storing the result in
5808 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5811 timeval_subtract (result
, x
, y
)
5812 struct timeval
*result
, x
, y
;
5814 /* Perform the carry for the later subtraction by updating y. This
5815 is safer because on some systems the tv_sec member is unsigned. */
5816 if (x
.tv_usec
< y
.tv_usec
)
5818 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5819 y
.tv_usec
-= 1000000 * nsec
;
5823 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5825 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5826 y
.tv_usec
+= 1000000 * nsec
;
5830 /* Compute the time remaining to wait. tv_usec is certainly
5832 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5833 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5835 /* Return indication of whether the result should be considered
5837 return x
.tv_sec
< y
.tv_sec
;
5849 struct timeval wakeup
;
5851 EMACS_GET_TIME (wakeup
);
5853 /* Compute time to wait until, propagating carry from usecs. */
5854 wakeup
.tv_usec
+= 150000;
5855 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5856 wakeup
.tv_usec
%= 1000000;
5858 /* Keep waiting until past the time wakeup. */
5861 struct timeval timeout
;
5863 EMACS_GET_TIME (timeout
);
5865 /* In effect, timeout = wakeup - timeout.
5866 Break if result would be negative. */
5867 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5870 /* Try to wait that long--but we might wake up sooner. */
5871 select (0, NULL
, NULL
, NULL
, &timeout
);
5880 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5883 /* Make audible bell. */
5888 struct frame
*f
= SELECTED_FRAME ();
5890 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5898 XFlush (FRAME_MAC_DISPLAY (f
));
5905 /* Specify how many text lines, from the top of the window,
5906 should be affected by insert-lines and delete-lines operations.
5907 This, and those operations, are used only within an update
5908 that is bounded by calls to x_update_begin and x_update_end. */
5911 XTset_terminal_window (n
)
5914 /* This function intentionally left blank. */
5919 /***********************************************************************
5921 ***********************************************************************/
5923 /* Perform an insert-lines or delete-lines operation, inserting N
5924 lines or deleting -N lines at vertical position VPOS. */
5927 x_ins_del_lines (vpos
, n
)
5934 /* Scroll part of the display as described by RUN. */
5937 x_scroll_run (w
, run
)
5941 struct frame
*f
= XFRAME (w
->frame
);
5942 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5944 /* Get frame-relative bounding box of the text display area of W,
5945 without mode lines. Include in this box the left and right
5947 window_box (w
, -1, &x
, &y
, &width
, &height
);
5948 width
+= FRAME_X_FRINGE_WIDTH (f
);
5949 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5951 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5952 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5953 bottom_y
= y
+ height
;
5957 /* Scrolling up. Make sure we don't copy part of the mode
5958 line at the bottom. */
5959 if (from_y
+ run
->height
> bottom_y
)
5960 height
= bottom_y
- from_y
;
5962 height
= run
->height
;
5966 /* Scolling down. Make sure we don't copy over the mode line.
5968 if (to_y
+ run
->height
> bottom_y
)
5969 height
= bottom_y
- to_y
;
5971 height
= run
->height
;
5976 /* Cursor off. Will be switched on again in x_update_window_end. */
5980 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5981 f
->output_data
.mac
->normal_gc
,
5991 /***********************************************************************
5993 ***********************************************************************/
5995 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5996 corner of the exposed rectangle. W and H are width and height of
5997 the exposed area. All are pixel values. W or H zero means redraw
5998 the entire frame. */
6001 expose_frame (f
, x
, y
, w
, h
)
6006 int mouse_face_overwritten_p
= 0;
6008 TRACE ((stderr
, "expose_frame "));
6010 /* No need to redraw if frame will be redrawn soon. */
6011 if (FRAME_GARBAGED_P (f
))
6013 TRACE ((stderr
, " garbaged\n"));
6017 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
6018 or deactivated here, for unknown reasons, activated scroll bars
6019 are shown in deactivated frames in some instances. */
6020 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6021 activate_scroll_bars (f
);
6023 deactivate_scroll_bars (f
);
6025 /* If basic faces haven't been realized yet, there is no point in
6026 trying to redraw anything. This can happen when we get an expose
6027 event while Emacs is starting, e.g. by moving another window. */
6028 if (FRAME_FACE_CACHE (f
) == NULL
6029 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
6031 TRACE ((stderr
, " no faces\n"));
6035 if (w
== 0 || h
== 0)
6038 r
.right
= CANON_X_UNIT (f
) * f
->width
;
6039 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
6049 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
6050 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
6052 if (WINDOWP (f
->tool_bar_window
))
6053 mouse_face_overwritten_p
6054 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
6056 /* Some window managers support a focus-follows-mouse style with
6057 delayed raising of frames. Imagine a partially obscured frame,
6058 and moving the mouse into partially obscured mouse-face on that
6059 frame. The visible part of the mouse-face will be highlighted,
6060 then the WM raises the obscured frame. With at least one WM, KDE
6061 2.1, Emacs is not getting any event for the raising of the frame
6062 (even tried with SubstructureRedirectMask), only Expose events.
6063 These expose events will draw text normally, i.e. not
6064 highlighted. Which means we must redo the highlight here.
6065 Subsume it under ``we love X''. --gerd 2001-08-15 */
6066 /* Included in Windows version because Windows most likely does not
6067 do the right thing if any third party tool offers
6068 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
6069 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
6071 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6072 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6074 int x
= dpyinfo
->mouse_face_mouse_x
;
6075 int y
= dpyinfo
->mouse_face_mouse_y
;
6076 clear_mouse_face (dpyinfo
);
6077 note_mouse_highlight (f
, x
, y
);
6083 /* Redraw (parts) of all windows in the window tree rooted at W that
6084 intersect R. R contains frame pixel coordinates. */
6087 expose_window_tree (w
, r
)
6091 struct frame
*f
= XFRAME (w
->frame
);
6092 int mouse_face_overwritten_p
= 0;
6094 while (w
&& !FRAME_GARBAGED_P (f
))
6096 if (!NILP (w
->hchild
))
6097 mouse_face_overwritten_p
6098 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
6099 else if (!NILP (w
->vchild
))
6100 mouse_face_overwritten_p
6101 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
6103 mouse_face_overwritten_p
|= expose_window (w
, r
);
6105 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
6108 return mouse_face_overwritten_p
;
6112 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
6113 which intersects rectangle R. R is in window-relative coordinates. */
6116 expose_area (w
, row
, r
, area
)
6118 struct glyph_row
*row
;
6120 enum glyph_row_area area
;
6122 struct glyph
*first
= row
->glyphs
[area
];
6123 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
6125 int first_x
, start_x
, x
;
6127 if (area
== TEXT_AREA
&& row
->fill_line_p
)
6128 /* If row extends face to end of line write the whole line. */
6129 x_draw_glyphs (w
, 0, row
, area
,
6131 DRAW_NORMAL_TEXT
, 0);
6134 /* Set START_X to the window-relative start position for drawing glyphs of
6135 AREA. The first glyph of the text area can be partially visible.
6136 The first glyphs of other areas cannot. */
6137 if (area
== LEFT_MARGIN_AREA
)
6139 else if (area
== TEXT_AREA
)
6140 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6142 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6143 + window_box_width (w
, TEXT_AREA
));
6146 /* Find the first glyph that must be redrawn. */
6148 && x
+ first
->pixel_width
< r
->left
)
6150 x
+= first
->pixel_width
;
6154 /* Find the last one. */
6160 x
+= last
->pixel_width
;
6166 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6167 first
- row
->glyphs
[area
],
6168 last
- row
->glyphs
[area
],
6169 DRAW_NORMAL_TEXT
, 0);
6174 /* Redraw the parts of the glyph row ROW on window W intersecting
6175 rectangle R. R is in window-relative coordinates. Value is
6176 non-zero if mouse face was overwritten. */
6179 expose_line (w
, row
, r
)
6181 struct glyph_row
*row
;
6184 xassert (row
->enabled_p
);
6186 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6187 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6188 DRAW_NORMAL_TEXT
, 0);
6191 if (row
->used
[LEFT_MARGIN_AREA
])
6192 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6193 if (row
->used
[TEXT_AREA
])
6194 expose_area (w
, row
, r
, TEXT_AREA
);
6195 if (row
->used
[RIGHT_MARGIN_AREA
])
6196 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6197 x_draw_row_fringe_bitmaps (w
, row
);
6200 return row
->mouse_face_p
;
6204 /* Return non-zero if W's cursor intersects rectangle R. */
6207 x_phys_cursor_in_rect_p (w
, r
)
6212 struct glyph
*cursor_glyph
;
6214 cursor_glyph
= get_phys_cursor_glyph (w
);
6217 cr
.left
= w
->phys_cursor
.x
;
6218 cr
.top
= w
->phys_cursor
.y
;
6219 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6220 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6221 return x_intersect_rectangles (&cr
, r
, &result
);
6228 /* Redraw the part of window W intersection rectagle FR. Pixel
6229 coordinates in FR are frame relative. Call this function with
6230 input blocked. Value is non-zero if the exposure overwrites
6234 expose_window (w
, fr
)
6238 struct frame
*f
= XFRAME (w
->frame
);
6240 int mouse_face_overwritten_p
= 0;
6242 /* If window is not yet fully initialized, do nothing. This can
6243 happen when toolkit scroll bars are used and a window is split.
6244 Reconfiguring the scroll bar will generate an expose for a newly
6246 if (w
->current_matrix
== NULL
)
6249 /* When we're currently updating the window, display and current
6250 matrix usually don't agree. Arrange for a thorough display
6252 if (w
== updated_window
)
6254 SET_FRAME_GARBAGED (f
);
6258 /* Frame-relative pixel rectangle of W. */
6259 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6260 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6261 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6262 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6264 if (x_intersect_rectangles (fr
, &wr
, &r
))
6266 int yb
= window_text_bottom_y (w
);
6267 struct glyph_row
*row
;
6268 int cursor_cleared_p
;
6270 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6271 r
.left
, r
.top
, r
.right
, r
.bottom
));
6273 /* Convert to window coordinates. */
6274 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6275 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6276 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6277 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6279 /* Turn off the cursor. */
6280 if (!w
->pseudo_window_p
6281 && x_phys_cursor_in_rect_p (w
, &r
))
6284 cursor_cleared_p
= 1;
6287 cursor_cleared_p
= 0;
6289 /* Find the first row intersecting the rectangle R. */
6290 for (row
= w
->current_matrix
->rows
;
6295 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6297 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6298 || (y1
> r
.top
&& y1
< r
.bottom
)
6299 || (r
.top
>= y0
&& r
.top
< y1
)
6300 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6302 if (expose_line (w
, row
, &r
))
6303 mouse_face_overwritten_p
= 1;
6310 /* Display the mode line if there is one. */
6311 if (WINDOW_WANTS_MODELINE_P (w
)
6312 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6314 && row
->y
< r
.bottom
)
6316 if (expose_line (w
, row
, &r
))
6317 mouse_face_overwritten_p
= 1;
6320 if (!w
->pseudo_window_p
)
6322 /* Draw border between windows. */
6323 x_draw_vertical_border (w
);
6325 /* Turn the cursor on again. */
6326 if (cursor_cleared_p
)
6327 x_update_window_cursor (w
, 1);
6331 /* Display scroll bar for this window. */
6332 if (!NILP (w
->vertical_scroll_bar
))
6335 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6340 return mouse_face_overwritten_p
;
6344 x_intersect_rectangles (r1
, r2
, result
)
6345 Rect
*r1
, *r2
, *result
;
6348 Rect
*upper
, *lower
;
6349 int intersection_p
= 0;
6351 /* Rerrange so that R1 is the left-most rectangle. */
6352 if (r1
->left
< r2
->left
)
6353 left
= r1
, right
= r2
;
6355 left
= r2
, right
= r1
;
6357 /* X0 of the intersection is right.x0, if this is inside R1,
6358 otherwise there is no intersection. */
6359 if (right
->left
<= left
->right
)
6361 result
->left
= right
->left
;
6363 /* The right end of the intersection is the minimum of the
6364 the right ends of left and right. */
6365 result
->right
= min (left
->right
, right
->right
);
6367 /* Same game for Y. */
6368 if (r1
->top
< r2
->top
)
6369 upper
= r1
, lower
= r2
;
6371 upper
= r2
, lower
= r1
;
6373 /* The upper end of the intersection is lower.y0, if this is inside
6374 of upper. Otherwise, there is no intersection. */
6375 if (lower
->top
<= upper
->bottom
)
6377 result
->top
= lower
->top
;
6379 /* The lower end of the intersection is the minimum of the lower
6380 ends of upper and lower. */
6381 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6386 return intersection_p
;
6397 x_update_cursor (f
, 1);
6401 frame_unhighlight (f
)
6404 x_update_cursor (f
, 1);
6407 /* The focus has changed. Update the frames as necessary to reflect
6408 the new situation. Note that we can't change the selected frame
6409 here, because the Lisp code we are interrupting might become confused.
6410 Each event gets marked with the frame in which it occurred, so the
6411 Lisp code can tell when the switch took place by examining the events. */
6414 x_new_focus_frame (dpyinfo
, frame
)
6415 struct x_display_info
*dpyinfo
;
6416 struct frame
*frame
;
6418 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6420 if (frame
!= dpyinfo
->x_focus_frame
)
6422 /* Set this before calling other routines, so that they see
6423 the correct value of x_focus_frame. */
6424 dpyinfo
->x_focus_frame
= frame
;
6426 if (old_focus
&& old_focus
->auto_lower
)
6427 x_lower_frame (old_focus
);
6430 selected_frame
= frame
;
6431 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6433 Fselect_window (selected_frame
->selected_window
);
6434 choose_minibuf_frame ();
6437 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6438 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6440 pending_autoraise_frame
= 0;
6443 x_frame_rehighlight (dpyinfo
);
6446 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6449 x_mouse_leave (dpyinfo
)
6450 struct x_display_info
*dpyinfo
;
6452 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6455 /* The focus has changed, or we have redirected a frame's focus to
6456 another frame (this happens when a frame uses a surrogate
6457 mini-buffer frame). Shift the highlight as appropriate.
6459 The FRAME argument doesn't necessarily have anything to do with which
6460 frame is being highlighted or un-highlighted; we only use it to find
6461 the appropriate X display info. */
6464 XTframe_rehighlight (frame
)
6465 struct frame
*frame
;
6467 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6471 x_frame_rehighlight (dpyinfo
)
6472 struct x_display_info
*dpyinfo
;
6474 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6476 if (dpyinfo
->x_focus_frame
)
6478 dpyinfo
->x_highlight_frame
6479 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6480 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6481 : dpyinfo
->x_focus_frame
);
6482 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6484 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6485 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6489 dpyinfo
->x_highlight_frame
= 0;
6491 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6494 frame_unhighlight (old_highlight
);
6495 if (dpyinfo
->x_highlight_frame
)
6496 frame_highlight (dpyinfo
->x_highlight_frame
);
6502 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6504 #if 0 /* MAC_TODO */
6505 /* Initialize mode_switch_bit and modifier_meaning. */
6507 x_find_modifier_meanings (dpyinfo
)
6508 struct x_display_info
*dpyinfo
;
6510 int min_code
, max_code
;
6513 XModifierKeymap
*mods
;
6515 dpyinfo
->meta_mod_mask
= 0;
6516 dpyinfo
->shift_lock_mask
= 0;
6517 dpyinfo
->alt_mod_mask
= 0;
6518 dpyinfo
->super_mod_mask
= 0;
6519 dpyinfo
->hyper_mod_mask
= 0;
6522 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6524 min_code
= dpyinfo
->display
->min_keycode
;
6525 max_code
= dpyinfo
->display
->max_keycode
;
6528 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6529 min_code
, max_code
- min_code
+ 1,
6531 mods
= XGetModifierMapping (dpyinfo
->display
);
6533 /* Scan the modifier table to see which modifier bits the Meta and
6534 Alt keysyms are on. */
6536 int row
, col
; /* The row and column in the modifier table. */
6538 for (row
= 3; row
< 8; row
++)
6539 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6542 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6544 /* Zeroes are used for filler. Skip them. */
6548 /* Are any of this keycode's keysyms a meta key? */
6552 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6554 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6560 dpyinfo
->meta_mod_mask
|= (1 << row
);
6565 dpyinfo
->alt_mod_mask
|= (1 << row
);
6570 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6575 dpyinfo
->super_mod_mask
|= (1 << row
);
6579 /* Ignore this if it's not on the lock modifier. */
6580 if ((1 << row
) == LockMask
)
6581 dpyinfo
->shift_lock_mask
= LockMask
;
6589 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6590 if (! dpyinfo
->meta_mod_mask
)
6592 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6593 dpyinfo
->alt_mod_mask
= 0;
6596 /* If some keys are both alt and meta,
6597 make them just meta, not alt. */
6598 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6600 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6603 XFree ((char *) syms
);
6604 XFreeModifiermap (mods
);
6607 #endif /* MAC_TODO */
6609 /* Convert between the modifier bits X uses and the modifier bits
6613 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6614 struct x_display_info
*dpyinfo
;
6615 unsigned short state
;
6617 return (((state
& shiftKey
) ? shift_modifier
: 0)
6618 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6619 | ((state
& cmdKey
) ? meta_modifier
: 0)
6620 | ((state
& optionKey
) ? alt_modifier
: 0));
6623 #if 0 /* MAC_TODO */
6624 static unsigned short
6625 x_emacs_to_x_modifiers (dpyinfo
, state
)
6626 struct x_display_info
*dpyinfo
;
6629 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6630 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6631 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6632 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6633 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6634 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6636 #endif /* MAC_TODO */
6638 /* Convert a keysym to its name. */
6641 x_get_keysym_name (keysym
)
6648 value
= XKeysymToString (keysym
);
6659 /* Mouse clicks and mouse movement. Rah. */
6661 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6662 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6663 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6664 not force the value into range. */
6667 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6669 register int pix_x
, pix_y
;
6670 register int *x
, *y
;
6674 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6675 if (NILP (Vwindow_system
))
6682 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6683 even for negative values. */
6685 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6687 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6689 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6690 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6694 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6695 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6696 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6697 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6704 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6705 pix_x
= FRAME_WINDOW_WIDTH (f
);
6709 else if (pix_y
> f
->height
)
6718 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6719 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6720 can't tell the positions because W's display is not up to date,
6724 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6727 int *frame_x
, *frame_y
;
6731 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6732 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6734 if (display_completed
)
6736 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6737 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6738 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6744 *frame_x
+= glyph
->pixel_width
;
6752 *frame_y
= *frame_x
= 0;
6756 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6757 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6762 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6764 If the event is a button press, then note that we have grabbed
6768 construct_mouse_click (result
, event
, f
)
6769 struct input_event
*result
;
6775 result
->kind
= MOUSE_CLICK_EVENT
;
6776 result
->code
= 0; /* only one mouse button */
6777 result
->timestamp
= event
->when
;
6778 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6780 mouseLoc
= event
->where
;
6782 #if TARGET_API_MAC_CARBON
6783 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6785 SetPort (FRAME_MAC_WINDOW (f
));
6788 GlobalToLocal (&mouseLoc
);
6789 XSETINT (result
->x
, mouseLoc
.h
);
6790 XSETINT (result
->y
, mouseLoc
.v
);
6792 XSETFRAME (result
->frame_or_window
, f
);
6799 /* Function to report a mouse movement to the mainstream Emacs code.
6800 The input handler calls this.
6802 We have received a mouse movement event, which is given in *event.
6803 If the mouse is over a different glyph than it was last time, tell
6804 the mainstream emacs code by setting mouse_moved. If not, ask for
6805 another motion event, so we can check again the next time it moves. */
6807 static Point last_mouse_motion_position
;
6808 static Lisp_Object last_mouse_motion_frame
;
6811 note_mouse_movement (frame
, pos
)
6815 #if TARGET_API_MAC_CARBON
6819 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6820 last_mouse_motion_position
= *pos
;
6821 XSETFRAME (last_mouse_motion_frame
, frame
);
6823 #if TARGET_API_MAC_CARBON
6824 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6826 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6829 frame
->mouse_moved
= 1;
6830 last_mouse_scroll_bar
= Qnil
;
6831 note_mouse_highlight (frame
, -1, -1);
6833 /* Has the mouse moved off the glyph it was on at the last sighting? */
6834 else if (pos
->h
< last_mouse_glyph
.left
6835 || pos
->h
>= last_mouse_glyph
.right
6836 || pos
->v
< last_mouse_glyph
.top
6837 || pos
->v
>= last_mouse_glyph
.bottom
)
6839 frame
->mouse_moved
= 1;
6840 last_mouse_scroll_bar
= Qnil
;
6841 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6845 /* This is used for debugging, to turn off note_mouse_highlight. */
6847 int disable_mouse_highlight
;
6851 /************************************************************************
6853 ************************************************************************/
6855 /* Find the glyph under window-relative coordinates X/Y in window W.
6856 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6857 strings. Return in *HPOS and *VPOS the row and column number of
6858 the glyph found. Return in *AREA the glyph area containing X.
6859 Value is a pointer to the glyph found or null if X/Y is not on
6860 text, or we can't tell because W's current matrix is not up to
6863 static struct glyph
*
6864 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6867 int *hpos
, *vpos
, *area
;
6870 struct glyph
*glyph
, *end
;
6871 struct glyph_row
*row
= NULL
;
6872 int x0
, i
, left_area_width
;
6874 /* Find row containing Y. Give up if some row is not enabled. */
6875 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6877 row
= MATRIX_ROW (w
->current_matrix
, i
);
6878 if (!row
->enabled_p
)
6880 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6887 /* Give up if Y is not in the window. */
6888 if (i
== w
->current_matrix
->nrows
)
6891 /* Get the glyph area containing X. */
6892 if (w
->pseudo_window_p
)
6899 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6900 if (x
< left_area_width
)
6902 *area
= LEFT_MARGIN_AREA
;
6905 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6908 x0
= row
->x
+ left_area_width
;
6912 *area
= RIGHT_MARGIN_AREA
;
6913 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6917 /* Find glyph containing X. */
6918 glyph
= row
->glyphs
[*area
];
6919 end
= glyph
+ row
->used
[*area
];
6922 if (x
< x0
+ glyph
->pixel_width
)
6924 if (w
->pseudo_window_p
)
6926 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6930 x0
+= glyph
->pixel_width
;
6937 *hpos
= glyph
- row
->glyphs
[*area
];
6942 /* Convert frame-relative x/y to coordinates relative to window W.
6943 Takes pseudo-windows into account. */
6946 frame_to_window_pixel_xy (w
, x
, y
)
6950 if (w
->pseudo_window_p
)
6952 /* A pseudo-window is always full-width, and starts at the
6953 left edge of the frame, plus a frame border. */
6954 struct frame
*f
= XFRAME (w
->frame
);
6955 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6956 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6960 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6961 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6966 /* Take proper action when mouse has moved to the mode or header line of
6967 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6968 mode line. X is relative to the start of the text display area of
6969 W, so the width of fringes and scroll bars must be subtracted
6970 to get a position relative to the start of the mode line. */
6973 note_mode_line_highlight (w
, x
, mode_line_p
)
6977 struct frame
*f
= XFRAME (w
->frame
);
6978 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6979 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6980 struct glyph_row
*row
;
6983 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6985 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6989 struct glyph
*glyph
, *end
;
6990 Lisp_Object help
, map
;
6993 /* Find the glyph under X. */
6994 glyph
= row
->glyphs
[TEXT_AREA
];
6995 end
= glyph
+ row
->used
[TEXT_AREA
];
6996 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6997 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
7000 && x
>= x0
+ glyph
->pixel_width
)
7002 x0
+= glyph
->pixel_width
;
7007 && STRINGP (glyph
->object
)
7008 && XSTRING (glyph
->object
)->intervals
7009 && glyph
->charpos
>= 0
7010 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
7012 /* If we're on a string with `help-echo' text property,
7013 arrange for the help to be displayed. This is done by
7014 setting the global variable help_echo to the help string. */
7015 help
= Fget_text_property (make_number (glyph
->charpos
),
7016 Qhelp_echo
, glyph
->object
);
7020 XSETWINDOW (help_echo_window
, w
);
7021 help_echo_object
= glyph
->object
;
7022 help_echo_pos
= glyph
->charpos
;
7025 /* Change the mouse pointer according to what is under X/Y. */
7026 map
= Fget_text_property (make_number (glyph
->charpos
),
7027 Qlocal_map
, glyph
->object
);
7029 cursor
= f
->output_data
.mac
->nontext_cursor
;
7032 map
= Fget_text_property (make_number (glyph
->charpos
),
7033 Qkeymap
, glyph
->object
);
7035 cursor
= f
->output_data
.mac
->nontext_cursor
;
7040 #if 0 /* MAC_TODO: mouse cursor */
7041 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7046 /* Take proper action when the mouse has moved to position X, Y on
7047 frame F as regards highlighting characters that have mouse-face
7048 properties. Also de-highlighting chars where the mouse was before.
7049 X and Y can be negative or out of range. */
7052 note_mouse_highlight (f
, x
, y
)
7056 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7063 /* When a menu is active, don't highlight because this looks odd. */
7064 if (popup_activated ())
7068 if (NILP (Vmouse_highlight
)
7069 || !f
->glyphs_initialized_p
)
7072 dpyinfo
->mouse_face_mouse_x
= x
;
7073 dpyinfo
->mouse_face_mouse_y
= y
;
7074 dpyinfo
->mouse_face_mouse_frame
= f
;
7076 if (dpyinfo
->mouse_face_defer
)
7081 dpyinfo
->mouse_face_deferred_gc
= 1;
7085 /* Which window is that in? */
7086 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7088 /* If we were displaying active text in another window, clear that. */
7089 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7090 clear_mouse_face (dpyinfo
);
7092 /* Not on a window -> return. */
7093 if (!WINDOWP (window
))
7096 /* Reset help_echo. It will get recomputed below. */
7099 /* Convert to window-relative pixel coordinates. */
7100 w
= XWINDOW (window
);
7101 frame_to_window_pixel_xy (w
, &x
, &y
);
7103 /* Handle tool-bar window differently since it doesn't display a
7105 if (EQ (window
, f
->tool_bar_window
))
7107 note_tool_bar_highlight (f
, x
, y
);
7111 /* Mouse is on the mode or header line? */
7112 if (portion
== 1 || portion
== 3)
7114 note_mode_line_highlight (w
, x
, portion
== 1);
7117 #if 0 /* TODO: mouse cursor */
7119 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7121 cursor
= f
->output_data
.x
->text_cursor
;
7123 /* Are we in a window whose display is up to date?
7124 And verify the buffer's text has not changed. */
7125 b
= XBUFFER (w
->buffer
);
7126 if (/* Within text portion of the window. */
7128 && EQ (w
->window_end_valid
, w
->buffer
)
7129 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7130 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7132 int hpos
, vpos
, pos
, i
, area
;
7133 struct glyph
*glyph
;
7135 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7136 Lisp_Object
*overlay_vec
= NULL
;
7138 struct buffer
*obuf
;
7139 int obegv
, ozv
, same_region
;
7141 /* Find the glyph under X/Y. */
7142 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7144 /* Clear mouse face if X/Y not over text. */
7146 || area
!= TEXT_AREA
7147 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7149 clear_mouse_face (dpyinfo
);
7150 /* TODO: mouse cursor */
7154 pos
= glyph
->charpos
;
7155 object
= glyph
->object
;
7156 if (!STRINGP (object
) && !BUFFERP (object
))
7159 /* If we get an out-of-range value, return now; avoid an error. */
7160 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7163 /* Make the window's buffer temporarily current for
7164 overlays_at and compute_char_face. */
7165 obuf
= current_buffer
;
7172 /* Is this char mouse-active or does it have help-echo? */
7173 position
= make_number (pos
);
7175 if (BUFFERP (object
))
7177 /* Put all the overlays we want in a vector in overlay_vec.
7178 Store the length in len. If there are more than 10, make
7179 enough space for all, and try again. */
7181 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7182 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7183 if (noverlays
> len
)
7186 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7187 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7190 /* Sort overlays into increasing priority order. */
7191 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7196 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7197 && vpos
>= dpyinfo
->mouse_face_beg_row
7198 && vpos
<= dpyinfo
->mouse_face_end_row
7199 && (vpos
> dpyinfo
->mouse_face_beg_row
7200 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7201 && (vpos
< dpyinfo
->mouse_face_end_row
7202 || hpos
< dpyinfo
->mouse_face_end_col
7203 || dpyinfo
->mouse_face_past_end
));
7205 /* TODO: if (same_region)
7208 /* Check mouse-face highlighting. */
7210 /* If there exists an overlay with mouse-face overlapping
7211 the one we are currently highlighting, we have to
7212 check if we enter the overlapping overlay, and then
7214 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7215 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7217 /* Find the highest priority overlay that has a mouse-face
7220 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7222 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7223 if (!NILP (mouse_face
))
7224 overlay
= overlay_vec
[i
];
7227 /* If we're actually highlighting the same overlay as
7228 before, there's no need to do that again. */
7230 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7231 goto check_help_echo
;
7233 dpyinfo
->mouse_face_overlay
= overlay
;
7235 /* Clear the display of the old active region, if any. */
7236 clear_mouse_face (dpyinfo
);
7237 /* TODO: mouse cursor changes. */
7239 /* If no overlay applies, get a text property. */
7241 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7243 /* Handle the overlay case. */
7244 if (!NILP (overlay
))
7246 /* Find the range of text around this char that
7247 should be active. */
7248 Lisp_Object before
, after
;
7251 before
= Foverlay_start (overlay
);
7252 after
= Foverlay_end (overlay
);
7253 /* Record this as the current active region. */
7254 fast_find_position (w
, XFASTINT (before
),
7255 &dpyinfo
->mouse_face_beg_col
,
7256 &dpyinfo
->mouse_face_beg_row
,
7257 &dpyinfo
->mouse_face_beg_x
,
7258 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7260 dpyinfo
->mouse_face_past_end
7261 = !fast_find_position (w
, XFASTINT (after
),
7262 &dpyinfo
->mouse_face_end_col
,
7263 &dpyinfo
->mouse_face_end_row
,
7264 &dpyinfo
->mouse_face_end_x
,
7265 &dpyinfo
->mouse_face_end_y
, Qnil
);
7266 dpyinfo
->mouse_face_window
= window
;
7268 dpyinfo
->mouse_face_face_id
7269 = face_at_buffer_position (w
, pos
, 0, 0,
7270 &ignore
, pos
+ 1, 1);
7272 /* Display it as active. */
7273 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7274 /* TODO: mouse cursor changes. */
7276 /* Handle the text property case. */
7277 else if (! NILP (mouse_face
) && BUFFERP (object
))
7279 /* Find the range of text around this char that
7280 should be active. */
7281 Lisp_Object before
, after
, beginning
, end
;
7284 beginning
= Fmarker_position (w
->start
);
7285 end
= make_number (BUF_Z (XBUFFER (object
))
7286 - XFASTINT (w
->window_end_pos
));
7288 = Fprevious_single_property_change (make_number (pos
+ 1),
7292 = Fnext_single_property_change (position
, Qmouse_face
,
7295 /* Record this as the current active region. */
7296 fast_find_position (w
, XFASTINT (before
),
7297 &dpyinfo
->mouse_face_beg_col
,
7298 &dpyinfo
->mouse_face_beg_row
,
7299 &dpyinfo
->mouse_face_beg_x
,
7300 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7301 dpyinfo
->mouse_face_past_end
7302 = !fast_find_position (w
, XFASTINT (after
),
7303 &dpyinfo
->mouse_face_end_col
,
7304 &dpyinfo
->mouse_face_end_row
,
7305 &dpyinfo
->mouse_face_end_x
,
7306 &dpyinfo
->mouse_face_end_y
, Qnil
);
7307 dpyinfo
->mouse_face_window
= window
;
7309 if (BUFFERP (object
))
7310 dpyinfo
->mouse_face_face_id
7311 = face_at_buffer_position (w
, pos
, 0, 0,
7312 &ignore
, pos
+ 1, 1);
7314 /* Display it as active. */
7315 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7316 /* TODO: mouse cursor changes. */
7318 else if (!NILP (mouse_face
) && STRINGP (object
))
7323 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7326 e
= Fnext_single_property_change (position
, Qmouse_face
,
7329 b
= make_number (0);
7331 e
= make_number (XSTRING (object
)->size
- 1);
7332 fast_find_string_pos (w
, XINT (b
), object
,
7333 &dpyinfo
->mouse_face_beg_col
,
7334 &dpyinfo
->mouse_face_beg_row
,
7335 &dpyinfo
->mouse_face_beg_x
,
7336 &dpyinfo
->mouse_face_beg_y
, 0);
7337 fast_find_string_pos (w
, XINT (e
), object
,
7338 &dpyinfo
->mouse_face_end_col
,
7339 &dpyinfo
->mouse_face_end_row
,
7340 &dpyinfo
->mouse_face_end_x
,
7341 &dpyinfo
->mouse_face_end_y
, 1);
7342 dpyinfo
->mouse_face_past_end
= 0;
7343 dpyinfo
->mouse_face_window
= window
;
7344 dpyinfo
->mouse_face_face_id
7345 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7347 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7348 /* TODO: mouse cursor changes. */
7350 else if (STRINGP (object
) && NILP (mouse_face
))
7352 /* A string which doesn't have mouse-face, but
7353 the text ``under'' it might have. */
7354 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7355 int start
= MATRIX_ROW_START_CHARPOS (r
);
7357 pos
= string_buffer_position (w
, object
, start
);
7359 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7363 if (!NILP (mouse_face
) && !NILP (overlay
))
7365 Lisp_Object before
= Foverlay_start (overlay
);
7366 Lisp_Object after
= Foverlay_end (overlay
);
7369 /* Note that we might not be able to find position
7370 BEFORE in the glyph matrix if the overlay is
7371 entirely covered by a `display' property. In
7372 this case, we overshoot. So let's stop in
7373 the glyph matrix before glyphs for OBJECT. */
7374 fast_find_position (w
, XFASTINT (before
),
7375 &dpyinfo
->mouse_face_beg_col
,
7376 &dpyinfo
->mouse_face_beg_row
,
7377 &dpyinfo
->mouse_face_beg_x
,
7378 &dpyinfo
->mouse_face_beg_y
,
7381 dpyinfo
->mouse_face_past_end
7382 = !fast_find_position (w
, XFASTINT (after
),
7383 &dpyinfo
->mouse_face_end_col
,
7384 &dpyinfo
->mouse_face_end_row
,
7385 &dpyinfo
->mouse_face_end_x
,
7386 &dpyinfo
->mouse_face_end_y
,
7388 dpyinfo
->mouse_face_window
= window
;
7389 dpyinfo
->mouse_face_face_id
7390 = face_at_buffer_position (w
, pos
, 0, 0,
7391 &ignore
, pos
+ 1, 1);
7393 /* Display it as active. */
7394 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7395 /* TODO: mouse cursor changes. */
7402 /* Look for a `help-echo' property. */
7404 Lisp_Object help
, overlay
;
7406 /* Check overlays first. */
7407 help
= overlay
= Qnil
;
7408 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7410 overlay
= overlay_vec
[i
];
7411 help
= Foverlay_get (overlay
, Qhelp_echo
);
7417 help_echo_window
= window
;
7418 help_echo_object
= overlay
;
7419 help_echo_pos
= pos
;
7423 Lisp_Object object
= glyph
->object
;
7424 int charpos
= glyph
->charpos
;
7426 /* Try text properties. */
7427 if (STRINGP (object
)
7429 && charpos
< XSTRING (object
)->size
)
7431 help
= Fget_text_property (make_number (charpos
),
7432 Qhelp_echo
, object
);
7435 /* If the string itself doesn't specify a help-echo,
7436 see if the buffer text ``under'' it does. */
7438 = MATRIX_ROW (w
->current_matrix
, vpos
);
7439 int start
= MATRIX_ROW_START_CHARPOS (r
);
7440 int pos
= string_buffer_position (w
, object
, start
);
7443 help
= Fget_char_property (make_number (pos
),
7444 Qhelp_echo
, w
->buffer
);
7453 else if (BUFFERP (object
)
7456 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7462 help_echo_window
= window
;
7463 help_echo_object
= object
;
7464 help_echo_pos
= charpos
;
7471 current_buffer
= obuf
;
7475 /* TODO: mouse cursor changes. */
7480 redo_mouse_highlight ()
7482 if (!NILP (last_mouse_motion_frame
)
7483 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7484 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7485 last_mouse_motion_position
.h
,
7486 last_mouse_motion_position
.v
);
7491 /***********************************************************************
7493 ***********************************************************************/
7495 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7496 struct glyph
**, int *, int *, int *));
7498 /* Tool-bar item index of the item on which a mouse button was pressed
7501 static int last_tool_bar_item
;
7504 /* Get information about the tool-bar item at position X/Y on frame F.
7505 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7506 the current matrix of the tool-bar window of F, or NULL if not
7507 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7508 item in F->current_tool_bar_items. Value is
7510 -1 if X/Y is not on a tool-bar item
7511 0 if X/Y is on the same item that was highlighted before.
7515 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7518 struct glyph
**glyph
;
7519 int *hpos
, *vpos
, *prop_idx
;
7521 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7522 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7525 /* Find the glyph under X/Y. */
7526 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7530 /* Get the start of this tool-bar item's properties in
7531 f->current_tool_bar_items. */
7532 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7535 /* Is mouse on the highlighted item? */
7536 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7537 && *vpos
>= dpyinfo
->mouse_face_beg_row
7538 && *vpos
<= dpyinfo
->mouse_face_end_row
7539 && (*vpos
> dpyinfo
->mouse_face_beg_row
7540 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7541 && (*vpos
< dpyinfo
->mouse_face_end_row
7542 || *hpos
< dpyinfo
->mouse_face_end_col
7543 || dpyinfo
->mouse_face_past_end
))
7550 /* Handle mouse button event on the tool-bar of frame F, at
7551 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7555 x_handle_tool_bar_click (f
, button_event
)
7557 EventRecord
*button_event
;
7559 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7560 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7561 int hpos
, vpos
, prop_idx
;
7562 struct glyph
*glyph
;
7563 Lisp_Object enabled_p
;
7564 int x
= button_event
->where
.h
;
7565 int y
= button_event
->where
.v
;
7567 /* If not on the highlighted tool-bar item, return. */
7568 frame_to_window_pixel_xy (w
, &x
, &y
);
7569 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7572 /* If item is disabled, do nothing. */
7573 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7574 if (NILP (enabled_p
))
7577 if (button_event
->what
== mouseDown
)
7579 /* Show item in pressed state. */
7580 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7581 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7582 last_tool_bar_item
= prop_idx
;
7586 Lisp_Object key
, frame
;
7587 struct input_event event
;
7589 /* Show item in released state. */
7590 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7591 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7593 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7595 XSETFRAME (frame
, f
);
7596 event
.kind
= TOOL_BAR_EVENT
;
7597 event
.frame_or_window
= frame
;
7599 kbd_buffer_store_event (&event
);
7601 event
.kind
= TOOL_BAR_EVENT
;
7602 event
.frame_or_window
= frame
;
7604 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7605 button_event
->modifiers
);
7606 kbd_buffer_store_event (&event
);
7607 last_tool_bar_item
= -1;
7612 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7613 tool-bar window-relative coordinates X/Y. Called from
7614 note_mouse_highlight. */
7617 note_tool_bar_highlight (f
, x
, y
)
7621 Lisp_Object window
= f
->tool_bar_window
;
7622 struct window
*w
= XWINDOW (window
);
7623 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7625 struct glyph
*glyph
;
7626 struct glyph_row
*row
;
7628 Lisp_Object enabled_p
;
7630 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7631 int mouse_down_p
, rc
;
7633 /* Function note_mouse_highlight is called with negative x(y
7634 values when mouse moves outside of the frame. */
7635 if (x
<= 0 || y
<= 0)
7637 clear_mouse_face (dpyinfo
);
7641 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7644 /* Not on tool-bar item. */
7645 clear_mouse_face (dpyinfo
);
7649 /* On same tool-bar item as before. */
7652 clear_mouse_face (dpyinfo
);
7654 /* Mouse is down, but on different tool-bar item? */
7655 mouse_down_p
= (dpyinfo
->grabbed
7656 && f
== last_mouse_frame
7657 && FRAME_LIVE_P (f
));
7659 && last_tool_bar_item
!= prop_idx
)
7662 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7663 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7665 /* If tool-bar item is not enabled, don't highlight it. */
7666 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7667 if (!NILP (enabled_p
))
7669 /* Compute the x-position of the glyph. In front and past the
7670 image is a space. We include this is the highlighted area. */
7671 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7672 for (i
= x
= 0; i
< hpos
; ++i
)
7673 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7675 /* Record this as the current active region. */
7676 dpyinfo
->mouse_face_beg_col
= hpos
;
7677 dpyinfo
->mouse_face_beg_row
= vpos
;
7678 dpyinfo
->mouse_face_beg_x
= x
;
7679 dpyinfo
->mouse_face_beg_y
= row
->y
;
7680 dpyinfo
->mouse_face_past_end
= 0;
7682 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7683 dpyinfo
->mouse_face_end_row
= vpos
;
7684 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7685 dpyinfo
->mouse_face_end_y
= row
->y
;
7686 dpyinfo
->mouse_face_window
= window
;
7687 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7689 /* Display it as active. */
7690 show_mouse_face (dpyinfo
, draw
);
7691 dpyinfo
->mouse_face_image_state
= draw
;
7696 /* Set help_echo to a help string.to display for this tool-bar item.
7697 XTread_socket does the rest. */
7698 help_echo_object
= help_echo_window
= Qnil
;
7700 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7701 if (NILP (help_echo
))
7702 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7707 /* Find the glyph matrix position of buffer position CHARPOS in window
7708 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7709 current glyphs must be up to date. If CHARPOS is above window
7710 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7711 of last line in W. In the row containing CHARPOS, stop before glyphs
7712 having STOP as object. */
7714 #if 0 /* This is a version of fast_find_position that's more correct
7715 in the presence of hscrolling, for example. I didn't install
7716 it right away because the problem fixed is minor, it failed
7717 in 20.x as well, and I think it's too risky to install
7718 so near the release of 21.1. 2001-09-25 gerd. */
7721 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7724 int *hpos
, *vpos
, *x
, *y
;
7727 struct glyph_row
*row
, *first
;
7728 struct glyph
*glyph
, *end
;
7729 int i
, past_end
= 0;
7731 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7732 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7735 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7737 *x
= *y
= *hpos
= *vpos
= 0;
7742 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7749 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7751 glyph
= row
->glyphs
[TEXT_AREA
];
7752 end
= glyph
+ row
->used
[TEXT_AREA
];
7754 /* Skip over glyphs not having an object at the start of the row.
7755 These are special glyphs like truncation marks on terminal
7757 if (row
->displays_text_p
)
7759 && INTEGERP (glyph
->object
)
7760 && !EQ (stop
, glyph
->object
)
7761 && glyph
->charpos
< 0)
7763 *x
+= glyph
->pixel_width
;
7768 && !INTEGERP (glyph
->object
)
7769 && !EQ (stop
, glyph
->object
)
7770 && (!BUFFERP (glyph
->object
)
7771 || glyph
->charpos
< charpos
))
7773 *x
+= glyph
->pixel_width
;
7777 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7784 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7787 int *hpos
, *vpos
, *x
, *y
;
7792 int maybe_next_line_p
= 0;
7793 int line_start_position
;
7794 int yb
= window_text_bottom_y (w
);
7795 struct glyph_row
*row
, *best_row
;
7796 int row_vpos
, best_row_vpos
;
7799 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7800 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7804 if (row
->used
[TEXT_AREA
])
7805 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7807 line_start_position
= 0;
7809 if (line_start_position
> pos
)
7811 /* If the position sought is the end of the buffer,
7812 don't include the blank lines at the bottom of the window. */
7813 else if (line_start_position
== pos
7814 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7816 maybe_next_line_p
= 1;
7819 else if (line_start_position
> 0)
7822 best_row_vpos
= row_vpos
;
7825 if (row
->y
+ row
->height
>= yb
)
7832 /* Find the right column within BEST_ROW. */
7834 current_x
= best_row
->x
;
7835 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7837 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7838 int charpos
= glyph
->charpos
;
7840 if (BUFFERP (glyph
->object
))
7845 *vpos
= best_row_vpos
;
7850 else if (charpos
> pos
)
7853 else if (EQ (glyph
->object
, stop
))
7858 current_x
+= glyph
->pixel_width
;
7861 /* If we're looking for the end of the buffer,
7862 and we didn't find it in the line we scanned,
7863 use the start of the following line. */
7864 if (maybe_next_line_p
)
7869 current_x
= best_row
->x
;
7872 *vpos
= best_row_vpos
;
7873 *hpos
= lastcol
+ 1;
7882 /* Find the position of the glyph for position POS in OBJECT in
7883 window W's current matrix, and return in *X/*Y the pixel
7884 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7886 RIGHT_P non-zero means return the position of the right edge of the
7887 glyph, RIGHT_P zero means return the left edge position.
7889 If no glyph for POS exists in the matrix, return the position of
7890 the glyph with the next smaller position that is in the matrix, if
7891 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7892 exists in the matrix, return the position of the glyph with the
7893 next larger position in OBJECT.
7895 Value is non-zero if a glyph was found. */
7898 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7902 int *hpos
, *vpos
, *x
, *y
;
7905 int yb
= window_text_bottom_y (w
);
7906 struct glyph_row
*r
;
7907 struct glyph
*best_glyph
= NULL
;
7908 struct glyph_row
*best_row
= NULL
;
7911 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7912 r
->enabled_p
&& r
->y
< yb
;
7915 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7916 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7919 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7920 if (EQ (g
->object
, object
))
7922 if (g
->charpos
== pos
)
7929 else if (best_glyph
== NULL
7930 || ((abs (g
->charpos
- pos
)
7931 < abs (best_glyph
->charpos
- pos
))
7934 : g
->charpos
> pos
)))
7948 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7952 *x
+= best_glyph
->pixel_width
;
7957 *vpos
= best_row
- w
->current_matrix
->rows
;
7960 return best_glyph
!= NULL
;
7964 /* Display the active region described by mouse_face_*
7965 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7968 show_mouse_face (dpyinfo
, draw
)
7969 struct mac_display_info
*dpyinfo
;
7970 enum draw_glyphs_face draw
;
7972 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7973 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7975 if (/* If window is in the process of being destroyed, don't bother
7977 w
->current_matrix
!= NULL
7978 /* Don't update mouse highlight if hidden */
7979 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7980 /* Recognize when we are called to operate on rows that don't exist
7981 anymore. This can happen when a window is split. */
7982 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7984 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7985 struct glyph_row
*row
, *first
, *last
;
7987 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7988 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7990 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7992 int start_hpos
, end_hpos
, start_x
;
7994 /* For all but the first row, the highlight starts at column 0. */
7997 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7998 start_x
= dpyinfo
->mouse_face_beg_x
;
8007 end_hpos
= dpyinfo
->mouse_face_end_col
;
8009 end_hpos
= row
->used
[TEXT_AREA
];
8011 if (end_hpos
> start_hpos
)
8013 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
8014 start_hpos
, end_hpos
, draw
, 0);
8017 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8021 /* When we've written over the cursor, arrange for it to
8022 be displayed again. */
8023 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8024 x_display_cursor (w
, 1,
8025 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8026 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8029 #if 0 /* MAC_TODO: mouse cursor */
8030 /* Change the mouse cursor. */
8031 if (draw
== DRAW_NORMAL_TEXT
)
8032 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8033 f
->output_data
.x
->text_cursor
);
8034 else if (draw
== DRAW_MOUSE_FACE
)
8035 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8036 f
->output_data
.x
->cross_cursor
);
8038 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8039 f
->output_data
.x
->nontext_cursor
);
8043 /* Clear out the mouse-highlighted active region.
8044 Redraw it un-highlighted first. */
8047 clear_mouse_face (dpyinfo
)
8048 struct mac_display_info
*dpyinfo
;
8052 if (! NILP (dpyinfo
->mouse_face_window
))
8054 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8058 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8059 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8060 dpyinfo
->mouse_face_window
= Qnil
;
8061 dpyinfo
->mouse_face_overlay
= Qnil
;
8066 /* Clear any mouse-face on window W. This function is part of the
8067 redisplay interface, and is called from try_window_id and similar
8068 functions to ensure the mouse-highlight is off. */
8071 x_clear_mouse_face (w
)
8074 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
8078 XSETWINDOW (window
, w
);
8079 if (EQ (window
, dpyinfo
->mouse_face_window
))
8080 clear_mouse_face (dpyinfo
);
8085 /* Just discard the mouse face information for frame F, if any.
8086 This is used when the size of F is changed. */
8089 cancel_mouse_face (f
)
8093 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8095 window
= dpyinfo
->mouse_face_window
;
8096 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8098 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8099 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8100 dpyinfo
->mouse_face_window
= Qnil
;
8104 static struct scroll_bar
*x_window_to_scroll_bar ();
8105 static void x_scroll_bar_report_motion ();
8106 static void x_check_fullscreen
P_ ((struct frame
*));
8107 static void x_check_fullscreen_move
P_ ((struct frame
*));
8108 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
8111 /* Try to determine frame pixel position and size of the glyph under
8112 frame pixel coordinates X/Y on frame F . Return the position and
8113 size in *RECT. Value is non-zero if we could compute these
8117 glyph_rect (f
, x
, y
, rect
)
8125 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8128 struct window
*w
= XWINDOW (window
);
8129 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8130 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8132 frame_to_window_pixel_xy (w
, &x
, &y
);
8134 for (; r
< end
&& r
->enabled_p
; ++r
)
8135 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
8137 /* Found the row at y. */
8138 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8139 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8142 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8143 rect
->bottom
= rect
->top
+ r
->height
;
8147 /* x is to the left of the first glyph in the row. */
8148 rect
->left
= XINT (w
->left
);
8149 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
8153 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
8154 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
8156 /* x is on a glyph. */
8157 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8158 rect
->right
= rect
->left
+ g
->pixel_width
;
8162 /* x is to the right of the last glyph in the row. */
8163 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8164 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8169 /* The y is not on any row. */
8173 /* Record the position of the mouse in last_mouse_glyph. */
8175 remember_mouse_glyph (f1
, gx
, gy
)
8179 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8181 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8182 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8184 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8185 round down even for negative values. */
8191 /* This was the original code from XTmouse_position, but it seems
8192 to give the position of the glyph diagonally next to the one
8193 the mouse is over. */
8194 gx
= (gx
+ width
- 1) / width
* width
;
8195 gy
= (gy
+ height
- 1) / height
* height
;
8197 gx
= gx
/ width
* width
;
8198 gy
= gy
/ height
* height
;
8201 last_mouse_glyph
.left
= gx
;
8202 last_mouse_glyph
.top
= gy
;
8203 last_mouse_glyph
.right
= gx
+ width
;
8204 last_mouse_glyph
.bottom
= gy
+ height
;
8208 /* Return the current position of the mouse.
8209 *fp should be a frame which indicates which display to ask about.
8211 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8212 and *part to the frame, window, and scroll bar part that the mouse
8213 is over. Set *x and *y to the portion and whole of the mouse's
8214 position on the scroll bar.
8216 If the mouse movement started elsewhere, set *fp to the frame the
8217 mouse is on, *bar_window to nil, and *x and *y to the character cell
8220 Set *time to the server time-stamp for the time at which the mouse
8221 was at this position.
8223 Don't store anything if we don't have a valid set of values to report.
8225 This clears the mouse_moved flag, so we can wait for the next mouse
8229 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8232 Lisp_Object
*bar_window
;
8233 enum scroll_bar_part
*part
;
8235 unsigned long *time
;
8238 int ignore1
, ignore2
;
8239 WindowPtr wp
= FrontWindow ();
8240 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8241 Lisp_Object frame
, tail
;
8245 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8246 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8249 /* Clear the mouse-moved flag for every frame on this display. */
8250 FOR_EACH_FRAME (tail
, frame
)
8251 XFRAME (frame
)->mouse_moved
= 0;
8253 last_mouse_scroll_bar
= Qnil
;
8255 #if TARGET_API_MAC_CARBON
8256 SetPort (GetWindowPort (wp
));
8261 GetMouse (&mouse_pos
);
8263 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8264 &last_mouse_glyph
, insist
);
8267 *part
= scroll_bar_handle
;
8269 XSETINT (*x
, mouse_pos
.h
);
8270 XSETINT (*y
, mouse_pos
.v
);
8271 *time
= last_mouse_movement_time
;
8278 /************************************************************************
8279 Scroll bars, general
8280 ************************************************************************/
8282 /* Create a scroll bar and return the scroll bar vector for it. W is
8283 the Emacs window on which to create the scroll bar. TOP, LEFT,
8284 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8287 static struct scroll_bar
*
8288 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8290 int top
, left
, width
, height
, disp_top
, disp_height
;
8292 struct frame
*f
= XFRAME (w
->frame
);
8293 struct scroll_bar
*bar
8294 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8302 r
.right
= left
+ width
;
8303 r
.bottom
= disp_top
+ disp_height
;
8305 #ifdef TARGET_API_MAC_CARBON
8306 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8307 kControlScrollBarProc
, 0L);
8309 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8312 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8313 SetControlReference (ch
, (long) bar
);
8315 XSETWINDOW (bar
->window
, w
);
8316 XSETINT (bar
->top
, top
);
8317 XSETINT (bar
->left
, left
);
8318 XSETINT (bar
->width
, width
);
8319 XSETINT (bar
->height
, height
);
8320 XSETINT (bar
->start
, 0);
8321 XSETINT (bar
->end
, 0);
8322 bar
->dragging
= Qnil
;
8324 /* Add bar to its frame's list of scroll bars. */
8325 bar
->next
= FRAME_SCROLL_BARS (f
);
8327 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8328 if (!NILP (bar
->next
))
8329 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8336 /* Draw BAR's handle in the proper position.
8338 If the handle is already drawn from START to END, don't bother
8339 redrawing it, unless REBUILD is non-zero; in that case, always
8340 redraw it. (REBUILD is handy for drawing the handle after expose
8343 Normally, we want to constrain the start and end of the handle to
8344 fit inside its rectangle, but if the user is dragging the scroll
8345 bar handle, we want to let them drag it down all the way, so that
8346 the bar's top is as far down as it goes; otherwise, there's no way
8347 to move to the very end of the buffer. */
8350 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8351 struct scroll_bar
*bar
;
8355 int dragging
= ! NILP (bar
->dragging
);
8356 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8357 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8358 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8359 int length
= end
- start
;
8361 /* If the display is already accurate, do nothing. */
8363 && start
== XINT (bar
->start
)
8364 && end
== XINT (bar
->end
))
8369 /* Make sure the values are reasonable, and try to preserve the
8370 distance between start and end. */
8373 else if (start
> top_range
)
8375 end
= start
+ length
;
8379 else if (end
> top_range
&& ! dragging
)
8382 /* Store the adjusted setting in the scroll bar. */
8383 XSETINT (bar
->start
, start
);
8384 XSETINT (bar
->end
, end
);
8386 /* Clip the end position, just for display. */
8387 if (end
> top_range
)
8390 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8391 top positions, to make sure the handle is always at least that
8392 many pixels tall. */
8393 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8395 SetControlMinimum (ch
, 0);
8396 /* Don't inadvertently activate deactivated scroll bars */
8397 if (GetControlMaximum (ch
) != -1)
8398 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8400 SetControlValue (ch
, start
);
8401 #if TARGET_API_MAC_CARBON
8402 SetControlViewSize (ch
, end
- start
);
8409 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8413 x_scroll_bar_remove (bar
)
8414 struct scroll_bar
*bar
;
8416 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8420 /* Destroy the Mac scroll bar control */
8421 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8423 /* Disassociate this scroll bar from its window. */
8424 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8429 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8430 that we are displaying PORTION characters out of a total of WHOLE
8431 characters, starting at POSITION. If WINDOW has no scroll bar,
8434 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8436 int portion
, whole
, position
;
8438 struct frame
*f
= XFRAME (w
->frame
);
8439 struct scroll_bar
*bar
;
8440 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8441 int window_x
, window_y
, window_width
, window_height
;
8443 /* Get window dimensions. */
8444 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8449 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8451 height
= window_height
;
8453 /* Compute the left edge of the scroll bar area. */
8454 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8455 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8457 left
= XFASTINT (w
->left
);
8458 left
*= CANON_X_UNIT (f
);
8459 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8461 /* Compute the width of the scroll bar which might be less than
8462 the width of the area reserved for the scroll bar. */
8463 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8464 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8468 /* Compute the left edge of the scroll bar. */
8469 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8470 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8472 sb_left
= left
+ (width
- sb_width
) / 2;
8474 /* Adjustments according to Inside Macintosh to make it look nice */
8476 disp_height
= height
;
8482 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8488 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8491 /* Does the scroll bar exist yet? */
8492 if (NILP (w
->vertical_scroll_bar
))
8495 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8496 left
, top
, width
, height
, 0);
8498 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8500 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8504 /* It may just need to be moved and resized. */
8507 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8508 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8512 /* If already correctly positioned, do nothing. */
8513 if (XINT (bar
->left
) == sb_left
8514 && XINT (bar
->top
) == top
8515 && XINT (bar
->width
) == sb_width
8516 && XINT (bar
->height
) == height
)
8520 /* Clear areas not covered by the scroll bar because it's not as
8521 wide as the area reserved for it . This makes sure a
8522 previous mode line display is cleared after C-x 2 C-x 1, for
8524 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8525 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8526 left
, top
, area_width
, height
, 0);
8529 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8530 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8531 sb_left
- 1, top
, 1, height
, 0);
8535 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8536 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8540 /* Remember new settings. */
8541 XSETINT (bar
->left
, sb_left
);
8542 XSETINT (bar
->top
, top
);
8543 XSETINT (bar
->width
, sb_width
);
8544 XSETINT (bar
->height
, height
);
8550 /* Set the scroll bar's current state, unless we're currently being
8552 if (NILP (bar
->dragging
))
8554 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8557 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8560 int start
= ((double) position
* top_range
) / whole
;
8561 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8562 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8568 /* The following three hooks are used when we're doing a thorough
8569 redisplay of the frame. We don't explicitly know which scroll bars
8570 are going to be deleted, because keeping track of when windows go
8571 away is a real pain - "Can you say set-window-configuration, boys
8572 and girls?" Instead, we just assert at the beginning of redisplay
8573 that *all* scroll bars are to be removed, and then save a scroll bar
8574 from the fiery pit when we actually redisplay its window. */
8576 /* Arrange for all scroll bars on FRAME to be removed at the next call
8577 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8578 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8581 XTcondemn_scroll_bars (frame
)
8584 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8585 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8588 bar
= FRAME_SCROLL_BARS (frame
);
8589 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8590 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8591 XSCROLL_BAR (bar
)->prev
= Qnil
;
8592 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8593 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8594 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8599 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8600 Note that WINDOW isn't necessarily condemned at all. */
8603 XTredeem_scroll_bar (window
)
8604 struct window
*window
;
8606 struct scroll_bar
*bar
;
8608 /* We can't redeem this window's scroll bar if it doesn't have one. */
8609 if (NILP (window
->vertical_scroll_bar
))
8612 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8614 /* Unlink it from the condemned list. */
8616 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8618 if (NILP (bar
->prev
))
8620 /* If the prev pointer is nil, it must be the first in one of
8622 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8623 /* It's not condemned. Everything's fine. */
8625 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8626 window
->vertical_scroll_bar
))
8627 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8629 /* If its prev pointer is nil, it must be at the front of
8630 one or the other! */
8634 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8636 if (! NILP (bar
->next
))
8637 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8639 bar
->next
= FRAME_SCROLL_BARS (f
);
8641 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8642 if (! NILP (bar
->next
))
8643 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8647 /* Remove all scroll bars on FRAME that haven't been saved since the
8648 last call to `*condemn_scroll_bars_hook'. */
8651 XTjudge_scroll_bars (f
)
8654 Lisp_Object bar
, next
;
8656 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8658 /* Clear out the condemned list now so we won't try to process any
8659 more events on the hapless scroll bars. */
8660 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8662 for (; ! NILP (bar
); bar
= next
)
8664 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8666 x_scroll_bar_remove (b
);
8669 b
->next
= b
->prev
= Qnil
;
8672 /* Now there should be no references to the condemned scroll bars,
8673 and they should get garbage-collected. */
8678 activate_scroll_bars (frame
)
8684 bar
= FRAME_SCROLL_BARS (frame
);
8685 while (! NILP (bar
))
8687 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8688 #ifdef TARGET_API_MAC_CARBON
8689 ActivateControl (ch
);
8691 SetControlMaximum (ch
,
8692 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8693 XINT (XSCROLL_BAR (bar
)
8696 bar
= XSCROLL_BAR (bar
)->next
;
8702 deactivate_scroll_bars (frame
)
8708 bar
= FRAME_SCROLL_BARS (frame
);
8709 while (! NILP (bar
))
8711 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8712 #ifdef TARGET_API_MAC_CARBON
8713 DeactivateControl (ch
);
8715 SetControlMaximum (ch
, XINT (-1));
8717 bar
= XSCROLL_BAR (bar
)->next
;
8721 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8722 is set to something other than NO_EVENT, it is enqueued.
8724 This may be called from a signal handler, so we have to ignore GC
8728 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8729 struct scroll_bar
*bar
;
8732 struct input_event
*bufp
;
8734 if (! GC_WINDOWP (bar
->window
))
8737 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
8738 bufp
->frame_or_window
= bar
->window
;
8741 bar
->dragging
= Qnil
;
8745 case kControlUpButtonPart
:
8746 bufp
->part
= scroll_bar_up_arrow
;
8748 case kControlDownButtonPart
:
8749 bufp
->part
= scroll_bar_down_arrow
;
8751 case kControlPageUpPart
:
8752 bufp
->part
= scroll_bar_above_handle
;
8754 case kControlPageDownPart
:
8755 bufp
->part
= scroll_bar_below_handle
;
8757 #ifdef TARGET_API_MAC_CARBON
8760 case kControlIndicatorPart
:
8762 if (er
->what
== mouseDown
)
8763 bar
->dragging
= make_number (0);
8764 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8765 bufp
->part
= scroll_bar_handle
;
8771 /* Handle some mouse motion while someone is dragging the scroll bar.
8773 This may be called from a signal handler, so we have to ignore GC
8777 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8778 struct scroll_bar
*bar
;
8782 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8784 last_mouse_movement_time
= t
;
8787 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8789 /* If we're dragging the bar, display it. */
8790 if (! GC_NILP (bar
->dragging
))
8792 /* Where should the handle be now? */
8793 int new_start
= y_pos
- 24;
8795 if (new_start
!= XINT (bar
->start
))
8797 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8799 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8805 /* Return information to the user about the current position of the
8806 mouse on the scroll bar. */
8809 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8811 Lisp_Object
*bar_window
;
8812 enum scroll_bar_part
*part
;
8814 unsigned long *time
;
8816 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8817 WindowPtr wp
= FrontWindow ();
8819 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8820 int win_y
, top_range
;
8822 #if TARGET_API_MAC_CARBON
8823 SetPort (GetWindowPort (wp
));
8828 GetMouse (&mouse_pos
);
8830 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8831 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8833 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8837 if (! NILP (bar
->dragging
))
8838 win_y
-= XINT (bar
->dragging
);
8842 if (win_y
> top_range
)
8846 *bar_window
= bar
->window
;
8848 if (! NILP (bar
->dragging
))
8849 *part
= scroll_bar_handle
;
8850 else if (win_y
< XINT (bar
->start
))
8851 *part
= scroll_bar_above_handle
;
8852 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8853 *part
= scroll_bar_handle
;
8855 *part
= scroll_bar_below_handle
;
8857 XSETINT (*x
, win_y
);
8858 XSETINT (*y
, top_range
);
8861 last_mouse_scroll_bar
= Qnil
;
8863 *time
= last_mouse_movement_time
;
8866 /***********************************************************************
8868 ***********************************************************************/
8870 /* Notice if the text cursor of window W has been overwritten by a
8871 drawing operation that outputs glyphs starting at START_X and
8872 ending at END_X in the line given by output_cursor.vpos.
8873 Coordinates are area-relative. END_X < 0 means all the rest
8874 of the line after START_X has been written. */
8877 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8879 enum glyph_row_area area
;
8882 if (area
== TEXT_AREA
8883 && w
->phys_cursor_on_p
8884 && y0
<= w
->phys_cursor
.y
8885 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8886 && x0
<= w
->phys_cursor
.x
8887 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8888 w
->phys_cursor_on_p
= 0;
8892 /* Set clipping for output in glyph row ROW. W is the window in which
8893 we operate. GC is the graphics context to set clipping in.
8894 WHOLE_LINE_P non-zero means include the areas used for truncation
8895 mark display and alike in the clipping rectangle.
8897 ROW may be a text row or, e.g., a mode line. Text rows must be
8898 clipped to the interior of the window dedicated to text display,
8899 mode lines must be clipped to the whole window. */
8902 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8904 struct glyph_row
*row
;
8908 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8910 int window_x
, window_y
, window_width
, window_height
;
8912 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8914 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8915 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8916 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8917 clip_rect
.right
= clip_rect
.left
+ window_width
;
8918 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8920 /* If clipping to the whole line, including trunc marks, extend
8921 the rectangle to the left and increase its width. */
8924 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8925 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8928 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8932 /* Draw a hollow box cursor on window W in glyph row ROW. */
8935 x_draw_hollow_cursor (w
, row
)
8937 struct glyph_row
*row
;
8939 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8940 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8941 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8944 struct glyph
*cursor_glyph
;
8947 /* Compute frame-relative coordinates from window-relative
8949 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8950 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8951 + row
->ascent
- w
->phys_cursor_ascent
);
8952 h
= row
->height
- 1;
8954 /* Get the glyph the cursor is on. If we can't tell because
8955 the current matrix is invalid or such, give up. */
8956 cursor_glyph
= get_phys_cursor_glyph (w
);
8957 if (cursor_glyph
== NULL
)
8960 /* Compute the width of the rectangle to draw. If on a stretch
8961 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8962 rectangle as wide as the glyph, but use a canonical character
8964 wd
= cursor_glyph
->pixel_width
- 1;
8965 if (cursor_glyph
->type
== STRETCH_GLYPH
8966 && !x_stretch_cursor_p
)
8967 wd
= min (CANON_X_UNIT (f
), wd
);
8969 /* The foreground of cursor_gc is typically the same as the normal
8970 background color, which can cause the cursor box to be invisible. */
8971 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8972 if (dpyinfo
->scratch_cursor_gc
)
8973 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8975 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8976 GCForeground
, &xgcv
);
8977 gc
= dpyinfo
->scratch_cursor_gc
;
8979 /* Set clipping, draw the rectangle, and reset clipping again. */
8980 x_clip_to_row (w
, row
, gc
, 0);
8981 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
8982 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8986 /* Draw a bar cursor on window W in glyph row ROW.
8988 Implementation note: One would like to draw a bar cursor with an
8989 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8990 Unfortunately, I didn't find a font yet that has this property set.
8994 x_draw_bar_cursor (w
, row
, width
)
8996 struct glyph_row
*row
;
8999 /* If cursor hpos is out of bounds, don't draw garbage. This can
9000 happen in mini-buffer windows when switching between echo area
9001 glyphs and mini-buffer. */
9002 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9004 struct frame
*f
= XFRAME (w
->frame
);
9005 struct glyph
*cursor_glyph
;
9013 cursor_glyph
= get_phys_cursor_glyph (w
);
9014 if (cursor_glyph
== NULL
)
9017 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
9018 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9019 mask
= GCForeground
| GCBackground
;
9020 dpy
= FRAME_MAC_DISPLAY (f
);
9021 window
= FRAME_MAC_WINDOW (f
);
9022 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9025 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9028 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9029 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9033 width
= f
->output_data
.mac
->cursor_width
;
9035 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9036 x_clip_to_row (w
, row
, gc
, 0);
9037 XFillRectangle (dpy
, window
, gc
,
9039 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9040 min (cursor_glyph
->pixel_width
, width
),
9042 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9047 /* Clear the cursor of window W to background color, and mark the
9048 cursor as not shown. This is used when the text where the cursor
9049 is is about to be rewritten. */
9055 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9056 x_update_window_cursor (w
, 0);
9060 /* Draw the cursor glyph of window W in glyph row ROW. See the
9061 comment of x_draw_glyphs for the meaning of HL. */
9064 x_draw_phys_cursor_glyph (w
, row
, hl
)
9066 struct glyph_row
*row
;
9067 enum draw_glyphs_face hl
;
9069 /* If cursor hpos is out of bounds, don't draw garbage. This can
9070 happen in mini-buffer windows when switching between echo area
9071 glyphs and mini-buffer. */
9072 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9074 int on_p
= w
->phys_cursor_on_p
;
9075 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9076 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9078 w
->phys_cursor_on_p
= on_p
;
9080 /* When we erase the cursor, and ROW is overlapped by other
9081 rows, make sure that these overlapping parts of other rows
9083 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9085 if (row
> w
->current_matrix
->rows
9086 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9087 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9089 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9090 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9091 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9097 /* Erase the image of a cursor of window W from the screen. */
9100 x_erase_phys_cursor (w
)
9103 struct frame
*f
= XFRAME (w
->frame
);
9104 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9105 int hpos
= w
->phys_cursor
.hpos
;
9106 int vpos
= w
->phys_cursor
.vpos
;
9107 int mouse_face_here_p
= 0;
9108 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9109 struct glyph_row
*cursor_row
;
9110 struct glyph
*cursor_glyph
;
9111 enum draw_glyphs_face hl
;
9113 /* No cursor displayed or row invalidated => nothing to do on the
9115 if (w
->phys_cursor_type
== NO_CURSOR
)
9116 goto mark_cursor_off
;
9118 /* VPOS >= active_glyphs->nrows means that window has been resized.
9119 Don't bother to erase the cursor. */
9120 if (vpos
>= active_glyphs
->nrows
)
9121 goto mark_cursor_off
;
9123 /* If row containing cursor is marked invalid, there is nothing we
9125 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9126 if (!cursor_row
->enabled_p
)
9127 goto mark_cursor_off
;
9129 /* If row is completely invisible, don't attempt to delete a cursor which
9130 isn't there. This may happen if cursor is at top of window, and
9131 we switch to a buffer with a header line in that window. */
9132 if (cursor_row
->visible_height
<= 0)
9133 goto mark_cursor_off
;
9135 /* This can happen when the new row is shorter than the old one.
9136 In this case, either x_draw_glyphs or clear_end_of_line
9137 should have cleared the cursor. Note that we wouldn't be
9138 able to erase the cursor in this case because we don't have a
9139 cursor glyph at hand. */
9140 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9141 goto mark_cursor_off
;
9143 /* If the cursor is in the mouse face area, redisplay that when
9144 we clear the cursor. */
9145 if (! NILP (dpyinfo
->mouse_face_window
)
9146 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9147 && (vpos
> dpyinfo
->mouse_face_beg_row
9148 || (vpos
== dpyinfo
->mouse_face_beg_row
9149 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9150 && (vpos
< dpyinfo
->mouse_face_end_row
9151 || (vpos
== dpyinfo
->mouse_face_end_row
9152 && hpos
< dpyinfo
->mouse_face_end_col
))
9153 /* Don't redraw the cursor's spot in mouse face if it is at the
9154 end of a line (on a newline). The cursor appears there, but
9155 mouse highlighting does not. */
9156 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9157 mouse_face_here_p
= 1;
9159 /* Maybe clear the display under the cursor. */
9160 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9163 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9165 cursor_glyph
= get_phys_cursor_glyph (w
);
9166 if (cursor_glyph
== NULL
)
9167 goto mark_cursor_off
;
9169 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9171 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9173 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9175 cursor_glyph
->pixel_width
,
9176 cursor_row
->visible_height
,
9180 /* Erase the cursor by redrawing the character underneath it. */
9181 if (mouse_face_here_p
)
9182 hl
= DRAW_MOUSE_FACE
;
9184 hl
= DRAW_NORMAL_TEXT
;
9185 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9188 w
->phys_cursor_on_p
= 0;
9189 w
->phys_cursor_type
= NO_CURSOR
;
9193 /* Non-zero if physical cursor of window W is within mouse face. */
9196 cursor_in_mouse_face_p (w
)
9199 struct mac_display_info
*dpyinfo
9200 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9201 int in_mouse_face
= 0;
9203 if (WINDOWP (dpyinfo
->mouse_face_window
)
9204 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9206 int hpos
= w
->phys_cursor
.hpos
;
9207 int vpos
= w
->phys_cursor
.vpos
;
9209 if (vpos
>= dpyinfo
->mouse_face_beg_row
9210 && vpos
<= dpyinfo
->mouse_face_end_row
9211 && (vpos
> dpyinfo
->mouse_face_beg_row
9212 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9213 && (vpos
< dpyinfo
->mouse_face_end_row
9214 || hpos
< dpyinfo
->mouse_face_end_col
9215 || dpyinfo
->mouse_face_past_end
))
9219 return in_mouse_face
;
9223 /* Display or clear cursor of window W. If ON is zero, clear the
9224 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9225 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9228 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9230 int on
, hpos
, vpos
, x
, y
;
9232 struct frame
*f
= XFRAME (w
->frame
);
9233 int new_cursor_type
;
9234 int new_cursor_width
;
9235 struct glyph_matrix
*current_glyphs
;
9236 struct glyph_row
*glyph_row
;
9237 struct glyph
*glyph
;
9238 int cursor_non_selected
;
9239 int active_cursor
= 1;
9241 /* This is pointless on invisible frames, and dangerous on garbaged
9242 windows and frames; in the latter case, the frame or window may
9243 be in the midst of changing its size, and x and y may be off the
9245 if (! FRAME_VISIBLE_P (f
)
9246 || FRAME_GARBAGED_P (f
)
9247 || vpos
>= w
->current_matrix
->nrows
9248 || hpos
>= w
->current_matrix
->matrix_w
)
9251 /* If cursor is off and we want it off, return quickly. */
9252 if (!on
&& !w
->phys_cursor_on_p
)
9255 current_glyphs
= w
->current_matrix
;
9256 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9257 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9259 /* If cursor row is not enabled, we don't really know where to
9260 display the cursor. */
9261 if (!glyph_row
->enabled_p
)
9263 w
->phys_cursor_on_p
= 0;
9267 xassert (interrupt_input_blocked
);
9269 /* Set new_cursor_type to the cursor we want to be displayed. In a
9270 mini-buffer window, we want the cursor only to appear if we are
9271 reading input from this window. For the selected window, we want
9272 the cursor type given by the frame parameter. If explicitly
9273 marked off, draw no cursor. In all other cases, we want a hollow
9276 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9278 new_cursor_width
= -1;
9279 if (cursor_in_echo_area
9280 && FRAME_HAS_MINIBUF_P (f
)
9281 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9283 if (w
== XWINDOW (echo_area_window
))
9284 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9287 if (cursor_non_selected
)
9288 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9290 new_cursor_type
= NO_CURSOR
;
9296 if (f
!= FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
9297 || w
!= XWINDOW (f
->selected_window
))
9301 if (MINI_WINDOW_P (w
)
9302 || !cursor_non_selected
9303 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9304 new_cursor_type
= NO_CURSOR
;
9306 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9310 struct buffer
*b
= XBUFFER (w
->buffer
);
9312 if (EQ (b
->cursor_type
, Qt
))
9313 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9315 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9317 if (w
->cursor_off_p
)
9319 if (new_cursor_type
== FILLED_BOX_CURSOR
)
9320 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9321 else if (new_cursor_type
== BAR_CURSOR
&& new_cursor_width
> 1)
9322 new_cursor_width
= 1;
9324 new_cursor_type
= NO_CURSOR
;
9329 /* If cursor is currently being shown and we don't want it to be or
9330 it is in the wrong place, or the cursor type is not what we want,
9332 if (w
->phys_cursor_on_p
9334 || w
->phys_cursor
.x
!= x
9335 || w
->phys_cursor
.y
!= y
9336 || new_cursor_type
!= w
->phys_cursor_type
9337 || (new_cursor_type
== BAR_CURSOR
9338 && new_cursor_width
!= w
->phys_cursor_width
)))
9339 x_erase_phys_cursor (w
);
9341 /* If the cursor is now invisible and we want it to be visible,
9343 if (on
&& !w
->phys_cursor_on_p
)
9345 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9346 w
->phys_cursor_height
= glyph_row
->height
;
9348 /* Set phys_cursor_.* before x_draw_.* is called because some
9349 of them may need the information. */
9350 w
->phys_cursor
.x
= x
;
9351 w
->phys_cursor
.y
= glyph_row
->y
;
9352 w
->phys_cursor
.hpos
= hpos
;
9353 w
->phys_cursor
.vpos
= vpos
;
9354 w
->phys_cursor_type
= new_cursor_type
;
9355 w
->phys_cursor_width
= new_cursor_width
;
9356 w
->phys_cursor_on_p
= 1;
9358 switch (new_cursor_type
)
9360 case HOLLOW_BOX_CURSOR
:
9361 x_draw_hollow_cursor (w
, glyph_row
);
9364 case FILLED_BOX_CURSOR
:
9365 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9369 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9382 /* Display the cursor on window W, or clear it. X and Y are window
9383 relative pixel coordinates. HPOS and VPOS are glyph matrix
9384 positions. If W is not the selected window, display a hollow
9385 cursor. ON non-zero means display the cursor at X, Y which
9386 correspond to HPOS, VPOS, otherwise it is cleared. */
9389 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9391 int on
, hpos
, vpos
, x
, y
;
9394 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9399 /* Display the cursor on window W, or clear it, according to ON_P.
9400 Don't change the cursor's position. */
9403 x_update_cursor (f
, on_p
)
9407 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9411 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9412 in the window tree rooted at W. */
9415 x_update_cursor_in_window_tree (w
, on_p
)
9421 if (!NILP (w
->hchild
))
9422 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9423 else if (!NILP (w
->vchild
))
9424 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9426 x_update_window_cursor (w
, on_p
);
9428 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9433 /* Switch the display of W's cursor on or off, according to the value
9437 x_update_window_cursor (w
, on
)
9441 /* Don't update cursor in windows whose frame is in the process
9442 of being deleted. */
9443 if (w
->current_matrix
)
9446 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9447 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9458 #if 0 /* MAC_TODO: no icon support yet. */
9460 x_bitmap_icon (f
, icon
)
9466 if (FRAME_W32_WINDOW (f
) == 0)
9470 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9471 else if (STRINGP (icon
))
9472 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9473 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9474 else if (SYMBOLP (icon
))
9478 if (EQ (icon
, intern ("application")))
9479 name
= (LPCTSTR
) IDI_APPLICATION
;
9480 else if (EQ (icon
, intern ("hand")))
9481 name
= (LPCTSTR
) IDI_HAND
;
9482 else if (EQ (icon
, intern ("question")))
9483 name
= (LPCTSTR
) IDI_QUESTION
;
9484 else if (EQ (icon
, intern ("exclamation")))
9485 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9486 else if (EQ (icon
, intern ("asterisk")))
9487 name
= (LPCTSTR
) IDI_ASTERISK
;
9488 else if (EQ (icon
, intern ("winlogo")))
9489 name
= (LPCTSTR
) IDI_WINLOGO
;
9493 hicon
= LoadIcon (NULL
, name
);
9501 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9506 #endif /* MAC_TODO */
9508 /************************************************************************
9510 ************************************************************************/
9512 /* Display Error Handling functions not used on W32. Listing them here
9513 helps diff stay in step when comparing w32term.c with xterm.c.
9515 x_error_catcher (display, error)
9516 x_catch_errors (dpy)
9517 x_catch_errors_unwind (old_val)
9518 x_check_errors (dpy, format)
9519 x_had_errors_p (dpy)
9520 x_clear_errors (dpy)
9521 x_uncatch_errors (dpy, count)
9523 x_connection_signal (signalnum)
9524 x_connection_closed (dpy, error_message)
9525 x_error_quitter (display, error)
9526 x_error_handler (display, error)
9527 x_io_error_quitter (display)
9532 /* Changing the font of the frame. */
9534 /* Give frame F the font named FONTNAME as its default font, and
9535 return the full name of that font. FONTNAME may be a wildcard
9536 pattern; in that case, we choose some font that fits the pattern.
9537 The return value shows which font we chose. */
9540 x_new_font (f
, fontname
)
9542 register char *fontname
;
9544 struct font_info
*fontp
9545 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9550 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9551 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9552 FRAME_FONTSET (f
) = -1;
9554 /* Compute the scroll bar width in character columns. */
9555 if (f
->scroll_bar_pixel_width
> 0)
9557 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9558 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9562 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9563 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9566 /* Now make the frame display the given font. */
9567 if (FRAME_MAC_WINDOW (f
) != 0)
9569 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9570 f
->output_data
.mac
->font
);
9571 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9572 f
->output_data
.mac
->font
);
9573 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9574 f
->output_data
.mac
->font
);
9576 frame_update_line_height (f
);
9577 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9578 x_set_window_size (f
, 0, f
->width
, f
->height
);
9581 /* If we are setting a new frame's font for the first time,
9582 there are no faces yet, so this font's height is the line height. */
9583 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9585 return build_string (fontp
->full_name
);
9588 /* Give frame F the fontset named FONTSETNAME as its default font, and
9589 return the full name of that fontset. FONTSETNAME may be a wildcard
9590 pattern; in that case, we choose some fontset that fits the pattern.
9591 The return value shows which fontset we chose. */
9594 x_new_fontset (f
, fontsetname
)
9598 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9604 if (FRAME_FONTSET (f
) == fontset
)
9605 /* This fontset is already set in frame F. There's nothing more
9607 return fontset_name (fontset
);
9609 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9611 if (!STRINGP (result
))
9612 /* Can't load ASCII font. */
9615 /* Since x_new_font doesn't update any fontset information, do it now. */
9616 FRAME_FONTSET(f
) = fontset
;
9618 return build_string (fontsetname
);
9621 /* Compute actual fringe widths */
9624 x_compute_fringe_widths (f
, redraw
)
9628 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9629 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9630 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9632 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9633 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9634 int left_fringe_width
, right_fringe_width
;
9636 if (!NILP (left_fringe
))
9637 left_fringe
= Fcdr (left_fringe
);
9638 if (!NILP (right_fringe
))
9639 right_fringe
= Fcdr (right_fringe
);
9641 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9642 XINT (left_fringe
));
9643 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9644 XINT (right_fringe
));
9646 if (left_fringe_width
|| right_fringe_width
)
9648 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9649 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9650 int conf_wid
= left_wid
+ right_wid
;
9651 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9652 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9653 int real_wid
= cols
* font_wid
;
9654 if (left_wid
&& right_wid
)
9656 if (left_fringe_width
< 0)
9658 /* Left fringe width is fixed, adjust right fringe if necessary */
9659 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9660 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9662 else if (right_fringe_width
< 0)
9664 /* Right fringe width is fixed, adjust left fringe if necessary */
9665 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9666 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9670 /* Adjust both fringes with an equal amount.
9671 Note that we are doing integer arithmetic here, so don't
9672 lose a pixel if the total width is an odd number. */
9673 int fill
= real_wid
- conf_wid
;
9674 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9675 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9678 else if (left_fringe_width
)
9680 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9681 f
->output_data
.mac
->right_fringe_width
= 0;
9685 f
->output_data
.mac
->left_fringe_width
= 0;
9686 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9688 f
->output_data
.mac
->fringe_cols
= cols
;
9689 f
->output_data
.mac
->fringes_extra
= real_wid
;
9693 f
->output_data
.mac
->left_fringe_width
= 0;
9694 f
->output_data
.mac
->right_fringe_width
= 0;
9695 f
->output_data
.mac
->fringe_cols
= 0;
9696 f
->output_data
.mac
->fringes_extra
= 0;
9699 if (redraw
&& FRAME_VISIBLE_P (f
))
9700 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9701 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9702 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9706 /***********************************************************************
9707 TODO: W32 Input Methods
9708 ***********************************************************************/
9709 /* Listing missing functions from xterm.c helps diff stay in step.
9711 xim_destroy_callback (xim, client_data, call_data)
9712 xim_open_dpy (dpyinfo, resource_name)
9714 xim_instantiate_callback (display, client_data, call_data)
9715 xim_initialize (dpyinfo, resource_name)
9716 xim_close_dpy (dpyinfo)
9721 /* Calculate the absolute position in frame F
9722 from its current recorded position values and gravity. */
9725 x_calc_absolute_position (f
)
9729 int flags
= f
->output_data
.mac
->size_hint_flags
;
9733 /* Find the position of the outside upper-left corner of
9734 the inner window, with respect to the outer window. */
9735 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9738 GetPort (&savePort
);
9740 #if TARGET_API_MAC_CARBON
9741 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9743 SetPort (FRAME_MAC_WINDOW (f
));
9746 #if TARGET_API_MAC_CARBON
9750 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9751 SetPt(&pt
, r
.left
, r
.top
);
9753 #else /* not TARGET_API_MAC_CARBON */
9754 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9755 #endif /* not TARGET_API_MAC_CARBON */
9756 LocalToGlobal (&pt
);
9760 /* Treat negative positions as relative to the leftmost bottommost
9761 position that fits on the screen. */
9762 if (flags
& XNegative
)
9763 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9764 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9766 + f
->output_data
.mac
->left_pos
);
9767 /* NTEMACS_TODO: Subtract menubar height? */
9768 if (flags
& YNegative
)
9769 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9770 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9772 + f
->output_data
.mac
->top_pos
);
9773 /* The left_pos and top_pos
9774 are now relative to the top and left screen edges,
9775 so the flags should correspond. */
9776 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9779 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9780 to really change the position, and 0 when calling from
9781 x_make_frame_visible (in that case, XOFF and YOFF are the current
9782 position values). It is -1 when calling from x_set_frame_parameters,
9783 which means, do adjust for borders but don't change the gravity. */
9786 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9788 register int xoff
, yoff
;
9791 int modified_top
, modified_left
;
9793 if (change_gravity
> 0)
9795 f
->output_data
.mac
->top_pos
= yoff
;
9796 f
->output_data
.mac
->left_pos
= xoff
;
9797 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9799 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9801 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9802 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9804 x_calc_absolute_position (f
);
9807 x_wm_set_size_hint (f
, (long) 0, 0);
9809 modified_left
= f
->output_data
.mac
->left_pos
;
9810 modified_top
= f
->output_data
.mac
->top_pos
;
9812 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9813 modified_top
+ 42, false);
9818 /* Call this to change the size of frame F's x-window.
9819 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9820 for this size change and subsequent size changes.
9821 Otherwise we leave the window gravity unchanged. */
9824 x_set_window_size (f
, change_gravity
, cols
, rows
)
9829 int pixelwidth
, pixelheight
;
9833 check_frame_size (f
, &rows
, &cols
);
9834 f
->output_data
.mac
->vertical_scroll_bar_extra
9835 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9837 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9839 x_compute_fringe_widths (f
, 0);
9841 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9842 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9844 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9845 x_wm_set_size_hint (f
, (long) 0, 0);
9847 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9849 /* Now, strictly speaking, we can't be sure that this is accurate,
9850 but the window manager will get around to dealing with the size
9851 change request eventually, and we'll hear how it went when the
9852 ConfigureNotify event gets here.
9854 We could just not bother storing any of this information here,
9855 and let the ConfigureNotify event set everything up, but that
9856 might be kind of confusing to the Lisp code, since size changes
9857 wouldn't be reported in the frame parameters until some random
9858 point in the future when the ConfigureNotify event arrives.
9860 We pass 1 for DELAY since we can't run Lisp code inside of
9862 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9863 PIXEL_WIDTH (f
) = pixelwidth
;
9864 PIXEL_HEIGHT (f
) = pixelheight
;
9866 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9867 receive in the ConfigureNotify event; if we get what we asked
9868 for, then the event won't cause the screen to become garbaged, so
9869 we have to make sure to do it here. */
9870 SET_FRAME_GARBAGED (f
);
9872 XFlush (FRAME_X_DISPLAY (f
));
9874 /* If cursor was outside the new size, mark it as off. */
9875 mark_window_cursors_off (XWINDOW (f
->root_window
));
9877 /* Clear out any recollection of where the mouse highlighting was,
9878 since it might be in a place that's outside the new frame size.
9879 Actually checking whether it is outside is a pain in the neck,
9880 so don't try--just let the highlighting be done afresh with new size. */
9881 cancel_mouse_face (f
);
9886 /* Mouse warping. */
9888 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9891 x_set_mouse_position (f
, x
, y
)
9897 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9898 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9900 if (pix_x
< 0) pix_x
= 0;
9901 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9903 if (pix_y
< 0) pix_y
= 0;
9904 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9906 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9910 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9914 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9917 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9918 0, 0, 0, 0, pix_x
, pix_y
);
9924 /* focus shifting, raising and lowering. */
9927 x_focus_on_frame (f
)
9930 #if 0 /* This proves to be unpleasant. */
9934 /* I don't think that the ICCCM allows programs to do things like this
9935 without the interaction of the window manager. Whatever you end up
9936 doing with this code, do it to x_unfocus_frame too. */
9937 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9938 RevertToPointerRoot
, CurrentTime
);
9948 /* Raise frame F. */
9953 if (f
->async_visible
)
9954 SelectWindow (FRAME_MAC_WINDOW (f
));
9957 /* Lower frame F. */
9962 if (f
->async_visible
)
9963 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9967 XTframe_raise_lower (f
, raise_flag
)
9977 /* Change of visibility. */
9979 /* This tries to wait until the frame is really visible.
9980 However, if the window manager asks the user where to position
9981 the frame, this will return before the user finishes doing that.
9982 The frame will not actually be visible at that time,
9983 but it will become visible later when the window manager
9984 finishes with it. */
9987 x_make_frame_visible (f
)
9991 int original_top
, original_left
;
9995 if (! FRAME_VISIBLE_P (f
))
9997 /* We test FRAME_GARBAGED_P here to make sure we don't
9998 call x_set_offset a second time
9999 if we get to x_make_frame_visible a second time
10000 before the window gets really visible. */
10001 if (! FRAME_ICONIFIED_P (f
)
10002 && ! f
->output_data
.mac
->asked_for_visible
)
10003 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
10004 f
->output_data
.mac
->top_pos
, 0);
10006 f
->output_data
.mac
->asked_for_visible
= 1;
10008 ShowWindow (FRAME_MAC_WINDOW (f
));
10011 XFlush (FRAME_MAC_DISPLAY (f
));
10013 #if 0 /* MAC_TODO */
10014 /* Synchronize to ensure Emacs knows the frame is visible
10015 before we do anything else. We do this loop with input not blocked
10016 so that incoming events are handled. */
10021 /* This must come after we set COUNT. */
10024 XSETFRAME (frame
, f
);
10026 /* Wait until the frame is visible. Process X events until a
10027 MapNotify event has been seen, or until we think we won't get a
10028 MapNotify at all.. */
10029 for (count
= input_signal_count
+ 10;
10030 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10032 /* Force processing of queued events. */
10035 /* Machines that do polling rather than SIGIO have been
10036 observed to go into a busy-wait here. So we'll fake an
10037 alarm signal to let the handler know that there's something
10038 to be read. We used to raise a real alarm, but it seems
10039 that the handler isn't always enabled here. This is
10041 if (input_polling_used ())
10043 /* It could be confusing if a real alarm arrives while
10044 processing the fake one. Turn it off and let the
10045 handler reset it. */
10046 extern void poll_for_input_1
P_ ((void));
10047 int old_poll_suppress_count
= poll_suppress_count
;
10048 poll_suppress_count
= 1;
10049 poll_for_input_1 ();
10050 poll_suppress_count
= old_poll_suppress_count
;
10053 /* See if a MapNotify event has been processed. */
10054 FRAME_SAMPLE_VISIBILITY (f
);
10057 #endif /* MAC_TODO */
10060 /* Change from mapped state to withdrawn state. */
10062 /* Make the frame visible (mapped and not iconified). */
10065 x_make_frame_invisible (f
)
10068 /* Don't keep the highlight on an invisible frame. */
10069 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10070 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10074 HideWindow (FRAME_MAC_WINDOW (f
));
10076 /* We can't distinguish this from iconification
10077 just by the event that we get from the server.
10078 So we can't win using the usual strategy of letting
10079 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10080 and synchronize with the server to make sure we agree. */
10082 FRAME_ICONIFIED_P (f
) = 0;
10083 f
->async_visible
= 0;
10084 f
->async_iconified
= 0;
10089 /* Change window state from mapped to iconified. */
10092 x_iconify_frame (f
)
10095 #if 0 /* MAC_TODO: really no iconify on Mac */
10099 /* Don't keep the highlight on an invisible frame. */
10100 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10101 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10103 if (f
->async_iconified
)
10108 FRAME_SAMPLE_VISIBILITY (f
);
10110 type
= x_icon_type (f
);
10112 x_bitmap_icon (f
, type
);
10114 #ifdef USE_X_TOOLKIT
10116 if (! FRAME_VISIBLE_P (f
))
10118 if (! EQ (Vx_no_window_manager
, Qt
))
10119 x_wm_set_window_state (f
, IconicState
);
10120 /* This was XtPopup, but that did nothing for an iconified frame. */
10121 XtMapWidget (f
->output_data
.x
->widget
);
10122 /* The server won't give us any event to indicate
10123 that an invisible frame was changed to an icon,
10124 so we have to record it here. */
10127 f
->async_iconified
= 1;
10128 f
->async_visible
= 0;
10133 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
10134 XtWindow (f
->output_data
.x
->widget
),
10135 DefaultScreen (FRAME_X_DISPLAY (f
)));
10139 error ("Can't notify window manager of iconification");
10141 f
->async_iconified
= 1;
10142 f
->async_visible
= 0;
10146 XFlush (FRAME_X_DISPLAY (f
));
10148 #else /* not USE_X_TOOLKIT */
10150 /* Make sure the X server knows where the window should be positioned,
10151 in case the user deiconifies with the window manager. */
10152 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
10153 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
10155 /* Since we don't know which revision of X we're running, we'll use both
10156 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
10158 /* X11R4: send a ClientMessage to the window manager using the
10159 WM_CHANGE_STATE type. */
10163 message
.xclient
.window
= FRAME_X_WINDOW (f
);
10164 message
.xclient
.type
= ClientMessage
;
10165 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
10166 message
.xclient
.format
= 32;
10167 message
.xclient
.data
.l
[0] = IconicState
;
10169 if (! XSendEvent (FRAME_X_DISPLAY (f
),
10170 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
10172 SubstructureRedirectMask
| SubstructureNotifyMask
,
10175 UNBLOCK_INPUT_RESIGNAL
;
10176 error ("Can't notify window manager of iconification");
10180 /* X11R3: set the initial_state field of the window manager hints to
10182 x_wm_set_window_state (f
, IconicState
);
10184 if (!FRAME_VISIBLE_P (f
))
10186 /* If the frame was withdrawn, before, we must map it. */
10187 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10190 f
->async_iconified
= 1;
10191 f
->async_visible
= 0;
10193 XFlush (FRAME_X_DISPLAY (f
));
10195 #endif /* not USE_X_TOOLKIT */
10196 #endif /* MAC_TODO */
10200 /* Destroy the X window of frame F. */
10203 x_destroy_window (f
)
10206 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10210 DisposeWindow (FRAME_MAC_WINDOW (f
));
10212 free_frame_menubar (f
);
10213 free_frame_faces (f
);
10215 xfree (f
->output_data
.mac
);
10216 f
->output_data
.mac
= 0;
10217 if (f
== dpyinfo
->x_focus_frame
)
10218 dpyinfo
->x_focus_frame
= 0;
10219 if (f
== dpyinfo
->x_focus_event_frame
)
10220 dpyinfo
->x_focus_event_frame
= 0;
10221 if (f
== dpyinfo
->x_highlight_frame
)
10222 dpyinfo
->x_highlight_frame
= 0;
10224 dpyinfo
->reference_count
--;
10226 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10228 dpyinfo
->mouse_face_beg_row
10229 = dpyinfo
->mouse_face_beg_col
= -1;
10230 dpyinfo
->mouse_face_end_row
10231 = dpyinfo
->mouse_face_end_col
= -1;
10232 dpyinfo
->mouse_face_window
= Qnil
;
10233 dpyinfo
->mouse_face_deferred_gc
= 0;
10234 dpyinfo
->mouse_face_mouse_frame
= 0;
10240 /* Setting window manager hints. */
10242 /* Set the normal size hints for the window manager, for frame F.
10243 FLAGS is the flags word to use--or 0 meaning preserve the flags
10244 that the window now has.
10245 If USER_POSITION is nonzero, we set the USPosition
10246 flag (this is useful when FLAGS is 0). */
10248 x_wm_set_size_hint (f
, flags
, user_position
)
10253 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10254 XSizeHints size_hints
;
10256 #ifdef USE_X_TOOLKIT
10259 Dimension widget_width
, widget_height
;
10260 Window window
= XtWindow (f
->output_data
.x
->widget
);
10261 #else /* not USE_X_TOOLKIT */
10262 Window window
= FRAME_X_WINDOW (f
);
10263 #endif /* not USE_X_TOOLKIT */
10265 /* Setting PMaxSize caused various problems. */
10266 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10268 size_hints
.x
= f
->output_data
.x
->left_pos
;
10269 size_hints
.y
= f
->output_data
.x
->top_pos
;
10271 #ifdef USE_X_TOOLKIT
10272 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10273 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10274 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10275 size_hints
.height
= widget_height
;
10276 size_hints
.width
= widget_width
;
10277 #else /* not USE_X_TOOLKIT */
10278 size_hints
.height
= PIXEL_HEIGHT (f
);
10279 size_hints
.width
= PIXEL_WIDTH (f
);
10280 #endif /* not USE_X_TOOLKIT */
10282 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10283 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10284 size_hints
.max_width
10285 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10286 size_hints
.max_height
10287 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10289 /* Calculate the base and minimum sizes.
10291 (When we use the X toolkit, we don't do it here.
10292 Instead we copy the values that the widgets are using, below.) */
10293 #ifndef USE_X_TOOLKIT
10295 int base_width
, base_height
;
10296 int min_rows
= 0, min_cols
= 0;
10298 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10299 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10301 check_frame_size (f
, &min_rows
, &min_cols
);
10303 /* The window manager uses the base width hints to calculate the
10304 current number of rows and columns in the frame while
10305 resizing; min_width and min_height aren't useful for this
10306 purpose, since they might not give the dimensions for a
10307 zero-row, zero-column frame.
10309 We use the base_width and base_height members if we have
10310 them; otherwise, we set the min_width and min_height members
10311 to the size for a zero x zero frame. */
10314 size_hints
.flags
|= PBaseSize
;
10315 size_hints
.base_width
= base_width
;
10316 size_hints
.base_height
= base_height
;
10317 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10318 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10320 size_hints
.min_width
= base_width
;
10321 size_hints
.min_height
= base_height
;
10325 /* If we don't need the old flags, we don't need the old hint at all. */
10328 size_hints
.flags
|= flags
;
10331 #endif /* not USE_X_TOOLKIT */
10334 XSizeHints hints
; /* Sometimes I hate X Windows... */
10335 long supplied_return
;
10339 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10342 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10345 #ifdef USE_X_TOOLKIT
10346 size_hints
.base_height
= hints
.base_height
;
10347 size_hints
.base_width
= hints
.base_width
;
10348 size_hints
.min_height
= hints
.min_height
;
10349 size_hints
.min_width
= hints
.min_width
;
10353 size_hints
.flags
|= flags
;
10358 if (hints
.flags
& PSize
)
10359 size_hints
.flags
|= PSize
;
10360 if (hints
.flags
& PPosition
)
10361 size_hints
.flags
|= PPosition
;
10362 if (hints
.flags
& USPosition
)
10363 size_hints
.flags
|= USPosition
;
10364 if (hints
.flags
& USSize
)
10365 size_hints
.flags
|= USSize
;
10369 #ifndef USE_X_TOOLKIT
10374 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10375 size_hints
.flags
|= PWinGravity
;
10379 size_hints
.flags
&= ~ PPosition
;
10380 size_hints
.flags
|= USPosition
;
10382 #endif /* PWinGravity */
10385 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10387 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10389 #endif /* MAC_TODO */
10392 #if 0 /* MAC_TODO: hide application instead of iconify? */
10393 /* Used for IconicState or NormalState */
10396 x_wm_set_window_state (f
, state
)
10400 #ifdef USE_X_TOOLKIT
10403 XtSetArg (al
[0], XtNinitialState
, state
);
10404 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10405 #else /* not USE_X_TOOLKIT */
10406 Window window
= FRAME_X_WINDOW (f
);
10408 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10409 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10411 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10412 #endif /* not USE_X_TOOLKIT */
10416 x_wm_set_icon_pixmap (f
, pixmap_id
)
10420 Pixmap icon_pixmap
;
10422 #ifndef USE_X_TOOLKIT
10423 Window window
= FRAME_X_WINDOW (f
);
10428 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10429 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10433 /* It seems there is no way to turn off use of an icon pixmap.
10434 The following line does it, only if no icon has yet been created,
10435 for some window managers. But with mwm it crashes.
10436 Some people say it should clear the IconPixmapHint bit in this case,
10437 but that doesn't work, and the X consortium said it isn't the
10438 right thing at all. Since there is no way to win,
10439 best to explicitly give up. */
10441 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10447 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10451 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10452 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10455 #else /* not USE_X_TOOLKIT */
10457 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10458 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10460 #endif /* not USE_X_TOOLKIT */
10463 #endif /* MAC_TODO */
10466 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10468 int icon_x
, icon_y
;
10470 #if 0 /* MAC_TODO: no icons on Mac */
10471 #ifdef USE_X_TOOLKIT
10472 Window window
= XtWindow (f
->output_data
.x
->widget
);
10474 Window window
= FRAME_X_WINDOW (f
);
10477 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10478 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10479 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10481 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10482 #endif /* MAC_TODO */
10486 /***********************************************************************
10488 ***********************************************************************/
10490 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10493 x_get_font_info (f
, font_idx
)
10497 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10500 /* the global font name table */
10501 char **font_name_table
= NULL
;
10502 int font_name_table_size
= 0;
10503 int font_name_count
= 0;
10505 /* compare two strings ignoring case */
10507 stricmp (const char *s
, const char *t
)
10509 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10512 return tolower (*s
) - tolower (*t
);
10515 /* compare two strings ignoring case and handling wildcard */
10517 wildstrieq (char *s1
, char *s2
)
10519 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10522 return stricmp (s1
, s2
) == 0;
10525 /* Assume parameter 1 is fully qualified, no wildcards. */
10527 mac_font_pattern_match (fontname
, pattern
)
10531 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10532 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10535 /* Copy fontname so we can modify it during comparison. */
10536 strcpy (font_name_copy
, fontname
);
10541 /* Turn pattern into a regexp and do a regexp match. */
10542 for (; *pattern
; pattern
++)
10544 if (*pattern
== '?')
10546 else if (*pattern
== '*')
10557 return (fast_c_string_match_ignore_case (build_string (regex
),
10558 font_name_copy
) >= 0);
10561 /* Two font specs are considered to match if their foundry, family,
10562 weight, slant, and charset match. */
10564 mac_font_match (char *mf
, char *xf
)
10566 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10567 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10569 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10570 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10571 return mac_font_pattern_match (mf
, xf
);
10573 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10574 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10575 return mac_font_pattern_match (mf
, xf
);
10577 return (wildstrieq (m_foundry
, x_foundry
)
10578 && wildstrieq (m_family
, x_family
)
10579 && wildstrieq (m_weight
, x_weight
)
10580 && wildstrieq (m_slant
, x_slant
)
10581 && wildstrieq (m_charset
, x_charset
))
10582 || mac_font_pattern_match (mf
, xf
);
10587 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10589 char foundry
[32], family
[32], cs
[32];
10590 char xf
[255], *result
, *p
;
10592 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10594 strcpy(foundry
, "Apple");
10595 strcpy(family
, name
);
10597 switch (scriptcode
)
10599 case smTradChinese
:
10600 strcpy(cs
, "big5-0");
10602 case smSimpChinese
:
10603 strcpy(cs
, "gb2312.1980-0");
10606 strcpy(cs
, "jisx0208.1983-sjis");
10609 /* Each Apple Japanese font is entered into the font table
10610 twice: once as a jisx0208.1983-sjis font and once as a
10611 jisx0201.1976-0 font. The latter can be used to display
10612 the ascii charset and katakana-jisx0201 charset. A
10613 negative script code signals that the name of this latter
10614 font is being built. */
10615 strcpy(cs
, "jisx0201.1976-0");
10618 strcpy(cs
, "ksc5601.1989-0");
10621 strcpy(cs
, "mac-roman");
10626 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10627 foundry
, family
, style
& bold
? "bold" : "medium",
10628 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10630 result
= (char *) xmalloc (strlen (xf
) + 1);
10631 strcpy (result
, xf
);
10632 for (p
= result
; *p
; p
++)
10638 /* Convert an X font spec to the corresponding mac font name, which
10639 can then be passed to GetFNum after conversion to a Pascal string.
10640 For ordinary Mac fonts, this should just be their names, like
10641 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10642 collection contain their charset designation in their names, like
10643 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10644 names are handled accordingly. */
10646 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10648 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10652 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10653 foundry
, family
, weight
, slant
, cs
) != 5 &&
10654 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10655 foundry
, family
, weight
, slant
, cs
) != 5)
10658 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10659 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10660 || strcmp (cs
, "jisx0201.1976-0") == 0
10661 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10662 strcpy(mf
, family
);
10664 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10669 add_font_name_table_entry (char *font_name
)
10671 if (font_name_table_size
== 0)
10673 font_name_table_size
= 16;
10674 font_name_table
= (char **)
10675 xmalloc (font_name_table_size
* sizeof (char *));
10677 else if (font_name_count
+ 1 >= font_name_table_size
)
10679 font_name_table_size
+= 16;
10680 font_name_table
= (char **)
10681 xrealloc (font_name_table
,
10682 font_name_table_size
* sizeof (char *));
10685 font_name_table
[font_name_count
++] = font_name
;
10688 /* Sets up the table font_name_table to contain the list of all fonts
10689 in the system the first time the table is used so that the Resource
10690 Manager need not be accessed every time this information is
10694 init_font_name_table ()
10696 #if TARGET_API_MAC_CARBON
10699 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10701 FMFontFamilyIterator ffi
;
10702 FMFontFamilyInstanceIterator ffii
;
10705 /* Create a dummy instance iterator here to avoid creating and
10706 destroying it in the loop. */
10707 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10709 /* Create an iterator to enumerate the font families. */
10710 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10713 FMDisposeFontFamilyInstanceIterator (&ffii
);
10717 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10725 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10729 sc
= FontToScript (ff
);
10731 /* Point the instance iterator at the current font family. */
10732 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10735 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
10739 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10741 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10743 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10745 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10750 add_font_name_table_entry (mac_to_x_fontname (name
, size
, style
,
10754 /* Dispose of the iterators. */
10755 FMDisposeFontFamilyIterator (&ffi
);
10756 FMDisposeFontFamilyInstanceIterator (&ffii
);
10760 #endif /* TARGET_API_MAC_CARBON */
10762 SInt16 fontnum
, old_fontnum
;
10763 int num_mac_fonts
= CountResources('FOND');
10765 Handle font_handle
, font_handle_2
;
10766 short id
, scriptcode
;
10769 struct FontAssoc
*fat
;
10770 struct AsscEntry
*assc_entry
;
10772 GetPort (&port
); /* save the current font number used */
10773 #if TARGET_API_MAC_CARBON
10774 old_fontnum
= GetPortTextFont (port
);
10776 old_fontnum
= port
->txFont
;
10779 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10781 font_handle
= GetIndResource ('FOND', i
);
10785 GetResInfo (font_handle
, &id
, &type
, name
);
10786 GetFNum (name
, &fontnum
);
10791 TextFont (fontnum
);
10792 scriptcode
= FontToScript (fontnum
);
10795 HLock (font_handle
);
10797 if (GetResourceSizeOnDisk (font_handle
)
10798 >= sizeof (struct FamRec
))
10800 fat
= (struct FontAssoc
*) (*font_handle
10801 + sizeof (struct FamRec
));
10803 = (struct AsscEntry
*) (*font_handle
10804 + sizeof (struct FamRec
)
10805 + sizeof (struct FontAssoc
));
10807 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10809 if (font_name_table_size
== 0)
10811 font_name_table_size
= 16;
10812 font_name_table
= (char **)
10813 xmalloc (font_name_table_size
* sizeof (char *));
10815 else if (font_name_count
>= font_name_table_size
)
10817 font_name_table_size
+= 16;
10818 font_name_table
= (char **)
10819 xrealloc (font_name_table
,
10820 font_name_table_size
* sizeof (char *));
10822 font_name_table
[font_name_count
++]
10823 = mac_to_x_fontname (name
,
10824 assc_entry
->fontSize
,
10825 assc_entry
->fontStyle
,
10827 /* Both jisx0208.1983-sjis and
10828 jisx0201.1976-sjis parts are contained in
10829 Apple Japanese (SJIS) font. */
10830 if (smJapanese
== scriptcode
)
10832 font_name_table
[font_name_count
++]
10833 = mac_to_x_fontname (name
,
10834 assc_entry
->fontSize
,
10835 assc_entry
->fontStyle
,
10841 HUnlock (font_handle
);
10842 font_handle_2
= GetNextFOND (font_handle
);
10843 ReleaseResource (font_handle
);
10844 font_handle
= font_handle_2
;
10846 while (ResError () == noErr
&& font_handle
);
10849 TextFont (old_fontnum
);
10850 #if TARGET_API_MAC_CARBON
10852 #endif /* TARGET_API_MAC_CARBON */
10856 /* Return a list of at most MAXNAMES font specs matching the one in
10857 PATTERN. Note that each '*' in the PATTERN matches exactly one
10858 field of the font spec, unlike X in which an '*' in a font spec can
10859 match a number of fields. The result is in the Mac implementation
10860 all fonts must be specified by a font spec with all 13 fields
10861 (although many of these can be "*'s"). */
10864 x_list_fonts (struct frame
*f
,
10865 Lisp_Object pattern
,
10870 Lisp_Object newlist
= Qnil
;
10873 struct gcpro gcpro1
, gcpro2
;
10875 if (font_name_table
== NULL
) /* Initialize when first used. */
10876 init_font_name_table ();
10878 ptnstr
= XSTRING (pattern
)->data
;
10880 GCPRO2 (pattern
, newlist
);
10882 /* Scan and matching bitmap fonts. */
10883 for (i
= 0; i
< font_name_count
; i
++)
10885 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10887 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10890 if (n_fonts
>= maxnames
)
10895 /* MAC_TODO: add code for matching outline fonts here */
10905 /* Check that FONT is valid on frame F. It is if it can be found in F's
10909 x_check_font (f
, font
)
10914 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10916 xassert (font
!= NULL
);
10918 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10919 if (dpyinfo
->font_table
[i
].name
10920 && font
== dpyinfo
->font_table
[i
].font
)
10923 xassert (i
< dpyinfo
->n_fonts
);
10926 #endif /* GLYPH_DEBUG != 0 */
10928 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10929 Note: There are (broken) X fonts out there with invalid XFontStruct
10930 min_bounds contents. For example, handa@etl.go.jp reports that
10931 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10932 have font->min_bounds.width == 0. */
10935 x_font_min_bounds (font
, w
, h
)
10936 MacFontStruct
*font
;
10940 * TODO: Windows does not appear to offer min bound, only
10941 * average and maximum width, and maximum height.
10943 *h
= FONT_HEIGHT (font
);
10944 *w
= FONT_WIDTH (font
);
10948 /* Compute the smallest character width and smallest font height over
10949 all fonts available on frame F. Set the members smallest_char_width
10950 and smallest_font_height in F's x_display_info structure to
10951 the values computed. Value is non-zero if smallest_font_height or
10952 smallest_char_width become smaller than they were before. */
10955 x_compute_min_glyph_bounds (f
)
10959 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10960 MacFontStruct
*font
;
10961 int old_width
= dpyinfo
->smallest_char_width
;
10962 int old_height
= dpyinfo
->smallest_font_height
;
10964 dpyinfo
->smallest_font_height
= 100000;
10965 dpyinfo
->smallest_char_width
= 100000;
10967 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10968 if (dpyinfo
->font_table
[i
].name
)
10970 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10973 font
= (MacFontStruct
*) fontp
->font
;
10974 xassert (font
!= (MacFontStruct
*) ~0);
10975 x_font_min_bounds (font
, &w
, &h
);
10977 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10978 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10981 xassert (dpyinfo
->smallest_char_width
> 0
10982 && dpyinfo
->smallest_font_height
> 0);
10984 return (dpyinfo
->n_fonts
== 1
10985 || dpyinfo
->smallest_char_width
< old_width
10986 || dpyinfo
->smallest_font_height
< old_height
);
10990 /* Determine whether given string is a fully-specified XLFD: all 14
10991 fields are present, none is '*'. */
10994 is_fully_specified_xlfd (char *p
)
11002 for (i
= 0; i
< 13; i
++)
11004 q
= strchr (p
+ 1, '-');
11007 if (q
- p
== 2 && *(p
+ 1) == '*')
11012 if (strchr (p
+ 1, '-') != NULL
)
11015 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
11022 const int kDefaultFontSize
= 9;
11025 /* XLoadQueryFont creates and returns an internal representation for a
11026 font in a MacFontStruct struct. There is really no concept
11027 corresponding to "loading" a font on the Mac. But we check its
11028 existence and find the font number and all other information for it
11029 and store them in the returned MacFontStruct. */
11031 static MacFontStruct
*
11032 XLoadQueryFont (Display
*dpy
, char *fontname
)
11034 int i
, size
, is_two_byte_font
, char_width
;
11037 SInt16 old_fontnum
, old_fontsize
;
11038 Style old_fontface
;
11041 Style fontface
= normal
;
11042 MacFontStruct
*font
;
11043 FontInfo the_fontinfo
;
11044 char s_weight
[7], c_slant
;
11046 if (is_fully_specified_xlfd (fontname
))
11050 for (i
= 0; i
< font_name_count
; i
++)
11051 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
11054 if (i
>= font_name_count
)
11057 name
= font_name_table
[i
];
11060 GetPort (&port
); /* save the current font number used */
11061 #if TARGET_API_MAC_CARBON
11062 old_fontnum
= GetPortTextFont (port
);
11063 old_fontsize
= GetPortTextSize (port
);
11064 old_fontface
= GetPortTextFace (port
);
11066 old_fontnum
= port
->txFont
;
11067 old_fontsize
= port
->txSize
;
11068 old_fontface
= port
->txFace
;
11071 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
11072 size
= kDefaultFontSize
;
11074 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
11075 if (strcmp (s_weight
, "bold") == 0)
11078 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
11079 if (c_slant
== 'i')
11080 fontface
|= italic
;
11082 x_font_name_to_mac_font_name (name
, mfontname
);
11083 c2pstr (mfontname
);
11084 GetFNum (mfontname
, &fontnum
);
11088 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
11090 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
11091 bcopy (name
, font
->fontname
, strlen (name
) + 1);
11093 font
->mac_fontnum
= fontnum
;
11094 font
->mac_fontsize
= size
;
11095 font
->mac_fontface
= fontface
;
11096 font
->mac_scriptcode
= FontToScript (fontnum
);
11098 /* Apple Japanese (SJIS) font is listed as both
11099 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
11100 (Roman script) in init_font_name_table (). The latter should be
11101 treated as a one-byte font. */
11106 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
11108 && 0 == strcmp (cs
, "mac-roman"))
11109 font
->mac_scriptcode
= smRoman
;
11112 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
11113 font
->mac_scriptcode
== smTradChinese
||
11114 font
->mac_scriptcode
== smSimpChinese
||
11115 font
->mac_scriptcode
== smKorean
;
11117 TextFont (fontnum
);
11119 TextFace (fontface
);
11121 GetFontInfo (&the_fontinfo
);
11123 font
->ascent
= the_fontinfo
.ascent
;
11124 font
->descent
= the_fontinfo
.descent
;
11126 font
->min_byte1
= 0;
11127 if (is_two_byte_font
)
11128 font
->max_byte1
= 1;
11130 font
->max_byte1
= 0;
11131 font
->min_char_or_byte2
= 0x20;
11132 font
->max_char_or_byte2
= 0xff;
11134 if (is_two_byte_font
)
11136 /* Use the width of an "ideographic space" of that font because
11137 the_fontinfo.widMax returns the wrong width for some fonts. */
11138 switch (font
->mac_scriptcode
)
11141 char_width
= StringWidth("\p\x81\x40");
11143 case smTradChinese
:
11144 char_width
= StringWidth("\p\xa1\x40");
11146 case smSimpChinese
:
11147 char_width
= StringWidth("\p\xa1\xa1");
11150 char_width
= StringWidth("\p\xa1\xa1");
11155 /* Do this instead of use the_fontinfo.widMax, which incorrectly
11156 returns 15 for 12-point Monaco! */
11157 char_width
= CharWidth ('m');
11159 font
->max_bounds
.rbearing
= char_width
;
11160 font
->max_bounds
.lbearing
= 0;
11161 font
->max_bounds
.width
= char_width
;
11162 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
11163 font
->max_bounds
.descent
= the_fontinfo
.descent
;
11165 font
->min_bounds
= font
->max_bounds
;
11167 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
11168 font
->per_char
= NULL
;
11171 font
->per_char
= (XCharStruct
*)
11172 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
11176 for (c
= 0x20; c
<= 0xff; c
++)
11178 font
->per_char
[c
- 0x20] = font
->max_bounds
;
11179 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
11184 TextFont (old_fontnum
); /* restore previous font number, size and face */
11185 TextSize (old_fontsize
);
11186 TextFace (old_fontface
);
11192 /* Load font named FONTNAME of the size SIZE for frame F, and return a
11193 pointer to the structure font_info while allocating it dynamically.
11194 If SIZE is 0, load any size of font.
11195 If loading is failed, return NULL. */
11198 x_load_font (f
, fontname
, size
)
11200 register char *fontname
;
11203 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11204 Lisp_Object font_names
;
11206 /* Get a list of all the fonts that match this name. Once we
11207 have a list of matching fonts, we compare them against the fonts
11208 we already have by comparing names. */
11209 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
11211 if (!NILP (font_names
))
11216 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11217 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
11218 if (dpyinfo
->font_table
[i
].name
11219 && (!strcmp (dpyinfo
->font_table
[i
].name
,
11220 XSTRING (XCAR (tail
))->data
)
11221 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
11222 XSTRING (XCAR (tail
))->data
)))
11223 return (dpyinfo
->font_table
+ i
);
11226 /* Load the font and add it to the table. */
11229 struct MacFontStruct
*font
;
11230 struct font_info
*fontp
;
11231 unsigned long value
;
11234 /* If we have found fonts by x_list_font, load one of them. If
11235 not, we still try to load a font by the name given as FONTNAME
11236 because XListFonts (called in x_list_font) of some X server has
11237 a bug of not finding a font even if the font surely exists and
11238 is loadable by XLoadQueryFont. */
11239 if (size
> 0 && !NILP (font_names
))
11240 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
11242 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
11246 /* Find a free slot in the font table. */
11247 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11248 if (dpyinfo
->font_table
[i
].name
== NULL
)
11251 /* If no free slot found, maybe enlarge the font table. */
11252 if (i
== dpyinfo
->n_fonts
11253 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
11256 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
11257 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
11258 dpyinfo
->font_table
11259 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
11262 fontp
= dpyinfo
->font_table
+ i
;
11263 if (i
== dpyinfo
->n_fonts
)
11264 ++dpyinfo
->n_fonts
;
11266 /* Now fill in the slots of *FONTP. */
11268 fontp
->font
= font
;
11269 fontp
->font_idx
= i
;
11270 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
11271 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
11273 fontp
->full_name
= fontp
->name
;
11275 fontp
->size
= font
->max_bounds
.width
;
11276 fontp
->height
= FONT_HEIGHT (font
);
11278 /* For some font, ascent and descent in max_bounds field is
11279 larger than the above value. */
11280 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
11281 if (max_height
> fontp
->height
)
11282 fontp
->height
= max_height
;
11285 /* The slot `encoding' specifies how to map a character
11286 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
11287 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
11288 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
11289 2:0xA020..0xFF7F). For the moment, we don't know which charset
11290 uses this font. So, we set information in fontp->encoding[1]
11291 which is never used by any charset. If mapping can't be
11292 decided, set FONT_ENCODING_NOT_DECIDED. */
11293 if (font
->mac_scriptcode
== smJapanese
)
11294 fontp
->encoding
[1] = 4;
11298 = (font
->max_byte1
== 0
11300 ? (font
->min_char_or_byte2
< 0x80
11301 ? (font
->max_char_or_byte2
< 0x80
11302 ? 0 /* 0x20..0x7F */
11303 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
11304 : 1) /* 0xA0..0xFF */
11306 : (font
->min_byte1
< 0x80
11307 ? (font
->max_byte1
< 0x80
11308 ? (font
->min_char_or_byte2
< 0x80
11309 ? (font
->max_char_or_byte2
< 0x80
11310 ? 0 /* 0x2020..0x7F7F */
11311 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
11312 : 3) /* 0x20A0..0x7FFF */
11313 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
11314 : (font
->min_char_or_byte2
< 0x80
11315 ? (font
->max_char_or_byte2
< 0x80
11316 ? 2 /* 0xA020..0xFF7F */
11317 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
11318 : 1))); /* 0xA0A0..0xFFFF */
11321 #if 0 /* MAC_TODO: fill these out with more reasonably values */
11322 fontp
->baseline_offset
11323 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
11324 ? (long) value
: 0);
11325 fontp
->relative_compose
11326 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
11327 ? (long) value
: 0);
11328 fontp
->default_ascent
11329 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
11330 ? (long) value
: 0);
11332 fontp
->baseline_offset
= 0;
11333 fontp
->relative_compose
= 0;
11334 fontp
->default_ascent
= 0;
11337 /* Set global flag fonts_changed_p to non-zero if the font loaded
11338 has a character with a smaller width than any other character
11339 before, or if the font loaded has a smalle>r height than any
11340 other font loaded before. If this happens, it will make a
11341 glyph matrix reallocation necessary. */
11342 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11349 /* Return a pointer to struct font_info of a font named FONTNAME for
11350 frame F. If no such font is loaded, return NULL. */
11353 x_query_font (f
, fontname
)
11355 register char *fontname
;
11357 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11360 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11361 if (dpyinfo
->font_table
[i
].name
11362 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11363 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11364 return (dpyinfo
->font_table
+ i
);
11369 /* Find a CCL program for a font specified by FONTP, and set the member
11370 `encoder' of the structure. */
11373 x_find_ccl_program (fontp
)
11374 struct font_info
*fontp
;
11376 Lisp_Object list
, elt
;
11378 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11382 && STRINGP (XCAR (elt
))
11383 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11389 struct ccl_program
*ccl
11390 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11392 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11395 fontp
->font_encoder
= ccl
;
11401 /***********************************************************************
11403 ***********************************************************************/
11405 #ifdef USE_X_TOOLKIT
11406 static XrmOptionDescRec emacs_options
[] = {
11407 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11408 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11410 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11411 XrmoptionSepArg
, NULL
},
11412 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11414 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11415 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11416 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11417 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11418 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11419 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11420 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11422 #endif /* USE_X_TOOLKIT */
11424 static int x_initialized
;
11426 #ifdef MULTI_KBOARD
11427 /* Test whether two display-name strings agree up to the dot that separates
11428 the screen number from the server number. */
11430 same_x_server (name1
, name2
)
11431 char *name1
, *name2
;
11433 int seen_colon
= 0;
11434 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
11435 int system_name_length
= strlen (system_name
);
11436 int length_until_period
= 0;
11438 while (system_name
[length_until_period
] != 0
11439 && system_name
[length_until_period
] != '.')
11440 length_until_period
++;
11442 /* Treat `unix' like an empty host name. */
11443 if (! strncmp (name1
, "unix:", 5))
11445 if (! strncmp (name2
, "unix:", 5))
11447 /* Treat this host's name like an empty host name. */
11448 if (! strncmp (name1
, system_name
, system_name_length
)
11449 && name1
[system_name_length
] == ':')
11450 name1
+= system_name_length
;
11451 if (! strncmp (name2
, system_name
, system_name_length
)
11452 && name2
[system_name_length
] == ':')
11453 name2
+= system_name_length
;
11454 /* Treat this host's domainless name like an empty host name. */
11455 if (! strncmp (name1
, system_name
, length_until_period
)
11456 && name1
[length_until_period
] == ':')
11457 name1
+= length_until_period
;
11458 if (! strncmp (name2
, system_name
, length_until_period
)
11459 && name2
[length_until_period
] == ':')
11460 name2
+= length_until_period
;
11462 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11466 if (seen_colon
&& *name1
== '.')
11470 && (*name1
== '.' || *name1
== '\0')
11471 && (*name2
== '.' || *name2
== '\0'));
11476 /* The Mac Event loop code */
11479 #include <Events.h>
11480 #include <Quickdraw.h>
11481 #include <Balloons.h>
11482 #include <Devices.h>
11484 #include <Gestalt.h>
11486 #include <Processes.h>
11488 #include <ToolUtils.h>
11489 #include <TextUtils.h>
11490 #include <Dialogs.h>
11491 #include <Script.h>
11493 #include <TextEncodingConverter.h>
11494 #include <Resources.h>
11499 #endif /* ! MAC_OSX */
11501 #define M_APPLE 128
11504 #define WINDOW_RESOURCE 128
11505 #define TERM_WINDOW_RESOURCE 129
11507 #define DEFAULT_NUM_COLS 80
11509 #define MIN_DOC_SIZE 64
11510 #define MAX_DOC_SIZE 32767
11512 /* sleep time for WaitNextEvent */
11513 #define WNE_SLEEP_AT_SUSPEND 10
11514 #define WNE_SLEEP_AT_RESUME 1
11516 /* true when cannot handle any Mac OS events */
11517 static int handling_window_update
= 0;
11519 /* the flag appl_is_suspended is used both for determining the sleep
11520 time to be passed to WaitNextEvent and whether the cursor should be
11521 drawn when updating the display. The cursor is turned off when
11522 Emacs is suspended. Redrawing it is unnecessary and what needs to
11523 be done depends on whether the cursor lies inside or outside the
11524 redraw region. So we might as well skip drawing it when Emacs is
11526 static Boolean app_is_suspended
= false;
11527 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11529 #define EXTRA_STACK_ALLOC (256 * 1024)
11531 #define ARGV_STRING_LIST_ID 129
11532 #define ABOUT_ALERT_ID 128
11533 #define RAM_TOO_LARGE_ALERT_ID 129
11535 Boolean terminate_flag
= false;
11537 /* true if using command key as meta key */
11538 Lisp_Object Vmac_command_key_is_meta
;
11540 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11541 to this text encoding */
11542 int mac_keyboard_text_encoding
;
11543 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11545 /* Set in term/mac-win.el to indicate that event loop can now generate
11546 drag and drop events. */
11547 Lisp_Object Qmac_ready_for_drag_n_drop
;
11549 Lisp_Object drag_and_drop_file_list
;
11551 Point saved_menu_event_location
;
11554 static void init_required_apple_events(void);
11555 static pascal OSErr
11556 do_ae_open_application(const AppleEvent
*, AppleEvent
*, long);
11557 static pascal OSErr
11558 do_ae_print_documents(const AppleEvent
*, AppleEvent
*, long);
11559 static pascal OSErr
do_ae_open_documents(AppleEvent
*, AppleEvent
*, long);
11560 static pascal OSErr
do_ae_quit_application(AppleEvent
*, AppleEvent
*, long);
11562 extern void init_emacs_passwd_dir ();
11563 extern int emacs_main (int, char **, char **);
11564 extern void check_alarm ();
11566 extern void initialize_applescript();
11567 extern void terminate_applescript();
11571 do_get_menus (void)
11573 Handle menubar_handle
;
11574 MenuHandle menu_handle
;
11576 menubar_handle
= GetNewMBar (128);
11577 if(menubar_handle
== NULL
)
11579 SetMenuBar (menubar_handle
);
11582 menu_handle
= GetMenuHandle (M_APPLE
);
11583 if(menu_handle
!= NULL
)
11584 AppendResMenu (menu_handle
,'DRVR');
11591 do_init_managers (void)
11593 #if !TARGET_API_MAC_CARBON
11594 InitGraf (&qd
.thePort
);
11596 FlushEvents (everyEvent
, 0);
11600 InitDialogs (NULL
);
11601 #endif /* !TARGET_API_MAC_CARBON */
11604 #if !TARGET_API_MAC_CARBON
11605 /* set up some extra stack space for use by emacs */
11606 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11608 /* MaxApplZone must be called for AppleScript to execute more
11609 complicated scripts */
11612 #endif /* !TARGET_API_MAC_CARBON */
11616 do_check_ram_size (void)
11618 SInt32 physical_ram_size
, logical_ram_size
;
11620 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11621 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11622 || physical_ram_size
> 256 * 1024 * 1024
11623 || logical_ram_size
> 256 * 1024 * 1024)
11625 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11631 do_window_update (WindowPtr win
)
11633 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11634 struct frame
*f
= mwp
->mFP
;
11638 if (f
->async_visible
== 0)
11640 f
->async_visible
= 1;
11641 f
->async_iconified
= 0;
11642 SET_FRAME_GARBAGED (f
);
11644 /* An update event is equivalent to MapNotify on X, so report
11645 visibility changes properly. */
11646 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11647 /* Force a redisplay sooner or later to update the
11648 frame titles in case this is the second frame. */
11649 record_asynch_buffer_change ();
11654 handling_window_update
= 1;
11656 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
11658 expose_frame (f
, 0, 0, 0, 0);
11660 handling_window_update
= 0;
11667 is_emacs_window (WindowPtr win
)
11669 Lisp_Object tail
, frame
;
11674 FOR_EACH_FRAME (tail
, frame
)
11675 if (FRAME_MAC_P (XFRAME (frame
)))
11676 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11683 do_window_activate (WindowPtr win
)
11688 if (is_emacs_window (win
))
11690 mwp
= (mac_output
*) GetWRefCon (win
);
11695 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11696 activate_scroll_bars (f
);
11702 do_window_deactivate (WindowPtr win
)
11707 if (is_emacs_window (win
))
11709 mwp
= (mac_output
*) GetWRefCon (win
);
11712 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11714 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11715 deactivate_scroll_bars (f
);
11727 wp
= FrontWindow();
11728 if (is_emacs_window (wp
))
11730 mwp
= (mac_output
*) GetWRefCon (wp
);
11735 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11736 activate_scroll_bars (f
);
11740 app_is_suspended
= false;
11741 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11751 wp
= FrontWindow();
11752 if (is_emacs_window (wp
))
11754 mwp
= (mac_output
*) GetWRefCon (wp
);
11757 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11759 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11760 deactivate_scroll_bars (f
);
11764 app_is_suspended
= true;
11765 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11770 do_mouse_moved (Point mouse_pos
)
11772 WindowPtr wp
= FrontWindow ();
11773 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11775 #if TARGET_API_MAC_CARBON
11776 SetPort (GetWindowPort (wp
));
11781 GlobalToLocal (&mouse_pos
);
11783 note_mouse_movement (f
, &mouse_pos
);
11788 do_os_event (EventRecord
*erp
)
11790 switch((erp
->message
>> 24) & 0x000000FF)
11792 case suspendResumeMessage
:
11793 if((erp
->message
& resumeFlag
) == 1)
11799 case mouseMovedMessage
:
11800 do_mouse_moved (erp
->where
);
11806 do_events (EventRecord
*erp
)
11811 do_window_update ((WindowPtr
) erp
->message
);
11819 if ((erp
->modifiers
& activeFlag
) != 0)
11820 do_window_activate ((WindowPtr
) erp
->message
);
11822 do_window_deactivate ((WindowPtr
) erp
->message
);
11828 do_apple_menu (SInt16 menu_item
)
11830 #if !TARGET_API_MAC_CARBON
11832 SInt16 da_driver_refnum
;
11834 if (menu_item
== I_ABOUT
)
11835 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11838 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11839 da_driver_refnum
= OpenDeskAcc (item_name
);
11841 #endif /* !TARGET_API_MAC_CARBON */
11845 do_menu_choice (SInt32 menu_choice
)
11847 SInt16 menu_id
, menu_item
;
11849 menu_id
= HiWord (menu_choice
);
11850 menu_item
= LoWord (menu_choice
);
11858 do_apple_menu (menu_item
);
11863 WindowPtr wp
= FrontWindow ();
11864 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11865 MenuHandle menu
= GetMenuHandle (menu_id
);
11870 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11871 menubar_selection_callback (f
, refcon
);
11880 /* Handle drags in size box. Based on code contributed by Ben
11881 Mesander and IM - Window Manager A. */
11884 do_grow_window (WindowPtr w
, EventRecord
*e
)
11889 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11890 struct frame
*f
= mwp
->mFP
;
11892 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11894 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11896 /* see if it really changed size */
11897 if (grow_size
!= 0)
11899 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11900 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11902 x_set_window_size (f
, 0, columns
, rows
);
11907 /* Handle clicks in zoom box. Calculation of "standard state" based
11908 on code in IM - Window Manager A and code contributed by Ben
11909 Mesander. The standard state of an Emacs window is 80-characters
11910 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11913 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11916 Rect zoom_rect
, port_rect
;
11918 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11919 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11920 struct frame
*f
= mwp
->mFP
;
11922 GetPort (&save_port
);
11924 #if TARGET_API_MAC_CARBON
11925 SetPort (GetWindowPort (w
));
11930 /* Clear window to avoid flicker. */
11931 #if TARGET_API_MAC_CARBON
11936 GetWindowPortBounds (w
, &r
);
11939 if (zoom_in_or_out
== inZoomOut
)
11941 /* calculate height of window's title bar (hard card it for now). */
11942 w_title_height
= 20 + GetMBarHeight ();
11944 /* get maximum height of window into zoom_rect.bottom -
11946 GetQDGlobalsScreenBits (&bm
);
11947 zoom_rect
= bm
.bounds
;
11948 zoom_rect
.top
+= w_title_height
;
11949 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11951 zoom_rect
.right
= zoom_rect
.left
11952 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11954 SetWindowStandardState (w
, &zoom_rect
);
11957 #else /* not TARGET_API_MAC_CARBON */
11958 EraseRect (&(w
->portRect
));
11959 if (zoom_in_or_out
== inZoomOut
)
11961 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
11962 LocalToGlobal (&top_left
);
11964 /* calculate height of window's title bar */
11965 w_title_height
= top_left
.v
- 1
11966 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
11968 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
11969 zoom_rect
= qd
.screenBits
.bounds
;
11970 zoom_rect
.top
+= w_title_height
;
11971 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11973 zoom_rect
.right
= zoom_rect
.left
11974 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11976 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
11979 #endif /* not TARGET_API_MAC_CARBON */
11981 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
11983 /* retrieve window size and update application values */
11984 #if TARGET_API_MAC_CARBON
11985 GetWindowPortBounds (w
, &port_rect
);
11987 port_rect
= w
->portRect
;
11989 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
11990 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
11991 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
11993 SetPort (save_port
);
11997 /* Intialize AppleEvent dispatcher table for the required events. */
11999 init_required_apple_events ()
12004 /* Make sure we have apple events before starting. */
12005 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
12009 if (!(result
& (1 << gestaltAppleEventsPresent
)))
12012 #if TARGET_API_MAC_CARBON
12013 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12014 NewAEEventHandlerUPP
12015 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12018 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12019 NewAEEventHandlerProc
12020 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12026 #if TARGET_API_MAC_CARBON
12027 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12028 NewAEEventHandlerUPP
12029 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12032 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12033 NewAEEventHandlerProc
12034 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12040 #if TARGET_API_MAC_CARBON
12041 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12042 NewAEEventHandlerUPP
12043 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12046 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12047 NewAEEventHandlerProc
12048 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12054 #if TARGET_API_MAC_CARBON
12055 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12056 NewAEEventHandlerUPP
12057 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12060 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12061 NewAEEventHandlerProc
12062 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12070 /* Open Application Apple Event */
12071 static pascal OSErr
12072 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
12078 /* Defined in mac.c. */
12080 path_from_vol_dir_name (char *, int, short, long, char *);
12083 /* Called when we receive an AppleEvent with an ID of
12084 "kAEOpenDocuments". This routine gets the direct parameter,
12085 extracts the FSSpecs in it, and puts their names on a list. */
12086 static pascal OSErr
12087 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
12092 DescType actual_type
;
12095 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
12097 goto descriptor_error_exit
;
12099 /* Check to see that we got all of the required parameters from the
12100 event descriptor. For an 'odoc' event this should just be the
12102 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
12103 &actual_type
, (Ptr
) &keyword
,
12104 sizeof (keyword
), &actual_size
);
12105 /* No error means that we found some unused parameters.
12106 errAEDescNotFound means that there are no more parameters. If we
12107 get an error code other than that, flag it. */
12108 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
12110 err
= errAEEventNotHandled
;
12115 /* Got all the parameters we need. Now, go through the direct
12116 object list and parse it up. */
12118 long num_files_to_open
;
12120 err
= AECountItems (&the_desc
, &num_files_to_open
);
12125 /* AE file list is one based so just use that for indexing here. */
12126 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++) {
12128 Str255 path_name
, unix_path_name
;
12130 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12131 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12132 if (err
!= noErr
) break;
12134 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12136 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12137 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12138 drag_and_drop_file_list
);
12144 /* Nuke the coerced file list in any case */
12145 err2
= AEDisposeDesc(&the_desc
);
12147 descriptor_error_exit
:
12148 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12153 /* Print Document Apple Event */
12154 static pascal OSErr
12155 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12157 return errAEEventNotHandled
;
12161 static pascal OSErr
12162 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12164 /* FixMe: Do we need an unwind-protect or something here? And what
12165 do we do about unsaved files. Currently just forces quit rather
12166 than doing recursive callback to get user input. */
12168 terminate_flag
= true;
12170 /* Fkill_emacs doesn't return. We have to return. (TI) */
12177 profiler_exit_proc ()
12179 ProfilerDump ("\pEmacs.prof");
12184 /* These few functions implement Emacs as a normal Mac application
12185 (almost): set up the heap and the Toolbox, handle necessary
12186 system events plus a few simple menu events. They also set up
12187 Emacs's access to functions defined in the rest of this file.
12188 Emacs uses function hooks to perform all its terminal I/O. A
12189 complete list of these functions appear in termhooks.h. For what
12190 they do, read the comments there and see also w32term.c and
12191 xterm.c. What's noticeably missing here is the event loop, which
12192 is normally present in most Mac application. After performing the
12193 necessary Mac initializations, main passes off control to
12194 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12195 mac_read_socket (defined further below) to read input. This is
12196 where WaitNextEvent is called to process Mac events. This is also
12197 where check_alarm in sysdep.c is called to simulate alarm signals.
12198 This makes the cursor jump back to its correct position after
12199 briefly jumping to that of the matching parenthesis, print useful
12200 hints and prompts in the minibuffer after the user stops typing for
12203 #if !TARGET_API_MAC_CARBON
12208 #if __profile__ /* is the profiler on? */
12209 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12214 /* set creator and type for files created by MSL */
12215 _fcreator
= 'EMAx';
12219 do_init_managers ();
12223 do_check_ram_size ();
12225 init_emacs_passwd_dir ();
12229 initialize_applescript ();
12231 init_required_apple_events ();
12237 /* set up argv array from STR# resource */
12238 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12242 /* free up AppleScript resources on exit */
12243 atexit (terminate_applescript
);
12245 #if __profile__ /* is the profiler on? */
12246 atexit (profiler_exit_proc
);
12249 /* 3rd param "envp" never used in emacs_main */
12250 (void) emacs_main (argc
, argv
, 0);
12253 /* Never reached - real exit in Fkill_emacs */
12258 /* Table for translating Mac keycode to X keysym values. Contributed
12259 by Sudhir Shenoy. */
12260 static unsigned char keycode_to_xkeysym_table
[] = {
12262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12267 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
12268 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
12269 0, 0, 0, '\xaf' /* kp/ */,
12270 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
12272 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
12273 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
12274 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
12275 '\xb9' /* kp9 */, 0, 0, 0,
12277 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
12278 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
12279 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
12280 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
12282 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
12283 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
12284 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
12285 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
12289 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12291 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12292 return *xKeySym
!= 0;
12295 /* Emacs calls this whenever it wants to read an input event from the
12298 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12303 EventMask event_mask
;
12306 if (interrupt_input_blocked
)
12308 interrupt_input_pending
= 1;
12313 interrupt_input_pending
= 0;
12316 /* So people can tell when we have read the available input. */
12317 input_signal_count
++;
12322 /* Don't poll for events to process (specifically updateEvt) if
12323 window update currently already in progress. A call to redisplay
12324 (in do_window_update) can be preempted by another call to
12325 redisplay, causing blank regions to be left on the screen and the
12326 cursor to be left at strange places. */
12327 if (handling_window_update
)
12333 if (terminate_flag
)
12334 Fkill_emacs (make_number (1));
12336 /* It is necessary to set this (additional) argument slot of an
12337 event to nil because keyboard.c protects incompletely processed
12338 event from being garbage collected by placing them in the
12339 kbd_buffer_gcpro vector. */
12342 event_mask
= everyEvent
;
12343 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12344 event_mask
-= highLevelEventMask
;
12346 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
12352 WindowPtr window_ptr
= FrontWindow ();
12355 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12356 && er
.what
== mouseUp
)
12358 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12359 Point mouse_loc
= er
.where
;
12361 /* Convert to local coordinates of new window. */
12362 #if TARGET_API_MAC_CARBON
12363 SetPort (GetWindowPort (window_ptr
));
12365 SetPort (window_ptr
);
12368 GlobalToLocal (&mouse_loc
);
12370 bufp
->code
= 0; /* only one mouse button */
12371 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
12372 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12373 bufp
->part
= scroll_bar_handle
;
12374 bufp
->modifiers
= up_modifier
;
12375 bufp
->timestamp
= er
.when
* (1000 / 60);
12376 /* ticks to milliseconds */
12378 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12379 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12380 tracked_scroll_bar
->dragging
= Qnil
;
12381 mouse_tracking_in_progress
= mouse_tracking_none
;
12382 tracked_scroll_bar
= NULL
;
12387 part_code
= FindWindow (er
.where
, &window_ptr
);
12393 struct frame
*f
= ((mac_output
*)
12394 GetWRefCon (FrontWindow ()))->mFP
;
12395 saved_menu_event_location
= er
.where
;
12396 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
12397 XSETFRAME (bufp
->frame_or_window
, f
);
12403 if (window_ptr
!= FrontWindow ())
12404 SelectWindow (window_ptr
);
12407 SInt16 control_part_code
;
12409 struct mac_output
*mwp
= (mac_output
*)
12410 GetWRefCon (window_ptr
);
12411 Point mouse_loc
= er
.where
;
12413 /* convert to local coordinates of new window */
12414 #if TARGET_API_MAC_CARBON
12415 SetPort (GetWindowPort (window_ptr
));
12417 SetPort (window_ptr
);
12420 GlobalToLocal (&mouse_loc
);
12421 #if TARGET_API_MAC_CARBON
12422 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12423 &control_part_code
);
12425 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12427 bufp
->code
= 0; /* only one mouse button */
12428 XSETINT (bufp
->x
, mouse_loc
.h
);
12429 XSETINT (bufp
->y
, mouse_loc
.v
);
12430 bufp
->timestamp
= er
.when
* (1000 / 60);
12431 /* ticks to milliseconds */
12433 #if TARGET_API_MAC_CARBON
12436 if (control_part_code
!= 0)
12439 struct scroll_bar
*bar
= (struct scroll_bar
*)
12440 GetControlReference (ch
);
12441 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12443 if (er
.what
== mouseDown
12444 && control_part_code
== kControlIndicatorPart
)
12446 mouse_tracking_in_progress
12447 = mouse_tracking_scroll_bar
;
12448 tracked_scroll_bar
= bar
;
12452 mouse_tracking_in_progress
= mouse_tracking_none
;
12453 tracked_scroll_bar
= NULL
;
12458 bufp
->kind
= MOUSE_CLICK_EVENT
;
12459 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12460 if (er
.what
== mouseDown
)
12461 mouse_tracking_in_progress
12462 = mouse_tracking_mouse_movement
;
12464 mouse_tracking_in_progress
= mouse_tracking_none
;
12470 bufp
->modifiers
= down_modifier
;
12473 bufp
->modifiers
= up_modifier
;
12482 #if TARGET_API_MAC_CARBON
12486 GetQDGlobalsScreenBits (&bm
);
12487 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12489 #else /* not TARGET_API_MAC_CARBON */
12490 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12491 #endif /* not TARGET_API_MAC_CARBON */
12495 if (TrackGoAway (window_ptr
, er
.where
))
12497 bufp
->kind
= DELETE_WINDOW_EVENT
;
12498 XSETFRAME (bufp
->frame_or_window
,
12499 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12504 /* window resize handling added --ben */
12506 do_grow_window(window_ptr
, &er
);
12509 /* window zoom handling added --ben */
12512 if (TrackBox (window_ptr
, er
.where
, part_code
))
12513 do_zoom_window (window_ptr
, part_code
);
12531 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12536 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12539 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12541 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12543 bufp
->code
= 0xff00 | xkeysym
;
12544 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
12549 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12551 /* This code comes from Keyboard Resource, Appendix
12552 C of IM - Text. This is necessary since shift is
12553 ignored in KCHR table translation when option or
12554 command is pressed. */
12555 int new_modifiers
= er
.modifiers
& 0xf600;
12556 /* mask off option and command */
12557 int new_keycode
= keycode
| new_modifiers
;
12558 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12559 unsigned long some_state
= 0;
12560 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12561 &some_state
) & 0xff;
12564 bufp
->code
= er
.message
& charCodeMask
;
12565 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12569 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12570 convert non-ASCII characters typed at the Mac keyboard
12571 (presumed to be in the Mac Roman encoding) to iso-latin-1
12572 encoding before they are passed to Emacs. This enables the
12573 Mac keyboard to be used to enter non-ASCII iso-latin-1
12574 characters directly. */
12575 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12576 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
12578 static TECObjectRef converter
= NULL
;
12579 OSStatus the_err
= noErr
;
12580 OSStatus convert_status
= noErr
;
12582 if (converter
== NULL
)
12584 the_err
= TECCreateConverter (&converter
,
12585 kTextEncodingMacRoman
,
12586 mac_keyboard_text_encoding
);
12587 current_mac_keyboard_text_encoding
12588 = mac_keyboard_text_encoding
;
12590 else if (mac_keyboard_text_encoding
12591 != current_mac_keyboard_text_encoding
)
12593 /* Free the converter for the current encoding before
12594 creating a new one. */
12595 TECDisposeConverter (converter
);
12596 the_err
= TECCreateConverter (&converter
,
12597 kTextEncodingMacRoman
,
12598 mac_keyboard_text_encoding
);
12599 current_mac_keyboard_text_encoding
12600 = mac_keyboard_text_encoding
;
12603 if (the_err
== noErr
)
12605 unsigned char ch
= bufp
->code
;
12606 ByteCount actual_input_length
, actual_output_length
;
12607 unsigned char outch
;
12609 convert_status
= TECConvertText (converter
, &ch
, 1,
12610 &actual_input_length
,
12612 &actual_output_length
);
12613 if (convert_status
== noErr
12614 && actual_input_length
== 1
12615 && actual_output_length
== 1)
12616 bufp
->code
= outch
;
12621 if (er
.modifiers
& shiftKey
)
12622 the_modifiers
|= shift_modifier
;
12623 if (er
.modifiers
& controlKey
)
12624 the_modifiers
|= ctrl_modifier
;
12625 /* Use option or command key as meta depending on value of
12626 mac-command-key-is-meta. */
12628 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12629 the_modifiers
|= meta_modifier
;
12631 /* If the Mac option key is meta, then make Emacs recognize
12632 the Mac command key as alt. */
12633 if (NILP (Vmac_command_key_is_meta
) && (er
.modifiers
& cmdKey
))
12634 the_modifiers
|= alt_modifier
;
12636 bufp
->modifiers
= the_modifiers
;
12640 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
12641 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12644 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
12649 case kHighLevelEvent
:
12650 drag_and_drop_file_list
= Qnil
;
12652 AEProcessAppleEvent(&er
);
12654 /* Build a DRAG_N_DROP_EVENT type event as is done in
12655 constuct_drag_n_drop in w32term.c. */
12656 if (!NILP (drag_and_drop_file_list
))
12662 wp
= FrontWindow ();
12666 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12668 bufp
->kind
= DRAG_N_DROP_EVENT
;
12670 bufp
->timestamp
= er
.when
* (1000 / 60);
12671 /* ticks to milliseconds */
12672 bufp
->modifiers
= 0;
12674 XSETINT (bufp
->x
, 0);
12675 XSETINT (bufp
->y
, 0);
12677 XSETFRAME (frame
, f
);
12678 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12680 /* Regardless of whether Emacs was suspended or in the
12681 foreground, ask it to redraw its entire screen.
12682 Otherwise parts of the screen can be left in an
12683 inconsistent state. */
12685 #if TARGET_API_MAC_CARBON
12689 GetWindowPortBounds (wp
, &r
);
12690 InvalWindowRect (wp
, &r
);
12692 #else /* not TARGET_API_MAC_CARBON */
12693 InvalRect (&(wp
->portRect
));
12694 #endif /* not TARGET_API_MAC_CARBON */
12703 /* If the focus was just given to an autoraising frame,
12705 /* ??? This ought to be able to handle more than one such frame. */
12706 if (pending_autoraise_frame
)
12708 x_raise_frame (pending_autoraise_frame
);
12709 pending_autoraise_frame
= 0;
12712 #if !TARGET_API_MAC_CARBON
12713 check_alarm (); /* simulate the handling of a SIGALRM */
12717 static Point old_mouse_pos
= { -1, -1 };
12719 if (app_is_suspended
)
12721 old_mouse_pos
.h
= -1;
12722 old_mouse_pos
.v
= -1;
12730 struct scroll_bar
*sb
;
12732 wp
= FrontWindow ();
12733 if (is_emacs_window (wp
))
12735 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12737 #if TARGET_API_MAC_CARBON
12738 SetPort (GetWindowPort (wp
));
12743 GetMouse (&mouse_pos
);
12745 if (!EqualPt (mouse_pos
, old_mouse_pos
))
12747 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12748 && tracked_scroll_bar
)
12749 x_scroll_bar_note_movement (tracked_scroll_bar
,
12751 - XINT (tracked_scroll_bar
->top
),
12752 TickCount() * (1000 / 60));
12754 note_mouse_movement (f
, &mouse_pos
);
12756 old_mouse_pos
= mouse_pos
;
12768 /* Need to override CodeWarrior's input function so no conversion is
12769 done on newlines Otherwise compiled functions in .elc files will be
12770 read incorrectly. Defined in ...:MSL C:MSL
12771 Common:Source:buffer_io.c. */
12774 __convert_to_newlines (unsigned char * p
, size_t * n
)
12776 #pragma unused(p,n)
12780 __convert_from_newlines (unsigned char * p
, size_t * n
)
12782 #pragma unused(p,n)
12787 /* Initialize the struct pointed to by MW to represent a new COLS x
12788 ROWS Macintosh window, using font with name FONTNAME and size
12791 NewMacWindow (FRAME_PTR fp
)
12794 #if TARGET_API_MAC_CARBON
12795 static int making_terminal_window
= 0;
12797 static int making_terminal_window
= 1;
12800 mwp
= fp
->output_data
.mac
;
12802 if (making_terminal_window
)
12804 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
12807 making_terminal_window
= 0;
12810 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
12814 SetWRefCon (mwp
->mWP
, (long) mwp
);
12815 /* so that update events can find this mac_output struct */
12816 mwp
->mFP
= fp
; /* point back to emacs frame */
12818 #if TARGET_API_MAC_CARBON
12819 SetPort (GetWindowPort (mwp
->mWP
));
12821 SetPort (mwp
->mWP
);
12826 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
12827 ShowWindow (mwp
->mWP
);
12832 void make_mac_frame (struct frame
*f
)
12834 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
12835 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
12839 f
->output_data
.mac
->cursor_pixel
= 0;
12840 f
->output_data
.mac
->border_pixel
= 0x00ff00;
12841 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
12842 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
12844 f
->output_data
.mac
->desired_cursor
= FILLED_BOX_CURSOR
;
12846 f
->output_data
.mac
->fontset
= -1;
12847 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12848 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12849 f
->output_data
.mac
->left_pos
= 4;
12850 f
->output_data
.mac
->top_pos
= 4;
12851 f
->output_data
.mac
->border_width
= 0;
12852 f
->output_data
.mac
->explicit_parent
= 0;
12854 f
->output_data
.mac
->internal_border_width
= 0;
12856 f
->output_method
= output_mac
;
12865 void make_mac_terminal_frame (struct frame
*f
)
12869 XSETFRAME (frame
, f
);
12871 f
->output_method
= output_mac
;
12872 f
->output_data
.mac
= (struct mac_output
*)
12873 xmalloc (sizeof (struct mac_output
));
12874 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
12875 f
->output_data
.mac
->fontset
= -1;
12876 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12877 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12879 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
12884 make_mac_frame (f
);
12888 /* Need to be initialized for unshow_buffer in window.c. */
12889 selected_window
= f
->selected_window
;
12891 Fmodify_frame_parameters (frame
,
12892 Fcons (Fcons (Qfont
,
12893 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
12894 Fmodify_frame_parameters (frame
,
12895 Fcons (Fcons (Qforeground_color
,
12896 build_string ("black")), Qnil
));
12897 Fmodify_frame_parameters (frame
,
12898 Fcons (Fcons (Qbackground_color
,
12899 build_string ("white")), Qnil
));
12903 /***********************************************************************
12905 ***********************************************************************/
12907 #ifdef USE_X_TOOLKIT
12908 static XrmOptionDescRec emacs_options
[] = {
12909 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
12910 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
12912 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
12913 XrmoptionSepArg
, NULL
},
12914 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
12916 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12917 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12918 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12919 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12920 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12921 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
12922 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
12924 #endif /* USE_X_TOOLKIT */
12926 #ifdef MULTI_KBOARD
12927 /* Test whether two display-name strings agree up to the dot that separates
12928 the screen number from the server number. */
12930 same_x_server (name1
, name2
)
12931 char *name1
, *name2
;
12933 int seen_colon
= 0;
12934 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
12935 int system_name_length
= strlen (system_name
);
12936 int length_until_period
= 0;
12938 while (system_name
[length_until_period
] != 0
12939 && system_name
[length_until_period
] != '.')
12940 length_until_period
++;
12942 /* Treat `unix' like an empty host name. */
12943 if (! strncmp (name1
, "unix:", 5))
12945 if (! strncmp (name2
, "unix:", 5))
12947 /* Treat this host's name like an empty host name. */
12948 if (! strncmp (name1
, system_name
, system_name_length
)
12949 && name1
[system_name_length
] == ':')
12950 name1
+= system_name_length
;
12951 if (! strncmp (name2
, system_name
, system_name_length
)
12952 && name2
[system_name_length
] == ':')
12953 name2
+= system_name_length
;
12954 /* Treat this host's domainless name like an empty host name. */
12955 if (! strncmp (name1
, system_name
, length_until_period
)
12956 && name1
[length_until_period
] == ':')
12957 name1
+= length_until_period
;
12958 if (! strncmp (name2
, system_name
, length_until_period
)
12959 && name2
[length_until_period
] == ':')
12960 name2
+= length_until_period
;
12962 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
12966 if (seen_colon
&& *name1
== '.')
12970 && (*name1
== '.' || *name1
== '\0')
12971 && (*name2
== '.' || *name2
== '\0'));
12975 int mac_initialized
= 0;
12978 mac_initialize_display_info ()
12980 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
12981 GDHandle main_device_handle
;
12983 bzero (dpyinfo
, sizeof (*dpyinfo
));
12985 /* Put it on x_display_name_list. */
12986 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
12987 x_display_name_list
);
12988 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
12991 dpyinfo
->mac_id_name
12992 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
12993 + XSTRING (Vsystem_name
)->size
12995 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
12996 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
12998 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
12999 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
13002 main_device_handle
= LMGetMainDevice();
13004 dpyinfo
->reference_count
= 0;
13005 dpyinfo
->resx
= 75.0;
13006 dpyinfo
->resy
= 75.0;
13007 dpyinfo
->n_planes
= 1;
13008 dpyinfo
->n_cbits
= 16;
13009 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13010 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13011 dpyinfo
->grabbed
= 0;
13012 dpyinfo
->root_window
= NULL
;
13014 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13015 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13016 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13017 dpyinfo
->mouse_face_window
= Qnil
;
13020 struct mac_display_info
*
13021 mac_term_init (display_name
, xrm_option
, resource_name
)
13022 Lisp_Object display_name
;
13024 char *resource_name
;
13026 struct mac_display_info
*dpyinfo
;
13027 GDHandle main_device_handle
;
13029 if (!mac_initialized
)
13032 mac_initialized
= 1;
13035 mac_initialize_display_info (display_name
);
13037 dpyinfo
= &one_mac_display_info
;
13039 main_device_handle
= LMGetMainDevice();
13041 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13042 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13047 /* Set up use of X before we make the first connection. */
13049 static struct redisplay_interface x_redisplay_interface
=
13054 x_clear_end_of_line
,
13056 x_after_update_window_line
,
13057 x_update_window_begin
,
13058 x_update_window_end
,
13061 x_clear_mouse_face
,
13062 x_get_glyph_overhangs
,
13063 x_fix_overlapping_area
13069 rif
= &x_redisplay_interface
;
13071 clear_frame_hook
= x_clear_frame
;
13072 ins_del_lines_hook
= x_ins_del_lines
;
13073 delete_glyphs_hook
= x_delete_glyphs
;
13074 ring_bell_hook
= XTring_bell
;
13075 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13076 set_terminal_modes_hook
= XTset_terminal_modes
;
13077 update_begin_hook
= x_update_begin
;
13078 update_end_hook
= x_update_end
;
13079 set_terminal_window_hook
= XTset_terminal_window
;
13080 read_socket_hook
= XTread_socket
;
13081 frame_up_to_date_hook
= XTframe_up_to_date
;
13082 mouse_position_hook
= XTmouse_position
;
13083 frame_rehighlight_hook
= XTframe_rehighlight
;
13084 frame_raise_lower_hook
= XTframe_raise_lower
;
13086 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13087 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13088 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13089 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13091 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13093 scroll_region_ok
= 1; /* we'll scroll partial frames */
13094 char_ins_del_ok
= 1;
13095 line_ins_del_ok
= 1; /* we'll just blt 'em */
13096 fast_clear_end_of_line
= 1; /* X does this well */
13097 memory_below_frame
= 0; /* we don't remember what scrolls
13102 last_tool_bar_item
= -1;
13103 any_help_event_p
= 0;
13105 /* Try to use interrupt input; if we can't, then start polling. */
13106 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13108 #ifdef USE_X_TOOLKIT
13109 XtToolkitInitialize ();
13110 Xt_app_con
= XtCreateApplicationContext ();
13111 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13113 /* Install an asynchronous timer that processes Xt timeout events
13114 every 0.1s. This is necessary because some widget sets use
13115 timeouts internally, for example the LessTif menu bar, or the
13116 Xaw3d scroll bar. When Xt timouts aren't processed, these
13117 widgets don't behave normally. */
13119 EMACS_TIME interval
;
13120 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13121 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13125 #if USE_TOOLKIT_SCROLL_BARS
13126 xaw3d_arrow_scroll
= False
;
13127 xaw3d_pick_top
= True
;
13131 /* Note that there is no real way portable across R3/R4 to get the
13132 original error handler. */
13133 XSetErrorHandler (x_error_handler
);
13134 XSetIOErrorHandler (x_io_error_quitter
);
13136 /* Disable Window Change signals; they are handled by X events. */
13138 signal (SIGWINCH
, SIG_DFL
);
13139 #endif /* ! defined (SIGWINCH) */
13141 signal (SIGPIPE
, x_connection_signal
);
13144 mac_initialize_display_info ();
13152 staticpro (&x_error_message_string
);
13153 x_error_message_string
= Qnil
;
13156 staticpro (&x_display_name_list
);
13157 x_display_name_list
= Qnil
;
13159 staticpro (&last_mouse_scroll_bar
);
13160 last_mouse_scroll_bar
= Qnil
;
13162 staticpro (&Qvendor_specific_keysyms
);
13163 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13165 staticpro (&last_mouse_press_frame
);
13166 last_mouse_press_frame
= Qnil
;
13168 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13169 staticpro (&Qmac_ready_for_drag_n_drop
);
13172 staticpro (&help_echo
);
13173 help_echo_object
= Qnil
;
13174 staticpro (&help_echo_object
);
13175 help_echo_window
= Qnil
;
13176 staticpro (&help_echo_window
);
13177 previous_help_echo
= Qnil
;
13178 staticpro (&previous_help_echo
);
13179 help_echo_pos
= -1;
13181 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13182 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13183 x_autoselect_window_p
= 0;
13185 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13186 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13187 For example, if a block cursor is over a tab, it will be drawn as
13188 wide as that tab on the display. */);
13189 x_stretch_cursor_p
= 0;
13191 #if 0 /* TODO: Setting underline position from font properties. */
13192 DEFVAR_BOOL ("x-use-underline-position-properties",
13193 &x_use_underline_position_properties
,
13194 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13195 nil means ignore them. If you encounter fonts with bogus
13196 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13197 to 4.1, set this to nil. */);
13198 x_use_underline_position_properties
= 1;
13201 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13202 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13203 Vx_toolkit_scroll_bars
= Qt
;
13205 staticpro (&last_mouse_motion_frame
);
13206 last_mouse_motion_frame
= Qnil
;
13208 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13209 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13210 Otherwise the option key is used. */);
13211 Vmac_command_key_is_meta
= Qt
;
13213 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13214 doc
: /* One of the Text Encoding Base constant values defined in the
13215 Basic Text Constants section of Inside Macintosh - Text Encoding
13216 Conversion Manager. Its value determines the encoding characters
13217 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13218 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13219 its default value, no conversion takes place. If it is set to
13220 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13221 characters typed on Mac keyboard are first converted into the
13222 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13223 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13224 command, this enables the Mac keyboard to be used to enter non-ASCII
13225 characters directly. */);
13226 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;