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 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
62 obtain events from the event queue. If set to 0, WaitNextEvent is
64 #define USE_CARBON_EVENTS 1
65 #else /* not MAC_OSX */
66 #include <Quickdraw.h>
67 #include <ToolUtils.h>
71 #include <Resources.h>
73 #include <TextUtils.h>
76 #if defined (__MRC__) || (__MSL__ >= 0x6000)
77 #include <ControlDefinitions.h>
84 #endif /* not MAC_OSX */
98 #include "dispextern.h"
100 #include "termhooks.h"
101 #include "termopts.h"
102 #include "termchar.h"
107 #include "intervals.h"
108 #include "composite.h"
111 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
113 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
114 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
115 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
116 #define macShiftKey (shiftKey)
117 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
118 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
120 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
124 extern Lisp_Object Qhelp_echo
;
126 /* Non-nil means Emacs uses toolkit scroll bars. */
128 Lisp_Object Vx_toolkit_scroll_bars
;
130 /* If a string, XTread_socket generates an event to display that string.
131 (The display is done in read_char.) */
133 static Lisp_Object help_echo
;
134 static Lisp_Object help_echo_window
;
135 static Lisp_Object help_echo_object
;
136 static int help_echo_pos
;
138 /* Temporary variable for XTread_socket. */
140 static Lisp_Object previous_help_echo
;
142 /* Non-zero means that a HELP_EVENT has been generated since Emacs
145 static int any_help_event_p
;
147 /* Non-zero means autoselect window with the mouse cursor. */
149 int x_autoselect_window_p
;
151 /* Non-zero means draw block and hollow cursor as wide as the glyph
152 under it. For example, if a block cursor is over a tab, it will be
153 drawn as wide as that tab on the display. */
155 int x_stretch_cursor_p
;
157 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
159 int x_use_underline_position_properties
;
161 /* This is a chain of structures for all the X displays currently in
164 struct x_display_info
*x_display_list
;
166 /* This is a list of cons cells, each of the form (NAME
167 . FONT-LIST-CACHE), one for each element of x_display_list and in
168 the same order. NAME is the name of the frame. FONT-LIST-CACHE
169 records previous values returned by x-list-fonts. */
171 Lisp_Object x_display_name_list
;
173 /* This is display since Mac does not support multiple ones. */
174 struct mac_display_info one_mac_display_info
;
176 /* Frame being updated by update_frame. This is declared in term.c.
177 This is set by update_begin and looked at by all the XT functions.
178 It is zero while not inside an update. In that case, the XT
179 functions assume that `selected_frame' is the frame to apply to. */
181 extern struct frame
*updating_frame
;
183 extern int waiting_for_input
;
185 /* This is a frame waiting to be auto-raised, within XTread_socket. */
187 struct frame
*pending_autoraise_frame
;
189 /* Nominal cursor position -- where to draw output.
190 HPOS and VPOS are window relative glyph matrix coordinates.
191 X and Y are window relative pixel coordinates. */
193 struct cursor_pos output_cursor
;
195 /* Non-zero means user is interacting with a toolkit scroll bar. */
197 static int toolkit_scroll_bar_interaction
;
201 Formerly, we used PointerMotionHintMask (in standard_event_mask)
202 so that we would have to call XQueryPointer after each MotionNotify
203 event to ask for another such event. However, this made mouse tracking
204 slow, and there was a bug that made it eventually stop.
206 Simply asking for MotionNotify all the time seems to work better.
208 In order to avoid asking for motion events and then throwing most
209 of them away or busy-polling the server for mouse positions, we ask
210 the server for pointer motion hints. This means that we get only
211 one event per group of mouse movements. "Groups" are delimited by
212 other kinds of events (focus changes and button clicks, for
213 example), or by XQueryPointer calls; when one of these happens, we
214 get another MotionNotify event the next time the mouse moves. This
215 is at least as efficient as getting motion events when mouse
216 tracking is on, and I suspect only negligibly worse when tracking
219 /* Where the mouse was last time we reported a mouse event. */
221 FRAME_PTR last_mouse_frame
;
222 static Rect last_mouse_glyph
;
223 static Lisp_Object last_mouse_press_frame
;
225 /* The scroll bar in which the last X motion event occurred.
227 If the last X motion event occurred in a scroll bar, we set this so
228 XTmouse_position can know whether to report a scroll bar motion or
231 If the last X motion event didn't occur in a scroll bar, we set
232 this to Qnil, to tell XTmouse_position to return an ordinary motion
235 static Lisp_Object last_mouse_scroll_bar
;
237 /* This is a hack. We would really prefer that XTmouse_position would
238 return the time associated with the position it returns, but there
239 doesn't seem to be any way to wrest the time-stamp from the server
240 along with the position query. So, we just keep track of the time
241 of the last movement we received, and return that in hopes that
242 it's somewhat accurate. */
244 static Time last_mouse_movement_time
;
246 enum mouse_tracking_type
{
248 mouse_tracking_mouse_movement
,
249 mouse_tracking_scroll_bar
252 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
254 struct scroll_bar
*tracked_scroll_bar
= NULL
;
256 /* Incremented by XTread_socket whenever it really tries to read
260 static int volatile input_signal_count
;
262 static int input_signal_count
;
265 /* Used locally within XTread_socket. */
267 static int x_noop_count
;
269 /* Initial values of argv and argc. */
271 extern char **initial_argv
;
272 extern int initial_argc
;
274 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
276 /* Tells if a window manager is present or not. */
278 extern Lisp_Object Vx_no_window_manager
;
280 extern Lisp_Object Qface
, Qmouse_face
;
284 /* A mask of extra modifier bits to put into every keyboard char. */
286 extern int extra_keyboard_modifiers
;
288 static Lisp_Object Qvendor_specific_keysyms
;
291 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
294 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
296 extern int inhibit_window_system
;
299 QDGlobals qd
; /* QuickDraw global information structure. */
303 /* Enumeration for overriding/changing the face to use for drawing
304 glyphs in x_draw_glyphs. */
306 enum draw_glyphs_face
316 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
317 struct mac_display_info
*mac_display_info_for_display (Display
*);
318 static void x_update_window_end
P_ ((struct window
*, int, int));
319 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
320 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
321 int *, int *, Lisp_Object
));
322 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
323 int *, int *, int *, int *, int));
324 static void set_output_cursor
P_ ((struct cursor_pos
*));
325 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
326 int *, int *, int *, int));
327 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
328 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
329 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
330 static void x_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
331 static void show_mouse_face
P_ ((struct x_display_info
*,
332 enum draw_glyphs_face
));
333 static int cursor_in_mouse_face_p
P_ ((struct window
*));
334 static int clear_mouse_face
P_ ((struct mac_display_info
*));
335 static int x_io_error_quitter
P_ ((Display
*));
336 int x_catch_errors
P_ ((Display
*));
337 void x_uncatch_errors
P_ ((Display
*, int));
338 void x_lower_frame
P_ ((struct frame
*));
339 void x_scroll_bar_clear
P_ ((struct frame
*));
340 int x_had_errors_p
P_ ((Display
*));
341 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
342 void x_raise_frame
P_ ((struct frame
*));
343 void x_set_window_size
P_ ((struct frame
*, int, int, int));
344 void x_wm_set_window_state
P_ ((struct frame
*, int));
345 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
346 void mac_initialize
P_ ((void));
347 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
348 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
349 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
351 enum draw_glyphs_face
));
352 static void x_update_end
P_ ((struct frame
*));
353 static void XTframe_up_to_date
P_ ((struct frame
*));
354 static void XTreassert_line_highlight
P_ ((int, int));
355 static void x_change_line_highlight
P_ ((int, int, int, int));
356 static void XTset_terminal_modes
P_ ((void));
357 static void XTreset_terminal_modes
P_ ((void));
358 static void XTcursor_to
P_ ((int, int, int, int));
359 static void x_write_glyphs
P_ ((struct glyph
*, int));
360 static void x_clear_end_of_line
P_ ((int));
361 static void x_clear_frame
P_ ((void));
362 static void x_clear_cursor
P_ ((struct window
*));
363 static void frame_highlight
P_ ((struct frame
*));
364 static void frame_unhighlight
P_ ((struct frame
*));
365 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
366 static void XTframe_rehighlight
P_ ((struct frame
*));
367 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
368 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
369 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
370 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
371 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
372 static int expose_window_tree
P_ ((struct window
*, Rect
*));
373 static void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
374 struct glyph_row
*));
375 static int expose_window
P_ ((struct window
*, Rect
*));
376 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
377 Rect
*, enum glyph_row_area
));
378 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
380 void x_display_cursor (struct window
*, int, int, int, int, int);
381 void x_update_cursor
P_ ((struct frame
*, int));
382 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
383 static void x_update_window_cursor
P_ ((struct window
*, int));
384 static void x_erase_phys_cursor
P_ ((struct window
*));
385 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
386 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
388 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
389 static void notice_overwritten_cursor
P_ ((struct window
*,
391 int, int, int, int));
392 static void x_flush
P_ ((struct frame
*f
));
393 static void x_update_begin
P_ ((struct frame
*));
394 static void x_update_window_begin
P_ ((struct window
*));
395 static void x_draw_vertical_border
P_ ((struct window
*));
396 static void x_after_update_window_line
P_ ((struct glyph_row
*));
397 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
398 static void x_produce_stretch_glyph
P_ ((struct it
*));
400 static void activate_scroll_bars (FRAME_PTR
);
401 static void deactivate_scroll_bars (FRAME_PTR
);
403 static int is_emacs_window (WindowPtr
);
405 extern int image_ascent (struct image
*, struct face
*);
406 void x_set_offset (struct frame
*, int, int, int);
407 int x_bitmap_icon (struct frame
*, Lisp_Object
);
408 void x_make_frame_visible (struct frame
*);
410 extern void window_scroll (Lisp_Object
, int, int, int);
412 /* Defined in macmenu.h. */
413 extern void menubar_selection_callback (FRAME_PTR
, int);
414 extern void set_frame_menubar (FRAME_PTR
, int, int);
416 /* X display function emulation */
418 /* Structure borrowed from Xlib.h to represent two-byte characters in
427 XFreePixmap (display
, pixmap
)
431 PixMap
*p
= (PixMap
*) pixmap
;
438 /* Set foreground color for subsequent QuickDraw commands. Assume
439 graphic port has already been set. */
442 mac_set_forecolor (unsigned long color
)
446 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
447 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
448 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
450 RGBForeColor (&fg_color
);
454 /* Set background color for subsequent QuickDraw commands. Assume
455 graphic port has already been set. */
458 mac_set_backcolor (unsigned long color
)
462 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
463 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
464 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
466 RGBBackColor (&bg_color
);
469 /* Set foreground and background color for subsequent QuickDraw
470 commands. Assume that the graphic port has already been set. */
473 mac_set_colors (GC gc
)
475 mac_set_forecolor (gc
->foreground
);
476 mac_set_backcolor (gc
->background
);
479 /* Mac version of XDrawLine. */
482 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
488 #if TARGET_API_MAC_CARBON
489 SetPort (GetWindowPort (w
));
500 /* Mac version of XClearArea. */
503 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
507 unsigned int width
, height
;
510 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
514 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
515 xgc
.background
= mwp
->x_compatible
.background_pixel
;
517 #if TARGET_API_MAC_CARBON
518 SetPort (GetWindowPort (w
));
523 mac_set_colors (&xgc
);
524 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
529 /* Mac version of XClearWindow. */
532 XClearWindow (display
, w
)
536 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
539 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
540 xgc
.background
= mwp
->x_compatible
.background_pixel
;
542 #if TARGET_API_MAC_CARBON
543 SetPort (GetWindowPort (w
));
548 mac_set_colors (&xgc
);
550 #if TARGET_API_MAC_CARBON
554 GetWindowPortBounds (w
, &r
);
557 #else /* not TARGET_API_MAC_CARBON */
558 EraseRect (&(w
->portRect
));
559 #endif /* not TARGET_API_MAC_CARBON */
563 /* Mac replacement for XCopyArea. */
566 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
575 #if TARGET_API_MAC_CARBON
576 SetPort (GetWindowPort (w
));
582 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
584 #if TARGET_API_MAC_CARBON
588 LockPortBits (GetWindowPort (w
));
589 pmh
= GetPortPixMap (GetWindowPort (w
));
590 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
591 UnlockPortBits (GetWindowPort (w
));
593 #else /* not TARGET_API_MAC_CARBON */
594 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
595 #endif /* not TARGET_API_MAC_CARBON */
599 /* Mac replacement for XSetClipRectangles. */
602 mac_set_clip_rectangle (display
, w
, r
)
607 #if TARGET_API_MAC_CARBON
608 SetPort (GetWindowPort (w
));
617 /* Mac replacement for XSetClipMask. */
620 mac_reset_clipping (display
, w
)
626 #if TARGET_API_MAC_CARBON
627 SetPort (GetWindowPort (w
));
632 SetRect (&r
, -32767, -32767, 32767, 32767);
637 /* Mac replacement for XCreateBitmapFromBitmapData. */
640 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
645 int bytes_per_row
, i
, j
;
647 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
648 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
649 if (!bitmap
->baseAddr
)
652 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
653 for (i
= 0; i
< h
; i
++)
654 for (j
= 0; j
< w
; j
++)
655 if (BitTst (bits
, i
* w
+ j
))
656 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
658 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
663 mac_free_bitmap (bitmap
)
666 xfree (bitmap
->baseAddr
);
669 /* Mac replacement for XFillRectangle. */
672 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
677 unsigned int width
, height
;
681 #if TARGET_API_MAC_CARBON
682 SetPort (GetWindowPort (w
));
688 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
690 PaintRect (&r
); /* using foreground color of gc */
694 /* Mac replacement for XDrawRectangle: dest is a window. */
697 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
702 unsigned int width
, height
;
706 #if TARGET_API_MAC_CARBON
707 SetPort (GetWindowPort (w
));
713 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
715 FrameRect (&r
); /* using foreground color of gc */
719 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
722 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
727 unsigned int width
, height
;
729 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
732 #if TARGET_API_MAC_CARBON
733 SetPort (GetWindowPort (w
));
739 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
741 FrameRect (&r
); /* using foreground color of gc */
747 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
754 int nchars
, mode
, bytes_per_char
;
756 #if TARGET_API_MAC_CARBON
757 SetPort (GetWindowPort (w
));
764 TextFont (gc
->font
->mac_fontnum
);
765 TextSize (gc
->font
->mac_fontsize
);
766 TextFace (gc
->font
->mac_fontface
);
770 DrawText (buf
, 0, nchars
* bytes_per_char
);
774 /* Mac replacement for XDrawString. */
777 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
785 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
789 /* Mac replacement for XDrawString16. */
792 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
800 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
805 /* Mac replacement for XDrawImageString. */
808 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
816 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
820 /* Mac replacement for XDrawString16. */
823 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
831 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
836 /* Mac replacement for XCopyArea: dest must be window. */
839 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
846 unsigned int width
, height
;
851 #if TARGET_API_MAC_CARBON
852 SetPort (GetWindowPort (dest
));
859 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
860 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
862 #if TARGET_API_MAC_CARBON
866 LockPortBits (GetWindowPort (dest
));
867 pmh
= GetPortPixMap (GetWindowPort (dest
));
868 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
869 UnlockPortBits (GetWindowPort (dest
));
871 #else /* not TARGET_API_MAC_CARBON */
872 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
873 #endif /* not TARGET_API_MAC_CARBON */
878 /* Convert a pair of local coordinates to global (screen) coordinates.
879 Assume graphic port has been properly set. */
881 local_to_global_coord (short *h
, short *v
)
895 /* Mac replacement for XCopyArea: used only for scrolling. */
898 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
903 unsigned int width
, height
;
906 #if TARGET_API_MAC_CARBON
907 Rect gw_r
, src_r
, dest_r
;
910 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
911 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
913 SetPort (GetWindowPort (w
));
915 ForeColor (blackColor
);
916 BackColor (whiteColor
);
918 LockPortBits (GetWindowPort (w
));
919 pmh
= GetPortPixMap (GetWindowPort (w
));
920 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
921 UnlockPortBits (GetWindowPort (w
));
924 #else /* not TARGET_API_MAC_CARBON */
932 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
933 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
936 /* Need to use global coordinates and screenBits since src and dest
937 areas overlap in general. */
938 local_to_global_coord (&src_r
.left
, &src_r
.top
);
939 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
940 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
941 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
943 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
945 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
946 color mapping in CopyBits. Otherwise, it will be slow. */
947 ForeColor (blackColor
);
948 BackColor (whiteColor
);
949 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
953 #endif /* not TARGET_API_MAC_CARBON */
957 /* Mac replacement for XCopyArea: dest must be Pixmap. */
960 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
967 unsigned int width
, height
;
971 int src_right
= ((PixMap
*) src
)->bounds
.right
;
972 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
973 int w
= src_right
- src_x
;
974 int h
= src_bottom
- src_y
;
978 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
979 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
981 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
985 /* Mac replacement for XChangeGC. */
988 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
991 if (mask
& GCForeground
)
992 gc
->foreground
= xgcv
->foreground
;
993 if (mask
& GCBackground
)
994 gc
->background
= xgcv
->background
;
996 gc
->font
= xgcv
->font
;
1000 /* Mac replacement for XCreateGC. */
1003 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1006 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1007 bzero (gc
, sizeof (XGCValues
));
1009 XChangeGC (ignore
, gc
, mask
, xgcv
);
1015 /* Used in xfaces.c. */
1018 XFreeGC (display
, gc
)
1026 /* Mac replacement for XGetGCValues. */
1029 XGetGCValues (void* ignore
, XGCValues
*gc
,
1030 unsigned long mask
, XGCValues
*xgcv
)
1032 XChangeGC (ignore
, xgcv
, mask
, gc
);
1036 /* Mac replacement for XSetForeground. */
1039 XSetForeground (display
, gc
, color
)
1042 unsigned long color
;
1044 gc
->foreground
= color
;
1048 /* Mac replacement for XSetFont. */
1051 XSetFont (display
, gc
, font
)
1061 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1062 int *direction
,int *font_ascent
,
1063 int *font_descent
, XCharStruct
*cs
)
1065 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1069 /* x_sync is a no-op on Mac. */
1077 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1078 Calls to XFlush should be unnecessary because the X output buffer
1079 is flushed automatically as needed by calls to XPending,
1080 XNextEvent, or XWindowEvent according to the XFlush man page.
1081 XTread_socket calls XPending. Removing XFlush improves
1084 #if TARGET_API_MAC_CARBON
1085 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1087 #define XFlush(DISPLAY) (void) 0
1090 /* Flush display of frame F, or of all frames if F is null. */
1096 #if TARGET_API_MAC_CARBON
1100 Lisp_Object rest
, frame
;
1101 FOR_EACH_FRAME (rest
, frame
)
1102 x_flush (XFRAME (frame
));
1104 else if (FRAME_X_P (f
))
1105 XFlush (FRAME_MAC_DISPLAY (f
));
1107 #endif /* TARGET_API_MAC_CARBON */
1112 /* Return the struct mac_display_info corresponding to DPY. There's
1115 struct mac_display_info
*
1116 mac_display_info_for_display (dpy
)
1119 return &one_mac_display_info
;
1124 /***********************************************************************
1125 Starting and ending an update
1126 ***********************************************************************/
1128 /* Start an update of frame F. This function is installed as a hook
1129 for update_begin, i.e. it is called when update_begin is called.
1130 This function is called prior to calls to x_update_window_begin for
1131 each window being updated. */
1137 /* Nothing to do. */
1141 /* Start update of window W. Set the global variable updated_window
1142 to the window being updated and set output_cursor to the cursor
1146 x_update_window_begin (w
)
1149 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1150 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1153 set_output_cursor (&w
->cursor
);
1157 if (f
== display_info
->mouse_face_mouse_frame
)
1159 /* Don't do highlighting for mouse motion during the update. */
1160 display_info
->mouse_face_defer
= 1;
1162 /* If F needs to be redrawn, simply forget about any prior mouse
1164 if (FRAME_GARBAGED_P (f
))
1165 display_info
->mouse_face_window
= Qnil
;
1167 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1168 their mouse_face_p flag set, which means that they are always
1169 unequal to rows in a desired matrix which never have that
1170 flag set. So, rows containing mouse-face glyphs are never
1171 scrolled, and we don't have to switch the mouse highlight off
1172 here to prevent it from being scrolled. */
1174 /* Can we tell that this update does not affect the window
1175 where the mouse highlight is? If so, no need to turn off.
1176 Likewise, don't do anything if the frame is garbaged;
1177 in that case, the frame's current matrix that we would use
1178 is all wrong, and we will redisplay that line anyway. */
1179 if (!NILP (display_info
->mouse_face_window
)
1180 && w
== XWINDOW (display_info
->mouse_face_window
))
1184 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1185 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1188 if (i
< w
->desired_matrix
->nrows
)
1189 clear_mouse_face (display_info
);
1198 /* Draw a vertical window border to the right of window W if W doesn't
1199 have vertical scroll bars. */
1202 x_draw_vertical_border (w
)
1205 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1207 /* Redraw borders between horizontally adjacent windows. Don't
1208 do it for frames with vertical scroll bars because either the
1209 right scroll bar of a window, or the left scroll bar of its
1210 neighbor will suffice as a border. */
1211 if (!WINDOW_RIGHTMOST_P (w
)
1212 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1216 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1217 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1220 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1221 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1226 /* End update of window W (which is equal to updated_window).
1228 Draw vertical borders between horizontally adjacent windows, and
1229 display W's cursor if CURSOR_ON_P is non-zero.
1231 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1232 glyphs in mouse-face were overwritten. In that case we have to
1233 make sure that the mouse-highlight is properly redrawn.
1235 W may be a menu bar pseudo-window in case we don't have X toolkit
1236 support. Such windows don't have a cursor, so don't display it
1240 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1242 int cursor_on_p
, mouse_face_overwritten_p
;
1244 struct mac_display_info
*dpyinfo
1245 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1247 if (!w
->pseudo_window_p
)
1252 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1254 output_cursor
.x
, output_cursor
.y
);
1256 x_draw_vertical_border (w
);
1260 /* If a row with mouse-face was overwritten, arrange for
1261 XTframe_up_to_date to redisplay the mouse highlight. */
1262 if (mouse_face_overwritten_p
)
1264 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1265 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1266 dpyinfo
->mouse_face_window
= Qnil
;
1270 /* Unhide the caret. This won't actually show the cursor, unless it
1271 was visible before the corresponding call to HideCaret in
1272 x_update_window_begin. */
1273 if (w32_use_visible_system_caret
)
1274 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1277 updated_window
= NULL
;
1281 /* End update of frame F. This function is installed as a hook in
1288 /* Reset the background color of Mac OS Window to that of the frame after
1289 update so that it is used by Mac Toolbox to clear the update region before
1290 an update event is generated. */
1291 #if TARGET_API_MAC_CARBON
1292 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1294 SetPort (FRAME_MAC_WINDOW (f
));
1297 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1299 /* Mouse highlight may be displayed again. */
1300 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1303 XFlush (FRAME_MAC_DISPLAY (f
));
1308 /* This function is called from various places in xdisp.c whenever a
1309 complete update has been performed. The global variable
1310 updated_window is not available here. */
1313 XTframe_up_to_date (f
)
1318 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1320 if (dpyinfo
->mouse_face_deferred_gc
1321 || f
== dpyinfo
->mouse_face_mouse_frame
)
1324 if (dpyinfo
->mouse_face_mouse_frame
)
1325 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1326 dpyinfo
->mouse_face_mouse_x
,
1327 dpyinfo
->mouse_face_mouse_y
);
1328 dpyinfo
->mouse_face_deferred_gc
= 0;
1335 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1336 arrow bitmaps, or clear the fringes if no bitmaps are required
1337 before DESIRED_ROW is made current. The window being updated is
1338 found in updated_window. This function is called from
1339 update_window_line only if it is known that there are differences
1340 between bitmaps to be drawn between current row and DESIRED_ROW. */
1343 x_after_update_window_line (desired_row
)
1344 struct glyph_row
*desired_row
;
1346 struct window
*w
= updated_window
;
1352 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1355 draw_row_fringe_bitmaps (w
, desired_row
);
1359 /* When a window has disappeared, make sure that no rest of
1360 full-width rows stays visible in the internal border. Could
1361 check here if updated_window is the leftmost/rightmost window,
1362 but I guess it's not worth doing since vertically split windows
1363 are almost never used, internal border is rarely set, and the
1364 overhead is very small. */
1365 if (windows_or_buffers_changed
1366 && desired_row
->full_width_p
1367 && (f
= XFRAME (w
->frame
),
1368 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1370 && (height
= desired_row
->visible_height
,
1373 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1374 /* Internal border is drawn below the tool bar. */
1375 if (WINDOWP (f
->tool_bar_window
)
1376 && w
== XWINDOW (f
->tool_bar_window
))
1381 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1382 0, y
, width
, height
, 0);
1383 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1384 f
->output_data
.mac
->pixel_width
- width
, y
,
1392 /* Draw the bitmap WHICH in one of the left or right fringes of
1393 window W. ROW is the glyph row for which to display the bitmap; it
1394 determines the vertical position at which the bitmap has to be
1398 x_draw_fringe_bitmap (w
, row
, p
)
1400 struct glyph_row
*row
;
1401 struct draw_fringe_bitmap_params
*p
;
1403 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1404 Display
*display
= FRAME_MAC_DISPLAY (f
);
1405 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1407 GC gc
= f
->output_data
.mac
->normal_gc
;
1408 struct face
*face
= p
->face
;
1410 /* Must clip because of partially visible lines. */
1411 x_clip_to_row (w
, row
, gc
, 1);
1416 gcv
.foreground
= face
->background
;
1418 #if 0 /* MAC_TODO: stipple */
1419 /* In case the same realized face is used for fringes and
1420 for something displayed in the text (e.g. face `region' on
1421 mono-displays, the fill style may have been changed to
1422 FillSolid in x_draw_glyph_string_background. */
1424 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1426 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1429 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1431 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1433 #if 0 /* MAC_TODO: stipple */
1435 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1439 if (p
->which
!= NO_FRINGE_BITMAP
)
1441 unsigned char *bits
= fringe_bitmaps
[p
->which
].bits
+ p
->dh
;
1444 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, p
->wd
, p
->h
);
1445 gcv
.foreground
= face
->foreground
;
1446 gcv
.background
= face
->background
;
1448 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
, &bitmap
);
1450 mac_free_bitmap (&bitmap
);
1453 mac_reset_clipping (display
, window
);
1457 /* This is called when starting Emacs and when restarting after
1458 suspend. When starting Emacs, no window is mapped. And nothing
1459 must be done to Emacs's own window if it is suspended (though that
1463 XTset_terminal_modes ()
1467 /* This is called when exiting or suspending Emacs. Exiting will make
1468 the windows go away, and suspending requires no action. */
1471 XTreset_terminal_modes ()
1477 /***********************************************************************
1479 ***********************************************************************/
1481 /* Set the global variable output_cursor to CURSOR. All cursor
1482 positions are relative to updated_window. */
1485 set_output_cursor (cursor
)
1486 struct cursor_pos
*cursor
;
1488 output_cursor
.hpos
= cursor
->hpos
;
1489 output_cursor
.vpos
= cursor
->vpos
;
1490 output_cursor
.x
= cursor
->x
;
1491 output_cursor
.y
= cursor
->y
;
1495 /* Set a nominal cursor position.
1497 HPOS and VPOS are column/row positions in a window glyph matrix. X
1498 and Y are window text area relative pixel positions.
1500 If this is done during an update, updated_window will contain the
1501 window that is being updated and the position is the future output
1502 cursor position for that window. If updated_window is null, use
1503 selected_window and display the cursor at the given position. */
1506 XTcursor_to (vpos
, hpos
, y
, x
)
1507 int vpos
, hpos
, y
, x
;
1511 /* If updated_window is not set, work on selected_window. */
1515 w
= XWINDOW (selected_window
);
1517 /* Set the output cursor. */
1518 output_cursor
.hpos
= hpos
;
1519 output_cursor
.vpos
= vpos
;
1520 output_cursor
.x
= x
;
1521 output_cursor
.y
= y
;
1523 /* If not called as part of an update, really display the cursor.
1524 This will also set the cursor position of W. */
1525 if (updated_window
== NULL
)
1528 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1529 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1536 /***********************************************************************
1538 ***********************************************************************/
1540 /* Function prototypes of this page. */
1542 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1546 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1547 int, XChar2b
*, int));
1548 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1549 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1550 static void x_append_glyph
P_ ((struct it
*));
1551 static void x_append_composite_glyph
P_ ((struct it
*));
1552 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1554 static void x_produce_glyphs
P_ ((struct it
*));
1555 static void x_produce_image_glyph
P_ ((struct it
*it
));
1558 /* Return a pointer to per-char metric information in FONT of a
1559 character pointed by B which is a pointer to an XChar2b. */
1561 #define PER_CHAR_METRIC(font, b) \
1563 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1564 + (((font)->min_byte1 || (font)->max_byte1) \
1565 ? (((b)->byte1 - (font)->min_byte1) \
1566 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1568 : &((font)->max_bounds))
1571 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1572 is not contained in the font. */
1574 static INLINE XCharStruct
*
1575 x_per_char_metric (font
, char2b
)
1579 /* The result metric information. */
1580 XCharStruct
*pcm
= NULL
;
1582 xassert (font
&& char2b
);
1584 if (font
->per_char
!= NULL
)
1586 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1588 /* min_char_or_byte2 specifies the linear character index
1589 corresponding to the first element of the per_char array,
1590 max_char_or_byte2 is the index of the last character. A
1591 character with non-zero CHAR2B->byte1 is not in the font.
1592 A character with byte2 less than min_char_or_byte2 or
1593 greater max_char_or_byte2 is not in the font. */
1594 if (char2b
->byte1
== 0
1595 && char2b
->byte2
>= font
->min_char_or_byte2
1596 && char2b
->byte2
<= font
->max_char_or_byte2
)
1597 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1601 /* If either min_byte1 or max_byte1 are nonzero, both
1602 min_char_or_byte2 and max_char_or_byte2 are less than
1603 256, and the 2-byte character index values corresponding
1604 to the per_char array element N (counting from 0) are:
1606 byte1 = N/D + min_byte1
1607 byte2 = N\D + min_char_or_byte2
1611 D = max_char_or_byte2 - min_char_or_byte2 + 1
1612 / = integer division
1613 \ = integer modulus */
1614 if (char2b
->byte1
>= font
->min_byte1
1615 && char2b
->byte1
<= font
->max_byte1
1616 && char2b
->byte2
>= font
->min_char_or_byte2
1617 && char2b
->byte2
<= font
->max_char_or_byte2
)
1619 pcm
= (font
->per_char
1620 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1621 * (char2b
->byte1
- font
->min_byte1
))
1622 + (char2b
->byte2
- font
->min_char_or_byte2
));
1628 /* If the per_char pointer is null, all glyphs between the first
1629 and last character indexes inclusive have the same
1630 information, as given by both min_bounds and max_bounds. */
1631 if (char2b
->byte2
>= font
->min_char_or_byte2
1632 && char2b
->byte2
<= font
->max_char_or_byte2
)
1633 pcm
= &font
->max_bounds
;
1636 return ((pcm
== NULL
1637 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1642 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1643 the two-byte form of C. Encoding is returned in *CHAR2B. */
1646 x_encode_char (c
, char2b
, font_info
)
1649 struct font_info
*font_info
;
1651 int charset
= CHAR_CHARSET (c
);
1652 XFontStruct
*font
= font_info
->font
;
1654 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1655 This may be either a program in a special encoder language or a
1657 if (font_info
->font_encoder
)
1659 /* It's a program. */
1660 struct ccl_program
*ccl
= font_info
->font_encoder
;
1662 if (CHARSET_DIMENSION (charset
) == 1)
1664 ccl
->reg
[0] = charset
;
1665 ccl
->reg
[1] = char2b
->byte2
;
1669 ccl
->reg
[0] = charset
;
1670 ccl
->reg
[1] = char2b
->byte1
;
1671 ccl
->reg
[2] = char2b
->byte2
;
1674 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1676 /* We assume that MSBs are appropriately set/reset by CCL
1678 if (font
->max_byte1
== 0) /* 1-byte font */
1679 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1681 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1683 else if (font_info
->encoding
[charset
])
1685 /* Fixed encoding scheme. See fontset.h for the meaning of the
1686 encoding numbers. */
1687 int enc
= font_info
->encoding
[charset
];
1689 if ((enc
== 1 || enc
== 2)
1690 && CHARSET_DIMENSION (charset
) == 2)
1691 char2b
->byte1
|= 0x80;
1693 if (enc
== 1 || enc
== 3)
1694 char2b
->byte2
|= 0x80;
1700 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1701 char2b
->byte1
= sjis1
;
1702 char2b
->byte2
= sjis2
;
1708 /* Get face and two-byte form of character C in face FACE_ID on frame
1709 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1710 means we want to display multibyte text. Value is a pointer to a
1711 realized face that is ready for display. */
1713 static INLINE
struct face
*
1714 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1720 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1724 /* Unibyte case. We don't have to encode, but we have to make
1725 sure to use a face suitable for unibyte. */
1728 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1729 face
= FACE_FROM_ID (f
, face_id
);
1731 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1733 /* Case of ASCII in a face known to fit ASCII. */
1739 int c1
, c2
, charset
;
1741 /* Split characters into bytes. If c2 is -1 afterwards, C is
1742 really a one-byte character so that byte1 is zero. */
1743 SPLIT_CHAR (c
, charset
, c1
, c2
);
1745 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1747 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1749 /* Maybe encode the character in *CHAR2B. */
1750 if (face
->font
!= NULL
)
1752 struct font_info
*font_info
1753 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1755 x_encode_char (c
, char2b
, font_info
);
1759 /* Make sure X resources of the face are allocated. */
1760 xassert (face
!= NULL
);
1761 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1767 /* Get face and two-byte form of character glyph GLYPH on frame F.
1768 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1769 a pointer to a realized face that is ready for display. */
1771 static INLINE
struct face
*
1772 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1774 struct glyph
*glyph
;
1780 xassert (glyph
->type
== CHAR_GLYPH
);
1781 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1786 if (!glyph
->multibyte_p
)
1788 /* Unibyte case. We don't have to encode, but we have to make
1789 sure to use a face suitable for unibyte. */
1791 char2b
->byte2
= glyph
->u
.ch
;
1793 else if (glyph
->u
.ch
< 128
1794 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1796 /* Case of ASCII in a face known to fit ASCII. */
1798 char2b
->byte2
= glyph
->u
.ch
;
1802 int c1
, c2
, charset
;
1804 /* Split characters into bytes. If c2 is -1 afterwards, C is
1805 really a one-byte character so that byte1 is zero. */
1806 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1808 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1810 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1812 /* Maybe encode the character in *CHAR2B. */
1813 if (charset
!= CHARSET_ASCII
)
1815 struct font_info
*font_info
1816 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1819 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1822 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1827 /* Make sure X resources of the face are allocated. */
1828 xassert (face
!= NULL
);
1829 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1834 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1835 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1841 struct glyph
*glyph
;
1842 enum glyph_row_area area
= it
->area
;
1844 xassert (it
->glyph_row
);
1845 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1847 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1848 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1850 glyph
->charpos
= CHARPOS (it
->position
);
1851 glyph
->object
= it
->object
;
1852 glyph
->pixel_width
= it
->pixel_width
;
1853 glyph
->voffset
= it
->voffset
;
1854 glyph
->type
= CHAR_GLYPH
;
1855 glyph
->multibyte_p
= it
->multibyte_p
;
1856 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1857 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1858 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1859 || it
->phys_descent
> it
->descent
);
1860 glyph
->padding_p
= 0;
1861 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1862 glyph
->face_id
= it
->face_id
;
1863 glyph
->u
.ch
= it
->char_to_display
;
1864 ++it
->glyph_row
->used
[area
];
1868 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1869 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1872 x_append_composite_glyph (it
)
1875 struct glyph
*glyph
;
1876 enum glyph_row_area area
= it
->area
;
1878 xassert (it
->glyph_row
);
1880 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1881 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1883 glyph
->charpos
= CHARPOS (it
->position
);
1884 glyph
->object
= it
->object
;
1885 glyph
->pixel_width
= it
->pixel_width
;
1886 glyph
->voffset
= it
->voffset
;
1887 glyph
->type
= COMPOSITE_GLYPH
;
1888 glyph
->multibyte_p
= it
->multibyte_p
;
1889 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1890 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1891 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1892 || it
->phys_descent
> it
->descent
);
1893 glyph
->padding_p
= 0;
1894 glyph
->glyph_not_available_p
= 0;
1895 glyph
->face_id
= it
->face_id
;
1896 glyph
->u
.cmp_id
= it
->cmp_id
;
1897 ++it
->glyph_row
->used
[area
];
1902 /* Change IT->ascent and IT->height according to the setting of
1906 take_vertical_position_into_account (it
)
1911 if (it
->voffset
< 0)
1912 /* Increase the ascent so that we can display the text higher
1914 it
->ascent
+= abs (it
->voffset
);
1916 /* Increase the descent so that we can display the text lower
1918 it
->descent
+= it
->voffset
;
1923 /* Produce glyphs/get display metrics for the image IT is loaded with.
1924 See the description of struct display_iterator in dispextern.h for
1925 an overview of struct display_iterator. */
1928 x_produce_image_glyph (it
)
1934 xassert (it
->what
== IT_IMAGE
);
1936 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
1937 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
1940 /* Make sure X resources of the face and image are loaded. */
1941 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
1942 prepare_image_for_display (it
->f
, img
);
1944 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
1945 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
1946 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
1950 if (face
->box
!= FACE_NO_BOX
)
1952 if (face
->box_line_width
> 0)
1954 it
->ascent
+= face
->box_line_width
;
1955 it
->descent
+= face
->box_line_width
;
1958 if (it
->start_of_box_run_p
)
1959 it
->pixel_width
+= abs (face
->box_line_width
);
1960 if (it
->end_of_box_run_p
)
1961 it
->pixel_width
+= abs (face
->box_line_width
);
1964 take_vertical_position_into_account (it
);
1968 struct glyph
*glyph
;
1969 enum glyph_row_area area
= it
->area
;
1971 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1972 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1974 glyph
->charpos
= CHARPOS (it
->position
);
1975 glyph
->object
= it
->object
;
1976 glyph
->pixel_width
= it
->pixel_width
;
1977 glyph
->voffset
= it
->voffset
;
1978 glyph
->type
= IMAGE_GLYPH
;
1979 glyph
->multibyte_p
= it
->multibyte_p
;
1980 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1981 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1982 glyph
->overlaps_vertically_p
= 0;
1983 glyph
->padding_p
= 0;
1984 glyph
->glyph_not_available_p
= 0;
1985 glyph
->face_id
= it
->face_id
;
1986 glyph
->u
.img_id
= img
->id
;
1987 ++it
->glyph_row
->used
[area
];
1993 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1994 of the glyph, WIDTH and HEIGHT are the width and height of the
1995 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1996 ascent of the glyph (0 <= ASCENT <= 1). */
1999 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2005 struct glyph
*glyph
;
2006 enum glyph_row_area area
= it
->area
;
2008 xassert (ascent
>= 0 && ascent
<= 1);
2010 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2011 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2013 glyph
->charpos
= CHARPOS (it
->position
);
2014 glyph
->object
= object
;
2015 glyph
->pixel_width
= width
;
2016 glyph
->voffset
= it
->voffset
;
2017 glyph
->type
= STRETCH_GLYPH
;
2018 glyph
->multibyte_p
= it
->multibyte_p
;
2019 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2020 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2021 glyph
->overlaps_vertically_p
= 0;
2022 glyph
->padding_p
= 0;
2023 glyph
->glyph_not_available_p
= 0;
2024 glyph
->face_id
= it
->face_id
;
2025 glyph
->u
.stretch
.ascent
= height
* ascent
;
2026 glyph
->u
.stretch
.height
= height
;
2027 ++it
->glyph_row
->used
[area
];
2032 /* Produce a stretch glyph for iterator IT. IT->object is the value
2033 of the glyph property displayed. The value must be a list
2034 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2037 1. `:width WIDTH' specifies that the space should be WIDTH *
2038 canonical char width wide. WIDTH may be an integer or floating
2041 2. `:relative-width FACTOR' specifies that the width of the stretch
2042 should be computed from the width of the first character having the
2043 `glyph' property, and should be FACTOR times that width.
2045 3. `:align-to HPOS' specifies that the space should be wide enough
2046 to reach HPOS, a value in canonical character units.
2048 Exactly one of the above pairs must be present.
2050 4. `:height HEIGHT' specifies that the height of the stretch produced
2051 should be HEIGHT, measured in canonical character units.
2053 5. `:relative-height FACTOR' specifies that the height of the
2054 stretch should be FACTOR times the height of the characters having
2057 Either none or exactly one of 4 or 5 must be present.
2059 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2060 of the stretch should be used for the ascent of the stretch.
2061 ASCENT must be in the range 0 <= ASCENT <= 100. */
2064 ((INTEGERP (X) || FLOATP (X)) \
2070 x_produce_stretch_glyph (it
)
2073 /* (space :width WIDTH :height HEIGHT. */
2075 extern Lisp_Object Qspace
;
2077 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2078 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2079 extern Lisp_Object QCalign_to
;
2080 Lisp_Object prop
, plist
;
2081 double width
= 0, height
= 0, ascent
= 0;
2082 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2083 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2085 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2087 /* List should start with `space'. */
2088 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2089 plist
= XCDR (it
->object
);
2091 /* Compute the width of the stretch. */
2092 if (prop
= Fplist_get (plist
, QCwidth
),
2094 /* Absolute width `:width WIDTH' specified and valid. */
2095 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2096 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2099 /* Relative width `:relative-width FACTOR' specified and valid.
2100 Compute the width of the characters having the `glyph'
2103 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2106 if (it
->multibyte_p
)
2108 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2109 - IT_BYTEPOS (*it
));
2110 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2113 it2
.c
= *p
, it2
.len
= 1;
2115 it2
.glyph_row
= NULL
;
2116 it2
.what
= IT_CHARACTER
;
2117 x_produce_glyphs (&it2
);
2118 width
= NUMVAL (prop
) * it2
.pixel_width
;
2120 else if (prop
= Fplist_get (plist
, QCalign_to
),
2122 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2124 /* Nothing specified -> width defaults to canonical char width. */
2125 width
= CANON_X_UNIT (it
->f
);
2127 /* Compute height. */
2128 if (prop
= Fplist_get (plist
, QCheight
),
2130 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2131 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2133 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2135 height
= FONT_HEIGHT (font
);
2137 /* Compute percentage of height used for ascent. If
2138 `:ascent ASCENT' is present and valid, use that. Otherwise,
2139 derive the ascent from the font in use. */
2140 if (prop
= Fplist_get (plist
, QCascent
),
2141 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2142 ascent
= NUMVAL (prop
) / 100.0;
2144 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2153 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2154 if (!STRINGP (object
))
2155 object
= it
->w
->buffer
;
2156 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2159 it
->pixel_width
= width
;
2160 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2161 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2164 if (face
->box
!= FACE_NO_BOX
)
2166 if (face
->box_line_width
> 0)
2168 it
->ascent
+= face
->box_line_width
;
2169 it
->descent
+= face
->box_line_width
;
2172 if (it
->start_of_box_run_p
)
2173 it
->pixel_width
+= abs (face
->box_line_width
);
2174 if (it
->end_of_box_run_p
)
2175 it
->pixel_width
+= abs (face
->box_line_width
);
2178 take_vertical_position_into_account (it
);
2181 /* Return proper value to be used as baseline offset of font that has
2182 ASCENT and DESCENT to draw characters by the font at the vertical
2183 center of the line of frame F.
2185 Here, out task is to find the value of BOFF in the following figure;
2187 -------------------------+-----------+-
2188 -+-+---------+-+ | |
2190 | | | | F_ASCENT F_HEIGHT
2193 | | |-|-+------+-----------|------- baseline
2195 | |---------|-+-+ | |
2197 -+-+---------+-+ F_DESCENT |
2198 -------------------------+-----------+-
2200 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2201 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2202 DESCENT = FONT->descent
2203 HEIGHT = FONT_HEIGHT (FONT)
2204 F_DESCENT = (F->output_data.x->font->descent
2205 - F->output_data.x->baseline_offset)
2206 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2209 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2210 (FONT_DESCENT (FONT) \
2211 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2212 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2213 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2215 /* Produce glyphs/get display metrics for the display element IT is
2216 loaded with. See the description of struct display_iterator in
2217 dispextern.h for an overview of struct display_iterator. */
2220 x_produce_glyphs (it
)
2223 it
->glyph_not_available_p
= 0;
2225 if (it
->what
== IT_CHARACTER
)
2229 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2231 int font_not_found_p
;
2232 struct font_info
*font_info
;
2233 int boff
; /* baseline offset */
2234 /* We may change it->multibyte_p upon unibyte<->multibyte
2235 conversion. So, save the current value now and restore it
2238 Note: It seems that we don't have to record multibyte_p in
2239 struct glyph because the character code itself tells if or
2240 not the character is multibyte. Thus, in the future, we must
2241 consider eliminating the field `multibyte_p' in the struct
2244 int saved_multibyte_p
= it
->multibyte_p
;
2246 /* Maybe translate single-byte characters to multibyte, or the
2248 it
->char_to_display
= it
->c
;
2249 if (!ASCII_BYTE_P (it
->c
))
2251 if (unibyte_display_via_language_environment
2252 && SINGLE_BYTE_CHAR_P (it
->c
)
2254 || !NILP (Vnonascii_translation_table
)))
2256 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2257 it
->multibyte_p
= 1;
2258 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2259 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2261 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2262 && !it
->multibyte_p
)
2264 it
->multibyte_p
= 1;
2265 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2266 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2270 /* Get font to use. Encode IT->char_to_display. */
2271 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2272 it
->face_id
, &char2b
,
2276 /* When no suitable font found, use the default font. */
2277 font_not_found_p
= font
== NULL
;
2278 if (font_not_found_p
)
2280 font
= FRAME_FONT (it
->f
);
2281 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2286 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2287 boff
= font_info
->baseline_offset
;
2288 if (font_info
->vertical_centering
)
2289 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2292 if (it
->char_to_display
>= ' '
2293 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2295 /* Either unibyte or ASCII. */
2300 pcm
= x_per_char_metric (font
, &char2b
);
2301 it
->ascent
= FONT_BASE (font
) + boff
;
2302 it
->descent
= FONT_DESCENT (font
) - boff
;
2306 it
->phys_ascent
= pcm
->ascent
+ boff
;
2307 it
->phys_descent
= pcm
->descent
- boff
;
2308 it
->pixel_width
= pcm
->width
;
2312 it
->glyph_not_available_p
= 1;
2313 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2314 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2315 it
->pixel_width
= FONT_WIDTH (font
);
2318 /* If this is a space inside a region of text with
2319 `space-width' property, change its width. */
2320 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2322 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2324 /* If face has a box, add the box thickness to the character
2325 height. If character has a box line to the left and/or
2326 right, add the box line width to the character's width. */
2327 if (face
->box
!= FACE_NO_BOX
)
2329 int thick
= face
->box_line_width
;
2333 it
->ascent
+= thick
;
2334 it
->descent
+= thick
;
2339 if (it
->start_of_box_run_p
)
2340 it
->pixel_width
+= thick
;
2341 if (it
->end_of_box_run_p
)
2342 it
->pixel_width
+= thick
;
2345 /* If face has an overline, add the height of the overline
2346 (1 pixel) and a 1 pixel margin to the character height. */
2347 if (face
->overline_p
)
2350 take_vertical_position_into_account (it
);
2352 /* If we have to actually produce glyphs, do it. */
2357 /* Translate a space with a `space-width' property
2358 into a stretch glyph. */
2359 double ascent
= (double) FONT_BASE (font
)
2360 / FONT_HEIGHT (font
);
2361 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2362 it
->ascent
+ it
->descent
, ascent
);
2365 x_append_glyph (it
);
2367 /* If characters with lbearing or rbearing are displayed
2368 in this line, record that fact in a flag of the
2369 glyph row. This is used to optimize X output code. */
2370 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2371 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2374 else if (it
->char_to_display
== '\n')
2376 /* A newline has no width but we need the height of the line. */
2377 it
->pixel_width
= 0;
2379 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2380 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2382 if (face
->box
!= FACE_NO_BOX
2383 && face
->box_line_width
> 0)
2385 it
->ascent
+= face
->box_line_width
;
2386 it
->descent
+= face
->box_line_width
;
2389 else if (it
->char_to_display
== '\t')
2391 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2392 int x
= it
->current_x
+ it
->continuation_lines_width
;
2393 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2395 /* If the distance from the current position to the next tab
2396 stop is less than a canonical character width, use the
2397 tab stop after that. */
2398 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2399 next_tab_x
+= tab_width
;
2401 it
->pixel_width
= next_tab_x
- x
;
2403 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2404 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2408 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2409 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2410 it
->ascent
+ it
->descent
, ascent
);
2415 /* A multi-byte character. Assume that the display width of the
2416 character is the width of the character multiplied by the
2417 width of the font. */
2419 /* If we found a font, this font should give us the right
2420 metrics. If we didn't find a font, use the frame's
2421 default font and calculate the width of the character
2422 from the charset width; this is what old redisplay code
2424 pcm
= x_per_char_metric (font
, &char2b
);
2425 if (font_not_found_p
|| !pcm
)
2427 int charset
= CHAR_CHARSET (it
->char_to_display
);
2429 it
->glyph_not_available_p
= 1;
2430 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2431 * CHARSET_WIDTH (charset
));
2432 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2433 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2437 it
->pixel_width
= pcm
->width
;
2438 it
->phys_ascent
= pcm
->ascent
+ boff
;
2439 it
->phys_descent
= pcm
->descent
- boff
;
2441 && (pcm
->lbearing
< 0
2442 || pcm
->rbearing
> pcm
->width
))
2443 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2446 it
->ascent
= FONT_BASE (font
) + boff
;
2447 it
->descent
= FONT_DESCENT (font
) - boff
;
2448 if (face
->box
!= FACE_NO_BOX
)
2450 int thick
= face
->box_line_width
;
2454 it
->ascent
+= thick
;
2455 it
->descent
+= thick
;
2460 if (it
->start_of_box_run_p
)
2461 it
->pixel_width
+= thick
;
2462 if (it
->end_of_box_run_p
)
2463 it
->pixel_width
+= thick
;
2466 /* If face has an overline, add the height of the overline
2467 (1 pixel) and a 1 pixel margin to the character height. */
2468 if (face
->overline_p
)
2471 take_vertical_position_into_account (it
);
2474 x_append_glyph (it
);
2476 it
->multibyte_p
= saved_multibyte_p
;
2478 else if (it
->what
== IT_COMPOSITION
)
2480 /* Note: A composition is represented as one glyph in the
2481 glyph matrix. There are no padding glyphs. */
2484 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2486 int font_not_found_p
;
2487 struct font_info
*font_info
;
2488 int boff
; /* baseline offset */
2489 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2491 /* Maybe translate single-byte characters to multibyte. */
2492 it
->char_to_display
= it
->c
;
2493 if (unibyte_display_via_language_environment
2494 && SINGLE_BYTE_CHAR_P (it
->c
)
2497 && !NILP (Vnonascii_translation_table
))))
2499 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2502 /* Get face and font to use. Encode IT->char_to_display. */
2503 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2504 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2505 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2506 it
->face_id
, &char2b
, it
->multibyte_p
);
2509 /* When no suitable font found, use the default font. */
2510 font_not_found_p
= font
== NULL
;
2511 if (font_not_found_p
)
2513 font
= FRAME_FONT (it
->f
);
2514 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2519 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2520 boff
= font_info
->baseline_offset
;
2521 if (font_info
->vertical_centering
)
2522 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2525 /* There are no padding glyphs, so there is only one glyph to
2526 produce for the composition. Important is that pixel_width,
2527 ascent and descent are the values of what is drawn by
2528 draw_glyphs (i.e. the values of the overall glyphs composed). */
2531 /* If we have not yet calculated pixel size data of glyphs of
2532 the composition for the current face font, calculate them
2533 now. Theoretically, we have to check all fonts for the
2534 glyphs, but that requires much time and memory space. So,
2535 here we check only the font of the first glyph. This leads
2536 to incorrect display very rarely, and C-l (recenter) can
2537 correct the display anyway. */
2538 if (cmp
->font
!= (void *) font
)
2540 /* Ascent and descent of the font of the first character of
2541 this composition (adjusted by baseline offset). Ascent
2542 and descent of overall glyphs should not be less than
2543 them respectively. */
2544 int font_ascent
= FONT_BASE (font
) + boff
;
2545 int font_descent
= FONT_DESCENT (font
) - boff
;
2546 /* Bounding box of the overall glyphs. */
2547 int leftmost
, rightmost
, lowest
, highest
;
2548 int i
, width
, ascent
, descent
;
2550 cmp
->font
= (void *) font
;
2552 /* Initialize the bounding box. */
2553 pcm
= x_per_char_metric (font
, &char2b
);
2557 ascent
= pcm
->ascent
;
2558 descent
= pcm
->descent
;
2562 width
= FONT_WIDTH (font
);
2563 ascent
= FONT_BASE (font
);
2564 descent
= FONT_DESCENT (font
);
2568 lowest
= - descent
+ boff
;
2569 highest
= ascent
+ boff
;
2573 && font_info
->default_ascent
2574 && CHAR_TABLE_P (Vuse_default_ascent
)
2575 && !NILP (Faref (Vuse_default_ascent
,
2576 make_number (it
->char_to_display
))))
2577 highest
= font_info
->default_ascent
+ boff
;
2579 /* Draw the first glyph at the normal position. It may be
2580 shifted to right later if some other glyphs are drawn at
2582 cmp
->offsets
[0] = 0;
2583 cmp
->offsets
[1] = boff
;
2585 /* Set cmp->offsets for the remaining glyphs. */
2586 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2588 int left
, right
, btm
, top
;
2589 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2590 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2592 face
= FACE_FROM_ID (it
->f
, face_id
);
2593 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2598 font
= FRAME_FONT (it
->f
);
2599 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2605 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2606 boff
= font_info
->baseline_offset
;
2607 if (font_info
->vertical_centering
)
2608 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2611 pcm
= x_per_char_metric (font
, &char2b
);
2615 ascent
= pcm
->ascent
;
2616 descent
= pcm
->descent
;
2620 width
= FONT_WIDTH (font
);
2625 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2627 /* Relative composition with or without
2629 left
= (leftmost
+ rightmost
- width
) / 2;
2630 btm
= - descent
+ boff
;
2631 if (font_info
&& font_info
->relative_compose
2632 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2633 || NILP (Faref (Vignore_relative_composition
,
2634 make_number (ch
)))))
2637 if (- descent
>= font_info
->relative_compose
)
2638 /* One extra pixel between two glyphs. */
2640 else if (ascent
<= 0)
2641 /* One extra pixel between two glyphs. */
2642 btm
= lowest
- 1 - ascent
- descent
;
2647 /* A composition rule is specified by an integer
2648 value that encodes global and new reference
2649 points (GREF and NREF). GREF and NREF are
2650 specified by numbers as below:
2658 ---3---4---5--- baseline
2660 6---7---8 -- descent
2662 int rule
= COMPOSITION_RULE (cmp
, i
);
2663 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2665 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2666 grefx
= gref
% 3, nrefx
= nref
% 3;
2667 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2670 + grefx
* (rightmost
- leftmost
) / 2
2671 - nrefx
* width
/ 2);
2672 btm
= ((grefy
== 0 ? highest
2674 : grefy
== 2 ? lowest
2675 : (highest
+ lowest
) / 2)
2676 - (nrefy
== 0 ? ascent
+ descent
2677 : nrefy
== 1 ? descent
- boff
2679 : (ascent
+ descent
) / 2));
2682 cmp
->offsets
[i
* 2] = left
;
2683 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2685 /* Update the bounding box of the overall glyphs. */
2686 right
= left
+ width
;
2687 top
= btm
+ descent
+ ascent
;
2688 if (left
< leftmost
)
2690 if (right
> rightmost
)
2698 /* If there are glyphs whose x-offsets are negative,
2699 shift all glyphs to the right and make all x-offsets
2703 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2704 cmp
->offsets
[i
* 2] -= leftmost
;
2705 rightmost
-= leftmost
;
2708 cmp
->pixel_width
= rightmost
;
2709 cmp
->ascent
= highest
;
2710 cmp
->descent
= - lowest
;
2711 if (cmp
->ascent
< font_ascent
)
2712 cmp
->ascent
= font_ascent
;
2713 if (cmp
->descent
< font_descent
)
2714 cmp
->descent
= font_descent
;
2717 it
->pixel_width
= cmp
->pixel_width
;
2718 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2719 it
->descent
= it
->phys_descent
= cmp
->descent
;
2721 if (face
->box
!= FACE_NO_BOX
)
2723 int thick
= face
->box_line_width
;
2727 it
->ascent
+= thick
;
2728 it
->descent
+= thick
;
2733 if (it
->start_of_box_run_p
)
2734 it
->pixel_width
+= thick
;
2735 if (it
->end_of_box_run_p
)
2736 it
->pixel_width
+= thick
;
2739 /* If face has an overline, add the height of the overline
2740 (1 pixel) and a 1 pixel margin to the character height. */
2741 if (face
->overline_p
)
2744 take_vertical_position_into_account (it
);
2747 x_append_composite_glyph (it
);
2749 else if (it
->what
== IT_IMAGE
)
2750 x_produce_image_glyph (it
);
2751 else if (it
->what
== IT_STRETCH
)
2752 x_produce_stretch_glyph (it
);
2754 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2755 because this isn't true for images with `:ascent 100'. */
2756 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2757 if (it
->area
== TEXT_AREA
)
2758 it
->current_x
+= it
->pixel_width
;
2760 it
->descent
+= it
->extra_line_spacing
;
2762 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2763 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2764 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2765 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2769 /* Estimate the pixel height of the mode or top line on frame F.
2770 FACE_ID specifies what line's height to estimate. */
2773 x_estimate_mode_line_height (f
, face_id
)
2775 enum face_id face_id
;
2777 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2779 /* This function is called so early when Emacs starts that the face
2780 cache and mode line face are not yet initialized. */
2781 if (FRAME_FACE_CACHE (f
))
2783 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2787 height
= FONT_HEIGHT (face
->font
);
2788 if (face
->box_line_width
> 0)
2789 height
+= 2 * face
->box_line_width
;
2797 /***********************************************************************
2799 ***********************************************************************/
2801 /* A sequence of glyphs to be drawn in the same face.
2803 This data structure is not really completely X specific, so it
2804 could possibly, at least partially, be useful for other systems. It
2805 is currently not part of the external redisplay interface because
2806 it's not clear what other systems will need. */
2810 /* X-origin of the string. */
2813 /* Y-origin and y-position of the base line of this string. */
2816 /* The width of the string, not including a face extension. */
2819 /* The width of the string, including a face extension. */
2820 int background_width
;
2822 /* The height of this string. This is the height of the line this
2823 string is drawn in, and can be different from the height of the
2824 font the string is drawn in. */
2827 /* Number of pixels this string overwrites in front of its x-origin.
2828 This number is zero if the string has an lbearing >= 0; it is
2829 -lbearing, if the string has an lbearing < 0. */
2832 /* Number of pixels this string overwrites past its right-most
2833 nominal x-position, i.e. x + width. Zero if the string's
2834 rbearing is <= its nominal width, rbearing - width otherwise. */
2837 /* The frame on which the glyph string is drawn. */
2840 /* The window on which the glyph string is drawn. */
2843 /* X display and window for convenience. */
2847 /* The glyph row for which this string was built. It determines the
2848 y-origin and height of the string. */
2849 struct glyph_row
*row
;
2851 /* The area within row. */
2852 enum glyph_row_area area
;
2854 /* Characters to be drawn, and number of characters. */
2858 /* A face-override for drawing cursors, mouse face and similar. */
2859 enum draw_glyphs_face hl
;
2861 /* Face in which this string is to be drawn. */
2864 /* Font in which this string is to be drawn. */
2867 /* Font info for this string. */
2868 struct font_info
*font_info
;
2870 /* Non-null means this string describes (part of) a composition.
2871 All characters from char2b are drawn composed. */
2872 struct composition
*cmp
;
2874 /* Index of this glyph string's first character in the glyph
2875 definition of CMP. If this is zero, this glyph string describes
2876 the first character of a composition. */
2879 /* 1 means this glyph strings face has to be drawn to the right end
2880 of the window's drawing area. */
2881 unsigned extends_to_end_of_line_p
: 1;
2883 /* 1 means the background of this string has been drawn. */
2884 unsigned background_filled_p
: 1;
2886 /* 1 means glyph string must be drawn with 16-bit functions. */
2887 unsigned two_byte_p
: 1;
2889 /* 1 means that the original font determined for drawing this glyph
2890 string could not be loaded. The member `font' has been set to
2891 the frame's default font in this case. */
2892 unsigned font_not_found_p
: 1;
2894 /* 1 means that the face in which this glyph string is drawn has a
2896 unsigned stippled_p
: 1;
2898 /* 1 means only the foreground of this glyph string must be drawn,
2899 and we should use the physical height of the line this glyph
2900 string appears in as clip rect. */
2901 unsigned for_overlaps_p
: 1;
2903 /* The GC to use for drawing this glyph string. */
2906 /* A pointer to the first glyph in the string. This glyph
2907 corresponds to char2b[0]. Needed to draw rectangles if
2908 font_not_found_p is 1. */
2909 struct glyph
*first_glyph
;
2911 /* Image, if any. */
2914 struct glyph_string
*next
, *prev
;
2921 x_dump_glyph_string (s
)
2922 struct glyph_string
*s
;
2924 fprintf (stderr
, "glyph string\n");
2925 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2926 s
->x
, s
->y
, s
->width
, s
->height
);
2927 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2928 fprintf (stderr
, " hl = %d\n", s
->hl
);
2929 fprintf (stderr
, " left overhang = %d, right = %d\n",
2930 s
->left_overhang
, s
->right_overhang
);
2931 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2932 fprintf (stderr
, " extends to end of line = %d\n",
2933 s
->extends_to_end_of_line_p
);
2934 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2935 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2938 #endif /* GLYPH_DEBUG */
2942 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2943 struct glyph_string
**,
2944 struct glyph_string
*,
2945 struct glyph_string
*));
2946 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2947 struct glyph_string
**,
2948 struct glyph_string
*,
2949 struct glyph_string
*));
2950 static void x_append_glyph_string
P_ ((struct glyph_string
**,
2951 struct glyph_string
**,
2952 struct glyph_string
*));
2953 static int x_left_overwritten
P_ ((struct glyph_string
*));
2954 static int x_left_overwriting
P_ ((struct glyph_string
*));
2955 static int x_right_overwritten
P_ ((struct glyph_string
*));
2956 static int x_right_overwriting
P_ ((struct glyph_string
*));
2957 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
2959 static void x_init_glyph_string
P_ ((struct glyph_string
*,
2960 XChar2b
*, struct window
*,
2962 enum glyph_row_area
, int,
2963 enum draw_glyphs_face
));
2964 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
2965 enum glyph_row_area
, int, int,
2966 enum draw_glyphs_face
, int));
2967 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2968 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2969 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2971 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2972 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2973 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2974 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2975 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2976 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2977 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2978 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2979 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
2981 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
2982 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
2983 unsigned long *, double, int));*/
2984 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2985 double, int, unsigned long));
2986 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2987 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2988 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2989 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2990 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2991 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
2992 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2994 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2995 int, int, int, int, Rect
*));
2996 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2997 int, int, int, Rect
*));
2998 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
2999 enum glyph_row_area
));
3000 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3002 enum glyph_row_area
, int, int));
3005 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3009 /* Append the list of glyph strings with head H and tail T to the list
3010 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3013 x_append_glyph_string_lists (head
, tail
, h
, t
)
3014 struct glyph_string
**head
, **tail
;
3015 struct glyph_string
*h
, *t
;
3029 /* Prepend the list of glyph strings with head H and tail T to the
3030 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3034 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3035 struct glyph_string
**head
, **tail
;
3036 struct glyph_string
*h
, *t
;
3050 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3051 Set *HEAD and *TAIL to the resulting list. */
3054 x_append_glyph_string (head
, tail
, s
)
3055 struct glyph_string
**head
, **tail
;
3056 struct glyph_string
*s
;
3058 s
->next
= s
->prev
= NULL
;
3059 x_append_glyph_string_lists (head
, tail
, s
, s
);
3063 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3068 struct glyph_string
*s
;
3070 if (s
->font
== FRAME_FONT (s
->f
)
3071 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3072 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3074 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3077 /* Cursor on non-default face: must merge. */
3081 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3082 xgcv
.foreground
= s
->face
->background
;
3084 /* If the glyph would be invisible, try a different foreground. */
3085 if (xgcv
.foreground
== xgcv
.background
)
3086 xgcv
.foreground
= s
->face
->foreground
;
3087 if (xgcv
.foreground
== xgcv
.background
)
3088 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3089 if (xgcv
.foreground
== xgcv
.background
)
3090 xgcv
.foreground
= s
->face
->foreground
;
3092 /* Make sure the cursor is distinct from text in this face. */
3093 if (xgcv
.background
== s
->face
->background
3094 && xgcv
.foreground
== s
->face
->foreground
)
3096 xgcv
.background
= s
->face
->foreground
;
3097 xgcv
.foreground
= s
->face
->background
;
3100 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3101 xgcv
.font
= s
->font
;
3102 mask
= GCForeground
| GCBackground
| GCFont
;
3104 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3105 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3108 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3109 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3111 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3116 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3119 x_set_mouse_face_gc (s
)
3120 struct glyph_string
*s
;
3125 /* What face has to be used last for the mouse face? */
3126 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3127 face
= FACE_FROM_ID (s
->f
, face_id
);
3129 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3131 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3132 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3134 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3135 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3136 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3138 /* If font in this face is same as S->font, use it. */
3139 if (s
->font
== s
->face
->font
)
3140 s
->gc
= s
->face
->gc
;
3143 /* Otherwise construct scratch_cursor_gc with values from FACE
3148 xgcv
.background
= s
->face
->background
;
3149 xgcv
.foreground
= s
->face
->foreground
;
3150 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3151 xgcv
.font
= s
->font
;
3152 mask
= GCForeground
| GCBackground
| GCFont
;
3154 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3155 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3158 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3159 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3161 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3164 xassert (s
->gc
!= 0);
3168 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3169 Faces to use in the mode line have already been computed when the
3170 matrix was built, so there isn't much to do, here. */
3173 x_set_mode_line_face_gc (s
)
3174 struct glyph_string
*s
;
3176 s
->gc
= s
->face
->gc
;
3180 /* Set S->gc of glyph string S for drawing that glyph string. Set
3181 S->stippled_p to a non-zero value if the face of S has a stipple
3185 x_set_glyph_string_gc (s
)
3186 struct glyph_string
*s
;
3188 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3190 if (s
->hl
== DRAW_NORMAL_TEXT
)
3192 s
->gc
= s
->face
->gc
;
3193 s
->stippled_p
= s
->face
->stipple
!= 0;
3195 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3197 x_set_mode_line_face_gc (s
);
3198 s
->stippled_p
= s
->face
->stipple
!= 0;
3200 else if (s
->hl
== DRAW_CURSOR
)
3202 x_set_cursor_gc (s
);
3205 else if (s
->hl
== DRAW_MOUSE_FACE
)
3207 x_set_mouse_face_gc (s
);
3208 s
->stippled_p
= s
->face
->stipple
!= 0;
3210 else if (s
->hl
== DRAW_IMAGE_RAISED
3211 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3213 s
->gc
= s
->face
->gc
;
3214 s
->stippled_p
= s
->face
->stipple
!= 0;
3218 s
->gc
= s
->face
->gc
;
3219 s
->stippled_p
= s
->face
->stipple
!= 0;
3222 /* GC must have been set. */
3223 xassert (s
->gc
!= 0);
3227 /* Return in *R the clipping rectangle for glyph string S. */
3230 x_get_glyph_string_clip_rect (s
, r
)
3231 struct glyph_string
*s
;
3234 int r_height
, r_width
;
3236 if (s
->row
->full_width_p
)
3238 /* Draw full-width. X coordinates are relative to S->w->left. */
3239 int canon_x
= CANON_X_UNIT (s
->f
);
3241 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3242 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3244 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3246 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3247 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3251 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3253 /* Unless displaying a mode or menu bar line, which are always
3254 fully visible, clip to the visible part of the row. */
3255 if (s
->w
->pseudo_window_p
)
3256 r_height
= s
->row
->visible_height
;
3258 r_height
= s
->height
;
3262 /* This is a text line that may be partially visible. */
3263 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3264 r_width
= window_box_width (s
->w
, s
->area
);
3265 r_height
= s
->row
->visible_height
;
3268 /* If S draws overlapping rows, it's sufficient to use the top and
3269 bottom of the window for clipping because this glyph string
3270 intentionally draws over other lines. */
3271 if (s
->for_overlaps_p
)
3273 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3274 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3278 /* Don't use S->y for clipping because it doesn't take partially
3279 visible lines into account. For example, it can be negative for
3280 partially visible lines at the top of a window. */
3281 if (!s
->row
->full_width_p
3282 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3283 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3285 r
->top
= max (0, s
->row
->y
);
3287 /* If drawing a tool-bar window, draw it over the internal border
3288 at the top of the window. */
3289 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3290 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3293 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3295 r
->bottom
= r
->top
+ r_height
;
3296 r
->right
= r
->left
+ r_width
;
3300 /* Set clipping for output of glyph string S. S may be part of a mode
3301 line or menu if we don't have X toolkit support. */
3304 x_set_glyph_string_clipping (s
)
3305 struct glyph_string
*s
;
3308 x_get_glyph_string_clip_rect (s
, &r
);
3309 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3313 /* Compute left and right overhang of glyph string S. If S is a glyph
3314 string for a composition, assume overhangs don't exist. */
3317 x_compute_glyph_string_overhangs (s
)
3318 struct glyph_string
*s
;
3321 && s
->first_glyph
->type
== CHAR_GLYPH
)
3324 int direction
, font_ascent
, font_descent
;
3325 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3326 &font_ascent
, &font_descent
, &cs
);
3327 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3328 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3333 /* Compute overhangs and x-positions for glyph string S and its
3334 predecessors, or successors. X is the starting x-position for S.
3335 BACKWARD_P non-zero means process predecessors. */
3338 x_compute_overhangs_and_x (s
, x
, backward_p
)
3339 struct glyph_string
*s
;
3347 x_compute_glyph_string_overhangs (s
);
3357 x_compute_glyph_string_overhangs (s
);
3366 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3367 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3368 assumed to be zero. */
3371 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3372 struct glyph
*glyph
;
3378 if (glyph
->type
== CHAR_GLYPH
)
3382 struct font_info
*font_info
;
3386 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3388 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3390 && (pcm
= x_per_char_metric (font
, &char2b
)))
3392 if (pcm
->rbearing
> pcm
->width
)
3393 *right
= pcm
->rbearing
- pcm
->width
;
3394 if (pcm
->lbearing
< 0)
3395 *left
= -pcm
->lbearing
;
3401 /* Return the index of the first glyph preceding glyph string S that
3402 is overwritten by S because of S's left overhang. Value is -1
3403 if no glyphs are overwritten. */
3406 x_left_overwritten (s
)
3407 struct glyph_string
*s
;
3411 if (s
->left_overhang
)
3414 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3415 int first
= s
->first_glyph
- glyphs
;
3417 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3418 x
-= glyphs
[i
].pixel_width
;
3429 /* Return the index of the first glyph preceding glyph string S that
3430 is overwriting S because of its right overhang. Value is -1 if no
3431 glyph in front of S overwrites S. */
3434 x_left_overwriting (s
)
3435 struct glyph_string
*s
;
3438 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3439 int first
= s
->first_glyph
- glyphs
;
3443 for (i
= first
- 1; i
>= 0; --i
)
3446 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3449 x
-= glyphs
[i
].pixel_width
;
3456 /* Return the index of the last glyph following glyph string S that is
3457 not overwritten by S because of S's right overhang. Value is -1 if
3458 no such glyph is found. */
3461 x_right_overwritten (s
)
3462 struct glyph_string
*s
;
3466 if (s
->right_overhang
)
3469 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3470 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3471 int end
= s
->row
->used
[s
->area
];
3473 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3474 x
+= glyphs
[i
].pixel_width
;
3483 /* Return the index of the last glyph following glyph string S that
3484 overwrites S because of its left overhang. Value is negative
3485 if no such glyph is found. */
3488 x_right_overwriting (s
)
3489 struct glyph_string
*s
;
3492 int end
= s
->row
->used
[s
->area
];
3493 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3494 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3498 for (i
= first
; i
< end
; ++i
)
3501 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3504 x
+= glyphs
[i
].pixel_width
;
3511 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3514 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3515 struct glyph_string
*s
;
3520 xgcv
.foreground
= s
->gc
->background
;
3521 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3525 /* Draw the background of glyph_string S. If S->background_filled_p
3526 is non-zero don't draw it. FORCE_P non-zero means draw the
3527 background even if it wouldn't be drawn normally. This is used
3528 when a string preceding S draws into the background of S, or S
3529 contains the first component of a composition. */
3532 x_draw_glyph_string_background (s
, force_p
)
3533 struct glyph_string
*s
;
3536 /* Nothing to do if background has already been drawn or if it
3537 shouldn't be drawn in the first place. */
3538 if (!s
->background_filled_p
)
3540 int box_line_width
= max (s
->face
->box_line_width
, 0);
3542 #if 0 /* MAC_TODO: stipple */
3545 /* Fill background with a stipple pattern. */
3546 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3547 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3548 s
->y
+ box_line_width
,
3549 s
->background_width
,
3550 s
->height
- 2 * box_line_width
);
3551 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3552 s
->background_filled_p
= 1;
3556 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3557 || s
->font_not_found_p
3558 || s
->extends_to_end_of_line_p
3561 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3562 s
->background_width
,
3563 s
->height
- 2 * box_line_width
);
3564 s
->background_filled_p
= 1;
3570 /* Draw the foreground of glyph string S. */
3573 x_draw_glyph_string_foreground (s
)
3574 struct glyph_string
*s
;
3578 /* If first glyph of S has a left box line, start drawing the text
3579 of S to the right of that box line. */
3580 if (s
->face
->box
!= FACE_NO_BOX
3581 && s
->first_glyph
->left_box_line_p
)
3582 x
= s
->x
+ abs (s
->face
->box_line_width
);
3586 /* Draw characters of S as rectangles if S's font could not be
3588 if (s
->font_not_found_p
)
3590 for (i
= 0; i
< s
->nchars
; ++i
)
3592 struct glyph
*g
= s
->first_glyph
+ i
;
3593 mac_draw_rectangle (s
->display
, s
->window
,
3594 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3596 x
+= g
->pixel_width
;
3601 char *char1b
= (char *) s
->char2b
;
3602 int boff
= s
->font_info
->baseline_offset
;
3604 if (s
->font_info
->vertical_centering
)
3605 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3607 /* If we can use 8-bit functions, condense S->char2b. */
3609 for (i
= 0; i
< s
->nchars
; ++i
)
3610 char1b
[i
] = s
->char2b
[i
].byte2
;
3612 /* Draw text with XDrawString if background has already been
3613 filled. Otherwise, use XDrawImageString. (Note that
3614 XDrawImageString is usually faster than XDrawString.) Always
3615 use XDrawImageString when drawing the cursor so that there is
3616 no chance that characters under a box cursor are invisible. */
3617 if (s
->for_overlaps_p
3618 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3620 /* Draw characters with 16-bit or 8-bit functions. */
3622 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3623 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3625 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3626 s
->ybase
- boff
, char1b
, s
->nchars
);
3631 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3632 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3634 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3635 s
->ybase
- boff
, char1b
, s
->nchars
);
3640 /* Draw the foreground of composite glyph string S. */
3643 x_draw_composite_glyph_string_foreground (s
)
3644 struct glyph_string
*s
;
3648 /* If first glyph of S has a left box line, start drawing the text
3649 of S to the right of that box line. */
3650 if (s
->face
->box
!= FACE_NO_BOX
3651 && s
->first_glyph
->left_box_line_p
)
3652 x
= s
->x
+ abs (s
->face
->box_line_width
);
3656 /* S is a glyph string for a composition. S->gidx is the index of
3657 the first character drawn for glyphs of this composition.
3658 S->gidx == 0 means we are drawing the very first character of
3659 this composition. */
3661 /* Draw a rectangle for the composition if the font for the very
3662 first character of the composition could not be loaded. */
3663 if (s
->font_not_found_p
)
3666 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3667 s
->width
- 1, s
->height
- 1);
3671 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3672 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3673 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3674 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3680 #ifdef USE_X_TOOLKIT
3682 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3685 /* Return the frame on which widget WIDGET is used.. Abort if frame
3686 cannot be determined. */
3688 static struct frame
*
3689 x_frame_of_widget (widget
)
3692 struct x_display_info
*dpyinfo
;
3696 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3698 /* Find the top-level shell of the widget. Note that this function
3699 can be called when the widget is not yet realized, so XtWindow
3700 (widget) == 0. That's the reason we can't simply use
3701 x_any_window_to_frame. */
3702 while (!XtIsTopLevelShell (widget
))
3703 widget
= XtParent (widget
);
3705 /* Look for a frame with that top-level widget. Allocate the color
3706 on that frame to get the right gamma correction value. */
3707 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3708 if (GC_FRAMEP (XCAR (tail
))
3709 && (f
= XFRAME (XCAR (tail
)),
3710 (f
->output_data
.nothing
!= 1
3711 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3712 && f
->output_data
.x
->widget
== widget
)
3719 /* Allocate the color COLOR->pixel on the screen and display of
3720 widget WIDGET in colormap CMAP. If an exact match cannot be
3721 allocated, try the nearest color available. Value is non-zero
3722 if successful. This is called from lwlib. */
3725 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3730 struct frame
*f
= x_frame_of_widget (widget
);
3731 return x_alloc_nearest_color (f
, cmap
, color
);
3735 #endif /* USE_X_TOOLKIT */
3737 #if 0 /* MAC_TODO */
3739 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3740 CMAP. If an exact match can't be allocated, try the nearest color
3741 available. Value is non-zero if successful. Set *COLOR to the
3745 x_alloc_nearest_color (f
, cmap
, color
)
3750 Display
*display
= FRAME_X_DISPLAY (f
);
3751 Screen
*screen
= FRAME_X_SCREEN (f
);
3754 gamma_correct (f
, color
);
3755 rc
= XAllocColor (display
, cmap
, color
);
3758 /* If we got to this point, the colormap is full, so we're going
3759 to try to get the next closest color. The algorithm used is
3760 a least-squares matching, which is what X uses for closest
3761 color matching with StaticColor visuals. */
3763 unsigned long nearest_delta
= ~0;
3764 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3765 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3767 for (i
= 0; i
< ncells
; ++i
)
3769 XQueryColors (display
, cmap
, cells
, ncells
);
3771 for (nearest
= i
= 0; i
< ncells
; ++i
)
3773 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3774 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3775 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3776 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3778 if (delta
< nearest_delta
)
3781 nearest_delta
= delta
;
3785 color
->red
= cells
[nearest
].red
;
3786 color
->green
= cells
[nearest
].green
;
3787 color
->blue
= cells
[nearest
].blue
;
3788 rc
= XAllocColor (display
, cmap
, color
);
3791 #ifdef DEBUG_X_COLORS
3793 register_color (color
->pixel
);
3794 #endif /* DEBUG_X_COLORS */
3800 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3801 It's necessary to do this instead of just using PIXEL directly to
3802 get color reference counts right. */
3805 x_copy_color (f
, pixel
)
3807 unsigned long pixel
;
3811 color
.pixel
= pixel
;
3813 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3814 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3816 #ifdef DEBUG_X_COLORS
3817 register_color (pixel
);
3823 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3824 It's necessary to do this instead of just using PIXEL directly to
3825 get color reference counts right. */
3828 x_copy_dpy_color (dpy
, cmap
, pixel
)
3831 unsigned long pixel
;
3835 color
.pixel
= pixel
;
3837 XQueryColor (dpy
, cmap
, &color
);
3838 XAllocColor (dpy
, cmap
, &color
);
3840 #ifdef DEBUG_X_COLORS
3841 register_color (pixel
);
3846 #endif /* MAC_TODO */
3848 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3849 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3850 If this produces the same color as COLOR, try a color where all RGB
3851 values have DELTA added. Return the allocated color in *COLOR.
3852 DISPLAY is the X display, CMAP is the colormap to operate on.
3853 Value is non-zero if successful. */
3856 mac_alloc_lighter_color (f
, color
, factor
, delta
)
3858 unsigned long *color
;
3864 /* Change RGB values by specified FACTOR. Avoid overflow! */
3865 xassert (factor
>= 0);
3866 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
3867 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
3868 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
3870 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
3871 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
3872 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
3874 /* MAC_TODO: Map to palette and retry with delta if same? */
3875 /* MAC_TODO: Free colors (if using palette)? */
3886 /* Set up the foreground color for drawing relief lines of glyph
3887 string S. RELIEF is a pointer to a struct relief containing the GC
3888 with which lines will be drawn. Use a color that is FACTOR or
3889 DELTA lighter or darker than the relief's background which is found
3890 in S->f->output_data.x->relief_background. If such a color cannot
3891 be allocated, use DEFAULT_PIXEL, instead. */
3894 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3896 struct relief
*relief
;
3899 unsigned long default_pixel
;
3902 struct mac_output
*di
= f
->output_data
.mac
;
3903 unsigned long mask
= GCForeground
;
3904 unsigned long pixel
;
3905 unsigned long background
= di
->relief_background
;
3906 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
3908 /* MAC_TODO: Free colors (if using palette)? */
3910 /* Allocate new color. */
3911 xgcv
.foreground
= default_pixel
;
3913 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3915 relief
->allocated_p
= 1;
3916 xgcv
.foreground
= relief
->pixel
= pixel
;
3919 if (relief
->gc
== 0)
3921 #if 0 /* MAC_TODO: stipple */
3922 xgcv
.stipple
= dpyinfo
->gray
;
3925 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
3928 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3932 /* Set up colors for the relief lines around glyph string S. */
3935 x_setup_relief_colors (s
)
3936 struct glyph_string
*s
;
3938 struct mac_output
*di
= s
->f
->output_data
.mac
;
3939 unsigned long color
;
3941 if (s
->face
->use_box_color_for_shadows_p
)
3942 color
= s
->face
->box_color
;
3947 /* Get the background color of the face. */
3948 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3949 color
= xgcv
.background
;
3952 if (di
->white_relief
.gc
== 0
3953 || color
!= di
->relief_background
)
3955 di
->relief_background
= color
;
3956 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3957 WHITE_PIX_DEFAULT (s
->f
));
3958 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3959 BLACK_PIX_DEFAULT (s
->f
));
3964 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3965 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3966 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3967 relief. LEFT_P non-zero means draw a relief on the left side of
3968 the rectangle. RIGHT_P non-zero means draw a relief on the right
3969 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3973 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3974 raised_p
, left_p
, right_p
, clip_rect
)
3976 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
3983 gc
= f
->output_data
.mac
->white_relief
.gc
;
3985 gc
= f
->output_data
.mac
->black_relief
.gc
;
3986 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
3989 for (i
= 0; i
< width
; ++i
)
3990 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
3991 left_x
+ i
* left_p
, top_y
+ i
,
3992 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3996 for (i
= 0; i
< width
; ++i
)
3997 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
3998 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4000 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4002 gc
= f
->output_data
.mac
->black_relief
.gc
;
4004 gc
= f
->output_data
.mac
->white_relief
.gc
;
4005 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4009 for (i
= 0; i
< width
; ++i
)
4010 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4011 left_x
+ i
* left_p
, bottom_y
- i
,
4012 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4016 for (i
= 0; i
< width
; ++i
)
4017 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4018 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4020 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4024 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4025 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4026 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4027 left side of the rectangle. RIGHT_P non-zero means draw a line
4028 on the right side of the rectangle. CLIP_RECT is the clipping
4029 rectangle to use when drawing. */
4032 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4033 left_p
, right_p
, clip_rect
)
4034 struct glyph_string
*s
;
4035 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4040 xgcv
.foreground
= s
->face
->box_color
;
4041 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4044 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4045 left_x
, top_y
, right_x
- left_x
, width
);
4049 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4050 left_x
, top_y
, width
, bottom_y
- top_y
);
4053 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4054 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4058 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4059 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4061 mac_reset_clipping (s
->display
, s
->window
);
4065 /* Draw a box around glyph string S. */
4068 x_draw_glyph_string_box (s
)
4069 struct glyph_string
*s
;
4071 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4072 int left_p
, right_p
;
4073 struct glyph
*last_glyph
;
4076 last_x
= window_box_right (s
->w
, s
->area
);
4077 if (s
->row
->full_width_p
4078 && !s
->w
->pseudo_window_p
)
4080 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4081 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4082 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4085 /* The glyph that may have a right box line. */
4086 last_glyph
= (s
->cmp
|| s
->img
4088 : s
->first_glyph
+ s
->nchars
- 1);
4090 width
= abs (s
->face
->box_line_width
);
4091 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4093 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4095 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4097 bottom_y
= top_y
+ s
->height
- 1;
4099 left_p
= (s
->first_glyph
->left_box_line_p
4100 || (s
->hl
== DRAW_MOUSE_FACE
4102 || s
->prev
->hl
!= s
->hl
)));
4103 right_p
= (last_glyph
->right_box_line_p
4104 || (s
->hl
== DRAW_MOUSE_FACE
4106 || s
->next
->hl
!= s
->hl
)));
4108 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4110 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4111 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4112 left_p
, right_p
, &clip_rect
);
4115 x_setup_relief_colors (s
);
4116 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4117 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4122 /* Draw foreground of image glyph string S. */
4125 x_draw_image_foreground (s
)
4126 struct glyph_string
*s
;
4129 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4131 /* If first glyph of S has a left box line, start drawing it to the
4132 right of that line. */
4133 if (s
->face
->box
!= FACE_NO_BOX
4134 && s
->first_glyph
->left_box_line_p
)
4135 x
= s
->x
+ abs (s
->face
->box_line_width
);
4139 /* If there is a margin around the image, adjust x- and y-position
4141 x
+= s
->img
->hmargin
;
4142 y
+= s
->img
->vmargin
;
4146 #if 0 /* MAC_TODO: image mask */
4149 /* We can't set both a clip mask and use XSetClipRectangles
4150 because the latter also sets a clip mask. We also can't
4151 trust on the shape extension to be available
4152 (XShapeCombineRegion). So, compute the rectangle to draw
4154 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4157 XRectangle clip_rect
, image_rect
, r
;
4159 xgcv
.clip_mask
= s
->img
->mask
;
4160 xgcv
.clip_x_origin
= x
;
4161 xgcv
.clip_y_origin
= y
;
4162 xgcv
.function
= GXcopy
;
4163 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4165 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4168 image_rect
.width
= s
->img
->width
;
4169 image_rect
.height
= s
->img
->height
;
4170 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4171 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4172 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4175 #endif /* MAC_TODO */
4177 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4178 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4180 /* When the image has a mask, we can expect that at
4181 least part of a mouse highlight or a block cursor will
4182 be visible. If the image doesn't have a mask, make
4183 a block cursor visible by drawing a rectangle around
4184 the image. I believe it's looking better if we do
4185 nothing here for mouse-face. */
4186 if (s
->hl
== DRAW_CURSOR
)
4188 int r
= s
->img
->relief
;
4190 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4191 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4196 /* Draw a rectangle if image could not be loaded. */
4197 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4198 s
->img
->width
- 1, s
->img
->height
- 1);
4203 /* Draw a relief around the image glyph string S. */
4206 x_draw_image_relief (s
)
4207 struct glyph_string
*s
;
4209 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4212 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4214 /* If first glyph of S has a left box line, start drawing it to the
4215 right of that line. */
4216 if (s
->face
->box
!= FACE_NO_BOX
4217 && s
->first_glyph
->left_box_line_p
)
4218 x
= s
->x
+ abs (s
->face
->box_line_width
);
4222 /* If there is a margin around the image, adjust x- and y-position
4224 x
+= s
->img
->hmargin
;
4225 y
+= s
->img
->vmargin
;
4227 if (s
->hl
== DRAW_IMAGE_SUNKEN
4228 || s
->hl
== DRAW_IMAGE_RAISED
)
4230 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4231 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4235 thick
= abs (s
->img
->relief
);
4236 raised_p
= s
->img
->relief
> 0;
4241 x1
= x
+ s
->img
->width
+ thick
- 1;
4242 y1
= y
+ s
->img
->height
+ thick
- 1;
4244 x_setup_relief_colors (s
);
4245 x_get_glyph_string_clip_rect (s
, &r
);
4246 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4250 /* Draw the foreground of image glyph string S to PIXMAP. */
4253 x_draw_image_foreground_1 (s
, pixmap
)
4254 struct glyph_string
*s
;
4258 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4260 /* If first glyph of S has a left box line, start drawing it to the
4261 right of that line. */
4262 if (s
->face
->box
!= FACE_NO_BOX
4263 && s
->first_glyph
->left_box_line_p
)
4264 x
= abs (s
->face
->box_line_width
);
4268 /* If there is a margin around the image, adjust x- and y-position
4270 x
+= s
->img
->hmargin
;
4271 y
+= s
->img
->vmargin
;
4275 #if 0 /* MAC_TODO: image mask */
4278 /* We can't set both a clip mask and use XSetClipRectangles
4279 because the latter also sets a clip mask. We also can't
4280 trust on the shape extension to be available
4281 (XShapeCombineRegion). So, compute the rectangle to draw
4283 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4287 xgcv
.clip_mask
= s
->img
->mask
;
4288 xgcv
.clip_x_origin
= x
;
4289 xgcv
.clip_y_origin
= y
;
4290 xgcv
.function
= GXcopy
;
4291 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4293 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4294 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4295 XSetClipMask (s
->display
, s
->gc
, None
);
4298 #endif /* MAC_TODO */
4300 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4301 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4303 /* When the image has a mask, we can expect that at
4304 least part of a mouse highlight or a block cursor will
4305 be visible. If the image doesn't have a mask, make
4306 a block cursor visible by drawing a rectangle around
4307 the image. I believe it's looking better if we do
4308 nothing here for mouse-face. */
4309 if (s
->hl
== DRAW_CURSOR
)
4311 int r
= s
->img
->relief
;
4313 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
4314 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4319 /* Draw a rectangle if image could not be loaded. */
4320 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4321 s
->img
->width
- 1, s
->img
->height
- 1);
4325 /* Draw part of the background of glyph string S. X, Y, W, and H
4326 give the rectangle to draw. */
4329 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4330 struct glyph_string
*s
;
4333 #if 0 /* MAC_TODO: stipple */
4336 /* Fill background with a stipple pattern. */
4337 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4338 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4339 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4342 #endif /* MAC_TODO */
4343 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4347 /* Draw image glyph string S.
4350 s->x +-------------------------
4353 | +-------------------------
4356 | | +-------------------
4362 x_draw_image_glyph_string (s
)
4363 struct glyph_string
*s
;
4366 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4367 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4371 height
= s
->height
- 2 * box_line_vwidth
;
4373 /* Fill background with face under the image. Do it only if row is
4374 taller than image or if image has a clip mask to reduce
4376 s
->stippled_p
= s
->face
->stipple
!= 0;
4377 if (height
> s
->img
->height
4380 #if 0 /* TODO: image mask */
4383 || s
->img
->pixmap
== 0
4384 || s
->width
!= s
->background_width
)
4386 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4387 x
= s
->x
+ box_line_hwidth
;
4391 y
= s
->y
+ box_line_vwidth
;
4392 #if 0 /* TODO: image mask */
4395 /* Create a pixmap as large as the glyph string. Fill it
4396 with the background color. Copy the image to it, using
4397 its mask. Copy the temporary pixmap to the display. */
4398 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4399 int depth
= DefaultDepthOfScreen (screen
);
4401 /* Create a pixmap as large as the glyph string. */
4402 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4403 s
->background_width
,
4406 /* Don't clip in the following because we're working on the
4408 XSetClipMask (s
->display
, s
->gc
, None
);
4410 /* Fill the pixmap with the background color/stipple. */
4413 /* Fill background with a stipple pattern. */
4414 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4415 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4416 0, 0, s
->background_width
, s
->height
);
4417 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4422 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4424 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4425 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4426 0, 0, s
->background_width
, s
->height
);
4427 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4432 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4434 s
->background_filled_p
= 1;
4437 /* Draw the foreground. */
4440 x_draw_image_foreground_1 (s
, pixmap
);
4441 x_set_glyph_string_clipping (s
);
4442 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4443 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4444 mac_reset_clipping (s
->display
, s
->window
);
4445 XFreePixmap (s
->display
, pixmap
);
4448 x_draw_image_foreground (s
);
4450 /* If we must draw a relief around the image, do it. */
4452 || s
->hl
== DRAW_IMAGE_RAISED
4453 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4454 x_draw_image_relief (s
);
4458 /* Draw stretch glyph string S. */
4461 x_draw_stretch_glyph_string (s
)
4462 struct glyph_string
*s
;
4464 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4465 s
->stippled_p
= s
->face
->stipple
!= 0;
4467 if (s
->hl
== DRAW_CURSOR
4468 && !x_stretch_cursor_p
)
4470 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4471 as wide as the stretch glyph. */
4472 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4475 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4477 /* Clear rest using the GC of the original non-cursor face. */
4478 if (width
< s
->background_width
)
4480 GC gc
= s
->face
->gc
;
4481 int x
= s
->x
+ width
, y
= s
->y
;
4482 int w
= s
->background_width
- width
, h
= s
->height
;
4485 if (s
->row
->mouse_face_p
4486 && cursor_in_mouse_face_p (s
->w
))
4488 x_set_mouse_face_gc (s
);
4494 x_get_glyph_string_clip_rect (s
, &r
);
4495 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4497 #if 0 /* MAC_TODO: stipple */
4498 if (s
->face
->stipple
)
4500 /* Fill background with a stipple pattern. */
4501 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4502 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4503 XSetFillStyle (s
->display
, gc
, FillSolid
);
4506 #endif /* MAC_TODO */
4509 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4510 XSetForeground (s
->display
, gc
, xgcv
.background
);
4511 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4512 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4515 mac_reset_clipping (s
->display
, s
->window
);
4518 else if (!s
->background_filled_p
)
4519 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4522 s
->background_filled_p
= 1;
4526 /* Draw glyph string S. */
4529 x_draw_glyph_string (s
)
4530 struct glyph_string
*s
;
4532 int relief_drawn_p
= 0;
4534 /* If S draws into the background of its successor, draw the
4535 background of the successor first so that S can draw into it.
4536 This makes S->next use XDrawString instead of XDrawImageString. */
4537 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4539 xassert (s
->next
->img
== NULL
);
4540 x_set_glyph_string_gc (s
->next
);
4541 x_set_glyph_string_clipping (s
->next
);
4542 x_draw_glyph_string_background (s
->next
, 1);
4546 /* Set up S->gc, set clipping and draw S. */
4547 x_set_glyph_string_gc (s
);
4549 /* Draw relief (if any) in advance for char/composition so that the
4550 glyph string can be drawn over it. */
4551 if (!s
->for_overlaps_p
4552 && s
->face
->box
!= FACE_NO_BOX
4553 && (s
->first_glyph
->type
== CHAR_GLYPH
4554 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4557 x_set_glyph_string_clipping (s
);
4558 x_draw_glyph_string_background (s
, 1);
4559 x_draw_glyph_string_box (s
);
4560 x_set_glyph_string_clipping (s
);
4564 x_set_glyph_string_clipping (s
);
4566 switch (s
->first_glyph
->type
)
4569 x_draw_image_glyph_string (s
);
4573 x_draw_stretch_glyph_string (s
);
4577 if (s
->for_overlaps_p
)
4578 s
->background_filled_p
= 1;
4580 x_draw_glyph_string_background (s
, 0);
4581 x_draw_glyph_string_foreground (s
);
4584 case COMPOSITE_GLYPH
:
4585 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4586 s
->background_filled_p
= 1;
4588 x_draw_glyph_string_background (s
, 1);
4589 x_draw_composite_glyph_string_foreground (s
);
4596 if (!s
->for_overlaps_p
)
4598 /* Draw underline. */
4599 if (s
->face
->underline_p
)
4601 unsigned long h
= 1;
4602 unsigned long dy
= s
->height
- h
;
4604 if (s
->face
->underline_defaulted_p
)
4605 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4610 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4611 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4612 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4614 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4618 /* Draw overline. */
4619 if (s
->face
->overline_p
)
4621 unsigned long dy
= 0, h
= 1;
4623 if (s
->face
->overline_color_defaulted_p
)
4624 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4629 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4630 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4631 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4633 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4637 /* Draw strike-through. */
4638 if (s
->face
->strike_through_p
)
4640 unsigned long h
= 1;
4641 unsigned long dy
= (s
->height
- h
) / 2;
4643 if (s
->face
->strike_through_color_defaulted_p
)
4644 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4649 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4650 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4651 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4653 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4658 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4659 x_draw_glyph_string_box (s
);
4662 /* Reset clipping. */
4663 mac_reset_clipping (s
->display
, s
->window
);
4667 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4668 struct face
**, int));
4671 /* Fill glyph string S with composition components specified by S->cmp.
4673 FACES is an array of faces for all components of this composition.
4674 S->gidx is the index of the first component for S.
4675 OVERLAPS_P non-zero means S should draw the foreground only, and
4676 use its physical height for clipping.
4678 Value is the index of a component not in S. */
4681 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4682 struct glyph_string
*s
;
4683 struct face
**faces
;
4690 s
->for_overlaps_p
= overlaps_p
;
4692 s
->face
= faces
[s
->gidx
];
4693 s
->font
= s
->face
->font
;
4694 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4696 /* For all glyphs of this composition, starting at the offset
4697 S->gidx, until we reach the end of the definition or encounter a
4698 glyph that requires the different face, add it to S. */
4700 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4703 /* All glyph strings for the same composition has the same width,
4704 i.e. the width set for the first component of the composition. */
4706 s
->width
= s
->first_glyph
->pixel_width
;
4708 /* If the specified font could not be loaded, use the frame's
4709 default font, but record the fact that we couldn't load it in
4710 the glyph string so that we can draw rectangles for the
4711 characters of the glyph string. */
4712 if (s
->font
== NULL
)
4714 s
->font_not_found_p
= 1;
4715 s
->font
= FRAME_FONT (s
->f
);
4718 /* Adjust base line for subscript/superscript text. */
4719 s
->ybase
+= s
->first_glyph
->voffset
;
4721 xassert (s
->face
&& s
->face
->gc
);
4723 /* This glyph string must always be drawn with 16-bit functions. */
4726 return s
->gidx
+ s
->nchars
;
4730 /* Fill glyph string S from a sequence of character glyphs.
4732 FACE_ID is the face id of the string. START is the index of the
4733 first glyph to consider, END is the index of the last + 1.
4734 OVERLAPS_P non-zero means S should draw the foreground only, and
4735 use its physical height for clipping.
4737 Value is the index of the first glyph not in S. */
4740 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4741 struct glyph_string
*s
;
4743 int start
, end
, overlaps_p
;
4745 struct glyph
*glyph
, *last
;
4747 int glyph_not_available_p
;
4749 xassert (s
->f
== XFRAME (s
->w
->frame
));
4750 xassert (s
->nchars
== 0);
4751 xassert (start
>= 0 && end
> start
);
4753 s
->for_overlaps_p
= overlaps_p
;
4754 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4755 last
= s
->row
->glyphs
[s
->area
] + end
;
4756 voffset
= glyph
->voffset
;
4758 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4761 && glyph
->type
== CHAR_GLYPH
4762 && glyph
->voffset
== voffset
4763 /* Same face id implies same font, nowadays. */
4764 && glyph
->face_id
== face_id
4765 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4769 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4770 s
->char2b
+ s
->nchars
,
4772 s
->two_byte_p
= two_byte_p
;
4774 xassert (s
->nchars
<= end
- start
);
4775 s
->width
+= glyph
->pixel_width
;
4779 s
->font
= s
->face
->font
;
4780 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4782 /* If the specified font could not be loaded, use the frame's font,
4783 but record the fact that we couldn't load it in
4784 S->font_not_found_p so that we can draw rectangles for the
4785 characters of the glyph string. */
4786 if (s
->font
== NULL
|| glyph_not_available_p
)
4788 s
->font_not_found_p
= 1;
4789 s
->font
= FRAME_FONT (s
->f
);
4792 /* Adjust base line for subscript/superscript text. */
4793 s
->ybase
+= voffset
;
4795 xassert (s
->face
&& s
->face
->gc
);
4796 return glyph
- s
->row
->glyphs
[s
->area
];
4800 /* Fill glyph string S from image glyph S->first_glyph. */
4803 x_fill_image_glyph_string (s
)
4804 struct glyph_string
*s
;
4806 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4807 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4809 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4810 s
->font
= s
->face
->font
;
4811 s
->width
= s
->first_glyph
->pixel_width
;
4813 /* Adjust base line for subscript/superscript text. */
4814 s
->ybase
+= s
->first_glyph
->voffset
;
4818 /* Fill glyph string S from a sequence of stretch glyphs.
4820 ROW is the glyph row in which the glyphs are found, AREA is the
4821 area within the row. START is the index of the first glyph to
4822 consider, END is the index of the last + 1.
4824 Value is the index of the first glyph not in S. */
4827 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4828 struct glyph_string
*s
;
4829 struct glyph_row
*row
;
4830 enum glyph_row_area area
;
4833 struct glyph
*glyph
, *last
;
4834 int voffset
, face_id
;
4836 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4838 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4839 last
= s
->row
->glyphs
[s
->area
] + end
;
4840 face_id
= glyph
->face_id
;
4841 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4842 s
->font
= s
->face
->font
;
4843 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4844 s
->width
= glyph
->pixel_width
;
4845 voffset
= glyph
->voffset
;
4849 && glyph
->type
== STRETCH_GLYPH
4850 && glyph
->voffset
== voffset
4851 && glyph
->face_id
== face_id
);
4853 s
->width
+= glyph
->pixel_width
;
4855 /* Adjust base line for subscript/superscript text. */
4856 s
->ybase
+= voffset
;
4859 return glyph
- s
->row
->glyphs
[s
->area
];
4863 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4864 of XChar2b structures for S; it can't be allocated in
4865 x_init_glyph_string because it must be allocated via `alloca'. W
4866 is the window on which S is drawn. ROW and AREA are the glyph row
4867 and area within the row from which S is constructed. START is the
4868 index of the first glyph structure covered by S. HL is a
4869 face-override for drawing S. */
4872 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4873 struct glyph_string
*s
;
4876 struct glyph_row
*row
;
4877 enum glyph_row_area area
;
4879 enum draw_glyphs_face hl
;
4881 bzero (s
, sizeof *s
);
4883 s
->f
= XFRAME (w
->frame
);
4884 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
4885 s
->window
= FRAME_MAC_WINDOW (s
->f
);
4890 s
->first_glyph
= row
->glyphs
[area
] + start
;
4891 s
->height
= row
->height
;
4892 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4894 /* Display the internal border below the tool-bar window. */
4895 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4896 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
4898 s
->ybase
= s
->y
+ row
->ascent
;
4902 /* Set background width of glyph string S. START is the index of the
4903 first glyph following S. LAST_X is the right-most x-position + 1
4904 in the drawing area. */
4907 x_set_glyph_string_background_width (s
, start
, last_x
)
4908 struct glyph_string
*s
;
4912 /* If the face of this glyph string has to be drawn to the end of
4913 the drawing area, set S->extends_to_end_of_line_p. */
4914 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4916 if (start
== s
->row
->used
[s
->area
]
4917 && s
->area
== TEXT_AREA
4918 && ((s
->hl
== DRAW_NORMAL_TEXT
4919 && (s
->row
->fill_line_p
4920 || s
->face
->background
!= default_face
->background
4921 || s
->face
->stipple
!= default_face
->stipple
4922 || s
->row
->mouse_face_p
))
4923 || s
->hl
== DRAW_MOUSE_FACE
4924 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
4925 && s
->row
->fill_line_p
)))
4926 s
->extends_to_end_of_line_p
= 1;
4928 /* If S extends its face to the end of the line, set its
4929 background_width to the distance to the right edge of the drawing
4931 if (s
->extends_to_end_of_line_p
)
4932 s
->background_width
= last_x
- s
->x
+ 1;
4934 s
->background_width
= s
->width
;
4938 /* Add a glyph string for a stretch glyph to the list of strings
4939 between HEAD and TAIL. START is the index of the stretch glyph in
4940 row area AREA of glyph row ROW. END is the index of the last glyph
4941 in that glyph row area. X is the current output position assigned
4942 to the new glyph string constructed. HL overrides that face of the
4943 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4944 is the right-most x-position of the drawing area. */
4946 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4947 and below -- keep them on one line. */
4948 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4951 s = (struct glyph_string *) alloca (sizeof *s); \
4952 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4953 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4954 x_append_glyph_string (&HEAD, &TAIL, s); \
4960 /* Add a glyph string for an image glyph to the list of strings
4961 between HEAD and TAIL. START is the index of the image glyph in
4962 row area AREA of glyph row ROW. END is the index of the last glyph
4963 in that glyph row area. X is the current output position assigned
4964 to the new glyph string constructed. HL overrides that face of the
4965 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4966 is the right-most x-position of the drawing area. */
4968 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4971 s = (struct glyph_string *) alloca (sizeof *s); \
4972 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4973 x_fill_image_glyph_string (s); \
4974 x_append_glyph_string (&HEAD, &TAIL, s); \
4981 /* Add a glyph string for a sequence of character glyphs to the list
4982 of strings between HEAD and TAIL. START is the index of the first
4983 glyph in row area AREA of glyph row ROW that is part of the new
4984 glyph string. END is the index of the last glyph in that glyph row
4985 area. X is the current output position assigned to the new glyph
4986 string constructed. HL overrides that face of the glyph; e.g. it
4987 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4988 right-most x-position of the drawing area. */
4990 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4996 c = (ROW)->glyphs[AREA][START].u.ch; \
4997 face_id = (ROW)->glyphs[AREA][START].face_id; \
4999 s = (struct glyph_string *) alloca (sizeof *s); \
5000 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5001 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5002 x_append_glyph_string (&HEAD, &TAIL, s); \
5004 START = x_fill_glyph_string (s, face_id, START, END, \
5010 /* Add a glyph string for a composite sequence to the list of strings
5011 between HEAD and TAIL. START is the index of the first glyph in
5012 row area AREA of glyph row ROW that is part of the new glyph
5013 string. END is the index of the last glyph in that glyph row area.
5014 X is the current output position assigned to the new glyph string
5015 constructed. HL overrides that face of the glyph; e.g. it is
5016 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5017 x-position of the drawing area. */
5019 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5021 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5022 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5023 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5024 struct composition *cmp = composition_table[cmp_id]; \
5025 int glyph_len = cmp->glyph_len; \
5027 struct face **faces; \
5028 struct glyph_string *first_s = NULL; \
5031 base_face = base_face->ascii_face; \
5032 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5033 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5034 /* At first, fill in `char2b' and `faces'. */ \
5035 for (n = 0; n < glyph_len; n++) \
5037 int c = COMPOSITION_GLYPH (cmp, n); \
5038 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5039 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5040 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5041 this_face_id, char2b + n, 1); \
5044 /* Make glyph_strings for each glyph sequence that is drawable by \
5045 the same face, and append them to HEAD/TAIL. */ \
5046 for (n = 0; n < cmp->glyph_len;) \
5048 s = (struct glyph_string *) alloca (sizeof *s); \
5049 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5050 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5058 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5066 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5067 of AREA of glyph row ROW on window W between indices START and END.
5068 HL overrides the face for drawing glyph strings, e.g. it is
5069 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5070 x-positions of the drawing area.
5072 This is an ugly monster macro construct because we must use alloca
5073 to allocate glyph strings (because x_draw_glyphs can be called
5076 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5079 HEAD = TAIL = NULL; \
5080 while (START < END) \
5082 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5083 switch (first_glyph->type) \
5086 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5087 TAIL, HL, X, LAST_X, \
5091 case COMPOSITE_GLYPH: \
5092 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5093 HEAD, TAIL, HL, X, LAST_X,\
5097 case STRETCH_GLYPH: \
5098 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5099 HEAD, TAIL, HL, X, LAST_X); \
5103 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5104 TAIL, HL, X, LAST_X); \
5111 x_set_glyph_string_background_width (s, START, LAST_X); \
5118 /* Draw glyphs between START and END in AREA of ROW on window W,
5119 starting at x-position X. X is relative to AREA in W. HL is a
5120 face-override with the following meaning:
5122 DRAW_NORMAL_TEXT draw normally
5123 DRAW_CURSOR draw in cursor face
5124 DRAW_MOUSE_FACE draw in mouse face.
5125 DRAW_INVERSE_VIDEO draw in mode line face
5126 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5127 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5129 If OVERLAPS_P is non-zero, draw only the foreground of characters
5130 and clip to the physical height of ROW.
5132 Value is the x-position reached, relative to AREA of W. */
5135 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5138 struct glyph_row
*row
;
5139 enum glyph_row_area area
;
5141 enum draw_glyphs_face hl
;
5144 struct glyph_string
*head
, *tail
;
5145 struct glyph_string
*s
;
5146 int last_x
, area_width
;
5150 /* Let's rather be paranoid than getting a SEGV. */
5151 end
= min (end
, row
->used
[area
]);
5152 start
= max (0, start
);
5153 start
= min (end
, start
);
5155 /* Translate X to frame coordinates. Set last_x to the right
5156 end of the drawing area. */
5157 if (row
->full_width_p
)
5159 /* X is relative to the left edge of W, without scroll bars
5161 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5162 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5165 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5166 last_x
= window_left_x
+ area_width
;
5168 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5170 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5171 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5177 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5178 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5182 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5183 area_width
= window_box_width (w
, area
);
5184 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5187 /* Build a doubly-linked list of glyph_string structures between
5188 head and tail from what we have to draw. Note that the macro
5189 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5190 the reason we use a separate variable `i'. */
5192 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5195 x_reached
= tail
->x
+ tail
->background_width
;
5199 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5200 the row, redraw some glyphs in front or following the glyph
5201 strings built above. */
5202 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5205 struct glyph_string
*h
, *t
;
5207 /* Compute overhangs for all glyph strings. */
5208 for (s
= head
; s
; s
= s
->next
)
5209 x_compute_glyph_string_overhangs (s
);
5211 /* Prepend glyph strings for glyphs in front of the first glyph
5212 string that are overwritten because of the first glyph
5213 string's left overhang. The background of all strings
5214 prepended must be drawn because the first glyph string
5216 i
= x_left_overwritten (head
);
5220 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5221 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5224 x_compute_overhangs_and_x (t
, head
->x
, 1);
5225 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5228 /* Prepend glyph strings for glyphs in front of the first glyph
5229 string that overwrite that glyph string because of their
5230 right overhang. For these strings, only the foreground must
5231 be drawn, because it draws over the glyph string at `head'.
5232 The background must not be drawn because this would overwrite
5233 right overhangs of preceding glyphs for which no glyph
5235 i
= x_left_overwriting (head
);
5238 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5239 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5241 for (s
= h
; s
; s
= s
->next
)
5242 s
->background_filled_p
= 1;
5243 x_compute_overhangs_and_x (t
, head
->x
, 1);
5244 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5247 /* Append glyphs strings for glyphs following the last glyph
5248 string tail that are overwritten by tail. The background of
5249 these strings has to be drawn because tail's foreground draws
5251 i
= x_right_overwritten (tail
);
5254 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5255 DRAW_NORMAL_TEXT
, x
, last_x
,
5257 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5258 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5261 /* Append glyph strings for glyphs following the last glyph
5262 string tail that overwrite tail. The foreground of such
5263 glyphs has to be drawn because it writes into the background
5264 of tail. The background must not be drawn because it could
5265 paint over the foreground of following glyphs. */
5266 i
= x_right_overwriting (tail
);
5269 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5270 DRAW_NORMAL_TEXT
, x
, last_x
,
5272 for (s
= h
; s
; s
= s
->next
)
5273 s
->background_filled_p
= 1;
5274 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5275 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5279 /* Draw all strings. */
5280 for (s
= head
; s
; s
= s
->next
)
5281 x_draw_glyph_string (s
);
5283 if (area
== TEXT_AREA
5284 && !row
->full_width_p
5285 /* When drawing overlapping rows, only the glyph strings'
5286 foreground is drawn, which doesn't erase a cursor
5290 int x0
= head
? head
->x
: x
;
5291 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5293 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5294 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5296 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5298 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5299 x0
-= left_area_width
;
5300 x1
-= left_area_width
;
5303 notice_overwritten_cursor (w
, area
, x0
, x1
,
5304 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5307 /* Value is the x-position up to which drawn, relative to AREA of W.
5308 This doesn't include parts drawn because of overhangs. */
5309 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5310 if (!row
->full_width_p
)
5312 if (area
> LEFT_MARGIN_AREA
)
5313 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5314 if (area
> TEXT_AREA
)
5315 x_reached
-= window_box_width (w
, TEXT_AREA
);
5322 /* Fix the display of area AREA of overlapping row ROW in window W. */
5325 x_fix_overlapping_area (w
, row
, area
)
5327 struct glyph_row
*row
;
5328 enum glyph_row_area area
;
5334 if (area
== LEFT_MARGIN_AREA
)
5336 else if (area
== TEXT_AREA
)
5337 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5339 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5340 + window_box_width (w
, TEXT_AREA
));
5342 for (i
= 0; i
< row
->used
[area
];)
5344 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5346 int start
= i
, start_x
= x
;
5350 x
+= row
->glyphs
[area
][i
].pixel_width
;
5353 while (i
< row
->used
[area
]
5354 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5356 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5357 DRAW_NORMAL_TEXT
, 1);
5361 x
+= row
->glyphs
[area
][i
].pixel_width
;
5370 /* Output LEN glyphs starting at START at the nominal cursor position.
5371 Advance the nominal cursor over the text. The global variable
5372 updated_window contains the window being updated, updated_row is
5373 the glyph row being updated, and updated_area is the area of that
5374 row being updated. */
5377 x_write_glyphs (start
, len
)
5378 struct glyph
*start
;
5383 xassert (updated_window
&& updated_row
);
5388 hpos
= start
- updated_row
->glyphs
[updated_area
];
5389 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5390 updated_row
, updated_area
,
5392 DRAW_NORMAL_TEXT
, 0);
5396 /* Advance the output cursor. */
5397 output_cursor
.hpos
+= len
;
5398 output_cursor
.x
= x
;
5402 /* Insert LEN glyphs from START at the nominal cursor position. */
5405 x_insert_glyphs (start
, len
)
5406 struct glyph
*start
;
5411 int line_height
, shift_by_width
, shifted_region_width
;
5412 struct glyph_row
*row
;
5413 struct glyph
*glyph
;
5414 int frame_x
, frame_y
, hpos
;
5416 xassert (updated_window
&& updated_row
);
5419 f
= XFRAME (WINDOW_FRAME (w
));
5421 /* Get the height of the line we are in. */
5423 line_height
= row
->height
;
5425 /* Get the width of the glyphs to insert. */
5427 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5428 shift_by_width
+= glyph
->pixel_width
;
5430 /* Get the width of the region to shift right. */
5431 shifted_region_width
= (window_box_width (w
, updated_area
)
5436 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5437 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5439 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5440 f
->output_data
.mac
->normal_gc
,
5442 shifted_region_width
, line_height
,
5443 frame_x
+ shift_by_width
, frame_y
);
5445 /* Write the glyphs. */
5446 hpos
= start
- row
->glyphs
[updated_area
];
5447 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5448 DRAW_NORMAL_TEXT
, 0);
5450 /* Advance the output cursor. */
5451 output_cursor
.hpos
+= len
;
5452 output_cursor
.x
+= shift_by_width
;
5457 /* Delete N glyphs at the nominal cursor position. Not implemented
5468 /* Erase the current text line from the nominal cursor position
5469 (inclusive) to pixel column TO_X (exclusive). The idea is that
5470 everything from TO_X onward is already erased.
5472 TO_X is a pixel position relative to updated_area of
5473 updated_window. TO_X == -1 means clear to the end of this area. */
5476 x_clear_end_of_line (to_x
)
5480 struct window
*w
= updated_window
;
5481 int max_x
, min_y
, max_y
;
5482 int from_x
, from_y
, to_y
;
5484 xassert (updated_window
&& updated_row
);
5485 f
= XFRAME (w
->frame
);
5487 if (updated_row
->full_width_p
)
5489 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5490 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5491 && !w
->pseudo_window_p
)
5492 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5495 max_x
= window_box_width (w
, updated_area
);
5496 max_y
= window_text_bottom_y (w
);
5498 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5499 of window. For TO_X > 0, truncate to end of drawing area. */
5505 to_x
= min (to_x
, max_x
);
5507 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5509 /* Notice if the cursor will be cleared by this operation. */
5510 if (!updated_row
->full_width_p
)
5511 notice_overwritten_cursor (w
, updated_area
,
5512 output_cursor
.x
, -1,
5514 MATRIX_ROW_BOTTOM_Y (updated_row
));
5516 from_x
= output_cursor
.x
;
5518 /* Translate to frame coordinates. */
5519 if (updated_row
->full_width_p
)
5521 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5522 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5526 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5527 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5530 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5531 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5532 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5534 /* Prevent inadvertently clearing to end of the X window. */
5535 if (to_x
> from_x
&& to_y
> from_y
)
5538 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5539 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5546 /* Clear entire frame. If updating_frame is non-null, clear that
5547 frame. Otherwise clear the selected frame. */
5557 f
= SELECTED_FRAME ();
5559 /* Clearing the frame will erase any cursor, so mark them all as no
5561 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5562 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5563 output_cursor
.x
= -1;
5565 /* We don't set the output cursor here because there will always
5566 follow an explicit cursor_to. */
5568 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5570 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5571 /* We have to clear the scroll bars, too. If we have changed
5572 colors or something like that, then they should be notified. */
5573 x_scroll_bar_clear (f
);
5576 XFlush (FRAME_MAC_DISPLAY (f
));
5582 /* Invert the middle quarter of the frame for .15 sec. */
5584 /* We use the select system call to do the waiting, so we have to make
5585 sure it's available. If it isn't, we just won't do visual bells. */
5587 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5589 /* Subtract the `struct timeval' values X and Y, storing the result in
5590 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5593 timeval_subtract (result
, x
, y
)
5594 struct timeval
*result
, x
, y
;
5596 /* Perform the carry for the later subtraction by updating y. This
5597 is safer because on some systems the tv_sec member is unsigned. */
5598 if (x
.tv_usec
< y
.tv_usec
)
5600 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5601 y
.tv_usec
-= 1000000 * nsec
;
5605 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5607 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5608 y
.tv_usec
+= 1000000 * nsec
;
5612 /* Compute the time remaining to wait. tv_usec is certainly
5614 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5615 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5617 /* Return indication of whether the result should be considered
5619 return x
.tv_sec
< y
.tv_sec
;
5631 struct timeval wakeup
;
5633 EMACS_GET_TIME (wakeup
);
5635 /* Compute time to wait until, propagating carry from usecs. */
5636 wakeup
.tv_usec
+= 150000;
5637 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5638 wakeup
.tv_usec
%= 1000000;
5640 /* Keep waiting until past the time wakeup. */
5643 struct timeval timeout
;
5645 EMACS_GET_TIME (timeout
);
5647 /* In effect, timeout = wakeup - timeout.
5648 Break if result would be negative. */
5649 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5652 /* Try to wait that long--but we might wake up sooner. */
5653 select (0, NULL
, NULL
, NULL
, &timeout
);
5662 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5665 /* Make audible bell. */
5670 struct frame
*f
= SELECTED_FRAME ();
5672 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5680 XFlush (FRAME_MAC_DISPLAY (f
));
5687 /* Specify how many text lines, from the top of the window,
5688 should be affected by insert-lines and delete-lines operations.
5689 This, and those operations, are used only within an update
5690 that is bounded by calls to x_update_begin and x_update_end. */
5693 XTset_terminal_window (n
)
5696 /* This function intentionally left blank. */
5701 /***********************************************************************
5703 ***********************************************************************/
5705 /* Perform an insert-lines or delete-lines operation, inserting N
5706 lines or deleting -N lines at vertical position VPOS. */
5709 x_ins_del_lines (vpos
, n
)
5716 /* Scroll part of the display as described by RUN. */
5719 x_scroll_run (w
, run
)
5723 struct frame
*f
= XFRAME (w
->frame
);
5724 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5726 /* Get frame-relative bounding box of the text display area of W,
5727 without mode lines. Include in this box the left and right
5729 window_box (w
, -1, &x
, &y
, &width
, &height
);
5730 width
+= FRAME_X_FRINGE_WIDTH (f
);
5731 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5733 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5734 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5735 bottom_y
= y
+ height
;
5739 /* Scrolling up. Make sure we don't copy part of the mode
5740 line at the bottom. */
5741 if (from_y
+ run
->height
> bottom_y
)
5742 height
= bottom_y
- from_y
;
5744 height
= run
->height
;
5748 /* Scolling down. Make sure we don't copy over the mode line.
5750 if (to_y
+ run
->height
> bottom_y
)
5751 height
= bottom_y
- to_y
;
5753 height
= run
->height
;
5758 /* Cursor off. Will be switched on again in x_update_window_end. */
5762 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5763 f
->output_data
.mac
->normal_gc
,
5773 /***********************************************************************
5775 ***********************************************************************/
5777 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5778 corner of the exposed rectangle. W and H are width and height of
5779 the exposed area. All are pixel values. W or H zero means redraw
5780 the entire frame. */
5783 expose_frame (f
, x
, y
, w
, h
)
5788 int mouse_face_overwritten_p
= 0;
5790 TRACE ((stderr
, "expose_frame "));
5792 /* No need to redraw if frame will be redrawn soon. */
5793 if (FRAME_GARBAGED_P (f
))
5795 TRACE ((stderr
, " garbaged\n"));
5799 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
5800 or deactivated here, for unknown reasons, activated scroll bars
5801 are shown in deactivated frames in some instances. */
5802 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
5803 activate_scroll_bars (f
);
5805 deactivate_scroll_bars (f
);
5807 /* If basic faces haven't been realized yet, there is no point in
5808 trying to redraw anything. This can happen when we get an expose
5809 event while Emacs is starting, e.g. by moving another window. */
5810 if (FRAME_FACE_CACHE (f
) == NULL
5811 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5813 TRACE ((stderr
, " no faces\n"));
5817 if (w
== 0 || h
== 0)
5820 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5821 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5831 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5832 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
5834 if (WINDOWP (f
->tool_bar_window
))
5835 mouse_face_overwritten_p
5836 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
5838 /* Some window managers support a focus-follows-mouse style with
5839 delayed raising of frames. Imagine a partially obscured frame,
5840 and moving the mouse into partially obscured mouse-face on that
5841 frame. The visible part of the mouse-face will be highlighted,
5842 then the WM raises the obscured frame. With at least one WM, KDE
5843 2.1, Emacs is not getting any event for the raising of the frame
5844 (even tried with SubstructureRedirectMask), only Expose events.
5845 These expose events will draw text normally, i.e. not
5846 highlighted. Which means we must redo the highlight here.
5847 Subsume it under ``we love X''. --gerd 2001-08-15 */
5848 /* Included in Windows version because Windows most likely does not
5849 do the right thing if any third party tool offers
5850 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
5851 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
5853 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5854 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5856 int x
= dpyinfo
->mouse_face_mouse_x
;
5857 int y
= dpyinfo
->mouse_face_mouse_y
;
5858 clear_mouse_face (dpyinfo
);
5859 note_mouse_highlight (f
, x
, y
);
5865 /* Redraw (parts) of all windows in the window tree rooted at W that
5866 intersect R. R contains frame pixel coordinates. */
5869 expose_window_tree (w
, r
)
5873 struct frame
*f
= XFRAME (w
->frame
);
5874 int mouse_face_overwritten_p
= 0;
5876 while (w
&& !FRAME_GARBAGED_P (f
))
5878 if (!NILP (w
->hchild
))
5879 mouse_face_overwritten_p
5880 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
5881 else if (!NILP (w
->vchild
))
5882 mouse_face_overwritten_p
5883 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
5885 mouse_face_overwritten_p
|= expose_window (w
, r
);
5887 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
5890 return mouse_face_overwritten_p
;
5894 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5895 which intersects rectangle R. R is in window-relative coordinates. */
5898 expose_area (w
, row
, r
, area
)
5900 struct glyph_row
*row
;
5902 enum glyph_row_area area
;
5904 struct glyph
*first
= row
->glyphs
[area
];
5905 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5907 int first_x
, start_x
, x
;
5909 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5910 /* If row extends face to end of line write the whole line. */
5911 x_draw_glyphs (w
, 0, row
, area
,
5913 DRAW_NORMAL_TEXT
, 0);
5916 /* Set START_X to the window-relative start position for drawing glyphs of
5917 AREA. The first glyph of the text area can be partially visible.
5918 The first glyphs of other areas cannot. */
5919 if (area
== LEFT_MARGIN_AREA
)
5921 else if (area
== TEXT_AREA
)
5922 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5924 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5925 + window_box_width (w
, TEXT_AREA
));
5928 /* Find the first glyph that must be redrawn. */
5930 && x
+ first
->pixel_width
< r
->left
)
5932 x
+= first
->pixel_width
;
5936 /* Find the last one. */
5942 x
+= last
->pixel_width
;
5948 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
5949 first
- row
->glyphs
[area
],
5950 last
- row
->glyphs
[area
],
5951 DRAW_NORMAL_TEXT
, 0);
5956 /* Redraw the parts of the glyph row ROW on window W intersecting
5957 rectangle R. R is in window-relative coordinates. Value is
5958 non-zero if mouse face was overwritten. */
5961 expose_line (w
, row
, r
)
5963 struct glyph_row
*row
;
5966 xassert (row
->enabled_p
);
5968 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5969 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5970 DRAW_NORMAL_TEXT
, 0);
5973 if (row
->used
[LEFT_MARGIN_AREA
])
5974 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
5975 if (row
->used
[TEXT_AREA
])
5976 expose_area (w
, row
, r
, TEXT_AREA
);
5977 if (row
->used
[RIGHT_MARGIN_AREA
])
5978 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
5979 draw_row_fringe_bitmaps (w
, row
);
5982 return row
->mouse_face_p
;
5986 /* Return non-zero if W's cursor intersects rectangle R. */
5989 x_phys_cursor_in_rect_p (w
, r
)
5994 struct glyph
*cursor_glyph
;
5996 cursor_glyph
= get_phys_cursor_glyph (w
);
5999 cr
.left
= w
->phys_cursor
.x
;
6000 cr
.top
= w
->phys_cursor
.y
;
6001 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6002 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6003 return x_intersect_rectangles (&cr
, r
, &result
);
6010 /* Redraw those parts of glyphs rows during expose event handling that
6011 overlap other rows. Redrawing of an exposed line writes over parts
6012 of lines overlapping that exposed line; this function fixes that.
6014 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
6015 row in W's current matrix that is exposed and overlaps other rows.
6016 LAST_OVERLAPPING_ROW is the last such row. */
6019 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
6021 struct glyph_row
*first_overlapping_row
;
6022 struct glyph_row
*last_overlapping_row
;
6024 struct glyph_row
*row
;
6026 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
6027 if (row
->overlapping_p
)
6029 xassert (row
->enabled_p
&& !row
->mode_line_p
);
6031 if (row
->used
[LEFT_MARGIN_AREA
])
6032 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
6034 if (row
->used
[TEXT_AREA
])
6035 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
6037 if (row
->used
[RIGHT_MARGIN_AREA
])
6038 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
6043 /* Redraw the part of window W intersection rectangle FR. Pixel
6044 coordinates in FR are frame-relative. Call this function with
6045 input blocked. Value is non-zero if the exposure overwrites
6049 expose_window (w
, fr
)
6053 struct frame
*f
= XFRAME (w
->frame
);
6055 int mouse_face_overwritten_p
= 0;
6057 /* If window is not yet fully initialized, do nothing. This can
6058 happen when toolkit scroll bars are used and a window is split.
6059 Reconfiguring the scroll bar will generate an expose for a newly
6061 if (w
->current_matrix
== NULL
)
6064 /* When we're currently updating the window, display and current
6065 matrix usually don't agree. Arrange for a thorough display
6067 if (w
== updated_window
)
6069 SET_FRAME_GARBAGED (f
);
6073 /* Frame-relative pixel rectangle of W. */
6074 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6075 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6076 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6077 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6079 if (x_intersect_rectangles (fr
, &wr
, &r
))
6081 int yb
= window_text_bottom_y (w
);
6082 struct glyph_row
*row
;
6083 int cursor_cleared_p
;
6084 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
6086 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6087 r
.left
, r
.top
, r
.right
, r
.bottom
));
6089 /* Convert to window coordinates. */
6090 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6091 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6092 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6093 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6095 /* Turn off the cursor. */
6096 if (!w
->pseudo_window_p
6097 && x_phys_cursor_in_rect_p (w
, &r
))
6100 cursor_cleared_p
= 1;
6103 cursor_cleared_p
= 0;
6105 /* Update lines intersecting rectangle R. */
6106 first_overlapping_row
= last_overlapping_row
= NULL
;
6107 for (row
= w
->current_matrix
->rows
;
6112 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6114 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6115 || (y1
> r
.top
&& y1
< r
.bottom
)
6116 || (r
.top
>= y0
&& r
.top
< y1
)
6117 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6119 if (row
->overlapping_p
)
6121 if (first_overlapping_row
== NULL
)
6122 first_overlapping_row
= row
;
6123 last_overlapping_row
= row
;
6126 if (expose_line (w
, row
, &r
))
6127 mouse_face_overwritten_p
= 1;
6134 /* Display the mode line if there is one. */
6135 if (WINDOW_WANTS_MODELINE_P (w
)
6136 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6138 && row
->y
< r
.bottom
)
6140 if (expose_line (w
, row
, &r
))
6141 mouse_face_overwritten_p
= 1;
6144 if (!w
->pseudo_window_p
)
6146 /* Fix the display of overlapping rows. */
6147 if (first_overlapping_row
)
6148 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
6150 /* Draw border between windows. */
6151 x_draw_vertical_border (w
);
6153 /* Turn the cursor on again. */
6154 if (cursor_cleared_p
)
6155 x_update_window_cursor (w
, 1);
6159 /* Display scroll bar for this window. */
6160 if (!NILP (w
->vertical_scroll_bar
))
6163 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6168 return mouse_face_overwritten_p
;
6172 x_intersect_rectangles (r1
, r2
, result
)
6173 Rect
*r1
, *r2
, *result
;
6176 Rect
*upper
, *lower
;
6177 int intersection_p
= 0;
6179 /* Rerrange so that R1 is the left-most rectangle. */
6180 if (r1
->left
< r2
->left
)
6181 left
= r1
, right
= r2
;
6183 left
= r2
, right
= r1
;
6185 /* X0 of the intersection is right.x0, if this is inside R1,
6186 otherwise there is no intersection. */
6187 if (right
->left
<= left
->right
)
6189 result
->left
= right
->left
;
6191 /* The right end of the intersection is the minimum of the
6192 the right ends of left and right. */
6193 result
->right
= min (left
->right
, right
->right
);
6195 /* Same game for Y. */
6196 if (r1
->top
< r2
->top
)
6197 upper
= r1
, lower
= r2
;
6199 upper
= r2
, lower
= r1
;
6201 /* The upper end of the intersection is lower.y0, if this is inside
6202 of upper. Otherwise, there is no intersection. */
6203 if (lower
->top
<= upper
->bottom
)
6205 result
->top
= lower
->top
;
6207 /* The lower end of the intersection is the minimum of the lower
6208 ends of upper and lower. */
6209 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6214 return intersection_p
;
6225 x_update_cursor (f
, 1);
6229 frame_unhighlight (f
)
6232 x_update_cursor (f
, 1);
6235 /* The focus has changed. Update the frames as necessary to reflect
6236 the new situation. Note that we can't change the selected frame
6237 here, because the Lisp code we are interrupting might become confused.
6238 Each event gets marked with the frame in which it occurred, so the
6239 Lisp code can tell when the switch took place by examining the events. */
6242 x_new_focus_frame (dpyinfo
, frame
)
6243 struct x_display_info
*dpyinfo
;
6244 struct frame
*frame
;
6246 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6248 if (frame
!= dpyinfo
->x_focus_frame
)
6250 /* Set this before calling other routines, so that they see
6251 the correct value of x_focus_frame. */
6252 dpyinfo
->x_focus_frame
= frame
;
6254 if (old_focus
&& old_focus
->auto_lower
)
6255 x_lower_frame (old_focus
);
6258 selected_frame
= frame
;
6259 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6261 Fselect_window (selected_frame
->selected_window
);
6262 choose_minibuf_frame ();
6265 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6266 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6268 pending_autoraise_frame
= 0;
6271 x_frame_rehighlight (dpyinfo
);
6274 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6277 x_mouse_leave (dpyinfo
)
6278 struct x_display_info
*dpyinfo
;
6280 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6283 /* The focus has changed, or we have redirected a frame's focus to
6284 another frame (this happens when a frame uses a surrogate
6285 mini-buffer frame). Shift the highlight as appropriate.
6287 The FRAME argument doesn't necessarily have anything to do with which
6288 frame is being highlighted or un-highlighted; we only use it to find
6289 the appropriate X display info. */
6292 XTframe_rehighlight (frame
)
6293 struct frame
*frame
;
6295 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6299 x_frame_rehighlight (dpyinfo
)
6300 struct x_display_info
*dpyinfo
;
6302 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6304 if (dpyinfo
->x_focus_frame
)
6306 dpyinfo
->x_highlight_frame
6307 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6308 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6309 : dpyinfo
->x_focus_frame
);
6310 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6312 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6313 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6317 dpyinfo
->x_highlight_frame
= 0;
6319 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6322 frame_unhighlight (old_highlight
);
6323 if (dpyinfo
->x_highlight_frame
)
6324 frame_highlight (dpyinfo
->x_highlight_frame
);
6330 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6332 #if 0 /* MAC_TODO */
6333 /* Initialize mode_switch_bit and modifier_meaning. */
6335 x_find_modifier_meanings (dpyinfo
)
6336 struct x_display_info
*dpyinfo
;
6338 int min_code
, max_code
;
6341 XModifierKeymap
*mods
;
6343 dpyinfo
->meta_mod_mask
= 0;
6344 dpyinfo
->shift_lock_mask
= 0;
6345 dpyinfo
->alt_mod_mask
= 0;
6346 dpyinfo
->super_mod_mask
= 0;
6347 dpyinfo
->hyper_mod_mask
= 0;
6350 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6352 min_code
= dpyinfo
->display
->min_keycode
;
6353 max_code
= dpyinfo
->display
->max_keycode
;
6356 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6357 min_code
, max_code
- min_code
+ 1,
6359 mods
= XGetModifierMapping (dpyinfo
->display
);
6361 /* Scan the modifier table to see which modifier bits the Meta and
6362 Alt keysyms are on. */
6364 int row
, col
; /* The row and column in the modifier table. */
6366 for (row
= 3; row
< 8; row
++)
6367 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6370 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6372 /* Zeroes are used for filler. Skip them. */
6376 /* Are any of this keycode's keysyms a meta key? */
6380 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6382 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6388 dpyinfo
->meta_mod_mask
|= (1 << row
);
6393 dpyinfo
->alt_mod_mask
|= (1 << row
);
6398 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6403 dpyinfo
->super_mod_mask
|= (1 << row
);
6407 /* Ignore this if it's not on the lock modifier. */
6408 if ((1 << row
) == LockMask
)
6409 dpyinfo
->shift_lock_mask
= LockMask
;
6417 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6418 if (! dpyinfo
->meta_mod_mask
)
6420 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6421 dpyinfo
->alt_mod_mask
= 0;
6424 /* If some keys are both alt and meta,
6425 make them just meta, not alt. */
6426 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6428 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6431 XFree ((char *) syms
);
6432 XFreeModifiermap (mods
);
6435 #endif /* MAC_TODO */
6437 /* Convert between the modifier bits X uses and the modifier bits
6441 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6442 struct x_display_info
*dpyinfo
;
6443 unsigned short state
;
6445 return (((state
& shiftKey
) ? shift_modifier
: 0)
6446 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6447 | ((state
& cmdKey
) ? meta_modifier
: 0)
6448 | ((state
& optionKey
) ? alt_modifier
: 0));
6451 #if 0 /* MAC_TODO */
6452 static unsigned short
6453 x_emacs_to_x_modifiers (dpyinfo
, state
)
6454 struct x_display_info
*dpyinfo
;
6457 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6458 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6459 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6460 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6461 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6462 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6464 #endif /* MAC_TODO */
6466 /* Convert a keysym to its name. */
6469 x_get_keysym_name (keysym
)
6476 value
= XKeysymToString (keysym
);
6487 /* Mouse clicks and mouse movement. Rah. */
6489 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6490 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6491 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6492 not force the value into range. */
6495 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6497 register int pix_x
, pix_y
;
6498 register int *x
, *y
;
6502 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6503 if (NILP (Vwindow_system
))
6510 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6511 even for negative values. */
6513 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6515 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6517 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6518 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6522 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6523 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6524 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6525 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6532 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6533 pix_x
= FRAME_WINDOW_WIDTH (f
);
6537 else if (pix_y
> f
->height
)
6546 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6547 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6548 can't tell the positions because W's display is not up to date,
6552 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6555 int *frame_x
, *frame_y
;
6559 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6560 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6562 if (display_completed
)
6564 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6565 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6566 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6572 *frame_x
+= glyph
->pixel_width
;
6580 *frame_y
= *frame_x
= 0;
6584 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6585 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6590 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6592 If the event is a button press, then note that we have grabbed
6596 construct_mouse_click (result
, event
, f
)
6597 struct input_event
*result
;
6603 result
->kind
= MOUSE_CLICK_EVENT
;
6604 result
->code
= 0; /* only one mouse button */
6605 result
->timestamp
= event
->when
;
6606 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6608 mouseLoc
= event
->where
;
6610 #if TARGET_API_MAC_CARBON
6611 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6613 SetPort (FRAME_MAC_WINDOW (f
));
6616 GlobalToLocal (&mouseLoc
);
6617 XSETINT (result
->x
, mouseLoc
.h
);
6618 XSETINT (result
->y
, mouseLoc
.v
);
6620 XSETFRAME (result
->frame_or_window
, f
);
6627 /* Function to report a mouse movement to the mainstream Emacs code.
6628 The input handler calls this.
6630 We have received a mouse movement event, which is given in *event.
6631 If the mouse is over a different glyph than it was last time, tell
6632 the mainstream emacs code by setting mouse_moved. If not, ask for
6633 another motion event, so we can check again the next time it moves. */
6635 static Point last_mouse_motion_position
;
6636 static Lisp_Object last_mouse_motion_frame
;
6639 note_mouse_movement (frame
, pos
)
6643 #if TARGET_API_MAC_CARBON
6647 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6648 last_mouse_motion_position
= *pos
;
6649 XSETFRAME (last_mouse_motion_frame
, frame
);
6651 #if TARGET_API_MAC_CARBON
6652 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6654 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6657 frame
->mouse_moved
= 1;
6658 last_mouse_scroll_bar
= Qnil
;
6659 note_mouse_highlight (frame
, -1, -1);
6661 /* Has the mouse moved off the glyph it was on at the last sighting? */
6662 else if (pos
->h
< last_mouse_glyph
.left
6663 || pos
->h
>= last_mouse_glyph
.right
6664 || pos
->v
< last_mouse_glyph
.top
6665 || pos
->v
>= last_mouse_glyph
.bottom
)
6667 frame
->mouse_moved
= 1;
6668 last_mouse_scroll_bar
= Qnil
;
6669 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6673 /* This is used for debugging, to turn off note_mouse_highlight. */
6675 int disable_mouse_highlight
;
6679 /************************************************************************
6681 ************************************************************************/
6683 /* Find the glyph under window-relative coordinates X/Y in window W.
6684 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6685 strings. Return in *HPOS and *VPOS the row and column number of
6686 the glyph found. Return in *AREA the glyph area containing X.
6687 Value is a pointer to the glyph found or null if X/Y is not on
6688 text, or we can't tell because W's current matrix is not up to
6691 static struct glyph
*
6692 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6695 int *hpos
, *vpos
, *area
;
6698 struct glyph
*glyph
, *end
;
6699 struct glyph_row
*row
= NULL
;
6700 int x0
, i
, left_area_width
;
6702 /* Find row containing Y. Give up if some row is not enabled. */
6703 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6705 row
= MATRIX_ROW (w
->current_matrix
, i
);
6706 if (!row
->enabled_p
)
6708 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6715 /* Give up if Y is not in the window. */
6716 if (i
== w
->current_matrix
->nrows
)
6719 /* Get the glyph area containing X. */
6720 if (w
->pseudo_window_p
)
6727 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6728 if (x
< left_area_width
)
6730 *area
= LEFT_MARGIN_AREA
;
6733 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6736 x0
= row
->x
+ left_area_width
;
6740 *area
= RIGHT_MARGIN_AREA
;
6741 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6745 /* Find glyph containing X. */
6746 glyph
= row
->glyphs
[*area
];
6747 end
= glyph
+ row
->used
[*area
];
6750 if (x
< x0
+ glyph
->pixel_width
)
6752 if (w
->pseudo_window_p
)
6754 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6758 x0
+= glyph
->pixel_width
;
6765 *hpos
= glyph
- row
->glyphs
[*area
];
6770 /* Convert frame-relative x/y to coordinates relative to window W.
6771 Takes pseudo-windows into account. */
6774 frame_to_window_pixel_xy (w
, x
, y
)
6778 if (w
->pseudo_window_p
)
6780 /* A pseudo-window is always full-width, and starts at the
6781 left edge of the frame, plus a frame border. */
6782 struct frame
*f
= XFRAME (w
->frame
);
6783 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6784 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6788 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6789 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6794 /* Take proper action when mouse has moved to the mode or header line of
6795 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6796 mode line. X is relative to the start of the text display area of
6797 W, so the width of fringes and scroll bars must be subtracted
6798 to get a position relative to the start of the mode line. */
6801 note_mode_line_highlight (w
, x
, mode_line_p
)
6805 struct frame
*f
= XFRAME (w
->frame
);
6806 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6807 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6808 struct glyph_row
*row
;
6811 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6813 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6817 struct glyph
*glyph
, *end
;
6818 Lisp_Object help
, map
;
6821 /* Find the glyph under X. */
6822 glyph
= row
->glyphs
[TEXT_AREA
];
6823 end
= glyph
+ row
->used
[TEXT_AREA
];
6824 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6825 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6828 && x
>= x0
+ glyph
->pixel_width
)
6830 x0
+= glyph
->pixel_width
;
6835 && STRINGP (glyph
->object
)
6836 && STRING_INTERVALS (glyph
->object
)
6837 && glyph
->charpos
>= 0
6838 && glyph
->charpos
< SCHARS (glyph
->object
))
6840 /* If we're on a string with `help-echo' text property,
6841 arrange for the help to be displayed. This is done by
6842 setting the global variable help_echo to the help string. */
6843 help
= Fget_text_property (make_number (glyph
->charpos
),
6844 Qhelp_echo
, glyph
->object
);
6848 XSETWINDOW (help_echo_window
, w
);
6849 help_echo_object
= glyph
->object
;
6850 help_echo_pos
= glyph
->charpos
;
6853 /* Change the mouse pointer according to what is under X/Y. */
6854 map
= Fget_text_property (make_number (glyph
->charpos
),
6855 Qlocal_map
, glyph
->object
);
6857 cursor
= f
->output_data
.mac
->nontext_cursor
;
6860 map
= Fget_text_property (make_number (glyph
->charpos
),
6861 Qkeymap
, glyph
->object
);
6863 cursor
= f
->output_data
.mac
->nontext_cursor
;
6868 #if 0 /* MAC_TODO: mouse cursor */
6869 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6874 /* Take proper action when the mouse has moved to position X, Y on
6875 frame F as regards highlighting characters that have mouse-face
6876 properties. Also de-highlighting chars where the mouse was before.
6877 X and Y can be negative or out of range. */
6880 note_mouse_highlight (f
, x
, y
)
6884 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6891 /* When a menu is active, don't highlight because this looks odd. */
6892 if (popup_activated ())
6896 if (NILP (Vmouse_highlight
)
6897 || !f
->glyphs_initialized_p
)
6900 dpyinfo
->mouse_face_mouse_x
= x
;
6901 dpyinfo
->mouse_face_mouse_y
= y
;
6902 dpyinfo
->mouse_face_mouse_frame
= f
;
6904 if (dpyinfo
->mouse_face_defer
)
6909 dpyinfo
->mouse_face_deferred_gc
= 1;
6913 /* Which window is that in? */
6914 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6916 /* If we were displaying active text in another window, clear that. */
6917 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6918 clear_mouse_face (dpyinfo
);
6920 /* Not on a window -> return. */
6921 if (!WINDOWP (window
))
6924 /* Reset help_echo. It will get recomputed below. */
6927 /* Convert to window-relative pixel coordinates. */
6928 w
= XWINDOW (window
);
6929 frame_to_window_pixel_xy (w
, &x
, &y
);
6931 /* Handle tool-bar window differently since it doesn't display a
6933 if (EQ (window
, f
->tool_bar_window
))
6935 note_tool_bar_highlight (f
, x
, y
);
6939 /* Mouse is on the mode or header line? */
6940 if (portion
== 1 || portion
== 3)
6942 note_mode_line_highlight (w
, x
, portion
== 1);
6945 #if 0 /* TODO: mouse cursor */
6947 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
6949 cursor
= f
->output_data
.x
->text_cursor
;
6951 /* Are we in a window whose display is up to date?
6952 And verify the buffer's text has not changed. */
6953 b
= XBUFFER (w
->buffer
);
6954 if (/* Within text portion of the window. */
6956 && EQ (w
->window_end_valid
, w
->buffer
)
6957 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
6958 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
6960 int hpos
, vpos
, pos
, i
, area
;
6961 struct glyph
*glyph
;
6963 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
6964 Lisp_Object
*overlay_vec
= NULL
;
6966 struct buffer
*obuf
;
6967 int obegv
, ozv
, same_region
;
6969 /* Find the glyph under X/Y. */
6970 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
6972 /* Clear mouse face if X/Y not over text. */
6974 || area
!= TEXT_AREA
6975 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6977 clear_mouse_face (dpyinfo
);
6978 /* TODO: mouse cursor */
6982 pos
= glyph
->charpos
;
6983 object
= glyph
->object
;
6984 if (!STRINGP (object
) && !BUFFERP (object
))
6987 /* If we get an out-of-range value, return now; avoid an error. */
6988 if (BUFFERP (object
) && pos
> BUF_Z (b
))
6991 /* Make the window's buffer temporarily current for
6992 overlays_at and compute_char_face. */
6993 obuf
= current_buffer
;
7000 /* Is this char mouse-active or does it have help-echo? */
7001 position
= make_number (pos
);
7003 if (BUFFERP (object
))
7005 /* Put all the overlays we want in a vector in overlay_vec.
7006 Store the length in len. If there are more than 10, make
7007 enough space for all, and try again. */
7009 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7010 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7011 if (noverlays
> len
)
7014 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7015 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7018 /* Sort overlays into increasing priority order. */
7019 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7024 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7025 && vpos
>= dpyinfo
->mouse_face_beg_row
7026 && vpos
<= dpyinfo
->mouse_face_end_row
7027 && (vpos
> dpyinfo
->mouse_face_beg_row
7028 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7029 && (vpos
< dpyinfo
->mouse_face_end_row
7030 || hpos
< dpyinfo
->mouse_face_end_col
7031 || dpyinfo
->mouse_face_past_end
));
7033 /* TODO: if (same_region)
7036 /* Check mouse-face highlighting. */
7038 /* If there exists an overlay with mouse-face overlapping
7039 the one we are currently highlighting, we have to
7040 check if we enter the overlapping overlay, and then
7042 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7043 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7045 /* Find the highest priority overlay that has a mouse-face
7048 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7050 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7051 if (!NILP (mouse_face
))
7052 overlay
= overlay_vec
[i
];
7055 /* If we're actually highlighting the same overlay as
7056 before, there's no need to do that again. */
7058 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7059 goto check_help_echo
;
7061 dpyinfo
->mouse_face_overlay
= overlay
;
7063 /* Clear the display of the old active region, if any. */
7064 clear_mouse_face (dpyinfo
);
7065 /* TODO: mouse cursor changes. */
7067 /* If no overlay applies, get a text property. */
7069 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7071 /* Handle the overlay case. */
7072 if (!NILP (overlay
))
7074 /* Find the range of text around this char that
7075 should be active. */
7076 Lisp_Object before
, after
;
7079 before
= Foverlay_start (overlay
);
7080 after
= Foverlay_end (overlay
);
7081 /* Record this as the current active region. */
7082 fast_find_position (w
, XFASTINT (before
),
7083 &dpyinfo
->mouse_face_beg_col
,
7084 &dpyinfo
->mouse_face_beg_row
,
7085 &dpyinfo
->mouse_face_beg_x
,
7086 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7088 dpyinfo
->mouse_face_past_end
7089 = !fast_find_position (w
, XFASTINT (after
),
7090 &dpyinfo
->mouse_face_end_col
,
7091 &dpyinfo
->mouse_face_end_row
,
7092 &dpyinfo
->mouse_face_end_x
,
7093 &dpyinfo
->mouse_face_end_y
, Qnil
);
7094 dpyinfo
->mouse_face_window
= window
;
7096 dpyinfo
->mouse_face_face_id
7097 = face_at_buffer_position (w
, pos
, 0, 0,
7099 !dpyinfo
->mouse_face_hidden
);
7101 /* Display it as active. */
7102 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7103 /* TODO: mouse cursor changes. */
7105 /* Handle the text property case. */
7106 else if (! NILP (mouse_face
) && BUFFERP (object
))
7108 /* Find the range of text around this char that
7109 should be active. */
7110 Lisp_Object before
, after
, beginning
, end
;
7113 beginning
= Fmarker_position (w
->start
);
7114 end
= make_number (BUF_Z (XBUFFER (object
))
7115 - XFASTINT (w
->window_end_pos
));
7117 = Fprevious_single_property_change (make_number (pos
+ 1),
7121 = Fnext_single_property_change (position
, Qmouse_face
,
7124 /* Record this as the current active region. */
7125 fast_find_position (w
, XFASTINT (before
),
7126 &dpyinfo
->mouse_face_beg_col
,
7127 &dpyinfo
->mouse_face_beg_row
,
7128 &dpyinfo
->mouse_face_beg_x
,
7129 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7130 dpyinfo
->mouse_face_past_end
7131 = !fast_find_position (w
, XFASTINT (after
),
7132 &dpyinfo
->mouse_face_end_col
,
7133 &dpyinfo
->mouse_face_end_row
,
7134 &dpyinfo
->mouse_face_end_x
,
7135 &dpyinfo
->mouse_face_end_y
, Qnil
);
7136 dpyinfo
->mouse_face_window
= window
;
7138 if (BUFFERP (object
))
7139 dpyinfo
->mouse_face_face_id
7140 = face_at_buffer_position (w
, pos
, 0, 0,
7142 !dpyinfo
->mouse_face_hidden
);
7144 /* Display it as active. */
7145 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7146 /* TODO: mouse cursor changes. */
7148 else if (!NILP (mouse_face
) && STRINGP (object
))
7153 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7156 e
= Fnext_single_property_change (position
, Qmouse_face
,
7159 b
= make_number (0);
7161 e
= make_number (SCHARS (object
) - 1);
7162 fast_find_string_pos (w
, XINT (b
), object
,
7163 &dpyinfo
->mouse_face_beg_col
,
7164 &dpyinfo
->mouse_face_beg_row
,
7165 &dpyinfo
->mouse_face_beg_x
,
7166 &dpyinfo
->mouse_face_beg_y
, 0);
7167 fast_find_string_pos (w
, XINT (e
), object
,
7168 &dpyinfo
->mouse_face_end_col
,
7169 &dpyinfo
->mouse_face_end_row
,
7170 &dpyinfo
->mouse_face_end_x
,
7171 &dpyinfo
->mouse_face_end_y
, 1);
7172 dpyinfo
->mouse_face_past_end
= 0;
7173 dpyinfo
->mouse_face_window
= window
;
7174 dpyinfo
->mouse_face_face_id
7175 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7177 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7178 /* TODO: mouse cursor changes. */
7180 else if (STRINGP (object
) && NILP (mouse_face
))
7182 /* A string which doesn't have mouse-face, but
7183 the text ``under'' it might have. */
7184 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7185 int start
= MATRIX_ROW_START_CHARPOS (r
);
7187 pos
= string_buffer_position (w
, object
, start
);
7189 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7193 if (!NILP (mouse_face
) && !NILP (overlay
))
7195 Lisp_Object before
= Foverlay_start (overlay
);
7196 Lisp_Object after
= Foverlay_end (overlay
);
7199 /* Note that we might not be able to find position
7200 BEFORE in the glyph matrix if the overlay is
7201 entirely covered by a `display' property. In
7202 this case, we overshoot. So let's stop in
7203 the glyph matrix before glyphs for OBJECT. */
7204 fast_find_position (w
, XFASTINT (before
),
7205 &dpyinfo
->mouse_face_beg_col
,
7206 &dpyinfo
->mouse_face_beg_row
,
7207 &dpyinfo
->mouse_face_beg_x
,
7208 &dpyinfo
->mouse_face_beg_y
,
7211 dpyinfo
->mouse_face_past_end
7212 = !fast_find_position (w
, XFASTINT (after
),
7213 &dpyinfo
->mouse_face_end_col
,
7214 &dpyinfo
->mouse_face_end_row
,
7215 &dpyinfo
->mouse_face_end_x
,
7216 &dpyinfo
->mouse_face_end_y
,
7218 dpyinfo
->mouse_face_window
= window
;
7219 dpyinfo
->mouse_face_face_id
7220 = face_at_buffer_position (w
, pos
, 0, 0,
7222 !dpyinfo
->mouse_face_hidden
);
7224 /* Display it as active. */
7225 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7226 /* TODO: mouse cursor changes. */
7233 /* Look for a `help-echo' property. */
7235 Lisp_Object help
, overlay
;
7237 /* Check overlays first. */
7238 help
= overlay
= Qnil
;
7239 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7241 overlay
= overlay_vec
[i
];
7242 help
= Foverlay_get (overlay
, Qhelp_echo
);
7248 help_echo_window
= window
;
7249 help_echo_object
= overlay
;
7250 help_echo_pos
= pos
;
7254 Lisp_Object object
= glyph
->object
;
7255 int charpos
= glyph
->charpos
;
7257 /* Try text properties. */
7258 if (STRINGP (object
)
7260 && charpos
< SCHARS (object
))
7262 help
= Fget_text_property (make_number (charpos
),
7263 Qhelp_echo
, object
);
7266 /* If the string itself doesn't specify a help-echo,
7267 see if the buffer text ``under'' it does. */
7269 = MATRIX_ROW (w
->current_matrix
, vpos
);
7270 int start
= MATRIX_ROW_START_CHARPOS (r
);
7271 int pos
= string_buffer_position (w
, object
, start
);
7274 help
= Fget_char_property (make_number (pos
),
7275 Qhelp_echo
, w
->buffer
);
7284 else if (BUFFERP (object
)
7287 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7293 help_echo_window
= window
;
7294 help_echo_object
= object
;
7295 help_echo_pos
= charpos
;
7302 current_buffer
= obuf
;
7306 /* TODO: mouse cursor changes. */
7311 redo_mouse_highlight ()
7313 if (!NILP (last_mouse_motion_frame
)
7314 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7315 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7316 last_mouse_motion_position
.h
,
7317 last_mouse_motion_position
.v
);
7322 /***********************************************************************
7324 ***********************************************************************/
7326 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7327 struct glyph
**, int *, int *, int *));
7329 /* Tool-bar item index of the item on which a mouse button was pressed
7332 static int last_tool_bar_item
;
7335 /* Get information about the tool-bar item at position X/Y on frame F.
7336 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7337 the current matrix of the tool-bar window of F, or NULL if not
7338 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7339 item in F->current_tool_bar_items. Value is
7341 -1 if X/Y is not on a tool-bar item
7342 0 if X/Y is on the same item that was highlighted before.
7346 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7349 struct glyph
**glyph
;
7350 int *hpos
, *vpos
, *prop_idx
;
7352 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7353 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7356 /* Find the glyph under X/Y. */
7357 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7361 /* Get the start of this tool-bar item's properties in
7362 f->current_tool_bar_items. */
7363 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7366 /* Is mouse on the highlighted item? */
7367 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7368 && *vpos
>= dpyinfo
->mouse_face_beg_row
7369 && *vpos
<= dpyinfo
->mouse_face_end_row
7370 && (*vpos
> dpyinfo
->mouse_face_beg_row
7371 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7372 && (*vpos
< dpyinfo
->mouse_face_end_row
7373 || *hpos
< dpyinfo
->mouse_face_end_col
7374 || dpyinfo
->mouse_face_past_end
))
7381 /* Handle mouse button event on the tool-bar of frame F, at
7382 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7386 x_handle_tool_bar_click (f
, button_event
)
7388 EventRecord
*button_event
;
7390 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7391 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7392 int hpos
, vpos
, prop_idx
;
7393 struct glyph
*glyph
;
7394 Lisp_Object enabled_p
;
7395 int x
= button_event
->where
.h
;
7396 int y
= button_event
->where
.v
;
7398 /* If not on the highlighted tool-bar item, return. */
7399 frame_to_window_pixel_xy (w
, &x
, &y
);
7400 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7403 /* If item is disabled, do nothing. */
7404 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7405 if (NILP (enabled_p
))
7408 if (button_event
->what
== mouseDown
)
7410 /* Show item in pressed state. */
7411 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7412 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7413 last_tool_bar_item
= prop_idx
;
7417 Lisp_Object key
, frame
;
7418 struct input_event event
;
7420 /* Show item in released state. */
7421 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7422 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7424 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7426 XSETFRAME (frame
, f
);
7427 event
.kind
= TOOL_BAR_EVENT
;
7428 event
.frame_or_window
= frame
;
7430 kbd_buffer_store_event (&event
);
7432 event
.kind
= TOOL_BAR_EVENT
;
7433 event
.frame_or_window
= frame
;
7435 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7436 button_event
->modifiers
);
7437 kbd_buffer_store_event (&event
);
7438 last_tool_bar_item
= -1;
7443 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7444 tool-bar window-relative coordinates X/Y. Called from
7445 note_mouse_highlight. */
7448 note_tool_bar_highlight (f
, x
, y
)
7452 Lisp_Object window
= f
->tool_bar_window
;
7453 struct window
*w
= XWINDOW (window
);
7454 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7456 struct glyph
*glyph
;
7457 struct glyph_row
*row
;
7459 Lisp_Object enabled_p
;
7461 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7462 int mouse_down_p
, rc
;
7464 /* Function note_mouse_highlight is called with negative x(y
7465 values when mouse moves outside of the frame. */
7466 if (x
<= 0 || y
<= 0)
7468 clear_mouse_face (dpyinfo
);
7472 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7475 /* Not on tool-bar item. */
7476 clear_mouse_face (dpyinfo
);
7480 /* On same tool-bar item as before. */
7483 clear_mouse_face (dpyinfo
);
7485 /* Mouse is down, but on different tool-bar item? */
7486 mouse_down_p
= (dpyinfo
->grabbed
7487 && f
== last_mouse_frame
7488 && FRAME_LIVE_P (f
));
7490 && last_tool_bar_item
!= prop_idx
)
7493 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7494 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7496 /* If tool-bar item is not enabled, don't highlight it. */
7497 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7498 if (!NILP (enabled_p
))
7500 /* Compute the x-position of the glyph. In front and past the
7501 image is a space. We include this is the highlighted area. */
7502 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7503 for (i
= x
= 0; i
< hpos
; ++i
)
7504 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7506 /* Record this as the current active region. */
7507 dpyinfo
->mouse_face_beg_col
= hpos
;
7508 dpyinfo
->mouse_face_beg_row
= vpos
;
7509 dpyinfo
->mouse_face_beg_x
= x
;
7510 dpyinfo
->mouse_face_beg_y
= row
->y
;
7511 dpyinfo
->mouse_face_past_end
= 0;
7513 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7514 dpyinfo
->mouse_face_end_row
= vpos
;
7515 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7516 dpyinfo
->mouse_face_end_y
= row
->y
;
7517 dpyinfo
->mouse_face_window
= window
;
7518 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7520 /* Display it as active. */
7521 show_mouse_face (dpyinfo
, draw
);
7522 dpyinfo
->mouse_face_image_state
= draw
;
7527 /* Set help_echo to a help string.to display for this tool-bar item.
7528 XTread_socket does the rest. */
7529 help_echo_object
= help_echo_window
= Qnil
;
7531 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7532 if (NILP (help_echo
))
7533 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7538 /* Find the glyph matrix position of buffer position CHARPOS in window
7539 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7540 current glyphs must be up to date. If CHARPOS is above window
7541 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7542 of last line in W. In the row containing CHARPOS, stop before glyphs
7543 having STOP as object. */
7545 #if 0 /* This is a version of fast_find_position that's more correct
7546 in the presence of hscrolling, for example. I didn't install
7547 it right away because the problem fixed is minor, it failed
7548 in 20.x as well, and I think it's too risky to install
7549 so near the release of 21.1. 2001-09-25 gerd. */
7552 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7555 int *hpos
, *vpos
, *x
, *y
;
7558 struct glyph_row
*row
, *first
;
7559 struct glyph
*glyph
, *end
;
7560 int i
, past_end
= 0;
7562 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7563 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7566 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7568 *x
= *y
= *hpos
= *vpos
= 0;
7573 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7580 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7582 glyph
= row
->glyphs
[TEXT_AREA
];
7583 end
= glyph
+ row
->used
[TEXT_AREA
];
7585 /* Skip over glyphs not having an object at the start of the row.
7586 These are special glyphs like truncation marks on terminal
7588 if (row
->displays_text_p
)
7590 && INTEGERP (glyph
->object
)
7591 && !EQ (stop
, glyph
->object
)
7592 && glyph
->charpos
< 0)
7594 *x
+= glyph
->pixel_width
;
7599 && !INTEGERP (glyph
->object
)
7600 && !EQ (stop
, glyph
->object
)
7601 && (!BUFFERP (glyph
->object
)
7602 || glyph
->charpos
< charpos
))
7604 *x
+= glyph
->pixel_width
;
7608 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7615 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7618 int *hpos
, *vpos
, *x
, *y
;
7623 int maybe_next_line_p
= 0;
7624 int line_start_position
;
7625 int yb
= window_text_bottom_y (w
);
7626 struct glyph_row
*row
, *best_row
;
7627 int row_vpos
, best_row_vpos
;
7630 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7631 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7635 if (row
->used
[TEXT_AREA
])
7636 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7638 line_start_position
= 0;
7640 if (line_start_position
> pos
)
7642 /* If the position sought is the end of the buffer,
7643 don't include the blank lines at the bottom of the window. */
7644 else if (line_start_position
== pos
7645 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7647 maybe_next_line_p
= 1;
7650 else if (line_start_position
> 0)
7653 best_row_vpos
= row_vpos
;
7656 if (row
->y
+ row
->height
>= yb
)
7663 /* Find the right column within BEST_ROW. */
7665 current_x
= best_row
->x
;
7666 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7668 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7669 int charpos
= glyph
->charpos
;
7671 if (BUFFERP (glyph
->object
))
7676 *vpos
= best_row_vpos
;
7681 else if (charpos
> pos
)
7684 else if (EQ (glyph
->object
, stop
))
7689 current_x
+= glyph
->pixel_width
;
7692 /* If we're looking for the end of the buffer,
7693 and we didn't find it in the line we scanned,
7694 use the start of the following line. */
7695 if (maybe_next_line_p
)
7700 current_x
= best_row
->x
;
7703 *vpos
= best_row_vpos
;
7704 *hpos
= lastcol
+ 1;
7713 /* Find the position of the glyph for position POS in OBJECT in
7714 window W's current matrix, and return in *X/*Y the pixel
7715 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7717 RIGHT_P non-zero means return the position of the right edge of the
7718 glyph, RIGHT_P zero means return the left edge position.
7720 If no glyph for POS exists in the matrix, return the position of
7721 the glyph with the next smaller position that is in the matrix, if
7722 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7723 exists in the matrix, return the position of the glyph with the
7724 next larger position in OBJECT.
7726 Value is non-zero if a glyph was found. */
7729 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7733 int *hpos
, *vpos
, *x
, *y
;
7736 int yb
= window_text_bottom_y (w
);
7737 struct glyph_row
*r
;
7738 struct glyph
*best_glyph
= NULL
;
7739 struct glyph_row
*best_row
= NULL
;
7742 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7743 r
->enabled_p
&& r
->y
< yb
;
7746 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7747 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7750 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7751 if (EQ (g
->object
, object
))
7753 if (g
->charpos
== pos
)
7760 else if (best_glyph
== NULL
7761 || ((abs (g
->charpos
- pos
)
7762 < abs (best_glyph
->charpos
- pos
))
7765 : g
->charpos
> pos
)))
7779 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7783 *x
+= best_glyph
->pixel_width
;
7788 *vpos
= best_row
- w
->current_matrix
->rows
;
7791 return best_glyph
!= NULL
;
7795 /* Display the active region described by mouse_face_*
7796 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7799 show_mouse_face (dpyinfo
, draw
)
7800 struct mac_display_info
*dpyinfo
;
7801 enum draw_glyphs_face draw
;
7803 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7804 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7806 if (/* If window is in the process of being destroyed, don't bother
7808 w
->current_matrix
!= NULL
7809 /* Don't update mouse highlight if hidden */
7810 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7811 /* Recognize when we are called to operate on rows that don't exist
7812 anymore. This can happen when a window is split. */
7813 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7815 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7816 struct glyph_row
*row
, *first
, *last
;
7818 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7819 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7821 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7823 int start_hpos
, end_hpos
, start_x
;
7825 /* For all but the first row, the highlight starts at column 0. */
7828 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7829 start_x
= dpyinfo
->mouse_face_beg_x
;
7838 end_hpos
= dpyinfo
->mouse_face_end_col
;
7840 end_hpos
= row
->used
[TEXT_AREA
];
7842 if (end_hpos
> start_hpos
)
7844 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7845 start_hpos
, end_hpos
, draw
, 0);
7848 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
7852 /* When we've written over the cursor, arrange for it to
7853 be displayed again. */
7854 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
7855 x_display_cursor (w
, 1,
7856 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
7857 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
7860 #if 0 /* MAC_TODO: mouse cursor */
7861 /* Change the mouse cursor. */
7862 if (draw
== DRAW_NORMAL_TEXT
)
7863 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7864 f
->output_data
.x
->text_cursor
);
7865 else if (draw
== DRAW_MOUSE_FACE
)
7866 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7867 f
->output_data
.x
->cross_cursor
);
7869 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7870 f
->output_data
.x
->nontext_cursor
);
7874 /* Clear out the mouse-highlighted active region.
7875 Redraw it un-highlighted first. */
7878 clear_mouse_face (dpyinfo
)
7879 struct mac_display_info
*dpyinfo
;
7883 if (! NILP (dpyinfo
->mouse_face_window
))
7885 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7889 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7890 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7891 dpyinfo
->mouse_face_window
= Qnil
;
7892 dpyinfo
->mouse_face_overlay
= Qnil
;
7897 /* Clear any mouse-face on window W. This function is part of the
7898 redisplay interface, and is called from try_window_id and similar
7899 functions to ensure the mouse-highlight is off. */
7902 x_clear_mouse_face (w
)
7905 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
7909 XSETWINDOW (window
, w
);
7910 if (EQ (window
, dpyinfo
->mouse_face_window
))
7911 clear_mouse_face (dpyinfo
);
7916 /* Just discard the mouse face information for frame F, if any.
7917 This is used when the size of F is changed. */
7920 cancel_mouse_face (f
)
7924 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7926 window
= dpyinfo
->mouse_face_window
;
7927 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7929 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7930 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7931 dpyinfo
->mouse_face_window
= Qnil
;
7935 static struct scroll_bar
*x_window_to_scroll_bar ();
7936 static void x_scroll_bar_report_motion ();
7937 static void x_check_fullscreen
P_ ((struct frame
*));
7938 static void x_check_fullscreen_move
P_ ((struct frame
*));
7939 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
7942 /* Try to determine frame pixel position and size of the glyph under
7943 frame pixel coordinates X/Y on frame F . Return the position and
7944 size in *RECT. Value is non-zero if we could compute these
7948 glyph_rect (f
, x
, y
, rect
)
7956 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
7959 struct window
*w
= XWINDOW (window
);
7960 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7961 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
7963 frame_to_window_pixel_xy (w
, &x
, &y
);
7965 for (; r
< end
&& r
->enabled_p
; ++r
)
7966 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
7968 /* Found the row at y. */
7969 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7970 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
7973 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
7974 rect
->bottom
= rect
->top
+ r
->height
;
7978 /* x is to the left of the first glyph in the row. */
7979 rect
->left
= XINT (w
->left
);
7980 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
7984 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
7985 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
7987 /* x is on a glyph. */
7988 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7989 rect
->right
= rect
->left
+ g
->pixel_width
;
7993 /* x is to the right of the last glyph in the row. */
7994 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
7995 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8000 /* The y is not on any row. */
8004 /* Record the position of the mouse in last_mouse_glyph. */
8006 remember_mouse_glyph (f1
, gx
, gy
)
8010 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8012 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8013 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8015 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8016 round down even for negative values. */
8022 /* This was the original code from XTmouse_position, but it seems
8023 to give the position of the glyph diagonally next to the one
8024 the mouse is over. */
8025 gx
= (gx
+ width
- 1) / width
* width
;
8026 gy
= (gy
+ height
- 1) / height
* height
;
8028 gx
= gx
/ width
* width
;
8029 gy
= gy
/ height
* height
;
8032 last_mouse_glyph
.left
= gx
;
8033 last_mouse_glyph
.top
= gy
;
8034 last_mouse_glyph
.right
= gx
+ width
;
8035 last_mouse_glyph
.bottom
= gy
+ height
;
8039 /* Return the current position of the mouse.
8040 *fp should be a frame which indicates which display to ask about.
8042 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8043 and *part to the frame, window, and scroll bar part that the mouse
8044 is over. Set *x and *y to the portion and whole of the mouse's
8045 position on the scroll bar.
8047 If the mouse movement started elsewhere, set *fp to the frame the
8048 mouse is on, *bar_window to nil, and *x and *y to the character cell
8051 Set *time to the server time-stamp for the time at which the mouse
8052 was at this position.
8054 Don't store anything if we don't have a valid set of values to report.
8056 This clears the mouse_moved flag, so we can wait for the next mouse
8060 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8063 Lisp_Object
*bar_window
;
8064 enum scroll_bar_part
*part
;
8066 unsigned long *time
;
8069 int ignore1
, ignore2
;
8070 WindowPtr wp
= FrontWindow ();
8072 Lisp_Object frame
, tail
;
8074 if (is_emacs_window(wp
))
8075 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8079 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8080 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8083 /* Clear the mouse-moved flag for every frame on this display. */
8084 FOR_EACH_FRAME (tail
, frame
)
8085 XFRAME (frame
)->mouse_moved
= 0;
8087 last_mouse_scroll_bar
= Qnil
;
8089 #if TARGET_API_MAC_CARBON
8090 SetPort (GetWindowPort (wp
));
8095 GetMouse (&mouse_pos
);
8097 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8098 &last_mouse_glyph
, insist
);
8101 *part
= scroll_bar_handle
;
8103 XSETINT (*x
, mouse_pos
.h
);
8104 XSETINT (*y
, mouse_pos
.v
);
8105 *time
= last_mouse_movement_time
;
8112 /************************************************************************
8113 Scroll bars, general
8114 ************************************************************************/
8116 /* Create a scroll bar and return the scroll bar vector for it. W is
8117 the Emacs window on which to create the scroll bar. TOP, LEFT,
8118 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8121 static struct scroll_bar
*
8122 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8124 int top
, left
, width
, height
, disp_top
, disp_height
;
8126 struct frame
*f
= XFRAME (w
->frame
);
8127 struct scroll_bar
*bar
8128 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8136 r
.right
= left
+ width
;
8137 r
.bottom
= disp_top
+ disp_height
;
8139 #ifdef TARGET_API_MAC_CARBON
8140 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8141 kControlScrollBarProc
, 0L);
8143 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8146 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8147 SetControlReference (ch
, (long) bar
);
8149 XSETWINDOW (bar
->window
, w
);
8150 XSETINT (bar
->top
, top
);
8151 XSETINT (bar
->left
, left
);
8152 XSETINT (bar
->width
, width
);
8153 XSETINT (bar
->height
, height
);
8154 XSETINT (bar
->start
, 0);
8155 XSETINT (bar
->end
, 0);
8156 bar
->dragging
= Qnil
;
8158 /* Add bar to its frame's list of scroll bars. */
8159 bar
->next
= FRAME_SCROLL_BARS (f
);
8161 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8162 if (!NILP (bar
->next
))
8163 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8170 /* Draw BAR's handle in the proper position.
8172 If the handle is already drawn from START to END, don't bother
8173 redrawing it, unless REBUILD is non-zero; in that case, always
8174 redraw it. (REBUILD is handy for drawing the handle after expose
8177 Normally, we want to constrain the start and end of the handle to
8178 fit inside its rectangle, but if the user is dragging the scroll
8179 bar handle, we want to let them drag it down all the way, so that
8180 the bar's top is as far down as it goes; otherwise, there's no way
8181 to move to the very end of the buffer. */
8184 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8185 struct scroll_bar
*bar
;
8189 int dragging
= ! NILP (bar
->dragging
);
8190 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8191 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8192 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8193 int length
= end
- start
;
8195 /* If the display is already accurate, do nothing. */
8197 && start
== XINT (bar
->start
)
8198 && end
== XINT (bar
->end
))
8203 /* Make sure the values are reasonable, and try to preserve the
8204 distance between start and end. */
8207 else if (start
> top_range
)
8209 end
= start
+ length
;
8213 else if (end
> top_range
&& ! dragging
)
8216 /* Store the adjusted setting in the scroll bar. */
8217 XSETINT (bar
->start
, start
);
8218 XSETINT (bar
->end
, end
);
8220 /* Clip the end position, just for display. */
8221 if (end
> top_range
)
8224 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8225 top positions, to make sure the handle is always at least that
8226 many pixels tall. */
8227 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8229 SetControlMinimum (ch
, 0);
8230 /* Don't inadvertently activate deactivated scroll bars */
8231 if (GetControlMaximum (ch
) != -1)
8232 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8234 SetControlValue (ch
, start
);
8235 #if TARGET_API_MAC_CARBON
8236 SetControlViewSize (ch
, end
- start
);
8243 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8247 x_scroll_bar_remove (bar
)
8248 struct scroll_bar
*bar
;
8250 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8254 /* Destroy the Mac scroll bar control */
8255 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8257 /* Disassociate this scroll bar from its window. */
8258 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8263 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8264 that we are displaying PORTION characters out of a total of WHOLE
8265 characters, starting at POSITION. If WINDOW has no scroll bar,
8268 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8270 int portion
, whole
, position
;
8272 struct frame
*f
= XFRAME (w
->frame
);
8273 struct scroll_bar
*bar
;
8274 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8275 int window_x
, window_y
, window_width
, window_height
;
8277 /* Get window dimensions. */
8278 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8283 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8285 height
= window_height
;
8287 /* Compute the left edge of the scroll bar area. */
8288 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8289 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8291 left
= XFASTINT (w
->left
);
8292 left
*= CANON_X_UNIT (f
);
8293 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8295 /* Compute the width of the scroll bar which might be less than
8296 the width of the area reserved for the scroll bar. */
8297 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8298 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8302 /* Compute the left edge of the scroll bar. */
8303 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8304 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8306 sb_left
= left
+ (width
- sb_width
) / 2;
8308 /* Adjustments according to Inside Macintosh to make it look nice */
8310 disp_height
= height
;
8316 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8322 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8325 /* Does the scroll bar exist yet? */
8326 if (NILP (w
->vertical_scroll_bar
))
8329 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8330 left
, top
, width
, height
, 0);
8332 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8334 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8338 /* It may just need to be moved and resized. */
8341 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8342 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8346 /* If already correctly positioned, do nothing. */
8347 if (XINT (bar
->left
) == sb_left
8348 && XINT (bar
->top
) == top
8349 && XINT (bar
->width
) == sb_width
8350 && XINT (bar
->height
) == height
)
8354 /* Clear areas not covered by the scroll bar because it's not as
8355 wide as the area reserved for it . This makes sure a
8356 previous mode line display is cleared after C-x 2 C-x 1, for
8358 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8359 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8360 left
, top
, area_width
, height
, 0);
8363 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8364 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8365 sb_left
- 1, top
, 1, height
, 0);
8369 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8370 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8374 /* Remember new settings. */
8375 XSETINT (bar
->left
, sb_left
);
8376 XSETINT (bar
->top
, top
);
8377 XSETINT (bar
->width
, sb_width
);
8378 XSETINT (bar
->height
, height
);
8384 /* Set the scroll bar's current state, unless we're currently being
8386 if (NILP (bar
->dragging
))
8388 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8391 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8394 int start
= ((double) position
* top_range
) / whole
;
8395 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8396 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8402 /* The following three hooks are used when we're doing a thorough
8403 redisplay of the frame. We don't explicitly know which scroll bars
8404 are going to be deleted, because keeping track of when windows go
8405 away is a real pain - "Can you say set-window-configuration, boys
8406 and girls?" Instead, we just assert at the beginning of redisplay
8407 that *all* scroll bars are to be removed, and then save a scroll bar
8408 from the fiery pit when we actually redisplay its window. */
8410 /* Arrange for all scroll bars on FRAME to be removed at the next call
8411 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8412 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8415 XTcondemn_scroll_bars (frame
)
8418 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8419 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8422 bar
= FRAME_SCROLL_BARS (frame
);
8423 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8424 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8425 XSCROLL_BAR (bar
)->prev
= Qnil
;
8426 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8427 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8428 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8433 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8434 Note that WINDOW isn't necessarily condemned at all. */
8437 XTredeem_scroll_bar (window
)
8438 struct window
*window
;
8440 struct scroll_bar
*bar
;
8442 /* We can't redeem this window's scroll bar if it doesn't have one. */
8443 if (NILP (window
->vertical_scroll_bar
))
8446 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8448 /* Unlink it from the condemned list. */
8450 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8452 if (NILP (bar
->prev
))
8454 /* If the prev pointer is nil, it must be the first in one of
8456 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8457 /* It's not condemned. Everything's fine. */
8459 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8460 window
->vertical_scroll_bar
))
8461 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8463 /* If its prev pointer is nil, it must be at the front of
8464 one or the other! */
8468 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8470 if (! NILP (bar
->next
))
8471 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8473 bar
->next
= FRAME_SCROLL_BARS (f
);
8475 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8476 if (! NILP (bar
->next
))
8477 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8481 /* Remove all scroll bars on FRAME that haven't been saved since the
8482 last call to `*condemn_scroll_bars_hook'. */
8485 XTjudge_scroll_bars (f
)
8488 Lisp_Object bar
, next
;
8490 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8492 /* Clear out the condemned list now so we won't try to process any
8493 more events on the hapless scroll bars. */
8494 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8496 for (; ! NILP (bar
); bar
= next
)
8498 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8500 x_scroll_bar_remove (b
);
8503 b
->next
= b
->prev
= Qnil
;
8506 /* Now there should be no references to the condemned scroll bars,
8507 and they should get garbage-collected. */
8512 activate_scroll_bars (frame
)
8518 bar
= FRAME_SCROLL_BARS (frame
);
8519 while (! NILP (bar
))
8521 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8522 #ifdef TARGET_API_MAC_CARBON
8523 ActivateControl (ch
);
8525 SetControlMaximum (ch
,
8526 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8527 XINT (XSCROLL_BAR (bar
)
8530 bar
= XSCROLL_BAR (bar
)->next
;
8536 deactivate_scroll_bars (frame
)
8542 bar
= FRAME_SCROLL_BARS (frame
);
8543 while (! NILP (bar
))
8545 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8546 #ifdef TARGET_API_MAC_CARBON
8547 DeactivateControl (ch
);
8549 SetControlMaximum (ch
, XINT (-1));
8551 bar
= XSCROLL_BAR (bar
)->next
;
8555 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8556 is set to something other than NO_EVENT, it is enqueued.
8558 This may be called from a signal handler, so we have to ignore GC
8562 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8563 struct scroll_bar
*bar
;
8566 struct input_event
*bufp
;
8568 if (! GC_WINDOWP (bar
->window
))
8571 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
8572 bufp
->frame_or_window
= bar
->window
;
8575 bar
->dragging
= Qnil
;
8579 case kControlUpButtonPart
:
8580 bufp
->part
= scroll_bar_up_arrow
;
8582 case kControlDownButtonPart
:
8583 bufp
->part
= scroll_bar_down_arrow
;
8585 case kControlPageUpPart
:
8586 bufp
->part
= scroll_bar_above_handle
;
8588 case kControlPageDownPart
:
8589 bufp
->part
= scroll_bar_below_handle
;
8591 #ifdef TARGET_API_MAC_CARBON
8594 case kControlIndicatorPart
:
8596 if (er
->what
== mouseDown
)
8597 bar
->dragging
= make_number (0);
8598 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8599 bufp
->part
= scroll_bar_handle
;
8605 /* Handle some mouse motion while someone is dragging the scroll bar.
8607 This may be called from a signal handler, so we have to ignore GC
8611 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8612 struct scroll_bar
*bar
;
8616 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8618 last_mouse_movement_time
= t
;
8621 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8623 /* If we're dragging the bar, display it. */
8624 if (! GC_NILP (bar
->dragging
))
8626 /* Where should the handle be now? */
8627 int new_start
= y_pos
- 24;
8629 if (new_start
!= XINT (bar
->start
))
8631 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8633 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8639 /* Return information to the user about the current position of the
8640 mouse on the scroll bar. */
8643 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8645 Lisp_Object
*bar_window
;
8646 enum scroll_bar_part
*part
;
8648 unsigned long *time
;
8650 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8651 WindowPtr wp
= FrontWindow ();
8653 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8654 int win_y
, top_range
;
8656 #if TARGET_API_MAC_CARBON
8657 SetPort (GetWindowPort (wp
));
8662 GetMouse (&mouse_pos
);
8664 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8665 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8667 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8671 if (! NILP (bar
->dragging
))
8672 win_y
-= XINT (bar
->dragging
);
8676 if (win_y
> top_range
)
8680 *bar_window
= bar
->window
;
8682 if (! NILP (bar
->dragging
))
8683 *part
= scroll_bar_handle
;
8684 else if (win_y
< XINT (bar
->start
))
8685 *part
= scroll_bar_above_handle
;
8686 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8687 *part
= scroll_bar_handle
;
8689 *part
= scroll_bar_below_handle
;
8691 XSETINT (*x
, win_y
);
8692 XSETINT (*y
, top_range
);
8695 last_mouse_scroll_bar
= Qnil
;
8697 *time
= last_mouse_movement_time
;
8700 /***********************************************************************
8702 ***********************************************************************/
8704 /* Notice if the text cursor of window W has been overwritten by a
8705 drawing operation that outputs glyphs starting at START_X and
8706 ending at END_X in the line given by output_cursor.vpos.
8707 Coordinates are area-relative. END_X < 0 means all the rest
8708 of the line after START_X has been written. */
8711 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8713 enum glyph_row_area area
;
8716 if (area
== TEXT_AREA
8717 && w
->phys_cursor_on_p
8718 && y0
<= w
->phys_cursor
.y
8719 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8720 && x0
<= w
->phys_cursor
.x
8721 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8722 w
->phys_cursor_on_p
= 0;
8726 /* Set clipping for output in glyph row ROW. W is the window in which
8727 we operate. GC is the graphics context to set clipping in.
8728 WHOLE_LINE_P non-zero means include the areas used for truncation
8729 mark display and alike in the clipping rectangle.
8731 ROW may be a text row or, e.g., a mode line. Text rows must be
8732 clipped to the interior of the window dedicated to text display,
8733 mode lines must be clipped to the whole window. */
8736 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8738 struct glyph_row
*row
;
8742 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8744 int window_x
, window_y
, window_width
, window_height
;
8746 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8748 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8749 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8750 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8751 clip_rect
.right
= clip_rect
.left
+ window_width
;
8752 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8754 /* If clipping to the whole line, including trunc marks, extend
8755 the rectangle to the left and increase its width. */
8758 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8759 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8762 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8766 /* Draw a hollow box cursor on window W in glyph row ROW. */
8769 x_draw_hollow_cursor (w
, row
)
8771 struct glyph_row
*row
;
8773 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8774 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8775 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8778 struct glyph
*cursor_glyph
;
8781 /* Compute frame-relative coordinates from window-relative
8783 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8784 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8785 + row
->ascent
- w
->phys_cursor_ascent
);
8786 h
= row
->height
- 1;
8788 /* Get the glyph the cursor is on. If we can't tell because
8789 the current matrix is invalid or such, give up. */
8790 cursor_glyph
= get_phys_cursor_glyph (w
);
8791 if (cursor_glyph
== NULL
)
8794 /* Compute the width of the rectangle to draw. If on a stretch
8795 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8796 rectangle as wide as the glyph, but use a canonical character
8798 wd
= cursor_glyph
->pixel_width
- 1;
8799 if (cursor_glyph
->type
== STRETCH_GLYPH
8800 && !x_stretch_cursor_p
)
8801 wd
= min (CANON_X_UNIT (f
), wd
);
8803 /* The foreground of cursor_gc is typically the same as the normal
8804 background color, which can cause the cursor box to be invisible. */
8805 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8806 if (dpyinfo
->scratch_cursor_gc
)
8807 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8809 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8810 GCForeground
, &xgcv
);
8811 gc
= dpyinfo
->scratch_cursor_gc
;
8813 /* Set clipping, draw the rectangle, and reset clipping again. */
8814 x_clip_to_row (w
, row
, gc
, 0);
8815 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
8816 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8820 /* Draw a bar cursor on window W in glyph row ROW.
8822 Implementation note: One would like to draw a bar cursor with an
8823 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8824 Unfortunately, I didn't find a font yet that has this property set.
8828 x_draw_bar_cursor (w
, row
, width
)
8830 struct glyph_row
*row
;
8833 /* If cursor hpos is out of bounds, don't draw garbage. This can
8834 happen in mini-buffer windows when switching between echo area
8835 glyphs and mini-buffer. */
8836 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8838 struct frame
*f
= XFRAME (w
->frame
);
8839 struct glyph
*cursor_glyph
;
8847 cursor_glyph
= get_phys_cursor_glyph (w
);
8848 if (cursor_glyph
== NULL
)
8851 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
8852 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8853 mask
= GCForeground
| GCBackground
;
8854 dpy
= FRAME_MAC_DISPLAY (f
);
8855 window
= FRAME_MAC_WINDOW (f
);
8856 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
8859 XChangeGC (dpy
, gc
, mask
, &xgcv
);
8862 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
8863 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
8867 width
= FRAME_CURSOR_WIDTH (f
);
8869 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8870 x_clip_to_row (w
, row
, gc
, 0);
8871 XFillRectangle (dpy
, window
, gc
,
8873 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8874 min (cursor_glyph
->pixel_width
, width
),
8876 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8881 /* Clear the cursor of window W to background color, and mark the
8882 cursor as not shown. This is used when the text where the cursor
8883 is is about to be rewritten. */
8889 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8890 x_update_window_cursor (w
, 0);
8894 /* Draw the cursor glyph of window W in glyph row ROW. See the
8895 comment of x_draw_glyphs for the meaning of HL. */
8898 x_draw_phys_cursor_glyph (w
, row
, hl
)
8900 struct glyph_row
*row
;
8901 enum draw_glyphs_face hl
;
8903 /* If cursor hpos is out of bounds, don't draw garbage. This can
8904 happen in mini-buffer windows when switching between echo area
8905 glyphs and mini-buffer. */
8906 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8908 int on_p
= w
->phys_cursor_on_p
;
8909 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8910 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8912 w
->phys_cursor_on_p
= on_p
;
8914 /* When we erase the cursor, and ROW is overlapped by other
8915 rows, make sure that these overlapping parts of other rows
8917 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8919 if (row
> w
->current_matrix
->rows
8920 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8921 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8923 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8924 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8925 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8931 /* Erase the image of a cursor of window W from the screen. */
8934 x_erase_phys_cursor (w
)
8937 struct frame
*f
= XFRAME (w
->frame
);
8938 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8939 int hpos
= w
->phys_cursor
.hpos
;
8940 int vpos
= w
->phys_cursor
.vpos
;
8941 int mouse_face_here_p
= 0;
8942 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8943 struct glyph_row
*cursor_row
;
8944 struct glyph
*cursor_glyph
;
8945 enum draw_glyphs_face hl
;
8947 /* No cursor displayed or row invalidated => nothing to do on the
8949 if (w
->phys_cursor_type
== NO_CURSOR
)
8950 goto mark_cursor_off
;
8952 /* VPOS >= active_glyphs->nrows means that window has been resized.
8953 Don't bother to erase the cursor. */
8954 if (vpos
>= active_glyphs
->nrows
)
8955 goto mark_cursor_off
;
8957 /* If row containing cursor is marked invalid, there is nothing we
8959 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8960 if (!cursor_row
->enabled_p
)
8961 goto mark_cursor_off
;
8963 /* If row is completely invisible, don't attempt to delete a cursor which
8964 isn't there. This may happen if cursor is at top of window, and
8965 we switch to a buffer with a header line in that window. */
8966 if (cursor_row
->visible_height
<= 0)
8967 goto mark_cursor_off
;
8969 /* This can happen when the new row is shorter than the old one.
8970 In this case, either x_draw_glyphs or clear_end_of_line
8971 should have cleared the cursor. Note that we wouldn't be
8972 able to erase the cursor in this case because we don't have a
8973 cursor glyph at hand. */
8974 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8975 goto mark_cursor_off
;
8977 /* If the cursor is in the mouse face area, redisplay that when
8978 we clear the cursor. */
8979 if (! NILP (dpyinfo
->mouse_face_window
)
8980 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
8981 && (vpos
> dpyinfo
->mouse_face_beg_row
8982 || (vpos
== dpyinfo
->mouse_face_beg_row
8983 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8984 && (vpos
< dpyinfo
->mouse_face_end_row
8985 || (vpos
== dpyinfo
->mouse_face_end_row
8986 && hpos
< dpyinfo
->mouse_face_end_col
))
8987 /* Don't redraw the cursor's spot in mouse face if it is at the
8988 end of a line (on a newline). The cursor appears there, but
8989 mouse highlighting does not. */
8990 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8991 mouse_face_here_p
= 1;
8993 /* Maybe clear the display under the cursor. */
8994 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8997 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8999 cursor_glyph
= get_phys_cursor_glyph (w
);
9000 if (cursor_glyph
== NULL
)
9001 goto mark_cursor_off
;
9003 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9005 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9007 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9009 cursor_glyph
->pixel_width
,
9010 cursor_row
->visible_height
,
9014 /* Erase the cursor by redrawing the character underneath it. */
9015 if (mouse_face_here_p
)
9016 hl
= DRAW_MOUSE_FACE
;
9018 hl
= DRAW_NORMAL_TEXT
;
9019 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9022 w
->phys_cursor_on_p
= 0;
9023 w
->phys_cursor_type
= NO_CURSOR
;
9027 /* Non-zero if physical cursor of window W is within mouse face. */
9030 cursor_in_mouse_face_p (w
)
9033 struct mac_display_info
*dpyinfo
9034 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9035 int in_mouse_face
= 0;
9037 if (WINDOWP (dpyinfo
->mouse_face_window
)
9038 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9040 int hpos
= w
->phys_cursor
.hpos
;
9041 int vpos
= w
->phys_cursor
.vpos
;
9043 if (vpos
>= dpyinfo
->mouse_face_beg_row
9044 && vpos
<= dpyinfo
->mouse_face_end_row
9045 && (vpos
> dpyinfo
->mouse_face_beg_row
9046 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9047 && (vpos
< dpyinfo
->mouse_face_end_row
9048 || hpos
< dpyinfo
->mouse_face_end_col
9049 || dpyinfo
->mouse_face_past_end
))
9053 return in_mouse_face
;
9057 /* Display or clear cursor of window W. If ON is zero, clear the
9058 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9059 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9062 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9064 int on
, hpos
, vpos
, x
, y
;
9066 struct frame
*f
= XFRAME (w
->frame
);
9067 int new_cursor_type
;
9068 int new_cursor_width
;
9070 struct glyph_matrix
*current_glyphs
;
9071 struct glyph_row
*glyph_row
;
9072 struct glyph
*glyph
;
9074 /* This is pointless on invisible frames, and dangerous on garbaged
9075 windows and frames; in the latter case, the frame or window may
9076 be in the midst of changing its size, and x and y may be off the
9078 if (! FRAME_VISIBLE_P (f
)
9079 || FRAME_GARBAGED_P (f
)
9080 || vpos
>= w
->current_matrix
->nrows
9081 || hpos
>= w
->current_matrix
->matrix_w
)
9084 /* If cursor is off and we want it off, return quickly. */
9085 if (!on
&& !w
->phys_cursor_on_p
)
9088 current_glyphs
= w
->current_matrix
;
9089 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9090 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9092 /* If cursor row is not enabled, we don't really know where to
9093 display the cursor. */
9094 if (!glyph_row
->enabled_p
)
9096 w
->phys_cursor_on_p
= 0;
9100 xassert (interrupt_input_blocked
);
9102 /* Set new_cursor_type to the cursor we want to be displayed. */
9103 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
9106 /* If cursor is currently being shown and we don't want it to be or
9107 it is in the wrong place, or the cursor type is not what we want,
9109 if (w
->phys_cursor_on_p
9111 || w
->phys_cursor
.x
!= x
9112 || w
->phys_cursor
.y
!= y
9113 || new_cursor_type
!= w
->phys_cursor_type
9114 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9115 && new_cursor_width
!= w
->phys_cursor_width
)))
9116 x_erase_phys_cursor (w
);
9118 /* If the cursor is now invisible and we want it to be visible,
9120 if (on
&& !w
->phys_cursor_on_p
)
9122 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9123 w
->phys_cursor_height
= glyph_row
->height
;
9125 /* Set phys_cursor_.* before x_draw_.* is called because some
9126 of them may need the information. */
9127 w
->phys_cursor
.x
= x
;
9128 w
->phys_cursor
.y
= glyph_row
->y
;
9129 w
->phys_cursor
.hpos
= hpos
;
9130 w
->phys_cursor
.vpos
= vpos
;
9131 w
->phys_cursor_type
= new_cursor_type
;
9132 w
->phys_cursor_width
= new_cursor_width
;
9133 w
->phys_cursor_on_p
= 1;
9135 switch (new_cursor_type
)
9137 case HOLLOW_BOX_CURSOR
:
9138 x_draw_hollow_cursor (w
, glyph_row
);
9141 case FILLED_BOX_CURSOR
:
9142 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9146 /* TODO. For now, just draw bar cursor. */
9148 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9161 /* Display the cursor on window W, or clear it. X and Y are window
9162 relative pixel coordinates. HPOS and VPOS are glyph matrix
9163 positions. If W is not the selected window, display a hollow
9164 cursor. ON non-zero means display the cursor at X, Y which
9165 correspond to HPOS, VPOS, otherwise it is cleared. */
9168 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9170 int on
, hpos
, vpos
, x
, y
;
9173 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9178 /* Display the cursor on window W, or clear it, according to ON_P.
9179 Don't change the cursor's position. */
9182 x_update_cursor (f
, on_p
)
9186 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9190 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9191 in the window tree rooted at W. */
9194 x_update_cursor_in_window_tree (w
, on_p
)
9200 if (!NILP (w
->hchild
))
9201 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9202 else if (!NILP (w
->vchild
))
9203 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9205 x_update_window_cursor (w
, on_p
);
9207 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9212 /* Switch the display of W's cursor on or off, according to the value
9216 x_update_window_cursor (w
, on
)
9220 /* Don't update cursor in windows whose frame is in the process
9221 of being deleted. */
9222 if (w
->current_matrix
)
9225 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9226 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9237 #if 0 /* MAC_TODO: no icon support yet. */
9239 x_bitmap_icon (f
, icon
)
9245 if (FRAME_W32_WINDOW (f
) == 0)
9249 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9250 else if (STRINGP (icon
))
9251 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9252 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9253 else if (SYMBOLP (icon
))
9257 if (EQ (icon
, intern ("application")))
9258 name
= (LPCTSTR
) IDI_APPLICATION
;
9259 else if (EQ (icon
, intern ("hand")))
9260 name
= (LPCTSTR
) IDI_HAND
;
9261 else if (EQ (icon
, intern ("question")))
9262 name
= (LPCTSTR
) IDI_QUESTION
;
9263 else if (EQ (icon
, intern ("exclamation")))
9264 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9265 else if (EQ (icon
, intern ("asterisk")))
9266 name
= (LPCTSTR
) IDI_ASTERISK
;
9267 else if (EQ (icon
, intern ("winlogo")))
9268 name
= (LPCTSTR
) IDI_WINLOGO
;
9272 hicon
= LoadIcon (NULL
, name
);
9280 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9285 #endif /* MAC_TODO */
9287 /************************************************************************
9289 ************************************************************************/
9291 /* Display Error Handling functions not used on W32. Listing them here
9292 helps diff stay in step when comparing w32term.c with xterm.c.
9294 x_error_catcher (display, error)
9295 x_catch_errors (dpy)
9296 x_catch_errors_unwind (old_val)
9297 x_check_errors (dpy, format)
9298 x_had_errors_p (dpy)
9299 x_clear_errors (dpy)
9300 x_uncatch_errors (dpy, count)
9302 x_connection_signal (signalnum)
9303 x_connection_closed (dpy, error_message)
9304 x_error_quitter (display, error)
9305 x_error_handler (display, error)
9306 x_io_error_quitter (display)
9311 /* Changing the font of the frame. */
9313 /* Give frame F the font named FONTNAME as its default font, and
9314 return the full name of that font. FONTNAME may be a wildcard
9315 pattern; in that case, we choose some font that fits the pattern.
9316 The return value shows which font we chose. */
9319 x_new_font (f
, fontname
)
9321 register char *fontname
;
9323 struct font_info
*fontp
9324 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9329 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9330 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9331 FRAME_FONTSET (f
) = -1;
9333 /* Compute the scroll bar width in character columns. */
9334 if (f
->scroll_bar_pixel_width
> 0)
9336 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9337 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9341 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9342 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9345 /* Now make the frame display the given font. */
9346 if (FRAME_MAC_WINDOW (f
) != 0)
9348 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9349 f
->output_data
.mac
->font
);
9350 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9351 f
->output_data
.mac
->font
);
9352 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9353 f
->output_data
.mac
->font
);
9355 frame_update_line_height (f
);
9356 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9357 x_set_window_size (f
, 0, f
->width
, f
->height
);
9360 /* If we are setting a new frame's font for the first time,
9361 there are no faces yet, so this font's height is the line height. */
9362 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9364 return build_string (fontp
->full_name
);
9367 /* Give frame F the fontset named FONTSETNAME as its default font, and
9368 return the full name of that fontset. FONTSETNAME may be a wildcard
9369 pattern; in that case, we choose some fontset that fits the pattern.
9370 The return value shows which fontset we chose. */
9373 x_new_fontset (f
, fontsetname
)
9377 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9383 if (FRAME_FONTSET (f
) == fontset
)
9384 /* This fontset is already set in frame F. There's nothing more
9386 return fontset_name (fontset
);
9388 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
9390 if (!STRINGP (result
))
9391 /* Can't load ASCII font. */
9394 /* Since x_new_font doesn't update any fontset information, do it now. */
9395 FRAME_FONTSET(f
) = fontset
;
9397 return build_string (fontsetname
);
9401 /***********************************************************************
9402 TODO: W32 Input Methods
9403 ***********************************************************************/
9404 /* Listing missing functions from xterm.c helps diff stay in step.
9406 xim_destroy_callback (xim, client_data, call_data)
9407 xim_open_dpy (dpyinfo, resource_name)
9409 xim_instantiate_callback (display, client_data, call_data)
9410 xim_initialize (dpyinfo, resource_name)
9411 xim_close_dpy (dpyinfo)
9416 /* Calculate the absolute position in frame F
9417 from its current recorded position values and gravity. */
9420 x_calc_absolute_position (f
)
9424 int flags
= f
->output_data
.mac
->size_hint_flags
;
9428 /* Find the position of the outside upper-left corner of
9429 the inner window, with respect to the outer window. */
9430 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9433 GetPort (&savePort
);
9435 #if TARGET_API_MAC_CARBON
9436 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9438 SetPort (FRAME_MAC_WINDOW (f
));
9441 #if TARGET_API_MAC_CARBON
9445 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9446 SetPt(&pt
, r
.left
, r
.top
);
9448 #else /* not TARGET_API_MAC_CARBON */
9449 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9450 #endif /* not TARGET_API_MAC_CARBON */
9451 LocalToGlobal (&pt
);
9455 /* Treat negative positions as relative to the leftmost bottommost
9456 position that fits on the screen. */
9457 if (flags
& XNegative
)
9458 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9459 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9461 + f
->output_data
.mac
->left_pos
);
9462 /* NTEMACS_TODO: Subtract menubar height? */
9463 if (flags
& YNegative
)
9464 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9465 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9467 + f
->output_data
.mac
->top_pos
);
9468 /* The left_pos and top_pos
9469 are now relative to the top and left screen edges,
9470 so the flags should correspond. */
9471 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9474 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9475 to really change the position, and 0 when calling from
9476 x_make_frame_visible (in that case, XOFF and YOFF are the current
9477 position values). It is -1 when calling from x_set_frame_parameters,
9478 which means, do adjust for borders but don't change the gravity. */
9481 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9483 register int xoff
, yoff
;
9486 int modified_top
, modified_left
;
9488 if (change_gravity
> 0)
9490 f
->output_data
.mac
->top_pos
= yoff
;
9491 f
->output_data
.mac
->left_pos
= xoff
;
9492 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9494 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9496 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9497 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9499 x_calc_absolute_position (f
);
9502 x_wm_set_size_hint (f
, (long) 0, 0);
9504 modified_left
= f
->output_data
.mac
->left_pos
;
9505 modified_top
= f
->output_data
.mac
->top_pos
;
9507 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9508 modified_top
+ 42, false);
9513 /* Call this to change the size of frame F's x-window.
9514 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9515 for this size change and subsequent size changes.
9516 Otherwise we leave the window gravity unchanged. */
9519 x_set_window_size (f
, change_gravity
, cols
, rows
)
9524 int pixelwidth
, pixelheight
;
9528 check_frame_size (f
, &rows
, &cols
);
9529 f
->output_data
.mac
->vertical_scroll_bar_extra
9530 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9532 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9534 compute_fringe_widths (f
, 0);
9536 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9537 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9539 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9540 x_wm_set_size_hint (f
, (long) 0, 0);
9542 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9544 /* Now, strictly speaking, we can't be sure that this is accurate,
9545 but the window manager will get around to dealing with the size
9546 change request eventually, and we'll hear how it went when the
9547 ConfigureNotify event gets here.
9549 We could just not bother storing any of this information here,
9550 and let the ConfigureNotify event set everything up, but that
9551 might be kind of confusing to the Lisp code, since size changes
9552 wouldn't be reported in the frame parameters until some random
9553 point in the future when the ConfigureNotify event arrives.
9555 We pass 1 for DELAY since we can't run Lisp code inside of
9557 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9558 PIXEL_WIDTH (f
) = pixelwidth
;
9559 PIXEL_HEIGHT (f
) = pixelheight
;
9561 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9562 receive in the ConfigureNotify event; if we get what we asked
9563 for, then the event won't cause the screen to become garbaged, so
9564 we have to make sure to do it here. */
9565 SET_FRAME_GARBAGED (f
);
9567 XFlush (FRAME_X_DISPLAY (f
));
9569 /* If cursor was outside the new size, mark it as off. */
9570 mark_window_cursors_off (XWINDOW (f
->root_window
));
9572 /* Clear out any recollection of where the mouse highlighting was,
9573 since it might be in a place that's outside the new frame size.
9574 Actually checking whether it is outside is a pain in the neck,
9575 so don't try--just let the highlighting be done afresh with new size. */
9576 cancel_mouse_face (f
);
9581 /* Mouse warping. */
9583 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9586 x_set_mouse_position (f
, x
, y
)
9592 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9593 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9595 if (pix_x
< 0) pix_x
= 0;
9596 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9598 if (pix_y
< 0) pix_y
= 0;
9599 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9601 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9605 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9609 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9612 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9613 0, 0, 0, 0, pix_x
, pix_y
);
9619 /* focus shifting, raising and lowering. */
9622 x_focus_on_frame (f
)
9625 #if 0 /* This proves to be unpleasant. */
9629 /* I don't think that the ICCCM allows programs to do things like this
9630 without the interaction of the window manager. Whatever you end up
9631 doing with this code, do it to x_unfocus_frame too. */
9632 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9633 RevertToPointerRoot
, CurrentTime
);
9643 /* Raise frame F. */
9648 if (f
->async_visible
)
9649 SelectWindow (FRAME_MAC_WINDOW (f
));
9652 /* Lower frame F. */
9657 if (f
->async_visible
)
9658 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9662 XTframe_raise_lower (f
, raise_flag
)
9672 /* Change of visibility. */
9674 /* This tries to wait until the frame is really visible.
9675 However, if the window manager asks the user where to position
9676 the frame, this will return before the user finishes doing that.
9677 The frame will not actually be visible at that time,
9678 but it will become visible later when the window manager
9679 finishes with it. */
9682 x_make_frame_visible (f
)
9686 int original_top
, original_left
;
9690 if (! FRAME_VISIBLE_P (f
))
9692 /* We test FRAME_GARBAGED_P here to make sure we don't
9693 call x_set_offset a second time
9694 if we get to x_make_frame_visible a second time
9695 before the window gets really visible. */
9696 if (! FRAME_ICONIFIED_P (f
)
9697 && ! f
->output_data
.mac
->asked_for_visible
)
9698 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
9699 f
->output_data
.mac
->top_pos
, 0);
9701 f
->output_data
.mac
->asked_for_visible
= 1;
9703 ShowWindow (FRAME_MAC_WINDOW (f
));
9706 XFlush (FRAME_MAC_DISPLAY (f
));
9708 #if 0 /* MAC_TODO */
9709 /* Synchronize to ensure Emacs knows the frame is visible
9710 before we do anything else. We do this loop with input not blocked
9711 so that incoming events are handled. */
9716 /* This must come after we set COUNT. */
9719 XSETFRAME (frame
, f
);
9721 /* Wait until the frame is visible. Process X events until a
9722 MapNotify event has been seen, or until we think we won't get a
9723 MapNotify at all.. */
9724 for (count
= input_signal_count
+ 10;
9725 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9727 /* Force processing of queued events. */
9730 /* Machines that do polling rather than SIGIO have been
9731 observed to go into a busy-wait here. So we'll fake an
9732 alarm signal to let the handler know that there's something
9733 to be read. We used to raise a real alarm, but it seems
9734 that the handler isn't always enabled here. This is
9736 if (input_polling_used ())
9738 /* It could be confusing if a real alarm arrives while
9739 processing the fake one. Turn it off and let the
9740 handler reset it. */
9741 extern void poll_for_input_1
P_ ((void));
9742 int old_poll_suppress_count
= poll_suppress_count
;
9743 poll_suppress_count
= 1;
9744 poll_for_input_1 ();
9745 poll_suppress_count
= old_poll_suppress_count
;
9748 /* See if a MapNotify event has been processed. */
9749 FRAME_SAMPLE_VISIBILITY (f
);
9752 #endif /* MAC_TODO */
9755 /* Change from mapped state to withdrawn state. */
9757 /* Make the frame visible (mapped and not iconified). */
9760 x_make_frame_invisible (f
)
9763 /* Don't keep the highlight on an invisible frame. */
9764 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
9765 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
9769 HideWindow (FRAME_MAC_WINDOW (f
));
9771 /* We can't distinguish this from iconification
9772 just by the event that we get from the server.
9773 So we can't win using the usual strategy of letting
9774 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9775 and synchronize with the server to make sure we agree. */
9777 FRAME_ICONIFIED_P (f
) = 0;
9778 f
->async_visible
= 0;
9779 f
->async_iconified
= 0;
9784 /* Change window state from mapped to iconified. */
9790 /* Don't keep the highlight on an invisible frame. */
9791 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
9792 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
9795 /* Review: Since window is still visible in dock, still allow updates? */
9796 if (f
->async_iconified
)
9802 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
9808 /* Destroy the X window of frame F. */
9811 x_destroy_window (f
)
9814 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9818 DisposeWindow (FRAME_MAC_WINDOW (f
));
9820 free_frame_menubar (f
);
9821 free_frame_faces (f
);
9823 xfree (f
->output_data
.mac
);
9824 f
->output_data
.mac
= 0;
9825 if (f
== dpyinfo
->x_focus_frame
)
9826 dpyinfo
->x_focus_frame
= 0;
9827 if (f
== dpyinfo
->x_focus_event_frame
)
9828 dpyinfo
->x_focus_event_frame
= 0;
9829 if (f
== dpyinfo
->x_highlight_frame
)
9830 dpyinfo
->x_highlight_frame
= 0;
9832 dpyinfo
->reference_count
--;
9834 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9836 dpyinfo
->mouse_face_beg_row
9837 = dpyinfo
->mouse_face_beg_col
= -1;
9838 dpyinfo
->mouse_face_end_row
9839 = dpyinfo
->mouse_face_end_col
= -1;
9840 dpyinfo
->mouse_face_window
= Qnil
;
9841 dpyinfo
->mouse_face_deferred_gc
= 0;
9842 dpyinfo
->mouse_face_mouse_frame
= 0;
9848 /* Setting window manager hints. */
9850 /* Set the normal size hints for the window manager, for frame F.
9851 FLAGS is the flags word to use--or 0 meaning preserve the flags
9852 that the window now has.
9853 If USER_POSITION is nonzero, we set the USPosition
9854 flag (this is useful when FLAGS is 0). */
9856 x_wm_set_size_hint (f
, flags
, user_position
)
9861 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
9862 XSizeHints size_hints
;
9864 #ifdef USE_X_TOOLKIT
9867 Dimension widget_width
, widget_height
;
9868 Window window
= XtWindow (f
->output_data
.x
->widget
);
9869 #else /* not USE_X_TOOLKIT */
9870 Window window
= FRAME_X_WINDOW (f
);
9871 #endif /* not USE_X_TOOLKIT */
9873 /* Setting PMaxSize caused various problems. */
9874 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
9876 size_hints
.x
= f
->output_data
.x
->left_pos
;
9877 size_hints
.y
= f
->output_data
.x
->top_pos
;
9879 #ifdef USE_X_TOOLKIT
9880 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
9881 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
9882 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
9883 size_hints
.height
= widget_height
;
9884 size_hints
.width
= widget_width
;
9885 #else /* not USE_X_TOOLKIT */
9886 size_hints
.height
= PIXEL_HEIGHT (f
);
9887 size_hints
.width
= PIXEL_WIDTH (f
);
9888 #endif /* not USE_X_TOOLKIT */
9890 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
9891 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
9892 size_hints
.max_width
9893 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
9894 size_hints
.max_height
9895 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
9897 /* Calculate the base and minimum sizes.
9899 (When we use the X toolkit, we don't do it here.
9900 Instead we copy the values that the widgets are using, below.) */
9901 #ifndef USE_X_TOOLKIT
9903 int base_width
, base_height
;
9904 int min_rows
= 0, min_cols
= 0;
9906 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
9907 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
9909 check_frame_size (f
, &min_rows
, &min_cols
);
9911 /* The window manager uses the base width hints to calculate the
9912 current number of rows and columns in the frame while
9913 resizing; min_width and min_height aren't useful for this
9914 purpose, since they might not give the dimensions for a
9915 zero-row, zero-column frame.
9917 We use the base_width and base_height members if we have
9918 them; otherwise, we set the min_width and min_height members
9919 to the size for a zero x zero frame. */
9922 size_hints
.flags
|= PBaseSize
;
9923 size_hints
.base_width
= base_width
;
9924 size_hints
.base_height
= base_height
;
9925 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
9926 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
9928 size_hints
.min_width
= base_width
;
9929 size_hints
.min_height
= base_height
;
9933 /* If we don't need the old flags, we don't need the old hint at all. */
9936 size_hints
.flags
|= flags
;
9939 #endif /* not USE_X_TOOLKIT */
9942 XSizeHints hints
; /* Sometimes I hate X Windows... */
9943 long supplied_return
;
9947 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
9950 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
9953 #ifdef USE_X_TOOLKIT
9954 size_hints
.base_height
= hints
.base_height
;
9955 size_hints
.base_width
= hints
.base_width
;
9956 size_hints
.min_height
= hints
.min_height
;
9957 size_hints
.min_width
= hints
.min_width
;
9961 size_hints
.flags
|= flags
;
9966 if (hints
.flags
& PSize
)
9967 size_hints
.flags
|= PSize
;
9968 if (hints
.flags
& PPosition
)
9969 size_hints
.flags
|= PPosition
;
9970 if (hints
.flags
& USPosition
)
9971 size_hints
.flags
|= USPosition
;
9972 if (hints
.flags
& USSize
)
9973 size_hints
.flags
|= USSize
;
9977 #ifndef USE_X_TOOLKIT
9982 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
9983 size_hints
.flags
|= PWinGravity
;
9987 size_hints
.flags
&= ~ PPosition
;
9988 size_hints
.flags
|= USPosition
;
9990 #endif /* PWinGravity */
9993 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
9995 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
9997 #endif /* MAC_TODO */
10000 #if 0 /* MAC_TODO: hide application instead of iconify? */
10001 /* Used for IconicState or NormalState */
10004 x_wm_set_window_state (f
, state
)
10008 #ifdef USE_X_TOOLKIT
10011 XtSetArg (al
[0], XtNinitialState
, state
);
10012 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10013 #else /* not USE_X_TOOLKIT */
10014 Window window
= FRAME_X_WINDOW (f
);
10016 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10017 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10019 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10020 #endif /* not USE_X_TOOLKIT */
10024 x_wm_set_icon_pixmap (f
, pixmap_id
)
10028 Pixmap icon_pixmap
;
10030 #ifndef USE_X_TOOLKIT
10031 Window window
= FRAME_X_WINDOW (f
);
10036 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10037 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10041 /* It seems there is no way to turn off use of an icon pixmap.
10042 The following line does it, only if no icon has yet been created,
10043 for some window managers. But with mwm it crashes.
10044 Some people say it should clear the IconPixmapHint bit in this case,
10045 but that doesn't work, and the X consortium said it isn't the
10046 right thing at all. Since there is no way to win,
10047 best to explicitly give up. */
10049 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10055 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10059 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10060 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10063 #else /* not USE_X_TOOLKIT */
10065 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10066 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10068 #endif /* not USE_X_TOOLKIT */
10071 #endif /* MAC_TODO */
10074 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10076 int icon_x
, icon_y
;
10078 #if 0 /* MAC_TODO: no icons on Mac */
10079 #ifdef USE_X_TOOLKIT
10080 Window window
= XtWindow (f
->output_data
.x
->widget
);
10082 Window window
= FRAME_X_WINDOW (f
);
10085 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10086 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10087 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10089 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10090 #endif /* MAC_TODO */
10094 /***********************************************************************
10096 ***********************************************************************/
10098 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10101 x_get_font_info (f
, font_idx
)
10105 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10108 /* the global font name table */
10109 char **font_name_table
= NULL
;
10110 int font_name_table_size
= 0;
10111 int font_name_count
= 0;
10113 /* compare two strings ignoring case */
10115 stricmp (const char *s
, const char *t
)
10117 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10120 return tolower (*s
) - tolower (*t
);
10123 /* compare two strings ignoring case and handling wildcard */
10125 wildstrieq (char *s1
, char *s2
)
10127 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10130 return stricmp (s1
, s2
) == 0;
10133 /* Assume parameter 1 is fully qualified, no wildcards. */
10135 mac_font_pattern_match (fontname
, pattern
)
10139 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10140 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10143 /* Copy fontname so we can modify it during comparison. */
10144 strcpy (font_name_copy
, fontname
);
10149 /* Turn pattern into a regexp and do a regexp match. */
10150 for (; *pattern
; pattern
++)
10152 if (*pattern
== '?')
10154 else if (*pattern
== '*')
10165 return (fast_c_string_match_ignore_case (build_string (regex
),
10166 font_name_copy
) >= 0);
10169 /* Two font specs are considered to match if their foundry, family,
10170 weight, slant, and charset match. */
10172 mac_font_match (char *mf
, char *xf
)
10174 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10175 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10177 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10178 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10179 return mac_font_pattern_match (mf
, xf
);
10181 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10182 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10183 return mac_font_pattern_match (mf
, xf
);
10185 return (wildstrieq (m_foundry
, x_foundry
)
10186 && wildstrieq (m_family
, x_family
)
10187 && wildstrieq (m_weight
, x_weight
)
10188 && wildstrieq (m_slant
, x_slant
)
10189 && wildstrieq (m_charset
, x_charset
))
10190 || mac_font_pattern_match (mf
, xf
);
10195 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10197 char foundry
[32], family
[32], cs
[32];
10198 char xf
[255], *result
, *p
;
10200 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10202 strcpy(foundry
, "Apple");
10203 strcpy(family
, name
);
10205 switch (scriptcode
)
10207 case smTradChinese
:
10208 strcpy(cs
, "big5-0");
10210 case smSimpChinese
:
10211 strcpy(cs
, "gb2312.1980-0");
10214 strcpy(cs
, "jisx0208.1983-sjis");
10217 /* Each Apple Japanese font is entered into the font table
10218 twice: once as a jisx0208.1983-sjis font and once as a
10219 jisx0201.1976-0 font. The latter can be used to display
10220 the ascii charset and katakana-jisx0201 charset. A
10221 negative script code signals that the name of this latter
10222 font is being built. */
10223 strcpy(cs
, "jisx0201.1976-0");
10226 strcpy(cs
, "ksc5601.1989-0");
10229 strcpy(cs
, "mac-roman");
10234 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10235 foundry
, family
, style
& bold
? "bold" : "medium",
10236 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10238 result
= (char *) xmalloc (strlen (xf
) + 1);
10239 strcpy (result
, xf
);
10240 for (p
= result
; *p
; p
++)
10246 /* Convert an X font spec to the corresponding mac font name, which
10247 can then be passed to GetFNum after conversion to a Pascal string.
10248 For ordinary Mac fonts, this should just be their names, like
10249 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10250 collection contain their charset designation in their names, like
10251 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10252 names are handled accordingly. */
10254 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10256 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10260 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10261 foundry
, family
, weight
, slant
, cs
) != 5 &&
10262 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10263 foundry
, family
, weight
, slant
, cs
) != 5)
10266 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10267 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10268 || strcmp (cs
, "jisx0201.1976-0") == 0
10269 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10270 strcpy(mf
, family
);
10272 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10277 add_font_name_table_entry (char *font_name
)
10279 if (font_name_table_size
== 0)
10281 font_name_table_size
= 16;
10282 font_name_table
= (char **)
10283 xmalloc (font_name_table_size
* sizeof (char *));
10285 else if (font_name_count
+ 1 >= font_name_table_size
)
10287 font_name_table_size
+= 16;
10288 font_name_table
= (char **)
10289 xrealloc (font_name_table
,
10290 font_name_table_size
* sizeof (char *));
10293 font_name_table
[font_name_count
++] = font_name
;
10296 /* Sets up the table font_name_table to contain the list of all fonts
10297 in the system the first time the table is used so that the Resource
10298 Manager need not be accessed every time this information is
10302 init_font_name_table ()
10304 #if TARGET_API_MAC_CARBON
10307 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10309 FMFontFamilyIterator ffi
;
10310 FMFontFamilyInstanceIterator ffii
;
10313 /* Create a dummy instance iterator here to avoid creating and
10314 destroying it in the loop. */
10315 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10317 /* Create an iterator to enumerate the font families. */
10318 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10321 FMDisposeFontFamilyInstanceIterator (&ffii
);
10325 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10333 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10337 sc
= FontToScript (ff
);
10339 /* Point the instance iterator at the current font family. */
10340 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10343 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
10347 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10349 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10351 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10353 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10359 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10361 if (smJapanese
== sc
)
10362 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10368 /* Dispose of the iterators. */
10369 FMDisposeFontFamilyIterator (&ffi
);
10370 FMDisposeFontFamilyInstanceIterator (&ffii
);
10374 #endif /* TARGET_API_MAC_CARBON */
10376 SInt16 fontnum
, old_fontnum
;
10377 int num_mac_fonts
= CountResources('FOND');
10379 Handle font_handle
, font_handle_2
;
10380 short id
, scriptcode
;
10383 struct FontAssoc
*fat
;
10384 struct AsscEntry
*assc_entry
;
10386 GetPort (&port
); /* save the current font number used */
10387 #if TARGET_API_MAC_CARBON
10388 old_fontnum
= GetPortTextFont (port
);
10390 old_fontnum
= port
->txFont
;
10393 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10395 font_handle
= GetIndResource ('FOND', i
);
10399 GetResInfo (font_handle
, &id
, &type
, name
);
10400 GetFNum (name
, &fontnum
);
10405 TextFont (fontnum
);
10406 scriptcode
= FontToScript (fontnum
);
10409 HLock (font_handle
);
10411 if (GetResourceSizeOnDisk (font_handle
)
10412 >= sizeof (struct FamRec
))
10414 fat
= (struct FontAssoc
*) (*font_handle
10415 + sizeof (struct FamRec
));
10417 = (struct AsscEntry
*) (*font_handle
10418 + sizeof (struct FamRec
)
10419 + sizeof (struct FontAssoc
));
10421 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10423 if (font_name_table_size
== 0)
10425 font_name_table_size
= 16;
10426 font_name_table
= (char **)
10427 xmalloc (font_name_table_size
* sizeof (char *));
10429 else if (font_name_count
>= font_name_table_size
)
10431 font_name_table_size
+= 16;
10432 font_name_table
= (char **)
10433 xrealloc (font_name_table
,
10434 font_name_table_size
* sizeof (char *));
10436 font_name_table
[font_name_count
++]
10437 = mac_to_x_fontname (name
,
10438 assc_entry
->fontSize
,
10439 assc_entry
->fontStyle
,
10441 /* Both jisx0208.1983-sjis and
10442 jisx0201.1976-sjis parts are contained in
10443 Apple Japanese (SJIS) font. */
10444 if (smJapanese
== scriptcode
)
10446 font_name_table
[font_name_count
++]
10447 = mac_to_x_fontname (name
,
10448 assc_entry
->fontSize
,
10449 assc_entry
->fontStyle
,
10455 HUnlock (font_handle
);
10456 font_handle_2
= GetNextFOND (font_handle
);
10457 ReleaseResource (font_handle
);
10458 font_handle
= font_handle_2
;
10460 while (ResError () == noErr
&& font_handle
);
10463 TextFont (old_fontnum
);
10464 #if TARGET_API_MAC_CARBON
10466 #endif /* TARGET_API_MAC_CARBON */
10470 /* Return a list of at most MAXNAMES font specs matching the one in
10471 PATTERN. Cache matching fonts for patterns in
10472 dpyinfo->name_list_element to avoid looking them up again by
10473 calling mac_font_pattern_match (slow). */
10476 x_list_fonts (struct frame
*f
,
10477 Lisp_Object pattern
,
10482 Lisp_Object newlist
= Qnil
, tem
, key
;
10485 struct gcpro gcpro1
, gcpro2
;
10486 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
10488 if (font_name_table
== NULL
) /* Initialize when first used. */
10489 init_font_name_table ();
10493 tem
= XCDR (dpyinfo
->name_list_element
);
10494 key
= Fcons (pattern
, make_number (maxnames
));
10496 newlist
= Fassoc (key
, tem
);
10497 if (!NILP (newlist
))
10499 newlist
= Fcdr_safe (newlist
);
10504 ptnstr
= SDATA (pattern
);
10506 GCPRO2 (pattern
, newlist
);
10508 /* Scan and matching bitmap fonts. */
10509 for (i
= 0; i
< font_name_count
; i
++)
10511 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10513 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10516 if (n_fonts
>= maxnames
)
10521 /* MAC_TODO: add code for matching outline fonts here */
10527 XSETCDR (dpyinfo
->name_list_element
,
10528 Fcons (Fcons (key
, newlist
),
10529 XCDR (dpyinfo
->name_list_element
)));
10539 /* Check that FONT is valid on frame F. It is if it can be found in F's
10543 x_check_font (f
, font
)
10548 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10550 xassert (font
!= NULL
);
10552 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10553 if (dpyinfo
->font_table
[i
].name
10554 && font
== dpyinfo
->font_table
[i
].font
)
10557 xassert (i
< dpyinfo
->n_fonts
);
10560 #endif /* GLYPH_DEBUG != 0 */
10562 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10563 Note: There are (broken) X fonts out there with invalid XFontStruct
10564 min_bounds contents. For example, handa@etl.go.jp reports that
10565 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10566 have font->min_bounds.width == 0. */
10569 x_font_min_bounds (font
, w
, h
)
10570 MacFontStruct
*font
;
10574 * TODO: Windows does not appear to offer min bound, only
10575 * average and maximum width, and maximum height.
10577 *h
= FONT_HEIGHT (font
);
10578 *w
= FONT_WIDTH (font
);
10582 /* Compute the smallest character width and smallest font height over
10583 all fonts available on frame F. Set the members smallest_char_width
10584 and smallest_font_height in F's x_display_info structure to
10585 the values computed. Value is non-zero if smallest_font_height or
10586 smallest_char_width become smaller than they were before. */
10589 x_compute_min_glyph_bounds (f
)
10593 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10594 MacFontStruct
*font
;
10595 int old_width
= dpyinfo
->smallest_char_width
;
10596 int old_height
= dpyinfo
->smallest_font_height
;
10598 dpyinfo
->smallest_font_height
= 100000;
10599 dpyinfo
->smallest_char_width
= 100000;
10601 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10602 if (dpyinfo
->font_table
[i
].name
)
10604 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10607 font
= (MacFontStruct
*) fontp
->font
;
10608 xassert (font
!= (MacFontStruct
*) ~0);
10609 x_font_min_bounds (font
, &w
, &h
);
10611 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10612 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10615 xassert (dpyinfo
->smallest_char_width
> 0
10616 && dpyinfo
->smallest_font_height
> 0);
10618 return (dpyinfo
->n_fonts
== 1
10619 || dpyinfo
->smallest_char_width
< old_width
10620 || dpyinfo
->smallest_font_height
< old_height
);
10624 /* Determine whether given string is a fully-specified XLFD: all 14
10625 fields are present, none is '*'. */
10628 is_fully_specified_xlfd (char *p
)
10636 for (i
= 0; i
< 13; i
++)
10638 q
= strchr (p
+ 1, '-');
10641 if (q
- p
== 2 && *(p
+ 1) == '*')
10646 if (strchr (p
+ 1, '-') != NULL
)
10649 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10656 const int kDefaultFontSize
= 9;
10659 /* XLoadQueryFont creates and returns an internal representation for a
10660 font in a MacFontStruct struct. There is really no concept
10661 corresponding to "loading" a font on the Mac. But we check its
10662 existence and find the font number and all other information for it
10663 and store them in the returned MacFontStruct. */
10665 static MacFontStruct
*
10666 XLoadQueryFont (Display
*dpy
, char *fontname
)
10668 int i
, size
, is_two_byte_font
, char_width
;
10671 SInt16 old_fontnum
, old_fontsize
;
10672 Style old_fontface
;
10675 Style fontface
= normal
;
10676 MacFontStruct
*font
;
10677 FontInfo the_fontinfo
;
10678 char s_weight
[7], c_slant
;
10680 if (is_fully_specified_xlfd (fontname
))
10684 for (i
= 0; i
< font_name_count
; i
++)
10685 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
10688 if (i
>= font_name_count
)
10691 name
= font_name_table
[i
];
10694 GetPort (&port
); /* save the current font number used */
10695 #if TARGET_API_MAC_CARBON
10696 old_fontnum
= GetPortTextFont (port
);
10697 old_fontsize
= GetPortTextSize (port
);
10698 old_fontface
= GetPortTextFace (port
);
10700 old_fontnum
= port
->txFont
;
10701 old_fontsize
= port
->txSize
;
10702 old_fontface
= port
->txFace
;
10705 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
10706 size
= kDefaultFontSize
;
10708 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
10709 if (strcmp (s_weight
, "bold") == 0)
10712 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
10713 if (c_slant
== 'i')
10714 fontface
|= italic
;
10716 x_font_name_to_mac_font_name (name
, mfontname
);
10717 c2pstr (mfontname
);
10718 GetFNum (mfontname
, &fontnum
);
10722 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
10724 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
10725 bcopy (name
, font
->fontname
, strlen (name
) + 1);
10727 font
->mac_fontnum
= fontnum
;
10728 font
->mac_fontsize
= size
;
10729 font
->mac_fontface
= fontface
;
10730 font
->mac_scriptcode
= FontToScript (fontnum
);
10732 /* Apple Japanese (SJIS) font is listed as both
10733 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
10734 (Roman script) in init_font_name_table (). The latter should be
10735 treated as a one-byte font. */
10740 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10742 && 0 == strcmp (cs
, "jisx0201.1976-0"))
10743 font
->mac_scriptcode
= smRoman
;
10746 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
10747 font
->mac_scriptcode
== smTradChinese
||
10748 font
->mac_scriptcode
== smSimpChinese
||
10749 font
->mac_scriptcode
== smKorean
;
10751 TextFont (fontnum
);
10753 TextFace (fontface
);
10755 GetFontInfo (&the_fontinfo
);
10757 font
->ascent
= the_fontinfo
.ascent
;
10758 font
->descent
= the_fontinfo
.descent
;
10760 font
->min_byte1
= 0;
10761 if (is_two_byte_font
)
10762 font
->max_byte1
= 1;
10764 font
->max_byte1
= 0;
10765 font
->min_char_or_byte2
= 0x20;
10766 font
->max_char_or_byte2
= 0xff;
10768 if (is_two_byte_font
)
10770 /* Use the width of an "ideographic space" of that font because
10771 the_fontinfo.widMax returns the wrong width for some fonts. */
10772 switch (font
->mac_scriptcode
)
10775 char_width
= StringWidth("\p\x81\x40");
10777 case smTradChinese
:
10778 char_width
= StringWidth("\p\xa1\x40");
10780 case smSimpChinese
:
10781 char_width
= StringWidth("\p\xa1\xa1");
10784 char_width
= StringWidth("\p\xa1\xa1");
10789 /* Do this instead of use the_fontinfo.widMax, which incorrectly
10790 returns 15 for 12-point Monaco! */
10791 char_width
= CharWidth ('m');
10793 font
->max_bounds
.rbearing
= char_width
;
10794 font
->max_bounds
.lbearing
= 0;
10795 font
->max_bounds
.width
= char_width
;
10796 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
10797 font
->max_bounds
.descent
= the_fontinfo
.descent
;
10799 font
->min_bounds
= font
->max_bounds
;
10801 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
10802 font
->per_char
= NULL
;
10805 font
->per_char
= (XCharStruct
*)
10806 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
10810 for (c
= 0x20; c
<= 0xff; c
++)
10812 font
->per_char
[c
- 0x20] = font
->max_bounds
;
10813 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
10818 TextFont (old_fontnum
); /* restore previous font number, size and face */
10819 TextSize (old_fontsize
);
10820 TextFace (old_fontface
);
10826 /* Load font named FONTNAME of the size SIZE for frame F, and return a
10827 pointer to the structure font_info while allocating it dynamically.
10828 If SIZE is 0, load any size of font.
10829 If loading is failed, return NULL. */
10832 x_load_font (f
, fontname
, size
)
10834 register char *fontname
;
10837 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10838 Lisp_Object font_names
;
10840 /* Get a list of all the fonts that match this name. Once we
10841 have a list of matching fonts, we compare them against the fonts
10842 we already have by comparing names. */
10843 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
10845 if (!NILP (font_names
))
10850 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10851 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
10852 if (dpyinfo
->font_table
[i
].name
10853 && (!strcmp (dpyinfo
->font_table
[i
].name
,
10854 SDATA (XCAR (tail
)))
10855 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
10856 SDATA (XCAR (tail
)))))
10857 return (dpyinfo
->font_table
+ i
);
10860 /* Load the font and add it to the table. */
10863 struct MacFontStruct
*font
;
10864 struct font_info
*fontp
;
10865 unsigned long value
;
10868 /* If we have found fonts by x_list_font, load one of them. If
10869 not, we still try to load a font by the name given as FONTNAME
10870 because XListFonts (called in x_list_font) of some X server has
10871 a bug of not finding a font even if the font surely exists and
10872 is loadable by XLoadQueryFont. */
10873 if (size
> 0 && !NILP (font_names
))
10874 fontname
= (char *) SDATA (XCAR (font_names
));
10876 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
10880 /* Find a free slot in the font table. */
10881 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10882 if (dpyinfo
->font_table
[i
].name
== NULL
)
10885 /* If no free slot found, maybe enlarge the font table. */
10886 if (i
== dpyinfo
->n_fonts
10887 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
10890 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
10891 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
10892 dpyinfo
->font_table
10893 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
10896 fontp
= dpyinfo
->font_table
+ i
;
10897 if (i
== dpyinfo
->n_fonts
)
10898 ++dpyinfo
->n_fonts
;
10900 /* Now fill in the slots of *FONTP. */
10902 fontp
->font
= font
;
10903 fontp
->font_idx
= i
;
10904 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
10905 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
10907 fontp
->full_name
= fontp
->name
;
10909 fontp
->size
= font
->max_bounds
.width
;
10910 fontp
->height
= FONT_HEIGHT (font
);
10912 /* For some font, ascent and descent in max_bounds field is
10913 larger than the above value. */
10914 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
10915 if (max_height
> fontp
->height
)
10916 fontp
->height
= max_height
;
10919 /* The slot `encoding' specifies how to map a character
10920 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
10921 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
10922 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
10923 2:0xA020..0xFF7F). For the moment, we don't know which charset
10924 uses this font. So, we set information in fontp->encoding[1]
10925 which is never used by any charset. If mapping can't be
10926 decided, set FONT_ENCODING_NOT_DECIDED. */
10927 if (font
->mac_scriptcode
== smJapanese
)
10928 fontp
->encoding
[1] = 4;
10932 = (font
->max_byte1
== 0
10934 ? (font
->min_char_or_byte2
< 0x80
10935 ? (font
->max_char_or_byte2
< 0x80
10936 ? 0 /* 0x20..0x7F */
10937 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
10938 : 1) /* 0xA0..0xFF */
10940 : (font
->min_byte1
< 0x80
10941 ? (font
->max_byte1
< 0x80
10942 ? (font
->min_char_or_byte2
< 0x80
10943 ? (font
->max_char_or_byte2
< 0x80
10944 ? 0 /* 0x2020..0x7F7F */
10945 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
10946 : 3) /* 0x20A0..0x7FFF */
10947 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
10948 : (font
->min_char_or_byte2
< 0x80
10949 ? (font
->max_char_or_byte2
< 0x80
10950 ? 2 /* 0xA020..0xFF7F */
10951 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
10952 : 1))); /* 0xA0A0..0xFFFF */
10955 #if 0 /* MAC_TODO: fill these out with more reasonably values */
10956 fontp
->baseline_offset
10957 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
10958 ? (long) value
: 0);
10959 fontp
->relative_compose
10960 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
10961 ? (long) value
: 0);
10962 fontp
->default_ascent
10963 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
10964 ? (long) value
: 0);
10966 fontp
->baseline_offset
= 0;
10967 fontp
->relative_compose
= 0;
10968 fontp
->default_ascent
= 0;
10971 /* Set global flag fonts_changed_p to non-zero if the font loaded
10972 has a character with a smaller width than any other character
10973 before, or if the font loaded has a smalle>r height than any
10974 other font loaded before. If this happens, it will make a
10975 glyph matrix reallocation necessary. */
10976 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
10983 /* Return a pointer to struct font_info of a font named FONTNAME for
10984 frame F. If no such font is loaded, return NULL. */
10987 x_query_font (f
, fontname
)
10989 register char *fontname
;
10991 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10994 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10995 if (dpyinfo
->font_table
[i
].name
10996 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
10997 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
10998 return (dpyinfo
->font_table
+ i
);
11003 /* Find a CCL program for a font specified by FONTP, and set the member
11004 `encoder' of the structure. */
11007 x_find_ccl_program (fontp
)
11008 struct font_info
*fontp
;
11010 Lisp_Object list
, elt
;
11012 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11016 && STRINGP (XCAR (elt
))
11017 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11023 struct ccl_program
*ccl
11024 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11026 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11029 fontp
->font_encoder
= ccl
;
11035 /***********************************************************************
11037 ***********************************************************************/
11039 #ifdef USE_X_TOOLKIT
11040 static XrmOptionDescRec emacs_options
[] = {
11041 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11042 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11044 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11045 XrmoptionSepArg
, NULL
},
11046 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11048 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11049 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11050 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11051 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11052 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11053 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11054 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11056 #endif /* USE_X_TOOLKIT */
11058 static int x_initialized
;
11060 #ifdef MULTI_KBOARD
11061 /* Test whether two display-name strings agree up to the dot that separates
11062 the screen number from the server number. */
11064 same_x_server (name1
, name2
)
11065 char *name1
, *name2
;
11067 int seen_colon
= 0;
11068 unsigned char *system_name
= SDATA (Vsystem_name
);
11069 int system_name_length
= strlen (system_name
);
11070 int length_until_period
= 0;
11072 while (system_name
[length_until_period
] != 0
11073 && system_name
[length_until_period
] != '.')
11074 length_until_period
++;
11076 /* Treat `unix' like an empty host name. */
11077 if (! strncmp (name1
, "unix:", 5))
11079 if (! strncmp (name2
, "unix:", 5))
11081 /* Treat this host's name like an empty host name. */
11082 if (! strncmp (name1
, system_name
, system_name_length
)
11083 && name1
[system_name_length
] == ':')
11084 name1
+= system_name_length
;
11085 if (! strncmp (name2
, system_name
, system_name_length
)
11086 && name2
[system_name_length
] == ':')
11087 name2
+= system_name_length
;
11088 /* Treat this host's domainless name like an empty host name. */
11089 if (! strncmp (name1
, system_name
, length_until_period
)
11090 && name1
[length_until_period
] == ':')
11091 name1
+= length_until_period
;
11092 if (! strncmp (name2
, system_name
, length_until_period
)
11093 && name2
[length_until_period
] == ':')
11094 name2
+= length_until_period
;
11096 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11100 if (seen_colon
&& *name1
== '.')
11104 && (*name1
== '.' || *name1
== '\0')
11105 && (*name2
== '.' || *name2
== '\0'));
11110 /* The Mac Event loop code */
11113 #include <Events.h>
11114 #include <Quickdraw.h>
11115 #include <Balloons.h>
11116 #include <Devices.h>
11118 #include <Gestalt.h>
11120 #include <Processes.h>
11122 #include <ToolUtils.h>
11123 #include <TextUtils.h>
11124 #include <Dialogs.h>
11125 #include <Script.h>
11127 #include <TextEncodingConverter.h>
11128 #include <Resources.h>
11133 #endif /* ! MAC_OSX */
11135 #define M_APPLE 128
11138 #define WINDOW_RESOURCE 128
11139 #define TERM_WINDOW_RESOURCE 129
11141 #define DEFAULT_NUM_COLS 80
11143 #define MIN_DOC_SIZE 64
11144 #define MAX_DOC_SIZE 32767
11146 /* sleep time for WaitNextEvent */
11147 #define WNE_SLEEP_AT_SUSPEND 10
11148 #define WNE_SLEEP_AT_RESUME 1
11150 /* true when cannot handle any Mac OS events */
11151 static int handling_window_update
= 0;
11153 /* the flag appl_is_suspended is used both for determining the sleep
11154 time to be passed to WaitNextEvent and whether the cursor should be
11155 drawn when updating the display. The cursor is turned off when
11156 Emacs is suspended. Redrawing it is unnecessary and what needs to
11157 be done depends on whether the cursor lies inside or outside the
11158 redraw region. So we might as well skip drawing it when Emacs is
11160 static Boolean app_is_suspended
= false;
11161 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11163 #define EXTRA_STACK_ALLOC (256 * 1024)
11165 #define ARGV_STRING_LIST_ID 129
11166 #define ABOUT_ALERT_ID 128
11167 #define RAM_TOO_LARGE_ALERT_ID 129
11169 Boolean terminate_flag
= false;
11171 /* True if using command key as meta key. */
11172 Lisp_Object Vmac_command_key_is_meta
;
11174 /* True if the ctrl and meta keys should be reversed. */
11175 Lisp_Object Vmac_reverse_ctrl_meta
;
11177 #if USE_CARBON_EVENTS
11178 /* True if the mouse wheel button (i.e. button 4) should map to
11179 mouse-2, instead of mouse-3. */
11180 Lisp_Object Vmac_wheel_button_is_mouse_2
;
11182 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
11183 for processing before Emacs sees it. */
11184 Lisp_Object Vmac_pass_command_to_system
;
11186 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
11187 for processing before Emacs sees it. */
11188 Lisp_Object Vmac_pass_control_to_system
;
11191 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11192 to this text encoding */
11193 int mac_keyboard_text_encoding
;
11194 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11196 /* Set in term/mac-win.el to indicate that event loop can now generate
11197 drag and drop events. */
11198 Lisp_Object Qmac_ready_for_drag_n_drop
;
11200 Lisp_Object drag_and_drop_file_list
;
11202 Point saved_menu_event_location
;
11205 static void init_required_apple_events (void);
11206 static pascal OSErr
11207 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
11208 static pascal OSErr
11209 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
11210 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
11211 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
11213 /* Drag and Drop */
11214 static OSErr
init_mac_drag_n_drop ();
11215 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
11217 #if USE_CARBON_EVENTS
11218 /* Preliminary Support for the OSX Services Menu */
11219 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
11220 static void init_service_handler ();
11223 extern void init_emacs_passwd_dir ();
11224 extern int emacs_main (int, char **, char **);
11225 extern void check_alarm ();
11227 extern void initialize_applescript();
11228 extern void terminate_applescript();
11230 static unsigned int
11231 #if USE_CARBON_EVENTS
11232 mac_to_emacs_modifiers (UInt32 mods
)
11234 mac_to_emacs_modifiers (EventModifiers mods
)
11237 unsigned int result
= 0;
11238 if (mods
& macShiftKey
)
11239 result
|= shift_modifier
;
11240 if (mods
& macCtrlKey
)
11241 result
|= ctrl_modifier
;
11242 if (mods
& macMetaKey
)
11243 result
|= meta_modifier
;
11244 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
11245 result
|= alt_modifier
;
11249 #if USE_CARBON_EVENTS
11250 /* Obtains the event modifiers from the event ref and then calls
11251 mac_to_emacs_modifiers. */
11253 mac_event_to_emacs_modifiers (EventRef eventRef
)
11256 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
11257 sizeof (UInt32
), NULL
, &mods
);
11258 return mac_to_emacs_modifiers (mods
);
11261 /* Given an event ref, return the code to use for the mouse button
11262 code in the emacs input_event. */
11264 mac_get_mouse_btn (EventRef ref
)
11266 EventMouseButton result
= kEventMouseButtonPrimary
;
11267 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
11268 sizeof (EventMouseButton
), NULL
, &result
);
11271 case kEventMouseButtonPrimary
:
11273 case kEventMouseButtonSecondary
:
11274 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
11275 case kEventMouseButtonTertiary
:
11276 case 4: /* 4 is the number for the mouse wheel button */
11277 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
11283 /* Normally, ConvertEventRefToEventRecord will correctly handle all
11284 events. However the click of the mouse wheel is not converted to a
11285 mouseDown or mouseUp event. This calls ConvertEventRef, but then
11286 checks to see if it is a mouse up or down carbon event that has not
11287 been converted, and if so, converts it by hand (to be picked up in
11288 the XTread_socket loop). */
11289 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
11291 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
11292 /* Do special case for mouse wheel button. */
11293 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
11295 UInt32 kind
= GetEventKind (eventRef
);
11296 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
11298 eventRec
->what
= mouseDown
;
11301 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
11303 eventRec
->what
= mouseUp
;
11308 /* Need where and when. */
11310 GetEventParameter (eventRef
, kEventParamMouseLocation
,
11311 typeQDPoint
, NULL
, sizeof (Point
),
11312 NULL
, &eventRec
->where
);
11313 /* Use two step process because new event modifiers are
11314 32-bit and old are 16-bit. Currently, only loss is
11316 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
11317 typeUInt32
, NULL
, sizeof (UInt32
),
11319 eventRec
->modifiers
= mods
;
11321 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
11330 do_get_menus (void)
11332 Handle menubar_handle
;
11333 MenuHandle menu_handle
;
11335 menubar_handle
= GetNewMBar (128);
11336 if(menubar_handle
== NULL
)
11338 SetMenuBar (menubar_handle
);
11341 menu_handle
= GetMenuHandle (M_APPLE
);
11342 if(menu_handle
!= NULL
)
11343 AppendResMenu (menu_handle
,'DRVR');
11350 do_init_managers (void)
11352 #if !TARGET_API_MAC_CARBON
11353 InitGraf (&qd
.thePort
);
11355 FlushEvents (everyEvent
, 0);
11359 InitDialogs (NULL
);
11360 #endif /* !TARGET_API_MAC_CARBON */
11363 #if !TARGET_API_MAC_CARBON
11364 /* set up some extra stack space for use by emacs */
11365 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11367 /* MaxApplZone must be called for AppleScript to execute more
11368 complicated scripts */
11371 #endif /* !TARGET_API_MAC_CARBON */
11375 do_check_ram_size (void)
11377 SInt32 physical_ram_size
, logical_ram_size
;
11379 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11380 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11381 || physical_ram_size
> 256 * 1024 * 1024
11382 || logical_ram_size
> 256 * 1024 * 1024)
11384 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11390 do_window_update (WindowPtr win
)
11392 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11393 struct frame
*f
= mwp
->mFP
;
11397 if (f
->async_visible
== 0)
11399 f
->async_visible
= 1;
11400 f
->async_iconified
= 0;
11401 SET_FRAME_GARBAGED (f
);
11403 /* An update event is equivalent to MapNotify on X, so report
11404 visibility changes properly. */
11405 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11406 /* Force a redisplay sooner or later to update the
11407 frame titles in case this is the second frame. */
11408 record_asynch_buffer_change ();
11413 handling_window_update
= 1;
11415 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
11417 expose_frame (f
, 0, 0, 0, 0);
11419 handling_window_update
= 0;
11426 is_emacs_window (WindowPtr win
)
11428 Lisp_Object tail
, frame
;
11433 FOR_EACH_FRAME (tail
, frame
)
11434 if (FRAME_MAC_P (XFRAME (frame
)))
11435 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11442 do_window_activate (WindowPtr win
)
11447 if (is_emacs_window (win
))
11449 mwp
= (mac_output
*) GetWRefCon (win
);
11454 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11455 activate_scroll_bars (f
);
11461 do_window_deactivate (WindowPtr win
)
11466 if (is_emacs_window (win
))
11468 mwp
= (mac_output
*) GetWRefCon (win
);
11471 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11473 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11474 deactivate_scroll_bars (f
);
11486 wp
= FrontWindow();
11487 if (is_emacs_window (wp
))
11489 mwp
= (mac_output
*) GetWRefCon (wp
);
11494 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11495 activate_scroll_bars (f
);
11499 app_is_suspended
= false;
11500 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11510 wp
= FrontWindow();
11511 if (is_emacs_window (wp
))
11513 mwp
= (mac_output
*) GetWRefCon (wp
);
11516 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11518 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11519 deactivate_scroll_bars (f
);
11523 app_is_suspended
= true;
11524 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11529 do_mouse_moved (Point mouse_pos
)
11531 WindowPtr wp
= FrontWindow ();
11534 if (is_emacs_window (wp
))
11536 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11538 #if TARGET_API_MAC_CARBON
11539 SetPort (GetWindowPort (wp
));
11544 GlobalToLocal (&mouse_pos
);
11546 note_mouse_movement (f
, &mouse_pos
);
11552 do_os_event (EventRecord
*erp
)
11554 switch((erp
->message
>> 24) & 0x000000FF)
11556 case suspendResumeMessage
:
11557 if((erp
->message
& resumeFlag
) == 1)
11563 case mouseMovedMessage
:
11564 do_mouse_moved (erp
->where
);
11570 do_events (EventRecord
*erp
)
11575 do_window_update ((WindowPtr
) erp
->message
);
11583 if ((erp
->modifiers
& activeFlag
) != 0)
11584 do_window_activate ((WindowPtr
) erp
->message
);
11586 do_window_deactivate ((WindowPtr
) erp
->message
);
11592 do_apple_menu (SInt16 menu_item
)
11594 #if !TARGET_API_MAC_CARBON
11596 SInt16 da_driver_refnum
;
11598 if (menu_item
== I_ABOUT
)
11599 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11602 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11603 da_driver_refnum
= OpenDeskAcc (item_name
);
11605 #endif /* !TARGET_API_MAC_CARBON */
11609 do_menu_choice (SInt32 menu_choice
)
11611 SInt16 menu_id
, menu_item
;
11613 menu_id
= HiWord (menu_choice
);
11614 menu_item
= LoWord (menu_choice
);
11622 do_apple_menu (menu_item
);
11627 WindowPtr wp
= FrontWindow ();
11628 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11629 MenuHandle menu
= GetMenuHandle (menu_id
);
11634 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11635 menubar_selection_callback (f
, refcon
);
11644 /* Handle drags in size box. Based on code contributed by Ben
11645 Mesander and IM - Window Manager A. */
11648 do_grow_window (WindowPtr w
, EventRecord
*e
)
11653 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11654 struct frame
*f
= mwp
->mFP
;
11656 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11658 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11660 /* see if it really changed size */
11661 if (grow_size
!= 0)
11663 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11664 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11666 x_set_window_size (f
, 0, columns
, rows
);
11671 /* Handle clicks in zoom box. Calculation of "standard state" based
11672 on code in IM - Window Manager A and code contributed by Ben
11673 Mesander. The standard state of an Emacs window is 80-characters
11674 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11677 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11680 Rect zoom_rect
, port_rect
;
11682 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11683 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11684 struct frame
*f
= mwp
->mFP
;
11686 GetPort (&save_port
);
11688 #if TARGET_API_MAC_CARBON
11689 SetPort (GetWindowPort (w
));
11694 /* Clear window to avoid flicker. */
11695 #if TARGET_API_MAC_CARBON
11700 GetWindowPortBounds (w
, &r
);
11703 if (zoom_in_or_out
== inZoomOut
)
11705 /* calculate height of window's title bar (hard card it for now). */
11706 w_title_height
= 20 + GetMBarHeight ();
11708 /* get maximum height of window into zoom_rect.bottom -
11710 GetQDGlobalsScreenBits (&bm
);
11711 zoom_rect
= bm
.bounds
;
11712 zoom_rect
.top
+= w_title_height
;
11713 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11715 zoom_rect
.right
= zoom_rect
.left
11716 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11718 SetWindowStandardState (w
, &zoom_rect
);
11721 #else /* not TARGET_API_MAC_CARBON */
11722 EraseRect (&(w
->portRect
));
11723 if (zoom_in_or_out
== inZoomOut
)
11725 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
11726 LocalToGlobal (&top_left
);
11728 /* calculate height of window's title bar */
11729 w_title_height
= top_left
.v
- 1
11730 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
11732 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
11733 zoom_rect
= qd
.screenBits
.bounds
;
11734 zoom_rect
.top
+= w_title_height
;
11735 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11737 zoom_rect
.right
= zoom_rect
.left
11738 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11740 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
11743 #endif /* not TARGET_API_MAC_CARBON */
11745 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
11747 /* retrieve window size and update application values */
11748 #if TARGET_API_MAC_CARBON
11749 GetWindowPortBounds (w
, &port_rect
);
11751 port_rect
= w
->portRect
;
11753 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
11754 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
11755 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
11757 SetPort (save_port
);
11760 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
11762 init_mac_drag_n_drop ()
11764 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
11768 /* Intialize AppleEvent dispatcher table for the required events. */
11770 init_required_apple_events ()
11775 /* Make sure we have apple events before starting. */
11776 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
11780 if (!(result
& (1 << gestaltAppleEventsPresent
)))
11783 #if TARGET_API_MAC_CARBON
11784 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
11785 NewAEEventHandlerUPP
11786 ((AEEventHandlerProcPtr
) do_ae_open_application
),
11789 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
11790 NewAEEventHandlerProc
11791 ((AEEventHandlerProcPtr
) do_ae_open_application
),
11797 #if TARGET_API_MAC_CARBON
11798 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
11799 NewAEEventHandlerUPP
11800 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
11803 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
11804 NewAEEventHandlerProc
11805 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
11811 #if TARGET_API_MAC_CARBON
11812 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
11813 NewAEEventHandlerUPP
11814 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
11817 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
11818 NewAEEventHandlerProc
11819 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
11825 #if TARGET_API_MAC_CARBON
11826 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
11827 NewAEEventHandlerUPP
11828 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
11831 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
11832 NewAEEventHandlerProc
11833 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
11840 #if USE_CARBON_EVENTS
11843 init_service_handler ()
11845 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
11846 {kEventClassService
, kEventServiceCopy
},
11847 {kEventClassService
, kEventServicePaste
}};
11848 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
11849 3, specs
, NULL
, NULL
);
11853 MAC_TODO: Check to see if this is called by AEProcessDesc...
11856 mac_handle_service_event (EventHandlerCallRef callRef
,
11857 EventRef event
, void *data
)
11859 OSStatus err
= noErr
;
11860 switch (GetEventKind (event
))
11862 case kEventServiceGetTypes
:
11864 CFMutableArrayRef copyTypes
, pasteTypes
;
11866 Boolean selection
= true;
11868 GetEventParameter(event, kEventParamServicePasteTypes,
11869 typeCFMutableArrayRef, NULL,
11870 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
11872 GetEventParameter(event
, kEventParamServiceCopyTypes
,
11873 typeCFMutableArrayRef
, NULL
,
11874 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
11875 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
11877 CFArrayAppendValue (copyTypes
, type
);
11878 //CFArrayAppendValue (pasteTypes, type);
11882 case kEventServiceCopy
:
11884 ScrapRef currentScrap
, specificScrap
;
11886 Size byteCount
= 0;
11888 GetCurrentScrap (¤tScrap
);
11890 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
11893 void *buffer
= xmalloc (byteCount
);
11894 if (buffer
!= NULL
)
11896 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
11897 sizeof (ScrapRef
), NULL
, &specificScrap
);
11899 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
11900 &byteCount
, buffer
);
11902 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
11903 kScrapFlavorMaskNone
, byteCount
, buffer
);
11909 case kEventServicePaste
:
11912 // Get the current location
11914 ScrapRef specificScrap;
11915 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
11916 sizeof(ScrapRef), NULL, &specificScrap);
11917 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
11918 if (err == noErr) {
11919 void * buffer = xmalloc(byteCount);
11920 if (buffer != NULL ) {
11921 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
11922 &byteCount, buffer);
11923 if (err == noErr) {
11924 // Actually place in the buffer
11926 // Get the current "selection" string here
11939 /* Open Application Apple Event */
11940 static pascal OSErr
11941 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
11947 /* Defined in mac.c. */
11949 path_from_vol_dir_name (char *, int, short, long, char *);
11952 /* Called when we receive an AppleEvent with an ID of
11953 "kAEOpenDocuments". This routine gets the direct parameter,
11954 extracts the FSSpecs in it, and puts their names on a list. */
11955 static pascal OSErr
11956 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
11961 DescType actual_type
;
11964 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
11966 goto descriptor_error_exit
;
11968 /* Check to see that we got all of the required parameters from the
11969 event descriptor. For an 'odoc' event this should just be the
11971 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
11972 &actual_type
, (Ptr
) &keyword
,
11973 sizeof (keyword
), &actual_size
);
11974 /* No error means that we found some unused parameters.
11975 errAEDescNotFound means that there are no more parameters. If we
11976 get an error code other than that, flag it. */
11977 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
11979 err
= errAEEventNotHandled
;
11984 /* Got all the parameters we need. Now, go through the direct
11985 object list and parse it up. */
11987 long num_files_to_open
;
11989 err
= AECountItems (&the_desc
, &num_files_to_open
);
11994 /* AE file list is one based so just use that for indexing here. */
11995 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
11998 Str255 path_name
, unix_path_name
;
12003 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12004 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12005 if (err
!= noErr
) break;
12008 err
= FSpMakeFSRef (&fs
, &fref
);
12009 if (err
!= noErr
) break;
12011 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
12013 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12015 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12017 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12018 drag_and_drop_file_list
);
12024 /* Nuke the coerced file list in any case */
12025 err2
= AEDisposeDesc(&the_desc
);
12027 descriptor_error_exit
:
12028 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12033 static pascal OSErr
12034 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
12035 DragReference theDrag
)
12039 FlavorFlags theFlags
;
12042 ItemReference theItem
;
12045 Size size
= sizeof (HFSFlavor
);
12047 drag_and_drop_file_list
= Qnil
;
12048 GetDragMouse (theDrag
, &mouse
, 0L);
12049 CountDragItems (theDrag
, &items
);
12050 for (index
= 1; index
<= items
; index
++)
12052 /* Only handle file references. */
12053 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
12054 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
12055 if (result
== noErr
)
12062 Str255 unix_path_name
;
12063 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
12065 /* Use Carbon routines, otherwise it converts the file name
12066 to /Macintosh HD/..., which is not correct. */
12067 FSpMakeFSRef (&data
.fileSpec
, &fref
);
12068 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
12070 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
12071 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
12072 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12074 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12075 drag_and_drop_file_list
);
12080 /* If there are items in the list, construct an event and post it to
12081 the queue like an interrupt using kbd_buffer_store_event. */
12082 if (!NILP (drag_and_drop_file_list
))
12084 struct input_event event
;
12086 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
12087 SetPort (GetWindowPort (window
));
12088 GlobalToLocal (&mouse
);
12090 event
.kind
= DRAG_N_DROP_EVENT
;
12092 event
.modifiers
= 0;
12093 event
.timestamp
= TickCount () * (1000 / 60);
12094 XSETINT (event
.x
, mouse
.h
);
12095 XSETINT (event
.y
, mouse
.v
);
12096 XSETFRAME (frame
, f
);
12097 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12099 /* Post to the interrupt queue */
12100 kbd_buffer_store_event (&event
);
12101 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
12103 ProcessSerialNumber psn
;
12104 GetCurrentProcess (&psn
);
12105 SetFrontProcess (&psn
);
12111 /* Print Document Apple Event */
12112 static pascal OSErr
12113 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12115 return errAEEventNotHandled
;
12119 static pascal OSErr
12120 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12122 /* FixMe: Do we need an unwind-protect or something here? And what
12123 do we do about unsaved files. Currently just forces quit rather
12124 than doing recursive callback to get user input. */
12126 terminate_flag
= true;
12128 /* Fkill_emacs doesn't return. We have to return. (TI) */
12135 profiler_exit_proc ()
12137 ProfilerDump ("\pEmacs.prof");
12142 /* These few functions implement Emacs as a normal Mac application
12143 (almost): set up the heap and the Toolbox, handle necessary
12144 system events plus a few simple menu events. They also set up
12145 Emacs's access to functions defined in the rest of this file.
12146 Emacs uses function hooks to perform all its terminal I/O. A
12147 complete list of these functions appear in termhooks.h. For what
12148 they do, read the comments there and see also w32term.c and
12149 xterm.c. What's noticeably missing here is the event loop, which
12150 is normally present in most Mac application. After performing the
12151 necessary Mac initializations, main passes off control to
12152 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12153 mac_read_socket (defined further below) to read input. This is
12154 where WaitNextEvent is called to process Mac events. This is also
12155 where check_alarm in sysdep.c is called to simulate alarm signals.
12156 This makes the cursor jump back to its correct position after
12157 briefly jumping to that of the matching parenthesis, print useful
12158 hints and prompts in the minibuffer after the user stops typing for
12161 #if !TARGET_API_MAC_CARBON
12166 #if __profile__ /* is the profiler on? */
12167 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12172 /* set creator and type for files created by MSL */
12173 _fcreator
= 'EMAx';
12177 do_init_managers ();
12181 do_check_ram_size ();
12183 init_emacs_passwd_dir ();
12187 initialize_applescript ();
12189 init_required_apple_events ();
12195 /* set up argv array from STR# resource */
12196 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12200 /* free up AppleScript resources on exit */
12201 atexit (terminate_applescript
);
12203 #if __profile__ /* is the profiler on? */
12204 atexit (profiler_exit_proc
);
12207 /* 3rd param "envp" never used in emacs_main */
12208 (void) emacs_main (argc
, argv
, 0);
12211 /* Never reached - real exit in Fkill_emacs */
12216 /* Table for translating Mac keycode to X keysym values. Contributed
12217 by Sudhir Shenoy. */
12218 static unsigned char keycode_to_xkeysym_table
[] = {
12219 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12220 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12221 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12223 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
12224 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
12225 /*0x38*/ 0, 0, 0, 0,
12226 /*0x3C*/ 0, 0, 0, 0,
12228 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
12229 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
12230 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
12231 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
12233 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
12234 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
12235 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
12236 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
12238 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
12239 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
12240 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
12241 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
12243 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
12244 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
12245 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
12246 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
12250 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12252 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12253 return *xKeySym
!= 0;
12256 /* Emacs calls this whenever it wants to read an input event from the
12259 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12262 #if USE_CARBON_EVENTS
12263 OSStatus rneResult
;
12265 EventMouseButton mouseBtn
;
12269 EventMask event_mask
;
12272 if (interrupt_input_blocked
)
12274 interrupt_input_pending
= 1;
12279 interrupt_input_pending
= 0;
12282 /* So people can tell when we have read the available input. */
12283 input_signal_count
++;
12288 /* Don't poll for events to process (specifically updateEvt) if
12289 window update currently already in progress. A call to redisplay
12290 (in do_window_update) can be preempted by another call to
12291 redisplay, causing blank regions to be left on the screen and the
12292 cursor to be left at strange places. */
12293 if (handling_window_update
)
12299 if (terminate_flag
)
12300 Fkill_emacs (make_number (1));
12302 /* It is necessary to set this (additional) argument slot of an
12303 event to nil because keyboard.c protects incompletely processed
12304 event from being garbage collected by placing them in the
12305 kbd_buffer_gcpro vector. */
12308 event_mask
= everyEvent
;
12309 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12310 event_mask
-= highLevelEventMask
;
12312 #if USE_CARBON_EVENTS
12313 rneResult
= ReceiveNextEvent (0, NULL
,
12315 ? TicksToEventTime (app_sleep_time
)
12317 kEventRemoveFromQueue
, &eventRef
);
12320 /* Handle new events */
12321 if (!mac_convert_event_ref (eventRef
, &er
))
12322 switch (GetEventClass (eventRef
))
12324 case kEventClassMouse
:
12325 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
12329 WindowPtr window_ptr
= FrontNonFloatingWindow ();
12330 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12331 if (!IsValidWindowPtr (window_ptr
))
12338 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
12339 typeSInt32
, NULL
, sizeof (SInt32
),
12341 GetEventParameter(eventRef
, kEventParamMouseLocation
,
12342 typeQDPoint
, NULL
, sizeof (Point
),
12344 bufp
->kind
= MOUSE_WHEEL_EVENT
;
12345 bufp
->code
= delta
;
12346 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
12347 SetPort (GetWindowPort (window_ptr
));
12348 GlobalToLocal (&point
);
12349 XSETINT (bufp
->x
, point
.h
);
12350 XSETINT (bufp
->y
, point
.v
);
12351 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12352 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
12356 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12360 /* Send the event to the appropriate receiver. */
12361 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12365 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
12366 #endif /* USE_CARBON_EVENTS */
12372 WindowPtr window_ptr
= FrontWindow ();
12375 #if USE_CARBON_EVENTS
12376 /* This is needed to send mouse events like aqua window buttons
12377 to the correct handler. */
12378 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
12382 if (!is_emacs_window(window_ptr
))
12386 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12387 && er
.what
== mouseUp
)
12389 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12390 Point mouse_loc
= er
.where
;
12392 /* Convert to local coordinates of new window. */
12393 #if TARGET_API_MAC_CARBON
12394 SetPort (GetWindowPort (window_ptr
));
12396 SetPort (window_ptr
);
12399 GlobalToLocal (&mouse_loc
);
12401 #if USE_CARBON_EVENTS
12402 bufp
->code
= mac_get_mouse_btn (eventRef
);
12404 bufp
->code
= 0; /* only one mouse button */
12406 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
12407 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12408 bufp
->part
= scroll_bar_handle
;
12409 #if USE_CARBON_EVENTS
12410 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12412 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12414 bufp
->modifiers
|= up_modifier
;
12415 bufp
->timestamp
= er
.when
* (1000 / 60);
12416 /* ticks to milliseconds */
12418 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12419 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12420 tracked_scroll_bar
->dragging
= Qnil
;
12421 mouse_tracking_in_progress
= mouse_tracking_none
;
12422 tracked_scroll_bar
= NULL
;
12427 part_code
= FindWindow (er
.where
, &window_ptr
);
12433 struct frame
*f
= ((mac_output
*)
12434 GetWRefCon (FrontWindow ()))->mFP
;
12435 saved_menu_event_location
= er
.where
;
12436 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
12437 XSETFRAME (bufp
->frame_or_window
, f
);
12443 if (window_ptr
!= FrontWindow ())
12444 SelectWindow (window_ptr
);
12447 SInt16 control_part_code
;
12449 struct mac_output
*mwp
= (mac_output
*)
12450 GetWRefCon (window_ptr
);
12451 Point mouse_loc
= er
.where
;
12453 /* convert to local coordinates of new window */
12454 #if TARGET_API_MAC_CARBON
12455 SetPort (GetWindowPort (window_ptr
));
12457 SetPort (window_ptr
);
12460 GlobalToLocal (&mouse_loc
);
12461 #if TARGET_API_MAC_CARBON
12462 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12463 &control_part_code
);
12465 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12468 #if USE_CARBON_EVENTS
12469 bufp
->code
= mac_get_mouse_btn (eventRef
);
12471 bufp
->code
= 0; /* only one mouse button */
12473 XSETINT (bufp
->x
, mouse_loc
.h
);
12474 XSETINT (bufp
->y
, mouse_loc
.v
);
12475 bufp
->timestamp
= er
.when
* (1000 / 60);
12476 /* ticks to milliseconds */
12478 #if TARGET_API_MAC_CARBON
12481 if (control_part_code
!= 0)
12484 struct scroll_bar
*bar
= (struct scroll_bar
*)
12485 GetControlReference (ch
);
12486 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12488 if (er
.what
== mouseDown
12489 && control_part_code
== kControlIndicatorPart
)
12491 mouse_tracking_in_progress
12492 = mouse_tracking_scroll_bar
;
12493 tracked_scroll_bar
= bar
;
12497 mouse_tracking_in_progress
= mouse_tracking_none
;
12498 tracked_scroll_bar
= NULL
;
12503 bufp
->kind
= MOUSE_CLICK_EVENT
;
12504 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12505 if (er
.what
== mouseDown
)
12506 mouse_tracking_in_progress
12507 = mouse_tracking_mouse_movement
;
12509 mouse_tracking_in_progress
= mouse_tracking_none
;
12512 #if USE_CARBON_EVENTS
12513 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12515 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12521 bufp
->modifiers
|= down_modifier
;
12524 bufp
->modifiers
|= up_modifier
;
12533 #if TARGET_API_MAC_CARBON
12537 GetQDGlobalsScreenBits (&bm
);
12538 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12540 #else /* not TARGET_API_MAC_CARBON */
12541 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12542 #endif /* not TARGET_API_MAC_CARBON */
12546 if (TrackGoAway (window_ptr
, er
.where
))
12548 bufp
->kind
= DELETE_WINDOW_EVENT
;
12549 XSETFRAME (bufp
->frame_or_window
,
12550 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12555 /* window resize handling added --ben */
12557 do_grow_window(window_ptr
, &er
);
12560 /* window zoom handling added --ben */
12563 if (TrackBox (window_ptr
, er
.where
, part_code
))
12564 do_zoom_window (window_ptr
, part_code
);
12576 #if USE_CARBON_EVENTS
12577 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
12585 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12588 #if USE_CARBON_EVENTS
12589 /* When using Carbon Events, we need to pass raw keyboard events
12590 to the TSM ourselves. If TSM handles it, it will pass back
12591 noErr, otherwise it will pass back "eventNotHandledErr" and
12592 we can process it normally. */
12593 if ((!NILP (Vmac_pass_command_to_system
)
12594 || !(er
.modifiers
& cmdKey
))
12595 && (!NILP (Vmac_pass_control_to_system
)
12596 || !(er
.modifiers
& controlKey
)))
12599 err
= SendEventToEventTarget (eventRef
,
12600 GetEventDispatcherTarget ());
12601 if (err
!= eventNotHandledErr
)
12606 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
12615 if (keycode_to_xkeysym (keycode
, &xkeysym
))
12617 bufp
->code
= 0xff00 | xkeysym
;
12618 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
12622 if (er
.modifiers
& (controlKey
|
12623 (NILP (Vmac_command_key_is_meta
) ? optionKey
12626 /* This code comes from Keyboard Resource, Appendix
12627 C of IM - Text. This is necessary since shift is
12628 ignored in KCHR table translation when option or
12629 command is pressed. It also does not translate
12630 correctly control-shift chars like C-% so mask off
12632 int new_modifiers
= er
.modifiers
& 0xe600;
12633 /* mask off option and command */
12634 int new_keycode
= keycode
| new_modifiers
;
12635 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12636 unsigned long some_state
= 0;
12637 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12638 &some_state
) & 0xff;
12641 bufp
->code
= er
.message
& charCodeMask
;
12642 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12646 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12647 convert non-ASCII characters typed at the Mac keyboard
12648 (presumed to be in the Mac Roman encoding) to iso-latin-1
12649 encoding before they are passed to Emacs. This enables the
12650 Mac keyboard to be used to enter non-ASCII iso-latin-1
12651 characters directly. */
12652 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12653 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
12655 static TECObjectRef converter
= NULL
;
12656 OSStatus the_err
= noErr
;
12657 OSStatus convert_status
= noErr
;
12659 if (converter
== NULL
)
12661 the_err
= TECCreateConverter (&converter
,
12662 kTextEncodingMacRoman
,
12663 mac_keyboard_text_encoding
);
12664 current_mac_keyboard_text_encoding
12665 = mac_keyboard_text_encoding
;
12667 else if (mac_keyboard_text_encoding
12668 != current_mac_keyboard_text_encoding
)
12670 /* Free the converter for the current encoding before
12671 creating a new one. */
12672 TECDisposeConverter (converter
);
12673 the_err
= TECCreateConverter (&converter
,
12674 kTextEncodingMacRoman
,
12675 mac_keyboard_text_encoding
);
12676 current_mac_keyboard_text_encoding
12677 = mac_keyboard_text_encoding
;
12680 if (the_err
== noErr
)
12682 unsigned char ch
= bufp
->code
;
12683 ByteCount actual_input_length
, actual_output_length
;
12684 unsigned char outch
;
12686 convert_status
= TECConvertText (converter
, &ch
, 1,
12687 &actual_input_length
,
12689 &actual_output_length
);
12690 if (convert_status
== noErr
12691 && actual_input_length
== 1
12692 && actual_output_length
== 1)
12693 bufp
->code
= outch
;
12697 #if USE_CARBON_EVENTS
12698 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12700 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12705 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
12706 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12709 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
12714 case kHighLevelEvent
:
12715 drag_and_drop_file_list
= Qnil
;
12717 AEProcessAppleEvent(&er
);
12719 /* Build a DRAG_N_DROP_EVENT type event as is done in
12720 constuct_drag_n_drop in w32term.c. */
12721 if (!NILP (drag_and_drop_file_list
))
12723 struct frame
*f
= NULL
;
12727 wp
= FrontNonFloatingWindow ();
12731 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
12732 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
12733 wp
= FrontNonFloatingWindow ();
12736 if (wp
&& is_emacs_window(wp
))
12737 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12739 bufp
->kind
= DRAG_N_DROP_EVENT
;
12741 bufp
->timestamp
= er
.when
* (1000 / 60);
12742 /* ticks to milliseconds */
12743 #if USE_CARBON_EVENTS
12744 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12746 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12749 XSETINT (bufp
->x
, 0);
12750 XSETINT (bufp
->y
, 0);
12752 XSETFRAME (frame
, f
);
12753 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12755 /* Regardless of whether Emacs was suspended or in the
12756 foreground, ask it to redraw its entire screen.
12757 Otherwise parts of the screen can be left in an
12758 inconsistent state. */
12760 #if TARGET_API_MAC_CARBON
12764 GetWindowPortBounds (wp
, &r
);
12765 InvalWindowRect (wp
, &r
);
12767 #else /* not TARGET_API_MAC_CARBON */
12768 InvalRect (&(wp
->portRect
));
12769 #endif /* not TARGET_API_MAC_CARBON */
12776 #if USE_CARBON_EVENTS
12777 ReleaseEvent (eventRef
);
12781 /* If the focus was just given to an autoraising frame,
12783 /* ??? This ought to be able to handle more than one such frame. */
12784 if (pending_autoraise_frame
)
12786 x_raise_frame (pending_autoraise_frame
);
12787 pending_autoraise_frame
= 0;
12790 #if !TARGET_API_MAC_CARBON
12791 check_alarm (); /* simulate the handling of a SIGALRM */
12795 static Point old_mouse_pos
= { -1, -1 };
12797 if (app_is_suspended
)
12799 old_mouse_pos
.h
= -1;
12800 old_mouse_pos
.v
= -1;
12808 struct scroll_bar
*sb
;
12810 wp
= FrontWindow ();
12811 if (is_emacs_window (wp
))
12813 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12815 #if TARGET_API_MAC_CARBON
12816 SetPort (GetWindowPort (wp
));
12821 GetMouse (&mouse_pos
);
12823 if (!EqualPt (mouse_pos
, old_mouse_pos
))
12825 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12826 && tracked_scroll_bar
)
12827 x_scroll_bar_note_movement (tracked_scroll_bar
,
12829 - XINT (tracked_scroll_bar
->top
),
12830 TickCount() * (1000 / 60));
12832 note_mouse_movement (f
, &mouse_pos
);
12834 old_mouse_pos
= mouse_pos
;
12846 /* Need to override CodeWarrior's input function so no conversion is
12847 done on newlines Otherwise compiled functions in .elc files will be
12848 read incorrectly. Defined in ...:MSL C:MSL
12849 Common:Source:buffer_io.c. */
12852 __convert_to_newlines (unsigned char * p
, size_t * n
)
12854 #pragma unused(p,n)
12858 __convert_from_newlines (unsigned char * p
, size_t * n
)
12860 #pragma unused(p,n)
12865 /* Initialize the struct pointed to by MW to represent a new COLS x
12866 ROWS Macintosh window, using font with name FONTNAME and size
12869 NewMacWindow (FRAME_PTR fp
)
12872 #if TARGET_API_MAC_CARBON
12873 static int making_terminal_window
= 0;
12875 static int making_terminal_window
= 1;
12878 mwp
= fp
->output_data
.mac
;
12880 if (making_terminal_window
)
12882 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
12885 making_terminal_window
= 0;
12888 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
12891 SetWRefCon (mwp
->mWP
, (long) mwp
);
12892 /* so that update events can find this mac_output struct */
12893 mwp
->mFP
= fp
; /* point back to emacs frame */
12895 #if TARGET_API_MAC_CARBON
12896 SetPort (GetWindowPort (mwp
->mWP
));
12898 SetPort (mwp
->mWP
);
12903 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
12904 ShowWindow (mwp
->mWP
);
12910 make_mac_frame (struct frame
*f
)
12912 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
12913 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
12915 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
12919 f
->output_data
.mac
->cursor_pixel
= 0;
12920 f
->output_data
.mac
->border_pixel
= 0x00ff00;
12921 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
12922 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
12924 f
->output_data
.mac
->fontset
= -1;
12925 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12926 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12927 f
->output_data
.mac
->left_pos
= 4;
12928 f
->output_data
.mac
->top_pos
= 4;
12929 f
->output_data
.mac
->border_width
= 0;
12930 f
->output_data
.mac
->explicit_parent
= 0;
12932 f
->output_data
.mac
->internal_border_width
= 0;
12934 f
->output_method
= output_mac
;
12944 make_mac_terminal_frame (struct frame
*f
)
12948 XSETFRAME (frame
, f
);
12950 f
->output_method
= output_mac
;
12951 f
->output_data
.mac
= (struct mac_output
*)
12952 xmalloc (sizeof (struct mac_output
));
12953 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
12954 f
->output_data
.mac
->fontset
= -1;
12955 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12956 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12958 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
12963 make_mac_frame (f
);
12967 /* Need to be initialized for unshow_buffer in window.c. */
12968 selected_window
= f
->selected_window
;
12970 Fmodify_frame_parameters (frame
,
12971 Fcons (Fcons (Qfont
,
12972 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
12973 Fmodify_frame_parameters (frame
,
12974 Fcons (Fcons (Qforeground_color
,
12975 build_string ("black")), Qnil
));
12976 Fmodify_frame_parameters (frame
,
12977 Fcons (Fcons (Qbackground_color
,
12978 build_string ("white")), Qnil
));
12982 /***********************************************************************
12984 ***********************************************************************/
12986 #ifdef USE_X_TOOLKIT
12987 static XrmOptionDescRec emacs_options
[] = {
12988 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
12989 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
12991 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
12992 XrmoptionSepArg
, NULL
},
12993 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
12995 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12996 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12997 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12998 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12999 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13000 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13001 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13003 #endif /* USE_X_TOOLKIT */
13005 #ifdef MULTI_KBOARD
13006 /* Test whether two display-name strings agree up to the dot that separates
13007 the screen number from the server number. */
13009 same_x_server (name1
, name2
)
13010 char *name1
, *name2
;
13012 int seen_colon
= 0;
13013 unsigned char *system_name
= SDATA (Vsystem_name
);
13014 int system_name_length
= strlen (system_name
);
13015 int length_until_period
= 0;
13017 while (system_name
[length_until_period
] != 0
13018 && system_name
[length_until_period
] != '.')
13019 length_until_period
++;
13021 /* Treat `unix' like an empty host name. */
13022 if (! strncmp (name1
, "unix:", 5))
13024 if (! strncmp (name2
, "unix:", 5))
13026 /* Treat this host's name like an empty host name. */
13027 if (! strncmp (name1
, system_name
, system_name_length
)
13028 && name1
[system_name_length
] == ':')
13029 name1
+= system_name_length
;
13030 if (! strncmp (name2
, system_name
, system_name_length
)
13031 && name2
[system_name_length
] == ':')
13032 name2
+= system_name_length
;
13033 /* Treat this host's domainless name like an empty host name. */
13034 if (! strncmp (name1
, system_name
, length_until_period
)
13035 && name1
[length_until_period
] == ':')
13036 name1
+= length_until_period
;
13037 if (! strncmp (name2
, system_name
, length_until_period
)
13038 && name2
[length_until_period
] == ':')
13039 name2
+= length_until_period
;
13041 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13045 if (seen_colon
&& *name1
== '.')
13049 && (*name1
== '.' || *name1
== '\0')
13050 && (*name2
== '.' || *name2
== '\0'));
13054 int mac_initialized
= 0;
13057 mac_initialize_display_info ()
13059 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
13060 GDHandle main_device_handle
;
13062 bzero (dpyinfo
, sizeof (*dpyinfo
));
13064 /* Put it on x_display_name_list. */
13065 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
13066 x_display_name_list
);
13067 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13070 dpyinfo
->mac_id_name
13071 = (char *) xmalloc (SCHARS (Vinvocation_name
)
13072 + SCHARS (Vsystem_name
)
13074 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
13075 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
13077 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
13078 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
13081 main_device_handle
= LMGetMainDevice();
13083 dpyinfo
->reference_count
= 0;
13084 dpyinfo
->resx
= 75.0;
13085 dpyinfo
->resy
= 75.0;
13086 dpyinfo
->n_planes
= 1;
13087 dpyinfo
->n_cbits
= 16;
13088 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13089 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13090 dpyinfo
->grabbed
= 0;
13091 dpyinfo
->root_window
= NULL
;
13093 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13094 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13095 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13096 dpyinfo
->mouse_face_window
= Qnil
;
13099 struct mac_display_info
*
13100 mac_term_init (display_name
, xrm_option
, resource_name
)
13101 Lisp_Object display_name
;
13103 char *resource_name
;
13105 struct mac_display_info
*dpyinfo
;
13106 GDHandle main_device_handle
;
13108 if (!mac_initialized
)
13111 mac_initialized
= 1;
13114 mac_initialize_display_info (display_name
);
13116 dpyinfo
= &one_mac_display_info
;
13118 main_device_handle
= LMGetMainDevice();
13120 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13121 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13130 extern int inhibit_window_system
;
13131 extern int noninteractive
;
13132 CFBundleRef appsBundle
;
13135 /* No need to test if already -nw*/
13136 if (inhibit_window_system
|| noninteractive
)
13139 appsBundle
= CFBundleGetMainBundle();
13140 if (appsBundle
!= NULL
)
13142 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
13143 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
13144 /* We found the bundle identifier, now we know we are valid. */
13151 /* MAC_TODO: Have this start the bundled executable */
13153 /* For now, prevent the fatal error by bringing it up in the terminal */
13154 inhibit_window_system
= 1;
13158 MakeMeTheFrontProcess ()
13160 ProcessSerialNumber psn
;
13163 err
= GetCurrentProcess (&psn
);
13165 (void) SetFrontProcess (&psn
);
13168 /***** Code to handle C-g testing *****/
13170 /* Contains the Mac modifier formed from quit_char */
13171 static mac_quit_char_modifiers
= 0;
13172 static mac_quit_char_keycode
;
13173 extern int quit_char
;
13176 mac_determine_quit_char_modifiers()
13178 /* Todo: Determine modifiers from quit_char. */
13179 UInt32 qc_modifiers
= ctrl_modifier
;
13181 /* Map modifiers */
13182 mac_quit_char_modifiers
= 0;
13183 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
13184 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
13185 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
13186 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
13190 init_quit_char_handler ()
13192 /* TODO: Let this support keys other the 'g' */
13193 mac_quit_char_keycode
= 5;
13194 /* Look at <architecture/adb_kb_map.h> for details */
13195 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
13197 mac_determine_quit_char_modifiers();
13201 quit_char_comp (EventRef inEvent
, void *inCompData
)
13203 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
13205 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
13209 UInt32 keyModifiers
;
13210 GetEventParameter(inEvent
, kEventParamKeyCode
,
13211 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
13212 if (keyCode
!= mac_quit_char_keycode
)
13214 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
13215 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
13216 if (keyModifiers
!= mac_quit_char_modifiers
)
13223 mac_check_for_quit_char()
13226 /* If windows are not initialized, return immediately (keep it bouncin')*/
13227 if (!mac_quit_char_modifiers
)
13230 /* Redetermine modifiers because they are based on lisp variables */
13231 mac_determine_quit_char_modifiers();
13233 /* Fill the queue with events */
13234 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
13235 event
= FindSpecificEventInQueue (GetMainEventQueue(), quit_char_comp
, NULL
);
13238 struct input_event e
;
13239 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
13240 /* Use an input_event to emulate what the interrupt handler does. */
13241 e
.kind
= ASCII_KEYSTROKE_EVENT
;
13242 e
.code
= quit_char
;
13244 e
.modifiers
= NULL
;
13245 e
.timestamp
= EventTimeToTicks(GetEventTime(event
))*(1000/60);
13246 XSETFRAME(e
.frame_or_window
, mwp
->mFP
);
13247 /* Remove event from queue to prevent looping. */
13248 RemoveEventFromQueue(GetMainEventQueue(), event
);
13249 ReleaseEvent(event
);
13250 kbd_buffer_store_event(&e
);
13254 #endif /* MAC_OSX */
13256 /* Set up use of X before we make the first connection. */
13258 static struct redisplay_interface x_redisplay_interface
=
13263 x_clear_end_of_line
,
13265 x_after_update_window_line
,
13266 x_update_window_begin
,
13267 x_update_window_end
,
13270 x_clear_mouse_face
,
13271 x_get_glyph_overhangs
,
13272 x_fix_overlapping_area
,
13273 x_draw_fringe_bitmap
13279 rif
= &x_redisplay_interface
;
13281 clear_frame_hook
= x_clear_frame
;
13282 ins_del_lines_hook
= x_ins_del_lines
;
13283 delete_glyphs_hook
= x_delete_glyphs
;
13284 ring_bell_hook
= XTring_bell
;
13285 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13286 set_terminal_modes_hook
= XTset_terminal_modes
;
13287 update_begin_hook
= x_update_begin
;
13288 update_end_hook
= x_update_end
;
13289 set_terminal_window_hook
= XTset_terminal_window
;
13290 read_socket_hook
= XTread_socket
;
13291 frame_up_to_date_hook
= XTframe_up_to_date
;
13292 mouse_position_hook
= XTmouse_position
;
13293 frame_rehighlight_hook
= XTframe_rehighlight
;
13294 frame_raise_lower_hook
= XTframe_raise_lower
;
13296 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13297 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13298 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13299 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13301 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13303 scroll_region_ok
= 1; /* we'll scroll partial frames */
13304 char_ins_del_ok
= 1;
13305 line_ins_del_ok
= 1; /* we'll just blt 'em */
13306 fast_clear_end_of_line
= 1; /* X does this well */
13307 memory_below_frame
= 0; /* we don't remember what scrolls
13312 last_tool_bar_item
= -1;
13313 any_help_event_p
= 0;
13315 /* Try to use interrupt input; if we can't, then start polling. */
13316 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13318 #ifdef USE_X_TOOLKIT
13319 XtToolkitInitialize ();
13320 Xt_app_con
= XtCreateApplicationContext ();
13321 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13323 /* Install an asynchronous timer that processes Xt timeout events
13324 every 0.1s. This is necessary because some widget sets use
13325 timeouts internally, for example the LessTif menu bar, or the
13326 Xaw3d scroll bar. When Xt timouts aren't processed, these
13327 widgets don't behave normally. */
13329 EMACS_TIME interval
;
13330 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13331 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13335 #if USE_TOOLKIT_SCROLL_BARS
13336 xaw3d_arrow_scroll
= False
;
13337 xaw3d_pick_top
= True
;
13341 /* Note that there is no real way portable across R3/R4 to get the
13342 original error handler. */
13343 XSetErrorHandler (x_error_handler
);
13344 XSetIOErrorHandler (x_io_error_quitter
);
13346 /* Disable Window Change signals; they are handled by X events. */
13348 signal (SIGWINCH
, SIG_DFL
);
13349 #endif /* ! defined (SIGWINCH) */
13351 signal (SIGPIPE
, x_connection_signal
);
13354 mac_initialize_display_info ();
13356 #if TARGET_API_MAC_CARBON
13357 init_required_apple_events ();
13359 init_mac_drag_n_drop ();
13361 #if USE_CARBON_EVENTS
13362 init_service_handler ();
13364 init_quit_char_handler ();
13367 DisableMenuCommand (NULL
, kHICommandQuit
);
13369 if (!inhibit_window_system
)
13370 MakeMeTheFrontProcess ();
13379 staticpro (&x_error_message_string
);
13380 x_error_message_string
= Qnil
;
13383 Fprovide (intern ("mac-carbon"), Qnil
);
13385 staticpro (&x_display_name_list
);
13386 x_display_name_list
= Qnil
;
13388 staticpro (&last_mouse_scroll_bar
);
13389 last_mouse_scroll_bar
= Qnil
;
13391 staticpro (&Qvendor_specific_keysyms
);
13392 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13394 staticpro (&last_mouse_press_frame
);
13395 last_mouse_press_frame
= Qnil
;
13397 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13398 staticpro (&Qmac_ready_for_drag_n_drop
);
13401 staticpro (&help_echo
);
13402 help_echo_object
= Qnil
;
13403 staticpro (&help_echo_object
);
13404 help_echo_window
= Qnil
;
13405 staticpro (&help_echo_window
);
13406 previous_help_echo
= Qnil
;
13407 staticpro (&previous_help_echo
);
13408 help_echo_pos
= -1;
13410 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13411 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13412 x_autoselect_window_p
= 0;
13414 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13415 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13416 For example, if a block cursor is over a tab, it will be drawn as
13417 wide as that tab on the display. */);
13418 x_stretch_cursor_p
= 0;
13420 #if 0 /* TODO: Setting underline position from font properties. */
13421 DEFVAR_BOOL ("x-use-underline-position-properties",
13422 &x_use_underline_position_properties
,
13423 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13424 nil means ignore them. If you encounter fonts with bogus
13425 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13426 to 4.1, set this to nil. */);
13427 x_use_underline_position_properties
= 1;
13430 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13431 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13432 Vx_toolkit_scroll_bars
= Qt
;
13434 staticpro (&last_mouse_motion_frame
);
13435 last_mouse_motion_frame
= Qnil
;
13437 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13438 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13439 Otherwise the option key is used. */);
13440 Vmac_command_key_is_meta
= Qt
;
13442 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
13443 doc
: /* Non-nil means that the control and meta keys are reversed. This is
13444 useful for non-standard keyboard layouts. */);
13445 Vmac_reverse_ctrl_meta
= Qnil
;
13447 #if USE_CARBON_EVENTS
13448 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
13449 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
13450 the right click will be mouse-3.
13451 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
13452 Vmac_wheel_button_is_mouse_2
= Qt
;
13454 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
13455 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
13456 Toolbox for processing before Emacs sees it. */);
13457 Vmac_pass_command_to_system
= Qt
;
13459 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
13460 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
13461 Toolbox for processing before Emacs sees it. */);
13462 Vmac_pass_control_to_system
= Qt
;
13465 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13466 doc
: /* One of the Text Encoding Base constant values defined in the
13467 Basic Text Constants section of Inside Macintosh - Text Encoding
13468 Conversion Manager. Its value determines the encoding characters
13469 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13470 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13471 its default value, no conversion takes place. If it is set to
13472 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13473 characters typed on Mac keyboard are first converted into the
13474 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13475 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13476 command, this enables the Mac keyboard to be used to enter non-ASCII
13477 characters directly. */);
13478 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;