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)
123 /* Fringe bitmaps. */
125 enum fringe_bitmap_type
128 LEFT_TRUNCATION_BITMAP
,
129 RIGHT_TRUNCATION_BITMAP
,
130 OVERLAY_ARROW_BITMAP
,
131 CONTINUED_LINE_BITMAP
,
132 CONTINUATION_LINE_BITMAP
,
136 /* Bitmap drawn to indicate lines not displaying text if
137 `indicate-empty-lines' is non-nil. */
142 static unsigned char zv_bits
[] = {
143 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
144 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
145 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
146 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
147 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
148 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
149 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
150 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
152 /* An arrow like this: `<-'. */
155 #define left_height 8
156 static unsigned char left_bits
[] = {
157 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
159 /* Right truncation arrow bitmap `->'. */
161 #define right_width 8
162 #define right_height 8
163 static unsigned char right_bits
[] = {
164 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
166 /* Marker for continued lines. */
168 #define continued_width 8
169 #define continued_height 8
170 static unsigned char continued_bits
[] = {
171 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
173 /* Marker for continuation lines. */
175 #define continuation_width 8
176 #define continuation_height 8
177 static unsigned char continuation_bits
[] = {
178 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
180 /* Overlay arrow bitmap. */
186 static unsigned char ov_bits
[] = {
187 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
189 /* A triangular arrow. */
192 static unsigned char ov_bits
[] = {
193 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
196 extern Lisp_Object Qhelp_echo
;
199 /* Non-nil means Emacs uses toolkit scroll bars. */
201 Lisp_Object Vx_toolkit_scroll_bars
;
203 /* If a string, XTread_socket generates an event to display that string.
204 (The display is done in read_char.) */
206 static Lisp_Object help_echo
;
207 static Lisp_Object help_echo_window
;
208 static Lisp_Object help_echo_object
;
209 static int help_echo_pos
;
211 /* Temporary variable for XTread_socket. */
213 static Lisp_Object previous_help_echo
;
215 /* Non-zero means that a HELP_EVENT has been generated since Emacs
218 static int any_help_event_p
;
220 /* Non-zero means autoselect window with the mouse cursor. */
222 int x_autoselect_window_p
;
224 /* Non-zero means draw block and hollow cursor as wide as the glyph
225 under it. For example, if a block cursor is over a tab, it will be
226 drawn as wide as that tab on the display. */
228 int x_stretch_cursor_p
;
230 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
232 int x_use_underline_position_properties
;
234 /* This is a chain of structures for all the X displays currently in
237 struct x_display_info
*x_display_list
;
239 /* This is a list of cons cells, each of the form (NAME
240 . FONT-LIST-CACHE), one for each element of x_display_list and in
241 the same order. NAME is the name of the frame. FONT-LIST-CACHE
242 records previous values returned by x-list-fonts. */
244 Lisp_Object x_display_name_list
;
246 /* This is display since Mac does not support multiple ones. */
247 struct mac_display_info one_mac_display_info
;
249 /* Frame being updated by update_frame. This is declared in term.c.
250 This is set by update_begin and looked at by all the XT functions.
251 It is zero while not inside an update. In that case, the XT
252 functions assume that `selected_frame' is the frame to apply to. */
254 extern struct frame
*updating_frame
;
256 extern int waiting_for_input
;
258 /* This is a frame waiting to be auto-raised, within XTread_socket. */
260 struct frame
*pending_autoraise_frame
;
262 /* Nominal cursor position -- where to draw output.
263 HPOS and VPOS are window relative glyph matrix coordinates.
264 X and Y are window relative pixel coordinates. */
266 struct cursor_pos output_cursor
;
268 /* Non-zero means user is interacting with a toolkit scroll bar. */
270 static int toolkit_scroll_bar_interaction
;
274 Formerly, we used PointerMotionHintMask (in standard_event_mask)
275 so that we would have to call XQueryPointer after each MotionNotify
276 event to ask for another such event. However, this made mouse tracking
277 slow, and there was a bug that made it eventually stop.
279 Simply asking for MotionNotify all the time seems to work better.
281 In order to avoid asking for motion events and then throwing most
282 of them away or busy-polling the server for mouse positions, we ask
283 the server for pointer motion hints. This means that we get only
284 one event per group of mouse movements. "Groups" are delimited by
285 other kinds of events (focus changes and button clicks, for
286 example), or by XQueryPointer calls; when one of these happens, we
287 get another MotionNotify event the next time the mouse moves. This
288 is at least as efficient as getting motion events when mouse
289 tracking is on, and I suspect only negligibly worse when tracking
292 /* Where the mouse was last time we reported a mouse event. */
294 FRAME_PTR last_mouse_frame
;
295 static Rect last_mouse_glyph
;
296 static Lisp_Object last_mouse_press_frame
;
298 /* The scroll bar in which the last X motion event occurred.
300 If the last X motion event occurred in a scroll bar, we set this so
301 XTmouse_position can know whether to report a scroll bar motion or
304 If the last X motion event didn't occur in a scroll bar, we set
305 this to Qnil, to tell XTmouse_position to return an ordinary motion
308 static Lisp_Object last_mouse_scroll_bar
;
310 /* This is a hack. We would really prefer that XTmouse_position would
311 return the time associated with the position it returns, but there
312 doesn't seem to be any way to wrest the time-stamp from the server
313 along with the position query. So, we just keep track of the time
314 of the last movement we received, and return that in hopes that
315 it's somewhat accurate. */
317 static Time last_mouse_movement_time
;
319 enum mouse_tracking_type
{
321 mouse_tracking_mouse_movement
,
322 mouse_tracking_scroll_bar
325 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
327 struct scroll_bar
*tracked_scroll_bar
= NULL
;
329 /* Incremented by XTread_socket whenever it really tries to read
333 static int volatile input_signal_count
;
335 static int input_signal_count
;
338 /* Used locally within XTread_socket. */
340 static int x_noop_count
;
342 /* Initial values of argv and argc. */
344 extern char **initial_argv
;
345 extern int initial_argc
;
347 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
349 /* Tells if a window manager is present or not. */
351 extern Lisp_Object Vx_no_window_manager
;
353 extern Lisp_Object Qface
, Qmouse_face
;
357 /* A mask of extra modifier bits to put into every keyboard char. */
359 extern int extra_keyboard_modifiers
;
361 static Lisp_Object Qvendor_specific_keysyms
;
364 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
367 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
369 extern int inhibit_window_system
;
372 QDGlobals qd
; /* QuickDraw global information structure. */
376 /* Enumeration for overriding/changing the face to use for drawing
377 glyphs in x_draw_glyphs. */
379 enum draw_glyphs_face
389 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
390 struct mac_display_info
*mac_display_info_for_display (Display
*);
391 static void x_update_window_end
P_ ((struct window
*, int, int));
392 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
393 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
394 int *, int *, Lisp_Object
));
395 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
396 int *, int *, int *, int *, int));
397 static void set_output_cursor
P_ ((struct cursor_pos
*));
398 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
399 int *, int *, int *, int));
400 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
401 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
402 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
403 static void x_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
404 static void show_mouse_face
P_ ((struct x_display_info
*,
405 enum draw_glyphs_face
));
406 static int cursor_in_mouse_face_p
P_ ((struct window
*));
407 static int clear_mouse_face
P_ ((struct mac_display_info
*));
408 static int x_io_error_quitter
P_ ((Display
*));
409 int x_catch_errors
P_ ((Display
*));
410 void x_uncatch_errors
P_ ((Display
*, int));
411 void x_lower_frame
P_ ((struct frame
*));
412 void x_scroll_bar_clear
P_ ((struct frame
*));
413 int x_had_errors_p
P_ ((Display
*));
414 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
415 void x_raise_frame
P_ ((struct frame
*));
416 void x_set_window_size
P_ ((struct frame
*, int, int, int));
417 void x_wm_set_window_state
P_ ((struct frame
*, int));
418 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
419 void mac_initialize
P_ ((void));
420 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
421 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
422 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
424 enum draw_glyphs_face
));
425 static void x_update_end
P_ ((struct frame
*));
426 static void XTframe_up_to_date
P_ ((struct frame
*));
427 static void XTreassert_line_highlight
P_ ((int, int));
428 static void x_change_line_highlight
P_ ((int, int, int, int));
429 static void XTset_terminal_modes
P_ ((void));
430 static void XTreset_terminal_modes
P_ ((void));
431 static void XTcursor_to
P_ ((int, int, int, int));
432 static void x_write_glyphs
P_ ((struct glyph
*, int));
433 static void x_clear_end_of_line
P_ ((int));
434 static void x_clear_frame
P_ ((void));
435 static void x_clear_cursor
P_ ((struct window
*));
436 static void frame_highlight
P_ ((struct frame
*));
437 static void frame_unhighlight
P_ ((struct frame
*));
438 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
439 static void XTframe_rehighlight
P_ ((struct frame
*));
440 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
441 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
442 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
443 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
444 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
445 static int expose_window_tree
P_ ((struct window
*, Rect
*));
446 static int expose_window
P_ ((struct window
*, Rect
*));
447 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
448 Rect
*, enum glyph_row_area
));
449 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
451 void x_display_cursor (struct window
*, int, int, int, int, int);
452 void x_update_cursor
P_ ((struct frame
*, int));
453 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
454 static void x_update_window_cursor
P_ ((struct window
*, int));
455 static void x_erase_phys_cursor
P_ ((struct window
*));
456 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
457 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
458 enum fringe_bitmap_type
, int left_p
));
459 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
461 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
462 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
463 static void notice_overwritten_cursor
P_ ((struct window
*,
465 int, int, int, int));
466 static void x_flush
P_ ((struct frame
*f
));
467 static void x_update_begin
P_ ((struct frame
*));
468 static void x_update_window_begin
P_ ((struct window
*));
469 static void x_draw_vertical_border
P_ ((struct window
*));
470 static void x_after_update_window_line
P_ ((struct glyph_row
*));
471 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
472 static void x_produce_stretch_glyph
P_ ((struct it
*));
474 static void activate_scroll_bars (FRAME_PTR
);
475 static void deactivate_scroll_bars (FRAME_PTR
);
477 static int is_emacs_window (WindowPtr
);
479 extern int image_ascent (struct image
*, struct face
*);
480 void x_set_offset (struct frame
*, int, int, int);
481 int x_bitmap_icon (struct frame
*, Lisp_Object
);
482 void x_make_frame_visible (struct frame
*);
484 extern void window_scroll (Lisp_Object
, int, int, int);
486 /* Defined in macmenu.h. */
487 extern void menubar_selection_callback (FRAME_PTR
, int);
488 extern void set_frame_menubar (FRAME_PTR
, int, int);
490 /* X display function emulation */
492 /* Structure borrowed from Xlib.h to represent two-byte characters in
501 XFreePixmap (display
, pixmap
)
505 PixMap
*p
= (PixMap
*) pixmap
;
512 /* Set foreground color for subsequent QuickDraw commands. Assume
513 graphic port has already been set. */
516 mac_set_forecolor (unsigned long color
)
520 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
521 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
522 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
524 RGBForeColor (&fg_color
);
528 /* Set background color for subsequent QuickDraw commands. Assume
529 graphic port has already been set. */
532 mac_set_backcolor (unsigned long color
)
536 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
537 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
538 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
540 RGBBackColor (&bg_color
);
543 /* Set foreground and background color for subsequent QuickDraw
544 commands. Assume that the graphic port has already been set. */
547 mac_set_colors (GC gc
)
549 mac_set_forecolor (gc
->foreground
);
550 mac_set_backcolor (gc
->background
);
553 /* Mac version of XDrawLine. */
556 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
562 #if TARGET_API_MAC_CARBON
563 SetPort (GetWindowPort (w
));
574 /* Mac version of XClearArea. */
577 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
581 unsigned int width
, height
;
584 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
588 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
589 xgc
.background
= mwp
->x_compatible
.background_pixel
;
591 #if TARGET_API_MAC_CARBON
592 SetPort (GetWindowPort (w
));
597 mac_set_colors (&xgc
);
598 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
603 /* Mac version of XClearWindow. */
606 XClearWindow (display
, w
)
610 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
613 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
614 xgc
.background
= mwp
->x_compatible
.background_pixel
;
616 #if TARGET_API_MAC_CARBON
617 SetPort (GetWindowPort (w
));
622 mac_set_colors (&xgc
);
624 #if TARGET_API_MAC_CARBON
628 GetWindowPortBounds (w
, &r
);
631 #else /* not TARGET_API_MAC_CARBON */
632 EraseRect (&(w
->portRect
));
633 #endif /* not TARGET_API_MAC_CARBON */
637 /* Mac replacement for XCopyArea. */
640 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
649 #if TARGET_API_MAC_CARBON
650 SetPort (GetWindowPort (w
));
656 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
658 #if TARGET_API_MAC_CARBON
662 LockPortBits (GetWindowPort (w
));
663 pmh
= GetPortPixMap (GetWindowPort (w
));
664 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
665 UnlockPortBits (GetWindowPort (w
));
667 #else /* not TARGET_API_MAC_CARBON */
668 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
669 #endif /* not TARGET_API_MAC_CARBON */
673 /* Mac replacement for XSetClipRectangles. */
676 mac_set_clip_rectangle (display
, w
, r
)
681 #if TARGET_API_MAC_CARBON
682 SetPort (GetWindowPort (w
));
691 /* Mac replacement for XSetClipMask. */
694 mac_reset_clipping (display
, w
)
700 #if TARGET_API_MAC_CARBON
701 SetPort (GetWindowPort (w
));
706 SetRect (&r
, -32767, -32767, 32767, 32767);
711 /* Mac replacement for XCreateBitmapFromBitmapData. */
714 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
719 int bytes_per_row
, i
, j
;
721 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
722 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
723 if (!bitmap
->baseAddr
)
726 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
727 for (i
= 0; i
< h
; i
++)
728 for (j
= 0; j
< w
; j
++)
729 if (BitTst (bits
, i
* w
+ j
))
730 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
732 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
737 mac_free_bitmap (bitmap
)
740 xfree (bitmap
->baseAddr
);
743 /* Mac replacement for XFillRectangle. */
746 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
751 unsigned int width
, height
;
755 #if TARGET_API_MAC_CARBON
756 SetPort (GetWindowPort (w
));
762 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
764 PaintRect (&r
); /* using foreground color of gc */
768 /* Mac replacement for XDrawRectangle: dest is a window. */
771 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
776 unsigned int width
, height
;
780 #if TARGET_API_MAC_CARBON
781 SetPort (GetWindowPort (w
));
787 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
789 FrameRect (&r
); /* using foreground color of gc */
793 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
796 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
801 unsigned int width
, height
;
803 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
806 #if TARGET_API_MAC_CARBON
807 SetPort (GetWindowPort (w
));
813 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
815 FrameRect (&r
); /* using foreground color of gc */
821 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
828 int nchars
, mode
, bytes_per_char
;
830 #if TARGET_API_MAC_CARBON
831 SetPort (GetWindowPort (w
));
838 TextFont (gc
->font
->mac_fontnum
);
839 TextSize (gc
->font
->mac_fontsize
);
840 TextFace (gc
->font
->mac_fontface
);
844 DrawText (buf
, 0, nchars
* bytes_per_char
);
848 /* Mac replacement for XDrawString. */
851 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
859 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
863 /* Mac replacement for XDrawString16. */
866 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
874 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
879 /* Mac replacement for XDrawImageString. */
882 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
890 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
894 /* Mac replacement for XDrawString16. */
897 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
905 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
910 /* Mac replacement for XCopyArea: dest must be window. */
913 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
920 unsigned int width
, height
;
925 #if TARGET_API_MAC_CARBON
926 SetPort (GetWindowPort (dest
));
933 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
934 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
936 #if TARGET_API_MAC_CARBON
940 LockPortBits (GetWindowPort (dest
));
941 pmh
= GetPortPixMap (GetWindowPort (dest
));
942 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
943 UnlockPortBits (GetWindowPort (dest
));
945 #else /* not TARGET_API_MAC_CARBON */
946 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
947 #endif /* not TARGET_API_MAC_CARBON */
952 /* Convert a pair of local coordinates to global (screen) coordinates.
953 Assume graphic port has been properly set. */
955 local_to_global_coord (short *h
, short *v
)
969 /* Mac replacement for XCopyArea: used only for scrolling. */
972 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
977 unsigned int width
, height
;
980 #if TARGET_API_MAC_CARBON
981 Rect gw_r
, src_r
, dest_r
;
984 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
985 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
987 SetPort (GetWindowPort (w
));
989 ForeColor (blackColor
);
990 BackColor (whiteColor
);
992 LockPortBits (GetWindowPort (w
));
993 pmh
= GetPortPixMap (GetWindowPort (w
));
994 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
995 UnlockPortBits (GetWindowPort (w
));
998 #else /* not TARGET_API_MAC_CARBON */
1003 mac_set_colors (gc
);
1006 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1007 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1010 /* Need to use global coordinates and screenBits since src and dest
1011 areas overlap in general. */
1012 local_to_global_coord (&src_r
.left
, &src_r
.top
);
1013 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
1014 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
1015 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
1017 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
1019 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1020 color mapping in CopyBits. Otherwise, it will be slow. */
1021 ForeColor (blackColor
);
1022 BackColor (whiteColor
);
1023 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1025 mac_set_colors (gc
);
1027 #endif /* not TARGET_API_MAC_CARBON */
1031 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1034 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1041 unsigned int width
, height
;
1045 int src_right
= ((PixMap
*) src
)->bounds
.right
;
1046 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
1047 int w
= src_right
- src_x
;
1048 int h
= src_bottom
- src_y
;
1050 mac_set_colors (gc
);
1052 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
1053 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
1055 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
1059 /* Mac replacement for XChangeGC. */
1062 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1065 if (mask
& GCForeground
)
1066 gc
->foreground
= xgcv
->foreground
;
1067 if (mask
& GCBackground
)
1068 gc
->background
= xgcv
->background
;
1070 gc
->font
= xgcv
->font
;
1074 /* Mac replacement for XCreateGC. */
1077 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1080 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1081 bzero (gc
, sizeof (XGCValues
));
1083 XChangeGC (ignore
, gc
, mask
, xgcv
);
1089 /* Used in xfaces.c. */
1092 XFreeGC (display
, gc
)
1100 /* Mac replacement for XGetGCValues. */
1103 XGetGCValues (void* ignore
, XGCValues
*gc
,
1104 unsigned long mask
, XGCValues
*xgcv
)
1106 XChangeGC (ignore
, xgcv
, mask
, gc
);
1110 /* Mac replacement for XSetForeground. */
1113 XSetForeground (display
, gc
, color
)
1116 unsigned long color
;
1118 gc
->foreground
= color
;
1122 /* Mac replacement for XSetFont. */
1125 XSetFont (display
, gc
, font
)
1135 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1136 int *direction
,int *font_ascent
,
1137 int *font_descent
, XCharStruct
*cs
)
1139 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1143 /* x_sync is a no-op on Mac. */
1151 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1152 Calls to XFlush should be unnecessary because the X output buffer
1153 is flushed automatically as needed by calls to XPending,
1154 XNextEvent, or XWindowEvent according to the XFlush man page.
1155 XTread_socket calls XPending. Removing XFlush improves
1158 #if TARGET_API_MAC_CARBON
1159 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1161 #define XFlush(DISPLAY) (void) 0
1164 /* Flush display of frame F, or of all frames if F is null. */
1170 #if TARGET_API_MAC_CARBON
1174 Lisp_Object rest
, frame
;
1175 FOR_EACH_FRAME (rest
, frame
)
1176 x_flush (XFRAME (frame
));
1178 else if (FRAME_X_P (f
))
1179 XFlush (FRAME_MAC_DISPLAY (f
));
1181 #endif /* TARGET_API_MAC_CARBON */
1186 /* Return the struct mac_display_info corresponding to DPY. There's
1189 struct mac_display_info
*
1190 mac_display_info_for_display (dpy
)
1193 return &one_mac_display_info
;
1198 /***********************************************************************
1199 Starting and ending an update
1200 ***********************************************************************/
1202 /* Start an update of frame F. This function is installed as a hook
1203 for update_begin, i.e. it is called when update_begin is called.
1204 This function is called prior to calls to x_update_window_begin for
1205 each window being updated. */
1211 /* Nothing to do. */
1215 /* Start update of window W. Set the global variable updated_window
1216 to the window being updated and set output_cursor to the cursor
1220 x_update_window_begin (w
)
1223 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1224 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1227 set_output_cursor (&w
->cursor
);
1231 if (f
== display_info
->mouse_face_mouse_frame
)
1233 /* Don't do highlighting for mouse motion during the update. */
1234 display_info
->mouse_face_defer
= 1;
1236 /* If F needs to be redrawn, simply forget about any prior mouse
1238 if (FRAME_GARBAGED_P (f
))
1239 display_info
->mouse_face_window
= Qnil
;
1241 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1242 their mouse_face_p flag set, which means that they are always
1243 unequal to rows in a desired matrix which never have that
1244 flag set. So, rows containing mouse-face glyphs are never
1245 scrolled, and we don't have to switch the mouse highlight off
1246 here to prevent it from being scrolled. */
1248 /* Can we tell that this update does not affect the window
1249 where the mouse highlight is? If so, no need to turn off.
1250 Likewise, don't do anything if the frame is garbaged;
1251 in that case, the frame's current matrix that we would use
1252 is all wrong, and we will redisplay that line anyway. */
1253 if (!NILP (display_info
->mouse_face_window
)
1254 && w
== XWINDOW (display_info
->mouse_face_window
))
1258 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1259 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1262 if (i
< w
->desired_matrix
->nrows
)
1263 clear_mouse_face (display_info
);
1272 /* Draw a vertical window border to the right of window W if W doesn't
1273 have vertical scroll bars. */
1276 x_draw_vertical_border (w
)
1279 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1281 /* Redraw borders between horizontally adjacent windows. Don't
1282 do it for frames with vertical scroll bars because either the
1283 right scroll bar of a window, or the left scroll bar of its
1284 neighbor will suffice as a border. */
1285 if (!WINDOW_RIGHTMOST_P (w
)
1286 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1290 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1291 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1294 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1295 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1300 /* End update of window W (which is equal to updated_window).
1302 Draw vertical borders between horizontally adjacent windows, and
1303 display W's cursor if CURSOR_ON_P is non-zero.
1305 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1306 glyphs in mouse-face were overwritten. In that case we have to
1307 make sure that the mouse-highlight is properly redrawn.
1309 W may be a menu bar pseudo-window in case we don't have X toolkit
1310 support. Such windows don't have a cursor, so don't display it
1314 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1316 int cursor_on_p
, mouse_face_overwritten_p
;
1318 struct mac_display_info
*dpyinfo
1319 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1321 if (!w
->pseudo_window_p
)
1326 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1328 output_cursor
.x
, output_cursor
.y
);
1330 x_draw_vertical_border (w
);
1334 /* If a row with mouse-face was overwritten, arrange for
1335 XTframe_up_to_date to redisplay the mouse highlight. */
1336 if (mouse_face_overwritten_p
)
1338 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1339 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1340 dpyinfo
->mouse_face_window
= Qnil
;
1344 /* Unhide the caret. This won't actually show the cursor, unless it
1345 was visible before the corresponding call to HideCaret in
1346 x_update_window_begin. */
1347 if (w32_use_visible_system_caret
)
1348 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1351 updated_window
= NULL
;
1355 /* End update of frame F. This function is installed as a hook in
1362 /* Reset the background color of Mac OS Window to that of the frame after
1363 update so that it is used by Mac Toolbox to clear the update region before
1364 an update event is generated. */
1365 #if TARGET_API_MAC_CARBON
1366 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1368 SetPort (FRAME_MAC_WINDOW (f
));
1371 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1373 /* Mouse highlight may be displayed again. */
1374 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1377 XFlush (FRAME_MAC_DISPLAY (f
));
1382 /* This function is called from various places in xdisp.c whenever a
1383 complete update has been performed. The global variable
1384 updated_window is not available here. */
1387 XTframe_up_to_date (f
)
1392 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1394 if (dpyinfo
->mouse_face_deferred_gc
1395 || f
== dpyinfo
->mouse_face_mouse_frame
)
1398 if (dpyinfo
->mouse_face_mouse_frame
)
1399 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1400 dpyinfo
->mouse_face_mouse_x
,
1401 dpyinfo
->mouse_face_mouse_y
);
1402 dpyinfo
->mouse_face_deferred_gc
= 0;
1409 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1410 arrow bitmaps, or clear the fringes if no bitmaps are required
1411 before DESIRED_ROW is made current. The window being updated is
1412 found in updated_window. This function is called from
1413 update_window_line only if it is known that there are differences
1414 between bitmaps to be drawn between current row and DESIRED_ROW. */
1417 x_after_update_window_line (desired_row
)
1418 struct glyph_row
*desired_row
;
1420 struct window
*w
= updated_window
;
1426 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1429 x_draw_row_fringe_bitmaps (w
, desired_row
);
1433 /* When a window has disappeared, make sure that no rest of
1434 full-width rows stays visible in the internal border. Could
1435 check here if updated_window is the leftmost/rightmost window,
1436 but I guess it's not worth doing since vertically split windows
1437 are almost never used, internal border is rarely set, and the
1438 overhead is very small. */
1439 if (windows_or_buffers_changed
1440 && desired_row
->full_width_p
1441 && (f
= XFRAME (w
->frame
),
1442 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1444 && (height
= desired_row
->visible_height
,
1447 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1448 /* Internal border is drawn below the tool bar. */
1449 if (WINDOWP (f
->tool_bar_window
)
1450 && w
== XWINDOW (f
->tool_bar_window
))
1455 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1456 0, y
, width
, height
, 0);
1457 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1458 f
->output_data
.mac
->pixel_width
- width
, y
,
1466 /* Draw the bitmap WHICH in one of the left or right fringes of
1467 window W. ROW is the glyph row for which to display the bitmap; it
1468 determines the vertical position at which the bitmap has to be
1472 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1474 struct glyph_row
*row
;
1475 enum fringe_bitmap_type which
;
1478 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1479 Display
*display
= FRAME_MAC_DISPLAY (f
);
1480 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1481 int x
, y
, wd
, h
, dy
;
1483 unsigned char *bits
;
1486 GC gc
= f
->output_data
.mac
->normal_gc
;
1489 /* Must clip because of partially visible lines. */
1490 x_clip_to_row (w
, row
, gc
, 1);
1492 /* Convert row to frame coordinates. */
1493 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1497 case NO_FRINGE_BITMAP
:
1502 case LEFT_TRUNCATION_BITMAP
:
1508 case OVERLAY_ARROW_BITMAP
:
1514 case RIGHT_TRUNCATION_BITMAP
:
1520 case CONTINUED_LINE_BITMAP
:
1521 wd
= continued_width
;
1522 h
= continued_height
;
1523 bits
= continued_bits
;
1526 case CONTINUATION_LINE_BITMAP
:
1527 wd
= continuation_width
;
1528 h
= continuation_height
;
1529 bits
= continuation_bits
;
1532 case ZV_LINE_BITMAP
:
1534 h
= zv_height
- (y
% zv_period
);
1535 bits
= zv_bits
+ (y
% zv_period
);
1542 /* Clip bitmap if too high. */
1543 if (h
> row
->height
)
1546 /* Set dy to the offset in the row to start drawing the bitmap. */
1547 dy
= (row
->height
- h
) / 2;
1549 /* Draw the bitmap. */
1550 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1551 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1553 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1558 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1559 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1560 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1562 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1563 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1565 /* If W has a vertical border to its left, don't draw over it. */
1566 int border
= ((XFASTINT (w
->left
) > 0
1567 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1569 b1
= (window_box_left (w
, -1)
1570 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1572 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1577 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1578 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1579 x
= (window_box_right (w
, -1)
1580 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1581 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1583 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1585 b1
= window_box_right (w
, -1);
1586 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1592 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1594 gcv
.foreground
= face
->background
;
1596 #if 0 /* MAC_TODO: stipple */
1597 /* In case the same realized face is used for fringes and
1598 for something displayed in the text (e.g. face `region' on
1599 mono-displays, the fill style may have been changed to
1600 FillSolid in x_draw_glyph_string_background. */
1602 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1604 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1607 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1610 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1613 row
->visible_height
);
1615 #if 0 /* MAC_TODO: stipple */
1617 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1621 if (which
== NO_FRINGE_BITMAP
)
1623 mac_reset_clipping (display
, window
);
1627 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1628 gcv
.foreground
= face
->foreground
;
1629 gcv
.background
= face
->background
;
1631 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1633 mac_free_bitmap (&bitmap
);
1634 mac_reset_clipping (display
, window
);
1638 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1639 function with input blocked. */
1642 x_draw_row_fringe_bitmaps (w
, row
)
1644 struct glyph_row
*row
;
1646 struct frame
*f
= XFRAME (w
->frame
);
1647 enum fringe_bitmap_type bitmap
;
1649 xassert (interrupt_input_blocked
);
1651 /* If row is completely invisible, because of vscrolling, we
1652 don't have to draw anything. */
1653 if (row
->visible_height
<= 0)
1656 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1658 /* Decide which bitmap to draw in the left fringe. */
1659 if (row
->overlay_arrow_p
)
1660 bitmap
= OVERLAY_ARROW_BITMAP
;
1661 else if (row
->truncated_on_left_p
)
1662 bitmap
= LEFT_TRUNCATION_BITMAP
;
1663 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1664 bitmap
= CONTINUATION_LINE_BITMAP
;
1665 else if (row
->indicate_empty_line_p
)
1666 bitmap
= ZV_LINE_BITMAP
;
1668 bitmap
= NO_FRINGE_BITMAP
;
1670 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1673 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1675 /* Decide which bitmap to draw in the right fringe. */
1676 if (row
->truncated_on_right_p
)
1677 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1678 else if (row
->continued_p
)
1679 bitmap
= CONTINUED_LINE_BITMAP
;
1680 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1681 bitmap
= ZV_LINE_BITMAP
;
1683 bitmap
= NO_FRINGE_BITMAP
;
1685 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1690 /* This is called when starting Emacs and when restarting after
1691 suspend. When starting Emacs, no window is mapped. And nothing
1692 must be done to Emacs's own window if it is suspended (though that
1696 XTset_terminal_modes ()
1700 /* This is called when exiting or suspending Emacs. Exiting will make
1701 the windows go away, and suspending requires no action. */
1704 XTreset_terminal_modes ()
1710 /***********************************************************************
1712 ***********************************************************************/
1714 /* Set the global variable output_cursor to CURSOR. All cursor
1715 positions are relative to updated_window. */
1718 set_output_cursor (cursor
)
1719 struct cursor_pos
*cursor
;
1721 output_cursor
.hpos
= cursor
->hpos
;
1722 output_cursor
.vpos
= cursor
->vpos
;
1723 output_cursor
.x
= cursor
->x
;
1724 output_cursor
.y
= cursor
->y
;
1728 /* Set a nominal cursor position.
1730 HPOS and VPOS are column/row positions in a window glyph matrix. X
1731 and Y are window text area relative pixel positions.
1733 If this is done during an update, updated_window will contain the
1734 window that is being updated and the position is the future output
1735 cursor position for that window. If updated_window is null, use
1736 selected_window and display the cursor at the given position. */
1739 XTcursor_to (vpos
, hpos
, y
, x
)
1740 int vpos
, hpos
, y
, x
;
1744 /* If updated_window is not set, work on selected_window. */
1748 w
= XWINDOW (selected_window
);
1750 /* Set the output cursor. */
1751 output_cursor
.hpos
= hpos
;
1752 output_cursor
.vpos
= vpos
;
1753 output_cursor
.x
= x
;
1754 output_cursor
.y
= y
;
1756 /* If not called as part of an update, really display the cursor.
1757 This will also set the cursor position of W. */
1758 if (updated_window
== NULL
)
1761 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1762 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1769 /***********************************************************************
1771 ***********************************************************************/
1773 /* Function prototypes of this page. */
1775 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1779 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1780 int, XChar2b
*, int));
1781 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1782 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1783 static void x_append_glyph
P_ ((struct it
*));
1784 static void x_append_composite_glyph
P_ ((struct it
*));
1785 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1787 static void x_produce_glyphs
P_ ((struct it
*));
1788 static void x_produce_image_glyph
P_ ((struct it
*it
));
1791 /* Return a pointer to per-char metric information in FONT of a
1792 character pointed by B which is a pointer to an XChar2b. */
1794 #define PER_CHAR_METRIC(font, b) \
1796 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1797 + (((font)->min_byte1 || (font)->max_byte1) \
1798 ? (((b)->byte1 - (font)->min_byte1) \
1799 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1801 : &((font)->max_bounds))
1804 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1805 is not contained in the font. */
1807 static INLINE XCharStruct
*
1808 x_per_char_metric (font
, char2b
)
1812 /* The result metric information. */
1813 XCharStruct
*pcm
= NULL
;
1815 xassert (font
&& char2b
);
1817 if (font
->per_char
!= NULL
)
1819 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1821 /* min_char_or_byte2 specifies the linear character index
1822 corresponding to the first element of the per_char array,
1823 max_char_or_byte2 is the index of the last character. A
1824 character with non-zero CHAR2B->byte1 is not in the font.
1825 A character with byte2 less than min_char_or_byte2 or
1826 greater max_char_or_byte2 is not in the font. */
1827 if (char2b
->byte1
== 0
1828 && char2b
->byte2
>= font
->min_char_or_byte2
1829 && char2b
->byte2
<= font
->max_char_or_byte2
)
1830 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1834 /* If either min_byte1 or max_byte1 are nonzero, both
1835 min_char_or_byte2 and max_char_or_byte2 are less than
1836 256, and the 2-byte character index values corresponding
1837 to the per_char array element N (counting from 0) are:
1839 byte1 = N/D + min_byte1
1840 byte2 = N\D + min_char_or_byte2
1844 D = max_char_or_byte2 - min_char_or_byte2 + 1
1845 / = integer division
1846 \ = integer modulus */
1847 if (char2b
->byte1
>= font
->min_byte1
1848 && char2b
->byte1
<= font
->max_byte1
1849 && char2b
->byte2
>= font
->min_char_or_byte2
1850 && char2b
->byte2
<= font
->max_char_or_byte2
)
1852 pcm
= (font
->per_char
1853 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1854 * (char2b
->byte1
- font
->min_byte1
))
1855 + (char2b
->byte2
- font
->min_char_or_byte2
));
1861 /* If the per_char pointer is null, all glyphs between the first
1862 and last character indexes inclusive have the same
1863 information, as given by both min_bounds and max_bounds. */
1864 if (char2b
->byte2
>= font
->min_char_or_byte2
1865 && char2b
->byte2
<= font
->max_char_or_byte2
)
1866 pcm
= &font
->max_bounds
;
1869 return ((pcm
== NULL
1870 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1875 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1876 the two-byte form of C. Encoding is returned in *CHAR2B. */
1879 x_encode_char (c
, char2b
, font_info
)
1882 struct font_info
*font_info
;
1884 int charset
= CHAR_CHARSET (c
);
1885 XFontStruct
*font
= font_info
->font
;
1887 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1888 This may be either a program in a special encoder language or a
1890 if (font_info
->font_encoder
)
1892 /* It's a program. */
1893 struct ccl_program
*ccl
= font_info
->font_encoder
;
1895 if (CHARSET_DIMENSION (charset
) == 1)
1897 ccl
->reg
[0] = charset
;
1898 ccl
->reg
[1] = char2b
->byte2
;
1902 ccl
->reg
[0] = charset
;
1903 ccl
->reg
[1] = char2b
->byte1
;
1904 ccl
->reg
[2] = char2b
->byte2
;
1907 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1909 /* We assume that MSBs are appropriately set/reset by CCL
1911 if (font
->max_byte1
== 0) /* 1-byte font */
1912 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1914 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1916 else if (font_info
->encoding
[charset
])
1918 /* Fixed encoding scheme. See fontset.h for the meaning of the
1919 encoding numbers. */
1920 int enc
= font_info
->encoding
[charset
];
1922 if ((enc
== 1 || enc
== 2)
1923 && CHARSET_DIMENSION (charset
) == 2)
1924 char2b
->byte1
|= 0x80;
1926 if (enc
== 1 || enc
== 3)
1927 char2b
->byte2
|= 0x80;
1933 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1934 char2b
->byte1
= sjis1
;
1935 char2b
->byte2
= sjis2
;
1941 /* Get face and two-byte form of character C in face FACE_ID on frame
1942 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1943 means we want to display multibyte text. Value is a pointer to a
1944 realized face that is ready for display. */
1946 static INLINE
struct face
*
1947 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1953 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1957 /* Unibyte case. We don't have to encode, but we have to make
1958 sure to use a face suitable for unibyte. */
1961 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1962 face
= FACE_FROM_ID (f
, face_id
);
1964 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1966 /* Case of ASCII in a face known to fit ASCII. */
1972 int c1
, c2
, charset
;
1974 /* Split characters into bytes. If c2 is -1 afterwards, C is
1975 really a one-byte character so that byte1 is zero. */
1976 SPLIT_CHAR (c
, charset
, c1
, c2
);
1978 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1980 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1982 /* Maybe encode the character in *CHAR2B. */
1983 if (face
->font
!= NULL
)
1985 struct font_info
*font_info
1986 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1988 x_encode_char (c
, char2b
, font_info
);
1992 /* Make sure X resources of the face are allocated. */
1993 xassert (face
!= NULL
);
1994 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2000 /* Get face and two-byte form of character glyph GLYPH on frame F.
2001 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
2002 a pointer to a realized face that is ready for display. */
2004 static INLINE
struct face
*
2005 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
2007 struct glyph
*glyph
;
2013 xassert (glyph
->type
== CHAR_GLYPH
);
2014 face
= FACE_FROM_ID (f
, glyph
->face_id
);
2019 if (!glyph
->multibyte_p
)
2021 /* Unibyte case. We don't have to encode, but we have to make
2022 sure to use a face suitable for unibyte. */
2024 char2b
->byte2
= glyph
->u
.ch
;
2026 else if (glyph
->u
.ch
< 128
2027 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
2029 /* Case of ASCII in a face known to fit ASCII. */
2031 char2b
->byte2
= glyph
->u
.ch
;
2035 int c1
, c2
, charset
;
2037 /* Split characters into bytes. If c2 is -1 afterwards, C is
2038 really a one-byte character so that byte1 is zero. */
2039 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
2041 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
2043 char2b
->byte1
= 0, char2b
->byte2
= c1
;
2045 /* Maybe encode the character in *CHAR2B. */
2046 if (charset
!= CHARSET_ASCII
)
2048 struct font_info
*font_info
2049 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2052 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
2055 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2060 /* Make sure X resources of the face are allocated. */
2061 xassert (face
!= NULL
);
2062 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2067 /* Store one glyph for IT->char_to_display in IT->glyph_row.
2068 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2074 struct glyph
*glyph
;
2075 enum glyph_row_area area
= it
->area
;
2077 xassert (it
->glyph_row
);
2078 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
2080 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2081 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2083 glyph
->charpos
= CHARPOS (it
->position
);
2084 glyph
->object
= it
->object
;
2085 glyph
->pixel_width
= it
->pixel_width
;
2086 glyph
->voffset
= it
->voffset
;
2087 glyph
->type
= CHAR_GLYPH
;
2088 glyph
->multibyte_p
= it
->multibyte_p
;
2089 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2090 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2091 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2092 || it
->phys_descent
> it
->descent
);
2093 glyph
->padding_p
= 0;
2094 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
2095 glyph
->face_id
= it
->face_id
;
2096 glyph
->u
.ch
= it
->char_to_display
;
2097 ++it
->glyph_row
->used
[area
];
2101 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
2102 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2105 x_append_composite_glyph (it
)
2108 struct glyph
*glyph
;
2109 enum glyph_row_area area
= it
->area
;
2111 xassert (it
->glyph_row
);
2113 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2114 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2116 glyph
->charpos
= CHARPOS (it
->position
);
2117 glyph
->object
= it
->object
;
2118 glyph
->pixel_width
= it
->pixel_width
;
2119 glyph
->voffset
= it
->voffset
;
2120 glyph
->type
= COMPOSITE_GLYPH
;
2121 glyph
->multibyte_p
= it
->multibyte_p
;
2122 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2123 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2124 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2125 || it
->phys_descent
> it
->descent
);
2126 glyph
->padding_p
= 0;
2127 glyph
->glyph_not_available_p
= 0;
2128 glyph
->face_id
= it
->face_id
;
2129 glyph
->u
.cmp_id
= it
->cmp_id
;
2130 ++it
->glyph_row
->used
[area
];
2135 /* Change IT->ascent and IT->height according to the setting of
2139 take_vertical_position_into_account (it
)
2144 if (it
->voffset
< 0)
2145 /* Increase the ascent so that we can display the text higher
2147 it
->ascent
+= abs (it
->voffset
);
2149 /* Increase the descent so that we can display the text lower
2151 it
->descent
+= it
->voffset
;
2156 /* Produce glyphs/get display metrics for the image IT is loaded with.
2157 See the description of struct display_iterator in dispextern.h for
2158 an overview of struct display_iterator. */
2161 x_produce_image_glyph (it
)
2167 xassert (it
->what
== IT_IMAGE
);
2169 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2170 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2173 /* Make sure X resources of the face and image are loaded. */
2174 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2175 prepare_image_for_display (it
->f
, img
);
2177 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2178 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2179 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2183 if (face
->box
!= FACE_NO_BOX
)
2185 if (face
->box_line_width
> 0)
2187 it
->ascent
+= face
->box_line_width
;
2188 it
->descent
+= face
->box_line_width
;
2191 if (it
->start_of_box_run_p
)
2192 it
->pixel_width
+= abs (face
->box_line_width
);
2193 if (it
->end_of_box_run_p
)
2194 it
->pixel_width
+= abs (face
->box_line_width
);
2197 take_vertical_position_into_account (it
);
2201 struct glyph
*glyph
;
2202 enum glyph_row_area area
= it
->area
;
2204 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2205 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2207 glyph
->charpos
= CHARPOS (it
->position
);
2208 glyph
->object
= it
->object
;
2209 glyph
->pixel_width
= it
->pixel_width
;
2210 glyph
->voffset
= it
->voffset
;
2211 glyph
->type
= IMAGE_GLYPH
;
2212 glyph
->multibyte_p
= it
->multibyte_p
;
2213 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2214 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2215 glyph
->overlaps_vertically_p
= 0;
2216 glyph
->padding_p
= 0;
2217 glyph
->glyph_not_available_p
= 0;
2218 glyph
->face_id
= it
->face_id
;
2219 glyph
->u
.img_id
= img
->id
;
2220 ++it
->glyph_row
->used
[area
];
2226 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2227 of the glyph, WIDTH and HEIGHT are the width and height of the
2228 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2229 ascent of the glyph (0 <= ASCENT <= 1). */
2232 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2238 struct glyph
*glyph
;
2239 enum glyph_row_area area
= it
->area
;
2241 xassert (ascent
>= 0 && ascent
<= 1);
2243 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2244 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2246 glyph
->charpos
= CHARPOS (it
->position
);
2247 glyph
->object
= object
;
2248 glyph
->pixel_width
= width
;
2249 glyph
->voffset
= it
->voffset
;
2250 glyph
->type
= STRETCH_GLYPH
;
2251 glyph
->multibyte_p
= it
->multibyte_p
;
2252 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2253 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2254 glyph
->overlaps_vertically_p
= 0;
2255 glyph
->padding_p
= 0;
2256 glyph
->glyph_not_available_p
= 0;
2257 glyph
->face_id
= it
->face_id
;
2258 glyph
->u
.stretch
.ascent
= height
* ascent
;
2259 glyph
->u
.stretch
.height
= height
;
2260 ++it
->glyph_row
->used
[area
];
2265 /* Produce a stretch glyph for iterator IT. IT->object is the value
2266 of the glyph property displayed. The value must be a list
2267 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2270 1. `:width WIDTH' specifies that the space should be WIDTH *
2271 canonical char width wide. WIDTH may be an integer or floating
2274 2. `:relative-width FACTOR' specifies that the width of the stretch
2275 should be computed from the width of the first character having the
2276 `glyph' property, and should be FACTOR times that width.
2278 3. `:align-to HPOS' specifies that the space should be wide enough
2279 to reach HPOS, a value in canonical character units.
2281 Exactly one of the above pairs must be present.
2283 4. `:height HEIGHT' specifies that the height of the stretch produced
2284 should be HEIGHT, measured in canonical character units.
2286 5. `:relative-height FACTOR' specifies that the height of the
2287 stretch should be FACTOR times the height of the characters having
2290 Either none or exactly one of 4 or 5 must be present.
2292 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2293 of the stretch should be used for the ascent of the stretch.
2294 ASCENT must be in the range 0 <= ASCENT <= 100. */
2297 ((INTEGERP (X) || FLOATP (X)) \
2303 x_produce_stretch_glyph (it
)
2306 /* (space :width WIDTH :height HEIGHT. */
2308 extern Lisp_Object Qspace
;
2310 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2311 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2312 extern Lisp_Object QCalign_to
;
2313 Lisp_Object prop
, plist
;
2314 double width
= 0, height
= 0, ascent
= 0;
2315 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2316 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2318 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2320 /* List should start with `space'. */
2321 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2322 plist
= XCDR (it
->object
);
2324 /* Compute the width of the stretch. */
2325 if (prop
= Fplist_get (plist
, QCwidth
),
2327 /* Absolute width `:width WIDTH' specified and valid. */
2328 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2329 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2332 /* Relative width `:relative-width FACTOR' specified and valid.
2333 Compute the width of the characters having the `glyph'
2336 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2339 if (it
->multibyte_p
)
2341 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2342 - IT_BYTEPOS (*it
));
2343 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2346 it2
.c
= *p
, it2
.len
= 1;
2348 it2
.glyph_row
= NULL
;
2349 it2
.what
= IT_CHARACTER
;
2350 x_produce_glyphs (&it2
);
2351 width
= NUMVAL (prop
) * it2
.pixel_width
;
2353 else if (prop
= Fplist_get (plist
, QCalign_to
),
2355 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2357 /* Nothing specified -> width defaults to canonical char width. */
2358 width
= CANON_X_UNIT (it
->f
);
2360 /* Compute height. */
2361 if (prop
= Fplist_get (plist
, QCheight
),
2363 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2364 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2366 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2368 height
= FONT_HEIGHT (font
);
2370 /* Compute percentage of height used for ascent. If
2371 `:ascent ASCENT' is present and valid, use that. Otherwise,
2372 derive the ascent from the font in use. */
2373 if (prop
= Fplist_get (plist
, QCascent
),
2374 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2375 ascent
= NUMVAL (prop
) / 100.0;
2377 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2386 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2387 if (!STRINGP (object
))
2388 object
= it
->w
->buffer
;
2389 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2392 it
->pixel_width
= width
;
2393 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2394 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2397 if (face
->box
!= FACE_NO_BOX
)
2399 if (face
->box_line_width
> 0)
2401 it
->ascent
+= face
->box_line_width
;
2402 it
->descent
+= face
->box_line_width
;
2405 if (it
->start_of_box_run_p
)
2406 it
->pixel_width
+= abs (face
->box_line_width
);
2407 if (it
->end_of_box_run_p
)
2408 it
->pixel_width
+= abs (face
->box_line_width
);
2411 take_vertical_position_into_account (it
);
2414 /* Return proper value to be used as baseline offset of font that has
2415 ASCENT and DESCENT to draw characters by the font at the vertical
2416 center of the line of frame F.
2418 Here, out task is to find the value of BOFF in the following figure;
2420 -------------------------+-----------+-
2421 -+-+---------+-+ | |
2423 | | | | F_ASCENT F_HEIGHT
2426 | | |-|-+------+-----------|------- baseline
2428 | |---------|-+-+ | |
2430 -+-+---------+-+ F_DESCENT |
2431 -------------------------+-----------+-
2433 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2434 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2435 DESCENT = FONT->descent
2436 HEIGHT = FONT_HEIGHT (FONT)
2437 F_DESCENT = (F->output_data.x->font->descent
2438 - F->output_data.x->baseline_offset)
2439 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2442 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2443 (FONT_DESCENT (FONT) \
2444 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2445 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2446 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2448 /* Produce glyphs/get display metrics for the display element IT is
2449 loaded with. See the description of struct display_iterator in
2450 dispextern.h for an overview of struct display_iterator. */
2453 x_produce_glyphs (it
)
2456 it
->glyph_not_available_p
= 0;
2458 if (it
->what
== IT_CHARACTER
)
2462 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2464 int font_not_found_p
;
2465 struct font_info
*font_info
;
2466 int boff
; /* baseline offset */
2467 /* We may change it->multibyte_p upon unibyte<->multibyte
2468 conversion. So, save the current value now and restore it
2471 Note: It seems that we don't have to record multibyte_p in
2472 struct glyph because the character code itself tells if or
2473 not the character is multibyte. Thus, in the future, we must
2474 consider eliminating the field `multibyte_p' in the struct
2477 int saved_multibyte_p
= it
->multibyte_p
;
2479 /* Maybe translate single-byte characters to multibyte, or the
2481 it
->char_to_display
= it
->c
;
2482 if (!ASCII_BYTE_P (it
->c
))
2484 if (unibyte_display_via_language_environment
2485 && SINGLE_BYTE_CHAR_P (it
->c
)
2487 || !NILP (Vnonascii_translation_table
)))
2489 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2490 it
->multibyte_p
= 1;
2491 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2492 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2494 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2495 && !it
->multibyte_p
)
2497 it
->multibyte_p
= 1;
2498 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2499 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2503 /* Get font to use. Encode IT->char_to_display. */
2504 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2505 it
->face_id
, &char2b
,
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 if (it
->char_to_display
>= ' '
2526 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2528 /* Either unibyte or ASCII. */
2533 pcm
= x_per_char_metric (font
, &char2b
);
2534 it
->ascent
= FONT_BASE (font
) + boff
;
2535 it
->descent
= FONT_DESCENT (font
) - boff
;
2539 it
->phys_ascent
= pcm
->ascent
+ boff
;
2540 it
->phys_descent
= pcm
->descent
- boff
;
2541 it
->pixel_width
= pcm
->width
;
2545 it
->glyph_not_available_p
= 1;
2546 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2547 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2548 it
->pixel_width
= FONT_WIDTH (font
);
2551 /* If this is a space inside a region of text with
2552 `space-width' property, change its width. */
2553 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2555 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2557 /* If face has a box, add the box thickness to the character
2558 height. If character has a box line to the left and/or
2559 right, add the box line width to the character's width. */
2560 if (face
->box
!= FACE_NO_BOX
)
2562 int thick
= face
->box_line_width
;
2566 it
->ascent
+= thick
;
2567 it
->descent
+= thick
;
2572 if (it
->start_of_box_run_p
)
2573 it
->pixel_width
+= thick
;
2574 if (it
->end_of_box_run_p
)
2575 it
->pixel_width
+= thick
;
2578 /* If face has an overline, add the height of the overline
2579 (1 pixel) and a 1 pixel margin to the character height. */
2580 if (face
->overline_p
)
2583 take_vertical_position_into_account (it
);
2585 /* If we have to actually produce glyphs, do it. */
2590 /* Translate a space with a `space-width' property
2591 into a stretch glyph. */
2592 double ascent
= (double) FONT_BASE (font
)
2593 / FONT_HEIGHT (font
);
2594 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2595 it
->ascent
+ it
->descent
, ascent
);
2598 x_append_glyph (it
);
2600 /* If characters with lbearing or rbearing are displayed
2601 in this line, record that fact in a flag of the
2602 glyph row. This is used to optimize X output code. */
2603 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2604 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2607 else if (it
->char_to_display
== '\n')
2609 /* A newline has no width but we need the height of the line. */
2610 it
->pixel_width
= 0;
2612 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2613 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2615 if (face
->box
!= FACE_NO_BOX
2616 && face
->box_line_width
> 0)
2618 it
->ascent
+= face
->box_line_width
;
2619 it
->descent
+= face
->box_line_width
;
2622 else if (it
->char_to_display
== '\t')
2624 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2625 int x
= it
->current_x
+ it
->continuation_lines_width
;
2626 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2628 /* If the distance from the current position to the next tab
2629 stop is less than a canonical character width, use the
2630 tab stop after that. */
2631 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2632 next_tab_x
+= tab_width
;
2634 it
->pixel_width
= next_tab_x
- x
;
2636 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2637 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2641 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2642 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2643 it
->ascent
+ it
->descent
, ascent
);
2648 /* A multi-byte character. Assume that the display width of the
2649 character is the width of the character multiplied by the
2650 width of the font. */
2652 /* If we found a font, this font should give us the right
2653 metrics. If we didn't find a font, use the frame's
2654 default font and calculate the width of the character
2655 from the charset width; this is what old redisplay code
2657 pcm
= x_per_char_metric (font
, &char2b
);
2658 if (font_not_found_p
|| !pcm
)
2660 int charset
= CHAR_CHARSET (it
->char_to_display
);
2662 it
->glyph_not_available_p
= 1;
2663 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2664 * CHARSET_WIDTH (charset
));
2665 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2666 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2670 it
->pixel_width
= pcm
->width
;
2671 it
->phys_ascent
= pcm
->ascent
+ boff
;
2672 it
->phys_descent
= pcm
->descent
- boff
;
2674 && (pcm
->lbearing
< 0
2675 || pcm
->rbearing
> pcm
->width
))
2676 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2679 it
->ascent
= FONT_BASE (font
) + boff
;
2680 it
->descent
= FONT_DESCENT (font
) - boff
;
2681 if (face
->box
!= FACE_NO_BOX
)
2683 int thick
= face
->box_line_width
;
2687 it
->ascent
+= thick
;
2688 it
->descent
+= thick
;
2693 if (it
->start_of_box_run_p
)
2694 it
->pixel_width
+= thick
;
2695 if (it
->end_of_box_run_p
)
2696 it
->pixel_width
+= thick
;
2699 /* If face has an overline, add the height of the overline
2700 (1 pixel) and a 1 pixel margin to the character height. */
2701 if (face
->overline_p
)
2704 take_vertical_position_into_account (it
);
2707 x_append_glyph (it
);
2709 it
->multibyte_p
= saved_multibyte_p
;
2711 else if (it
->what
== IT_COMPOSITION
)
2713 /* Note: A composition is represented as one glyph in the
2714 glyph matrix. There are no padding glyphs. */
2717 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2719 int font_not_found_p
;
2720 struct font_info
*font_info
;
2721 int boff
; /* baseline offset */
2722 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2724 /* Maybe translate single-byte characters to multibyte. */
2725 it
->char_to_display
= it
->c
;
2726 if (unibyte_display_via_language_environment
2727 && SINGLE_BYTE_CHAR_P (it
->c
)
2730 && !NILP (Vnonascii_translation_table
))))
2732 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2735 /* Get face and font to use. Encode IT->char_to_display. */
2736 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2737 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2738 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2739 it
->face_id
, &char2b
, it
->multibyte_p
);
2742 /* When no suitable font found, use the default font. */
2743 font_not_found_p
= font
== NULL
;
2744 if (font_not_found_p
)
2746 font
= FRAME_FONT (it
->f
);
2747 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2752 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2753 boff
= font_info
->baseline_offset
;
2754 if (font_info
->vertical_centering
)
2755 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2758 /* There are no padding glyphs, so there is only one glyph to
2759 produce for the composition. Important is that pixel_width,
2760 ascent and descent are the values of what is drawn by
2761 draw_glyphs (i.e. the values of the overall glyphs composed). */
2764 /* If we have not yet calculated pixel size data of glyphs of
2765 the composition for the current face font, calculate them
2766 now. Theoretically, we have to check all fonts for the
2767 glyphs, but that requires much time and memory space. So,
2768 here we check only the font of the first glyph. This leads
2769 to incorrect display very rarely, and C-l (recenter) can
2770 correct the display anyway. */
2771 if (cmp
->font
!= (void *) font
)
2773 /* Ascent and descent of the font of the first character of
2774 this composition (adjusted by baseline offset). Ascent
2775 and descent of overall glyphs should not be less than
2776 them respectively. */
2777 int font_ascent
= FONT_BASE (font
) + boff
;
2778 int font_descent
= FONT_DESCENT (font
) - boff
;
2779 /* Bounding box of the overall glyphs. */
2780 int leftmost
, rightmost
, lowest
, highest
;
2781 int i
, width
, ascent
, descent
;
2783 cmp
->font
= (void *) font
;
2785 /* Initialize the bounding box. */
2786 pcm
= x_per_char_metric (font
, &char2b
);
2790 ascent
= pcm
->ascent
;
2791 descent
= pcm
->descent
;
2795 width
= FONT_WIDTH (font
);
2796 ascent
= FONT_BASE (font
);
2797 descent
= FONT_DESCENT (font
);
2801 lowest
= - descent
+ boff
;
2802 highest
= ascent
+ boff
;
2806 && font_info
->default_ascent
2807 && CHAR_TABLE_P (Vuse_default_ascent
)
2808 && !NILP (Faref (Vuse_default_ascent
,
2809 make_number (it
->char_to_display
))))
2810 highest
= font_info
->default_ascent
+ boff
;
2812 /* Draw the first glyph at the normal position. It may be
2813 shifted to right later if some other glyphs are drawn at
2815 cmp
->offsets
[0] = 0;
2816 cmp
->offsets
[1] = boff
;
2818 /* Set cmp->offsets for the remaining glyphs. */
2819 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2821 int left
, right
, btm
, top
;
2822 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2823 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2825 face
= FACE_FROM_ID (it
->f
, face_id
);
2826 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2831 font
= FRAME_FONT (it
->f
);
2832 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2838 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2839 boff
= font_info
->baseline_offset
;
2840 if (font_info
->vertical_centering
)
2841 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2844 pcm
= x_per_char_metric (font
, &char2b
);
2848 ascent
= pcm
->ascent
;
2849 descent
= pcm
->descent
;
2853 width
= FONT_WIDTH (font
);
2858 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2860 /* Relative composition with or without
2862 left
= (leftmost
+ rightmost
- width
) / 2;
2863 btm
= - descent
+ boff
;
2864 if (font_info
&& font_info
->relative_compose
2865 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2866 || NILP (Faref (Vignore_relative_composition
,
2867 make_number (ch
)))))
2870 if (- descent
>= font_info
->relative_compose
)
2871 /* One extra pixel between two glyphs. */
2873 else if (ascent
<= 0)
2874 /* One extra pixel between two glyphs. */
2875 btm
= lowest
- 1 - ascent
- descent
;
2880 /* A composition rule is specified by an integer
2881 value that encodes global and new reference
2882 points (GREF and NREF). GREF and NREF are
2883 specified by numbers as below:
2891 ---3---4---5--- baseline
2893 6---7---8 -- descent
2895 int rule
= COMPOSITION_RULE (cmp
, i
);
2896 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2898 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2899 grefx
= gref
% 3, nrefx
= nref
% 3;
2900 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2903 + grefx
* (rightmost
- leftmost
) / 2
2904 - nrefx
* width
/ 2);
2905 btm
= ((grefy
== 0 ? highest
2907 : grefy
== 2 ? lowest
2908 : (highest
+ lowest
) / 2)
2909 - (nrefy
== 0 ? ascent
+ descent
2910 : nrefy
== 1 ? descent
- boff
2912 : (ascent
+ descent
) / 2));
2915 cmp
->offsets
[i
* 2] = left
;
2916 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2918 /* Update the bounding box of the overall glyphs. */
2919 right
= left
+ width
;
2920 top
= btm
+ descent
+ ascent
;
2921 if (left
< leftmost
)
2923 if (right
> rightmost
)
2931 /* If there are glyphs whose x-offsets are negative,
2932 shift all glyphs to the right and make all x-offsets
2936 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2937 cmp
->offsets
[i
* 2] -= leftmost
;
2938 rightmost
-= leftmost
;
2941 cmp
->pixel_width
= rightmost
;
2942 cmp
->ascent
= highest
;
2943 cmp
->descent
= - lowest
;
2944 if (cmp
->ascent
< font_ascent
)
2945 cmp
->ascent
= font_ascent
;
2946 if (cmp
->descent
< font_descent
)
2947 cmp
->descent
= font_descent
;
2950 it
->pixel_width
= cmp
->pixel_width
;
2951 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2952 it
->descent
= it
->phys_descent
= cmp
->descent
;
2954 if (face
->box
!= FACE_NO_BOX
)
2956 int thick
= face
->box_line_width
;
2960 it
->ascent
+= thick
;
2961 it
->descent
+= thick
;
2966 if (it
->start_of_box_run_p
)
2967 it
->pixel_width
+= thick
;
2968 if (it
->end_of_box_run_p
)
2969 it
->pixel_width
+= thick
;
2972 /* If face has an overline, add the height of the overline
2973 (1 pixel) and a 1 pixel margin to the character height. */
2974 if (face
->overline_p
)
2977 take_vertical_position_into_account (it
);
2980 x_append_composite_glyph (it
);
2982 else if (it
->what
== IT_IMAGE
)
2983 x_produce_image_glyph (it
);
2984 else if (it
->what
== IT_STRETCH
)
2985 x_produce_stretch_glyph (it
);
2987 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2988 because this isn't true for images with `:ascent 100'. */
2989 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2990 if (it
->area
== TEXT_AREA
)
2991 it
->current_x
+= it
->pixel_width
;
2993 it
->descent
+= it
->extra_line_spacing
;
2995 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2996 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2997 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2998 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
3002 /* Estimate the pixel height of the mode or top line on frame F.
3003 FACE_ID specifies what line's height to estimate. */
3006 x_estimate_mode_line_height (f
, face_id
)
3008 enum face_id face_id
;
3010 int height
= FONT_HEIGHT (FRAME_FONT (f
));
3012 /* This function is called so early when Emacs starts that the face
3013 cache and mode line face are not yet initialized. */
3014 if (FRAME_FACE_CACHE (f
))
3016 struct face
*face
= FACE_FROM_ID (f
, face_id
);
3020 height
= FONT_HEIGHT (face
->font
);
3021 if (face
->box_line_width
> 0)
3022 height
+= 2 * face
->box_line_width
;
3030 /***********************************************************************
3032 ***********************************************************************/
3034 /* A sequence of glyphs to be drawn in the same face.
3036 This data structure is not really completely X specific, so it
3037 could possibly, at least partially, be useful for other systems. It
3038 is currently not part of the external redisplay interface because
3039 it's not clear what other systems will need. */
3043 /* X-origin of the string. */
3046 /* Y-origin and y-position of the base line of this string. */
3049 /* The width of the string, not including a face extension. */
3052 /* The width of the string, including a face extension. */
3053 int background_width
;
3055 /* The height of this string. This is the height of the line this
3056 string is drawn in, and can be different from the height of the
3057 font the string is drawn in. */
3060 /* Number of pixels this string overwrites in front of its x-origin.
3061 This number is zero if the string has an lbearing >= 0; it is
3062 -lbearing, if the string has an lbearing < 0. */
3065 /* Number of pixels this string overwrites past its right-most
3066 nominal x-position, i.e. x + width. Zero if the string's
3067 rbearing is <= its nominal width, rbearing - width otherwise. */
3070 /* The frame on which the glyph string is drawn. */
3073 /* The window on which the glyph string is drawn. */
3076 /* X display and window for convenience. */
3080 /* The glyph row for which this string was built. It determines the
3081 y-origin and height of the string. */
3082 struct glyph_row
*row
;
3084 /* The area within row. */
3085 enum glyph_row_area area
;
3087 /* Characters to be drawn, and number of characters. */
3091 /* A face-override for drawing cursors, mouse face and similar. */
3092 enum draw_glyphs_face hl
;
3094 /* Face in which this string is to be drawn. */
3097 /* Font in which this string is to be drawn. */
3100 /* Font info for this string. */
3101 struct font_info
*font_info
;
3103 /* Non-null means this string describes (part of) a composition.
3104 All characters from char2b are drawn composed. */
3105 struct composition
*cmp
;
3107 /* Index of this glyph string's first character in the glyph
3108 definition of CMP. If this is zero, this glyph string describes
3109 the first character of a composition. */
3112 /* 1 means this glyph strings face has to be drawn to the right end
3113 of the window's drawing area. */
3114 unsigned extends_to_end_of_line_p
: 1;
3116 /* 1 means the background of this string has been drawn. */
3117 unsigned background_filled_p
: 1;
3119 /* 1 means glyph string must be drawn with 16-bit functions. */
3120 unsigned two_byte_p
: 1;
3122 /* 1 means that the original font determined for drawing this glyph
3123 string could not be loaded. The member `font' has been set to
3124 the frame's default font in this case. */
3125 unsigned font_not_found_p
: 1;
3127 /* 1 means that the face in which this glyph string is drawn has a
3129 unsigned stippled_p
: 1;
3131 /* 1 means only the foreground of this glyph string must be drawn,
3132 and we should use the physical height of the line this glyph
3133 string appears in as clip rect. */
3134 unsigned for_overlaps_p
: 1;
3136 /* The GC to use for drawing this glyph string. */
3139 /* A pointer to the first glyph in the string. This glyph
3140 corresponds to char2b[0]. Needed to draw rectangles if
3141 font_not_found_p is 1. */
3142 struct glyph
*first_glyph
;
3144 /* Image, if any. */
3147 struct glyph_string
*next
, *prev
;
3154 x_dump_glyph_string (s
)
3155 struct glyph_string
*s
;
3157 fprintf (stderr
, "glyph string\n");
3158 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
3159 s
->x
, s
->y
, s
->width
, s
->height
);
3160 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
3161 fprintf (stderr
, " hl = %d\n", s
->hl
);
3162 fprintf (stderr
, " left overhang = %d, right = %d\n",
3163 s
->left_overhang
, s
->right_overhang
);
3164 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
3165 fprintf (stderr
, " extends to end of line = %d\n",
3166 s
->extends_to_end_of_line_p
);
3167 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
3168 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
3171 #endif /* GLYPH_DEBUG */
3175 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
3176 struct glyph_string
**,
3177 struct glyph_string
*,
3178 struct glyph_string
*));
3179 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
3180 struct glyph_string
**,
3181 struct glyph_string
*,
3182 struct glyph_string
*));
3183 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3184 struct glyph_string
**,
3185 struct glyph_string
*));
3186 static int x_left_overwritten
P_ ((struct glyph_string
*));
3187 static int x_left_overwriting
P_ ((struct glyph_string
*));
3188 static int x_right_overwritten
P_ ((struct glyph_string
*));
3189 static int x_right_overwriting
P_ ((struct glyph_string
*));
3190 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3192 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3193 XChar2b
*, struct window
*,
3195 enum glyph_row_area
, int,
3196 enum draw_glyphs_face
));
3197 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3198 enum glyph_row_area
, int, int,
3199 enum draw_glyphs_face
, int));
3200 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3201 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3202 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3204 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3205 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3206 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3207 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3208 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3209 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3210 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3211 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3212 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3214 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3215 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
3216 unsigned long *, double, int));*/
3217 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3218 double, int, unsigned long));
3219 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3220 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3221 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3222 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3223 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3224 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3225 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3227 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3228 int, int, int, int, Rect
*));
3229 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3230 int, int, int, Rect
*));
3231 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3232 enum glyph_row_area
));
3233 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3235 enum glyph_row_area
, int, int));
3238 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3242 /* Append the list of glyph strings with head H and tail T to the list
3243 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3246 x_append_glyph_string_lists (head
, tail
, h
, t
)
3247 struct glyph_string
**head
, **tail
;
3248 struct glyph_string
*h
, *t
;
3262 /* Prepend the list of glyph strings with head H and tail T to the
3263 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3267 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3268 struct glyph_string
**head
, **tail
;
3269 struct glyph_string
*h
, *t
;
3283 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3284 Set *HEAD and *TAIL to the resulting list. */
3287 x_append_glyph_string (head
, tail
, s
)
3288 struct glyph_string
**head
, **tail
;
3289 struct glyph_string
*s
;
3291 s
->next
= s
->prev
= NULL
;
3292 x_append_glyph_string_lists (head
, tail
, s
, s
);
3296 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3301 struct glyph_string
*s
;
3303 if (s
->font
== FRAME_FONT (s
->f
)
3304 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3305 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3307 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3310 /* Cursor on non-default face: must merge. */
3314 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3315 xgcv
.foreground
= s
->face
->background
;
3317 /* If the glyph would be invisible, try a different foreground. */
3318 if (xgcv
.foreground
== xgcv
.background
)
3319 xgcv
.foreground
= s
->face
->foreground
;
3320 if (xgcv
.foreground
== xgcv
.background
)
3321 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3322 if (xgcv
.foreground
== xgcv
.background
)
3323 xgcv
.foreground
= s
->face
->foreground
;
3325 /* Make sure the cursor is distinct from text in this face. */
3326 if (xgcv
.background
== s
->face
->background
3327 && xgcv
.foreground
== s
->face
->foreground
)
3329 xgcv
.background
= s
->face
->foreground
;
3330 xgcv
.foreground
= s
->face
->background
;
3333 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3334 xgcv
.font
= s
->font
;
3335 mask
= GCForeground
| GCBackground
| GCFont
;
3337 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3338 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3341 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3342 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3344 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3349 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3352 x_set_mouse_face_gc (s
)
3353 struct glyph_string
*s
;
3358 /* What face has to be used last for the mouse face? */
3359 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3360 face
= FACE_FROM_ID (s
->f
, face_id
);
3362 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3364 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3365 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3367 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3368 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3369 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3371 /* If font in this face is same as S->font, use it. */
3372 if (s
->font
== s
->face
->font
)
3373 s
->gc
= s
->face
->gc
;
3376 /* Otherwise construct scratch_cursor_gc with values from FACE
3381 xgcv
.background
= s
->face
->background
;
3382 xgcv
.foreground
= s
->face
->foreground
;
3383 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3384 xgcv
.font
= s
->font
;
3385 mask
= GCForeground
| GCBackground
| GCFont
;
3387 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3388 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3391 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3392 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3394 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3397 xassert (s
->gc
!= 0);
3401 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3402 Faces to use in the mode line have already been computed when the
3403 matrix was built, so there isn't much to do, here. */
3406 x_set_mode_line_face_gc (s
)
3407 struct glyph_string
*s
;
3409 s
->gc
= s
->face
->gc
;
3413 /* Set S->gc of glyph string S for drawing that glyph string. Set
3414 S->stippled_p to a non-zero value if the face of S has a stipple
3418 x_set_glyph_string_gc (s
)
3419 struct glyph_string
*s
;
3421 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3423 if (s
->hl
== DRAW_NORMAL_TEXT
)
3425 s
->gc
= s
->face
->gc
;
3426 s
->stippled_p
= s
->face
->stipple
!= 0;
3428 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3430 x_set_mode_line_face_gc (s
);
3431 s
->stippled_p
= s
->face
->stipple
!= 0;
3433 else if (s
->hl
== DRAW_CURSOR
)
3435 x_set_cursor_gc (s
);
3438 else if (s
->hl
== DRAW_MOUSE_FACE
)
3440 x_set_mouse_face_gc (s
);
3441 s
->stippled_p
= s
->face
->stipple
!= 0;
3443 else if (s
->hl
== DRAW_IMAGE_RAISED
3444 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3446 s
->gc
= s
->face
->gc
;
3447 s
->stippled_p
= s
->face
->stipple
!= 0;
3451 s
->gc
= s
->face
->gc
;
3452 s
->stippled_p
= s
->face
->stipple
!= 0;
3455 /* GC must have been set. */
3456 xassert (s
->gc
!= 0);
3460 /* Return in *R the clipping rectangle for glyph string S. */
3463 x_get_glyph_string_clip_rect (s
, r
)
3464 struct glyph_string
*s
;
3467 int r_height
, r_width
;
3469 if (s
->row
->full_width_p
)
3471 /* Draw full-width. X coordinates are relative to S->w->left. */
3472 int canon_x
= CANON_X_UNIT (s
->f
);
3474 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3475 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3477 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3479 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3480 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3484 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3486 /* Unless displaying a mode or menu bar line, which are always
3487 fully visible, clip to the visible part of the row. */
3488 if (s
->w
->pseudo_window_p
)
3489 r_height
= s
->row
->visible_height
;
3491 r_height
= s
->height
;
3495 /* This is a text line that may be partially visible. */
3496 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3497 r_width
= window_box_width (s
->w
, s
->area
);
3498 r_height
= s
->row
->visible_height
;
3501 /* If S draws overlapping rows, it's sufficient to use the top and
3502 bottom of the window for clipping because this glyph string
3503 intentionally draws over other lines. */
3504 if (s
->for_overlaps_p
)
3506 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3507 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3511 /* Don't use S->y for clipping because it doesn't take partially
3512 visible lines into account. For example, it can be negative for
3513 partially visible lines at the top of a window. */
3514 if (!s
->row
->full_width_p
3515 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3516 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3518 r
->top
= max (0, s
->row
->y
);
3520 /* If drawing a tool-bar window, draw it over the internal border
3521 at the top of the window. */
3522 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3523 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3526 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3528 r
->bottom
= r
->top
+ r_height
;
3529 r
->right
= r
->left
+ r_width
;
3533 /* Set clipping for output of glyph string S. S may be part of a mode
3534 line or menu if we don't have X toolkit support. */
3537 x_set_glyph_string_clipping (s
)
3538 struct glyph_string
*s
;
3541 x_get_glyph_string_clip_rect (s
, &r
);
3542 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3546 /* Compute left and right overhang of glyph string S. If S is a glyph
3547 string for a composition, assume overhangs don't exist. */
3550 x_compute_glyph_string_overhangs (s
)
3551 struct glyph_string
*s
;
3554 && s
->first_glyph
->type
== CHAR_GLYPH
)
3557 int direction
, font_ascent
, font_descent
;
3558 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3559 &font_ascent
, &font_descent
, &cs
);
3560 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3561 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3566 /* Compute overhangs and x-positions for glyph string S and its
3567 predecessors, or successors. X is the starting x-position for S.
3568 BACKWARD_P non-zero means process predecessors. */
3571 x_compute_overhangs_and_x (s
, x
, backward_p
)
3572 struct glyph_string
*s
;
3580 x_compute_glyph_string_overhangs (s
);
3590 x_compute_glyph_string_overhangs (s
);
3599 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3600 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3601 assumed to be zero. */
3604 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3605 struct glyph
*glyph
;
3611 if (glyph
->type
== CHAR_GLYPH
)
3615 struct font_info
*font_info
;
3619 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3621 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3623 && (pcm
= x_per_char_metric (font
, &char2b
)))
3625 if (pcm
->rbearing
> pcm
->width
)
3626 *right
= pcm
->rbearing
- pcm
->width
;
3627 if (pcm
->lbearing
< 0)
3628 *left
= -pcm
->lbearing
;
3634 /* Return the index of the first glyph preceding glyph string S that
3635 is overwritten by S because of S's left overhang. Value is -1
3636 if no glyphs are overwritten. */
3639 x_left_overwritten (s
)
3640 struct glyph_string
*s
;
3644 if (s
->left_overhang
)
3647 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3648 int first
= s
->first_glyph
- glyphs
;
3650 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3651 x
-= glyphs
[i
].pixel_width
;
3662 /* Return the index of the first glyph preceding glyph string S that
3663 is overwriting S because of its right overhang. Value is -1 if no
3664 glyph in front of S overwrites S. */
3667 x_left_overwriting (s
)
3668 struct glyph_string
*s
;
3671 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3672 int first
= s
->first_glyph
- glyphs
;
3676 for (i
= first
- 1; i
>= 0; --i
)
3679 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3682 x
-= glyphs
[i
].pixel_width
;
3689 /* Return the index of the last glyph following glyph string S that is
3690 not overwritten by S because of S's right overhang. Value is -1 if
3691 no such glyph is found. */
3694 x_right_overwritten (s
)
3695 struct glyph_string
*s
;
3699 if (s
->right_overhang
)
3702 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3703 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3704 int end
= s
->row
->used
[s
->area
];
3706 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3707 x
+= glyphs
[i
].pixel_width
;
3716 /* Return the index of the last glyph following glyph string S that
3717 overwrites S because of its left overhang. Value is negative
3718 if no such glyph is found. */
3721 x_right_overwriting (s
)
3722 struct glyph_string
*s
;
3725 int end
= s
->row
->used
[s
->area
];
3726 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3727 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3731 for (i
= first
; i
< end
; ++i
)
3734 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3737 x
+= glyphs
[i
].pixel_width
;
3744 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3747 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3748 struct glyph_string
*s
;
3753 xgcv
.foreground
= s
->gc
->background
;
3754 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3758 /* Draw the background of glyph_string S. If S->background_filled_p
3759 is non-zero don't draw it. FORCE_P non-zero means draw the
3760 background even if it wouldn't be drawn normally. This is used
3761 when a string preceding S draws into the background of S, or S
3762 contains the first component of a composition. */
3765 x_draw_glyph_string_background (s
, force_p
)
3766 struct glyph_string
*s
;
3769 /* Nothing to do if background has already been drawn or if it
3770 shouldn't be drawn in the first place. */
3771 if (!s
->background_filled_p
)
3773 int box_line_width
= max (s
->face
->box_line_width
, 0);
3775 #if 0 /* MAC_TODO: stipple */
3778 /* Fill background with a stipple pattern. */
3779 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3780 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3781 s
->y
+ box_line_width
,
3782 s
->background_width
,
3783 s
->height
- 2 * box_line_width
);
3784 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3785 s
->background_filled_p
= 1;
3789 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3790 || s
->font_not_found_p
3791 || s
->extends_to_end_of_line_p
3794 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3795 s
->background_width
,
3796 s
->height
- 2 * box_line_width
);
3797 s
->background_filled_p
= 1;
3803 /* Draw the foreground of glyph string S. */
3806 x_draw_glyph_string_foreground (s
)
3807 struct glyph_string
*s
;
3811 /* If first glyph of S has a left box line, start drawing the text
3812 of S to the right of that box line. */
3813 if (s
->face
->box
!= FACE_NO_BOX
3814 && s
->first_glyph
->left_box_line_p
)
3815 x
= s
->x
+ abs (s
->face
->box_line_width
);
3819 /* Draw characters of S as rectangles if S's font could not be
3821 if (s
->font_not_found_p
)
3823 for (i
= 0; i
< s
->nchars
; ++i
)
3825 struct glyph
*g
= s
->first_glyph
+ i
;
3826 mac_draw_rectangle (s
->display
, s
->window
,
3827 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3829 x
+= g
->pixel_width
;
3834 char *char1b
= (char *) s
->char2b
;
3835 int boff
= s
->font_info
->baseline_offset
;
3837 if (s
->font_info
->vertical_centering
)
3838 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3840 /* If we can use 8-bit functions, condense S->char2b. */
3842 for (i
= 0; i
< s
->nchars
; ++i
)
3843 char1b
[i
] = s
->char2b
[i
].byte2
;
3845 /* Draw text with XDrawString if background has already been
3846 filled. Otherwise, use XDrawImageString. (Note that
3847 XDrawImageString is usually faster than XDrawString.) Always
3848 use XDrawImageString when drawing the cursor so that there is
3849 no chance that characters under a box cursor are invisible. */
3850 if (s
->for_overlaps_p
3851 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3853 /* Draw characters with 16-bit or 8-bit functions. */
3855 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3856 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3858 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3859 s
->ybase
- boff
, char1b
, s
->nchars
);
3864 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3865 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3867 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3868 s
->ybase
- boff
, char1b
, s
->nchars
);
3873 /* Draw the foreground of composite glyph string S. */
3876 x_draw_composite_glyph_string_foreground (s
)
3877 struct glyph_string
*s
;
3881 /* If first glyph of S has a left box line, start drawing the text
3882 of S to the right of that box line. */
3883 if (s
->face
->box
!= FACE_NO_BOX
3884 && s
->first_glyph
->left_box_line_p
)
3885 x
= s
->x
+ abs (s
->face
->box_line_width
);
3889 /* S is a glyph string for a composition. S->gidx is the index of
3890 the first character drawn for glyphs of this composition.
3891 S->gidx == 0 means we are drawing the very first character of
3892 this composition. */
3894 /* Draw a rectangle for the composition if the font for the very
3895 first character of the composition could not be loaded. */
3896 if (s
->font_not_found_p
)
3899 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3900 s
->width
- 1, s
->height
- 1);
3904 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3905 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3906 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3907 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3913 #ifdef USE_X_TOOLKIT
3915 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3918 /* Return the frame on which widget WIDGET is used.. Abort if frame
3919 cannot be determined. */
3921 static struct frame
*
3922 x_frame_of_widget (widget
)
3925 struct x_display_info
*dpyinfo
;
3929 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3931 /* Find the top-level shell of the widget. Note that this function
3932 can be called when the widget is not yet realized, so XtWindow
3933 (widget) == 0. That's the reason we can't simply use
3934 x_any_window_to_frame. */
3935 while (!XtIsTopLevelShell (widget
))
3936 widget
= XtParent (widget
);
3938 /* Look for a frame with that top-level widget. Allocate the color
3939 on that frame to get the right gamma correction value. */
3940 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3941 if (GC_FRAMEP (XCAR (tail
))
3942 && (f
= XFRAME (XCAR (tail
)),
3943 (f
->output_data
.nothing
!= 1
3944 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3945 && f
->output_data
.x
->widget
== widget
)
3952 /* Allocate the color COLOR->pixel on the screen and display of
3953 widget WIDGET in colormap CMAP. If an exact match cannot be
3954 allocated, try the nearest color available. Value is non-zero
3955 if successful. This is called from lwlib. */
3958 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3963 struct frame
*f
= x_frame_of_widget (widget
);
3964 return x_alloc_nearest_color (f
, cmap
, color
);
3968 #endif /* USE_X_TOOLKIT */
3970 #if 0 /* MAC_TODO */
3972 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3973 CMAP. If an exact match can't be allocated, try the nearest color
3974 available. Value is non-zero if successful. Set *COLOR to the
3978 x_alloc_nearest_color (f
, cmap
, color
)
3983 Display
*display
= FRAME_X_DISPLAY (f
);
3984 Screen
*screen
= FRAME_X_SCREEN (f
);
3987 gamma_correct (f
, color
);
3988 rc
= XAllocColor (display
, cmap
, color
);
3991 /* If we got to this point, the colormap is full, so we're going
3992 to try to get the next closest color. The algorithm used is
3993 a least-squares matching, which is what X uses for closest
3994 color matching with StaticColor visuals. */
3996 unsigned long nearest_delta
= ~0;
3997 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3998 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
4000 for (i
= 0; i
< ncells
; ++i
)
4002 XQueryColors (display
, cmap
, cells
, ncells
);
4004 for (nearest
= i
= 0; i
< ncells
; ++i
)
4006 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
4007 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
4008 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
4009 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
4011 if (delta
< nearest_delta
)
4014 nearest_delta
= delta
;
4018 color
->red
= cells
[nearest
].red
;
4019 color
->green
= cells
[nearest
].green
;
4020 color
->blue
= cells
[nearest
].blue
;
4021 rc
= XAllocColor (display
, cmap
, color
);
4024 #ifdef DEBUG_X_COLORS
4026 register_color (color
->pixel
);
4027 #endif /* DEBUG_X_COLORS */
4033 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
4034 It's necessary to do this instead of just using PIXEL directly to
4035 get color reference counts right. */
4038 x_copy_color (f
, pixel
)
4040 unsigned long pixel
;
4044 color
.pixel
= pixel
;
4046 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4047 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4049 #ifdef DEBUG_X_COLORS
4050 register_color (pixel
);
4056 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
4057 It's necessary to do this instead of just using PIXEL directly to
4058 get color reference counts right. */
4061 x_copy_dpy_color (dpy
, cmap
, pixel
)
4064 unsigned long pixel
;
4068 color
.pixel
= pixel
;
4070 XQueryColor (dpy
, cmap
, &color
);
4071 XAllocColor (dpy
, cmap
, &color
);
4073 #ifdef DEBUG_X_COLORS
4074 register_color (pixel
);
4079 #endif /* MAC_TODO */
4081 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
4082 or DELTA. Try a color with RGB values multiplied by FACTOR first.
4083 If this produces the same color as COLOR, try a color where all RGB
4084 values have DELTA added. Return the allocated color in *COLOR.
4085 DISPLAY is the X display, CMAP is the colormap to operate on.
4086 Value is non-zero if successful. */
4089 mac_alloc_lighter_color (f
, color
, factor
, delta
)
4091 unsigned long *color
;
4097 /* Change RGB values by specified FACTOR. Avoid overflow! */
4098 xassert (factor
>= 0);
4099 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
4100 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
4101 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
4103 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
4104 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
4105 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
4107 /* MAC_TODO: Map to palette and retry with delta if same? */
4108 /* MAC_TODO: Free colors (if using palette)? */
4119 /* Set up the foreground color for drawing relief lines of glyph
4120 string S. RELIEF is a pointer to a struct relief containing the GC
4121 with which lines will be drawn. Use a color that is FACTOR or
4122 DELTA lighter or darker than the relief's background which is found
4123 in S->f->output_data.x->relief_background. If such a color cannot
4124 be allocated, use DEFAULT_PIXEL, instead. */
4127 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
4129 struct relief
*relief
;
4132 unsigned long default_pixel
;
4135 struct mac_output
*di
= f
->output_data
.mac
;
4136 unsigned long mask
= GCForeground
;
4137 unsigned long pixel
;
4138 unsigned long background
= di
->relief_background
;
4139 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4141 /* MAC_TODO: Free colors (if using palette)? */
4143 /* Allocate new color. */
4144 xgcv
.foreground
= default_pixel
;
4146 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
4148 relief
->allocated_p
= 1;
4149 xgcv
.foreground
= relief
->pixel
= pixel
;
4152 if (relief
->gc
== 0)
4154 #if 0 /* MAC_TODO: stipple */
4155 xgcv
.stipple
= dpyinfo
->gray
;
4158 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
4161 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
4165 /* Set up colors for the relief lines around glyph string S. */
4168 x_setup_relief_colors (s
)
4169 struct glyph_string
*s
;
4171 struct mac_output
*di
= s
->f
->output_data
.mac
;
4172 unsigned long color
;
4174 if (s
->face
->use_box_color_for_shadows_p
)
4175 color
= s
->face
->box_color
;
4180 /* Get the background color of the face. */
4181 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
4182 color
= xgcv
.background
;
4185 if (di
->white_relief
.gc
== 0
4186 || color
!= di
->relief_background
)
4188 di
->relief_background
= color
;
4189 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
4190 WHITE_PIX_DEFAULT (s
->f
));
4191 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4192 BLACK_PIX_DEFAULT (s
->f
));
4197 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4198 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4199 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4200 relief. LEFT_P non-zero means draw a relief on the left side of
4201 the rectangle. RIGHT_P non-zero means draw a relief on the right
4202 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4206 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4207 raised_p
, left_p
, right_p
, clip_rect
)
4209 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4216 gc
= f
->output_data
.mac
->white_relief
.gc
;
4218 gc
= f
->output_data
.mac
->black_relief
.gc
;
4219 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4222 for (i
= 0; i
< width
; ++i
)
4223 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4224 left_x
+ i
* left_p
, top_y
+ i
,
4225 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4229 for (i
= 0; i
< width
; ++i
)
4230 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4231 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4233 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4235 gc
= f
->output_data
.mac
->black_relief
.gc
;
4237 gc
= f
->output_data
.mac
->white_relief
.gc
;
4238 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4242 for (i
= 0; i
< width
; ++i
)
4243 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4244 left_x
+ i
* left_p
, bottom_y
- i
,
4245 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4249 for (i
= 0; i
< width
; ++i
)
4250 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4251 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4253 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4257 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4258 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4259 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4260 left side of the rectangle. RIGHT_P non-zero means draw a line
4261 on the right side of the rectangle. CLIP_RECT is the clipping
4262 rectangle to use when drawing. */
4265 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4266 left_p
, right_p
, clip_rect
)
4267 struct glyph_string
*s
;
4268 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4273 xgcv
.foreground
= s
->face
->box_color
;
4274 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4277 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4278 left_x
, top_y
, right_x
- left_x
, width
);
4282 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4283 left_x
, top_y
, width
, bottom_y
- top_y
);
4286 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4287 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4291 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4292 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4294 mac_reset_clipping (s
->display
, s
->window
);
4298 /* Draw a box around glyph string S. */
4301 x_draw_glyph_string_box (s
)
4302 struct glyph_string
*s
;
4304 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4305 int left_p
, right_p
;
4306 struct glyph
*last_glyph
;
4309 last_x
= window_box_right (s
->w
, s
->area
);
4310 if (s
->row
->full_width_p
4311 && !s
->w
->pseudo_window_p
)
4313 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4314 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4315 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4318 /* The glyph that may have a right box line. */
4319 last_glyph
= (s
->cmp
|| s
->img
4321 : s
->first_glyph
+ s
->nchars
- 1);
4323 width
= abs (s
->face
->box_line_width
);
4324 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4326 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4328 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4330 bottom_y
= top_y
+ s
->height
- 1;
4332 left_p
= (s
->first_glyph
->left_box_line_p
4333 || (s
->hl
== DRAW_MOUSE_FACE
4335 || s
->prev
->hl
!= s
->hl
)));
4336 right_p
= (last_glyph
->right_box_line_p
4337 || (s
->hl
== DRAW_MOUSE_FACE
4339 || s
->next
->hl
!= s
->hl
)));
4341 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4343 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4344 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4345 left_p
, right_p
, &clip_rect
);
4348 x_setup_relief_colors (s
);
4349 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4350 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4355 /* Draw foreground of image glyph string S. */
4358 x_draw_image_foreground (s
)
4359 struct glyph_string
*s
;
4362 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4364 /* If first glyph of S has a left box line, start drawing it to the
4365 right of that line. */
4366 if (s
->face
->box
!= FACE_NO_BOX
4367 && s
->first_glyph
->left_box_line_p
)
4368 x
= s
->x
+ abs (s
->face
->box_line_width
);
4372 /* If there is a margin around the image, adjust x- and y-position
4374 x
+= s
->img
->hmargin
;
4375 y
+= s
->img
->vmargin
;
4379 #if 0 /* MAC_TODO: image mask */
4382 /* We can't set both a clip mask and use XSetClipRectangles
4383 because the latter also sets a clip mask. We also can't
4384 trust on the shape extension to be available
4385 (XShapeCombineRegion). So, compute the rectangle to draw
4387 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4390 XRectangle clip_rect
, image_rect
, r
;
4392 xgcv
.clip_mask
= s
->img
->mask
;
4393 xgcv
.clip_x_origin
= x
;
4394 xgcv
.clip_y_origin
= y
;
4395 xgcv
.function
= GXcopy
;
4396 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4398 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4401 image_rect
.width
= s
->img
->width
;
4402 image_rect
.height
= s
->img
->height
;
4403 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4404 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4405 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4408 #endif /* MAC_TODO */
4410 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4411 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4413 /* When the image has a mask, we can expect that at
4414 least part of a mouse highlight or a block cursor will
4415 be visible. If the image doesn't have a mask, make
4416 a block cursor visible by drawing a rectangle around
4417 the image. I believe it's looking better if we do
4418 nothing here for mouse-face. */
4419 if (s
->hl
== DRAW_CURSOR
)
4421 int r
= s
->img
->relief
;
4423 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4424 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4429 /* Draw a rectangle if image could not be loaded. */
4430 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4431 s
->img
->width
- 1, s
->img
->height
- 1);
4436 /* Draw a relief around the image glyph string S. */
4439 x_draw_image_relief (s
)
4440 struct glyph_string
*s
;
4442 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4445 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4447 /* If first glyph of S has a left box line, start drawing it to the
4448 right of that line. */
4449 if (s
->face
->box
!= FACE_NO_BOX
4450 && s
->first_glyph
->left_box_line_p
)
4451 x
= s
->x
+ abs (s
->face
->box_line_width
);
4455 /* If there is a margin around the image, adjust x- and y-position
4457 x
+= s
->img
->hmargin
;
4458 y
+= s
->img
->vmargin
;
4460 if (s
->hl
== DRAW_IMAGE_SUNKEN
4461 || s
->hl
== DRAW_IMAGE_RAISED
)
4463 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4464 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4468 thick
= abs (s
->img
->relief
);
4469 raised_p
= s
->img
->relief
> 0;
4474 x1
= x
+ s
->img
->width
+ thick
- 1;
4475 y1
= y
+ s
->img
->height
+ thick
- 1;
4477 x_setup_relief_colors (s
);
4478 x_get_glyph_string_clip_rect (s
, &r
);
4479 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4483 /* Draw the foreground of image glyph string S to PIXMAP. */
4486 x_draw_image_foreground_1 (s
, pixmap
)
4487 struct glyph_string
*s
;
4491 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4493 /* If first glyph of S has a left box line, start drawing it to the
4494 right of that line. */
4495 if (s
->face
->box
!= FACE_NO_BOX
4496 && s
->first_glyph
->left_box_line_p
)
4497 x
= abs (s
->face
->box_line_width
);
4501 /* If there is a margin around the image, adjust x- and y-position
4503 x
+= s
->img
->hmargin
;
4504 y
+= s
->img
->vmargin
;
4508 #if 0 /* MAC_TODO: image mask */
4511 /* We can't set both a clip mask and use XSetClipRectangles
4512 because the latter also sets a clip mask. We also can't
4513 trust on the shape extension to be available
4514 (XShapeCombineRegion). So, compute the rectangle to draw
4516 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4520 xgcv
.clip_mask
= s
->img
->mask
;
4521 xgcv
.clip_x_origin
= x
;
4522 xgcv
.clip_y_origin
= y
;
4523 xgcv
.function
= GXcopy
;
4524 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4526 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4527 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4528 XSetClipMask (s
->display
, s
->gc
, None
);
4531 #endif /* MAC_TODO */
4533 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4534 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4536 /* When the image has a mask, we can expect that at
4537 least part of a mouse highlight or a block cursor will
4538 be visible. If the image doesn't have a mask, make
4539 a block cursor visible by drawing a rectangle around
4540 the image. I believe it's looking better if we do
4541 nothing here for mouse-face. */
4542 if (s
->hl
== DRAW_CURSOR
)
4544 int r
= s
->img
->relief
;
4546 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
4547 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4552 /* Draw a rectangle if image could not be loaded. */
4553 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4554 s
->img
->width
- 1, s
->img
->height
- 1);
4558 /* Draw part of the background of glyph string S. X, Y, W, and H
4559 give the rectangle to draw. */
4562 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4563 struct glyph_string
*s
;
4566 #if 0 /* MAC_TODO: stipple */
4569 /* Fill background with a stipple pattern. */
4570 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4571 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4572 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4575 #endif /* MAC_TODO */
4576 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4580 /* Draw image glyph string S.
4583 s->x +-------------------------
4586 | +-------------------------
4589 | | +-------------------
4595 x_draw_image_glyph_string (s
)
4596 struct glyph_string
*s
;
4599 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4600 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4604 height
= s
->height
- 2 * box_line_vwidth
;
4606 /* Fill background with face under the image. Do it only if row is
4607 taller than image or if image has a clip mask to reduce
4609 s
->stippled_p
= s
->face
->stipple
!= 0;
4610 if (height
> s
->img
->height
4613 #if 0 /* TODO: image mask */
4616 || s
->img
->pixmap
== 0
4617 || s
->width
!= s
->background_width
)
4619 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4620 x
= s
->x
+ box_line_hwidth
;
4624 y
= s
->y
+ box_line_vwidth
;
4625 #if 0 /* TODO: image mask */
4628 /* Create a pixmap as large as the glyph string. Fill it
4629 with the background color. Copy the image to it, using
4630 its mask. Copy the temporary pixmap to the display. */
4631 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4632 int depth
= DefaultDepthOfScreen (screen
);
4634 /* Create a pixmap as large as the glyph string. */
4635 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4636 s
->background_width
,
4639 /* Don't clip in the following because we're working on the
4641 XSetClipMask (s
->display
, s
->gc
, None
);
4643 /* Fill the pixmap with the background color/stipple. */
4646 /* Fill background with a stipple pattern. */
4647 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4648 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4649 0, 0, s
->background_width
, s
->height
);
4650 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4655 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4657 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4658 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4659 0, 0, s
->background_width
, s
->height
);
4660 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4665 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4667 s
->background_filled_p
= 1;
4670 /* Draw the foreground. */
4673 x_draw_image_foreground_1 (s
, pixmap
);
4674 x_set_glyph_string_clipping (s
);
4675 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4676 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4677 mac_reset_clipping (s
->display
, s
->window
);
4678 XFreePixmap (s
->display
, pixmap
);
4681 x_draw_image_foreground (s
);
4683 /* If we must draw a relief around the image, do it. */
4685 || s
->hl
== DRAW_IMAGE_RAISED
4686 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4687 x_draw_image_relief (s
);
4691 /* Draw stretch glyph string S. */
4694 x_draw_stretch_glyph_string (s
)
4695 struct glyph_string
*s
;
4697 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4698 s
->stippled_p
= s
->face
->stipple
!= 0;
4700 if (s
->hl
== DRAW_CURSOR
4701 && !x_stretch_cursor_p
)
4703 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4704 as wide as the stretch glyph. */
4705 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4708 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4710 /* Clear rest using the GC of the original non-cursor face. */
4711 if (width
< s
->background_width
)
4713 GC gc
= s
->face
->gc
;
4714 int x
= s
->x
+ width
, y
= s
->y
;
4715 int w
= s
->background_width
- width
, h
= s
->height
;
4718 if (s
->row
->mouse_face_p
4719 && cursor_in_mouse_face_p (s
->w
))
4721 x_set_mouse_face_gc (s
);
4727 x_get_glyph_string_clip_rect (s
, &r
);
4728 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4730 #if 0 /* MAC_TODO: stipple */
4731 if (s
->face
->stipple
)
4733 /* Fill background with a stipple pattern. */
4734 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4735 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4736 XSetFillStyle (s
->display
, gc
, FillSolid
);
4739 #endif /* MAC_TODO */
4742 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4743 XSetForeground (s
->display
, gc
, xgcv
.background
);
4744 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4745 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4748 mac_reset_clipping (s
->display
, s
->window
);
4751 else if (!s
->background_filled_p
)
4752 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4755 s
->background_filled_p
= 1;
4759 /* Draw glyph string S. */
4762 x_draw_glyph_string (s
)
4763 struct glyph_string
*s
;
4765 int relief_drawn_p
= 0;
4767 /* If S draws into the background of its successor, draw the
4768 background of the successor first so that S can draw into it.
4769 This makes S->next use XDrawString instead of XDrawImageString. */
4770 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4772 xassert (s
->next
->img
== NULL
);
4773 x_set_glyph_string_gc (s
->next
);
4774 x_set_glyph_string_clipping (s
->next
);
4775 x_draw_glyph_string_background (s
->next
, 1);
4779 /* Set up S->gc, set clipping and draw S. */
4780 x_set_glyph_string_gc (s
);
4782 /* Draw relief (if any) in advance for char/composition so that the
4783 glyph string can be drawn over it. */
4784 if (!s
->for_overlaps_p
4785 && s
->face
->box
!= FACE_NO_BOX
4786 && (s
->first_glyph
->type
== CHAR_GLYPH
4787 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4790 x_set_glyph_string_clipping (s
);
4791 x_draw_glyph_string_background (s
, 1);
4792 x_draw_glyph_string_box (s
);
4793 x_set_glyph_string_clipping (s
);
4797 x_set_glyph_string_clipping (s
);
4799 switch (s
->first_glyph
->type
)
4802 x_draw_image_glyph_string (s
);
4806 x_draw_stretch_glyph_string (s
);
4810 if (s
->for_overlaps_p
)
4811 s
->background_filled_p
= 1;
4813 x_draw_glyph_string_background (s
, 0);
4814 x_draw_glyph_string_foreground (s
);
4817 case COMPOSITE_GLYPH
:
4818 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4819 s
->background_filled_p
= 1;
4821 x_draw_glyph_string_background (s
, 1);
4822 x_draw_composite_glyph_string_foreground (s
);
4829 if (!s
->for_overlaps_p
)
4831 /* Draw underline. */
4832 if (s
->face
->underline_p
)
4834 unsigned long h
= 1;
4835 unsigned long dy
= s
->height
- h
;
4837 if (s
->face
->underline_defaulted_p
)
4838 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4843 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4844 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4845 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4847 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4851 /* Draw overline. */
4852 if (s
->face
->overline_p
)
4854 unsigned long dy
= 0, h
= 1;
4856 if (s
->face
->overline_color_defaulted_p
)
4857 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4862 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4863 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4864 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4866 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4870 /* Draw strike-through. */
4871 if (s
->face
->strike_through_p
)
4873 unsigned long h
= 1;
4874 unsigned long dy
= (s
->height
- h
) / 2;
4876 if (s
->face
->strike_through_color_defaulted_p
)
4877 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4882 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4883 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4884 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4886 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4891 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4892 x_draw_glyph_string_box (s
);
4895 /* Reset clipping. */
4896 mac_reset_clipping (s
->display
, s
->window
);
4900 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4901 struct face
**, int));
4904 /* Fill glyph string S with composition components specified by S->cmp.
4906 FACES is an array of faces for all components of this composition.
4907 S->gidx is the index of the first component for S.
4908 OVERLAPS_P non-zero means S should draw the foreground only, and
4909 use its physical height for clipping.
4911 Value is the index of a component not in S. */
4914 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4915 struct glyph_string
*s
;
4916 struct face
**faces
;
4923 s
->for_overlaps_p
= overlaps_p
;
4925 s
->face
= faces
[s
->gidx
];
4926 s
->font
= s
->face
->font
;
4927 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4929 /* For all glyphs of this composition, starting at the offset
4930 S->gidx, until we reach the end of the definition or encounter a
4931 glyph that requires the different face, add it to S. */
4933 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4936 /* All glyph strings for the same composition has the same width,
4937 i.e. the width set for the first component of the composition. */
4939 s
->width
= s
->first_glyph
->pixel_width
;
4941 /* If the specified font could not be loaded, use the frame's
4942 default font, but record the fact that we couldn't load it in
4943 the glyph string so that we can draw rectangles for the
4944 characters of the glyph string. */
4945 if (s
->font
== NULL
)
4947 s
->font_not_found_p
= 1;
4948 s
->font
= FRAME_FONT (s
->f
);
4951 /* Adjust base line for subscript/superscript text. */
4952 s
->ybase
+= s
->first_glyph
->voffset
;
4954 xassert (s
->face
&& s
->face
->gc
);
4956 /* This glyph string must always be drawn with 16-bit functions. */
4959 return s
->gidx
+ s
->nchars
;
4963 /* Fill glyph string S from a sequence of character glyphs.
4965 FACE_ID is the face id of the string. START is the index of the
4966 first glyph to consider, END is the index of the last + 1.
4967 OVERLAPS_P non-zero means S should draw the foreground only, and
4968 use its physical height for clipping.
4970 Value is the index of the first glyph not in S. */
4973 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4974 struct glyph_string
*s
;
4976 int start
, end
, overlaps_p
;
4978 struct glyph
*glyph
, *last
;
4980 int glyph_not_available_p
;
4982 xassert (s
->f
== XFRAME (s
->w
->frame
));
4983 xassert (s
->nchars
== 0);
4984 xassert (start
>= 0 && end
> start
);
4986 s
->for_overlaps_p
= overlaps_p
;
4987 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4988 last
= s
->row
->glyphs
[s
->area
] + end
;
4989 voffset
= glyph
->voffset
;
4991 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4994 && glyph
->type
== CHAR_GLYPH
4995 && glyph
->voffset
== voffset
4996 /* Same face id implies same font, nowadays. */
4997 && glyph
->face_id
== face_id
4998 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
5002 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
5003 s
->char2b
+ s
->nchars
,
5005 s
->two_byte_p
= two_byte_p
;
5007 xassert (s
->nchars
<= end
- start
);
5008 s
->width
+= glyph
->pixel_width
;
5012 s
->font
= s
->face
->font
;
5013 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5015 /* If the specified font could not be loaded, use the frame's font,
5016 but record the fact that we couldn't load it in
5017 S->font_not_found_p so that we can draw rectangles for the
5018 characters of the glyph string. */
5019 if (s
->font
== NULL
|| glyph_not_available_p
)
5021 s
->font_not_found_p
= 1;
5022 s
->font
= FRAME_FONT (s
->f
);
5025 /* Adjust base line for subscript/superscript text. */
5026 s
->ybase
+= voffset
;
5028 xassert (s
->face
&& s
->face
->gc
);
5029 return glyph
- s
->row
->glyphs
[s
->area
];
5033 /* Fill glyph string S from image glyph S->first_glyph. */
5036 x_fill_image_glyph_string (s
)
5037 struct glyph_string
*s
;
5039 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
5040 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
5042 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
5043 s
->font
= s
->face
->font
;
5044 s
->width
= s
->first_glyph
->pixel_width
;
5046 /* Adjust base line for subscript/superscript text. */
5047 s
->ybase
+= s
->first_glyph
->voffset
;
5051 /* Fill glyph string S from a sequence of stretch glyphs.
5053 ROW is the glyph row in which the glyphs are found, AREA is the
5054 area within the row. START is the index of the first glyph to
5055 consider, END is the index of the last + 1.
5057 Value is the index of the first glyph not in S. */
5060 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
5061 struct glyph_string
*s
;
5062 struct glyph_row
*row
;
5063 enum glyph_row_area area
;
5066 struct glyph
*glyph
, *last
;
5067 int voffset
, face_id
;
5069 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
5071 glyph
= s
->row
->glyphs
[s
->area
] + start
;
5072 last
= s
->row
->glyphs
[s
->area
] + end
;
5073 face_id
= glyph
->face_id
;
5074 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
5075 s
->font
= s
->face
->font
;
5076 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5077 s
->width
= glyph
->pixel_width
;
5078 voffset
= glyph
->voffset
;
5082 && glyph
->type
== STRETCH_GLYPH
5083 && glyph
->voffset
== voffset
5084 && glyph
->face_id
== face_id
);
5086 s
->width
+= glyph
->pixel_width
;
5088 /* Adjust base line for subscript/superscript text. */
5089 s
->ybase
+= voffset
;
5092 return glyph
- s
->row
->glyphs
[s
->area
];
5096 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
5097 of XChar2b structures for S; it can't be allocated in
5098 x_init_glyph_string because it must be allocated via `alloca'. W
5099 is the window on which S is drawn. ROW and AREA are the glyph row
5100 and area within the row from which S is constructed. START is the
5101 index of the first glyph structure covered by S. HL is a
5102 face-override for drawing S. */
5105 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
5106 struct glyph_string
*s
;
5109 struct glyph_row
*row
;
5110 enum glyph_row_area area
;
5112 enum draw_glyphs_face hl
;
5114 bzero (s
, sizeof *s
);
5116 s
->f
= XFRAME (w
->frame
);
5117 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
5118 s
->window
= FRAME_MAC_WINDOW (s
->f
);
5123 s
->first_glyph
= row
->glyphs
[area
] + start
;
5124 s
->height
= row
->height
;
5125 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5127 /* Display the internal border below the tool-bar window. */
5128 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
5129 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
5131 s
->ybase
= s
->y
+ row
->ascent
;
5135 /* Set background width of glyph string S. START is the index of the
5136 first glyph following S. LAST_X is the right-most x-position + 1
5137 in the drawing area. */
5140 x_set_glyph_string_background_width (s
, start
, last_x
)
5141 struct glyph_string
*s
;
5145 /* If the face of this glyph string has to be drawn to the end of
5146 the drawing area, set S->extends_to_end_of_line_p. */
5147 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
5149 if (start
== s
->row
->used
[s
->area
]
5150 && s
->area
== TEXT_AREA
5151 && ((s
->hl
== DRAW_NORMAL_TEXT
5152 && (s
->row
->fill_line_p
5153 || s
->face
->background
!= default_face
->background
5154 || s
->face
->stipple
!= default_face
->stipple
5155 || s
->row
->mouse_face_p
))
5156 || s
->hl
== DRAW_MOUSE_FACE
5157 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
5158 && s
->row
->fill_line_p
)))
5159 s
->extends_to_end_of_line_p
= 1;
5161 /* If S extends its face to the end of the line, set its
5162 background_width to the distance to the right edge of the drawing
5164 if (s
->extends_to_end_of_line_p
)
5165 s
->background_width
= last_x
- s
->x
+ 1;
5167 s
->background_width
= s
->width
;
5171 /* Add a glyph string for a stretch glyph to the list of strings
5172 between HEAD and TAIL. START is the index of the stretch glyph in
5173 row area AREA of glyph row ROW. END is the index of the last glyph
5174 in that glyph row area. X is the current output position assigned
5175 to the new glyph string constructed. HL overrides that face of the
5176 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5177 is the right-most x-position of the drawing area. */
5179 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
5180 and below -- keep them on one line. */
5181 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5184 s = (struct glyph_string *) alloca (sizeof *s); \
5185 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5186 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
5187 x_append_glyph_string (&HEAD, &TAIL, s); \
5193 /* Add a glyph string for an image glyph to the list of strings
5194 between HEAD and TAIL. START is the index of the image glyph in
5195 row area AREA of glyph row ROW. END is the index of the last glyph
5196 in that glyph row area. X is the current output position assigned
5197 to the new glyph string constructed. HL overrides that face of the
5198 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5199 is the right-most x-position of the drawing area. */
5201 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5204 s = (struct glyph_string *) alloca (sizeof *s); \
5205 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5206 x_fill_image_glyph_string (s); \
5207 x_append_glyph_string (&HEAD, &TAIL, s); \
5214 /* Add a glyph string for a sequence of character glyphs to the list
5215 of strings between HEAD and TAIL. START is the index of the first
5216 glyph in row area AREA of glyph row ROW that is part of the new
5217 glyph string. END is the index of the last glyph in that glyph row
5218 area. X is the current output position assigned to the new glyph
5219 string constructed. HL overrides that face of the glyph; e.g. it
5220 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
5221 right-most x-position of the drawing area. */
5223 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5229 c = (ROW)->glyphs[AREA][START].u.ch; \
5230 face_id = (ROW)->glyphs[AREA][START].face_id; \
5232 s = (struct glyph_string *) alloca (sizeof *s); \
5233 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5234 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5235 x_append_glyph_string (&HEAD, &TAIL, s); \
5237 START = x_fill_glyph_string (s, face_id, START, END, \
5243 /* Add a glyph string for a composite sequence to the list of strings
5244 between HEAD and TAIL. START is the index of the first glyph in
5245 row area AREA of glyph row ROW that is part of the new glyph
5246 string. END is the index of the last glyph in that glyph row area.
5247 X is the current output position assigned to the new glyph string
5248 constructed. HL overrides that face of the glyph; e.g. it is
5249 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5250 x-position of the drawing area. */
5252 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5254 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5255 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5256 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5257 struct composition *cmp = composition_table[cmp_id]; \
5258 int glyph_len = cmp->glyph_len; \
5260 struct face **faces; \
5261 struct glyph_string *first_s = NULL; \
5264 base_face = base_face->ascii_face; \
5265 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5266 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5267 /* At first, fill in `char2b' and `faces'. */ \
5268 for (n = 0; n < glyph_len; n++) \
5270 int c = COMPOSITION_GLYPH (cmp, n); \
5271 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5272 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5273 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5274 this_face_id, char2b + n, 1); \
5277 /* Make glyph_strings for each glyph sequence that is drawable by \
5278 the same face, and append them to HEAD/TAIL. */ \
5279 for (n = 0; n < cmp->glyph_len;) \
5281 s = (struct glyph_string *) alloca (sizeof *s); \
5282 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5283 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5291 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5299 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5300 of AREA of glyph row ROW on window W between indices START and END.
5301 HL overrides the face for drawing glyph strings, e.g. it is
5302 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5303 x-positions of the drawing area.
5305 This is an ugly monster macro construct because we must use alloca
5306 to allocate glyph strings (because x_draw_glyphs can be called
5309 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5312 HEAD = TAIL = NULL; \
5313 while (START < END) \
5315 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5316 switch (first_glyph->type) \
5319 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5320 TAIL, HL, X, LAST_X, \
5324 case COMPOSITE_GLYPH: \
5325 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5326 HEAD, TAIL, HL, X, LAST_X,\
5330 case STRETCH_GLYPH: \
5331 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5332 HEAD, TAIL, HL, X, LAST_X); \
5336 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5337 TAIL, HL, X, LAST_X); \
5344 x_set_glyph_string_background_width (s, START, LAST_X); \
5351 /* Draw glyphs between START and END in AREA of ROW on window W,
5352 starting at x-position X. X is relative to AREA in W. HL is a
5353 face-override with the following meaning:
5355 DRAW_NORMAL_TEXT draw normally
5356 DRAW_CURSOR draw in cursor face
5357 DRAW_MOUSE_FACE draw in mouse face.
5358 DRAW_INVERSE_VIDEO draw in mode line face
5359 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5360 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5362 If OVERLAPS_P is non-zero, draw only the foreground of characters
5363 and clip to the physical height of ROW.
5365 Value is the x-position reached, relative to AREA of W. */
5368 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5371 struct glyph_row
*row
;
5372 enum glyph_row_area area
;
5374 enum draw_glyphs_face hl
;
5377 struct glyph_string
*head
, *tail
;
5378 struct glyph_string
*s
;
5379 int last_x
, area_width
;
5383 /* Let's rather be paranoid than getting a SEGV. */
5384 end
= min (end
, row
->used
[area
]);
5385 start
= max (0, start
);
5386 start
= min (end
, start
);
5388 /* Translate X to frame coordinates. Set last_x to the right
5389 end of the drawing area. */
5390 if (row
->full_width_p
)
5392 /* X is relative to the left edge of W, without scroll bars
5394 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5395 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5398 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5399 last_x
= window_left_x
+ area_width
;
5401 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5403 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5404 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5410 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5411 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5415 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5416 area_width
= window_box_width (w
, area
);
5417 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5420 /* Build a doubly-linked list of glyph_string structures between
5421 head and tail from what we have to draw. Note that the macro
5422 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5423 the reason we use a separate variable `i'. */
5425 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5428 x_reached
= tail
->x
+ tail
->background_width
;
5432 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5433 the row, redraw some glyphs in front or following the glyph
5434 strings built above. */
5435 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5438 struct glyph_string
*h
, *t
;
5440 /* Compute overhangs for all glyph strings. */
5441 for (s
= head
; s
; s
= s
->next
)
5442 x_compute_glyph_string_overhangs (s
);
5444 /* Prepend glyph strings for glyphs in front of the first glyph
5445 string that are overwritten because of the first glyph
5446 string's left overhang. The background of all strings
5447 prepended must be drawn because the first glyph string
5449 i
= x_left_overwritten (head
);
5453 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5454 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5457 x_compute_overhangs_and_x (t
, head
->x
, 1);
5458 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5461 /* Prepend glyph strings for glyphs in front of the first glyph
5462 string that overwrite that glyph string because of their
5463 right overhang. For these strings, only the foreground must
5464 be drawn, because it draws over the glyph string at `head'.
5465 The background must not be drawn because this would overwrite
5466 right overhangs of preceding glyphs for which no glyph
5468 i
= x_left_overwriting (head
);
5471 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5472 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5474 for (s
= h
; s
; s
= s
->next
)
5475 s
->background_filled_p
= 1;
5476 x_compute_overhangs_and_x (t
, head
->x
, 1);
5477 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5480 /* Append glyphs strings for glyphs following the last glyph
5481 string tail that are overwritten by tail. The background of
5482 these strings has to be drawn because tail's foreground draws
5484 i
= x_right_overwritten (tail
);
5487 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5488 DRAW_NORMAL_TEXT
, x
, last_x
,
5490 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5491 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5494 /* Append glyph strings for glyphs following the last glyph
5495 string tail that overwrite tail. The foreground of such
5496 glyphs has to be drawn because it writes into the background
5497 of tail. The background must not be drawn because it could
5498 paint over the foreground of following glyphs. */
5499 i
= x_right_overwriting (tail
);
5502 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5503 DRAW_NORMAL_TEXT
, x
, last_x
,
5505 for (s
= h
; s
; s
= s
->next
)
5506 s
->background_filled_p
= 1;
5507 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5508 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5512 /* Draw all strings. */
5513 for (s
= head
; s
; s
= s
->next
)
5514 x_draw_glyph_string (s
);
5516 if (area
== TEXT_AREA
5517 && !row
->full_width_p
5518 /* When drawing overlapping rows, only the glyph strings'
5519 foreground is drawn, which doesn't erase a cursor
5523 int x0
= head
? head
->x
: x
;
5524 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5526 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5527 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5529 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5531 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5532 x0
-= left_area_width
;
5533 x1
-= left_area_width
;
5536 notice_overwritten_cursor (w
, area
, x0
, x1
,
5537 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5540 /* Value is the x-position up to which drawn, relative to AREA of W.
5541 This doesn't include parts drawn because of overhangs. */
5542 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5543 if (!row
->full_width_p
)
5545 if (area
> LEFT_MARGIN_AREA
)
5546 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5547 if (area
> TEXT_AREA
)
5548 x_reached
-= window_box_width (w
, TEXT_AREA
);
5555 /* Fix the display of area AREA of overlapping row ROW in window W. */
5558 x_fix_overlapping_area (w
, row
, area
)
5560 struct glyph_row
*row
;
5561 enum glyph_row_area area
;
5567 if (area
== LEFT_MARGIN_AREA
)
5569 else if (area
== TEXT_AREA
)
5570 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5572 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5573 + window_box_width (w
, TEXT_AREA
));
5575 for (i
= 0; i
< row
->used
[area
];)
5577 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5579 int start
= i
, start_x
= x
;
5583 x
+= row
->glyphs
[area
][i
].pixel_width
;
5586 while (i
< row
->used
[area
]
5587 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5589 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5590 DRAW_NORMAL_TEXT
, 1);
5594 x
+= row
->glyphs
[area
][i
].pixel_width
;
5603 /* Output LEN glyphs starting at START at the nominal cursor position.
5604 Advance the nominal cursor over the text. The global variable
5605 updated_window contains the window being updated, updated_row is
5606 the glyph row being updated, and updated_area is the area of that
5607 row being updated. */
5610 x_write_glyphs (start
, len
)
5611 struct glyph
*start
;
5616 xassert (updated_window
&& updated_row
);
5621 hpos
= start
- updated_row
->glyphs
[updated_area
];
5622 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5623 updated_row
, updated_area
,
5625 DRAW_NORMAL_TEXT
, 0);
5629 /* Advance the output cursor. */
5630 output_cursor
.hpos
+= len
;
5631 output_cursor
.x
= x
;
5635 /* Insert LEN glyphs from START at the nominal cursor position. */
5638 x_insert_glyphs (start
, len
)
5639 struct glyph
*start
;
5644 int line_height
, shift_by_width
, shifted_region_width
;
5645 struct glyph_row
*row
;
5646 struct glyph
*glyph
;
5647 int frame_x
, frame_y
, hpos
;
5649 xassert (updated_window
&& updated_row
);
5652 f
= XFRAME (WINDOW_FRAME (w
));
5654 /* Get the height of the line we are in. */
5656 line_height
= row
->height
;
5658 /* Get the width of the glyphs to insert. */
5660 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5661 shift_by_width
+= glyph
->pixel_width
;
5663 /* Get the width of the region to shift right. */
5664 shifted_region_width
= (window_box_width (w
, updated_area
)
5669 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5670 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5672 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5673 f
->output_data
.mac
->normal_gc
,
5675 shifted_region_width
, line_height
,
5676 frame_x
+ shift_by_width
, frame_y
);
5678 /* Write the glyphs. */
5679 hpos
= start
- row
->glyphs
[updated_area
];
5680 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5681 DRAW_NORMAL_TEXT
, 0);
5683 /* Advance the output cursor. */
5684 output_cursor
.hpos
+= len
;
5685 output_cursor
.x
+= shift_by_width
;
5690 /* Delete N glyphs at the nominal cursor position. Not implemented
5701 /* Erase the current text line from the nominal cursor position
5702 (inclusive) to pixel column TO_X (exclusive). The idea is that
5703 everything from TO_X onward is already erased.
5705 TO_X is a pixel position relative to updated_area of
5706 updated_window. TO_X == -1 means clear to the end of this area. */
5709 x_clear_end_of_line (to_x
)
5713 struct window
*w
= updated_window
;
5714 int max_x
, min_y
, max_y
;
5715 int from_x
, from_y
, to_y
;
5717 xassert (updated_window
&& updated_row
);
5718 f
= XFRAME (w
->frame
);
5720 if (updated_row
->full_width_p
)
5722 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5723 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5724 && !w
->pseudo_window_p
)
5725 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5728 max_x
= window_box_width (w
, updated_area
);
5729 max_y
= window_text_bottom_y (w
);
5731 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5732 of window. For TO_X > 0, truncate to end of drawing area. */
5738 to_x
= min (to_x
, max_x
);
5740 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5742 /* Notice if the cursor will be cleared by this operation. */
5743 if (!updated_row
->full_width_p
)
5744 notice_overwritten_cursor (w
, updated_area
,
5745 output_cursor
.x
, -1,
5747 MATRIX_ROW_BOTTOM_Y (updated_row
));
5749 from_x
= output_cursor
.x
;
5751 /* Translate to frame coordinates. */
5752 if (updated_row
->full_width_p
)
5754 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5755 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5759 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5760 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5763 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5764 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5765 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5767 /* Prevent inadvertently clearing to end of the X window. */
5768 if (to_x
> from_x
&& to_y
> from_y
)
5771 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5772 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5779 /* Clear entire frame. If updating_frame is non-null, clear that
5780 frame. Otherwise clear the selected frame. */
5790 f
= SELECTED_FRAME ();
5792 /* Clearing the frame will erase any cursor, so mark them all as no
5794 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5795 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5796 output_cursor
.x
= -1;
5798 /* We don't set the output cursor here because there will always
5799 follow an explicit cursor_to. */
5801 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5803 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5804 /* We have to clear the scroll bars, too. If we have changed
5805 colors or something like that, then they should be notified. */
5806 x_scroll_bar_clear (f
);
5809 XFlush (FRAME_MAC_DISPLAY (f
));
5815 /* Invert the middle quarter of the frame for .15 sec. */
5817 /* We use the select system call to do the waiting, so we have to make
5818 sure it's available. If it isn't, we just won't do visual bells. */
5820 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5822 /* Subtract the `struct timeval' values X and Y, storing the result in
5823 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5826 timeval_subtract (result
, x
, y
)
5827 struct timeval
*result
, x
, y
;
5829 /* Perform the carry for the later subtraction by updating y. This
5830 is safer because on some systems the tv_sec member is unsigned. */
5831 if (x
.tv_usec
< y
.tv_usec
)
5833 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5834 y
.tv_usec
-= 1000000 * nsec
;
5838 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5840 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5841 y
.tv_usec
+= 1000000 * nsec
;
5845 /* Compute the time remaining to wait. tv_usec is certainly
5847 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5848 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5850 /* Return indication of whether the result should be considered
5852 return x
.tv_sec
< y
.tv_sec
;
5864 struct timeval wakeup
;
5866 EMACS_GET_TIME (wakeup
);
5868 /* Compute time to wait until, propagating carry from usecs. */
5869 wakeup
.tv_usec
+= 150000;
5870 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5871 wakeup
.tv_usec
%= 1000000;
5873 /* Keep waiting until past the time wakeup. */
5876 struct timeval timeout
;
5878 EMACS_GET_TIME (timeout
);
5880 /* In effect, timeout = wakeup - timeout.
5881 Break if result would be negative. */
5882 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5885 /* Try to wait that long--but we might wake up sooner. */
5886 select (0, NULL
, NULL
, NULL
, &timeout
);
5895 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5898 /* Make audible bell. */
5903 struct frame
*f
= SELECTED_FRAME ();
5905 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5913 XFlush (FRAME_MAC_DISPLAY (f
));
5920 /* Specify how many text lines, from the top of the window,
5921 should be affected by insert-lines and delete-lines operations.
5922 This, and those operations, are used only within an update
5923 that is bounded by calls to x_update_begin and x_update_end. */
5926 XTset_terminal_window (n
)
5929 /* This function intentionally left blank. */
5934 /***********************************************************************
5936 ***********************************************************************/
5938 /* Perform an insert-lines or delete-lines operation, inserting N
5939 lines or deleting -N lines at vertical position VPOS. */
5942 x_ins_del_lines (vpos
, n
)
5949 /* Scroll part of the display as described by RUN. */
5952 x_scroll_run (w
, run
)
5956 struct frame
*f
= XFRAME (w
->frame
);
5957 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5959 /* Get frame-relative bounding box of the text display area of W,
5960 without mode lines. Include in this box the left and right
5962 window_box (w
, -1, &x
, &y
, &width
, &height
);
5963 width
+= FRAME_X_FRINGE_WIDTH (f
);
5964 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5966 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5967 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5968 bottom_y
= y
+ height
;
5972 /* Scrolling up. Make sure we don't copy part of the mode
5973 line at the bottom. */
5974 if (from_y
+ run
->height
> bottom_y
)
5975 height
= bottom_y
- from_y
;
5977 height
= run
->height
;
5981 /* Scolling down. Make sure we don't copy over the mode line.
5983 if (to_y
+ run
->height
> bottom_y
)
5984 height
= bottom_y
- to_y
;
5986 height
= run
->height
;
5991 /* Cursor off. Will be switched on again in x_update_window_end. */
5995 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5996 f
->output_data
.mac
->normal_gc
,
6006 /***********************************************************************
6008 ***********************************************************************/
6010 /* Redisplay an exposed area of frame F. X and Y are the upper-left
6011 corner of the exposed rectangle. W and H are width and height of
6012 the exposed area. All are pixel values. W or H zero means redraw
6013 the entire frame. */
6016 expose_frame (f
, x
, y
, w
, h
)
6021 int mouse_face_overwritten_p
= 0;
6023 TRACE ((stderr
, "expose_frame "));
6025 /* No need to redraw if frame will be redrawn soon. */
6026 if (FRAME_GARBAGED_P (f
))
6028 TRACE ((stderr
, " garbaged\n"));
6032 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
6033 or deactivated here, for unknown reasons, activated scroll bars
6034 are shown in deactivated frames in some instances. */
6035 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6036 activate_scroll_bars (f
);
6038 deactivate_scroll_bars (f
);
6040 /* If basic faces haven't been realized yet, there is no point in
6041 trying to redraw anything. This can happen when we get an expose
6042 event while Emacs is starting, e.g. by moving another window. */
6043 if (FRAME_FACE_CACHE (f
) == NULL
6044 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
6046 TRACE ((stderr
, " no faces\n"));
6050 if (w
== 0 || h
== 0)
6053 r
.right
= CANON_X_UNIT (f
) * f
->width
;
6054 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
6064 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
6065 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
6067 if (WINDOWP (f
->tool_bar_window
))
6068 mouse_face_overwritten_p
6069 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
6071 /* Some window managers support a focus-follows-mouse style with
6072 delayed raising of frames. Imagine a partially obscured frame,
6073 and moving the mouse into partially obscured mouse-face on that
6074 frame. The visible part of the mouse-face will be highlighted,
6075 then the WM raises the obscured frame. With at least one WM, KDE
6076 2.1, Emacs is not getting any event for the raising of the frame
6077 (even tried with SubstructureRedirectMask), only Expose events.
6078 These expose events will draw text normally, i.e. not
6079 highlighted. Which means we must redo the highlight here.
6080 Subsume it under ``we love X''. --gerd 2001-08-15 */
6081 /* Included in Windows version because Windows most likely does not
6082 do the right thing if any third party tool offers
6083 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
6084 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
6086 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6087 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6089 int x
= dpyinfo
->mouse_face_mouse_x
;
6090 int y
= dpyinfo
->mouse_face_mouse_y
;
6091 clear_mouse_face (dpyinfo
);
6092 note_mouse_highlight (f
, x
, y
);
6098 /* Redraw (parts) of all windows in the window tree rooted at W that
6099 intersect R. R contains frame pixel coordinates. */
6102 expose_window_tree (w
, r
)
6106 struct frame
*f
= XFRAME (w
->frame
);
6107 int mouse_face_overwritten_p
= 0;
6109 while (w
&& !FRAME_GARBAGED_P (f
))
6111 if (!NILP (w
->hchild
))
6112 mouse_face_overwritten_p
6113 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
6114 else if (!NILP (w
->vchild
))
6115 mouse_face_overwritten_p
6116 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
6118 mouse_face_overwritten_p
|= expose_window (w
, r
);
6120 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
6123 return mouse_face_overwritten_p
;
6127 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
6128 which intersects rectangle R. R is in window-relative coordinates. */
6131 expose_area (w
, row
, r
, area
)
6133 struct glyph_row
*row
;
6135 enum glyph_row_area area
;
6137 struct glyph
*first
= row
->glyphs
[area
];
6138 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
6140 int first_x
, start_x
, x
;
6142 if (area
== TEXT_AREA
&& row
->fill_line_p
)
6143 /* If row extends face to end of line write the whole line. */
6144 x_draw_glyphs (w
, 0, row
, area
,
6146 DRAW_NORMAL_TEXT
, 0);
6149 /* Set START_X to the window-relative start position for drawing glyphs of
6150 AREA. The first glyph of the text area can be partially visible.
6151 The first glyphs of other areas cannot. */
6152 if (area
== LEFT_MARGIN_AREA
)
6154 else if (area
== TEXT_AREA
)
6155 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6157 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6158 + window_box_width (w
, TEXT_AREA
));
6161 /* Find the first glyph that must be redrawn. */
6163 && x
+ first
->pixel_width
< r
->left
)
6165 x
+= first
->pixel_width
;
6169 /* Find the last one. */
6175 x
+= last
->pixel_width
;
6181 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6182 first
- row
->glyphs
[area
],
6183 last
- row
->glyphs
[area
],
6184 DRAW_NORMAL_TEXT
, 0);
6189 /* Redraw the parts of the glyph row ROW on window W intersecting
6190 rectangle R. R is in window-relative coordinates. Value is
6191 non-zero if mouse face was overwritten. */
6194 expose_line (w
, row
, r
)
6196 struct glyph_row
*row
;
6199 xassert (row
->enabled_p
);
6201 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6202 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6203 DRAW_NORMAL_TEXT
, 0);
6206 if (row
->used
[LEFT_MARGIN_AREA
])
6207 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6208 if (row
->used
[TEXT_AREA
])
6209 expose_area (w
, row
, r
, TEXT_AREA
);
6210 if (row
->used
[RIGHT_MARGIN_AREA
])
6211 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6212 x_draw_row_fringe_bitmaps (w
, row
);
6215 return row
->mouse_face_p
;
6219 /* Return non-zero if W's cursor intersects rectangle R. */
6222 x_phys_cursor_in_rect_p (w
, r
)
6227 struct glyph
*cursor_glyph
;
6229 cursor_glyph
= get_phys_cursor_glyph (w
);
6232 cr
.left
= w
->phys_cursor
.x
;
6233 cr
.top
= w
->phys_cursor
.y
;
6234 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6235 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6236 return x_intersect_rectangles (&cr
, r
, &result
);
6243 /* Redraw the part of window W intersection rectagle FR. Pixel
6244 coordinates in FR are frame relative. Call this function with
6245 input blocked. Value is non-zero if the exposure overwrites
6249 expose_window (w
, fr
)
6253 struct frame
*f
= XFRAME (w
->frame
);
6255 int mouse_face_overwritten_p
= 0;
6257 /* If window is not yet fully initialized, do nothing. This can
6258 happen when toolkit scroll bars are used and a window is split.
6259 Reconfiguring the scroll bar will generate an expose for a newly
6261 if (w
->current_matrix
== NULL
)
6264 /* When we're currently updating the window, display and current
6265 matrix usually don't agree. Arrange for a thorough display
6267 if (w
== updated_window
)
6269 SET_FRAME_GARBAGED (f
);
6273 /* Frame-relative pixel rectangle of W. */
6274 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6275 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6276 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6277 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6279 if (x_intersect_rectangles (fr
, &wr
, &r
))
6281 int yb
= window_text_bottom_y (w
);
6282 struct glyph_row
*row
;
6283 int cursor_cleared_p
;
6285 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6286 r
.left
, r
.top
, r
.right
, r
.bottom
));
6288 /* Convert to window coordinates. */
6289 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6290 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6291 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6292 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6294 /* Turn off the cursor. */
6295 if (!w
->pseudo_window_p
6296 && x_phys_cursor_in_rect_p (w
, &r
))
6299 cursor_cleared_p
= 1;
6302 cursor_cleared_p
= 0;
6304 /* Find the first row intersecting the rectangle R. */
6305 for (row
= w
->current_matrix
->rows
;
6310 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6312 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6313 || (y1
> r
.top
&& y1
< r
.bottom
)
6314 || (r
.top
>= y0
&& r
.top
< y1
)
6315 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6317 if (expose_line (w
, row
, &r
))
6318 mouse_face_overwritten_p
= 1;
6325 /* Display the mode line if there is one. */
6326 if (WINDOW_WANTS_MODELINE_P (w
)
6327 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6329 && row
->y
< r
.bottom
)
6331 if (expose_line (w
, row
, &r
))
6332 mouse_face_overwritten_p
= 1;
6335 if (!w
->pseudo_window_p
)
6337 /* Draw border between windows. */
6338 x_draw_vertical_border (w
);
6340 /* Turn the cursor on again. */
6341 if (cursor_cleared_p
)
6342 x_update_window_cursor (w
, 1);
6346 /* Display scroll bar for this window. */
6347 if (!NILP (w
->vertical_scroll_bar
))
6350 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6355 return mouse_face_overwritten_p
;
6359 x_intersect_rectangles (r1
, r2
, result
)
6360 Rect
*r1
, *r2
, *result
;
6363 Rect
*upper
, *lower
;
6364 int intersection_p
= 0;
6366 /* Rerrange so that R1 is the left-most rectangle. */
6367 if (r1
->left
< r2
->left
)
6368 left
= r1
, right
= r2
;
6370 left
= r2
, right
= r1
;
6372 /* X0 of the intersection is right.x0, if this is inside R1,
6373 otherwise there is no intersection. */
6374 if (right
->left
<= left
->right
)
6376 result
->left
= right
->left
;
6378 /* The right end of the intersection is the minimum of the
6379 the right ends of left and right. */
6380 result
->right
= min (left
->right
, right
->right
);
6382 /* Same game for Y. */
6383 if (r1
->top
< r2
->top
)
6384 upper
= r1
, lower
= r2
;
6386 upper
= r2
, lower
= r1
;
6388 /* The upper end of the intersection is lower.y0, if this is inside
6389 of upper. Otherwise, there is no intersection. */
6390 if (lower
->top
<= upper
->bottom
)
6392 result
->top
= lower
->top
;
6394 /* The lower end of the intersection is the minimum of the lower
6395 ends of upper and lower. */
6396 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6401 return intersection_p
;
6412 x_update_cursor (f
, 1);
6416 frame_unhighlight (f
)
6419 x_update_cursor (f
, 1);
6422 /* The focus has changed. Update the frames as necessary to reflect
6423 the new situation. Note that we can't change the selected frame
6424 here, because the Lisp code we are interrupting might become confused.
6425 Each event gets marked with the frame in which it occurred, so the
6426 Lisp code can tell when the switch took place by examining the events. */
6429 x_new_focus_frame (dpyinfo
, frame
)
6430 struct x_display_info
*dpyinfo
;
6431 struct frame
*frame
;
6433 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6435 if (frame
!= dpyinfo
->x_focus_frame
)
6437 /* Set this before calling other routines, so that they see
6438 the correct value of x_focus_frame. */
6439 dpyinfo
->x_focus_frame
= frame
;
6441 if (old_focus
&& old_focus
->auto_lower
)
6442 x_lower_frame (old_focus
);
6445 selected_frame
= frame
;
6446 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6448 Fselect_window (selected_frame
->selected_window
);
6449 choose_minibuf_frame ();
6452 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6453 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6455 pending_autoraise_frame
= 0;
6458 x_frame_rehighlight (dpyinfo
);
6461 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6464 x_mouse_leave (dpyinfo
)
6465 struct x_display_info
*dpyinfo
;
6467 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6470 /* The focus has changed, or we have redirected a frame's focus to
6471 another frame (this happens when a frame uses a surrogate
6472 mini-buffer frame). Shift the highlight as appropriate.
6474 The FRAME argument doesn't necessarily have anything to do with which
6475 frame is being highlighted or un-highlighted; we only use it to find
6476 the appropriate X display info. */
6479 XTframe_rehighlight (frame
)
6480 struct frame
*frame
;
6482 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6486 x_frame_rehighlight (dpyinfo
)
6487 struct x_display_info
*dpyinfo
;
6489 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6491 if (dpyinfo
->x_focus_frame
)
6493 dpyinfo
->x_highlight_frame
6494 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6495 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6496 : dpyinfo
->x_focus_frame
);
6497 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6499 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6500 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6504 dpyinfo
->x_highlight_frame
= 0;
6506 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6509 frame_unhighlight (old_highlight
);
6510 if (dpyinfo
->x_highlight_frame
)
6511 frame_highlight (dpyinfo
->x_highlight_frame
);
6517 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6519 #if 0 /* MAC_TODO */
6520 /* Initialize mode_switch_bit and modifier_meaning. */
6522 x_find_modifier_meanings (dpyinfo
)
6523 struct x_display_info
*dpyinfo
;
6525 int min_code
, max_code
;
6528 XModifierKeymap
*mods
;
6530 dpyinfo
->meta_mod_mask
= 0;
6531 dpyinfo
->shift_lock_mask
= 0;
6532 dpyinfo
->alt_mod_mask
= 0;
6533 dpyinfo
->super_mod_mask
= 0;
6534 dpyinfo
->hyper_mod_mask
= 0;
6537 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6539 min_code
= dpyinfo
->display
->min_keycode
;
6540 max_code
= dpyinfo
->display
->max_keycode
;
6543 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6544 min_code
, max_code
- min_code
+ 1,
6546 mods
= XGetModifierMapping (dpyinfo
->display
);
6548 /* Scan the modifier table to see which modifier bits the Meta and
6549 Alt keysyms are on. */
6551 int row
, col
; /* The row and column in the modifier table. */
6553 for (row
= 3; row
< 8; row
++)
6554 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6557 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6559 /* Zeroes are used for filler. Skip them. */
6563 /* Are any of this keycode's keysyms a meta key? */
6567 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6569 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6575 dpyinfo
->meta_mod_mask
|= (1 << row
);
6580 dpyinfo
->alt_mod_mask
|= (1 << row
);
6585 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6590 dpyinfo
->super_mod_mask
|= (1 << row
);
6594 /* Ignore this if it's not on the lock modifier. */
6595 if ((1 << row
) == LockMask
)
6596 dpyinfo
->shift_lock_mask
= LockMask
;
6604 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6605 if (! dpyinfo
->meta_mod_mask
)
6607 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6608 dpyinfo
->alt_mod_mask
= 0;
6611 /* If some keys are both alt and meta,
6612 make them just meta, not alt. */
6613 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6615 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6618 XFree ((char *) syms
);
6619 XFreeModifiermap (mods
);
6622 #endif /* MAC_TODO */
6624 /* Convert between the modifier bits X uses and the modifier bits
6628 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6629 struct x_display_info
*dpyinfo
;
6630 unsigned short state
;
6632 return (((state
& shiftKey
) ? shift_modifier
: 0)
6633 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6634 | ((state
& cmdKey
) ? meta_modifier
: 0)
6635 | ((state
& optionKey
) ? alt_modifier
: 0));
6638 #if 0 /* MAC_TODO */
6639 static unsigned short
6640 x_emacs_to_x_modifiers (dpyinfo
, state
)
6641 struct x_display_info
*dpyinfo
;
6644 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6645 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6646 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6647 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6648 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6649 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6651 #endif /* MAC_TODO */
6653 /* Convert a keysym to its name. */
6656 x_get_keysym_name (keysym
)
6663 value
= XKeysymToString (keysym
);
6674 /* Mouse clicks and mouse movement. Rah. */
6676 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6677 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6678 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6679 not force the value into range. */
6682 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6684 register int pix_x
, pix_y
;
6685 register int *x
, *y
;
6689 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6690 if (NILP (Vwindow_system
))
6697 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6698 even for negative values. */
6700 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6702 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6704 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6705 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6709 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6710 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6711 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6712 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6719 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6720 pix_x
= FRAME_WINDOW_WIDTH (f
);
6724 else if (pix_y
> f
->height
)
6733 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6734 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6735 can't tell the positions because W's display is not up to date,
6739 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6742 int *frame_x
, *frame_y
;
6746 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6747 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6749 if (display_completed
)
6751 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6752 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6753 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6759 *frame_x
+= glyph
->pixel_width
;
6767 *frame_y
= *frame_x
= 0;
6771 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6772 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6777 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6779 If the event is a button press, then note that we have grabbed
6783 construct_mouse_click (result
, event
, f
)
6784 struct input_event
*result
;
6790 result
->kind
= MOUSE_CLICK_EVENT
;
6791 result
->code
= 0; /* only one mouse button */
6792 result
->timestamp
= event
->when
;
6793 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6795 mouseLoc
= event
->where
;
6797 #if TARGET_API_MAC_CARBON
6798 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6800 SetPort (FRAME_MAC_WINDOW (f
));
6803 GlobalToLocal (&mouseLoc
);
6804 XSETINT (result
->x
, mouseLoc
.h
);
6805 XSETINT (result
->y
, mouseLoc
.v
);
6807 XSETFRAME (result
->frame_or_window
, f
);
6814 /* Function to report a mouse movement to the mainstream Emacs code.
6815 The input handler calls this.
6817 We have received a mouse movement event, which is given in *event.
6818 If the mouse is over a different glyph than it was last time, tell
6819 the mainstream emacs code by setting mouse_moved. If not, ask for
6820 another motion event, so we can check again the next time it moves. */
6822 static Point last_mouse_motion_position
;
6823 static Lisp_Object last_mouse_motion_frame
;
6826 note_mouse_movement (frame
, pos
)
6830 #if TARGET_API_MAC_CARBON
6834 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6835 last_mouse_motion_position
= *pos
;
6836 XSETFRAME (last_mouse_motion_frame
, frame
);
6838 #if TARGET_API_MAC_CARBON
6839 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6841 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6844 frame
->mouse_moved
= 1;
6845 last_mouse_scroll_bar
= Qnil
;
6846 note_mouse_highlight (frame
, -1, -1);
6848 /* Has the mouse moved off the glyph it was on at the last sighting? */
6849 else if (pos
->h
< last_mouse_glyph
.left
6850 || pos
->h
>= last_mouse_glyph
.right
6851 || pos
->v
< last_mouse_glyph
.top
6852 || pos
->v
>= last_mouse_glyph
.bottom
)
6854 frame
->mouse_moved
= 1;
6855 last_mouse_scroll_bar
= Qnil
;
6856 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6860 /* This is used for debugging, to turn off note_mouse_highlight. */
6862 int disable_mouse_highlight
;
6866 /************************************************************************
6868 ************************************************************************/
6870 /* Find the glyph under window-relative coordinates X/Y in window W.
6871 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6872 strings. Return in *HPOS and *VPOS the row and column number of
6873 the glyph found. Return in *AREA the glyph area containing X.
6874 Value is a pointer to the glyph found or null if X/Y is not on
6875 text, or we can't tell because W's current matrix is not up to
6878 static struct glyph
*
6879 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6882 int *hpos
, *vpos
, *area
;
6885 struct glyph
*glyph
, *end
;
6886 struct glyph_row
*row
= NULL
;
6887 int x0
, i
, left_area_width
;
6889 /* Find row containing Y. Give up if some row is not enabled. */
6890 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6892 row
= MATRIX_ROW (w
->current_matrix
, i
);
6893 if (!row
->enabled_p
)
6895 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6902 /* Give up if Y is not in the window. */
6903 if (i
== w
->current_matrix
->nrows
)
6906 /* Get the glyph area containing X. */
6907 if (w
->pseudo_window_p
)
6914 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6915 if (x
< left_area_width
)
6917 *area
= LEFT_MARGIN_AREA
;
6920 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6923 x0
= row
->x
+ left_area_width
;
6927 *area
= RIGHT_MARGIN_AREA
;
6928 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6932 /* Find glyph containing X. */
6933 glyph
= row
->glyphs
[*area
];
6934 end
= glyph
+ row
->used
[*area
];
6937 if (x
< x0
+ glyph
->pixel_width
)
6939 if (w
->pseudo_window_p
)
6941 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6945 x0
+= glyph
->pixel_width
;
6952 *hpos
= glyph
- row
->glyphs
[*area
];
6957 /* Convert frame-relative x/y to coordinates relative to window W.
6958 Takes pseudo-windows into account. */
6961 frame_to_window_pixel_xy (w
, x
, y
)
6965 if (w
->pseudo_window_p
)
6967 /* A pseudo-window is always full-width, and starts at the
6968 left edge of the frame, plus a frame border. */
6969 struct frame
*f
= XFRAME (w
->frame
);
6970 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6971 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6975 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6976 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6981 /* Take proper action when mouse has moved to the mode or header line of
6982 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6983 mode line. X is relative to the start of the text display area of
6984 W, so the width of fringes and scroll bars must be subtracted
6985 to get a position relative to the start of the mode line. */
6988 note_mode_line_highlight (w
, x
, mode_line_p
)
6992 struct frame
*f
= XFRAME (w
->frame
);
6993 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6994 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6995 struct glyph_row
*row
;
6998 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
7000 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
7004 struct glyph
*glyph
, *end
;
7005 Lisp_Object help
, map
;
7008 /* Find the glyph under X. */
7009 glyph
= row
->glyphs
[TEXT_AREA
];
7010 end
= glyph
+ row
->used
[TEXT_AREA
];
7011 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
7012 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
7015 && x
>= x0
+ glyph
->pixel_width
)
7017 x0
+= glyph
->pixel_width
;
7022 && STRINGP (glyph
->object
)
7023 && STRING_INTERVALS (glyph
->object
)
7024 && glyph
->charpos
>= 0
7025 && glyph
->charpos
< SCHARS (glyph
->object
))
7027 /* If we're on a string with `help-echo' text property,
7028 arrange for the help to be displayed. This is done by
7029 setting the global variable help_echo to the help string. */
7030 help
= Fget_text_property (make_number (glyph
->charpos
),
7031 Qhelp_echo
, glyph
->object
);
7035 XSETWINDOW (help_echo_window
, w
);
7036 help_echo_object
= glyph
->object
;
7037 help_echo_pos
= glyph
->charpos
;
7040 /* Change the mouse pointer according to what is under X/Y. */
7041 map
= Fget_text_property (make_number (glyph
->charpos
),
7042 Qlocal_map
, glyph
->object
);
7044 cursor
= f
->output_data
.mac
->nontext_cursor
;
7047 map
= Fget_text_property (make_number (glyph
->charpos
),
7048 Qkeymap
, glyph
->object
);
7050 cursor
= f
->output_data
.mac
->nontext_cursor
;
7055 #if 0 /* MAC_TODO: mouse cursor */
7056 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7061 /* Take proper action when the mouse has moved to position X, Y on
7062 frame F as regards highlighting characters that have mouse-face
7063 properties. Also de-highlighting chars where the mouse was before.
7064 X and Y can be negative or out of range. */
7067 note_mouse_highlight (f
, x
, y
)
7071 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7078 /* When a menu is active, don't highlight because this looks odd. */
7079 if (popup_activated ())
7083 if (NILP (Vmouse_highlight
)
7084 || !f
->glyphs_initialized_p
)
7087 dpyinfo
->mouse_face_mouse_x
= x
;
7088 dpyinfo
->mouse_face_mouse_y
= y
;
7089 dpyinfo
->mouse_face_mouse_frame
= f
;
7091 if (dpyinfo
->mouse_face_defer
)
7096 dpyinfo
->mouse_face_deferred_gc
= 1;
7100 /* Which window is that in? */
7101 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7103 /* If we were displaying active text in another window, clear that. */
7104 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7105 clear_mouse_face (dpyinfo
);
7107 /* Not on a window -> return. */
7108 if (!WINDOWP (window
))
7111 /* Reset help_echo. It will get recomputed below. */
7114 /* Convert to window-relative pixel coordinates. */
7115 w
= XWINDOW (window
);
7116 frame_to_window_pixel_xy (w
, &x
, &y
);
7118 /* Handle tool-bar window differently since it doesn't display a
7120 if (EQ (window
, f
->tool_bar_window
))
7122 note_tool_bar_highlight (f
, x
, y
);
7126 /* Mouse is on the mode or header line? */
7127 if (portion
== 1 || portion
== 3)
7129 note_mode_line_highlight (w
, x
, portion
== 1);
7132 #if 0 /* TODO: mouse cursor */
7134 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7136 cursor
= f
->output_data
.x
->text_cursor
;
7138 /* Are we in a window whose display is up to date?
7139 And verify the buffer's text has not changed. */
7140 b
= XBUFFER (w
->buffer
);
7141 if (/* Within text portion of the window. */
7143 && EQ (w
->window_end_valid
, w
->buffer
)
7144 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7145 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7147 int hpos
, vpos
, pos
, i
, area
;
7148 struct glyph
*glyph
;
7150 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7151 Lisp_Object
*overlay_vec
= NULL
;
7153 struct buffer
*obuf
;
7154 int obegv
, ozv
, same_region
;
7156 /* Find the glyph under X/Y. */
7157 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7159 /* Clear mouse face if X/Y not over text. */
7161 || area
!= TEXT_AREA
7162 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7164 clear_mouse_face (dpyinfo
);
7165 /* TODO: mouse cursor */
7169 pos
= glyph
->charpos
;
7170 object
= glyph
->object
;
7171 if (!STRINGP (object
) && !BUFFERP (object
))
7174 /* If we get an out-of-range value, return now; avoid an error. */
7175 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7178 /* Make the window's buffer temporarily current for
7179 overlays_at and compute_char_face. */
7180 obuf
= current_buffer
;
7187 /* Is this char mouse-active or does it have help-echo? */
7188 position
= make_number (pos
);
7190 if (BUFFERP (object
))
7192 /* Put all the overlays we want in a vector in overlay_vec.
7193 Store the length in len. If there are more than 10, make
7194 enough space for all, and try again. */
7196 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7197 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7198 if (noverlays
> len
)
7201 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7202 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7205 /* Sort overlays into increasing priority order. */
7206 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7211 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7212 && vpos
>= dpyinfo
->mouse_face_beg_row
7213 && vpos
<= dpyinfo
->mouse_face_end_row
7214 && (vpos
> dpyinfo
->mouse_face_beg_row
7215 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7216 && (vpos
< dpyinfo
->mouse_face_end_row
7217 || hpos
< dpyinfo
->mouse_face_end_col
7218 || dpyinfo
->mouse_face_past_end
));
7220 /* TODO: if (same_region)
7223 /* Check mouse-face highlighting. */
7225 /* If there exists an overlay with mouse-face overlapping
7226 the one we are currently highlighting, we have to
7227 check if we enter the overlapping overlay, and then
7229 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7230 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7232 /* Find the highest priority overlay that has a mouse-face
7235 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7237 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7238 if (!NILP (mouse_face
))
7239 overlay
= overlay_vec
[i
];
7242 /* If we're actually highlighting the same overlay as
7243 before, there's no need to do that again. */
7245 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7246 goto check_help_echo
;
7248 dpyinfo
->mouse_face_overlay
= overlay
;
7250 /* Clear the display of the old active region, if any. */
7251 clear_mouse_face (dpyinfo
);
7252 /* TODO: mouse cursor changes. */
7254 /* If no overlay applies, get a text property. */
7256 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7258 /* Handle the overlay case. */
7259 if (!NILP (overlay
))
7261 /* Find the range of text around this char that
7262 should be active. */
7263 Lisp_Object before
, after
;
7266 before
= Foverlay_start (overlay
);
7267 after
= Foverlay_end (overlay
);
7268 /* Record this as the current active region. */
7269 fast_find_position (w
, XFASTINT (before
),
7270 &dpyinfo
->mouse_face_beg_col
,
7271 &dpyinfo
->mouse_face_beg_row
,
7272 &dpyinfo
->mouse_face_beg_x
,
7273 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7275 dpyinfo
->mouse_face_past_end
7276 = !fast_find_position (w
, XFASTINT (after
),
7277 &dpyinfo
->mouse_face_end_col
,
7278 &dpyinfo
->mouse_face_end_row
,
7279 &dpyinfo
->mouse_face_end_x
,
7280 &dpyinfo
->mouse_face_end_y
, Qnil
);
7281 dpyinfo
->mouse_face_window
= window
;
7283 dpyinfo
->mouse_face_face_id
7284 = face_at_buffer_position (w
, pos
, 0, 0,
7285 &ignore
, pos
+ 1, 1);
7287 /* Display it as active. */
7288 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7289 /* TODO: mouse cursor changes. */
7291 /* Handle the text property case. */
7292 else if (! NILP (mouse_face
) && BUFFERP (object
))
7294 /* Find the range of text around this char that
7295 should be active. */
7296 Lisp_Object before
, after
, beginning
, end
;
7299 beginning
= Fmarker_position (w
->start
);
7300 end
= make_number (BUF_Z (XBUFFER (object
))
7301 - XFASTINT (w
->window_end_pos
));
7303 = Fprevious_single_property_change (make_number (pos
+ 1),
7307 = Fnext_single_property_change (position
, Qmouse_face
,
7310 /* Record this as the current active region. */
7311 fast_find_position (w
, XFASTINT (before
),
7312 &dpyinfo
->mouse_face_beg_col
,
7313 &dpyinfo
->mouse_face_beg_row
,
7314 &dpyinfo
->mouse_face_beg_x
,
7315 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7316 dpyinfo
->mouse_face_past_end
7317 = !fast_find_position (w
, XFASTINT (after
),
7318 &dpyinfo
->mouse_face_end_col
,
7319 &dpyinfo
->mouse_face_end_row
,
7320 &dpyinfo
->mouse_face_end_x
,
7321 &dpyinfo
->mouse_face_end_y
, Qnil
);
7322 dpyinfo
->mouse_face_window
= window
;
7324 if (BUFFERP (object
))
7325 dpyinfo
->mouse_face_face_id
7326 = face_at_buffer_position (w
, pos
, 0, 0,
7327 &ignore
, pos
+ 1, 1);
7329 /* Display it as active. */
7330 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7331 /* TODO: mouse cursor changes. */
7333 else if (!NILP (mouse_face
) && STRINGP (object
))
7338 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7341 e
= Fnext_single_property_change (position
, Qmouse_face
,
7344 b
= make_number (0);
7346 e
= make_number (SCHARS (object
) - 1);
7347 fast_find_string_pos (w
, XINT (b
), object
,
7348 &dpyinfo
->mouse_face_beg_col
,
7349 &dpyinfo
->mouse_face_beg_row
,
7350 &dpyinfo
->mouse_face_beg_x
,
7351 &dpyinfo
->mouse_face_beg_y
, 0);
7352 fast_find_string_pos (w
, XINT (e
), object
,
7353 &dpyinfo
->mouse_face_end_col
,
7354 &dpyinfo
->mouse_face_end_row
,
7355 &dpyinfo
->mouse_face_end_x
,
7356 &dpyinfo
->mouse_face_end_y
, 1);
7357 dpyinfo
->mouse_face_past_end
= 0;
7358 dpyinfo
->mouse_face_window
= window
;
7359 dpyinfo
->mouse_face_face_id
7360 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7362 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7363 /* TODO: mouse cursor changes. */
7365 else if (STRINGP (object
) && NILP (mouse_face
))
7367 /* A string which doesn't have mouse-face, but
7368 the text ``under'' it might have. */
7369 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7370 int start
= MATRIX_ROW_START_CHARPOS (r
);
7372 pos
= string_buffer_position (w
, object
, start
);
7374 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7378 if (!NILP (mouse_face
) && !NILP (overlay
))
7380 Lisp_Object before
= Foverlay_start (overlay
);
7381 Lisp_Object after
= Foverlay_end (overlay
);
7384 /* Note that we might not be able to find position
7385 BEFORE in the glyph matrix if the overlay is
7386 entirely covered by a `display' property. In
7387 this case, we overshoot. So let's stop in
7388 the glyph matrix before glyphs for OBJECT. */
7389 fast_find_position (w
, XFASTINT (before
),
7390 &dpyinfo
->mouse_face_beg_col
,
7391 &dpyinfo
->mouse_face_beg_row
,
7392 &dpyinfo
->mouse_face_beg_x
,
7393 &dpyinfo
->mouse_face_beg_y
,
7396 dpyinfo
->mouse_face_past_end
7397 = !fast_find_position (w
, XFASTINT (after
),
7398 &dpyinfo
->mouse_face_end_col
,
7399 &dpyinfo
->mouse_face_end_row
,
7400 &dpyinfo
->mouse_face_end_x
,
7401 &dpyinfo
->mouse_face_end_y
,
7403 dpyinfo
->mouse_face_window
= window
;
7404 dpyinfo
->mouse_face_face_id
7405 = face_at_buffer_position (w
, pos
, 0, 0,
7406 &ignore
, pos
+ 1, 1);
7408 /* Display it as active. */
7409 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7410 /* TODO: mouse cursor changes. */
7417 /* Look for a `help-echo' property. */
7419 Lisp_Object help
, overlay
;
7421 /* Check overlays first. */
7422 help
= overlay
= Qnil
;
7423 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7425 overlay
= overlay_vec
[i
];
7426 help
= Foverlay_get (overlay
, Qhelp_echo
);
7432 help_echo_window
= window
;
7433 help_echo_object
= overlay
;
7434 help_echo_pos
= pos
;
7438 Lisp_Object object
= glyph
->object
;
7439 int charpos
= glyph
->charpos
;
7441 /* Try text properties. */
7442 if (STRINGP (object
)
7444 && charpos
< SCHARS (object
))
7446 help
= Fget_text_property (make_number (charpos
),
7447 Qhelp_echo
, object
);
7450 /* If the string itself doesn't specify a help-echo,
7451 see if the buffer text ``under'' it does. */
7453 = MATRIX_ROW (w
->current_matrix
, vpos
);
7454 int start
= MATRIX_ROW_START_CHARPOS (r
);
7455 int pos
= string_buffer_position (w
, object
, start
);
7458 help
= Fget_char_property (make_number (pos
),
7459 Qhelp_echo
, w
->buffer
);
7468 else if (BUFFERP (object
)
7471 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7477 help_echo_window
= window
;
7478 help_echo_object
= object
;
7479 help_echo_pos
= charpos
;
7486 current_buffer
= obuf
;
7490 /* TODO: mouse cursor changes. */
7495 redo_mouse_highlight ()
7497 if (!NILP (last_mouse_motion_frame
)
7498 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7499 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7500 last_mouse_motion_position
.h
,
7501 last_mouse_motion_position
.v
);
7506 /***********************************************************************
7508 ***********************************************************************/
7510 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7511 struct glyph
**, int *, int *, int *));
7513 /* Tool-bar item index of the item on which a mouse button was pressed
7516 static int last_tool_bar_item
;
7519 /* Get information about the tool-bar item at position X/Y on frame F.
7520 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7521 the current matrix of the tool-bar window of F, or NULL if not
7522 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7523 item in F->current_tool_bar_items. Value is
7525 -1 if X/Y is not on a tool-bar item
7526 0 if X/Y is on the same item that was highlighted before.
7530 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7533 struct glyph
**glyph
;
7534 int *hpos
, *vpos
, *prop_idx
;
7536 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7537 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7540 /* Find the glyph under X/Y. */
7541 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7545 /* Get the start of this tool-bar item's properties in
7546 f->current_tool_bar_items. */
7547 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7550 /* Is mouse on the highlighted item? */
7551 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7552 && *vpos
>= dpyinfo
->mouse_face_beg_row
7553 && *vpos
<= dpyinfo
->mouse_face_end_row
7554 && (*vpos
> dpyinfo
->mouse_face_beg_row
7555 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7556 && (*vpos
< dpyinfo
->mouse_face_end_row
7557 || *hpos
< dpyinfo
->mouse_face_end_col
7558 || dpyinfo
->mouse_face_past_end
))
7565 /* Handle mouse button event on the tool-bar of frame F, at
7566 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7570 x_handle_tool_bar_click (f
, button_event
)
7572 EventRecord
*button_event
;
7574 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7575 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7576 int hpos
, vpos
, prop_idx
;
7577 struct glyph
*glyph
;
7578 Lisp_Object enabled_p
;
7579 int x
= button_event
->where
.h
;
7580 int y
= button_event
->where
.v
;
7582 /* If not on the highlighted tool-bar item, return. */
7583 frame_to_window_pixel_xy (w
, &x
, &y
);
7584 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7587 /* If item is disabled, do nothing. */
7588 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7589 if (NILP (enabled_p
))
7592 if (button_event
->what
== mouseDown
)
7594 /* Show item in pressed state. */
7595 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7596 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7597 last_tool_bar_item
= prop_idx
;
7601 Lisp_Object key
, frame
;
7602 struct input_event event
;
7604 /* Show item in released state. */
7605 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7606 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7608 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7610 XSETFRAME (frame
, f
);
7611 event
.kind
= TOOL_BAR_EVENT
;
7612 event
.frame_or_window
= frame
;
7614 kbd_buffer_store_event (&event
);
7616 event
.kind
= TOOL_BAR_EVENT
;
7617 event
.frame_or_window
= frame
;
7619 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7620 button_event
->modifiers
);
7621 kbd_buffer_store_event (&event
);
7622 last_tool_bar_item
= -1;
7627 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7628 tool-bar window-relative coordinates X/Y. Called from
7629 note_mouse_highlight. */
7632 note_tool_bar_highlight (f
, x
, y
)
7636 Lisp_Object window
= f
->tool_bar_window
;
7637 struct window
*w
= XWINDOW (window
);
7638 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7640 struct glyph
*glyph
;
7641 struct glyph_row
*row
;
7643 Lisp_Object enabled_p
;
7645 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7646 int mouse_down_p
, rc
;
7648 /* Function note_mouse_highlight is called with negative x(y
7649 values when mouse moves outside of the frame. */
7650 if (x
<= 0 || y
<= 0)
7652 clear_mouse_face (dpyinfo
);
7656 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7659 /* Not on tool-bar item. */
7660 clear_mouse_face (dpyinfo
);
7664 /* On same tool-bar item as before. */
7667 clear_mouse_face (dpyinfo
);
7669 /* Mouse is down, but on different tool-bar item? */
7670 mouse_down_p
= (dpyinfo
->grabbed
7671 && f
== last_mouse_frame
7672 && FRAME_LIVE_P (f
));
7674 && last_tool_bar_item
!= prop_idx
)
7677 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7678 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7680 /* If tool-bar item is not enabled, don't highlight it. */
7681 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7682 if (!NILP (enabled_p
))
7684 /* Compute the x-position of the glyph. In front and past the
7685 image is a space. We include this is the highlighted area. */
7686 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7687 for (i
= x
= 0; i
< hpos
; ++i
)
7688 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7690 /* Record this as the current active region. */
7691 dpyinfo
->mouse_face_beg_col
= hpos
;
7692 dpyinfo
->mouse_face_beg_row
= vpos
;
7693 dpyinfo
->mouse_face_beg_x
= x
;
7694 dpyinfo
->mouse_face_beg_y
= row
->y
;
7695 dpyinfo
->mouse_face_past_end
= 0;
7697 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7698 dpyinfo
->mouse_face_end_row
= vpos
;
7699 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7700 dpyinfo
->mouse_face_end_y
= row
->y
;
7701 dpyinfo
->mouse_face_window
= window
;
7702 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7704 /* Display it as active. */
7705 show_mouse_face (dpyinfo
, draw
);
7706 dpyinfo
->mouse_face_image_state
= draw
;
7711 /* Set help_echo to a help string.to display for this tool-bar item.
7712 XTread_socket does the rest. */
7713 help_echo_object
= help_echo_window
= Qnil
;
7715 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7716 if (NILP (help_echo
))
7717 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7722 /* Find the glyph matrix position of buffer position CHARPOS in window
7723 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7724 current glyphs must be up to date. If CHARPOS is above window
7725 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7726 of last line in W. In the row containing CHARPOS, stop before glyphs
7727 having STOP as object. */
7729 #if 0 /* This is a version of fast_find_position that's more correct
7730 in the presence of hscrolling, for example. I didn't install
7731 it right away because the problem fixed is minor, it failed
7732 in 20.x as well, and I think it's too risky to install
7733 so near the release of 21.1. 2001-09-25 gerd. */
7736 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7739 int *hpos
, *vpos
, *x
, *y
;
7742 struct glyph_row
*row
, *first
;
7743 struct glyph
*glyph
, *end
;
7744 int i
, past_end
= 0;
7746 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7747 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7750 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7752 *x
= *y
= *hpos
= *vpos
= 0;
7757 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7764 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7766 glyph
= row
->glyphs
[TEXT_AREA
];
7767 end
= glyph
+ row
->used
[TEXT_AREA
];
7769 /* Skip over glyphs not having an object at the start of the row.
7770 These are special glyphs like truncation marks on terminal
7772 if (row
->displays_text_p
)
7774 && INTEGERP (glyph
->object
)
7775 && !EQ (stop
, glyph
->object
)
7776 && glyph
->charpos
< 0)
7778 *x
+= glyph
->pixel_width
;
7783 && !INTEGERP (glyph
->object
)
7784 && !EQ (stop
, glyph
->object
)
7785 && (!BUFFERP (glyph
->object
)
7786 || glyph
->charpos
< charpos
))
7788 *x
+= glyph
->pixel_width
;
7792 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7799 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7802 int *hpos
, *vpos
, *x
, *y
;
7807 int maybe_next_line_p
= 0;
7808 int line_start_position
;
7809 int yb
= window_text_bottom_y (w
);
7810 struct glyph_row
*row
, *best_row
;
7811 int row_vpos
, best_row_vpos
;
7814 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7815 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7819 if (row
->used
[TEXT_AREA
])
7820 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7822 line_start_position
= 0;
7824 if (line_start_position
> pos
)
7826 /* If the position sought is the end of the buffer,
7827 don't include the blank lines at the bottom of the window. */
7828 else if (line_start_position
== pos
7829 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7831 maybe_next_line_p
= 1;
7834 else if (line_start_position
> 0)
7837 best_row_vpos
= row_vpos
;
7840 if (row
->y
+ row
->height
>= yb
)
7847 /* Find the right column within BEST_ROW. */
7849 current_x
= best_row
->x
;
7850 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7852 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7853 int charpos
= glyph
->charpos
;
7855 if (BUFFERP (glyph
->object
))
7860 *vpos
= best_row_vpos
;
7865 else if (charpos
> pos
)
7868 else if (EQ (glyph
->object
, stop
))
7873 current_x
+= glyph
->pixel_width
;
7876 /* If we're looking for the end of the buffer,
7877 and we didn't find it in the line we scanned,
7878 use the start of the following line. */
7879 if (maybe_next_line_p
)
7884 current_x
= best_row
->x
;
7887 *vpos
= best_row_vpos
;
7888 *hpos
= lastcol
+ 1;
7897 /* Find the position of the glyph for position POS in OBJECT in
7898 window W's current matrix, and return in *X/*Y the pixel
7899 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7901 RIGHT_P non-zero means return the position of the right edge of the
7902 glyph, RIGHT_P zero means return the left edge position.
7904 If no glyph for POS exists in the matrix, return the position of
7905 the glyph with the next smaller position that is in the matrix, if
7906 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7907 exists in the matrix, return the position of the glyph with the
7908 next larger position in OBJECT.
7910 Value is non-zero if a glyph was found. */
7913 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7917 int *hpos
, *vpos
, *x
, *y
;
7920 int yb
= window_text_bottom_y (w
);
7921 struct glyph_row
*r
;
7922 struct glyph
*best_glyph
= NULL
;
7923 struct glyph_row
*best_row
= NULL
;
7926 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7927 r
->enabled_p
&& r
->y
< yb
;
7930 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7931 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7934 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7935 if (EQ (g
->object
, object
))
7937 if (g
->charpos
== pos
)
7944 else if (best_glyph
== NULL
7945 || ((abs (g
->charpos
- pos
)
7946 < abs (best_glyph
->charpos
- pos
))
7949 : g
->charpos
> pos
)))
7963 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7967 *x
+= best_glyph
->pixel_width
;
7972 *vpos
= best_row
- w
->current_matrix
->rows
;
7975 return best_glyph
!= NULL
;
7979 /* Display the active region described by mouse_face_*
7980 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7983 show_mouse_face (dpyinfo
, draw
)
7984 struct mac_display_info
*dpyinfo
;
7985 enum draw_glyphs_face draw
;
7987 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7988 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7990 if (/* If window is in the process of being destroyed, don't bother
7992 w
->current_matrix
!= NULL
7993 /* Don't update mouse highlight if hidden */
7994 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7995 /* Recognize when we are called to operate on rows that don't exist
7996 anymore. This can happen when a window is split. */
7997 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7999 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
8000 struct glyph_row
*row
, *first
, *last
;
8002 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
8003 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
8005 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
8007 int start_hpos
, end_hpos
, start_x
;
8009 /* For all but the first row, the highlight starts at column 0. */
8012 start_hpos
= dpyinfo
->mouse_face_beg_col
;
8013 start_x
= dpyinfo
->mouse_face_beg_x
;
8022 end_hpos
= dpyinfo
->mouse_face_end_col
;
8024 end_hpos
= row
->used
[TEXT_AREA
];
8026 if (end_hpos
> start_hpos
)
8028 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
8029 start_hpos
, end_hpos
, draw
, 0);
8032 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8036 /* When we've written over the cursor, arrange for it to
8037 be displayed again. */
8038 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8039 x_display_cursor (w
, 1,
8040 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8041 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8044 #if 0 /* MAC_TODO: mouse cursor */
8045 /* Change the mouse cursor. */
8046 if (draw
== DRAW_NORMAL_TEXT
)
8047 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8048 f
->output_data
.x
->text_cursor
);
8049 else if (draw
== DRAW_MOUSE_FACE
)
8050 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8051 f
->output_data
.x
->cross_cursor
);
8053 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8054 f
->output_data
.x
->nontext_cursor
);
8058 /* Clear out the mouse-highlighted active region.
8059 Redraw it un-highlighted first. */
8062 clear_mouse_face (dpyinfo
)
8063 struct mac_display_info
*dpyinfo
;
8067 if (! NILP (dpyinfo
->mouse_face_window
))
8069 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8073 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8074 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8075 dpyinfo
->mouse_face_window
= Qnil
;
8076 dpyinfo
->mouse_face_overlay
= Qnil
;
8081 /* Clear any mouse-face on window W. This function is part of the
8082 redisplay interface, and is called from try_window_id and similar
8083 functions to ensure the mouse-highlight is off. */
8086 x_clear_mouse_face (w
)
8089 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
8093 XSETWINDOW (window
, w
);
8094 if (EQ (window
, dpyinfo
->mouse_face_window
))
8095 clear_mouse_face (dpyinfo
);
8100 /* Just discard the mouse face information for frame F, if any.
8101 This is used when the size of F is changed. */
8104 cancel_mouse_face (f
)
8108 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8110 window
= dpyinfo
->mouse_face_window
;
8111 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8113 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8114 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8115 dpyinfo
->mouse_face_window
= Qnil
;
8119 static struct scroll_bar
*x_window_to_scroll_bar ();
8120 static void x_scroll_bar_report_motion ();
8121 static void x_check_fullscreen
P_ ((struct frame
*));
8122 static void x_check_fullscreen_move
P_ ((struct frame
*));
8123 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
8126 /* Try to determine frame pixel position and size of the glyph under
8127 frame pixel coordinates X/Y on frame F . Return the position and
8128 size in *RECT. Value is non-zero if we could compute these
8132 glyph_rect (f
, x
, y
, rect
)
8140 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8143 struct window
*w
= XWINDOW (window
);
8144 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8145 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8147 frame_to_window_pixel_xy (w
, &x
, &y
);
8149 for (; r
< end
&& r
->enabled_p
; ++r
)
8150 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
8152 /* Found the row at y. */
8153 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8154 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8157 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8158 rect
->bottom
= rect
->top
+ r
->height
;
8162 /* x is to the left of the first glyph in the row. */
8163 rect
->left
= XINT (w
->left
);
8164 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
8168 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
8169 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
8171 /* x is on a glyph. */
8172 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8173 rect
->right
= rect
->left
+ g
->pixel_width
;
8177 /* x is to the right of the last glyph in the row. */
8178 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8179 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8184 /* The y is not on any row. */
8188 /* Record the position of the mouse in last_mouse_glyph. */
8190 remember_mouse_glyph (f1
, gx
, gy
)
8194 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8196 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8197 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8199 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8200 round down even for negative values. */
8206 /* This was the original code from XTmouse_position, but it seems
8207 to give the position of the glyph diagonally next to the one
8208 the mouse is over. */
8209 gx
= (gx
+ width
- 1) / width
* width
;
8210 gy
= (gy
+ height
- 1) / height
* height
;
8212 gx
= gx
/ width
* width
;
8213 gy
= gy
/ height
* height
;
8216 last_mouse_glyph
.left
= gx
;
8217 last_mouse_glyph
.top
= gy
;
8218 last_mouse_glyph
.right
= gx
+ width
;
8219 last_mouse_glyph
.bottom
= gy
+ height
;
8223 /* Return the current position of the mouse.
8224 *fp should be a frame which indicates which display to ask about.
8226 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8227 and *part to the frame, window, and scroll bar part that the mouse
8228 is over. Set *x and *y to the portion and whole of the mouse's
8229 position on the scroll bar.
8231 If the mouse movement started elsewhere, set *fp to the frame the
8232 mouse is on, *bar_window to nil, and *x and *y to the character cell
8235 Set *time to the server time-stamp for the time at which the mouse
8236 was at this position.
8238 Don't store anything if we don't have a valid set of values to report.
8240 This clears the mouse_moved flag, so we can wait for the next mouse
8244 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8247 Lisp_Object
*bar_window
;
8248 enum scroll_bar_part
*part
;
8250 unsigned long *time
;
8253 int ignore1
, ignore2
;
8254 WindowPtr wp
= FrontWindow ();
8256 Lisp_Object frame
, tail
;
8258 if (is_emacs_window(wp
))
8259 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8263 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8264 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8267 /* Clear the mouse-moved flag for every frame on this display. */
8268 FOR_EACH_FRAME (tail
, frame
)
8269 XFRAME (frame
)->mouse_moved
= 0;
8271 last_mouse_scroll_bar
= Qnil
;
8273 #if TARGET_API_MAC_CARBON
8274 SetPort (GetWindowPort (wp
));
8279 GetMouse (&mouse_pos
);
8281 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8282 &last_mouse_glyph
, insist
);
8285 *part
= scroll_bar_handle
;
8287 XSETINT (*x
, mouse_pos
.h
);
8288 XSETINT (*y
, mouse_pos
.v
);
8289 *time
= last_mouse_movement_time
;
8296 /************************************************************************
8297 Scroll bars, general
8298 ************************************************************************/
8300 /* Create a scroll bar and return the scroll bar vector for it. W is
8301 the Emacs window on which to create the scroll bar. TOP, LEFT,
8302 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8305 static struct scroll_bar
*
8306 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8308 int top
, left
, width
, height
, disp_top
, disp_height
;
8310 struct frame
*f
= XFRAME (w
->frame
);
8311 struct scroll_bar
*bar
8312 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8320 r
.right
= left
+ width
;
8321 r
.bottom
= disp_top
+ disp_height
;
8323 #ifdef TARGET_API_MAC_CARBON
8324 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8325 kControlScrollBarProc
, 0L);
8327 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8330 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8331 SetControlReference (ch
, (long) bar
);
8333 XSETWINDOW (bar
->window
, w
);
8334 XSETINT (bar
->top
, top
);
8335 XSETINT (bar
->left
, left
);
8336 XSETINT (bar
->width
, width
);
8337 XSETINT (bar
->height
, height
);
8338 XSETINT (bar
->start
, 0);
8339 XSETINT (bar
->end
, 0);
8340 bar
->dragging
= Qnil
;
8342 /* Add bar to its frame's list of scroll bars. */
8343 bar
->next
= FRAME_SCROLL_BARS (f
);
8345 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8346 if (!NILP (bar
->next
))
8347 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8354 /* Draw BAR's handle in the proper position.
8356 If the handle is already drawn from START to END, don't bother
8357 redrawing it, unless REBUILD is non-zero; in that case, always
8358 redraw it. (REBUILD is handy for drawing the handle after expose
8361 Normally, we want to constrain the start and end of the handle to
8362 fit inside its rectangle, but if the user is dragging the scroll
8363 bar handle, we want to let them drag it down all the way, so that
8364 the bar's top is as far down as it goes; otherwise, there's no way
8365 to move to the very end of the buffer. */
8368 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8369 struct scroll_bar
*bar
;
8373 int dragging
= ! NILP (bar
->dragging
);
8374 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8375 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8376 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8377 int length
= end
- start
;
8379 /* If the display is already accurate, do nothing. */
8381 && start
== XINT (bar
->start
)
8382 && end
== XINT (bar
->end
))
8387 /* Make sure the values are reasonable, and try to preserve the
8388 distance between start and end. */
8391 else if (start
> top_range
)
8393 end
= start
+ length
;
8397 else if (end
> top_range
&& ! dragging
)
8400 /* Store the adjusted setting in the scroll bar. */
8401 XSETINT (bar
->start
, start
);
8402 XSETINT (bar
->end
, end
);
8404 /* Clip the end position, just for display. */
8405 if (end
> top_range
)
8408 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8409 top positions, to make sure the handle is always at least that
8410 many pixels tall. */
8411 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8413 SetControlMinimum (ch
, 0);
8414 /* Don't inadvertently activate deactivated scroll bars */
8415 if (GetControlMaximum (ch
) != -1)
8416 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8418 SetControlValue (ch
, start
);
8419 #if TARGET_API_MAC_CARBON
8420 SetControlViewSize (ch
, end
- start
);
8427 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8431 x_scroll_bar_remove (bar
)
8432 struct scroll_bar
*bar
;
8434 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8438 /* Destroy the Mac scroll bar control */
8439 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8441 /* Disassociate this scroll bar from its window. */
8442 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8447 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8448 that we are displaying PORTION characters out of a total of WHOLE
8449 characters, starting at POSITION. If WINDOW has no scroll bar,
8452 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8454 int portion
, whole
, position
;
8456 struct frame
*f
= XFRAME (w
->frame
);
8457 struct scroll_bar
*bar
;
8458 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8459 int window_x
, window_y
, window_width
, window_height
;
8461 /* Get window dimensions. */
8462 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8467 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8469 height
= window_height
;
8471 /* Compute the left edge of the scroll bar area. */
8472 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8473 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8475 left
= XFASTINT (w
->left
);
8476 left
*= CANON_X_UNIT (f
);
8477 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8479 /* Compute the width of the scroll bar which might be less than
8480 the width of the area reserved for the scroll bar. */
8481 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8482 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8486 /* Compute the left edge of the scroll bar. */
8487 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8488 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8490 sb_left
= left
+ (width
- sb_width
) / 2;
8492 /* Adjustments according to Inside Macintosh to make it look nice */
8494 disp_height
= height
;
8500 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8506 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8509 /* Does the scroll bar exist yet? */
8510 if (NILP (w
->vertical_scroll_bar
))
8513 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8514 left
, top
, width
, height
, 0);
8516 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8518 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8522 /* It may just need to be moved and resized. */
8525 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8526 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8530 /* If already correctly positioned, do nothing. */
8531 if (XINT (bar
->left
) == sb_left
8532 && XINT (bar
->top
) == top
8533 && XINT (bar
->width
) == sb_width
8534 && XINT (bar
->height
) == height
)
8538 /* Clear areas not covered by the scroll bar because it's not as
8539 wide as the area reserved for it . This makes sure a
8540 previous mode line display is cleared after C-x 2 C-x 1, for
8542 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8543 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8544 left
, top
, area_width
, height
, 0);
8547 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8548 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8549 sb_left
- 1, top
, 1, height
, 0);
8553 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8554 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8558 /* Remember new settings. */
8559 XSETINT (bar
->left
, sb_left
);
8560 XSETINT (bar
->top
, top
);
8561 XSETINT (bar
->width
, sb_width
);
8562 XSETINT (bar
->height
, height
);
8568 /* Set the scroll bar's current state, unless we're currently being
8570 if (NILP (bar
->dragging
))
8572 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8575 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8578 int start
= ((double) position
* top_range
) / whole
;
8579 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8580 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8586 /* The following three hooks are used when we're doing a thorough
8587 redisplay of the frame. We don't explicitly know which scroll bars
8588 are going to be deleted, because keeping track of when windows go
8589 away is a real pain - "Can you say set-window-configuration, boys
8590 and girls?" Instead, we just assert at the beginning of redisplay
8591 that *all* scroll bars are to be removed, and then save a scroll bar
8592 from the fiery pit when we actually redisplay its window. */
8594 /* Arrange for all scroll bars on FRAME to be removed at the next call
8595 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8596 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8599 XTcondemn_scroll_bars (frame
)
8602 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8603 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8606 bar
= FRAME_SCROLL_BARS (frame
);
8607 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8608 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8609 XSCROLL_BAR (bar
)->prev
= Qnil
;
8610 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8611 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8612 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8617 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8618 Note that WINDOW isn't necessarily condemned at all. */
8621 XTredeem_scroll_bar (window
)
8622 struct window
*window
;
8624 struct scroll_bar
*bar
;
8626 /* We can't redeem this window's scroll bar if it doesn't have one. */
8627 if (NILP (window
->vertical_scroll_bar
))
8630 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8632 /* Unlink it from the condemned list. */
8634 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8636 if (NILP (bar
->prev
))
8638 /* If the prev pointer is nil, it must be the first in one of
8640 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8641 /* It's not condemned. Everything's fine. */
8643 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8644 window
->vertical_scroll_bar
))
8645 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8647 /* If its prev pointer is nil, it must be at the front of
8648 one or the other! */
8652 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8654 if (! NILP (bar
->next
))
8655 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8657 bar
->next
= FRAME_SCROLL_BARS (f
);
8659 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8660 if (! NILP (bar
->next
))
8661 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8665 /* Remove all scroll bars on FRAME that haven't been saved since the
8666 last call to `*condemn_scroll_bars_hook'. */
8669 XTjudge_scroll_bars (f
)
8672 Lisp_Object bar
, next
;
8674 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8676 /* Clear out the condemned list now so we won't try to process any
8677 more events on the hapless scroll bars. */
8678 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8680 for (; ! NILP (bar
); bar
= next
)
8682 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8684 x_scroll_bar_remove (b
);
8687 b
->next
= b
->prev
= Qnil
;
8690 /* Now there should be no references to the condemned scroll bars,
8691 and they should get garbage-collected. */
8696 activate_scroll_bars (frame
)
8702 bar
= FRAME_SCROLL_BARS (frame
);
8703 while (! NILP (bar
))
8705 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8706 #ifdef TARGET_API_MAC_CARBON
8707 ActivateControl (ch
);
8709 SetControlMaximum (ch
,
8710 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8711 XINT (XSCROLL_BAR (bar
)
8714 bar
= XSCROLL_BAR (bar
)->next
;
8720 deactivate_scroll_bars (frame
)
8726 bar
= FRAME_SCROLL_BARS (frame
);
8727 while (! NILP (bar
))
8729 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8730 #ifdef TARGET_API_MAC_CARBON
8731 DeactivateControl (ch
);
8733 SetControlMaximum (ch
, XINT (-1));
8735 bar
= XSCROLL_BAR (bar
)->next
;
8739 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8740 is set to something other than NO_EVENT, it is enqueued.
8742 This may be called from a signal handler, so we have to ignore GC
8746 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8747 struct scroll_bar
*bar
;
8750 struct input_event
*bufp
;
8752 if (! GC_WINDOWP (bar
->window
))
8755 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
8756 bufp
->frame_or_window
= bar
->window
;
8759 bar
->dragging
= Qnil
;
8763 case kControlUpButtonPart
:
8764 bufp
->part
= scroll_bar_up_arrow
;
8766 case kControlDownButtonPart
:
8767 bufp
->part
= scroll_bar_down_arrow
;
8769 case kControlPageUpPart
:
8770 bufp
->part
= scroll_bar_above_handle
;
8772 case kControlPageDownPart
:
8773 bufp
->part
= scroll_bar_below_handle
;
8775 #ifdef TARGET_API_MAC_CARBON
8778 case kControlIndicatorPart
:
8780 if (er
->what
== mouseDown
)
8781 bar
->dragging
= make_number (0);
8782 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8783 bufp
->part
= scroll_bar_handle
;
8789 /* Handle some mouse motion while someone is dragging the scroll bar.
8791 This may be called from a signal handler, so we have to ignore GC
8795 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8796 struct scroll_bar
*bar
;
8800 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8802 last_mouse_movement_time
= t
;
8805 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8807 /* If we're dragging the bar, display it. */
8808 if (! GC_NILP (bar
->dragging
))
8810 /* Where should the handle be now? */
8811 int new_start
= y_pos
- 24;
8813 if (new_start
!= XINT (bar
->start
))
8815 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8817 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8823 /* Return information to the user about the current position of the
8824 mouse on the scroll bar. */
8827 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8829 Lisp_Object
*bar_window
;
8830 enum scroll_bar_part
*part
;
8832 unsigned long *time
;
8834 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8835 WindowPtr wp
= FrontWindow ();
8837 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8838 int win_y
, top_range
;
8840 #if TARGET_API_MAC_CARBON
8841 SetPort (GetWindowPort (wp
));
8846 GetMouse (&mouse_pos
);
8848 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8849 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8851 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8855 if (! NILP (bar
->dragging
))
8856 win_y
-= XINT (bar
->dragging
);
8860 if (win_y
> top_range
)
8864 *bar_window
= bar
->window
;
8866 if (! NILP (bar
->dragging
))
8867 *part
= scroll_bar_handle
;
8868 else if (win_y
< XINT (bar
->start
))
8869 *part
= scroll_bar_above_handle
;
8870 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8871 *part
= scroll_bar_handle
;
8873 *part
= scroll_bar_below_handle
;
8875 XSETINT (*x
, win_y
);
8876 XSETINT (*y
, top_range
);
8879 last_mouse_scroll_bar
= Qnil
;
8881 *time
= last_mouse_movement_time
;
8884 /***********************************************************************
8886 ***********************************************************************/
8888 /* Notice if the text cursor of window W has been overwritten by a
8889 drawing operation that outputs glyphs starting at START_X and
8890 ending at END_X in the line given by output_cursor.vpos.
8891 Coordinates are area-relative. END_X < 0 means all the rest
8892 of the line after START_X has been written. */
8895 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8897 enum glyph_row_area area
;
8900 if (area
== TEXT_AREA
8901 && w
->phys_cursor_on_p
8902 && y0
<= w
->phys_cursor
.y
8903 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8904 && x0
<= w
->phys_cursor
.x
8905 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8906 w
->phys_cursor_on_p
= 0;
8910 /* Set clipping for output in glyph row ROW. W is the window in which
8911 we operate. GC is the graphics context to set clipping in.
8912 WHOLE_LINE_P non-zero means include the areas used for truncation
8913 mark display and alike in the clipping rectangle.
8915 ROW may be a text row or, e.g., a mode line. Text rows must be
8916 clipped to the interior of the window dedicated to text display,
8917 mode lines must be clipped to the whole window. */
8920 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8922 struct glyph_row
*row
;
8926 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8928 int window_x
, window_y
, window_width
, window_height
;
8930 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8932 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8933 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8934 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8935 clip_rect
.right
= clip_rect
.left
+ window_width
;
8936 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8938 /* If clipping to the whole line, including trunc marks, extend
8939 the rectangle to the left and increase its width. */
8942 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8943 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8946 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8950 /* Draw a hollow box cursor on window W in glyph row ROW. */
8953 x_draw_hollow_cursor (w
, row
)
8955 struct glyph_row
*row
;
8957 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8958 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8959 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8962 struct glyph
*cursor_glyph
;
8965 /* Compute frame-relative coordinates from window-relative
8967 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8968 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8969 + row
->ascent
- w
->phys_cursor_ascent
);
8970 h
= row
->height
- 1;
8972 /* Get the glyph the cursor is on. If we can't tell because
8973 the current matrix is invalid or such, give up. */
8974 cursor_glyph
= get_phys_cursor_glyph (w
);
8975 if (cursor_glyph
== NULL
)
8978 /* Compute the width of the rectangle to draw. If on a stretch
8979 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8980 rectangle as wide as the glyph, but use a canonical character
8982 wd
= cursor_glyph
->pixel_width
- 1;
8983 if (cursor_glyph
->type
== STRETCH_GLYPH
8984 && !x_stretch_cursor_p
)
8985 wd
= min (CANON_X_UNIT (f
), wd
);
8987 /* The foreground of cursor_gc is typically the same as the normal
8988 background color, which can cause the cursor box to be invisible. */
8989 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8990 if (dpyinfo
->scratch_cursor_gc
)
8991 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8993 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8994 GCForeground
, &xgcv
);
8995 gc
= dpyinfo
->scratch_cursor_gc
;
8997 /* Set clipping, draw the rectangle, and reset clipping again. */
8998 x_clip_to_row (w
, row
, gc
, 0);
8999 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
9000 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9004 /* Draw a bar cursor on window W in glyph row ROW.
9006 Implementation note: One would like to draw a bar cursor with an
9007 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9008 Unfortunately, I didn't find a font yet that has this property set.
9012 x_draw_bar_cursor (w
, row
, width
)
9014 struct glyph_row
*row
;
9017 /* If cursor hpos is out of bounds, don't draw garbage. This can
9018 happen in mini-buffer windows when switching between echo area
9019 glyphs and mini-buffer. */
9020 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9022 struct frame
*f
= XFRAME (w
->frame
);
9023 struct glyph
*cursor_glyph
;
9031 cursor_glyph
= get_phys_cursor_glyph (w
);
9032 if (cursor_glyph
== NULL
)
9035 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
9036 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9037 mask
= GCForeground
| GCBackground
;
9038 dpy
= FRAME_MAC_DISPLAY (f
);
9039 window
= FRAME_MAC_WINDOW (f
);
9040 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9043 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9046 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9047 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9051 width
= FRAME_CURSOR_WIDTH (f
);
9053 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9054 x_clip_to_row (w
, row
, gc
, 0);
9055 XFillRectangle (dpy
, window
, gc
,
9057 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9058 min (cursor_glyph
->pixel_width
, width
),
9060 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9065 /* Clear the cursor of window W to background color, and mark the
9066 cursor as not shown. This is used when the text where the cursor
9067 is is about to be rewritten. */
9073 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9074 x_update_window_cursor (w
, 0);
9078 /* Draw the cursor glyph of window W in glyph row ROW. See the
9079 comment of x_draw_glyphs for the meaning of HL. */
9082 x_draw_phys_cursor_glyph (w
, row
, hl
)
9084 struct glyph_row
*row
;
9085 enum draw_glyphs_face hl
;
9087 /* If cursor hpos is out of bounds, don't draw garbage. This can
9088 happen in mini-buffer windows when switching between echo area
9089 glyphs and mini-buffer. */
9090 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9092 int on_p
= w
->phys_cursor_on_p
;
9093 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9094 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9096 w
->phys_cursor_on_p
= on_p
;
9098 /* When we erase the cursor, and ROW is overlapped by other
9099 rows, make sure that these overlapping parts of other rows
9101 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9103 if (row
> w
->current_matrix
->rows
9104 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9105 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9107 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9108 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9109 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9115 /* Erase the image of a cursor of window W from the screen. */
9118 x_erase_phys_cursor (w
)
9121 struct frame
*f
= XFRAME (w
->frame
);
9122 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9123 int hpos
= w
->phys_cursor
.hpos
;
9124 int vpos
= w
->phys_cursor
.vpos
;
9125 int mouse_face_here_p
= 0;
9126 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9127 struct glyph_row
*cursor_row
;
9128 struct glyph
*cursor_glyph
;
9129 enum draw_glyphs_face hl
;
9131 /* No cursor displayed or row invalidated => nothing to do on the
9133 if (w
->phys_cursor_type
== NO_CURSOR
)
9134 goto mark_cursor_off
;
9136 /* VPOS >= active_glyphs->nrows means that window has been resized.
9137 Don't bother to erase the cursor. */
9138 if (vpos
>= active_glyphs
->nrows
)
9139 goto mark_cursor_off
;
9141 /* If row containing cursor is marked invalid, there is nothing we
9143 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9144 if (!cursor_row
->enabled_p
)
9145 goto mark_cursor_off
;
9147 /* If row is completely invisible, don't attempt to delete a cursor which
9148 isn't there. This may happen if cursor is at top of window, and
9149 we switch to a buffer with a header line in that window. */
9150 if (cursor_row
->visible_height
<= 0)
9151 goto mark_cursor_off
;
9153 /* This can happen when the new row is shorter than the old one.
9154 In this case, either x_draw_glyphs or clear_end_of_line
9155 should have cleared the cursor. Note that we wouldn't be
9156 able to erase the cursor in this case because we don't have a
9157 cursor glyph at hand. */
9158 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9159 goto mark_cursor_off
;
9161 /* If the cursor is in the mouse face area, redisplay that when
9162 we clear the cursor. */
9163 if (! NILP (dpyinfo
->mouse_face_window
)
9164 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9165 && (vpos
> dpyinfo
->mouse_face_beg_row
9166 || (vpos
== dpyinfo
->mouse_face_beg_row
9167 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9168 && (vpos
< dpyinfo
->mouse_face_end_row
9169 || (vpos
== dpyinfo
->mouse_face_end_row
9170 && hpos
< dpyinfo
->mouse_face_end_col
))
9171 /* Don't redraw the cursor's spot in mouse face if it is at the
9172 end of a line (on a newline). The cursor appears there, but
9173 mouse highlighting does not. */
9174 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9175 mouse_face_here_p
= 1;
9177 /* Maybe clear the display under the cursor. */
9178 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9181 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9183 cursor_glyph
= get_phys_cursor_glyph (w
);
9184 if (cursor_glyph
== NULL
)
9185 goto mark_cursor_off
;
9187 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9189 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9191 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9193 cursor_glyph
->pixel_width
,
9194 cursor_row
->visible_height
,
9198 /* Erase the cursor by redrawing the character underneath it. */
9199 if (mouse_face_here_p
)
9200 hl
= DRAW_MOUSE_FACE
;
9202 hl
= DRAW_NORMAL_TEXT
;
9203 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9206 w
->phys_cursor_on_p
= 0;
9207 w
->phys_cursor_type
= NO_CURSOR
;
9211 /* Non-zero if physical cursor of window W is within mouse face. */
9214 cursor_in_mouse_face_p (w
)
9217 struct mac_display_info
*dpyinfo
9218 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9219 int in_mouse_face
= 0;
9221 if (WINDOWP (dpyinfo
->mouse_face_window
)
9222 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9224 int hpos
= w
->phys_cursor
.hpos
;
9225 int vpos
= w
->phys_cursor
.vpos
;
9227 if (vpos
>= dpyinfo
->mouse_face_beg_row
9228 && vpos
<= dpyinfo
->mouse_face_end_row
9229 && (vpos
> dpyinfo
->mouse_face_beg_row
9230 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9231 && (vpos
< dpyinfo
->mouse_face_end_row
9232 || hpos
< dpyinfo
->mouse_face_end_col
9233 || dpyinfo
->mouse_face_past_end
))
9237 return in_mouse_face
;
9241 /* Display or clear cursor of window W. If ON is zero, clear the
9242 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9243 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9246 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9248 int on
, hpos
, vpos
, x
, y
;
9250 struct frame
*f
= XFRAME (w
->frame
);
9251 int new_cursor_type
;
9252 int new_cursor_width
;
9253 struct glyph_matrix
*current_glyphs
;
9254 struct glyph_row
*glyph_row
;
9255 struct glyph
*glyph
;
9257 /* This is pointless on invisible frames, and dangerous on garbaged
9258 windows and frames; in the latter case, the frame or window may
9259 be in the midst of changing its size, and x and y may be off the
9261 if (! FRAME_VISIBLE_P (f
)
9262 || FRAME_GARBAGED_P (f
)
9263 || vpos
>= w
->current_matrix
->nrows
9264 || hpos
>= w
->current_matrix
->matrix_w
)
9267 /* If cursor is off and we want it off, return quickly. */
9268 if (!on
&& !w
->phys_cursor_on_p
)
9271 current_glyphs
= w
->current_matrix
;
9272 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9273 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9275 /* If cursor row is not enabled, we don't really know where to
9276 display the cursor. */
9277 if (!glyph_row
->enabled_p
)
9279 w
->phys_cursor_on_p
= 0;
9283 xassert (interrupt_input_blocked
);
9285 /* Set new_cursor_type to the cursor we want to be displayed. */
9286 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
);
9289 /* If cursor is currently being shown and we don't want it to be or
9290 it is in the wrong place, or the cursor type is not what we want,
9292 if (w
->phys_cursor_on_p
9294 || w
->phys_cursor
.x
!= x
9295 || w
->phys_cursor
.y
!= y
9296 || new_cursor_type
!= w
->phys_cursor_type
9297 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9298 && new_cursor_width
!= w
->phys_cursor_width
)))
9299 x_erase_phys_cursor (w
);
9301 /* If the cursor is now invisible and we want it to be visible,
9303 if (on
&& !w
->phys_cursor_on_p
)
9305 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9306 w
->phys_cursor_height
= glyph_row
->height
;
9308 /* Set phys_cursor_.* before x_draw_.* is called because some
9309 of them may need the information. */
9310 w
->phys_cursor
.x
= x
;
9311 w
->phys_cursor
.y
= glyph_row
->y
;
9312 w
->phys_cursor
.hpos
= hpos
;
9313 w
->phys_cursor
.vpos
= vpos
;
9314 w
->phys_cursor_type
= new_cursor_type
;
9315 w
->phys_cursor_width
= new_cursor_width
;
9316 w
->phys_cursor_on_p
= 1;
9318 switch (new_cursor_type
)
9320 case HOLLOW_BOX_CURSOR
:
9321 x_draw_hollow_cursor (w
, glyph_row
);
9324 case FILLED_BOX_CURSOR
:
9325 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9329 /* TODO. For now, just draw bar cursor. */
9331 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9344 /* Display the cursor on window W, or clear it. X and Y are window
9345 relative pixel coordinates. HPOS and VPOS are glyph matrix
9346 positions. If W is not the selected window, display a hollow
9347 cursor. ON non-zero means display the cursor at X, Y which
9348 correspond to HPOS, VPOS, otherwise it is cleared. */
9351 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9353 int on
, hpos
, vpos
, x
, y
;
9356 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9361 /* Display the cursor on window W, or clear it, according to ON_P.
9362 Don't change the cursor's position. */
9365 x_update_cursor (f
, on_p
)
9369 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9373 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9374 in the window tree rooted at W. */
9377 x_update_cursor_in_window_tree (w
, on_p
)
9383 if (!NILP (w
->hchild
))
9384 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9385 else if (!NILP (w
->vchild
))
9386 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9388 x_update_window_cursor (w
, on_p
);
9390 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9395 /* Switch the display of W's cursor on or off, according to the value
9399 x_update_window_cursor (w
, on
)
9403 /* Don't update cursor in windows whose frame is in the process
9404 of being deleted. */
9405 if (w
->current_matrix
)
9408 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9409 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9420 #if 0 /* MAC_TODO: no icon support yet. */
9422 x_bitmap_icon (f
, icon
)
9428 if (FRAME_W32_WINDOW (f
) == 0)
9432 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9433 else if (STRINGP (icon
))
9434 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9435 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9436 else if (SYMBOLP (icon
))
9440 if (EQ (icon
, intern ("application")))
9441 name
= (LPCTSTR
) IDI_APPLICATION
;
9442 else if (EQ (icon
, intern ("hand")))
9443 name
= (LPCTSTR
) IDI_HAND
;
9444 else if (EQ (icon
, intern ("question")))
9445 name
= (LPCTSTR
) IDI_QUESTION
;
9446 else if (EQ (icon
, intern ("exclamation")))
9447 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9448 else if (EQ (icon
, intern ("asterisk")))
9449 name
= (LPCTSTR
) IDI_ASTERISK
;
9450 else if (EQ (icon
, intern ("winlogo")))
9451 name
= (LPCTSTR
) IDI_WINLOGO
;
9455 hicon
= LoadIcon (NULL
, name
);
9463 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9468 #endif /* MAC_TODO */
9470 /************************************************************************
9472 ************************************************************************/
9474 /* Display Error Handling functions not used on W32. Listing them here
9475 helps diff stay in step when comparing w32term.c with xterm.c.
9477 x_error_catcher (display, error)
9478 x_catch_errors (dpy)
9479 x_catch_errors_unwind (old_val)
9480 x_check_errors (dpy, format)
9481 x_had_errors_p (dpy)
9482 x_clear_errors (dpy)
9483 x_uncatch_errors (dpy, count)
9485 x_connection_signal (signalnum)
9486 x_connection_closed (dpy, error_message)
9487 x_error_quitter (display, error)
9488 x_error_handler (display, error)
9489 x_io_error_quitter (display)
9494 /* Changing the font of the frame. */
9496 /* Give frame F the font named FONTNAME as its default font, and
9497 return the full name of that font. FONTNAME may be a wildcard
9498 pattern; in that case, we choose some font that fits the pattern.
9499 The return value shows which font we chose. */
9502 x_new_font (f
, fontname
)
9504 register char *fontname
;
9506 struct font_info
*fontp
9507 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9512 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9513 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9514 FRAME_FONTSET (f
) = -1;
9516 /* Compute the scroll bar width in character columns. */
9517 if (f
->scroll_bar_pixel_width
> 0)
9519 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9520 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9524 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9525 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9528 /* Now make the frame display the given font. */
9529 if (FRAME_MAC_WINDOW (f
) != 0)
9531 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9532 f
->output_data
.mac
->font
);
9533 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9534 f
->output_data
.mac
->font
);
9535 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9536 f
->output_data
.mac
->font
);
9538 frame_update_line_height (f
);
9539 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9540 x_set_window_size (f
, 0, f
->width
, f
->height
);
9543 /* If we are setting a new frame's font for the first time,
9544 there are no faces yet, so this font's height is the line height. */
9545 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9547 return build_string (fontp
->full_name
);
9550 /* Give frame F the fontset named FONTSETNAME as its default font, and
9551 return the full name of that fontset. FONTSETNAME may be a wildcard
9552 pattern; in that case, we choose some fontset that fits the pattern.
9553 The return value shows which fontset we chose. */
9556 x_new_fontset (f
, fontsetname
)
9560 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9566 if (FRAME_FONTSET (f
) == fontset
)
9567 /* This fontset is already set in frame F. There's nothing more
9569 return fontset_name (fontset
);
9571 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
9573 if (!STRINGP (result
))
9574 /* Can't load ASCII font. */
9577 /* Since x_new_font doesn't update any fontset information, do it now. */
9578 FRAME_FONTSET(f
) = fontset
;
9580 return build_string (fontsetname
);
9583 /* Compute actual fringe widths */
9586 x_compute_fringe_widths (f
, redraw
)
9590 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9591 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9592 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9594 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9595 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9596 int left_fringe_width
, right_fringe_width
;
9598 if (!NILP (left_fringe
))
9599 left_fringe
= Fcdr (left_fringe
);
9600 if (!NILP (right_fringe
))
9601 right_fringe
= Fcdr (right_fringe
);
9603 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9604 XINT (left_fringe
));
9605 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9606 XINT (right_fringe
));
9608 if (left_fringe_width
|| right_fringe_width
)
9610 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9611 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9612 int conf_wid
= left_wid
+ right_wid
;
9613 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9614 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9615 int real_wid
= cols
* font_wid
;
9616 if (left_wid
&& right_wid
)
9618 if (left_fringe_width
< 0)
9620 /* Left fringe width is fixed, adjust right fringe if necessary */
9621 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9622 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9624 else if (right_fringe_width
< 0)
9626 /* Right fringe width is fixed, adjust left fringe if necessary */
9627 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9628 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9632 /* Adjust both fringes with an equal amount.
9633 Note that we are doing integer arithmetic here, so don't
9634 lose a pixel if the total width is an odd number. */
9635 int fill
= real_wid
- conf_wid
;
9636 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9637 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9640 else if (left_fringe_width
)
9642 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9643 f
->output_data
.mac
->right_fringe_width
= 0;
9647 f
->output_data
.mac
->left_fringe_width
= 0;
9648 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9650 f
->output_data
.mac
->fringe_cols
= cols
;
9651 f
->output_data
.mac
->fringes_extra
= real_wid
;
9655 f
->output_data
.mac
->left_fringe_width
= 0;
9656 f
->output_data
.mac
->right_fringe_width
= 0;
9657 f
->output_data
.mac
->fringe_cols
= 0;
9658 f
->output_data
.mac
->fringes_extra
= 0;
9661 if (redraw
&& FRAME_VISIBLE_P (f
))
9662 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9663 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9664 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9668 /***********************************************************************
9669 TODO: W32 Input Methods
9670 ***********************************************************************/
9671 /* Listing missing functions from xterm.c helps diff stay in step.
9673 xim_destroy_callback (xim, client_data, call_data)
9674 xim_open_dpy (dpyinfo, resource_name)
9676 xim_instantiate_callback (display, client_data, call_data)
9677 xim_initialize (dpyinfo, resource_name)
9678 xim_close_dpy (dpyinfo)
9683 /* Calculate the absolute position in frame F
9684 from its current recorded position values and gravity. */
9687 x_calc_absolute_position (f
)
9691 int flags
= f
->output_data
.mac
->size_hint_flags
;
9695 /* Find the position of the outside upper-left corner of
9696 the inner window, with respect to the outer window. */
9697 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9700 GetPort (&savePort
);
9702 #if TARGET_API_MAC_CARBON
9703 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9705 SetPort (FRAME_MAC_WINDOW (f
));
9708 #if TARGET_API_MAC_CARBON
9712 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9713 SetPt(&pt
, r
.left
, r
.top
);
9715 #else /* not TARGET_API_MAC_CARBON */
9716 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9717 #endif /* not TARGET_API_MAC_CARBON */
9718 LocalToGlobal (&pt
);
9722 /* Treat negative positions as relative to the leftmost bottommost
9723 position that fits on the screen. */
9724 if (flags
& XNegative
)
9725 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9726 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9728 + f
->output_data
.mac
->left_pos
);
9729 /* NTEMACS_TODO: Subtract menubar height? */
9730 if (flags
& YNegative
)
9731 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9732 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9734 + f
->output_data
.mac
->top_pos
);
9735 /* The left_pos and top_pos
9736 are now relative to the top and left screen edges,
9737 so the flags should correspond. */
9738 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9741 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9742 to really change the position, and 0 when calling from
9743 x_make_frame_visible (in that case, XOFF and YOFF are the current
9744 position values). It is -1 when calling from x_set_frame_parameters,
9745 which means, do adjust for borders but don't change the gravity. */
9748 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9750 register int xoff
, yoff
;
9753 int modified_top
, modified_left
;
9755 if (change_gravity
> 0)
9757 f
->output_data
.mac
->top_pos
= yoff
;
9758 f
->output_data
.mac
->left_pos
= xoff
;
9759 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9761 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9763 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9764 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9766 x_calc_absolute_position (f
);
9769 x_wm_set_size_hint (f
, (long) 0, 0);
9771 modified_left
= f
->output_data
.mac
->left_pos
;
9772 modified_top
= f
->output_data
.mac
->top_pos
;
9774 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9775 modified_top
+ 42, false);
9780 /* Call this to change the size of frame F's x-window.
9781 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9782 for this size change and subsequent size changes.
9783 Otherwise we leave the window gravity unchanged. */
9786 x_set_window_size (f
, change_gravity
, cols
, rows
)
9791 int pixelwidth
, pixelheight
;
9795 check_frame_size (f
, &rows
, &cols
);
9796 f
->output_data
.mac
->vertical_scroll_bar_extra
9797 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9799 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9801 x_compute_fringe_widths (f
, 0);
9803 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9804 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9806 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9807 x_wm_set_size_hint (f
, (long) 0, 0);
9809 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9811 /* Now, strictly speaking, we can't be sure that this is accurate,
9812 but the window manager will get around to dealing with the size
9813 change request eventually, and we'll hear how it went when the
9814 ConfigureNotify event gets here.
9816 We could just not bother storing any of this information here,
9817 and let the ConfigureNotify event set everything up, but that
9818 might be kind of confusing to the Lisp code, since size changes
9819 wouldn't be reported in the frame parameters until some random
9820 point in the future when the ConfigureNotify event arrives.
9822 We pass 1 for DELAY since we can't run Lisp code inside of
9824 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9825 PIXEL_WIDTH (f
) = pixelwidth
;
9826 PIXEL_HEIGHT (f
) = pixelheight
;
9828 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9829 receive in the ConfigureNotify event; if we get what we asked
9830 for, then the event won't cause the screen to become garbaged, so
9831 we have to make sure to do it here. */
9832 SET_FRAME_GARBAGED (f
);
9834 XFlush (FRAME_X_DISPLAY (f
));
9836 /* If cursor was outside the new size, mark it as off. */
9837 mark_window_cursors_off (XWINDOW (f
->root_window
));
9839 /* Clear out any recollection of where the mouse highlighting was,
9840 since it might be in a place that's outside the new frame size.
9841 Actually checking whether it is outside is a pain in the neck,
9842 so don't try--just let the highlighting be done afresh with new size. */
9843 cancel_mouse_face (f
);
9848 /* Mouse warping. */
9850 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9853 x_set_mouse_position (f
, x
, y
)
9859 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9860 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9862 if (pix_x
< 0) pix_x
= 0;
9863 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9865 if (pix_y
< 0) pix_y
= 0;
9866 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9868 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9872 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9876 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9879 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9880 0, 0, 0, 0, pix_x
, pix_y
);
9886 /* focus shifting, raising and lowering. */
9889 x_focus_on_frame (f
)
9892 #if 0 /* This proves to be unpleasant. */
9896 /* I don't think that the ICCCM allows programs to do things like this
9897 without the interaction of the window manager. Whatever you end up
9898 doing with this code, do it to x_unfocus_frame too. */
9899 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9900 RevertToPointerRoot
, CurrentTime
);
9910 /* Raise frame F. */
9915 if (f
->async_visible
)
9916 SelectWindow (FRAME_MAC_WINDOW (f
));
9919 /* Lower frame F. */
9924 if (f
->async_visible
)
9925 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9929 XTframe_raise_lower (f
, raise_flag
)
9939 /* Change of visibility. */
9941 /* This tries to wait until the frame is really visible.
9942 However, if the window manager asks the user where to position
9943 the frame, this will return before the user finishes doing that.
9944 The frame will not actually be visible at that time,
9945 but it will become visible later when the window manager
9946 finishes with it. */
9949 x_make_frame_visible (f
)
9953 int original_top
, original_left
;
9957 if (! FRAME_VISIBLE_P (f
))
9959 /* We test FRAME_GARBAGED_P here to make sure we don't
9960 call x_set_offset a second time
9961 if we get to x_make_frame_visible a second time
9962 before the window gets really visible. */
9963 if (! FRAME_ICONIFIED_P (f
)
9964 && ! f
->output_data
.mac
->asked_for_visible
)
9965 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
9966 f
->output_data
.mac
->top_pos
, 0);
9968 f
->output_data
.mac
->asked_for_visible
= 1;
9970 ShowWindow (FRAME_MAC_WINDOW (f
));
9973 XFlush (FRAME_MAC_DISPLAY (f
));
9975 #if 0 /* MAC_TODO */
9976 /* Synchronize to ensure Emacs knows the frame is visible
9977 before we do anything else. We do this loop with input not blocked
9978 so that incoming events are handled. */
9983 /* This must come after we set COUNT. */
9986 XSETFRAME (frame
, f
);
9988 /* Wait until the frame is visible. Process X events until a
9989 MapNotify event has been seen, or until we think we won't get a
9990 MapNotify at all.. */
9991 for (count
= input_signal_count
+ 10;
9992 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9994 /* Force processing of queued events. */
9997 /* Machines that do polling rather than SIGIO have been
9998 observed to go into a busy-wait here. So we'll fake an
9999 alarm signal to let the handler know that there's something
10000 to be read. We used to raise a real alarm, but it seems
10001 that the handler isn't always enabled here. This is
10003 if (input_polling_used ())
10005 /* It could be confusing if a real alarm arrives while
10006 processing the fake one. Turn it off and let the
10007 handler reset it. */
10008 extern void poll_for_input_1
P_ ((void));
10009 int old_poll_suppress_count
= poll_suppress_count
;
10010 poll_suppress_count
= 1;
10011 poll_for_input_1 ();
10012 poll_suppress_count
= old_poll_suppress_count
;
10015 /* See if a MapNotify event has been processed. */
10016 FRAME_SAMPLE_VISIBILITY (f
);
10019 #endif /* MAC_TODO */
10022 /* Change from mapped state to withdrawn state. */
10024 /* Make the frame visible (mapped and not iconified). */
10027 x_make_frame_invisible (f
)
10030 /* Don't keep the highlight on an invisible frame. */
10031 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10032 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10036 HideWindow (FRAME_MAC_WINDOW (f
));
10038 /* We can't distinguish this from iconification
10039 just by the event that we get from the server.
10040 So we can't win using the usual strategy of letting
10041 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10042 and synchronize with the server to make sure we agree. */
10044 FRAME_ICONIFIED_P (f
) = 0;
10045 f
->async_visible
= 0;
10046 f
->async_iconified
= 0;
10051 /* Change window state from mapped to iconified. */
10054 x_iconify_frame (f
)
10057 /* Don't keep the highlight on an invisible frame. */
10058 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10059 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10062 /* Review: Since window is still visible in dock, still allow updates? */
10063 if (f
->async_iconified
)
10069 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
10075 /* Destroy the X window of frame F. */
10078 x_destroy_window (f
)
10081 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10085 DisposeWindow (FRAME_MAC_WINDOW (f
));
10087 free_frame_menubar (f
);
10088 free_frame_faces (f
);
10090 xfree (f
->output_data
.mac
);
10091 f
->output_data
.mac
= 0;
10092 if (f
== dpyinfo
->x_focus_frame
)
10093 dpyinfo
->x_focus_frame
= 0;
10094 if (f
== dpyinfo
->x_focus_event_frame
)
10095 dpyinfo
->x_focus_event_frame
= 0;
10096 if (f
== dpyinfo
->x_highlight_frame
)
10097 dpyinfo
->x_highlight_frame
= 0;
10099 dpyinfo
->reference_count
--;
10101 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10103 dpyinfo
->mouse_face_beg_row
10104 = dpyinfo
->mouse_face_beg_col
= -1;
10105 dpyinfo
->mouse_face_end_row
10106 = dpyinfo
->mouse_face_end_col
= -1;
10107 dpyinfo
->mouse_face_window
= Qnil
;
10108 dpyinfo
->mouse_face_deferred_gc
= 0;
10109 dpyinfo
->mouse_face_mouse_frame
= 0;
10115 /* Setting window manager hints. */
10117 /* Set the normal size hints for the window manager, for frame F.
10118 FLAGS is the flags word to use--or 0 meaning preserve the flags
10119 that the window now has.
10120 If USER_POSITION is nonzero, we set the USPosition
10121 flag (this is useful when FLAGS is 0). */
10123 x_wm_set_size_hint (f
, flags
, user_position
)
10128 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10129 XSizeHints size_hints
;
10131 #ifdef USE_X_TOOLKIT
10134 Dimension widget_width
, widget_height
;
10135 Window window
= XtWindow (f
->output_data
.x
->widget
);
10136 #else /* not USE_X_TOOLKIT */
10137 Window window
= FRAME_X_WINDOW (f
);
10138 #endif /* not USE_X_TOOLKIT */
10140 /* Setting PMaxSize caused various problems. */
10141 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10143 size_hints
.x
= f
->output_data
.x
->left_pos
;
10144 size_hints
.y
= f
->output_data
.x
->top_pos
;
10146 #ifdef USE_X_TOOLKIT
10147 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10148 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10149 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10150 size_hints
.height
= widget_height
;
10151 size_hints
.width
= widget_width
;
10152 #else /* not USE_X_TOOLKIT */
10153 size_hints
.height
= PIXEL_HEIGHT (f
);
10154 size_hints
.width
= PIXEL_WIDTH (f
);
10155 #endif /* not USE_X_TOOLKIT */
10157 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10158 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10159 size_hints
.max_width
10160 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10161 size_hints
.max_height
10162 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10164 /* Calculate the base and minimum sizes.
10166 (When we use the X toolkit, we don't do it here.
10167 Instead we copy the values that the widgets are using, below.) */
10168 #ifndef USE_X_TOOLKIT
10170 int base_width
, base_height
;
10171 int min_rows
= 0, min_cols
= 0;
10173 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10174 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10176 check_frame_size (f
, &min_rows
, &min_cols
);
10178 /* The window manager uses the base width hints to calculate the
10179 current number of rows and columns in the frame while
10180 resizing; min_width and min_height aren't useful for this
10181 purpose, since they might not give the dimensions for a
10182 zero-row, zero-column frame.
10184 We use the base_width and base_height members if we have
10185 them; otherwise, we set the min_width and min_height members
10186 to the size for a zero x zero frame. */
10189 size_hints
.flags
|= PBaseSize
;
10190 size_hints
.base_width
= base_width
;
10191 size_hints
.base_height
= base_height
;
10192 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10193 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10195 size_hints
.min_width
= base_width
;
10196 size_hints
.min_height
= base_height
;
10200 /* If we don't need the old flags, we don't need the old hint at all. */
10203 size_hints
.flags
|= flags
;
10206 #endif /* not USE_X_TOOLKIT */
10209 XSizeHints hints
; /* Sometimes I hate X Windows... */
10210 long supplied_return
;
10214 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10217 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10220 #ifdef USE_X_TOOLKIT
10221 size_hints
.base_height
= hints
.base_height
;
10222 size_hints
.base_width
= hints
.base_width
;
10223 size_hints
.min_height
= hints
.min_height
;
10224 size_hints
.min_width
= hints
.min_width
;
10228 size_hints
.flags
|= flags
;
10233 if (hints
.flags
& PSize
)
10234 size_hints
.flags
|= PSize
;
10235 if (hints
.flags
& PPosition
)
10236 size_hints
.flags
|= PPosition
;
10237 if (hints
.flags
& USPosition
)
10238 size_hints
.flags
|= USPosition
;
10239 if (hints
.flags
& USSize
)
10240 size_hints
.flags
|= USSize
;
10244 #ifndef USE_X_TOOLKIT
10249 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10250 size_hints
.flags
|= PWinGravity
;
10254 size_hints
.flags
&= ~ PPosition
;
10255 size_hints
.flags
|= USPosition
;
10257 #endif /* PWinGravity */
10260 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10262 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10264 #endif /* MAC_TODO */
10267 #if 0 /* MAC_TODO: hide application instead of iconify? */
10268 /* Used for IconicState or NormalState */
10271 x_wm_set_window_state (f
, state
)
10275 #ifdef USE_X_TOOLKIT
10278 XtSetArg (al
[0], XtNinitialState
, state
);
10279 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10280 #else /* not USE_X_TOOLKIT */
10281 Window window
= FRAME_X_WINDOW (f
);
10283 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10284 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10286 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10287 #endif /* not USE_X_TOOLKIT */
10291 x_wm_set_icon_pixmap (f
, pixmap_id
)
10295 Pixmap icon_pixmap
;
10297 #ifndef USE_X_TOOLKIT
10298 Window window
= FRAME_X_WINDOW (f
);
10303 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10304 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10308 /* It seems there is no way to turn off use of an icon pixmap.
10309 The following line does it, only if no icon has yet been created,
10310 for some window managers. But with mwm it crashes.
10311 Some people say it should clear the IconPixmapHint bit in this case,
10312 but that doesn't work, and the X consortium said it isn't the
10313 right thing at all. Since there is no way to win,
10314 best to explicitly give up. */
10316 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10322 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10326 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10327 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10330 #else /* not USE_X_TOOLKIT */
10332 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10333 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10335 #endif /* not USE_X_TOOLKIT */
10338 #endif /* MAC_TODO */
10341 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10343 int icon_x
, icon_y
;
10345 #if 0 /* MAC_TODO: no icons on Mac */
10346 #ifdef USE_X_TOOLKIT
10347 Window window
= XtWindow (f
->output_data
.x
->widget
);
10349 Window window
= FRAME_X_WINDOW (f
);
10352 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10353 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10354 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10356 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10357 #endif /* MAC_TODO */
10361 /***********************************************************************
10363 ***********************************************************************/
10365 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10368 x_get_font_info (f
, font_idx
)
10372 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10375 /* the global font name table */
10376 char **font_name_table
= NULL
;
10377 int font_name_table_size
= 0;
10378 int font_name_count
= 0;
10380 /* compare two strings ignoring case */
10382 stricmp (const char *s
, const char *t
)
10384 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10387 return tolower (*s
) - tolower (*t
);
10390 /* compare two strings ignoring case and handling wildcard */
10392 wildstrieq (char *s1
, char *s2
)
10394 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10397 return stricmp (s1
, s2
) == 0;
10400 /* Assume parameter 1 is fully qualified, no wildcards. */
10402 mac_font_pattern_match (fontname
, pattern
)
10406 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10407 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10410 /* Copy fontname so we can modify it during comparison. */
10411 strcpy (font_name_copy
, fontname
);
10416 /* Turn pattern into a regexp and do a regexp match. */
10417 for (; *pattern
; pattern
++)
10419 if (*pattern
== '?')
10421 else if (*pattern
== '*')
10432 return (fast_c_string_match_ignore_case (build_string (regex
),
10433 font_name_copy
) >= 0);
10436 /* Two font specs are considered to match if their foundry, family,
10437 weight, slant, and charset match. */
10439 mac_font_match (char *mf
, char *xf
)
10441 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10442 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10444 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10445 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10446 return mac_font_pattern_match (mf
, xf
);
10448 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10449 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10450 return mac_font_pattern_match (mf
, xf
);
10452 return (wildstrieq (m_foundry
, x_foundry
)
10453 && wildstrieq (m_family
, x_family
)
10454 && wildstrieq (m_weight
, x_weight
)
10455 && wildstrieq (m_slant
, x_slant
)
10456 && wildstrieq (m_charset
, x_charset
))
10457 || mac_font_pattern_match (mf
, xf
);
10462 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10464 char foundry
[32], family
[32], cs
[32];
10465 char xf
[255], *result
, *p
;
10467 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10469 strcpy(foundry
, "Apple");
10470 strcpy(family
, name
);
10472 switch (scriptcode
)
10474 case smTradChinese
:
10475 strcpy(cs
, "big5-0");
10477 case smSimpChinese
:
10478 strcpy(cs
, "gb2312.1980-0");
10481 strcpy(cs
, "jisx0208.1983-sjis");
10484 /* Each Apple Japanese font is entered into the font table
10485 twice: once as a jisx0208.1983-sjis font and once as a
10486 jisx0201.1976-0 font. The latter can be used to display
10487 the ascii charset and katakana-jisx0201 charset. A
10488 negative script code signals that the name of this latter
10489 font is being built. */
10490 strcpy(cs
, "jisx0201.1976-0");
10493 strcpy(cs
, "ksc5601.1989-0");
10496 strcpy(cs
, "mac-roman");
10501 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10502 foundry
, family
, style
& bold
? "bold" : "medium",
10503 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10505 result
= (char *) xmalloc (strlen (xf
) + 1);
10506 strcpy (result
, xf
);
10507 for (p
= result
; *p
; p
++)
10513 /* Convert an X font spec to the corresponding mac font name, which
10514 can then be passed to GetFNum after conversion to a Pascal string.
10515 For ordinary Mac fonts, this should just be their names, like
10516 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10517 collection contain their charset designation in their names, like
10518 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10519 names are handled accordingly. */
10521 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10523 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10527 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10528 foundry
, family
, weight
, slant
, cs
) != 5 &&
10529 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10530 foundry
, family
, weight
, slant
, cs
) != 5)
10533 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10534 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10535 || strcmp (cs
, "jisx0201.1976-0") == 0
10536 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10537 strcpy(mf
, family
);
10539 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10544 add_font_name_table_entry (char *font_name
)
10546 if (font_name_table_size
== 0)
10548 font_name_table_size
= 16;
10549 font_name_table
= (char **)
10550 xmalloc (font_name_table_size
* sizeof (char *));
10552 else if (font_name_count
+ 1 >= font_name_table_size
)
10554 font_name_table_size
+= 16;
10555 font_name_table
= (char **)
10556 xrealloc (font_name_table
,
10557 font_name_table_size
* sizeof (char *));
10560 font_name_table
[font_name_count
++] = font_name
;
10563 /* Sets up the table font_name_table to contain the list of all fonts
10564 in the system the first time the table is used so that the Resource
10565 Manager need not be accessed every time this information is
10569 init_font_name_table ()
10571 #if TARGET_API_MAC_CARBON
10574 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10576 FMFontFamilyIterator ffi
;
10577 FMFontFamilyInstanceIterator ffii
;
10580 /* Create a dummy instance iterator here to avoid creating and
10581 destroying it in the loop. */
10582 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10584 /* Create an iterator to enumerate the font families. */
10585 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10588 FMDisposeFontFamilyInstanceIterator (&ffii
);
10592 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10600 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10604 sc
= FontToScript (ff
);
10606 /* Point the instance iterator at the current font family. */
10607 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10610 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
10614 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10616 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10618 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10620 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10626 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10628 if (smJapanese
== sc
)
10629 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10635 /* Dispose of the iterators. */
10636 FMDisposeFontFamilyIterator (&ffi
);
10637 FMDisposeFontFamilyInstanceIterator (&ffii
);
10641 #endif /* TARGET_API_MAC_CARBON */
10643 SInt16 fontnum
, old_fontnum
;
10644 int num_mac_fonts
= CountResources('FOND');
10646 Handle font_handle
, font_handle_2
;
10647 short id
, scriptcode
;
10650 struct FontAssoc
*fat
;
10651 struct AsscEntry
*assc_entry
;
10653 GetPort (&port
); /* save the current font number used */
10654 #if TARGET_API_MAC_CARBON
10655 old_fontnum
= GetPortTextFont (port
);
10657 old_fontnum
= port
->txFont
;
10660 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10662 font_handle
= GetIndResource ('FOND', i
);
10666 GetResInfo (font_handle
, &id
, &type
, name
);
10667 GetFNum (name
, &fontnum
);
10672 TextFont (fontnum
);
10673 scriptcode
= FontToScript (fontnum
);
10676 HLock (font_handle
);
10678 if (GetResourceSizeOnDisk (font_handle
)
10679 >= sizeof (struct FamRec
))
10681 fat
= (struct FontAssoc
*) (*font_handle
10682 + sizeof (struct FamRec
));
10684 = (struct AsscEntry
*) (*font_handle
10685 + sizeof (struct FamRec
)
10686 + sizeof (struct FontAssoc
));
10688 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10690 if (font_name_table_size
== 0)
10692 font_name_table_size
= 16;
10693 font_name_table
= (char **)
10694 xmalloc (font_name_table_size
* sizeof (char *));
10696 else if (font_name_count
>= font_name_table_size
)
10698 font_name_table_size
+= 16;
10699 font_name_table
= (char **)
10700 xrealloc (font_name_table
,
10701 font_name_table_size
* sizeof (char *));
10703 font_name_table
[font_name_count
++]
10704 = mac_to_x_fontname (name
,
10705 assc_entry
->fontSize
,
10706 assc_entry
->fontStyle
,
10708 /* Both jisx0208.1983-sjis and
10709 jisx0201.1976-sjis parts are contained in
10710 Apple Japanese (SJIS) font. */
10711 if (smJapanese
== scriptcode
)
10713 font_name_table
[font_name_count
++]
10714 = mac_to_x_fontname (name
,
10715 assc_entry
->fontSize
,
10716 assc_entry
->fontStyle
,
10722 HUnlock (font_handle
);
10723 font_handle_2
= GetNextFOND (font_handle
);
10724 ReleaseResource (font_handle
);
10725 font_handle
= font_handle_2
;
10727 while (ResError () == noErr
&& font_handle
);
10730 TextFont (old_fontnum
);
10731 #if TARGET_API_MAC_CARBON
10733 #endif /* TARGET_API_MAC_CARBON */
10737 /* Return a list of at most MAXNAMES font specs matching the one in
10738 PATTERN. Cache matching fonts for patterns in
10739 dpyinfo->name_list_element to avoid looking them up again by
10740 calling mac_font_pattern_match (slow). */
10743 x_list_fonts (struct frame
*f
,
10744 Lisp_Object pattern
,
10749 Lisp_Object newlist
= Qnil
, tem
, key
;
10752 struct gcpro gcpro1
, gcpro2
;
10753 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
10755 if (font_name_table
== NULL
) /* Initialize when first used. */
10756 init_font_name_table ();
10760 tem
= XCDR (dpyinfo
->name_list_element
);
10761 key
= Fcons (pattern
, make_number (maxnames
));
10763 newlist
= Fassoc (key
, tem
);
10764 if (!NILP (newlist
))
10766 newlist
= Fcdr_safe (newlist
);
10771 ptnstr
= SDATA (pattern
);
10773 GCPRO2 (pattern
, newlist
);
10775 /* Scan and matching bitmap fonts. */
10776 for (i
= 0; i
< font_name_count
; i
++)
10778 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10780 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10783 if (n_fonts
>= maxnames
)
10788 /* MAC_TODO: add code for matching outline fonts here */
10794 XSETCDR (dpyinfo
->name_list_element
,
10795 Fcons (Fcons (key
, newlist
),
10796 XCDR (dpyinfo
->name_list_element
)));
10806 /* Check that FONT is valid on frame F. It is if it can be found in F's
10810 x_check_font (f
, font
)
10815 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10817 xassert (font
!= NULL
);
10819 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10820 if (dpyinfo
->font_table
[i
].name
10821 && font
== dpyinfo
->font_table
[i
].font
)
10824 xassert (i
< dpyinfo
->n_fonts
);
10827 #endif /* GLYPH_DEBUG != 0 */
10829 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10830 Note: There are (broken) X fonts out there with invalid XFontStruct
10831 min_bounds contents. For example, handa@etl.go.jp reports that
10832 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10833 have font->min_bounds.width == 0. */
10836 x_font_min_bounds (font
, w
, h
)
10837 MacFontStruct
*font
;
10841 * TODO: Windows does not appear to offer min bound, only
10842 * average and maximum width, and maximum height.
10844 *h
= FONT_HEIGHT (font
);
10845 *w
= FONT_WIDTH (font
);
10849 /* Compute the smallest character width and smallest font height over
10850 all fonts available on frame F. Set the members smallest_char_width
10851 and smallest_font_height in F's x_display_info structure to
10852 the values computed. Value is non-zero if smallest_font_height or
10853 smallest_char_width become smaller than they were before. */
10856 x_compute_min_glyph_bounds (f
)
10860 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10861 MacFontStruct
*font
;
10862 int old_width
= dpyinfo
->smallest_char_width
;
10863 int old_height
= dpyinfo
->smallest_font_height
;
10865 dpyinfo
->smallest_font_height
= 100000;
10866 dpyinfo
->smallest_char_width
= 100000;
10868 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10869 if (dpyinfo
->font_table
[i
].name
)
10871 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10874 font
= (MacFontStruct
*) fontp
->font
;
10875 xassert (font
!= (MacFontStruct
*) ~0);
10876 x_font_min_bounds (font
, &w
, &h
);
10878 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10879 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10882 xassert (dpyinfo
->smallest_char_width
> 0
10883 && dpyinfo
->smallest_font_height
> 0);
10885 return (dpyinfo
->n_fonts
== 1
10886 || dpyinfo
->smallest_char_width
< old_width
10887 || dpyinfo
->smallest_font_height
< old_height
);
10891 /* Determine whether given string is a fully-specified XLFD: all 14
10892 fields are present, none is '*'. */
10895 is_fully_specified_xlfd (char *p
)
10903 for (i
= 0; i
< 13; i
++)
10905 q
= strchr (p
+ 1, '-');
10908 if (q
- p
== 2 && *(p
+ 1) == '*')
10913 if (strchr (p
+ 1, '-') != NULL
)
10916 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10923 const int kDefaultFontSize
= 9;
10926 /* XLoadQueryFont creates and returns an internal representation for a
10927 font in a MacFontStruct struct. There is really no concept
10928 corresponding to "loading" a font on the Mac. But we check its
10929 existence and find the font number and all other information for it
10930 and store them in the returned MacFontStruct. */
10932 static MacFontStruct
*
10933 XLoadQueryFont (Display
*dpy
, char *fontname
)
10935 int i
, size
, is_two_byte_font
, char_width
;
10938 SInt16 old_fontnum
, old_fontsize
;
10939 Style old_fontface
;
10942 Style fontface
= normal
;
10943 MacFontStruct
*font
;
10944 FontInfo the_fontinfo
;
10945 char s_weight
[7], c_slant
;
10947 if (is_fully_specified_xlfd (fontname
))
10951 for (i
= 0; i
< font_name_count
; i
++)
10952 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
10955 if (i
>= font_name_count
)
10958 name
= font_name_table
[i
];
10961 GetPort (&port
); /* save the current font number used */
10962 #if TARGET_API_MAC_CARBON
10963 old_fontnum
= GetPortTextFont (port
);
10964 old_fontsize
= GetPortTextSize (port
);
10965 old_fontface
= GetPortTextFace (port
);
10967 old_fontnum
= port
->txFont
;
10968 old_fontsize
= port
->txSize
;
10969 old_fontface
= port
->txFace
;
10972 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
10973 size
= kDefaultFontSize
;
10975 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
10976 if (strcmp (s_weight
, "bold") == 0)
10979 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
10980 if (c_slant
== 'i')
10981 fontface
|= italic
;
10983 x_font_name_to_mac_font_name (name
, mfontname
);
10984 c2pstr (mfontname
);
10985 GetFNum (mfontname
, &fontnum
);
10989 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
10991 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
10992 bcopy (name
, font
->fontname
, strlen (name
) + 1);
10994 font
->mac_fontnum
= fontnum
;
10995 font
->mac_fontsize
= size
;
10996 font
->mac_fontface
= fontface
;
10997 font
->mac_scriptcode
= FontToScript (fontnum
);
10999 /* Apple Japanese (SJIS) font is listed as both
11000 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
11001 (Roman script) in init_font_name_table (). The latter should be
11002 treated as a one-byte font. */
11007 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
11009 && 0 == strcmp (cs
, "jisx0201.1976-0"))
11010 font
->mac_scriptcode
= smRoman
;
11013 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
11014 font
->mac_scriptcode
== smTradChinese
||
11015 font
->mac_scriptcode
== smSimpChinese
||
11016 font
->mac_scriptcode
== smKorean
;
11018 TextFont (fontnum
);
11020 TextFace (fontface
);
11022 GetFontInfo (&the_fontinfo
);
11024 font
->ascent
= the_fontinfo
.ascent
;
11025 font
->descent
= the_fontinfo
.descent
;
11027 font
->min_byte1
= 0;
11028 if (is_two_byte_font
)
11029 font
->max_byte1
= 1;
11031 font
->max_byte1
= 0;
11032 font
->min_char_or_byte2
= 0x20;
11033 font
->max_char_or_byte2
= 0xff;
11035 if (is_two_byte_font
)
11037 /* Use the width of an "ideographic space" of that font because
11038 the_fontinfo.widMax returns the wrong width for some fonts. */
11039 switch (font
->mac_scriptcode
)
11042 char_width
= StringWidth("\p\x81\x40");
11044 case smTradChinese
:
11045 char_width
= StringWidth("\p\xa1\x40");
11047 case smSimpChinese
:
11048 char_width
= StringWidth("\p\xa1\xa1");
11051 char_width
= StringWidth("\p\xa1\xa1");
11056 /* Do this instead of use the_fontinfo.widMax, which incorrectly
11057 returns 15 for 12-point Monaco! */
11058 char_width
= CharWidth ('m');
11060 font
->max_bounds
.rbearing
= char_width
;
11061 font
->max_bounds
.lbearing
= 0;
11062 font
->max_bounds
.width
= char_width
;
11063 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
11064 font
->max_bounds
.descent
= the_fontinfo
.descent
;
11066 font
->min_bounds
= font
->max_bounds
;
11068 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
11069 font
->per_char
= NULL
;
11072 font
->per_char
= (XCharStruct
*)
11073 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
11077 for (c
= 0x20; c
<= 0xff; c
++)
11079 font
->per_char
[c
- 0x20] = font
->max_bounds
;
11080 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
11085 TextFont (old_fontnum
); /* restore previous font number, size and face */
11086 TextSize (old_fontsize
);
11087 TextFace (old_fontface
);
11093 /* Load font named FONTNAME of the size SIZE for frame F, and return a
11094 pointer to the structure font_info while allocating it dynamically.
11095 If SIZE is 0, load any size of font.
11096 If loading is failed, return NULL. */
11099 x_load_font (f
, fontname
, size
)
11101 register char *fontname
;
11104 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11105 Lisp_Object font_names
;
11107 /* Get a list of all the fonts that match this name. Once we
11108 have a list of matching fonts, we compare them against the fonts
11109 we already have by comparing names. */
11110 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
11112 if (!NILP (font_names
))
11117 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11118 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
11119 if (dpyinfo
->font_table
[i
].name
11120 && (!strcmp (dpyinfo
->font_table
[i
].name
,
11121 SDATA (XCAR (tail
)))
11122 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
11123 SDATA (XCAR (tail
)))))
11124 return (dpyinfo
->font_table
+ i
);
11127 /* Load the font and add it to the table. */
11130 struct MacFontStruct
*font
;
11131 struct font_info
*fontp
;
11132 unsigned long value
;
11135 /* If we have found fonts by x_list_font, load one of them. If
11136 not, we still try to load a font by the name given as FONTNAME
11137 because XListFonts (called in x_list_font) of some X server has
11138 a bug of not finding a font even if the font surely exists and
11139 is loadable by XLoadQueryFont. */
11140 if (size
> 0 && !NILP (font_names
))
11141 fontname
= (char *) SDATA (XCAR (font_names
));
11143 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
11147 /* Find a free slot in the font table. */
11148 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11149 if (dpyinfo
->font_table
[i
].name
== NULL
)
11152 /* If no free slot found, maybe enlarge the font table. */
11153 if (i
== dpyinfo
->n_fonts
11154 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
11157 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
11158 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
11159 dpyinfo
->font_table
11160 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
11163 fontp
= dpyinfo
->font_table
+ i
;
11164 if (i
== dpyinfo
->n_fonts
)
11165 ++dpyinfo
->n_fonts
;
11167 /* Now fill in the slots of *FONTP. */
11169 fontp
->font
= font
;
11170 fontp
->font_idx
= i
;
11171 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
11172 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
11174 fontp
->full_name
= fontp
->name
;
11176 fontp
->size
= font
->max_bounds
.width
;
11177 fontp
->height
= FONT_HEIGHT (font
);
11179 /* For some font, ascent and descent in max_bounds field is
11180 larger than the above value. */
11181 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
11182 if (max_height
> fontp
->height
)
11183 fontp
->height
= max_height
;
11186 /* The slot `encoding' specifies how to map a character
11187 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
11188 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
11189 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
11190 2:0xA020..0xFF7F). For the moment, we don't know which charset
11191 uses this font. So, we set information in fontp->encoding[1]
11192 which is never used by any charset. If mapping can't be
11193 decided, set FONT_ENCODING_NOT_DECIDED. */
11194 if (font
->mac_scriptcode
== smJapanese
)
11195 fontp
->encoding
[1] = 4;
11199 = (font
->max_byte1
== 0
11201 ? (font
->min_char_or_byte2
< 0x80
11202 ? (font
->max_char_or_byte2
< 0x80
11203 ? 0 /* 0x20..0x7F */
11204 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
11205 : 1) /* 0xA0..0xFF */
11207 : (font
->min_byte1
< 0x80
11208 ? (font
->max_byte1
< 0x80
11209 ? (font
->min_char_or_byte2
< 0x80
11210 ? (font
->max_char_or_byte2
< 0x80
11211 ? 0 /* 0x2020..0x7F7F */
11212 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
11213 : 3) /* 0x20A0..0x7FFF */
11214 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
11215 : (font
->min_char_or_byte2
< 0x80
11216 ? (font
->max_char_or_byte2
< 0x80
11217 ? 2 /* 0xA020..0xFF7F */
11218 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
11219 : 1))); /* 0xA0A0..0xFFFF */
11222 #if 0 /* MAC_TODO: fill these out with more reasonably values */
11223 fontp
->baseline_offset
11224 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
11225 ? (long) value
: 0);
11226 fontp
->relative_compose
11227 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
11228 ? (long) value
: 0);
11229 fontp
->default_ascent
11230 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
11231 ? (long) value
: 0);
11233 fontp
->baseline_offset
= 0;
11234 fontp
->relative_compose
= 0;
11235 fontp
->default_ascent
= 0;
11238 /* Set global flag fonts_changed_p to non-zero if the font loaded
11239 has a character with a smaller width than any other character
11240 before, or if the font loaded has a smalle>r height than any
11241 other font loaded before. If this happens, it will make a
11242 glyph matrix reallocation necessary. */
11243 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11250 /* Return a pointer to struct font_info of a font named FONTNAME for
11251 frame F. If no such font is loaded, return NULL. */
11254 x_query_font (f
, fontname
)
11256 register char *fontname
;
11258 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11261 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11262 if (dpyinfo
->font_table
[i
].name
11263 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11264 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11265 return (dpyinfo
->font_table
+ i
);
11270 /* Find a CCL program for a font specified by FONTP, and set the member
11271 `encoder' of the structure. */
11274 x_find_ccl_program (fontp
)
11275 struct font_info
*fontp
;
11277 Lisp_Object list
, elt
;
11279 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11283 && STRINGP (XCAR (elt
))
11284 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11290 struct ccl_program
*ccl
11291 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11293 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11296 fontp
->font_encoder
= ccl
;
11302 /***********************************************************************
11304 ***********************************************************************/
11306 #ifdef USE_X_TOOLKIT
11307 static XrmOptionDescRec emacs_options
[] = {
11308 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11309 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11311 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11312 XrmoptionSepArg
, NULL
},
11313 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11315 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11316 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11317 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11318 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11319 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11320 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11321 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11323 #endif /* USE_X_TOOLKIT */
11325 static int x_initialized
;
11327 #ifdef MULTI_KBOARD
11328 /* Test whether two display-name strings agree up to the dot that separates
11329 the screen number from the server number. */
11331 same_x_server (name1
, name2
)
11332 char *name1
, *name2
;
11334 int seen_colon
= 0;
11335 unsigned char *system_name
= SDATA (Vsystem_name
);
11336 int system_name_length
= strlen (system_name
);
11337 int length_until_period
= 0;
11339 while (system_name
[length_until_period
] != 0
11340 && system_name
[length_until_period
] != '.')
11341 length_until_period
++;
11343 /* Treat `unix' like an empty host name. */
11344 if (! strncmp (name1
, "unix:", 5))
11346 if (! strncmp (name2
, "unix:", 5))
11348 /* Treat this host's name like an empty host name. */
11349 if (! strncmp (name1
, system_name
, system_name_length
)
11350 && name1
[system_name_length
] == ':')
11351 name1
+= system_name_length
;
11352 if (! strncmp (name2
, system_name
, system_name_length
)
11353 && name2
[system_name_length
] == ':')
11354 name2
+= system_name_length
;
11355 /* Treat this host's domainless name like an empty host name. */
11356 if (! strncmp (name1
, system_name
, length_until_period
)
11357 && name1
[length_until_period
] == ':')
11358 name1
+= length_until_period
;
11359 if (! strncmp (name2
, system_name
, length_until_period
)
11360 && name2
[length_until_period
] == ':')
11361 name2
+= length_until_period
;
11363 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11367 if (seen_colon
&& *name1
== '.')
11371 && (*name1
== '.' || *name1
== '\0')
11372 && (*name2
== '.' || *name2
== '\0'));
11377 /* The Mac Event loop code */
11380 #include <Events.h>
11381 #include <Quickdraw.h>
11382 #include <Balloons.h>
11383 #include <Devices.h>
11385 #include <Gestalt.h>
11387 #include <Processes.h>
11389 #include <ToolUtils.h>
11390 #include <TextUtils.h>
11391 #include <Dialogs.h>
11392 #include <Script.h>
11394 #include <TextEncodingConverter.h>
11395 #include <Resources.h>
11400 #endif /* ! MAC_OSX */
11402 #define M_APPLE 128
11405 #define WINDOW_RESOURCE 128
11406 #define TERM_WINDOW_RESOURCE 129
11408 #define DEFAULT_NUM_COLS 80
11410 #define MIN_DOC_SIZE 64
11411 #define MAX_DOC_SIZE 32767
11413 /* sleep time for WaitNextEvent */
11414 #define WNE_SLEEP_AT_SUSPEND 10
11415 #define WNE_SLEEP_AT_RESUME 1
11417 /* true when cannot handle any Mac OS events */
11418 static int handling_window_update
= 0;
11420 /* the flag appl_is_suspended is used both for determining the sleep
11421 time to be passed to WaitNextEvent and whether the cursor should be
11422 drawn when updating the display. The cursor is turned off when
11423 Emacs is suspended. Redrawing it is unnecessary and what needs to
11424 be done depends on whether the cursor lies inside or outside the
11425 redraw region. So we might as well skip drawing it when Emacs is
11427 static Boolean app_is_suspended
= false;
11428 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11430 #define EXTRA_STACK_ALLOC (256 * 1024)
11432 #define ARGV_STRING_LIST_ID 129
11433 #define ABOUT_ALERT_ID 128
11434 #define RAM_TOO_LARGE_ALERT_ID 129
11436 Boolean terminate_flag
= false;
11438 /* True if using command key as meta key. */
11439 Lisp_Object Vmac_command_key_is_meta
;
11441 /* True if the ctrl and meta keys should be reversed. */
11442 Lisp_Object Vmac_reverse_ctrl_meta
;
11444 #if USE_CARBON_EVENTS
11445 /* True if the mouse wheel button (i.e. button 4) should map to
11446 mouse-2, instead of mouse-3. */
11447 Lisp_Object Vmac_wheel_button_is_mouse_2
;
11449 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
11450 for processing before Emacs sees it. */
11451 Lisp_Object Vmac_pass_command_to_system
;
11453 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
11454 for processing before Emacs sees it. */
11455 Lisp_Object Vmac_pass_control_to_system
;
11458 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11459 to this text encoding */
11460 int mac_keyboard_text_encoding
;
11461 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11463 /* Set in term/mac-win.el to indicate that event loop can now generate
11464 drag and drop events. */
11465 Lisp_Object Qmac_ready_for_drag_n_drop
;
11467 Lisp_Object drag_and_drop_file_list
;
11469 Point saved_menu_event_location
;
11472 static void init_required_apple_events (void);
11473 static pascal OSErr
11474 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
11475 static pascal OSErr
11476 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
11477 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
11478 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
11480 /* Drag and Drop */
11481 static OSErr
init_mac_drag_n_drop ();
11482 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
11484 #if USE_CARBON_EVENTS
11485 /* Preliminary Support for the OSX Services Menu */
11486 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
11487 static void init_service_handler ();
11490 extern void init_emacs_passwd_dir ();
11491 extern int emacs_main (int, char **, char **);
11492 extern void check_alarm ();
11494 extern void initialize_applescript();
11495 extern void terminate_applescript();
11497 static unsigned int
11498 #if USE_CARBON_EVENTS
11499 mac_to_emacs_modifiers (UInt32 mods
)
11501 mac_to_emacs_modifiers (EventModifiers mods
)
11504 unsigned int result
= 0;
11505 if (mods
& macShiftKey
)
11506 result
|= shift_modifier
;
11507 if (mods
& macCtrlKey
)
11508 result
|= ctrl_modifier
;
11509 if (mods
& macMetaKey
)
11510 result
|= meta_modifier
;
11511 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
11512 result
|= alt_modifier
;
11516 #if USE_CARBON_EVENTS
11517 /* Obtains the event modifiers from the event ref and then calls
11518 mac_to_emacs_modifiers. */
11520 mac_event_to_emacs_modifiers (EventRef eventRef
)
11523 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
11524 sizeof (UInt32
), NULL
, &mods
);
11525 return mac_to_emacs_modifiers (mods
);
11528 /* Given an event ref, return the code to use for the mouse button
11529 code in the emacs input_event. */
11531 mac_get_mouse_btn (EventRef ref
)
11533 EventMouseButton result
= kEventMouseButtonPrimary
;
11534 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
11535 sizeof (EventMouseButton
), NULL
, &result
);
11538 case kEventMouseButtonPrimary
:
11540 case kEventMouseButtonSecondary
:
11541 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
11542 case kEventMouseButtonTertiary
:
11543 case 4: /* 4 is the number for the mouse wheel button */
11544 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
11550 /* Normally, ConvertEventRefToEventRecord will correctly handle all
11551 events. However the click of the mouse wheel is not converted to a
11552 mouseDown or mouseUp event. This calls ConvertEventRef, but then
11553 checks to see if it is a mouse up or down carbon event that has not
11554 been converted, and if so, converts it by hand (to be picked up in
11555 the XTread_socket loop). */
11556 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
11558 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
11559 /* Do special case for mouse wheel button. */
11560 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
11562 UInt32 kind
= GetEventKind (eventRef
);
11563 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
11565 eventRec
->what
= mouseDown
;
11568 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
11570 eventRec
->what
= mouseUp
;
11575 /* Need where and when. */
11577 GetEventParameter (eventRef
, kEventParamMouseLocation
,
11578 typeQDPoint
, NULL
, sizeof (Point
),
11579 NULL
, &eventRec
->where
);
11580 /* Use two step process because new event modifiers are
11581 32-bit and old are 16-bit. Currently, only loss is
11583 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
11584 typeUInt32
, NULL
, sizeof (UInt32
),
11586 eventRec
->modifiers
= mods
;
11588 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
11597 do_get_menus (void)
11599 Handle menubar_handle
;
11600 MenuHandle menu_handle
;
11602 menubar_handle
= GetNewMBar (128);
11603 if(menubar_handle
== NULL
)
11605 SetMenuBar (menubar_handle
);
11608 menu_handle
= GetMenuHandle (M_APPLE
);
11609 if(menu_handle
!= NULL
)
11610 AppendResMenu (menu_handle
,'DRVR');
11617 do_init_managers (void)
11619 #if !TARGET_API_MAC_CARBON
11620 InitGraf (&qd
.thePort
);
11622 FlushEvents (everyEvent
, 0);
11626 InitDialogs (NULL
);
11627 #endif /* !TARGET_API_MAC_CARBON */
11630 #if !TARGET_API_MAC_CARBON
11631 /* set up some extra stack space for use by emacs */
11632 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11634 /* MaxApplZone must be called for AppleScript to execute more
11635 complicated scripts */
11638 #endif /* !TARGET_API_MAC_CARBON */
11642 do_check_ram_size (void)
11644 SInt32 physical_ram_size
, logical_ram_size
;
11646 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11647 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11648 || physical_ram_size
> 256 * 1024 * 1024
11649 || logical_ram_size
> 256 * 1024 * 1024)
11651 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11657 do_window_update (WindowPtr win
)
11659 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11660 struct frame
*f
= mwp
->mFP
;
11664 if (f
->async_visible
== 0)
11666 f
->async_visible
= 1;
11667 f
->async_iconified
= 0;
11668 SET_FRAME_GARBAGED (f
);
11670 /* An update event is equivalent to MapNotify on X, so report
11671 visibility changes properly. */
11672 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11673 /* Force a redisplay sooner or later to update the
11674 frame titles in case this is the second frame. */
11675 record_asynch_buffer_change ();
11680 handling_window_update
= 1;
11682 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
11684 expose_frame (f
, 0, 0, 0, 0);
11686 handling_window_update
= 0;
11693 is_emacs_window (WindowPtr win
)
11695 Lisp_Object tail
, frame
;
11700 FOR_EACH_FRAME (tail
, frame
)
11701 if (FRAME_MAC_P (XFRAME (frame
)))
11702 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11709 do_window_activate (WindowPtr win
)
11714 if (is_emacs_window (win
))
11716 mwp
= (mac_output
*) GetWRefCon (win
);
11721 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11722 activate_scroll_bars (f
);
11728 do_window_deactivate (WindowPtr win
)
11733 if (is_emacs_window (win
))
11735 mwp
= (mac_output
*) GetWRefCon (win
);
11738 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11740 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11741 deactivate_scroll_bars (f
);
11753 wp
= FrontWindow();
11754 if (is_emacs_window (wp
))
11756 mwp
= (mac_output
*) GetWRefCon (wp
);
11761 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11762 activate_scroll_bars (f
);
11766 app_is_suspended
= false;
11767 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11777 wp
= FrontWindow();
11778 if (is_emacs_window (wp
))
11780 mwp
= (mac_output
*) GetWRefCon (wp
);
11783 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11785 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11786 deactivate_scroll_bars (f
);
11790 app_is_suspended
= true;
11791 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11796 do_mouse_moved (Point mouse_pos
)
11798 WindowPtr wp
= FrontWindow ();
11801 if (is_emacs_window (wp
))
11803 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11805 #if TARGET_API_MAC_CARBON
11806 SetPort (GetWindowPort (wp
));
11811 GlobalToLocal (&mouse_pos
);
11813 note_mouse_movement (f
, &mouse_pos
);
11819 do_os_event (EventRecord
*erp
)
11821 switch((erp
->message
>> 24) & 0x000000FF)
11823 case suspendResumeMessage
:
11824 if((erp
->message
& resumeFlag
) == 1)
11830 case mouseMovedMessage
:
11831 do_mouse_moved (erp
->where
);
11837 do_events (EventRecord
*erp
)
11842 do_window_update ((WindowPtr
) erp
->message
);
11850 if ((erp
->modifiers
& activeFlag
) != 0)
11851 do_window_activate ((WindowPtr
) erp
->message
);
11853 do_window_deactivate ((WindowPtr
) erp
->message
);
11859 do_apple_menu (SInt16 menu_item
)
11861 #if !TARGET_API_MAC_CARBON
11863 SInt16 da_driver_refnum
;
11865 if (menu_item
== I_ABOUT
)
11866 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11869 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11870 da_driver_refnum
= OpenDeskAcc (item_name
);
11872 #endif /* !TARGET_API_MAC_CARBON */
11876 do_menu_choice (SInt32 menu_choice
)
11878 SInt16 menu_id
, menu_item
;
11880 menu_id
= HiWord (menu_choice
);
11881 menu_item
= LoWord (menu_choice
);
11889 do_apple_menu (menu_item
);
11894 WindowPtr wp
= FrontWindow ();
11895 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11896 MenuHandle menu
= GetMenuHandle (menu_id
);
11901 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11902 menubar_selection_callback (f
, refcon
);
11911 /* Handle drags in size box. Based on code contributed by Ben
11912 Mesander and IM - Window Manager A. */
11915 do_grow_window (WindowPtr w
, EventRecord
*e
)
11920 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11921 struct frame
*f
= mwp
->mFP
;
11923 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11925 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11927 /* see if it really changed size */
11928 if (grow_size
!= 0)
11930 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11931 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11933 x_set_window_size (f
, 0, columns
, rows
);
11938 /* Handle clicks in zoom box. Calculation of "standard state" based
11939 on code in IM - Window Manager A and code contributed by Ben
11940 Mesander. The standard state of an Emacs window is 80-characters
11941 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11944 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11947 Rect zoom_rect
, port_rect
;
11949 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11950 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11951 struct frame
*f
= mwp
->mFP
;
11953 GetPort (&save_port
);
11955 #if TARGET_API_MAC_CARBON
11956 SetPort (GetWindowPort (w
));
11961 /* Clear window to avoid flicker. */
11962 #if TARGET_API_MAC_CARBON
11967 GetWindowPortBounds (w
, &r
);
11970 if (zoom_in_or_out
== inZoomOut
)
11972 /* calculate height of window's title bar (hard card it for now). */
11973 w_title_height
= 20 + GetMBarHeight ();
11975 /* get maximum height of window into zoom_rect.bottom -
11977 GetQDGlobalsScreenBits (&bm
);
11978 zoom_rect
= bm
.bounds
;
11979 zoom_rect
.top
+= w_title_height
;
11980 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11982 zoom_rect
.right
= zoom_rect
.left
11983 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11985 SetWindowStandardState (w
, &zoom_rect
);
11988 #else /* not TARGET_API_MAC_CARBON */
11989 EraseRect (&(w
->portRect
));
11990 if (zoom_in_or_out
== inZoomOut
)
11992 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
11993 LocalToGlobal (&top_left
);
11995 /* calculate height of window's title bar */
11996 w_title_height
= top_left
.v
- 1
11997 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
11999 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
12000 zoom_rect
= qd
.screenBits
.bounds
;
12001 zoom_rect
.top
+= w_title_height
;
12002 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
12004 zoom_rect
.right
= zoom_rect
.left
12005 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
12007 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
12010 #endif /* not TARGET_API_MAC_CARBON */
12012 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
12014 /* retrieve window size and update application values */
12015 #if TARGET_API_MAC_CARBON
12016 GetWindowPortBounds (w
, &port_rect
);
12018 port_rect
= w
->portRect
;
12020 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
12021 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
12022 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
12024 SetPort (save_port
);
12027 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
12029 init_mac_drag_n_drop ()
12031 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
12035 /* Intialize AppleEvent dispatcher table for the required events. */
12037 init_required_apple_events ()
12042 /* Make sure we have apple events before starting. */
12043 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
12047 if (!(result
& (1 << gestaltAppleEventsPresent
)))
12050 #if TARGET_API_MAC_CARBON
12051 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12052 NewAEEventHandlerUPP
12053 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12056 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12057 NewAEEventHandlerProc
12058 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12064 #if TARGET_API_MAC_CARBON
12065 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12066 NewAEEventHandlerUPP
12067 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12070 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12071 NewAEEventHandlerProc
12072 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12078 #if TARGET_API_MAC_CARBON
12079 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12080 NewAEEventHandlerUPP
12081 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12084 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12085 NewAEEventHandlerProc
12086 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12092 #if TARGET_API_MAC_CARBON
12093 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12094 NewAEEventHandlerUPP
12095 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12098 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12099 NewAEEventHandlerProc
12100 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12107 #if USE_CARBON_EVENTS
12109 void init_service_handler()
12111 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
12112 {kEventClassService
, kEventServiceCopy
},
12113 {kEventClassService
, kEventServicePaste
}};
12114 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
12115 3, specs
, NULL
, NULL
);
12119 MAC_TODO: Check to see if this is called by AEProcessDesc...
12121 OSStatus
mac_handle_service_event (EventHandlerCallRef callRef
,
12122 EventRef event
, void *data
)
12124 OSStatus err
= noErr
;
12125 switch (GetEventKind (event
))
12127 case kEventServiceGetTypes
:
12129 CFMutableArrayRef copyTypes
, pasteTypes
;
12131 Boolean selection
= true;
12133 GetEventParameter(event, kEventParamServicePasteTypes,
12134 typeCFMutableArrayRef, NULL,
12135 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
12137 GetEventParameter(event
, kEventParamServiceCopyTypes
,
12138 typeCFMutableArrayRef
, NULL
,
12139 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
12140 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
12142 CFArrayAppendValue (copyTypes
, type
);
12143 //CFArrayAppendValue (pasteTypes, type);
12147 case kEventServiceCopy
:
12149 ScrapRef currentScrap
, specificScrap
;
12151 Size byteCount
= 0;
12153 GetCurrentScrap (¤tScrap
);
12155 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
12158 void *buffer
= xmalloc (byteCount
);
12159 if (buffer
!= NULL
)
12161 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
12162 sizeof (ScrapRef
), NULL
, &specificScrap
);
12164 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
12165 &byteCount
, buffer
);
12167 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
12168 kScrapFlavorMaskNone
, byteCount
, buffer
);
12174 case kEventServicePaste
:
12177 // Get the current location
12179 ScrapRef specificScrap;
12180 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
12181 sizeof(ScrapRef), NULL, &specificScrap);
12182 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
12183 if (err == noErr) {
12184 void * buffer = xmalloc(byteCount);
12185 if (buffer != NULL ) {
12186 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
12187 &byteCount, buffer);
12188 if (err == noErr) {
12189 // Actually place in the buffer
12191 // Get the current "selection" string here
12204 /* Open Application Apple Event */
12205 static pascal OSErr
12206 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
12212 /* Defined in mac.c. */
12214 path_from_vol_dir_name (char *, int, short, long, char *);
12217 /* Called when we receive an AppleEvent with an ID of
12218 "kAEOpenDocuments". This routine gets the direct parameter,
12219 extracts the FSSpecs in it, and puts their names on a list. */
12220 static pascal OSErr
12221 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
12226 DescType actual_type
;
12229 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
12231 goto descriptor_error_exit
;
12233 /* Check to see that we got all of the required parameters from the
12234 event descriptor. For an 'odoc' event this should just be the
12236 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
12237 &actual_type
, (Ptr
) &keyword
,
12238 sizeof (keyword
), &actual_size
);
12239 /* No error means that we found some unused parameters.
12240 errAEDescNotFound means that there are no more parameters. If we
12241 get an error code other than that, flag it. */
12242 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
12244 err
= errAEEventNotHandled
;
12249 /* Got all the parameters we need. Now, go through the direct
12250 object list and parse it up. */
12252 long num_files_to_open
;
12254 err
= AECountItems (&the_desc
, &num_files_to_open
);
12259 /* AE file list is one based so just use that for indexing here. */
12260 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
12263 Str255 path_name
, unix_path_name
;
12268 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12269 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12270 if (err
!= noErr
) break;
12273 err
= FSpMakeFSRef (&fs
, &fref
);
12274 if (err
!= noErr
) break;
12276 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
12278 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12280 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12282 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12283 drag_and_drop_file_list
);
12289 /* Nuke the coerced file list in any case */
12290 err2
= AEDisposeDesc(&the_desc
);
12292 descriptor_error_exit
:
12293 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12298 static pascal OSErr
mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
12299 DragReference theDrag
)
12303 FlavorFlags theFlags
;
12306 ItemReference theItem
;
12309 Size size
= sizeof (HFSFlavor
);
12311 drag_and_drop_file_list
= Qnil
;
12312 GetDragMouse (theDrag
, &mouse
, 0L);
12313 CountDragItems (theDrag
, &items
);
12314 for (index
= 1; index
<= items
; index
++)
12316 /* Only handle file references. */
12317 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
12318 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
12319 if (result
== noErr
)
12326 Str255 unix_path_name
;
12327 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
12329 /* Use Carbon routines, otherwise it converts the file name
12330 to /Macintosh HD/..., which is not correct. */
12331 FSpMakeFSRef (&data
.fileSpec
, &fref
);
12332 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
12334 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
12335 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
12336 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12338 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12339 drag_and_drop_file_list
);
12344 /* If there are items in the list, construct an event and post it to
12345 the queue like an interrupt using kbd_buffer_store_event. */
12346 if (!NILP (drag_and_drop_file_list
))
12348 struct input_event event
;
12350 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
12351 SetPort (GetWindowPort (window
));
12352 GlobalToLocal (&mouse
);
12354 event
.kind
= DRAG_N_DROP_EVENT
;
12356 event
.modifiers
= 0;
12357 event
.timestamp
= TickCount () * (1000 / 60);
12358 XSETINT (event
.x
, mouse
.h
);
12359 XSETINT (event
.y
, mouse
.v
);
12360 XSETFRAME (frame
, f
);
12361 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12363 /* Post to the interrupt queue */
12364 kbd_buffer_store_event (&event
);
12365 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
12367 ProcessSerialNumber psn
;
12368 GetCurrentProcess (&psn
);
12369 SetFrontProcess (&psn
);
12375 /* Print Document Apple Event */
12376 static pascal OSErr
12377 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12379 return errAEEventNotHandled
;
12383 static pascal OSErr
12384 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12386 /* FixMe: Do we need an unwind-protect or something here? And what
12387 do we do about unsaved files. Currently just forces quit rather
12388 than doing recursive callback to get user input. */
12390 terminate_flag
= true;
12392 /* Fkill_emacs doesn't return. We have to return. (TI) */
12399 profiler_exit_proc ()
12401 ProfilerDump ("\pEmacs.prof");
12406 /* These few functions implement Emacs as a normal Mac application
12407 (almost): set up the heap and the Toolbox, handle necessary
12408 system events plus a few simple menu events. They also set up
12409 Emacs's access to functions defined in the rest of this file.
12410 Emacs uses function hooks to perform all its terminal I/O. A
12411 complete list of these functions appear in termhooks.h. For what
12412 they do, read the comments there and see also w32term.c and
12413 xterm.c. What's noticeably missing here is the event loop, which
12414 is normally present in most Mac application. After performing the
12415 necessary Mac initializations, main passes off control to
12416 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12417 mac_read_socket (defined further below) to read input. This is
12418 where WaitNextEvent is called to process Mac events. This is also
12419 where check_alarm in sysdep.c is called to simulate alarm signals.
12420 This makes the cursor jump back to its correct position after
12421 briefly jumping to that of the matching parenthesis, print useful
12422 hints and prompts in the minibuffer after the user stops typing for
12425 #if !TARGET_API_MAC_CARBON
12430 #if __profile__ /* is the profiler on? */
12431 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12436 /* set creator and type for files created by MSL */
12437 _fcreator
= 'EMAx';
12441 do_init_managers ();
12445 do_check_ram_size ();
12447 init_emacs_passwd_dir ();
12451 initialize_applescript ();
12453 init_required_apple_events ();
12459 /* set up argv array from STR# resource */
12460 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12464 /* free up AppleScript resources on exit */
12465 atexit (terminate_applescript
);
12467 #if __profile__ /* is the profiler on? */
12468 atexit (profiler_exit_proc
);
12471 /* 3rd param "envp" never used in emacs_main */
12472 (void) emacs_main (argc
, argv
, 0);
12475 /* Never reached - real exit in Fkill_emacs */
12480 /* Table for translating Mac keycode to X keysym values. Contributed
12481 by Sudhir Shenoy. */
12482 static unsigned char keycode_to_xkeysym_table
[] = {
12484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12485 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12486 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12487 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12489 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
12490 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
12491 0, 0, 0, '\xaf' /* kp/ */,
12492 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
12494 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
12495 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
12496 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
12497 '\xb9' /* kp9 */, 0, 0, 0,
12499 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
12500 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
12501 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
12502 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
12504 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
12505 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
12506 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
12507 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
12511 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12513 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12514 return *xKeySym
!= 0;
12517 /* Emacs calls this whenever it wants to read an input event from the
12520 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12523 #if USE_CARBON_EVENTS
12524 OSStatus rneResult
;
12526 EventMouseButton mouseBtn
;
12530 EventMask event_mask
;
12533 if (interrupt_input_blocked
)
12535 interrupt_input_pending
= 1;
12540 interrupt_input_pending
= 0;
12543 /* So people can tell when we have read the available input. */
12544 input_signal_count
++;
12549 /* Don't poll for events to process (specifically updateEvt) if
12550 window update currently already in progress. A call to redisplay
12551 (in do_window_update) can be preempted by another call to
12552 redisplay, causing blank regions to be left on the screen and the
12553 cursor to be left at strange places. */
12554 if (handling_window_update
)
12560 if (terminate_flag
)
12561 Fkill_emacs (make_number (1));
12563 /* It is necessary to set this (additional) argument slot of an
12564 event to nil because keyboard.c protects incompletely processed
12565 event from being garbage collected by placing them in the
12566 kbd_buffer_gcpro vector. */
12569 event_mask
= everyEvent
;
12570 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12571 event_mask
-= highLevelEventMask
;
12573 #if USE_CARBON_EVENTS
12574 rneResult
= ReceiveNextEvent (0, NULL
,
12576 ? TicksToEventTime (app_sleep_time
)
12581 /* Handle new events */
12582 if (!mac_convert_event_ref (eventRef
, &er
))
12583 switch (GetEventClass (eventRef
))
12585 case kEventClassMouse
:
12586 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
12590 WindowPtr window_ptr
= FrontNonFloatingWindow ();
12591 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12592 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
12593 typeSInt32
, NULL
, sizeof (SInt32
),
12595 GetEventParameter(eventRef
, kEventParamMouseLocation
,
12596 typeQDPoint
, NULL
, sizeof (Point
),
12598 bufp
->kind
= MOUSE_WHEEL_EVENT
;
12599 bufp
->code
= delta
;
12600 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
12601 SetPort (GetWindowPort (window_ptr
));
12602 GlobalToLocal (&point
);
12603 XSETINT (bufp
->x
, point
.h
);
12604 XSETINT (bufp
->y
, point
.v
);
12605 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12606 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
12610 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12614 /* Send the event to the appropriate receiver. */
12615 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12619 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
12620 #endif /* USE_CARBON_EVENTS */
12626 WindowPtr window_ptr
= FrontWindow ();
12629 #if USE_CARBON_EVENTS
12630 /* This is needed to send mouse events like aqua window buttons
12631 to the correct handler. */
12632 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
12636 if (!is_emacs_window(window_ptr
))
12640 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12641 && er
.what
== mouseUp
)
12643 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12644 Point mouse_loc
= er
.where
;
12646 /* Convert to local coordinates of new window. */
12647 #if TARGET_API_MAC_CARBON
12648 SetPort (GetWindowPort (window_ptr
));
12650 SetPort (window_ptr
);
12653 GlobalToLocal (&mouse_loc
);
12655 #if USE_CARBON_EVENTS
12656 bufp
->code
= mac_get_mouse_btn (eventRef
);
12658 bufp
->code
= 0; /* only one mouse button */
12660 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
12661 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12662 bufp
->part
= scroll_bar_handle
;
12663 #if USE_CARBON_EVENTS
12664 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12666 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12668 bufp
->modifiers
|= up_modifier
;
12669 bufp
->timestamp
= er
.when
* (1000 / 60);
12670 /* ticks to milliseconds */
12672 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12673 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12674 tracked_scroll_bar
->dragging
= Qnil
;
12675 mouse_tracking_in_progress
= mouse_tracking_none
;
12676 tracked_scroll_bar
= NULL
;
12681 part_code
= FindWindow (er
.where
, &window_ptr
);
12687 struct frame
*f
= ((mac_output
*)
12688 GetWRefCon (FrontWindow ()))->mFP
;
12689 saved_menu_event_location
= er
.where
;
12690 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
12691 XSETFRAME (bufp
->frame_or_window
, f
);
12697 if (window_ptr
!= FrontWindow ())
12698 SelectWindow (window_ptr
);
12701 SInt16 control_part_code
;
12703 struct mac_output
*mwp
= (mac_output
*)
12704 GetWRefCon (window_ptr
);
12705 Point mouse_loc
= er
.where
;
12707 /* convert to local coordinates of new window */
12708 #if TARGET_API_MAC_CARBON
12709 SetPort (GetWindowPort (window_ptr
));
12711 SetPort (window_ptr
);
12714 GlobalToLocal (&mouse_loc
);
12715 #if TARGET_API_MAC_CARBON
12716 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12717 &control_part_code
);
12719 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12722 #if USE_CARBON_EVENTS
12723 bufp
->code
= mac_get_mouse_btn (eventRef
);
12725 bufp
->code
= 0; /* only one mouse button */
12727 XSETINT (bufp
->x
, mouse_loc
.h
);
12728 XSETINT (bufp
->y
, mouse_loc
.v
);
12729 bufp
->timestamp
= er
.when
* (1000 / 60);
12730 /* ticks to milliseconds */
12732 #if TARGET_API_MAC_CARBON
12735 if (control_part_code
!= 0)
12738 struct scroll_bar
*bar
= (struct scroll_bar
*)
12739 GetControlReference (ch
);
12740 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12742 if (er
.what
== mouseDown
12743 && control_part_code
== kControlIndicatorPart
)
12745 mouse_tracking_in_progress
12746 = mouse_tracking_scroll_bar
;
12747 tracked_scroll_bar
= bar
;
12751 mouse_tracking_in_progress
= mouse_tracking_none
;
12752 tracked_scroll_bar
= NULL
;
12757 bufp
->kind
= MOUSE_CLICK_EVENT
;
12758 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12759 if (er
.what
== mouseDown
)
12760 mouse_tracking_in_progress
12761 = mouse_tracking_mouse_movement
;
12763 mouse_tracking_in_progress
= mouse_tracking_none
;
12766 #if USE_CARBON_EVENTS
12767 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12769 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12775 bufp
->modifiers
|= down_modifier
;
12778 bufp
->modifiers
|= up_modifier
;
12787 #if TARGET_API_MAC_CARBON
12791 GetQDGlobalsScreenBits (&bm
);
12792 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12794 #else /* not TARGET_API_MAC_CARBON */
12795 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12796 #endif /* not TARGET_API_MAC_CARBON */
12800 if (TrackGoAway (window_ptr
, er
.where
))
12802 bufp
->kind
= DELETE_WINDOW_EVENT
;
12803 XSETFRAME (bufp
->frame_or_window
,
12804 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12809 /* window resize handling added --ben */
12811 do_grow_window(window_ptr
, &er
);
12814 /* window zoom handling added --ben */
12817 if (TrackBox (window_ptr
, er
.where
, part_code
))
12818 do_zoom_window (window_ptr
, part_code
);
12830 #if USE_CARBON_EVENTS
12831 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
12839 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12842 #if USE_CARBON_EVENTS
12843 /* When using Carbon Events, we need to pass raw keyboard events
12844 to the TSM ourselves. If TSM handles it, it will pass back
12845 noErr, otherwise it will pass back "eventNotHandledErr" and
12846 we can process it normally. */
12847 if ((!NILP (Vmac_pass_command_to_system
)
12848 || !(er
.modifiers
& cmdKey
))
12849 && (!NILP (Vmac_pass_control_to_system
)
12850 || !(er
.modifiers
& controlKey
)))
12853 err
= SendEventToEventTarget (eventRef
,
12854 GetEventDispatcherTarget ());
12855 if (err
!= eventNotHandledErr
)
12860 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
12869 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12872 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12874 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12876 bufp
->code
= 0xff00 | xkeysym
;
12877 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
12879 else if (!NILP (Vmac_reverse_ctrl_meta
) && (er
.modifiers
& controlKey
))
12881 /* This is a special case to deal with converting from
12882 a control character to non-control character */
12883 int new_modifiers
= er
.modifiers
& ~controlKey
;
12884 int new_keycode
= keycode
| new_modifiers
;
12885 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12886 unsigned long some_state
= 0;
12887 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
, &some_state
) & 0xff;
12888 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12892 if (er
.modifiers
& macMetaKey
)
12894 /* This code comes from Keyboard Resource, Appendix
12895 C of IM - Text. This is necessary since shift is
12896 ignored in KCHR table translation when option or
12897 command is pressed. */
12898 int new_modifiers
= er
.modifiers
& 0xf600;
12899 /* mask off option and command */
12900 int new_keycode
= keycode
| new_modifiers
;
12901 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12902 unsigned long some_state
= 0;
12903 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12904 &some_state
) & 0xff;
12907 bufp
->code
= er
.message
& charCodeMask
;
12908 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12912 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12913 convert non-ASCII characters typed at the Mac keyboard
12914 (presumed to be in the Mac Roman encoding) to iso-latin-1
12915 encoding before they are passed to Emacs. This enables the
12916 Mac keyboard to be used to enter non-ASCII iso-latin-1
12917 characters directly. */
12918 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12919 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
12921 static TECObjectRef converter
= NULL
;
12922 OSStatus the_err
= noErr
;
12923 OSStatus convert_status
= noErr
;
12925 if (converter
== NULL
)
12927 the_err
= TECCreateConverter (&converter
,
12928 kTextEncodingMacRoman
,
12929 mac_keyboard_text_encoding
);
12930 current_mac_keyboard_text_encoding
12931 = mac_keyboard_text_encoding
;
12933 else if (mac_keyboard_text_encoding
12934 != current_mac_keyboard_text_encoding
)
12936 /* Free the converter for the current encoding before
12937 creating a new one. */
12938 TECDisposeConverter (converter
);
12939 the_err
= TECCreateConverter (&converter
,
12940 kTextEncodingMacRoman
,
12941 mac_keyboard_text_encoding
);
12942 current_mac_keyboard_text_encoding
12943 = mac_keyboard_text_encoding
;
12946 if (the_err
== noErr
)
12948 unsigned char ch
= bufp
->code
;
12949 ByteCount actual_input_length
, actual_output_length
;
12950 unsigned char outch
;
12952 convert_status
= TECConvertText (converter
, &ch
, 1,
12953 &actual_input_length
,
12955 &actual_output_length
);
12956 if (convert_status
== noErr
12957 && actual_input_length
== 1
12958 && actual_output_length
== 1)
12959 bufp
->code
= outch
;
12963 #if USE_CARBON_EVENTS
12964 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12966 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12971 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
12972 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12975 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
12980 case kHighLevelEvent
:
12981 drag_and_drop_file_list
= Qnil
;
12983 AEProcessAppleEvent(&er
);
12985 /* Build a DRAG_N_DROP_EVENT type event as is done in
12986 constuct_drag_n_drop in w32term.c. */
12987 if (!NILP (drag_and_drop_file_list
))
12989 struct frame
*f
= NULL
;
12993 wp
= FrontNonFloatingWindow ();
12994 if (wp
&& is_emacs_window(wp
))
12995 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12997 bufp
->kind
= DRAG_N_DROP_EVENT
;
12999 bufp
->timestamp
= er
.when
* (1000 / 60);
13000 /* ticks to milliseconds */
13001 #if USE_CARBON_EVENTS
13002 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
13004 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
13007 XSETINT (bufp
->x
, 0);
13008 XSETINT (bufp
->y
, 0);
13010 XSETFRAME (frame
, f
);
13011 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
13013 /* Regardless of whether Emacs was suspended or in the
13014 foreground, ask it to redraw its entire screen.
13015 Otherwise parts of the screen can be left in an
13016 inconsistent state. */
13018 #if TARGET_API_MAC_CARBON
13022 GetWindowPortBounds (wp
, &r
);
13023 InvalWindowRect (wp
, &r
);
13025 #else /* not TARGET_API_MAC_CARBON */
13026 InvalRect (&(wp
->portRect
));
13027 #endif /* not TARGET_API_MAC_CARBON */
13034 #if USE_CARBON_EVENTS
13035 ReleaseEvent (eventRef
);
13039 /* If the focus was just given to an autoraising frame,
13041 /* ??? This ought to be able to handle more than one such frame. */
13042 if (pending_autoraise_frame
)
13044 x_raise_frame (pending_autoraise_frame
);
13045 pending_autoraise_frame
= 0;
13048 #if !TARGET_API_MAC_CARBON
13049 check_alarm (); /* simulate the handling of a SIGALRM */
13053 static Point old_mouse_pos
= { -1, -1 };
13055 if (app_is_suspended
)
13057 old_mouse_pos
.h
= -1;
13058 old_mouse_pos
.v
= -1;
13066 struct scroll_bar
*sb
;
13068 wp
= FrontWindow ();
13069 if (is_emacs_window (wp
))
13071 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
13073 #if TARGET_API_MAC_CARBON
13074 SetPort (GetWindowPort (wp
));
13079 GetMouse (&mouse_pos
);
13081 if (!EqualPt (mouse_pos
, old_mouse_pos
))
13083 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
13084 && tracked_scroll_bar
)
13085 x_scroll_bar_note_movement (tracked_scroll_bar
,
13087 - XINT (tracked_scroll_bar
->top
),
13088 TickCount() * (1000 / 60));
13090 note_mouse_movement (f
, &mouse_pos
);
13092 old_mouse_pos
= mouse_pos
;
13104 /* Need to override CodeWarrior's input function so no conversion is
13105 done on newlines Otherwise compiled functions in .elc files will be
13106 read incorrectly. Defined in ...:MSL C:MSL
13107 Common:Source:buffer_io.c. */
13110 __convert_to_newlines (unsigned char * p
, size_t * n
)
13112 #pragma unused(p,n)
13116 __convert_from_newlines (unsigned char * p
, size_t * n
)
13118 #pragma unused(p,n)
13123 /* Initialize the struct pointed to by MW to represent a new COLS x
13124 ROWS Macintosh window, using font with name FONTNAME and size
13127 NewMacWindow (FRAME_PTR fp
)
13130 #if TARGET_API_MAC_CARBON
13131 static int making_terminal_window
= 0;
13133 static int making_terminal_window
= 1;
13136 mwp
= fp
->output_data
.mac
;
13138 if (making_terminal_window
)
13140 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
13143 making_terminal_window
= 0;
13146 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
13149 SetWRefCon (mwp
->mWP
, (long) mwp
);
13150 /* so that update events can find this mac_output struct */
13151 mwp
->mFP
= fp
; /* point back to emacs frame */
13153 #if TARGET_API_MAC_CARBON
13154 SetPort (GetWindowPort (mwp
->mWP
));
13156 SetPort (mwp
->mWP
);
13161 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
13162 ShowWindow (mwp
->mWP
);
13167 void make_mac_frame (struct frame
*f
)
13169 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
13170 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
13172 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
13176 f
->output_data
.mac
->cursor_pixel
= 0;
13177 f
->output_data
.mac
->border_pixel
= 0x00ff00;
13178 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
13179 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
13181 f
->output_data
.mac
->fontset
= -1;
13182 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13183 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13184 f
->output_data
.mac
->left_pos
= 4;
13185 f
->output_data
.mac
->top_pos
= 4;
13186 f
->output_data
.mac
->border_width
= 0;
13187 f
->output_data
.mac
->explicit_parent
= 0;
13189 f
->output_data
.mac
->internal_border_width
= 0;
13191 f
->output_method
= output_mac
;
13200 void make_mac_terminal_frame (struct frame
*f
)
13204 XSETFRAME (frame
, f
);
13206 f
->output_method
= output_mac
;
13207 f
->output_data
.mac
= (struct mac_output
*)
13208 xmalloc (sizeof (struct mac_output
));
13209 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
13210 f
->output_data
.mac
->fontset
= -1;
13211 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13212 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13214 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
13219 make_mac_frame (f
);
13223 /* Need to be initialized for unshow_buffer in window.c. */
13224 selected_window
= f
->selected_window
;
13226 Fmodify_frame_parameters (frame
,
13227 Fcons (Fcons (Qfont
,
13228 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
13229 Fmodify_frame_parameters (frame
,
13230 Fcons (Fcons (Qforeground_color
,
13231 build_string ("black")), Qnil
));
13232 Fmodify_frame_parameters (frame
,
13233 Fcons (Fcons (Qbackground_color
,
13234 build_string ("white")), Qnil
));
13238 /***********************************************************************
13240 ***********************************************************************/
13242 #ifdef USE_X_TOOLKIT
13243 static XrmOptionDescRec emacs_options
[] = {
13244 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13245 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13247 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13248 XrmoptionSepArg
, NULL
},
13249 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13251 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13252 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13253 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13254 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13255 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13256 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13257 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13259 #endif /* USE_X_TOOLKIT */
13261 #ifdef MULTI_KBOARD
13262 /* Test whether two display-name strings agree up to the dot that separates
13263 the screen number from the server number. */
13265 same_x_server (name1
, name2
)
13266 char *name1
, *name2
;
13268 int seen_colon
= 0;
13269 unsigned char *system_name
= SDATA (Vsystem_name
);
13270 int system_name_length
= strlen (system_name
);
13271 int length_until_period
= 0;
13273 while (system_name
[length_until_period
] != 0
13274 && system_name
[length_until_period
] != '.')
13275 length_until_period
++;
13277 /* Treat `unix' like an empty host name. */
13278 if (! strncmp (name1
, "unix:", 5))
13280 if (! strncmp (name2
, "unix:", 5))
13282 /* Treat this host's name like an empty host name. */
13283 if (! strncmp (name1
, system_name
, system_name_length
)
13284 && name1
[system_name_length
] == ':')
13285 name1
+= system_name_length
;
13286 if (! strncmp (name2
, system_name
, system_name_length
)
13287 && name2
[system_name_length
] == ':')
13288 name2
+= system_name_length
;
13289 /* Treat this host's domainless name like an empty host name. */
13290 if (! strncmp (name1
, system_name
, length_until_period
)
13291 && name1
[length_until_period
] == ':')
13292 name1
+= length_until_period
;
13293 if (! strncmp (name2
, system_name
, length_until_period
)
13294 && name2
[length_until_period
] == ':')
13295 name2
+= length_until_period
;
13297 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13301 if (seen_colon
&& *name1
== '.')
13305 && (*name1
== '.' || *name1
== '\0')
13306 && (*name2
== '.' || *name2
== '\0'));
13310 int mac_initialized
= 0;
13313 mac_initialize_display_info ()
13315 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
13316 GDHandle main_device_handle
;
13318 bzero (dpyinfo
, sizeof (*dpyinfo
));
13320 /* Put it on x_display_name_list. */
13321 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
13322 x_display_name_list
);
13323 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13326 dpyinfo
->mac_id_name
13327 = (char *) xmalloc (SCHARS (Vinvocation_name
)
13328 + SCHARS (Vsystem_name
)
13330 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
13331 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
13333 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
13334 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
13337 main_device_handle
= LMGetMainDevice();
13339 dpyinfo
->reference_count
= 0;
13340 dpyinfo
->resx
= 75.0;
13341 dpyinfo
->resy
= 75.0;
13342 dpyinfo
->n_planes
= 1;
13343 dpyinfo
->n_cbits
= 16;
13344 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13345 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13346 dpyinfo
->grabbed
= 0;
13347 dpyinfo
->root_window
= NULL
;
13349 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13350 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13351 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13352 dpyinfo
->mouse_face_window
= Qnil
;
13355 struct mac_display_info
*
13356 mac_term_init (display_name
, xrm_option
, resource_name
)
13357 Lisp_Object display_name
;
13359 char *resource_name
;
13361 struct mac_display_info
*dpyinfo
;
13362 GDHandle main_device_handle
;
13364 if (!mac_initialized
)
13367 mac_initialized
= 1;
13370 mac_initialize_display_info (display_name
);
13372 dpyinfo
= &one_mac_display_info
;
13374 main_device_handle
= LMGetMainDevice();
13376 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13377 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13383 void MakeMeTheFrontProcess ()
13385 ProcessSerialNumber psn
;
13388 err
= GetCurrentProcess (&psn
);
13390 (void) SetFrontProcess (&psn
);
13392 #endif /* MAC_OSX */
13394 /* Set up use of X before we make the first connection. */
13396 static struct redisplay_interface x_redisplay_interface
=
13401 x_clear_end_of_line
,
13403 x_after_update_window_line
,
13404 x_update_window_begin
,
13405 x_update_window_end
,
13408 x_clear_mouse_face
,
13409 x_get_glyph_overhangs
,
13410 x_fix_overlapping_area
13416 rif
= &x_redisplay_interface
;
13418 clear_frame_hook
= x_clear_frame
;
13419 ins_del_lines_hook
= x_ins_del_lines
;
13420 delete_glyphs_hook
= x_delete_glyphs
;
13421 ring_bell_hook
= XTring_bell
;
13422 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13423 set_terminal_modes_hook
= XTset_terminal_modes
;
13424 update_begin_hook
= x_update_begin
;
13425 update_end_hook
= x_update_end
;
13426 set_terminal_window_hook
= XTset_terminal_window
;
13427 read_socket_hook
= XTread_socket
;
13428 frame_up_to_date_hook
= XTframe_up_to_date
;
13429 mouse_position_hook
= XTmouse_position
;
13430 frame_rehighlight_hook
= XTframe_rehighlight
;
13431 frame_raise_lower_hook
= XTframe_raise_lower
;
13433 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13434 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13435 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13436 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13438 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13440 scroll_region_ok
= 1; /* we'll scroll partial frames */
13441 char_ins_del_ok
= 1;
13442 line_ins_del_ok
= 1; /* we'll just blt 'em */
13443 fast_clear_end_of_line
= 1; /* X does this well */
13444 memory_below_frame
= 0; /* we don't remember what scrolls
13449 last_tool_bar_item
= -1;
13450 any_help_event_p
= 0;
13452 /* Try to use interrupt input; if we can't, then start polling. */
13453 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13455 #ifdef USE_X_TOOLKIT
13456 XtToolkitInitialize ();
13457 Xt_app_con
= XtCreateApplicationContext ();
13458 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13460 /* Install an asynchronous timer that processes Xt timeout events
13461 every 0.1s. This is necessary because some widget sets use
13462 timeouts internally, for example the LessTif menu bar, or the
13463 Xaw3d scroll bar. When Xt timouts aren't processed, these
13464 widgets don't behave normally. */
13466 EMACS_TIME interval
;
13467 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13468 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13472 #if USE_TOOLKIT_SCROLL_BARS
13473 xaw3d_arrow_scroll
= False
;
13474 xaw3d_pick_top
= True
;
13478 /* Note that there is no real way portable across R3/R4 to get the
13479 original error handler. */
13480 XSetErrorHandler (x_error_handler
);
13481 XSetIOErrorHandler (x_io_error_quitter
);
13483 /* Disable Window Change signals; they are handled by X events. */
13485 signal (SIGWINCH
, SIG_DFL
);
13486 #endif /* ! defined (SIGWINCH) */
13488 signal (SIGPIPE
, x_connection_signal
);
13491 mac_initialize_display_info ();
13493 #if TARGET_API_MAC_CARBON
13494 init_required_apple_events ();
13496 init_mac_drag_n_drop ();
13498 #if USE_CARBON_EVENTS
13499 init_service_handler ();
13502 DisableMenuCommand (NULL
, kHICommandQuit
);
13504 if (!inhibit_window_system
)
13505 MakeMeTheFrontProcess ();
13514 staticpro (&x_error_message_string
);
13515 x_error_message_string
= Qnil
;
13518 staticpro (&x_display_name_list
);
13519 x_display_name_list
= Qnil
;
13521 staticpro (&last_mouse_scroll_bar
);
13522 last_mouse_scroll_bar
= Qnil
;
13524 staticpro (&Qvendor_specific_keysyms
);
13525 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13527 staticpro (&last_mouse_press_frame
);
13528 last_mouse_press_frame
= Qnil
;
13530 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13531 staticpro (&Qmac_ready_for_drag_n_drop
);
13534 staticpro (&help_echo
);
13535 help_echo_object
= Qnil
;
13536 staticpro (&help_echo_object
);
13537 help_echo_window
= Qnil
;
13538 staticpro (&help_echo_window
);
13539 previous_help_echo
= Qnil
;
13540 staticpro (&previous_help_echo
);
13541 help_echo_pos
= -1;
13543 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13544 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13545 x_autoselect_window_p
= 0;
13547 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13548 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13549 For example, if a block cursor is over a tab, it will be drawn as
13550 wide as that tab on the display. */);
13551 x_stretch_cursor_p
= 0;
13553 #if 0 /* TODO: Setting underline position from font properties. */
13554 DEFVAR_BOOL ("x-use-underline-position-properties",
13555 &x_use_underline_position_properties
,
13556 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13557 nil means ignore them. If you encounter fonts with bogus
13558 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13559 to 4.1, set this to nil. */);
13560 x_use_underline_position_properties
= 1;
13563 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13564 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13565 Vx_toolkit_scroll_bars
= Qt
;
13567 staticpro (&last_mouse_motion_frame
);
13568 last_mouse_motion_frame
= Qnil
;
13570 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13571 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13572 Otherwise the option key is used. */);
13573 Vmac_command_key_is_meta
= Qt
;
13575 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
13576 doc
: /* Non-nil means that the control and meta keys are reversed. This is
13577 useful for non-standard keyboard layouts. */);
13578 Vmac_reverse_ctrl_meta
= Qnil
;
13580 #if USE_CARBON_EVENTS
13581 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
13582 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
13583 the right click will be mouse-3.
13584 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
13585 Vmac_wheel_button_is_mouse_2
= Qt
;
13587 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
13588 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
13589 Toolbox for processing before Emacs sees it. */);
13590 Vmac_pass_command_to_system
= Qt
;
13592 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
13593 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
13594 Toolbox for processing before Emacs sees it. */);
13595 Vmac_pass_control_to_system
= Qt
;
13598 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13599 doc
: /* One of the Text Encoding Base constant values defined in the
13600 Basic Text Constants section of Inside Macintosh - Text Encoding
13601 Conversion Manager. Its value determines the encoding characters
13602 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13603 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13604 its default value, no conversion takes place. If it is set to
13605 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13606 characters typed on Mac keyboard are first converted into the
13607 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13608 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13609 command, this enables the Mac keyboard to be used to enter non-ASCII
13610 characters directly. */);
13611 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;