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 void expose_overlaps
P_ ((struct window
*, struct glyph_row
*,
447 struct glyph_row
*));
448 static int expose_window
P_ ((struct window
*, Rect
*));
449 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
450 Rect
*, enum glyph_row_area
));
451 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
453 void x_display_cursor (struct window
*, int, int, int, int, int);
454 void x_update_cursor
P_ ((struct frame
*, int));
455 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
456 static void x_update_window_cursor
P_ ((struct window
*, int));
457 static void x_erase_phys_cursor
P_ ((struct window
*));
458 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
459 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
460 enum fringe_bitmap_type
, int left_p
));
461 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
463 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
464 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
465 static void notice_overwritten_cursor
P_ ((struct window
*,
467 int, int, int, int));
468 static void x_flush
P_ ((struct frame
*f
));
469 static void x_update_begin
P_ ((struct frame
*));
470 static void x_update_window_begin
P_ ((struct window
*));
471 static void x_draw_vertical_border
P_ ((struct window
*));
472 static void x_after_update_window_line
P_ ((struct glyph_row
*));
473 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
474 static void x_produce_stretch_glyph
P_ ((struct it
*));
476 static void activate_scroll_bars (FRAME_PTR
);
477 static void deactivate_scroll_bars (FRAME_PTR
);
479 static int is_emacs_window (WindowPtr
);
481 extern int image_ascent (struct image
*, struct face
*);
482 void x_set_offset (struct frame
*, int, int, int);
483 int x_bitmap_icon (struct frame
*, Lisp_Object
);
484 void x_make_frame_visible (struct frame
*);
486 extern void window_scroll (Lisp_Object
, int, int, int);
488 /* Defined in macmenu.h. */
489 extern void menubar_selection_callback (FRAME_PTR
, int);
490 extern void set_frame_menubar (FRAME_PTR
, int, int);
492 /* X display function emulation */
494 /* Structure borrowed from Xlib.h to represent two-byte characters in
503 XFreePixmap (display
, pixmap
)
507 PixMap
*p
= (PixMap
*) pixmap
;
514 /* Set foreground color for subsequent QuickDraw commands. Assume
515 graphic port has already been set. */
518 mac_set_forecolor (unsigned long color
)
522 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
523 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
524 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
526 RGBForeColor (&fg_color
);
530 /* Set background color for subsequent QuickDraw commands. Assume
531 graphic port has already been set. */
534 mac_set_backcolor (unsigned long color
)
538 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
539 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
540 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
542 RGBBackColor (&bg_color
);
545 /* Set foreground and background color for subsequent QuickDraw
546 commands. Assume that the graphic port has already been set. */
549 mac_set_colors (GC gc
)
551 mac_set_forecolor (gc
->foreground
);
552 mac_set_backcolor (gc
->background
);
555 /* Mac version of XDrawLine. */
558 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
564 #if TARGET_API_MAC_CARBON
565 SetPort (GetWindowPort (w
));
576 /* Mac version of XClearArea. */
579 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
583 unsigned int width
, height
;
586 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
590 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
591 xgc
.background
= mwp
->x_compatible
.background_pixel
;
593 #if TARGET_API_MAC_CARBON
594 SetPort (GetWindowPort (w
));
599 mac_set_colors (&xgc
);
600 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
605 /* Mac version of XClearWindow. */
608 XClearWindow (display
, w
)
612 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
615 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
616 xgc
.background
= mwp
->x_compatible
.background_pixel
;
618 #if TARGET_API_MAC_CARBON
619 SetPort (GetWindowPort (w
));
624 mac_set_colors (&xgc
);
626 #if TARGET_API_MAC_CARBON
630 GetWindowPortBounds (w
, &r
);
633 #else /* not TARGET_API_MAC_CARBON */
634 EraseRect (&(w
->portRect
));
635 #endif /* not TARGET_API_MAC_CARBON */
639 /* Mac replacement for XCopyArea. */
642 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
651 #if TARGET_API_MAC_CARBON
652 SetPort (GetWindowPort (w
));
658 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
660 #if TARGET_API_MAC_CARBON
664 LockPortBits (GetWindowPort (w
));
665 pmh
= GetPortPixMap (GetWindowPort (w
));
666 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
667 UnlockPortBits (GetWindowPort (w
));
669 #else /* not TARGET_API_MAC_CARBON */
670 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
671 #endif /* not TARGET_API_MAC_CARBON */
675 /* Mac replacement for XSetClipRectangles. */
678 mac_set_clip_rectangle (display
, w
, r
)
683 #if TARGET_API_MAC_CARBON
684 SetPort (GetWindowPort (w
));
693 /* Mac replacement for XSetClipMask. */
696 mac_reset_clipping (display
, w
)
702 #if TARGET_API_MAC_CARBON
703 SetPort (GetWindowPort (w
));
708 SetRect (&r
, -32767, -32767, 32767, 32767);
713 /* Mac replacement for XCreateBitmapFromBitmapData. */
716 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
721 int bytes_per_row
, i
, j
;
723 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
724 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
725 if (!bitmap
->baseAddr
)
728 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
729 for (i
= 0; i
< h
; i
++)
730 for (j
= 0; j
< w
; j
++)
731 if (BitTst (bits
, i
* w
+ j
))
732 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
734 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
739 mac_free_bitmap (bitmap
)
742 xfree (bitmap
->baseAddr
);
745 /* Mac replacement for XFillRectangle. */
748 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
753 unsigned int width
, height
;
757 #if TARGET_API_MAC_CARBON
758 SetPort (GetWindowPort (w
));
764 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
766 PaintRect (&r
); /* using foreground color of gc */
770 /* Mac replacement for XDrawRectangle: dest is a window. */
773 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
778 unsigned int width
, height
;
782 #if TARGET_API_MAC_CARBON
783 SetPort (GetWindowPort (w
));
789 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
791 FrameRect (&r
); /* using foreground color of gc */
795 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
798 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
803 unsigned int width
, height
;
805 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
808 #if TARGET_API_MAC_CARBON
809 SetPort (GetWindowPort (w
));
815 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
817 FrameRect (&r
); /* using foreground color of gc */
823 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
830 int nchars
, mode
, bytes_per_char
;
832 #if TARGET_API_MAC_CARBON
833 SetPort (GetWindowPort (w
));
840 TextFont (gc
->font
->mac_fontnum
);
841 TextSize (gc
->font
->mac_fontsize
);
842 TextFace (gc
->font
->mac_fontface
);
846 DrawText (buf
, 0, nchars
* bytes_per_char
);
850 /* Mac replacement for XDrawString. */
853 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
861 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
865 /* Mac replacement for XDrawString16. */
868 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
876 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
881 /* Mac replacement for XDrawImageString. */
884 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
892 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
896 /* Mac replacement for XDrawString16. */
899 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
907 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
912 /* Mac replacement for XCopyArea: dest must be window. */
915 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
922 unsigned int width
, height
;
927 #if TARGET_API_MAC_CARBON
928 SetPort (GetWindowPort (dest
));
935 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
936 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
938 #if TARGET_API_MAC_CARBON
942 LockPortBits (GetWindowPort (dest
));
943 pmh
= GetPortPixMap (GetWindowPort (dest
));
944 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
945 UnlockPortBits (GetWindowPort (dest
));
947 #else /* not TARGET_API_MAC_CARBON */
948 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
949 #endif /* not TARGET_API_MAC_CARBON */
954 /* Convert a pair of local coordinates to global (screen) coordinates.
955 Assume graphic port has been properly set. */
957 local_to_global_coord (short *h
, short *v
)
971 /* Mac replacement for XCopyArea: used only for scrolling. */
974 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
979 unsigned int width
, height
;
982 #if TARGET_API_MAC_CARBON
983 Rect gw_r
, src_r
, dest_r
;
986 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
987 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
989 SetPort (GetWindowPort (w
));
991 ForeColor (blackColor
);
992 BackColor (whiteColor
);
994 LockPortBits (GetWindowPort (w
));
995 pmh
= GetPortPixMap (GetWindowPort (w
));
996 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
997 UnlockPortBits (GetWindowPort (w
));
1000 #else /* not TARGET_API_MAC_CARBON */
1005 mac_set_colors (gc
);
1008 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1009 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1012 /* Need to use global coordinates and screenBits since src and dest
1013 areas overlap in general. */
1014 local_to_global_coord (&src_r
.left
, &src_r
.top
);
1015 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
1016 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
1017 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
1019 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
1021 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1022 color mapping in CopyBits. Otherwise, it will be slow. */
1023 ForeColor (blackColor
);
1024 BackColor (whiteColor
);
1025 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1027 mac_set_colors (gc
);
1029 #endif /* not TARGET_API_MAC_CARBON */
1033 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1036 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1043 unsigned int width
, height
;
1047 int src_right
= ((PixMap
*) src
)->bounds
.right
;
1048 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
1049 int w
= src_right
- src_x
;
1050 int h
= src_bottom
- src_y
;
1052 mac_set_colors (gc
);
1054 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
1055 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
1057 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
1061 /* Mac replacement for XChangeGC. */
1064 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1067 if (mask
& GCForeground
)
1068 gc
->foreground
= xgcv
->foreground
;
1069 if (mask
& GCBackground
)
1070 gc
->background
= xgcv
->background
;
1072 gc
->font
= xgcv
->font
;
1076 /* Mac replacement for XCreateGC. */
1079 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1082 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1083 bzero (gc
, sizeof (XGCValues
));
1085 XChangeGC (ignore
, gc
, mask
, xgcv
);
1091 /* Used in xfaces.c. */
1094 XFreeGC (display
, gc
)
1102 /* Mac replacement for XGetGCValues. */
1105 XGetGCValues (void* ignore
, XGCValues
*gc
,
1106 unsigned long mask
, XGCValues
*xgcv
)
1108 XChangeGC (ignore
, xgcv
, mask
, gc
);
1112 /* Mac replacement for XSetForeground. */
1115 XSetForeground (display
, gc
, color
)
1118 unsigned long color
;
1120 gc
->foreground
= color
;
1124 /* Mac replacement for XSetFont. */
1127 XSetFont (display
, gc
, font
)
1137 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1138 int *direction
,int *font_ascent
,
1139 int *font_descent
, XCharStruct
*cs
)
1141 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1145 /* x_sync is a no-op on Mac. */
1153 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1154 Calls to XFlush should be unnecessary because the X output buffer
1155 is flushed automatically as needed by calls to XPending,
1156 XNextEvent, or XWindowEvent according to the XFlush man page.
1157 XTread_socket calls XPending. Removing XFlush improves
1160 #if TARGET_API_MAC_CARBON
1161 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1163 #define XFlush(DISPLAY) (void) 0
1166 /* Flush display of frame F, or of all frames if F is null. */
1172 #if TARGET_API_MAC_CARBON
1176 Lisp_Object rest
, frame
;
1177 FOR_EACH_FRAME (rest
, frame
)
1178 x_flush (XFRAME (frame
));
1180 else if (FRAME_X_P (f
))
1181 XFlush (FRAME_MAC_DISPLAY (f
));
1183 #endif /* TARGET_API_MAC_CARBON */
1188 /* Return the struct mac_display_info corresponding to DPY. There's
1191 struct mac_display_info
*
1192 mac_display_info_for_display (dpy
)
1195 return &one_mac_display_info
;
1200 /***********************************************************************
1201 Starting and ending an update
1202 ***********************************************************************/
1204 /* Start an update of frame F. This function is installed as a hook
1205 for update_begin, i.e. it is called when update_begin is called.
1206 This function is called prior to calls to x_update_window_begin for
1207 each window being updated. */
1213 /* Nothing to do. */
1217 /* Start update of window W. Set the global variable updated_window
1218 to the window being updated and set output_cursor to the cursor
1222 x_update_window_begin (w
)
1225 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1226 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1229 set_output_cursor (&w
->cursor
);
1233 if (f
== display_info
->mouse_face_mouse_frame
)
1235 /* Don't do highlighting for mouse motion during the update. */
1236 display_info
->mouse_face_defer
= 1;
1238 /* If F needs to be redrawn, simply forget about any prior mouse
1240 if (FRAME_GARBAGED_P (f
))
1241 display_info
->mouse_face_window
= Qnil
;
1243 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1244 their mouse_face_p flag set, which means that they are always
1245 unequal to rows in a desired matrix which never have that
1246 flag set. So, rows containing mouse-face glyphs are never
1247 scrolled, and we don't have to switch the mouse highlight off
1248 here to prevent it from being scrolled. */
1250 /* Can we tell that this update does not affect the window
1251 where the mouse highlight is? If so, no need to turn off.
1252 Likewise, don't do anything if the frame is garbaged;
1253 in that case, the frame's current matrix that we would use
1254 is all wrong, and we will redisplay that line anyway. */
1255 if (!NILP (display_info
->mouse_face_window
)
1256 && w
== XWINDOW (display_info
->mouse_face_window
))
1260 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1261 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1264 if (i
< w
->desired_matrix
->nrows
)
1265 clear_mouse_face (display_info
);
1274 /* Draw a vertical window border to the right of window W if W doesn't
1275 have vertical scroll bars. */
1278 x_draw_vertical_border (w
)
1281 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1283 /* Redraw borders between horizontally adjacent windows. Don't
1284 do it for frames with vertical scroll bars because either the
1285 right scroll bar of a window, or the left scroll bar of its
1286 neighbor will suffice as a border. */
1287 if (!WINDOW_RIGHTMOST_P (w
)
1288 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1292 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1293 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1296 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1297 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1302 /* End update of window W (which is equal to updated_window).
1304 Draw vertical borders between horizontally adjacent windows, and
1305 display W's cursor if CURSOR_ON_P is non-zero.
1307 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1308 glyphs in mouse-face were overwritten. In that case we have to
1309 make sure that the mouse-highlight is properly redrawn.
1311 W may be a menu bar pseudo-window in case we don't have X toolkit
1312 support. Such windows don't have a cursor, so don't display it
1316 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1318 int cursor_on_p
, mouse_face_overwritten_p
;
1320 struct mac_display_info
*dpyinfo
1321 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1323 if (!w
->pseudo_window_p
)
1328 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1330 output_cursor
.x
, output_cursor
.y
);
1332 x_draw_vertical_border (w
);
1336 /* If a row with mouse-face was overwritten, arrange for
1337 XTframe_up_to_date to redisplay the mouse highlight. */
1338 if (mouse_face_overwritten_p
)
1340 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1341 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1342 dpyinfo
->mouse_face_window
= Qnil
;
1346 /* Unhide the caret. This won't actually show the cursor, unless it
1347 was visible before the corresponding call to HideCaret in
1348 x_update_window_begin. */
1349 if (w32_use_visible_system_caret
)
1350 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1353 updated_window
= NULL
;
1357 /* End update of frame F. This function is installed as a hook in
1364 /* Reset the background color of Mac OS Window to that of the frame after
1365 update so that it is used by Mac Toolbox to clear the update region before
1366 an update event is generated. */
1367 #if TARGET_API_MAC_CARBON
1368 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1370 SetPort (FRAME_MAC_WINDOW (f
));
1373 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1375 /* Mouse highlight may be displayed again. */
1376 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1379 XFlush (FRAME_MAC_DISPLAY (f
));
1384 /* This function is called from various places in xdisp.c whenever a
1385 complete update has been performed. The global variable
1386 updated_window is not available here. */
1389 XTframe_up_to_date (f
)
1394 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1396 if (dpyinfo
->mouse_face_deferred_gc
1397 || f
== dpyinfo
->mouse_face_mouse_frame
)
1400 if (dpyinfo
->mouse_face_mouse_frame
)
1401 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1402 dpyinfo
->mouse_face_mouse_x
,
1403 dpyinfo
->mouse_face_mouse_y
);
1404 dpyinfo
->mouse_face_deferred_gc
= 0;
1411 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1412 arrow bitmaps, or clear the fringes if no bitmaps are required
1413 before DESIRED_ROW is made current. The window being updated is
1414 found in updated_window. This function is called from
1415 update_window_line only if it is known that there are differences
1416 between bitmaps to be drawn between current row and DESIRED_ROW. */
1419 x_after_update_window_line (desired_row
)
1420 struct glyph_row
*desired_row
;
1422 struct window
*w
= updated_window
;
1428 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1431 x_draw_row_fringe_bitmaps (w
, desired_row
);
1435 /* When a window has disappeared, make sure that no rest of
1436 full-width rows stays visible in the internal border. Could
1437 check here if updated_window is the leftmost/rightmost window,
1438 but I guess it's not worth doing since vertically split windows
1439 are almost never used, internal border is rarely set, and the
1440 overhead is very small. */
1441 if (windows_or_buffers_changed
1442 && desired_row
->full_width_p
1443 && (f
= XFRAME (w
->frame
),
1444 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1446 && (height
= desired_row
->visible_height
,
1449 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1450 /* Internal border is drawn below the tool bar. */
1451 if (WINDOWP (f
->tool_bar_window
)
1452 && w
== XWINDOW (f
->tool_bar_window
))
1457 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1458 0, y
, width
, height
, 0);
1459 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1460 f
->output_data
.mac
->pixel_width
- width
, y
,
1468 /* Draw the bitmap WHICH in one of the left or right fringes of
1469 window W. ROW is the glyph row for which to display the bitmap; it
1470 determines the vertical position at which the bitmap has to be
1474 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1476 struct glyph_row
*row
;
1477 enum fringe_bitmap_type which
;
1480 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1481 Display
*display
= FRAME_MAC_DISPLAY (f
);
1482 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1483 int x
, y
, wd
, h
, dy
;
1485 unsigned char *bits
;
1488 GC gc
= f
->output_data
.mac
->normal_gc
;
1491 /* Must clip because of partially visible lines. */
1492 x_clip_to_row (w
, row
, gc
, 1);
1494 /* Convert row to frame coordinates. */
1495 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1499 case NO_FRINGE_BITMAP
:
1504 case LEFT_TRUNCATION_BITMAP
:
1510 case OVERLAY_ARROW_BITMAP
:
1516 case RIGHT_TRUNCATION_BITMAP
:
1522 case CONTINUED_LINE_BITMAP
:
1523 wd
= continued_width
;
1524 h
= continued_height
;
1525 bits
= continued_bits
;
1528 case CONTINUATION_LINE_BITMAP
:
1529 wd
= continuation_width
;
1530 h
= continuation_height
;
1531 bits
= continuation_bits
;
1534 case ZV_LINE_BITMAP
:
1536 h
= zv_height
- (y
% zv_period
);
1537 bits
= zv_bits
+ (y
% zv_period
);
1544 /* Clip bitmap if too high. */
1545 if (h
> row
->height
)
1548 /* Set dy to the offset in the row to start drawing the bitmap. */
1549 dy
= (row
->height
- h
) / 2;
1551 /* Draw the bitmap. */
1552 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1553 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1555 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1560 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1561 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1562 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1564 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1565 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1567 /* If W has a vertical border to its left, don't draw over it. */
1568 int border
= ((XFASTINT (w
->left
) > 0
1569 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1571 b1
= (window_box_left (w
, -1)
1572 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1574 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1579 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1580 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1581 x
= (window_box_right (w
, -1)
1582 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1583 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1585 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1587 b1
= window_box_right (w
, -1);
1588 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1594 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1596 gcv
.foreground
= face
->background
;
1598 #if 0 /* MAC_TODO: stipple */
1599 /* In case the same realized face is used for fringes and
1600 for something displayed in the text (e.g. face `region' on
1601 mono-displays, the fill style may have been changed to
1602 FillSolid in x_draw_glyph_string_background. */
1604 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1606 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1609 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1612 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1615 row
->visible_height
);
1617 #if 0 /* MAC_TODO: stipple */
1619 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1623 if (which
== NO_FRINGE_BITMAP
)
1625 mac_reset_clipping (display
, window
);
1629 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1630 gcv
.foreground
= face
->foreground
;
1631 gcv
.background
= face
->background
;
1633 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1635 mac_free_bitmap (&bitmap
);
1636 mac_reset_clipping (display
, window
);
1640 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1641 function with input blocked. */
1644 x_draw_row_fringe_bitmaps (w
, row
)
1646 struct glyph_row
*row
;
1648 struct frame
*f
= XFRAME (w
->frame
);
1649 enum fringe_bitmap_type bitmap
;
1651 xassert (interrupt_input_blocked
);
1653 /* If row is completely invisible, because of vscrolling, we
1654 don't have to draw anything. */
1655 if (row
->visible_height
<= 0)
1658 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1660 /* Decide which bitmap to draw in the left fringe. */
1661 if (row
->overlay_arrow_p
)
1662 bitmap
= OVERLAY_ARROW_BITMAP
;
1663 else if (row
->truncated_on_left_p
)
1664 bitmap
= LEFT_TRUNCATION_BITMAP
;
1665 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1666 bitmap
= CONTINUATION_LINE_BITMAP
;
1667 else if (row
->indicate_empty_line_p
)
1668 bitmap
= ZV_LINE_BITMAP
;
1670 bitmap
= NO_FRINGE_BITMAP
;
1672 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1675 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1677 /* Decide which bitmap to draw in the right fringe. */
1678 if (row
->truncated_on_right_p
)
1679 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1680 else if (row
->continued_p
)
1681 bitmap
= CONTINUED_LINE_BITMAP
;
1682 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1683 bitmap
= ZV_LINE_BITMAP
;
1685 bitmap
= NO_FRINGE_BITMAP
;
1687 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1692 /* This is called when starting Emacs and when restarting after
1693 suspend. When starting Emacs, no window is mapped. And nothing
1694 must be done to Emacs's own window if it is suspended (though that
1698 XTset_terminal_modes ()
1702 /* This is called when exiting or suspending Emacs. Exiting will make
1703 the windows go away, and suspending requires no action. */
1706 XTreset_terminal_modes ()
1712 /***********************************************************************
1714 ***********************************************************************/
1716 /* Set the global variable output_cursor to CURSOR. All cursor
1717 positions are relative to updated_window. */
1720 set_output_cursor (cursor
)
1721 struct cursor_pos
*cursor
;
1723 output_cursor
.hpos
= cursor
->hpos
;
1724 output_cursor
.vpos
= cursor
->vpos
;
1725 output_cursor
.x
= cursor
->x
;
1726 output_cursor
.y
= cursor
->y
;
1730 /* Set a nominal cursor position.
1732 HPOS and VPOS are column/row positions in a window glyph matrix. X
1733 and Y are window text area relative pixel positions.
1735 If this is done during an update, updated_window will contain the
1736 window that is being updated and the position is the future output
1737 cursor position for that window. If updated_window is null, use
1738 selected_window and display the cursor at the given position. */
1741 XTcursor_to (vpos
, hpos
, y
, x
)
1742 int vpos
, hpos
, y
, x
;
1746 /* If updated_window is not set, work on selected_window. */
1750 w
= XWINDOW (selected_window
);
1752 /* Set the output cursor. */
1753 output_cursor
.hpos
= hpos
;
1754 output_cursor
.vpos
= vpos
;
1755 output_cursor
.x
= x
;
1756 output_cursor
.y
= y
;
1758 /* If not called as part of an update, really display the cursor.
1759 This will also set the cursor position of W. */
1760 if (updated_window
== NULL
)
1763 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1764 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1771 /***********************************************************************
1773 ***********************************************************************/
1775 /* Function prototypes of this page. */
1777 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1781 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1782 int, XChar2b
*, int));
1783 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1784 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1785 static void x_append_glyph
P_ ((struct it
*));
1786 static void x_append_composite_glyph
P_ ((struct it
*));
1787 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1789 static void x_produce_glyphs
P_ ((struct it
*));
1790 static void x_produce_image_glyph
P_ ((struct it
*it
));
1793 /* Return a pointer to per-char metric information in FONT of a
1794 character pointed by B which is a pointer to an XChar2b. */
1796 #define PER_CHAR_METRIC(font, b) \
1798 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1799 + (((font)->min_byte1 || (font)->max_byte1) \
1800 ? (((b)->byte1 - (font)->min_byte1) \
1801 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1803 : &((font)->max_bounds))
1806 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1807 is not contained in the font. */
1809 static INLINE XCharStruct
*
1810 x_per_char_metric (font
, char2b
)
1814 /* The result metric information. */
1815 XCharStruct
*pcm
= NULL
;
1817 xassert (font
&& char2b
);
1819 if (font
->per_char
!= NULL
)
1821 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1823 /* min_char_or_byte2 specifies the linear character index
1824 corresponding to the first element of the per_char array,
1825 max_char_or_byte2 is the index of the last character. A
1826 character with non-zero CHAR2B->byte1 is not in the font.
1827 A character with byte2 less than min_char_or_byte2 or
1828 greater max_char_or_byte2 is not in the font. */
1829 if (char2b
->byte1
== 0
1830 && char2b
->byte2
>= font
->min_char_or_byte2
1831 && char2b
->byte2
<= font
->max_char_or_byte2
)
1832 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1836 /* If either min_byte1 or max_byte1 are nonzero, both
1837 min_char_or_byte2 and max_char_or_byte2 are less than
1838 256, and the 2-byte character index values corresponding
1839 to the per_char array element N (counting from 0) are:
1841 byte1 = N/D + min_byte1
1842 byte2 = N\D + min_char_or_byte2
1846 D = max_char_or_byte2 - min_char_or_byte2 + 1
1847 / = integer division
1848 \ = integer modulus */
1849 if (char2b
->byte1
>= font
->min_byte1
1850 && char2b
->byte1
<= font
->max_byte1
1851 && char2b
->byte2
>= font
->min_char_or_byte2
1852 && char2b
->byte2
<= font
->max_char_or_byte2
)
1854 pcm
= (font
->per_char
1855 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1856 * (char2b
->byte1
- font
->min_byte1
))
1857 + (char2b
->byte2
- font
->min_char_or_byte2
));
1863 /* If the per_char pointer is null, all glyphs between the first
1864 and last character indexes inclusive have the same
1865 information, as given by both min_bounds and max_bounds. */
1866 if (char2b
->byte2
>= font
->min_char_or_byte2
1867 && char2b
->byte2
<= font
->max_char_or_byte2
)
1868 pcm
= &font
->max_bounds
;
1871 return ((pcm
== NULL
1872 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1877 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1878 the two-byte form of C. Encoding is returned in *CHAR2B. */
1881 x_encode_char (c
, char2b
, font_info
)
1884 struct font_info
*font_info
;
1886 int charset
= CHAR_CHARSET (c
);
1887 XFontStruct
*font
= font_info
->font
;
1889 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1890 This may be either a program in a special encoder language or a
1892 if (font_info
->font_encoder
)
1894 /* It's a program. */
1895 struct ccl_program
*ccl
= font_info
->font_encoder
;
1897 if (CHARSET_DIMENSION (charset
) == 1)
1899 ccl
->reg
[0] = charset
;
1900 ccl
->reg
[1] = char2b
->byte2
;
1904 ccl
->reg
[0] = charset
;
1905 ccl
->reg
[1] = char2b
->byte1
;
1906 ccl
->reg
[2] = char2b
->byte2
;
1909 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1911 /* We assume that MSBs are appropriately set/reset by CCL
1913 if (font
->max_byte1
== 0) /* 1-byte font */
1914 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1916 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1918 else if (font_info
->encoding
[charset
])
1920 /* Fixed encoding scheme. See fontset.h for the meaning of the
1921 encoding numbers. */
1922 int enc
= font_info
->encoding
[charset
];
1924 if ((enc
== 1 || enc
== 2)
1925 && CHARSET_DIMENSION (charset
) == 2)
1926 char2b
->byte1
|= 0x80;
1928 if (enc
== 1 || enc
== 3)
1929 char2b
->byte2
|= 0x80;
1935 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1936 char2b
->byte1
= sjis1
;
1937 char2b
->byte2
= sjis2
;
1943 /* Get face and two-byte form of character C in face FACE_ID on frame
1944 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1945 means we want to display multibyte text. Value is a pointer to a
1946 realized face that is ready for display. */
1948 static INLINE
struct face
*
1949 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1955 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1959 /* Unibyte case. We don't have to encode, but we have to make
1960 sure to use a face suitable for unibyte. */
1963 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1964 face
= FACE_FROM_ID (f
, face_id
);
1966 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1968 /* Case of ASCII in a face known to fit ASCII. */
1974 int c1
, c2
, charset
;
1976 /* Split characters into bytes. If c2 is -1 afterwards, C is
1977 really a one-byte character so that byte1 is zero. */
1978 SPLIT_CHAR (c
, charset
, c1
, c2
);
1980 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1982 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1984 /* Maybe encode the character in *CHAR2B. */
1985 if (face
->font
!= NULL
)
1987 struct font_info
*font_info
1988 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1990 x_encode_char (c
, char2b
, font_info
);
1994 /* Make sure X resources of the face are allocated. */
1995 xassert (face
!= NULL
);
1996 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2002 /* Get face and two-byte form of character glyph GLYPH on frame F.
2003 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
2004 a pointer to a realized face that is ready for display. */
2006 static INLINE
struct face
*
2007 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
2009 struct glyph
*glyph
;
2015 xassert (glyph
->type
== CHAR_GLYPH
);
2016 face
= FACE_FROM_ID (f
, glyph
->face_id
);
2021 if (!glyph
->multibyte_p
)
2023 /* Unibyte case. We don't have to encode, but we have to make
2024 sure to use a face suitable for unibyte. */
2026 char2b
->byte2
= glyph
->u
.ch
;
2028 else if (glyph
->u
.ch
< 128
2029 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
2031 /* Case of ASCII in a face known to fit ASCII. */
2033 char2b
->byte2
= glyph
->u
.ch
;
2037 int c1
, c2
, charset
;
2039 /* Split characters into bytes. If c2 is -1 afterwards, C is
2040 really a one-byte character so that byte1 is zero. */
2041 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
2043 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
2045 char2b
->byte1
= 0, char2b
->byte2
= c1
;
2047 /* Maybe encode the character in *CHAR2B. */
2048 if (charset
!= CHARSET_ASCII
)
2050 struct font_info
*font_info
2051 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2054 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
2057 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2062 /* Make sure X resources of the face are allocated. */
2063 xassert (face
!= NULL
);
2064 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2069 /* Store one glyph for IT->char_to_display in IT->glyph_row.
2070 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2076 struct glyph
*glyph
;
2077 enum glyph_row_area area
= it
->area
;
2079 xassert (it
->glyph_row
);
2080 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
2082 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2083 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2085 glyph
->charpos
= CHARPOS (it
->position
);
2086 glyph
->object
= it
->object
;
2087 glyph
->pixel_width
= it
->pixel_width
;
2088 glyph
->voffset
= it
->voffset
;
2089 glyph
->type
= CHAR_GLYPH
;
2090 glyph
->multibyte_p
= it
->multibyte_p
;
2091 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2092 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2093 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2094 || it
->phys_descent
> it
->descent
);
2095 glyph
->padding_p
= 0;
2096 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
2097 glyph
->face_id
= it
->face_id
;
2098 glyph
->u
.ch
= it
->char_to_display
;
2099 ++it
->glyph_row
->used
[area
];
2103 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
2104 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2107 x_append_composite_glyph (it
)
2110 struct glyph
*glyph
;
2111 enum glyph_row_area area
= it
->area
;
2113 xassert (it
->glyph_row
);
2115 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2116 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2118 glyph
->charpos
= CHARPOS (it
->position
);
2119 glyph
->object
= it
->object
;
2120 glyph
->pixel_width
= it
->pixel_width
;
2121 glyph
->voffset
= it
->voffset
;
2122 glyph
->type
= COMPOSITE_GLYPH
;
2123 glyph
->multibyte_p
= it
->multibyte_p
;
2124 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2125 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2126 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2127 || it
->phys_descent
> it
->descent
);
2128 glyph
->padding_p
= 0;
2129 glyph
->glyph_not_available_p
= 0;
2130 glyph
->face_id
= it
->face_id
;
2131 glyph
->u
.cmp_id
= it
->cmp_id
;
2132 ++it
->glyph_row
->used
[area
];
2137 /* Change IT->ascent and IT->height according to the setting of
2141 take_vertical_position_into_account (it
)
2146 if (it
->voffset
< 0)
2147 /* Increase the ascent so that we can display the text higher
2149 it
->ascent
+= abs (it
->voffset
);
2151 /* Increase the descent so that we can display the text lower
2153 it
->descent
+= it
->voffset
;
2158 /* Produce glyphs/get display metrics for the image IT is loaded with.
2159 See the description of struct display_iterator in dispextern.h for
2160 an overview of struct display_iterator. */
2163 x_produce_image_glyph (it
)
2169 xassert (it
->what
== IT_IMAGE
);
2171 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2172 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2175 /* Make sure X resources of the face and image are loaded. */
2176 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2177 prepare_image_for_display (it
->f
, img
);
2179 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2180 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2181 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2185 if (face
->box
!= FACE_NO_BOX
)
2187 if (face
->box_line_width
> 0)
2189 it
->ascent
+= face
->box_line_width
;
2190 it
->descent
+= face
->box_line_width
;
2193 if (it
->start_of_box_run_p
)
2194 it
->pixel_width
+= abs (face
->box_line_width
);
2195 if (it
->end_of_box_run_p
)
2196 it
->pixel_width
+= abs (face
->box_line_width
);
2199 take_vertical_position_into_account (it
);
2203 struct glyph
*glyph
;
2204 enum glyph_row_area area
= it
->area
;
2206 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2207 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2209 glyph
->charpos
= CHARPOS (it
->position
);
2210 glyph
->object
= it
->object
;
2211 glyph
->pixel_width
= it
->pixel_width
;
2212 glyph
->voffset
= it
->voffset
;
2213 glyph
->type
= IMAGE_GLYPH
;
2214 glyph
->multibyte_p
= it
->multibyte_p
;
2215 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2216 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2217 glyph
->overlaps_vertically_p
= 0;
2218 glyph
->padding_p
= 0;
2219 glyph
->glyph_not_available_p
= 0;
2220 glyph
->face_id
= it
->face_id
;
2221 glyph
->u
.img_id
= img
->id
;
2222 ++it
->glyph_row
->used
[area
];
2228 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2229 of the glyph, WIDTH and HEIGHT are the width and height of the
2230 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2231 ascent of the glyph (0 <= ASCENT <= 1). */
2234 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2240 struct glyph
*glyph
;
2241 enum glyph_row_area area
= it
->area
;
2243 xassert (ascent
>= 0 && ascent
<= 1);
2245 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2246 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2248 glyph
->charpos
= CHARPOS (it
->position
);
2249 glyph
->object
= object
;
2250 glyph
->pixel_width
= width
;
2251 glyph
->voffset
= it
->voffset
;
2252 glyph
->type
= STRETCH_GLYPH
;
2253 glyph
->multibyte_p
= it
->multibyte_p
;
2254 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2255 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2256 glyph
->overlaps_vertically_p
= 0;
2257 glyph
->padding_p
= 0;
2258 glyph
->glyph_not_available_p
= 0;
2259 glyph
->face_id
= it
->face_id
;
2260 glyph
->u
.stretch
.ascent
= height
* ascent
;
2261 glyph
->u
.stretch
.height
= height
;
2262 ++it
->glyph_row
->used
[area
];
2267 /* Produce a stretch glyph for iterator IT. IT->object is the value
2268 of the glyph property displayed. The value must be a list
2269 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2272 1. `:width WIDTH' specifies that the space should be WIDTH *
2273 canonical char width wide. WIDTH may be an integer or floating
2276 2. `:relative-width FACTOR' specifies that the width of the stretch
2277 should be computed from the width of the first character having the
2278 `glyph' property, and should be FACTOR times that width.
2280 3. `:align-to HPOS' specifies that the space should be wide enough
2281 to reach HPOS, a value in canonical character units.
2283 Exactly one of the above pairs must be present.
2285 4. `:height HEIGHT' specifies that the height of the stretch produced
2286 should be HEIGHT, measured in canonical character units.
2288 5. `:relative-height FACTOR' specifies that the height of the
2289 stretch should be FACTOR times the height of the characters having
2292 Either none or exactly one of 4 or 5 must be present.
2294 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2295 of the stretch should be used for the ascent of the stretch.
2296 ASCENT must be in the range 0 <= ASCENT <= 100. */
2299 ((INTEGERP (X) || FLOATP (X)) \
2305 x_produce_stretch_glyph (it
)
2308 /* (space :width WIDTH :height HEIGHT. */
2310 extern Lisp_Object Qspace
;
2312 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2313 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2314 extern Lisp_Object QCalign_to
;
2315 Lisp_Object prop
, plist
;
2316 double width
= 0, height
= 0, ascent
= 0;
2317 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2318 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2320 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2322 /* List should start with `space'. */
2323 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2324 plist
= XCDR (it
->object
);
2326 /* Compute the width of the stretch. */
2327 if (prop
= Fplist_get (plist
, QCwidth
),
2329 /* Absolute width `:width WIDTH' specified and valid. */
2330 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2331 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2334 /* Relative width `:relative-width FACTOR' specified and valid.
2335 Compute the width of the characters having the `glyph'
2338 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2341 if (it
->multibyte_p
)
2343 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2344 - IT_BYTEPOS (*it
));
2345 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2348 it2
.c
= *p
, it2
.len
= 1;
2350 it2
.glyph_row
= NULL
;
2351 it2
.what
= IT_CHARACTER
;
2352 x_produce_glyphs (&it2
);
2353 width
= NUMVAL (prop
) * it2
.pixel_width
;
2355 else if (prop
= Fplist_get (plist
, QCalign_to
),
2357 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2359 /* Nothing specified -> width defaults to canonical char width. */
2360 width
= CANON_X_UNIT (it
->f
);
2362 /* Compute height. */
2363 if (prop
= Fplist_get (plist
, QCheight
),
2365 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2366 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2368 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2370 height
= FONT_HEIGHT (font
);
2372 /* Compute percentage of height used for ascent. If
2373 `:ascent ASCENT' is present and valid, use that. Otherwise,
2374 derive the ascent from the font in use. */
2375 if (prop
= Fplist_get (plist
, QCascent
),
2376 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2377 ascent
= NUMVAL (prop
) / 100.0;
2379 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2388 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2389 if (!STRINGP (object
))
2390 object
= it
->w
->buffer
;
2391 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2394 it
->pixel_width
= width
;
2395 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2396 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2399 if (face
->box
!= FACE_NO_BOX
)
2401 if (face
->box_line_width
> 0)
2403 it
->ascent
+= face
->box_line_width
;
2404 it
->descent
+= face
->box_line_width
;
2407 if (it
->start_of_box_run_p
)
2408 it
->pixel_width
+= abs (face
->box_line_width
);
2409 if (it
->end_of_box_run_p
)
2410 it
->pixel_width
+= abs (face
->box_line_width
);
2413 take_vertical_position_into_account (it
);
2416 /* Return proper value to be used as baseline offset of font that has
2417 ASCENT and DESCENT to draw characters by the font at the vertical
2418 center of the line of frame F.
2420 Here, out task is to find the value of BOFF in the following figure;
2422 -------------------------+-----------+-
2423 -+-+---------+-+ | |
2425 | | | | F_ASCENT F_HEIGHT
2428 | | |-|-+------+-----------|------- baseline
2430 | |---------|-+-+ | |
2432 -+-+---------+-+ F_DESCENT |
2433 -------------------------+-----------+-
2435 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2436 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2437 DESCENT = FONT->descent
2438 HEIGHT = FONT_HEIGHT (FONT)
2439 F_DESCENT = (F->output_data.x->font->descent
2440 - F->output_data.x->baseline_offset)
2441 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2444 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2445 (FONT_DESCENT (FONT) \
2446 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2447 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2448 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2450 /* Produce glyphs/get display metrics for the display element IT is
2451 loaded with. See the description of struct display_iterator in
2452 dispextern.h for an overview of struct display_iterator. */
2455 x_produce_glyphs (it
)
2458 it
->glyph_not_available_p
= 0;
2460 if (it
->what
== IT_CHARACTER
)
2464 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2466 int font_not_found_p
;
2467 struct font_info
*font_info
;
2468 int boff
; /* baseline offset */
2469 /* We may change it->multibyte_p upon unibyte<->multibyte
2470 conversion. So, save the current value now and restore it
2473 Note: It seems that we don't have to record multibyte_p in
2474 struct glyph because the character code itself tells if or
2475 not the character is multibyte. Thus, in the future, we must
2476 consider eliminating the field `multibyte_p' in the struct
2479 int saved_multibyte_p
= it
->multibyte_p
;
2481 /* Maybe translate single-byte characters to multibyte, or the
2483 it
->char_to_display
= it
->c
;
2484 if (!ASCII_BYTE_P (it
->c
))
2486 if (unibyte_display_via_language_environment
2487 && SINGLE_BYTE_CHAR_P (it
->c
)
2489 || !NILP (Vnonascii_translation_table
)))
2491 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2492 it
->multibyte_p
= 1;
2493 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2494 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2496 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2497 && !it
->multibyte_p
)
2499 it
->multibyte_p
= 1;
2500 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2501 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2505 /* Get font to use. Encode IT->char_to_display. */
2506 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2507 it
->face_id
, &char2b
,
2511 /* When no suitable font found, use the default font. */
2512 font_not_found_p
= font
== NULL
;
2513 if (font_not_found_p
)
2515 font
= FRAME_FONT (it
->f
);
2516 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2521 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2522 boff
= font_info
->baseline_offset
;
2523 if (font_info
->vertical_centering
)
2524 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2527 if (it
->char_to_display
>= ' '
2528 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2530 /* Either unibyte or ASCII. */
2535 pcm
= x_per_char_metric (font
, &char2b
);
2536 it
->ascent
= FONT_BASE (font
) + boff
;
2537 it
->descent
= FONT_DESCENT (font
) - boff
;
2541 it
->phys_ascent
= pcm
->ascent
+ boff
;
2542 it
->phys_descent
= pcm
->descent
- boff
;
2543 it
->pixel_width
= pcm
->width
;
2547 it
->glyph_not_available_p
= 1;
2548 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2549 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2550 it
->pixel_width
= FONT_WIDTH (font
);
2553 /* If this is a space inside a region of text with
2554 `space-width' property, change its width. */
2555 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2557 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2559 /* If face has a box, add the box thickness to the character
2560 height. If character has a box line to the left and/or
2561 right, add the box line width to the character's width. */
2562 if (face
->box
!= FACE_NO_BOX
)
2564 int thick
= face
->box_line_width
;
2568 it
->ascent
+= thick
;
2569 it
->descent
+= thick
;
2574 if (it
->start_of_box_run_p
)
2575 it
->pixel_width
+= thick
;
2576 if (it
->end_of_box_run_p
)
2577 it
->pixel_width
+= thick
;
2580 /* If face has an overline, add the height of the overline
2581 (1 pixel) and a 1 pixel margin to the character height. */
2582 if (face
->overline_p
)
2585 take_vertical_position_into_account (it
);
2587 /* If we have to actually produce glyphs, do it. */
2592 /* Translate a space with a `space-width' property
2593 into a stretch glyph. */
2594 double ascent
= (double) FONT_BASE (font
)
2595 / FONT_HEIGHT (font
);
2596 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2597 it
->ascent
+ it
->descent
, ascent
);
2600 x_append_glyph (it
);
2602 /* If characters with lbearing or rbearing are displayed
2603 in this line, record that fact in a flag of the
2604 glyph row. This is used to optimize X output code. */
2605 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2606 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2609 else if (it
->char_to_display
== '\n')
2611 /* A newline has no width but we need the height of the line. */
2612 it
->pixel_width
= 0;
2614 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2615 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2617 if (face
->box
!= FACE_NO_BOX
2618 && face
->box_line_width
> 0)
2620 it
->ascent
+= face
->box_line_width
;
2621 it
->descent
+= face
->box_line_width
;
2624 else if (it
->char_to_display
== '\t')
2626 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2627 int x
= it
->current_x
+ it
->continuation_lines_width
;
2628 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2630 /* If the distance from the current position to the next tab
2631 stop is less than a canonical character width, use the
2632 tab stop after that. */
2633 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2634 next_tab_x
+= tab_width
;
2636 it
->pixel_width
= next_tab_x
- x
;
2638 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2639 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2643 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2644 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2645 it
->ascent
+ it
->descent
, ascent
);
2650 /* A multi-byte character. Assume that the display width of the
2651 character is the width of the character multiplied by the
2652 width of the font. */
2654 /* If we found a font, this font should give us the right
2655 metrics. If we didn't find a font, use the frame's
2656 default font and calculate the width of the character
2657 from the charset width; this is what old redisplay code
2659 pcm
= x_per_char_metric (font
, &char2b
);
2660 if (font_not_found_p
|| !pcm
)
2662 int charset
= CHAR_CHARSET (it
->char_to_display
);
2664 it
->glyph_not_available_p
= 1;
2665 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2666 * CHARSET_WIDTH (charset
));
2667 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2668 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2672 it
->pixel_width
= pcm
->width
;
2673 it
->phys_ascent
= pcm
->ascent
+ boff
;
2674 it
->phys_descent
= pcm
->descent
- boff
;
2676 && (pcm
->lbearing
< 0
2677 || pcm
->rbearing
> pcm
->width
))
2678 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2681 it
->ascent
= FONT_BASE (font
) + boff
;
2682 it
->descent
= FONT_DESCENT (font
) - boff
;
2683 if (face
->box
!= FACE_NO_BOX
)
2685 int thick
= face
->box_line_width
;
2689 it
->ascent
+= thick
;
2690 it
->descent
+= thick
;
2695 if (it
->start_of_box_run_p
)
2696 it
->pixel_width
+= thick
;
2697 if (it
->end_of_box_run_p
)
2698 it
->pixel_width
+= thick
;
2701 /* If face has an overline, add the height of the overline
2702 (1 pixel) and a 1 pixel margin to the character height. */
2703 if (face
->overline_p
)
2706 take_vertical_position_into_account (it
);
2709 x_append_glyph (it
);
2711 it
->multibyte_p
= saved_multibyte_p
;
2713 else if (it
->what
== IT_COMPOSITION
)
2715 /* Note: A composition is represented as one glyph in the
2716 glyph matrix. There are no padding glyphs. */
2719 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2721 int font_not_found_p
;
2722 struct font_info
*font_info
;
2723 int boff
; /* baseline offset */
2724 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2726 /* Maybe translate single-byte characters to multibyte. */
2727 it
->char_to_display
= it
->c
;
2728 if (unibyte_display_via_language_environment
2729 && SINGLE_BYTE_CHAR_P (it
->c
)
2732 && !NILP (Vnonascii_translation_table
))))
2734 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2737 /* Get face and font to use. Encode IT->char_to_display. */
2738 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2739 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2740 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2741 it
->face_id
, &char2b
, it
->multibyte_p
);
2744 /* When no suitable font found, use the default font. */
2745 font_not_found_p
= font
== NULL
;
2746 if (font_not_found_p
)
2748 font
= FRAME_FONT (it
->f
);
2749 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2754 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2755 boff
= font_info
->baseline_offset
;
2756 if (font_info
->vertical_centering
)
2757 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2760 /* There are no padding glyphs, so there is only one glyph to
2761 produce for the composition. Important is that pixel_width,
2762 ascent and descent are the values of what is drawn by
2763 draw_glyphs (i.e. the values of the overall glyphs composed). */
2766 /* If we have not yet calculated pixel size data of glyphs of
2767 the composition for the current face font, calculate them
2768 now. Theoretically, we have to check all fonts for the
2769 glyphs, but that requires much time and memory space. So,
2770 here we check only the font of the first glyph. This leads
2771 to incorrect display very rarely, and C-l (recenter) can
2772 correct the display anyway. */
2773 if (cmp
->font
!= (void *) font
)
2775 /* Ascent and descent of the font of the first character of
2776 this composition (adjusted by baseline offset). Ascent
2777 and descent of overall glyphs should not be less than
2778 them respectively. */
2779 int font_ascent
= FONT_BASE (font
) + boff
;
2780 int font_descent
= FONT_DESCENT (font
) - boff
;
2781 /* Bounding box of the overall glyphs. */
2782 int leftmost
, rightmost
, lowest
, highest
;
2783 int i
, width
, ascent
, descent
;
2785 cmp
->font
= (void *) font
;
2787 /* Initialize the bounding box. */
2788 pcm
= x_per_char_metric (font
, &char2b
);
2792 ascent
= pcm
->ascent
;
2793 descent
= pcm
->descent
;
2797 width
= FONT_WIDTH (font
);
2798 ascent
= FONT_BASE (font
);
2799 descent
= FONT_DESCENT (font
);
2803 lowest
= - descent
+ boff
;
2804 highest
= ascent
+ boff
;
2808 && font_info
->default_ascent
2809 && CHAR_TABLE_P (Vuse_default_ascent
)
2810 && !NILP (Faref (Vuse_default_ascent
,
2811 make_number (it
->char_to_display
))))
2812 highest
= font_info
->default_ascent
+ boff
;
2814 /* Draw the first glyph at the normal position. It may be
2815 shifted to right later if some other glyphs are drawn at
2817 cmp
->offsets
[0] = 0;
2818 cmp
->offsets
[1] = boff
;
2820 /* Set cmp->offsets for the remaining glyphs. */
2821 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2823 int left
, right
, btm
, top
;
2824 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2825 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2827 face
= FACE_FROM_ID (it
->f
, face_id
);
2828 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2833 font
= FRAME_FONT (it
->f
);
2834 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2840 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2841 boff
= font_info
->baseline_offset
;
2842 if (font_info
->vertical_centering
)
2843 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2846 pcm
= x_per_char_metric (font
, &char2b
);
2850 ascent
= pcm
->ascent
;
2851 descent
= pcm
->descent
;
2855 width
= FONT_WIDTH (font
);
2860 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2862 /* Relative composition with or without
2864 left
= (leftmost
+ rightmost
- width
) / 2;
2865 btm
= - descent
+ boff
;
2866 if (font_info
&& font_info
->relative_compose
2867 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2868 || NILP (Faref (Vignore_relative_composition
,
2869 make_number (ch
)))))
2872 if (- descent
>= font_info
->relative_compose
)
2873 /* One extra pixel between two glyphs. */
2875 else if (ascent
<= 0)
2876 /* One extra pixel between two glyphs. */
2877 btm
= lowest
- 1 - ascent
- descent
;
2882 /* A composition rule is specified by an integer
2883 value that encodes global and new reference
2884 points (GREF and NREF). GREF and NREF are
2885 specified by numbers as below:
2893 ---3---4---5--- baseline
2895 6---7---8 -- descent
2897 int rule
= COMPOSITION_RULE (cmp
, i
);
2898 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2900 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2901 grefx
= gref
% 3, nrefx
= nref
% 3;
2902 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2905 + grefx
* (rightmost
- leftmost
) / 2
2906 - nrefx
* width
/ 2);
2907 btm
= ((grefy
== 0 ? highest
2909 : grefy
== 2 ? lowest
2910 : (highest
+ lowest
) / 2)
2911 - (nrefy
== 0 ? ascent
+ descent
2912 : nrefy
== 1 ? descent
- boff
2914 : (ascent
+ descent
) / 2));
2917 cmp
->offsets
[i
* 2] = left
;
2918 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2920 /* Update the bounding box of the overall glyphs. */
2921 right
= left
+ width
;
2922 top
= btm
+ descent
+ ascent
;
2923 if (left
< leftmost
)
2925 if (right
> rightmost
)
2933 /* If there are glyphs whose x-offsets are negative,
2934 shift all glyphs to the right and make all x-offsets
2938 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2939 cmp
->offsets
[i
* 2] -= leftmost
;
2940 rightmost
-= leftmost
;
2943 cmp
->pixel_width
= rightmost
;
2944 cmp
->ascent
= highest
;
2945 cmp
->descent
= - lowest
;
2946 if (cmp
->ascent
< font_ascent
)
2947 cmp
->ascent
= font_ascent
;
2948 if (cmp
->descent
< font_descent
)
2949 cmp
->descent
= font_descent
;
2952 it
->pixel_width
= cmp
->pixel_width
;
2953 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2954 it
->descent
= it
->phys_descent
= cmp
->descent
;
2956 if (face
->box
!= FACE_NO_BOX
)
2958 int thick
= face
->box_line_width
;
2962 it
->ascent
+= thick
;
2963 it
->descent
+= thick
;
2968 if (it
->start_of_box_run_p
)
2969 it
->pixel_width
+= thick
;
2970 if (it
->end_of_box_run_p
)
2971 it
->pixel_width
+= thick
;
2974 /* If face has an overline, add the height of the overline
2975 (1 pixel) and a 1 pixel margin to the character height. */
2976 if (face
->overline_p
)
2979 take_vertical_position_into_account (it
);
2982 x_append_composite_glyph (it
);
2984 else if (it
->what
== IT_IMAGE
)
2985 x_produce_image_glyph (it
);
2986 else if (it
->what
== IT_STRETCH
)
2987 x_produce_stretch_glyph (it
);
2989 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2990 because this isn't true for images with `:ascent 100'. */
2991 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2992 if (it
->area
== TEXT_AREA
)
2993 it
->current_x
+= it
->pixel_width
;
2995 it
->descent
+= it
->extra_line_spacing
;
2997 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2998 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2999 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
3000 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
3004 /* Estimate the pixel height of the mode or top line on frame F.
3005 FACE_ID specifies what line's height to estimate. */
3008 x_estimate_mode_line_height (f
, face_id
)
3010 enum face_id face_id
;
3012 int height
= FONT_HEIGHT (FRAME_FONT (f
));
3014 /* This function is called so early when Emacs starts that the face
3015 cache and mode line face are not yet initialized. */
3016 if (FRAME_FACE_CACHE (f
))
3018 struct face
*face
= FACE_FROM_ID (f
, face_id
);
3022 height
= FONT_HEIGHT (face
->font
);
3023 if (face
->box_line_width
> 0)
3024 height
+= 2 * face
->box_line_width
;
3032 /***********************************************************************
3034 ***********************************************************************/
3036 /* A sequence of glyphs to be drawn in the same face.
3038 This data structure is not really completely X specific, so it
3039 could possibly, at least partially, be useful for other systems. It
3040 is currently not part of the external redisplay interface because
3041 it's not clear what other systems will need. */
3045 /* X-origin of the string. */
3048 /* Y-origin and y-position of the base line of this string. */
3051 /* The width of the string, not including a face extension. */
3054 /* The width of the string, including a face extension. */
3055 int background_width
;
3057 /* The height of this string. This is the height of the line this
3058 string is drawn in, and can be different from the height of the
3059 font the string is drawn in. */
3062 /* Number of pixels this string overwrites in front of its x-origin.
3063 This number is zero if the string has an lbearing >= 0; it is
3064 -lbearing, if the string has an lbearing < 0. */
3067 /* Number of pixels this string overwrites past its right-most
3068 nominal x-position, i.e. x + width. Zero if the string's
3069 rbearing is <= its nominal width, rbearing - width otherwise. */
3072 /* The frame on which the glyph string is drawn. */
3075 /* The window on which the glyph string is drawn. */
3078 /* X display and window for convenience. */
3082 /* The glyph row for which this string was built. It determines the
3083 y-origin and height of the string. */
3084 struct glyph_row
*row
;
3086 /* The area within row. */
3087 enum glyph_row_area area
;
3089 /* Characters to be drawn, and number of characters. */
3093 /* A face-override for drawing cursors, mouse face and similar. */
3094 enum draw_glyphs_face hl
;
3096 /* Face in which this string is to be drawn. */
3099 /* Font in which this string is to be drawn. */
3102 /* Font info for this string. */
3103 struct font_info
*font_info
;
3105 /* Non-null means this string describes (part of) a composition.
3106 All characters from char2b are drawn composed. */
3107 struct composition
*cmp
;
3109 /* Index of this glyph string's first character in the glyph
3110 definition of CMP. If this is zero, this glyph string describes
3111 the first character of a composition. */
3114 /* 1 means this glyph strings face has to be drawn to the right end
3115 of the window's drawing area. */
3116 unsigned extends_to_end_of_line_p
: 1;
3118 /* 1 means the background of this string has been drawn. */
3119 unsigned background_filled_p
: 1;
3121 /* 1 means glyph string must be drawn with 16-bit functions. */
3122 unsigned two_byte_p
: 1;
3124 /* 1 means that the original font determined for drawing this glyph
3125 string could not be loaded. The member `font' has been set to
3126 the frame's default font in this case. */
3127 unsigned font_not_found_p
: 1;
3129 /* 1 means that the face in which this glyph string is drawn has a
3131 unsigned stippled_p
: 1;
3133 /* 1 means only the foreground of this glyph string must be drawn,
3134 and we should use the physical height of the line this glyph
3135 string appears in as clip rect. */
3136 unsigned for_overlaps_p
: 1;
3138 /* The GC to use for drawing this glyph string. */
3141 /* A pointer to the first glyph in the string. This glyph
3142 corresponds to char2b[0]. Needed to draw rectangles if
3143 font_not_found_p is 1. */
3144 struct glyph
*first_glyph
;
3146 /* Image, if any. */
3149 struct glyph_string
*next
, *prev
;
3156 x_dump_glyph_string (s
)
3157 struct glyph_string
*s
;
3159 fprintf (stderr
, "glyph string\n");
3160 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
3161 s
->x
, s
->y
, s
->width
, s
->height
);
3162 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
3163 fprintf (stderr
, " hl = %d\n", s
->hl
);
3164 fprintf (stderr
, " left overhang = %d, right = %d\n",
3165 s
->left_overhang
, s
->right_overhang
);
3166 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
3167 fprintf (stderr
, " extends to end of line = %d\n",
3168 s
->extends_to_end_of_line_p
);
3169 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
3170 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
3173 #endif /* GLYPH_DEBUG */
3177 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
3178 struct glyph_string
**,
3179 struct glyph_string
*,
3180 struct glyph_string
*));
3181 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
3182 struct glyph_string
**,
3183 struct glyph_string
*,
3184 struct glyph_string
*));
3185 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3186 struct glyph_string
**,
3187 struct glyph_string
*));
3188 static int x_left_overwritten
P_ ((struct glyph_string
*));
3189 static int x_left_overwriting
P_ ((struct glyph_string
*));
3190 static int x_right_overwritten
P_ ((struct glyph_string
*));
3191 static int x_right_overwriting
P_ ((struct glyph_string
*));
3192 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3194 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3195 XChar2b
*, struct window
*,
3197 enum glyph_row_area
, int,
3198 enum draw_glyphs_face
));
3199 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3200 enum glyph_row_area
, int, int,
3201 enum draw_glyphs_face
, int));
3202 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3203 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3204 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3206 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3207 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3208 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3209 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3210 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3211 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3212 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3213 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3214 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3216 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3217 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
3218 unsigned long *, double, int));*/
3219 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3220 double, int, unsigned long));
3221 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3222 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3223 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3224 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3225 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3226 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3227 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3229 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3230 int, int, int, int, Rect
*));
3231 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3232 int, int, int, Rect
*));
3233 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3234 enum glyph_row_area
));
3235 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3237 enum glyph_row_area
, int, int));
3240 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3244 /* Append the list of glyph strings with head H and tail T to the list
3245 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3248 x_append_glyph_string_lists (head
, tail
, h
, t
)
3249 struct glyph_string
**head
, **tail
;
3250 struct glyph_string
*h
, *t
;
3264 /* Prepend the list of glyph strings with head H and tail T to the
3265 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3269 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3270 struct glyph_string
**head
, **tail
;
3271 struct glyph_string
*h
, *t
;
3285 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3286 Set *HEAD and *TAIL to the resulting list. */
3289 x_append_glyph_string (head
, tail
, s
)
3290 struct glyph_string
**head
, **tail
;
3291 struct glyph_string
*s
;
3293 s
->next
= s
->prev
= NULL
;
3294 x_append_glyph_string_lists (head
, tail
, s
, s
);
3298 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3303 struct glyph_string
*s
;
3305 if (s
->font
== FRAME_FONT (s
->f
)
3306 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3307 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3309 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3312 /* Cursor on non-default face: must merge. */
3316 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3317 xgcv
.foreground
= s
->face
->background
;
3319 /* If the glyph would be invisible, try a different foreground. */
3320 if (xgcv
.foreground
== xgcv
.background
)
3321 xgcv
.foreground
= s
->face
->foreground
;
3322 if (xgcv
.foreground
== xgcv
.background
)
3323 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3324 if (xgcv
.foreground
== xgcv
.background
)
3325 xgcv
.foreground
= s
->face
->foreground
;
3327 /* Make sure the cursor is distinct from text in this face. */
3328 if (xgcv
.background
== s
->face
->background
3329 && xgcv
.foreground
== s
->face
->foreground
)
3331 xgcv
.background
= s
->face
->foreground
;
3332 xgcv
.foreground
= s
->face
->background
;
3335 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3336 xgcv
.font
= s
->font
;
3337 mask
= GCForeground
| GCBackground
| GCFont
;
3339 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3340 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3343 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3344 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3346 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3351 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3354 x_set_mouse_face_gc (s
)
3355 struct glyph_string
*s
;
3360 /* What face has to be used last for the mouse face? */
3361 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3362 face
= FACE_FROM_ID (s
->f
, face_id
);
3364 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3366 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3367 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3369 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3370 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3371 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3373 /* If font in this face is same as S->font, use it. */
3374 if (s
->font
== s
->face
->font
)
3375 s
->gc
= s
->face
->gc
;
3378 /* Otherwise construct scratch_cursor_gc with values from FACE
3383 xgcv
.background
= s
->face
->background
;
3384 xgcv
.foreground
= s
->face
->foreground
;
3385 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3386 xgcv
.font
= s
->font
;
3387 mask
= GCForeground
| GCBackground
| GCFont
;
3389 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3390 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3393 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3394 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3396 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3399 xassert (s
->gc
!= 0);
3403 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3404 Faces to use in the mode line have already been computed when the
3405 matrix was built, so there isn't much to do, here. */
3408 x_set_mode_line_face_gc (s
)
3409 struct glyph_string
*s
;
3411 s
->gc
= s
->face
->gc
;
3415 /* Set S->gc of glyph string S for drawing that glyph string. Set
3416 S->stippled_p to a non-zero value if the face of S has a stipple
3420 x_set_glyph_string_gc (s
)
3421 struct glyph_string
*s
;
3423 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3425 if (s
->hl
== DRAW_NORMAL_TEXT
)
3427 s
->gc
= s
->face
->gc
;
3428 s
->stippled_p
= s
->face
->stipple
!= 0;
3430 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3432 x_set_mode_line_face_gc (s
);
3433 s
->stippled_p
= s
->face
->stipple
!= 0;
3435 else if (s
->hl
== DRAW_CURSOR
)
3437 x_set_cursor_gc (s
);
3440 else if (s
->hl
== DRAW_MOUSE_FACE
)
3442 x_set_mouse_face_gc (s
);
3443 s
->stippled_p
= s
->face
->stipple
!= 0;
3445 else if (s
->hl
== DRAW_IMAGE_RAISED
3446 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3448 s
->gc
= s
->face
->gc
;
3449 s
->stippled_p
= s
->face
->stipple
!= 0;
3453 s
->gc
= s
->face
->gc
;
3454 s
->stippled_p
= s
->face
->stipple
!= 0;
3457 /* GC must have been set. */
3458 xassert (s
->gc
!= 0);
3462 /* Return in *R the clipping rectangle for glyph string S. */
3465 x_get_glyph_string_clip_rect (s
, r
)
3466 struct glyph_string
*s
;
3469 int r_height
, r_width
;
3471 if (s
->row
->full_width_p
)
3473 /* Draw full-width. X coordinates are relative to S->w->left. */
3474 int canon_x
= CANON_X_UNIT (s
->f
);
3476 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3477 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3479 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3481 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3482 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3486 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3488 /* Unless displaying a mode or menu bar line, which are always
3489 fully visible, clip to the visible part of the row. */
3490 if (s
->w
->pseudo_window_p
)
3491 r_height
= s
->row
->visible_height
;
3493 r_height
= s
->height
;
3497 /* This is a text line that may be partially visible. */
3498 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3499 r_width
= window_box_width (s
->w
, s
->area
);
3500 r_height
= s
->row
->visible_height
;
3503 /* If S draws overlapping rows, it's sufficient to use the top and
3504 bottom of the window for clipping because this glyph string
3505 intentionally draws over other lines. */
3506 if (s
->for_overlaps_p
)
3508 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3509 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3513 /* Don't use S->y for clipping because it doesn't take partially
3514 visible lines into account. For example, it can be negative for
3515 partially visible lines at the top of a window. */
3516 if (!s
->row
->full_width_p
3517 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3518 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3520 r
->top
= max (0, s
->row
->y
);
3522 /* If drawing a tool-bar window, draw it over the internal border
3523 at the top of the window. */
3524 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3525 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3528 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3530 r
->bottom
= r
->top
+ r_height
;
3531 r
->right
= r
->left
+ r_width
;
3535 /* Set clipping for output of glyph string S. S may be part of a mode
3536 line or menu if we don't have X toolkit support. */
3539 x_set_glyph_string_clipping (s
)
3540 struct glyph_string
*s
;
3543 x_get_glyph_string_clip_rect (s
, &r
);
3544 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3548 /* Compute left and right overhang of glyph string S. If S is a glyph
3549 string for a composition, assume overhangs don't exist. */
3552 x_compute_glyph_string_overhangs (s
)
3553 struct glyph_string
*s
;
3556 && s
->first_glyph
->type
== CHAR_GLYPH
)
3559 int direction
, font_ascent
, font_descent
;
3560 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3561 &font_ascent
, &font_descent
, &cs
);
3562 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3563 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3568 /* Compute overhangs and x-positions for glyph string S and its
3569 predecessors, or successors. X is the starting x-position for S.
3570 BACKWARD_P non-zero means process predecessors. */
3573 x_compute_overhangs_and_x (s
, x
, backward_p
)
3574 struct glyph_string
*s
;
3582 x_compute_glyph_string_overhangs (s
);
3592 x_compute_glyph_string_overhangs (s
);
3601 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3602 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3603 assumed to be zero. */
3606 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3607 struct glyph
*glyph
;
3613 if (glyph
->type
== CHAR_GLYPH
)
3617 struct font_info
*font_info
;
3621 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3623 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3625 && (pcm
= x_per_char_metric (font
, &char2b
)))
3627 if (pcm
->rbearing
> pcm
->width
)
3628 *right
= pcm
->rbearing
- pcm
->width
;
3629 if (pcm
->lbearing
< 0)
3630 *left
= -pcm
->lbearing
;
3636 /* Return the index of the first glyph preceding glyph string S that
3637 is overwritten by S because of S's left overhang. Value is -1
3638 if no glyphs are overwritten. */
3641 x_left_overwritten (s
)
3642 struct glyph_string
*s
;
3646 if (s
->left_overhang
)
3649 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3650 int first
= s
->first_glyph
- glyphs
;
3652 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3653 x
-= glyphs
[i
].pixel_width
;
3664 /* Return the index of the first glyph preceding glyph string S that
3665 is overwriting S because of its right overhang. Value is -1 if no
3666 glyph in front of S overwrites S. */
3669 x_left_overwriting (s
)
3670 struct glyph_string
*s
;
3673 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3674 int first
= s
->first_glyph
- glyphs
;
3678 for (i
= first
- 1; i
>= 0; --i
)
3681 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3684 x
-= glyphs
[i
].pixel_width
;
3691 /* Return the index of the last glyph following glyph string S that is
3692 not overwritten by S because of S's right overhang. Value is -1 if
3693 no such glyph is found. */
3696 x_right_overwritten (s
)
3697 struct glyph_string
*s
;
3701 if (s
->right_overhang
)
3704 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3705 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3706 int end
= s
->row
->used
[s
->area
];
3708 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3709 x
+= glyphs
[i
].pixel_width
;
3718 /* Return the index of the last glyph following glyph string S that
3719 overwrites S because of its left overhang. Value is negative
3720 if no such glyph is found. */
3723 x_right_overwriting (s
)
3724 struct glyph_string
*s
;
3727 int end
= s
->row
->used
[s
->area
];
3728 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3729 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3733 for (i
= first
; i
< end
; ++i
)
3736 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3739 x
+= glyphs
[i
].pixel_width
;
3746 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3749 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3750 struct glyph_string
*s
;
3755 xgcv
.foreground
= s
->gc
->background
;
3756 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3760 /* Draw the background of glyph_string S. If S->background_filled_p
3761 is non-zero don't draw it. FORCE_P non-zero means draw the
3762 background even if it wouldn't be drawn normally. This is used
3763 when a string preceding S draws into the background of S, or S
3764 contains the first component of a composition. */
3767 x_draw_glyph_string_background (s
, force_p
)
3768 struct glyph_string
*s
;
3771 /* Nothing to do if background has already been drawn or if it
3772 shouldn't be drawn in the first place. */
3773 if (!s
->background_filled_p
)
3775 int box_line_width
= max (s
->face
->box_line_width
, 0);
3777 #if 0 /* MAC_TODO: stipple */
3780 /* Fill background with a stipple pattern. */
3781 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3782 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3783 s
->y
+ box_line_width
,
3784 s
->background_width
,
3785 s
->height
- 2 * box_line_width
);
3786 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3787 s
->background_filled_p
= 1;
3791 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3792 || s
->font_not_found_p
3793 || s
->extends_to_end_of_line_p
3796 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3797 s
->background_width
,
3798 s
->height
- 2 * box_line_width
);
3799 s
->background_filled_p
= 1;
3805 /* Draw the foreground of glyph string S. */
3808 x_draw_glyph_string_foreground (s
)
3809 struct glyph_string
*s
;
3813 /* If first glyph of S has a left box line, start drawing the text
3814 of S to the right of that box line. */
3815 if (s
->face
->box
!= FACE_NO_BOX
3816 && s
->first_glyph
->left_box_line_p
)
3817 x
= s
->x
+ abs (s
->face
->box_line_width
);
3821 /* Draw characters of S as rectangles if S's font could not be
3823 if (s
->font_not_found_p
)
3825 for (i
= 0; i
< s
->nchars
; ++i
)
3827 struct glyph
*g
= s
->first_glyph
+ i
;
3828 mac_draw_rectangle (s
->display
, s
->window
,
3829 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3831 x
+= g
->pixel_width
;
3836 char *char1b
= (char *) s
->char2b
;
3837 int boff
= s
->font_info
->baseline_offset
;
3839 if (s
->font_info
->vertical_centering
)
3840 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3842 /* If we can use 8-bit functions, condense S->char2b. */
3844 for (i
= 0; i
< s
->nchars
; ++i
)
3845 char1b
[i
] = s
->char2b
[i
].byte2
;
3847 /* Draw text with XDrawString if background has already been
3848 filled. Otherwise, use XDrawImageString. (Note that
3849 XDrawImageString is usually faster than XDrawString.) Always
3850 use XDrawImageString when drawing the cursor so that there is
3851 no chance that characters under a box cursor are invisible. */
3852 if (s
->for_overlaps_p
3853 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3855 /* Draw characters with 16-bit or 8-bit functions. */
3857 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3858 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3860 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3861 s
->ybase
- boff
, char1b
, s
->nchars
);
3866 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3867 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3869 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3870 s
->ybase
- boff
, char1b
, s
->nchars
);
3875 /* Draw the foreground of composite glyph string S. */
3878 x_draw_composite_glyph_string_foreground (s
)
3879 struct glyph_string
*s
;
3883 /* If first glyph of S has a left box line, start drawing the text
3884 of S to the right of that box line. */
3885 if (s
->face
->box
!= FACE_NO_BOX
3886 && s
->first_glyph
->left_box_line_p
)
3887 x
= s
->x
+ abs (s
->face
->box_line_width
);
3891 /* S is a glyph string for a composition. S->gidx is the index of
3892 the first character drawn for glyphs of this composition.
3893 S->gidx == 0 means we are drawing the very first character of
3894 this composition. */
3896 /* Draw a rectangle for the composition if the font for the very
3897 first character of the composition could not be loaded. */
3898 if (s
->font_not_found_p
)
3901 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3902 s
->width
- 1, s
->height
- 1);
3906 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3907 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3908 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3909 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3915 #ifdef USE_X_TOOLKIT
3917 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3920 /* Return the frame on which widget WIDGET is used.. Abort if frame
3921 cannot be determined. */
3923 static struct frame
*
3924 x_frame_of_widget (widget
)
3927 struct x_display_info
*dpyinfo
;
3931 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3933 /* Find the top-level shell of the widget. Note that this function
3934 can be called when the widget is not yet realized, so XtWindow
3935 (widget) == 0. That's the reason we can't simply use
3936 x_any_window_to_frame. */
3937 while (!XtIsTopLevelShell (widget
))
3938 widget
= XtParent (widget
);
3940 /* Look for a frame with that top-level widget. Allocate the color
3941 on that frame to get the right gamma correction value. */
3942 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3943 if (GC_FRAMEP (XCAR (tail
))
3944 && (f
= XFRAME (XCAR (tail
)),
3945 (f
->output_data
.nothing
!= 1
3946 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3947 && f
->output_data
.x
->widget
== widget
)
3954 /* Allocate the color COLOR->pixel on the screen and display of
3955 widget WIDGET in colormap CMAP. If an exact match cannot be
3956 allocated, try the nearest color available. Value is non-zero
3957 if successful. This is called from lwlib. */
3960 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3965 struct frame
*f
= x_frame_of_widget (widget
);
3966 return x_alloc_nearest_color (f
, cmap
, color
);
3970 #endif /* USE_X_TOOLKIT */
3972 #if 0 /* MAC_TODO */
3974 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3975 CMAP. If an exact match can't be allocated, try the nearest color
3976 available. Value is non-zero if successful. Set *COLOR to the
3980 x_alloc_nearest_color (f
, cmap
, color
)
3985 Display
*display
= FRAME_X_DISPLAY (f
);
3986 Screen
*screen
= FRAME_X_SCREEN (f
);
3989 gamma_correct (f
, color
);
3990 rc
= XAllocColor (display
, cmap
, color
);
3993 /* If we got to this point, the colormap is full, so we're going
3994 to try to get the next closest color. The algorithm used is
3995 a least-squares matching, which is what X uses for closest
3996 color matching with StaticColor visuals. */
3998 unsigned long nearest_delta
= ~0;
3999 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
4000 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
4002 for (i
= 0; i
< ncells
; ++i
)
4004 XQueryColors (display
, cmap
, cells
, ncells
);
4006 for (nearest
= i
= 0; i
< ncells
; ++i
)
4008 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
4009 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
4010 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
4011 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
4013 if (delta
< nearest_delta
)
4016 nearest_delta
= delta
;
4020 color
->red
= cells
[nearest
].red
;
4021 color
->green
= cells
[nearest
].green
;
4022 color
->blue
= cells
[nearest
].blue
;
4023 rc
= XAllocColor (display
, cmap
, color
);
4026 #ifdef DEBUG_X_COLORS
4028 register_color (color
->pixel
);
4029 #endif /* DEBUG_X_COLORS */
4035 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
4036 It's necessary to do this instead of just using PIXEL directly to
4037 get color reference counts right. */
4040 x_copy_color (f
, pixel
)
4042 unsigned long pixel
;
4046 color
.pixel
= pixel
;
4048 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4049 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4051 #ifdef DEBUG_X_COLORS
4052 register_color (pixel
);
4058 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
4059 It's necessary to do this instead of just using PIXEL directly to
4060 get color reference counts right. */
4063 x_copy_dpy_color (dpy
, cmap
, pixel
)
4066 unsigned long pixel
;
4070 color
.pixel
= pixel
;
4072 XQueryColor (dpy
, cmap
, &color
);
4073 XAllocColor (dpy
, cmap
, &color
);
4075 #ifdef DEBUG_X_COLORS
4076 register_color (pixel
);
4081 #endif /* MAC_TODO */
4083 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
4084 or DELTA. Try a color with RGB values multiplied by FACTOR first.
4085 If this produces the same color as COLOR, try a color where all RGB
4086 values have DELTA added. Return the allocated color in *COLOR.
4087 DISPLAY is the X display, CMAP is the colormap to operate on.
4088 Value is non-zero if successful. */
4091 mac_alloc_lighter_color (f
, color
, factor
, delta
)
4093 unsigned long *color
;
4099 /* Change RGB values by specified FACTOR. Avoid overflow! */
4100 xassert (factor
>= 0);
4101 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
4102 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
4103 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
4105 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
4106 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
4107 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
4109 /* MAC_TODO: Map to palette and retry with delta if same? */
4110 /* MAC_TODO: Free colors (if using palette)? */
4121 /* Set up the foreground color for drawing relief lines of glyph
4122 string S. RELIEF is a pointer to a struct relief containing the GC
4123 with which lines will be drawn. Use a color that is FACTOR or
4124 DELTA lighter or darker than the relief's background which is found
4125 in S->f->output_data.x->relief_background. If such a color cannot
4126 be allocated, use DEFAULT_PIXEL, instead. */
4129 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
4131 struct relief
*relief
;
4134 unsigned long default_pixel
;
4137 struct mac_output
*di
= f
->output_data
.mac
;
4138 unsigned long mask
= GCForeground
;
4139 unsigned long pixel
;
4140 unsigned long background
= di
->relief_background
;
4141 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4143 /* MAC_TODO: Free colors (if using palette)? */
4145 /* Allocate new color. */
4146 xgcv
.foreground
= default_pixel
;
4148 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
4150 relief
->allocated_p
= 1;
4151 xgcv
.foreground
= relief
->pixel
= pixel
;
4154 if (relief
->gc
== 0)
4156 #if 0 /* MAC_TODO: stipple */
4157 xgcv
.stipple
= dpyinfo
->gray
;
4160 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
4163 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
4167 /* Set up colors for the relief lines around glyph string S. */
4170 x_setup_relief_colors (s
)
4171 struct glyph_string
*s
;
4173 struct mac_output
*di
= s
->f
->output_data
.mac
;
4174 unsigned long color
;
4176 if (s
->face
->use_box_color_for_shadows_p
)
4177 color
= s
->face
->box_color
;
4182 /* Get the background color of the face. */
4183 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
4184 color
= xgcv
.background
;
4187 if (di
->white_relief
.gc
== 0
4188 || color
!= di
->relief_background
)
4190 di
->relief_background
= color
;
4191 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
4192 WHITE_PIX_DEFAULT (s
->f
));
4193 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4194 BLACK_PIX_DEFAULT (s
->f
));
4199 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4200 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4201 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4202 relief. LEFT_P non-zero means draw a relief on the left side of
4203 the rectangle. RIGHT_P non-zero means draw a relief on the right
4204 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4208 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4209 raised_p
, left_p
, right_p
, clip_rect
)
4211 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4218 gc
= f
->output_data
.mac
->white_relief
.gc
;
4220 gc
= f
->output_data
.mac
->black_relief
.gc
;
4221 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4224 for (i
= 0; i
< width
; ++i
)
4225 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4226 left_x
+ i
* left_p
, top_y
+ i
,
4227 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4231 for (i
= 0; i
< width
; ++i
)
4232 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4233 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4235 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4237 gc
= f
->output_data
.mac
->black_relief
.gc
;
4239 gc
= f
->output_data
.mac
->white_relief
.gc
;
4240 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4244 for (i
= 0; i
< width
; ++i
)
4245 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4246 left_x
+ i
* left_p
, bottom_y
- i
,
4247 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4251 for (i
= 0; i
< width
; ++i
)
4252 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4253 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4255 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4259 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4260 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4261 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4262 left side of the rectangle. RIGHT_P non-zero means draw a line
4263 on the right side of the rectangle. CLIP_RECT is the clipping
4264 rectangle to use when drawing. */
4267 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4268 left_p
, right_p
, clip_rect
)
4269 struct glyph_string
*s
;
4270 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4275 xgcv
.foreground
= s
->face
->box_color
;
4276 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4279 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4280 left_x
, top_y
, right_x
- left_x
, width
);
4284 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4285 left_x
, top_y
, width
, bottom_y
- top_y
);
4288 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4289 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4293 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4294 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4296 mac_reset_clipping (s
->display
, s
->window
);
4300 /* Draw a box around glyph string S. */
4303 x_draw_glyph_string_box (s
)
4304 struct glyph_string
*s
;
4306 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4307 int left_p
, right_p
;
4308 struct glyph
*last_glyph
;
4311 last_x
= window_box_right (s
->w
, s
->area
);
4312 if (s
->row
->full_width_p
4313 && !s
->w
->pseudo_window_p
)
4315 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4316 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4317 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4320 /* The glyph that may have a right box line. */
4321 last_glyph
= (s
->cmp
|| s
->img
4323 : s
->first_glyph
+ s
->nchars
- 1);
4325 width
= abs (s
->face
->box_line_width
);
4326 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4328 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4330 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4332 bottom_y
= top_y
+ s
->height
- 1;
4334 left_p
= (s
->first_glyph
->left_box_line_p
4335 || (s
->hl
== DRAW_MOUSE_FACE
4337 || s
->prev
->hl
!= s
->hl
)));
4338 right_p
= (last_glyph
->right_box_line_p
4339 || (s
->hl
== DRAW_MOUSE_FACE
4341 || s
->next
->hl
!= s
->hl
)));
4343 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4345 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4346 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4347 left_p
, right_p
, &clip_rect
);
4350 x_setup_relief_colors (s
);
4351 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4352 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4357 /* Draw foreground of image glyph string S. */
4360 x_draw_image_foreground (s
)
4361 struct glyph_string
*s
;
4364 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4366 /* If first glyph of S has a left box line, start drawing it to the
4367 right of that line. */
4368 if (s
->face
->box
!= FACE_NO_BOX
4369 && s
->first_glyph
->left_box_line_p
)
4370 x
= s
->x
+ abs (s
->face
->box_line_width
);
4374 /* If there is a margin around the image, adjust x- and y-position
4376 x
+= s
->img
->hmargin
;
4377 y
+= s
->img
->vmargin
;
4381 #if 0 /* MAC_TODO: image mask */
4384 /* We can't set both a clip mask and use XSetClipRectangles
4385 because the latter also sets a clip mask. We also can't
4386 trust on the shape extension to be available
4387 (XShapeCombineRegion). So, compute the rectangle to draw
4389 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4392 XRectangle clip_rect
, image_rect
, r
;
4394 xgcv
.clip_mask
= s
->img
->mask
;
4395 xgcv
.clip_x_origin
= x
;
4396 xgcv
.clip_y_origin
= y
;
4397 xgcv
.function
= GXcopy
;
4398 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4400 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4403 image_rect
.width
= s
->img
->width
;
4404 image_rect
.height
= s
->img
->height
;
4405 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4406 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4407 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4410 #endif /* MAC_TODO */
4412 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4413 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4415 /* When the image has a mask, we can expect that at
4416 least part of a mouse highlight or a block cursor will
4417 be visible. If the image doesn't have a mask, make
4418 a block cursor visible by drawing a rectangle around
4419 the image. I believe it's looking better if we do
4420 nothing here for mouse-face. */
4421 if (s
->hl
== DRAW_CURSOR
)
4423 int r
= s
->img
->relief
;
4425 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4426 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4431 /* Draw a rectangle if image could not be loaded. */
4432 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4433 s
->img
->width
- 1, s
->img
->height
- 1);
4438 /* Draw a relief around the image glyph string S. */
4441 x_draw_image_relief (s
)
4442 struct glyph_string
*s
;
4444 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4447 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4449 /* If first glyph of S has a left box line, start drawing it to the
4450 right of that line. */
4451 if (s
->face
->box
!= FACE_NO_BOX
4452 && s
->first_glyph
->left_box_line_p
)
4453 x
= s
->x
+ abs (s
->face
->box_line_width
);
4457 /* If there is a margin around the image, adjust x- and y-position
4459 x
+= s
->img
->hmargin
;
4460 y
+= s
->img
->vmargin
;
4462 if (s
->hl
== DRAW_IMAGE_SUNKEN
4463 || s
->hl
== DRAW_IMAGE_RAISED
)
4465 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4466 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4470 thick
= abs (s
->img
->relief
);
4471 raised_p
= s
->img
->relief
> 0;
4476 x1
= x
+ s
->img
->width
+ thick
- 1;
4477 y1
= y
+ s
->img
->height
+ thick
- 1;
4479 x_setup_relief_colors (s
);
4480 x_get_glyph_string_clip_rect (s
, &r
);
4481 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4485 /* Draw the foreground of image glyph string S to PIXMAP. */
4488 x_draw_image_foreground_1 (s
, pixmap
)
4489 struct glyph_string
*s
;
4493 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4495 /* If first glyph of S has a left box line, start drawing it to the
4496 right of that line. */
4497 if (s
->face
->box
!= FACE_NO_BOX
4498 && s
->first_glyph
->left_box_line_p
)
4499 x
= abs (s
->face
->box_line_width
);
4503 /* If there is a margin around the image, adjust x- and y-position
4505 x
+= s
->img
->hmargin
;
4506 y
+= s
->img
->vmargin
;
4510 #if 0 /* MAC_TODO: image mask */
4513 /* We can't set both a clip mask and use XSetClipRectangles
4514 because the latter also sets a clip mask. We also can't
4515 trust on the shape extension to be available
4516 (XShapeCombineRegion). So, compute the rectangle to draw
4518 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4522 xgcv
.clip_mask
= s
->img
->mask
;
4523 xgcv
.clip_x_origin
= x
;
4524 xgcv
.clip_y_origin
= y
;
4525 xgcv
.function
= GXcopy
;
4526 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4528 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4529 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4530 XSetClipMask (s
->display
, s
->gc
, None
);
4533 #endif /* MAC_TODO */
4535 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4536 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4538 /* When the image has a mask, we can expect that at
4539 least part of a mouse highlight or a block cursor will
4540 be visible. If the image doesn't have a mask, make
4541 a block cursor visible by drawing a rectangle around
4542 the image. I believe it's looking better if we do
4543 nothing here for mouse-face. */
4544 if (s
->hl
== DRAW_CURSOR
)
4546 int r
= s
->img
->relief
;
4548 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
4549 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4554 /* Draw a rectangle if image could not be loaded. */
4555 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4556 s
->img
->width
- 1, s
->img
->height
- 1);
4560 /* Draw part of the background of glyph string S. X, Y, W, and H
4561 give the rectangle to draw. */
4564 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4565 struct glyph_string
*s
;
4568 #if 0 /* MAC_TODO: stipple */
4571 /* Fill background with a stipple pattern. */
4572 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4573 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4574 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4577 #endif /* MAC_TODO */
4578 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4582 /* Draw image glyph string S.
4585 s->x +-------------------------
4588 | +-------------------------
4591 | | +-------------------
4597 x_draw_image_glyph_string (s
)
4598 struct glyph_string
*s
;
4601 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4602 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4606 height
= s
->height
- 2 * box_line_vwidth
;
4608 /* Fill background with face under the image. Do it only if row is
4609 taller than image or if image has a clip mask to reduce
4611 s
->stippled_p
= s
->face
->stipple
!= 0;
4612 if (height
> s
->img
->height
4615 #if 0 /* TODO: image mask */
4618 || s
->img
->pixmap
== 0
4619 || s
->width
!= s
->background_width
)
4621 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4622 x
= s
->x
+ box_line_hwidth
;
4626 y
= s
->y
+ box_line_vwidth
;
4627 #if 0 /* TODO: image mask */
4630 /* Create a pixmap as large as the glyph string. Fill it
4631 with the background color. Copy the image to it, using
4632 its mask. Copy the temporary pixmap to the display. */
4633 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4634 int depth
= DefaultDepthOfScreen (screen
);
4636 /* Create a pixmap as large as the glyph string. */
4637 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4638 s
->background_width
,
4641 /* Don't clip in the following because we're working on the
4643 XSetClipMask (s
->display
, s
->gc
, None
);
4645 /* Fill the pixmap with the background color/stipple. */
4648 /* Fill background with a stipple pattern. */
4649 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4650 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4651 0, 0, s
->background_width
, s
->height
);
4652 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4657 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4659 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4660 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4661 0, 0, s
->background_width
, s
->height
);
4662 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4667 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4669 s
->background_filled_p
= 1;
4672 /* Draw the foreground. */
4675 x_draw_image_foreground_1 (s
, pixmap
);
4676 x_set_glyph_string_clipping (s
);
4677 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4678 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4679 mac_reset_clipping (s
->display
, s
->window
);
4680 XFreePixmap (s
->display
, pixmap
);
4683 x_draw_image_foreground (s
);
4685 /* If we must draw a relief around the image, do it. */
4687 || s
->hl
== DRAW_IMAGE_RAISED
4688 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4689 x_draw_image_relief (s
);
4693 /* Draw stretch glyph string S. */
4696 x_draw_stretch_glyph_string (s
)
4697 struct glyph_string
*s
;
4699 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4700 s
->stippled_p
= s
->face
->stipple
!= 0;
4702 if (s
->hl
== DRAW_CURSOR
4703 && !x_stretch_cursor_p
)
4705 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4706 as wide as the stretch glyph. */
4707 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4710 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4712 /* Clear rest using the GC of the original non-cursor face. */
4713 if (width
< s
->background_width
)
4715 GC gc
= s
->face
->gc
;
4716 int x
= s
->x
+ width
, y
= s
->y
;
4717 int w
= s
->background_width
- width
, h
= s
->height
;
4720 if (s
->row
->mouse_face_p
4721 && cursor_in_mouse_face_p (s
->w
))
4723 x_set_mouse_face_gc (s
);
4729 x_get_glyph_string_clip_rect (s
, &r
);
4730 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4732 #if 0 /* MAC_TODO: stipple */
4733 if (s
->face
->stipple
)
4735 /* Fill background with a stipple pattern. */
4736 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4737 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4738 XSetFillStyle (s
->display
, gc
, FillSolid
);
4741 #endif /* MAC_TODO */
4744 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4745 XSetForeground (s
->display
, gc
, xgcv
.background
);
4746 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4747 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4750 mac_reset_clipping (s
->display
, s
->window
);
4753 else if (!s
->background_filled_p
)
4754 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4757 s
->background_filled_p
= 1;
4761 /* Draw glyph string S. */
4764 x_draw_glyph_string (s
)
4765 struct glyph_string
*s
;
4767 int relief_drawn_p
= 0;
4769 /* If S draws into the background of its successor, draw the
4770 background of the successor first so that S can draw into it.
4771 This makes S->next use XDrawString instead of XDrawImageString. */
4772 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4774 xassert (s
->next
->img
== NULL
);
4775 x_set_glyph_string_gc (s
->next
);
4776 x_set_glyph_string_clipping (s
->next
);
4777 x_draw_glyph_string_background (s
->next
, 1);
4781 /* Set up S->gc, set clipping and draw S. */
4782 x_set_glyph_string_gc (s
);
4784 /* Draw relief (if any) in advance for char/composition so that the
4785 glyph string can be drawn over it. */
4786 if (!s
->for_overlaps_p
4787 && s
->face
->box
!= FACE_NO_BOX
4788 && (s
->first_glyph
->type
== CHAR_GLYPH
4789 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4792 x_set_glyph_string_clipping (s
);
4793 x_draw_glyph_string_background (s
, 1);
4794 x_draw_glyph_string_box (s
);
4795 x_set_glyph_string_clipping (s
);
4799 x_set_glyph_string_clipping (s
);
4801 switch (s
->first_glyph
->type
)
4804 x_draw_image_glyph_string (s
);
4808 x_draw_stretch_glyph_string (s
);
4812 if (s
->for_overlaps_p
)
4813 s
->background_filled_p
= 1;
4815 x_draw_glyph_string_background (s
, 0);
4816 x_draw_glyph_string_foreground (s
);
4819 case COMPOSITE_GLYPH
:
4820 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4821 s
->background_filled_p
= 1;
4823 x_draw_glyph_string_background (s
, 1);
4824 x_draw_composite_glyph_string_foreground (s
);
4831 if (!s
->for_overlaps_p
)
4833 /* Draw underline. */
4834 if (s
->face
->underline_p
)
4836 unsigned long h
= 1;
4837 unsigned long dy
= s
->height
- h
;
4839 if (s
->face
->underline_defaulted_p
)
4840 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4845 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4846 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4847 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4849 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4853 /* Draw overline. */
4854 if (s
->face
->overline_p
)
4856 unsigned long dy
= 0, h
= 1;
4858 if (s
->face
->overline_color_defaulted_p
)
4859 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4864 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4865 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4866 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4868 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4872 /* Draw strike-through. */
4873 if (s
->face
->strike_through_p
)
4875 unsigned long h
= 1;
4876 unsigned long dy
= (s
->height
- h
) / 2;
4878 if (s
->face
->strike_through_color_defaulted_p
)
4879 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4884 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4885 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4886 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4888 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4893 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4894 x_draw_glyph_string_box (s
);
4897 /* Reset clipping. */
4898 mac_reset_clipping (s
->display
, s
->window
);
4902 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4903 struct face
**, int));
4906 /* Fill glyph string S with composition components specified by S->cmp.
4908 FACES is an array of faces for all components of this composition.
4909 S->gidx is the index of the first component for S.
4910 OVERLAPS_P non-zero means S should draw the foreground only, and
4911 use its physical height for clipping.
4913 Value is the index of a component not in S. */
4916 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4917 struct glyph_string
*s
;
4918 struct face
**faces
;
4925 s
->for_overlaps_p
= overlaps_p
;
4927 s
->face
= faces
[s
->gidx
];
4928 s
->font
= s
->face
->font
;
4929 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4931 /* For all glyphs of this composition, starting at the offset
4932 S->gidx, until we reach the end of the definition or encounter a
4933 glyph that requires the different face, add it to S. */
4935 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4938 /* All glyph strings for the same composition has the same width,
4939 i.e. the width set for the first component of the composition. */
4941 s
->width
= s
->first_glyph
->pixel_width
;
4943 /* If the specified font could not be loaded, use the frame's
4944 default font, but record the fact that we couldn't load it in
4945 the glyph string so that we can draw rectangles for the
4946 characters of the glyph string. */
4947 if (s
->font
== NULL
)
4949 s
->font_not_found_p
= 1;
4950 s
->font
= FRAME_FONT (s
->f
);
4953 /* Adjust base line for subscript/superscript text. */
4954 s
->ybase
+= s
->first_glyph
->voffset
;
4956 xassert (s
->face
&& s
->face
->gc
);
4958 /* This glyph string must always be drawn with 16-bit functions. */
4961 return s
->gidx
+ s
->nchars
;
4965 /* Fill glyph string S from a sequence of character glyphs.
4967 FACE_ID is the face id of the string. START is the index of the
4968 first glyph to consider, END is the index of the last + 1.
4969 OVERLAPS_P non-zero means S should draw the foreground only, and
4970 use its physical height for clipping.
4972 Value is the index of the first glyph not in S. */
4975 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4976 struct glyph_string
*s
;
4978 int start
, end
, overlaps_p
;
4980 struct glyph
*glyph
, *last
;
4982 int glyph_not_available_p
;
4984 xassert (s
->f
== XFRAME (s
->w
->frame
));
4985 xassert (s
->nchars
== 0);
4986 xassert (start
>= 0 && end
> start
);
4988 s
->for_overlaps_p
= overlaps_p
;
4989 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4990 last
= s
->row
->glyphs
[s
->area
] + end
;
4991 voffset
= glyph
->voffset
;
4993 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4996 && glyph
->type
== CHAR_GLYPH
4997 && glyph
->voffset
== voffset
4998 /* Same face id implies same font, nowadays. */
4999 && glyph
->face_id
== face_id
5000 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
5004 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
5005 s
->char2b
+ s
->nchars
,
5007 s
->two_byte_p
= two_byte_p
;
5009 xassert (s
->nchars
<= end
- start
);
5010 s
->width
+= glyph
->pixel_width
;
5014 s
->font
= s
->face
->font
;
5015 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5017 /* If the specified font could not be loaded, use the frame's font,
5018 but record the fact that we couldn't load it in
5019 S->font_not_found_p so that we can draw rectangles for the
5020 characters of the glyph string. */
5021 if (s
->font
== NULL
|| glyph_not_available_p
)
5023 s
->font_not_found_p
= 1;
5024 s
->font
= FRAME_FONT (s
->f
);
5027 /* Adjust base line for subscript/superscript text. */
5028 s
->ybase
+= voffset
;
5030 xassert (s
->face
&& s
->face
->gc
);
5031 return glyph
- s
->row
->glyphs
[s
->area
];
5035 /* Fill glyph string S from image glyph S->first_glyph. */
5038 x_fill_image_glyph_string (s
)
5039 struct glyph_string
*s
;
5041 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
5042 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
5044 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
5045 s
->font
= s
->face
->font
;
5046 s
->width
= s
->first_glyph
->pixel_width
;
5048 /* Adjust base line for subscript/superscript text. */
5049 s
->ybase
+= s
->first_glyph
->voffset
;
5053 /* Fill glyph string S from a sequence of stretch glyphs.
5055 ROW is the glyph row in which the glyphs are found, AREA is the
5056 area within the row. START is the index of the first glyph to
5057 consider, END is the index of the last + 1.
5059 Value is the index of the first glyph not in S. */
5062 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
5063 struct glyph_string
*s
;
5064 struct glyph_row
*row
;
5065 enum glyph_row_area area
;
5068 struct glyph
*glyph
, *last
;
5069 int voffset
, face_id
;
5071 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
5073 glyph
= s
->row
->glyphs
[s
->area
] + start
;
5074 last
= s
->row
->glyphs
[s
->area
] + end
;
5075 face_id
= glyph
->face_id
;
5076 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
5077 s
->font
= s
->face
->font
;
5078 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5079 s
->width
= glyph
->pixel_width
;
5080 voffset
= glyph
->voffset
;
5084 && glyph
->type
== STRETCH_GLYPH
5085 && glyph
->voffset
== voffset
5086 && glyph
->face_id
== face_id
);
5088 s
->width
+= glyph
->pixel_width
;
5090 /* Adjust base line for subscript/superscript text. */
5091 s
->ybase
+= voffset
;
5094 return glyph
- s
->row
->glyphs
[s
->area
];
5098 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
5099 of XChar2b structures for S; it can't be allocated in
5100 x_init_glyph_string because it must be allocated via `alloca'. W
5101 is the window on which S is drawn. ROW and AREA are the glyph row
5102 and area within the row from which S is constructed. START is the
5103 index of the first glyph structure covered by S. HL is a
5104 face-override for drawing S. */
5107 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
5108 struct glyph_string
*s
;
5111 struct glyph_row
*row
;
5112 enum glyph_row_area area
;
5114 enum draw_glyphs_face hl
;
5116 bzero (s
, sizeof *s
);
5118 s
->f
= XFRAME (w
->frame
);
5119 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
5120 s
->window
= FRAME_MAC_WINDOW (s
->f
);
5125 s
->first_glyph
= row
->glyphs
[area
] + start
;
5126 s
->height
= row
->height
;
5127 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5129 /* Display the internal border below the tool-bar window. */
5130 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
5131 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
5133 s
->ybase
= s
->y
+ row
->ascent
;
5137 /* Set background width of glyph string S. START is the index of the
5138 first glyph following S. LAST_X is the right-most x-position + 1
5139 in the drawing area. */
5142 x_set_glyph_string_background_width (s
, start
, last_x
)
5143 struct glyph_string
*s
;
5147 /* If the face of this glyph string has to be drawn to the end of
5148 the drawing area, set S->extends_to_end_of_line_p. */
5149 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
5151 if (start
== s
->row
->used
[s
->area
]
5152 && s
->area
== TEXT_AREA
5153 && ((s
->hl
== DRAW_NORMAL_TEXT
5154 && (s
->row
->fill_line_p
5155 || s
->face
->background
!= default_face
->background
5156 || s
->face
->stipple
!= default_face
->stipple
5157 || s
->row
->mouse_face_p
))
5158 || s
->hl
== DRAW_MOUSE_FACE
5159 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
5160 && s
->row
->fill_line_p
)))
5161 s
->extends_to_end_of_line_p
= 1;
5163 /* If S extends its face to the end of the line, set its
5164 background_width to the distance to the right edge of the drawing
5166 if (s
->extends_to_end_of_line_p
)
5167 s
->background_width
= last_x
- s
->x
+ 1;
5169 s
->background_width
= s
->width
;
5173 /* Add a glyph string for a stretch glyph to the list of strings
5174 between HEAD and TAIL. START is the index of the stretch glyph in
5175 row area AREA of glyph row ROW. END is the index of the last glyph
5176 in that glyph row area. X is the current output position assigned
5177 to the new glyph string constructed. HL overrides that face of the
5178 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5179 is the right-most x-position of the drawing area. */
5181 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
5182 and below -- keep them on one line. */
5183 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5186 s = (struct glyph_string *) alloca (sizeof *s); \
5187 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5188 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
5189 x_append_glyph_string (&HEAD, &TAIL, s); \
5195 /* Add a glyph string for an image glyph to the list of strings
5196 between HEAD and TAIL. START is the index of the image glyph in
5197 row area AREA of glyph row ROW. END is the index of the last glyph
5198 in that glyph row area. X is the current output position assigned
5199 to the new glyph string constructed. HL overrides that face of the
5200 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5201 is the right-most x-position of the drawing area. */
5203 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5206 s = (struct glyph_string *) alloca (sizeof *s); \
5207 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5208 x_fill_image_glyph_string (s); \
5209 x_append_glyph_string (&HEAD, &TAIL, s); \
5216 /* Add a glyph string for a sequence of character glyphs to the list
5217 of strings between HEAD and TAIL. START is the index of the first
5218 glyph in row area AREA of glyph row ROW that is part of the new
5219 glyph string. END is the index of the last glyph in that glyph row
5220 area. X is the current output position assigned to the new glyph
5221 string constructed. HL overrides that face of the glyph; e.g. it
5222 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
5223 right-most x-position of the drawing area. */
5225 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5231 c = (ROW)->glyphs[AREA][START].u.ch; \
5232 face_id = (ROW)->glyphs[AREA][START].face_id; \
5234 s = (struct glyph_string *) alloca (sizeof *s); \
5235 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5236 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5237 x_append_glyph_string (&HEAD, &TAIL, s); \
5239 START = x_fill_glyph_string (s, face_id, START, END, \
5245 /* Add a glyph string for a composite sequence to the list of strings
5246 between HEAD and TAIL. START is the index of the first glyph in
5247 row area AREA of glyph row ROW that is part of the new glyph
5248 string. END is the index of the last glyph in that glyph row area.
5249 X is the current output position assigned to the new glyph string
5250 constructed. HL overrides that face of the glyph; e.g. it is
5251 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5252 x-position of the drawing area. */
5254 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5256 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5257 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5258 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5259 struct composition *cmp = composition_table[cmp_id]; \
5260 int glyph_len = cmp->glyph_len; \
5262 struct face **faces; \
5263 struct glyph_string *first_s = NULL; \
5266 base_face = base_face->ascii_face; \
5267 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5268 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5269 /* At first, fill in `char2b' and `faces'. */ \
5270 for (n = 0; n < glyph_len; n++) \
5272 int c = COMPOSITION_GLYPH (cmp, n); \
5273 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5274 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5275 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5276 this_face_id, char2b + n, 1); \
5279 /* Make glyph_strings for each glyph sequence that is drawable by \
5280 the same face, and append them to HEAD/TAIL. */ \
5281 for (n = 0; n < cmp->glyph_len;) \
5283 s = (struct glyph_string *) alloca (sizeof *s); \
5284 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5285 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5293 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5301 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5302 of AREA of glyph row ROW on window W between indices START and END.
5303 HL overrides the face for drawing glyph strings, e.g. it is
5304 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5305 x-positions of the drawing area.
5307 This is an ugly monster macro construct because we must use alloca
5308 to allocate glyph strings (because x_draw_glyphs can be called
5311 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5314 HEAD = TAIL = NULL; \
5315 while (START < END) \
5317 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5318 switch (first_glyph->type) \
5321 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5322 TAIL, HL, X, LAST_X, \
5326 case COMPOSITE_GLYPH: \
5327 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5328 HEAD, TAIL, HL, X, LAST_X,\
5332 case STRETCH_GLYPH: \
5333 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5334 HEAD, TAIL, HL, X, LAST_X); \
5338 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5339 TAIL, HL, X, LAST_X); \
5346 x_set_glyph_string_background_width (s, START, LAST_X); \
5353 /* Draw glyphs between START and END in AREA of ROW on window W,
5354 starting at x-position X. X is relative to AREA in W. HL is a
5355 face-override with the following meaning:
5357 DRAW_NORMAL_TEXT draw normally
5358 DRAW_CURSOR draw in cursor face
5359 DRAW_MOUSE_FACE draw in mouse face.
5360 DRAW_INVERSE_VIDEO draw in mode line face
5361 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5362 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5364 If OVERLAPS_P is non-zero, draw only the foreground of characters
5365 and clip to the physical height of ROW.
5367 Value is the x-position reached, relative to AREA of W. */
5370 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5373 struct glyph_row
*row
;
5374 enum glyph_row_area area
;
5376 enum draw_glyphs_face hl
;
5379 struct glyph_string
*head
, *tail
;
5380 struct glyph_string
*s
;
5381 int last_x
, area_width
;
5385 /* Let's rather be paranoid than getting a SEGV. */
5386 end
= min (end
, row
->used
[area
]);
5387 start
= max (0, start
);
5388 start
= min (end
, start
);
5390 /* Translate X to frame coordinates. Set last_x to the right
5391 end of the drawing area. */
5392 if (row
->full_width_p
)
5394 /* X is relative to the left edge of W, without scroll bars
5396 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5397 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5400 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5401 last_x
= window_left_x
+ area_width
;
5403 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5405 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5406 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5412 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5413 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5417 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5418 area_width
= window_box_width (w
, area
);
5419 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5422 /* Build a doubly-linked list of glyph_string structures between
5423 head and tail from what we have to draw. Note that the macro
5424 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5425 the reason we use a separate variable `i'. */
5427 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5430 x_reached
= tail
->x
+ tail
->background_width
;
5434 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5435 the row, redraw some glyphs in front or following the glyph
5436 strings built above. */
5437 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5440 struct glyph_string
*h
, *t
;
5442 /* Compute overhangs for all glyph strings. */
5443 for (s
= head
; s
; s
= s
->next
)
5444 x_compute_glyph_string_overhangs (s
);
5446 /* Prepend glyph strings for glyphs in front of the first glyph
5447 string that are overwritten because of the first glyph
5448 string's left overhang. The background of all strings
5449 prepended must be drawn because the first glyph string
5451 i
= x_left_overwritten (head
);
5455 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5456 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5459 x_compute_overhangs_and_x (t
, head
->x
, 1);
5460 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5463 /* Prepend glyph strings for glyphs in front of the first glyph
5464 string that overwrite that glyph string because of their
5465 right overhang. For these strings, only the foreground must
5466 be drawn, because it draws over the glyph string at `head'.
5467 The background must not be drawn because this would overwrite
5468 right overhangs of preceding glyphs for which no glyph
5470 i
= x_left_overwriting (head
);
5473 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5474 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5476 for (s
= h
; s
; s
= s
->next
)
5477 s
->background_filled_p
= 1;
5478 x_compute_overhangs_and_x (t
, head
->x
, 1);
5479 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5482 /* Append glyphs strings for glyphs following the last glyph
5483 string tail that are overwritten by tail. The background of
5484 these strings has to be drawn because tail's foreground draws
5486 i
= x_right_overwritten (tail
);
5489 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5490 DRAW_NORMAL_TEXT
, x
, last_x
,
5492 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5493 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5496 /* Append glyph strings for glyphs following the last glyph
5497 string tail that overwrite tail. The foreground of such
5498 glyphs has to be drawn because it writes into the background
5499 of tail. The background must not be drawn because it could
5500 paint over the foreground of following glyphs. */
5501 i
= x_right_overwriting (tail
);
5504 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5505 DRAW_NORMAL_TEXT
, x
, last_x
,
5507 for (s
= h
; s
; s
= s
->next
)
5508 s
->background_filled_p
= 1;
5509 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5510 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5514 /* Draw all strings. */
5515 for (s
= head
; s
; s
= s
->next
)
5516 x_draw_glyph_string (s
);
5518 if (area
== TEXT_AREA
5519 && !row
->full_width_p
5520 /* When drawing overlapping rows, only the glyph strings'
5521 foreground is drawn, which doesn't erase a cursor
5525 int x0
= head
? head
->x
: x
;
5526 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5528 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5529 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5531 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5533 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5534 x0
-= left_area_width
;
5535 x1
-= left_area_width
;
5538 notice_overwritten_cursor (w
, area
, x0
, x1
,
5539 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5542 /* Value is the x-position up to which drawn, relative to AREA of W.
5543 This doesn't include parts drawn because of overhangs. */
5544 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5545 if (!row
->full_width_p
)
5547 if (area
> LEFT_MARGIN_AREA
)
5548 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5549 if (area
> TEXT_AREA
)
5550 x_reached
-= window_box_width (w
, TEXT_AREA
);
5557 /* Fix the display of area AREA of overlapping row ROW in window W. */
5560 x_fix_overlapping_area (w
, row
, area
)
5562 struct glyph_row
*row
;
5563 enum glyph_row_area area
;
5569 if (area
== LEFT_MARGIN_AREA
)
5571 else if (area
== TEXT_AREA
)
5572 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5574 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5575 + window_box_width (w
, TEXT_AREA
));
5577 for (i
= 0; i
< row
->used
[area
];)
5579 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5581 int start
= i
, start_x
= x
;
5585 x
+= row
->glyphs
[area
][i
].pixel_width
;
5588 while (i
< row
->used
[area
]
5589 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5591 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5592 DRAW_NORMAL_TEXT
, 1);
5596 x
+= row
->glyphs
[area
][i
].pixel_width
;
5605 /* Output LEN glyphs starting at START at the nominal cursor position.
5606 Advance the nominal cursor over the text. The global variable
5607 updated_window contains the window being updated, updated_row is
5608 the glyph row being updated, and updated_area is the area of that
5609 row being updated. */
5612 x_write_glyphs (start
, len
)
5613 struct glyph
*start
;
5618 xassert (updated_window
&& updated_row
);
5623 hpos
= start
- updated_row
->glyphs
[updated_area
];
5624 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5625 updated_row
, updated_area
,
5627 DRAW_NORMAL_TEXT
, 0);
5631 /* Advance the output cursor. */
5632 output_cursor
.hpos
+= len
;
5633 output_cursor
.x
= x
;
5637 /* Insert LEN glyphs from START at the nominal cursor position. */
5640 x_insert_glyphs (start
, len
)
5641 struct glyph
*start
;
5646 int line_height
, shift_by_width
, shifted_region_width
;
5647 struct glyph_row
*row
;
5648 struct glyph
*glyph
;
5649 int frame_x
, frame_y
, hpos
;
5651 xassert (updated_window
&& updated_row
);
5654 f
= XFRAME (WINDOW_FRAME (w
));
5656 /* Get the height of the line we are in. */
5658 line_height
= row
->height
;
5660 /* Get the width of the glyphs to insert. */
5662 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5663 shift_by_width
+= glyph
->pixel_width
;
5665 /* Get the width of the region to shift right. */
5666 shifted_region_width
= (window_box_width (w
, updated_area
)
5671 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5672 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5674 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5675 f
->output_data
.mac
->normal_gc
,
5677 shifted_region_width
, line_height
,
5678 frame_x
+ shift_by_width
, frame_y
);
5680 /* Write the glyphs. */
5681 hpos
= start
- row
->glyphs
[updated_area
];
5682 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5683 DRAW_NORMAL_TEXT
, 0);
5685 /* Advance the output cursor. */
5686 output_cursor
.hpos
+= len
;
5687 output_cursor
.x
+= shift_by_width
;
5692 /* Delete N glyphs at the nominal cursor position. Not implemented
5703 /* Erase the current text line from the nominal cursor position
5704 (inclusive) to pixel column TO_X (exclusive). The idea is that
5705 everything from TO_X onward is already erased.
5707 TO_X is a pixel position relative to updated_area of
5708 updated_window. TO_X == -1 means clear to the end of this area. */
5711 x_clear_end_of_line (to_x
)
5715 struct window
*w
= updated_window
;
5716 int max_x
, min_y
, max_y
;
5717 int from_x
, from_y
, to_y
;
5719 xassert (updated_window
&& updated_row
);
5720 f
= XFRAME (w
->frame
);
5722 if (updated_row
->full_width_p
)
5724 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5725 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5726 && !w
->pseudo_window_p
)
5727 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5730 max_x
= window_box_width (w
, updated_area
);
5731 max_y
= window_text_bottom_y (w
);
5733 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5734 of window. For TO_X > 0, truncate to end of drawing area. */
5740 to_x
= min (to_x
, max_x
);
5742 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5744 /* Notice if the cursor will be cleared by this operation. */
5745 if (!updated_row
->full_width_p
)
5746 notice_overwritten_cursor (w
, updated_area
,
5747 output_cursor
.x
, -1,
5749 MATRIX_ROW_BOTTOM_Y (updated_row
));
5751 from_x
= output_cursor
.x
;
5753 /* Translate to frame coordinates. */
5754 if (updated_row
->full_width_p
)
5756 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5757 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5761 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5762 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5765 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5766 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5767 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5769 /* Prevent inadvertently clearing to end of the X window. */
5770 if (to_x
> from_x
&& to_y
> from_y
)
5773 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5774 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5781 /* Clear entire frame. If updating_frame is non-null, clear that
5782 frame. Otherwise clear the selected frame. */
5792 f
= SELECTED_FRAME ();
5794 /* Clearing the frame will erase any cursor, so mark them all as no
5796 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5797 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5798 output_cursor
.x
= -1;
5800 /* We don't set the output cursor here because there will always
5801 follow an explicit cursor_to. */
5803 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5805 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5806 /* We have to clear the scroll bars, too. If we have changed
5807 colors or something like that, then they should be notified. */
5808 x_scroll_bar_clear (f
);
5811 XFlush (FRAME_MAC_DISPLAY (f
));
5817 /* Invert the middle quarter of the frame for .15 sec. */
5819 /* We use the select system call to do the waiting, so we have to make
5820 sure it's available. If it isn't, we just won't do visual bells. */
5822 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5824 /* Subtract the `struct timeval' values X and Y, storing the result in
5825 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5828 timeval_subtract (result
, x
, y
)
5829 struct timeval
*result
, x
, y
;
5831 /* Perform the carry for the later subtraction by updating y. This
5832 is safer because on some systems the tv_sec member is unsigned. */
5833 if (x
.tv_usec
< y
.tv_usec
)
5835 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5836 y
.tv_usec
-= 1000000 * nsec
;
5840 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5842 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5843 y
.tv_usec
+= 1000000 * nsec
;
5847 /* Compute the time remaining to wait. tv_usec is certainly
5849 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5850 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5852 /* Return indication of whether the result should be considered
5854 return x
.tv_sec
< y
.tv_sec
;
5866 struct timeval wakeup
;
5868 EMACS_GET_TIME (wakeup
);
5870 /* Compute time to wait until, propagating carry from usecs. */
5871 wakeup
.tv_usec
+= 150000;
5872 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5873 wakeup
.tv_usec
%= 1000000;
5875 /* Keep waiting until past the time wakeup. */
5878 struct timeval timeout
;
5880 EMACS_GET_TIME (timeout
);
5882 /* In effect, timeout = wakeup - timeout.
5883 Break if result would be negative. */
5884 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5887 /* Try to wait that long--but we might wake up sooner. */
5888 select (0, NULL
, NULL
, NULL
, &timeout
);
5897 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5900 /* Make audible bell. */
5905 struct frame
*f
= SELECTED_FRAME ();
5907 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5915 XFlush (FRAME_MAC_DISPLAY (f
));
5922 /* Specify how many text lines, from the top of the window,
5923 should be affected by insert-lines and delete-lines operations.
5924 This, and those operations, are used only within an update
5925 that is bounded by calls to x_update_begin and x_update_end. */
5928 XTset_terminal_window (n
)
5931 /* This function intentionally left blank. */
5936 /***********************************************************************
5938 ***********************************************************************/
5940 /* Perform an insert-lines or delete-lines operation, inserting N
5941 lines or deleting -N lines at vertical position VPOS. */
5944 x_ins_del_lines (vpos
, n
)
5951 /* Scroll part of the display as described by RUN. */
5954 x_scroll_run (w
, run
)
5958 struct frame
*f
= XFRAME (w
->frame
);
5959 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5961 /* Get frame-relative bounding box of the text display area of W,
5962 without mode lines. Include in this box the left and right
5964 window_box (w
, -1, &x
, &y
, &width
, &height
);
5965 width
+= FRAME_X_FRINGE_WIDTH (f
);
5966 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5968 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5969 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5970 bottom_y
= y
+ height
;
5974 /* Scrolling up. Make sure we don't copy part of the mode
5975 line at the bottom. */
5976 if (from_y
+ run
->height
> bottom_y
)
5977 height
= bottom_y
- from_y
;
5979 height
= run
->height
;
5983 /* Scolling down. Make sure we don't copy over the mode line.
5985 if (to_y
+ run
->height
> bottom_y
)
5986 height
= bottom_y
- to_y
;
5988 height
= run
->height
;
5993 /* Cursor off. Will be switched on again in x_update_window_end. */
5997 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5998 f
->output_data
.mac
->normal_gc
,
6008 /***********************************************************************
6010 ***********************************************************************/
6012 /* Redisplay an exposed area of frame F. X and Y are the upper-left
6013 corner of the exposed rectangle. W and H are width and height of
6014 the exposed area. All are pixel values. W or H zero means redraw
6015 the entire frame. */
6018 expose_frame (f
, x
, y
, w
, h
)
6023 int mouse_face_overwritten_p
= 0;
6025 TRACE ((stderr
, "expose_frame "));
6027 /* No need to redraw if frame will be redrawn soon. */
6028 if (FRAME_GARBAGED_P (f
))
6030 TRACE ((stderr
, " garbaged\n"));
6034 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
6035 or deactivated here, for unknown reasons, activated scroll bars
6036 are shown in deactivated frames in some instances. */
6037 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6038 activate_scroll_bars (f
);
6040 deactivate_scroll_bars (f
);
6042 /* If basic faces haven't been realized yet, there is no point in
6043 trying to redraw anything. This can happen when we get an expose
6044 event while Emacs is starting, e.g. by moving another window. */
6045 if (FRAME_FACE_CACHE (f
) == NULL
6046 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
6048 TRACE ((stderr
, " no faces\n"));
6052 if (w
== 0 || h
== 0)
6055 r
.right
= CANON_X_UNIT (f
) * f
->width
;
6056 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
6066 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
6067 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
6069 if (WINDOWP (f
->tool_bar_window
))
6070 mouse_face_overwritten_p
6071 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
6073 /* Some window managers support a focus-follows-mouse style with
6074 delayed raising of frames. Imagine a partially obscured frame,
6075 and moving the mouse into partially obscured mouse-face on that
6076 frame. The visible part of the mouse-face will be highlighted,
6077 then the WM raises the obscured frame. With at least one WM, KDE
6078 2.1, Emacs is not getting any event for the raising of the frame
6079 (even tried with SubstructureRedirectMask), only Expose events.
6080 These expose events will draw text normally, i.e. not
6081 highlighted. Which means we must redo the highlight here.
6082 Subsume it under ``we love X''. --gerd 2001-08-15 */
6083 /* Included in Windows version because Windows most likely does not
6084 do the right thing if any third party tool offers
6085 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
6086 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
6088 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6089 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6091 int x
= dpyinfo
->mouse_face_mouse_x
;
6092 int y
= dpyinfo
->mouse_face_mouse_y
;
6093 clear_mouse_face (dpyinfo
);
6094 note_mouse_highlight (f
, x
, y
);
6100 /* Redraw (parts) of all windows in the window tree rooted at W that
6101 intersect R. R contains frame pixel coordinates. */
6104 expose_window_tree (w
, r
)
6108 struct frame
*f
= XFRAME (w
->frame
);
6109 int mouse_face_overwritten_p
= 0;
6111 while (w
&& !FRAME_GARBAGED_P (f
))
6113 if (!NILP (w
->hchild
))
6114 mouse_face_overwritten_p
6115 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
6116 else if (!NILP (w
->vchild
))
6117 mouse_face_overwritten_p
6118 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
6120 mouse_face_overwritten_p
|= expose_window (w
, r
);
6122 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
6125 return mouse_face_overwritten_p
;
6129 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
6130 which intersects rectangle R. R is in window-relative coordinates. */
6133 expose_area (w
, row
, r
, area
)
6135 struct glyph_row
*row
;
6137 enum glyph_row_area area
;
6139 struct glyph
*first
= row
->glyphs
[area
];
6140 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
6142 int first_x
, start_x
, x
;
6144 if (area
== TEXT_AREA
&& row
->fill_line_p
)
6145 /* If row extends face to end of line write the whole line. */
6146 x_draw_glyphs (w
, 0, row
, area
,
6148 DRAW_NORMAL_TEXT
, 0);
6151 /* Set START_X to the window-relative start position for drawing glyphs of
6152 AREA. The first glyph of the text area can be partially visible.
6153 The first glyphs of other areas cannot. */
6154 if (area
== LEFT_MARGIN_AREA
)
6156 else if (area
== TEXT_AREA
)
6157 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6159 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6160 + window_box_width (w
, TEXT_AREA
));
6163 /* Find the first glyph that must be redrawn. */
6165 && x
+ first
->pixel_width
< r
->left
)
6167 x
+= first
->pixel_width
;
6171 /* Find the last one. */
6177 x
+= last
->pixel_width
;
6183 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6184 first
- row
->glyphs
[area
],
6185 last
- row
->glyphs
[area
],
6186 DRAW_NORMAL_TEXT
, 0);
6191 /* Redraw the parts of the glyph row ROW on window W intersecting
6192 rectangle R. R is in window-relative coordinates. Value is
6193 non-zero if mouse face was overwritten. */
6196 expose_line (w
, row
, r
)
6198 struct glyph_row
*row
;
6201 xassert (row
->enabled_p
);
6203 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6204 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6205 DRAW_NORMAL_TEXT
, 0);
6208 if (row
->used
[LEFT_MARGIN_AREA
])
6209 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6210 if (row
->used
[TEXT_AREA
])
6211 expose_area (w
, row
, r
, TEXT_AREA
);
6212 if (row
->used
[RIGHT_MARGIN_AREA
])
6213 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6214 x_draw_row_fringe_bitmaps (w
, row
);
6217 return row
->mouse_face_p
;
6221 /* Return non-zero if W's cursor intersects rectangle R. */
6224 x_phys_cursor_in_rect_p (w
, r
)
6229 struct glyph
*cursor_glyph
;
6231 cursor_glyph
= get_phys_cursor_glyph (w
);
6234 cr
.left
= w
->phys_cursor
.x
;
6235 cr
.top
= w
->phys_cursor
.y
;
6236 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6237 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6238 return x_intersect_rectangles (&cr
, r
, &result
);
6245 /* Redraw those parts of glyphs rows during expose event handling that
6246 overlap other rows. Redrawing of an exposed line writes over parts
6247 of lines overlapping that exposed line; this function fixes that.
6249 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
6250 row in W's current matrix that is exposed and overlaps other rows.
6251 LAST_OVERLAPPING_ROW is the last such row. */
6254 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
)
6256 struct glyph_row
*first_overlapping_row
;
6257 struct glyph_row
*last_overlapping_row
;
6259 struct glyph_row
*row
;
6261 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
6262 if (row
->overlapping_p
)
6264 xassert (row
->enabled_p
&& !row
->mode_line_p
);
6266 if (row
->used
[LEFT_MARGIN_AREA
])
6267 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
);
6269 if (row
->used
[TEXT_AREA
])
6270 x_fix_overlapping_area (w
, row
, TEXT_AREA
);
6272 if (row
->used
[RIGHT_MARGIN_AREA
])
6273 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
);
6278 /* Redraw the part of window W intersection rectangle FR. Pixel
6279 coordinates in FR are frame-relative. Call this function with
6280 input blocked. Value is non-zero if the exposure overwrites
6284 expose_window (w
, fr
)
6288 struct frame
*f
= XFRAME (w
->frame
);
6290 int mouse_face_overwritten_p
= 0;
6292 /* If window is not yet fully initialized, do nothing. This can
6293 happen when toolkit scroll bars are used and a window is split.
6294 Reconfiguring the scroll bar will generate an expose for a newly
6296 if (w
->current_matrix
== NULL
)
6299 /* When we're currently updating the window, display and current
6300 matrix usually don't agree. Arrange for a thorough display
6302 if (w
== updated_window
)
6304 SET_FRAME_GARBAGED (f
);
6308 /* Frame-relative pixel rectangle of W. */
6309 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6310 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6311 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6312 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6314 if (x_intersect_rectangles (fr
, &wr
, &r
))
6316 int yb
= window_text_bottom_y (w
);
6317 struct glyph_row
*row
;
6318 int cursor_cleared_p
;
6319 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
6321 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6322 r
.left
, r
.top
, r
.right
, r
.bottom
));
6324 /* Convert to window coordinates. */
6325 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6326 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6327 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6328 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6330 /* Turn off the cursor. */
6331 if (!w
->pseudo_window_p
6332 && x_phys_cursor_in_rect_p (w
, &r
))
6335 cursor_cleared_p
= 1;
6338 cursor_cleared_p
= 0;
6340 /* Update lines intersecting rectangle R. */
6341 first_overlapping_row
= last_overlapping_row
= NULL
;
6342 for (row
= w
->current_matrix
->rows
;
6347 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6349 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6350 || (y1
> r
.top
&& y1
< r
.bottom
)
6351 || (r
.top
>= y0
&& r
.top
< y1
)
6352 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6354 if (row
->overlapping_p
)
6356 if (first_overlapping_row
== NULL
)
6357 first_overlapping_row
= row
;
6358 last_overlapping_row
= row
;
6361 if (expose_line (w
, row
, &r
))
6362 mouse_face_overwritten_p
= 1;
6369 /* Display the mode line if there is one. */
6370 if (WINDOW_WANTS_MODELINE_P (w
)
6371 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6373 && row
->y
< r
.bottom
)
6375 if (expose_line (w
, row
, &r
))
6376 mouse_face_overwritten_p
= 1;
6379 if (!w
->pseudo_window_p
)
6381 /* Fix the display of overlapping rows. */
6382 if (first_overlapping_row
)
6383 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
);
6385 /* Draw border between windows. */
6386 x_draw_vertical_border (w
);
6388 /* Turn the cursor on again. */
6389 if (cursor_cleared_p
)
6390 x_update_window_cursor (w
, 1);
6394 /* Display scroll bar for this window. */
6395 if (!NILP (w
->vertical_scroll_bar
))
6398 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6403 return mouse_face_overwritten_p
;
6407 x_intersect_rectangles (r1
, r2
, result
)
6408 Rect
*r1
, *r2
, *result
;
6411 Rect
*upper
, *lower
;
6412 int intersection_p
= 0;
6414 /* Rerrange so that R1 is the left-most rectangle. */
6415 if (r1
->left
< r2
->left
)
6416 left
= r1
, right
= r2
;
6418 left
= r2
, right
= r1
;
6420 /* X0 of the intersection is right.x0, if this is inside R1,
6421 otherwise there is no intersection. */
6422 if (right
->left
<= left
->right
)
6424 result
->left
= right
->left
;
6426 /* The right end of the intersection is the minimum of the
6427 the right ends of left and right. */
6428 result
->right
= min (left
->right
, right
->right
);
6430 /* Same game for Y. */
6431 if (r1
->top
< r2
->top
)
6432 upper
= r1
, lower
= r2
;
6434 upper
= r2
, lower
= r1
;
6436 /* The upper end of the intersection is lower.y0, if this is inside
6437 of upper. Otherwise, there is no intersection. */
6438 if (lower
->top
<= upper
->bottom
)
6440 result
->top
= lower
->top
;
6442 /* The lower end of the intersection is the minimum of the lower
6443 ends of upper and lower. */
6444 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6449 return intersection_p
;
6460 x_update_cursor (f
, 1);
6464 frame_unhighlight (f
)
6467 x_update_cursor (f
, 1);
6470 /* The focus has changed. Update the frames as necessary to reflect
6471 the new situation. Note that we can't change the selected frame
6472 here, because the Lisp code we are interrupting might become confused.
6473 Each event gets marked with the frame in which it occurred, so the
6474 Lisp code can tell when the switch took place by examining the events. */
6477 x_new_focus_frame (dpyinfo
, frame
)
6478 struct x_display_info
*dpyinfo
;
6479 struct frame
*frame
;
6481 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6483 if (frame
!= dpyinfo
->x_focus_frame
)
6485 /* Set this before calling other routines, so that they see
6486 the correct value of x_focus_frame. */
6487 dpyinfo
->x_focus_frame
= frame
;
6489 if (old_focus
&& old_focus
->auto_lower
)
6490 x_lower_frame (old_focus
);
6493 selected_frame
= frame
;
6494 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6496 Fselect_window (selected_frame
->selected_window
);
6497 choose_minibuf_frame ();
6500 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6501 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6503 pending_autoraise_frame
= 0;
6506 x_frame_rehighlight (dpyinfo
);
6509 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6512 x_mouse_leave (dpyinfo
)
6513 struct x_display_info
*dpyinfo
;
6515 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6518 /* The focus has changed, or we have redirected a frame's focus to
6519 another frame (this happens when a frame uses a surrogate
6520 mini-buffer frame). Shift the highlight as appropriate.
6522 The FRAME argument doesn't necessarily have anything to do with which
6523 frame is being highlighted or un-highlighted; we only use it to find
6524 the appropriate X display info. */
6527 XTframe_rehighlight (frame
)
6528 struct frame
*frame
;
6530 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6534 x_frame_rehighlight (dpyinfo
)
6535 struct x_display_info
*dpyinfo
;
6537 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6539 if (dpyinfo
->x_focus_frame
)
6541 dpyinfo
->x_highlight_frame
6542 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6543 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6544 : dpyinfo
->x_focus_frame
);
6545 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6547 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6548 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6552 dpyinfo
->x_highlight_frame
= 0;
6554 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6557 frame_unhighlight (old_highlight
);
6558 if (dpyinfo
->x_highlight_frame
)
6559 frame_highlight (dpyinfo
->x_highlight_frame
);
6565 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6567 #if 0 /* MAC_TODO */
6568 /* Initialize mode_switch_bit and modifier_meaning. */
6570 x_find_modifier_meanings (dpyinfo
)
6571 struct x_display_info
*dpyinfo
;
6573 int min_code
, max_code
;
6576 XModifierKeymap
*mods
;
6578 dpyinfo
->meta_mod_mask
= 0;
6579 dpyinfo
->shift_lock_mask
= 0;
6580 dpyinfo
->alt_mod_mask
= 0;
6581 dpyinfo
->super_mod_mask
= 0;
6582 dpyinfo
->hyper_mod_mask
= 0;
6585 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6587 min_code
= dpyinfo
->display
->min_keycode
;
6588 max_code
= dpyinfo
->display
->max_keycode
;
6591 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6592 min_code
, max_code
- min_code
+ 1,
6594 mods
= XGetModifierMapping (dpyinfo
->display
);
6596 /* Scan the modifier table to see which modifier bits the Meta and
6597 Alt keysyms are on. */
6599 int row
, col
; /* The row and column in the modifier table. */
6601 for (row
= 3; row
< 8; row
++)
6602 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6605 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6607 /* Zeroes are used for filler. Skip them. */
6611 /* Are any of this keycode's keysyms a meta key? */
6615 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6617 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6623 dpyinfo
->meta_mod_mask
|= (1 << row
);
6628 dpyinfo
->alt_mod_mask
|= (1 << row
);
6633 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6638 dpyinfo
->super_mod_mask
|= (1 << row
);
6642 /* Ignore this if it's not on the lock modifier. */
6643 if ((1 << row
) == LockMask
)
6644 dpyinfo
->shift_lock_mask
= LockMask
;
6652 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6653 if (! dpyinfo
->meta_mod_mask
)
6655 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6656 dpyinfo
->alt_mod_mask
= 0;
6659 /* If some keys are both alt and meta,
6660 make them just meta, not alt. */
6661 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6663 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6666 XFree ((char *) syms
);
6667 XFreeModifiermap (mods
);
6670 #endif /* MAC_TODO */
6672 /* Convert between the modifier bits X uses and the modifier bits
6676 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6677 struct x_display_info
*dpyinfo
;
6678 unsigned short state
;
6680 return (((state
& shiftKey
) ? shift_modifier
: 0)
6681 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6682 | ((state
& cmdKey
) ? meta_modifier
: 0)
6683 | ((state
& optionKey
) ? alt_modifier
: 0));
6686 #if 0 /* MAC_TODO */
6687 static unsigned short
6688 x_emacs_to_x_modifiers (dpyinfo
, state
)
6689 struct x_display_info
*dpyinfo
;
6692 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6693 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6694 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6695 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6696 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6697 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6699 #endif /* MAC_TODO */
6701 /* Convert a keysym to its name. */
6704 x_get_keysym_name (keysym
)
6711 value
= XKeysymToString (keysym
);
6722 /* Mouse clicks and mouse movement. Rah. */
6724 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6725 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6726 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6727 not force the value into range. */
6730 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6732 register int pix_x
, pix_y
;
6733 register int *x
, *y
;
6737 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6738 if (NILP (Vwindow_system
))
6745 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6746 even for negative values. */
6748 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6750 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6752 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6753 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6757 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6758 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6759 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6760 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6767 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6768 pix_x
= FRAME_WINDOW_WIDTH (f
);
6772 else if (pix_y
> f
->height
)
6781 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6782 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6783 can't tell the positions because W's display is not up to date,
6787 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6790 int *frame_x
, *frame_y
;
6794 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6795 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6797 if (display_completed
)
6799 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6800 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6801 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6807 *frame_x
+= glyph
->pixel_width
;
6815 *frame_y
= *frame_x
= 0;
6819 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6820 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6825 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6827 If the event is a button press, then note that we have grabbed
6831 construct_mouse_click (result
, event
, f
)
6832 struct input_event
*result
;
6838 result
->kind
= MOUSE_CLICK_EVENT
;
6839 result
->code
= 0; /* only one mouse button */
6840 result
->timestamp
= event
->when
;
6841 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6843 mouseLoc
= event
->where
;
6845 #if TARGET_API_MAC_CARBON
6846 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6848 SetPort (FRAME_MAC_WINDOW (f
));
6851 GlobalToLocal (&mouseLoc
);
6852 XSETINT (result
->x
, mouseLoc
.h
);
6853 XSETINT (result
->y
, mouseLoc
.v
);
6855 XSETFRAME (result
->frame_or_window
, f
);
6862 /* Function to report a mouse movement to the mainstream Emacs code.
6863 The input handler calls this.
6865 We have received a mouse movement event, which is given in *event.
6866 If the mouse is over a different glyph than it was last time, tell
6867 the mainstream emacs code by setting mouse_moved. If not, ask for
6868 another motion event, so we can check again the next time it moves. */
6870 static Point last_mouse_motion_position
;
6871 static Lisp_Object last_mouse_motion_frame
;
6874 note_mouse_movement (frame
, pos
)
6878 #if TARGET_API_MAC_CARBON
6882 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6883 last_mouse_motion_position
= *pos
;
6884 XSETFRAME (last_mouse_motion_frame
, frame
);
6886 #if TARGET_API_MAC_CARBON
6887 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6889 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6892 frame
->mouse_moved
= 1;
6893 last_mouse_scroll_bar
= Qnil
;
6894 note_mouse_highlight (frame
, -1, -1);
6896 /* Has the mouse moved off the glyph it was on at the last sighting? */
6897 else if (pos
->h
< last_mouse_glyph
.left
6898 || pos
->h
>= last_mouse_glyph
.right
6899 || pos
->v
< last_mouse_glyph
.top
6900 || pos
->v
>= last_mouse_glyph
.bottom
)
6902 frame
->mouse_moved
= 1;
6903 last_mouse_scroll_bar
= Qnil
;
6904 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6908 /* This is used for debugging, to turn off note_mouse_highlight. */
6910 int disable_mouse_highlight
;
6914 /************************************************************************
6916 ************************************************************************/
6918 /* Find the glyph under window-relative coordinates X/Y in window W.
6919 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6920 strings. Return in *HPOS and *VPOS the row and column number of
6921 the glyph found. Return in *AREA the glyph area containing X.
6922 Value is a pointer to the glyph found or null if X/Y is not on
6923 text, or we can't tell because W's current matrix is not up to
6926 static struct glyph
*
6927 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6930 int *hpos
, *vpos
, *area
;
6933 struct glyph
*glyph
, *end
;
6934 struct glyph_row
*row
= NULL
;
6935 int x0
, i
, left_area_width
;
6937 /* Find row containing Y. Give up if some row is not enabled. */
6938 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6940 row
= MATRIX_ROW (w
->current_matrix
, i
);
6941 if (!row
->enabled_p
)
6943 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6950 /* Give up if Y is not in the window. */
6951 if (i
== w
->current_matrix
->nrows
)
6954 /* Get the glyph area containing X. */
6955 if (w
->pseudo_window_p
)
6962 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6963 if (x
< left_area_width
)
6965 *area
= LEFT_MARGIN_AREA
;
6968 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6971 x0
= row
->x
+ left_area_width
;
6975 *area
= RIGHT_MARGIN_AREA
;
6976 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6980 /* Find glyph containing X. */
6981 glyph
= row
->glyphs
[*area
];
6982 end
= glyph
+ row
->used
[*area
];
6985 if (x
< x0
+ glyph
->pixel_width
)
6987 if (w
->pseudo_window_p
)
6989 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6993 x0
+= glyph
->pixel_width
;
7000 *hpos
= glyph
- row
->glyphs
[*area
];
7005 /* Convert frame-relative x/y to coordinates relative to window W.
7006 Takes pseudo-windows into account. */
7009 frame_to_window_pixel_xy (w
, x
, y
)
7013 if (w
->pseudo_window_p
)
7015 /* A pseudo-window is always full-width, and starts at the
7016 left edge of the frame, plus a frame border. */
7017 struct frame
*f
= XFRAME (w
->frame
);
7018 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
7019 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
7023 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
7024 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
7029 /* Take proper action when mouse has moved to the mode or header line of
7030 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
7031 mode line. X is relative to the start of the text display area of
7032 W, so the width of fringes and scroll bars must be subtracted
7033 to get a position relative to the start of the mode line. */
7036 note_mode_line_highlight (w
, x
, mode_line_p
)
7040 struct frame
*f
= XFRAME (w
->frame
);
7041 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7042 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
7043 struct glyph_row
*row
;
7046 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
7048 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
7052 struct glyph
*glyph
, *end
;
7053 Lisp_Object help
, map
;
7056 /* Find the glyph under X. */
7057 glyph
= row
->glyphs
[TEXT_AREA
];
7058 end
= glyph
+ row
->used
[TEXT_AREA
];
7059 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
7060 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
7063 && x
>= x0
+ glyph
->pixel_width
)
7065 x0
+= glyph
->pixel_width
;
7070 && STRINGP (glyph
->object
)
7071 && STRING_INTERVALS (glyph
->object
)
7072 && glyph
->charpos
>= 0
7073 && glyph
->charpos
< SCHARS (glyph
->object
))
7075 /* If we're on a string with `help-echo' text property,
7076 arrange for the help to be displayed. This is done by
7077 setting the global variable help_echo to the help string. */
7078 help
= Fget_text_property (make_number (glyph
->charpos
),
7079 Qhelp_echo
, glyph
->object
);
7083 XSETWINDOW (help_echo_window
, w
);
7084 help_echo_object
= glyph
->object
;
7085 help_echo_pos
= glyph
->charpos
;
7088 /* Change the mouse pointer according to what is under X/Y. */
7089 map
= Fget_text_property (make_number (glyph
->charpos
),
7090 Qlocal_map
, glyph
->object
);
7092 cursor
= f
->output_data
.mac
->nontext_cursor
;
7095 map
= Fget_text_property (make_number (glyph
->charpos
),
7096 Qkeymap
, glyph
->object
);
7098 cursor
= f
->output_data
.mac
->nontext_cursor
;
7103 #if 0 /* MAC_TODO: mouse cursor */
7104 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7109 /* Take proper action when the mouse has moved to position X, Y on
7110 frame F as regards highlighting characters that have mouse-face
7111 properties. Also de-highlighting chars where the mouse was before.
7112 X and Y can be negative or out of range. */
7115 note_mouse_highlight (f
, x
, y
)
7119 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7126 /* When a menu is active, don't highlight because this looks odd. */
7127 if (popup_activated ())
7131 if (NILP (Vmouse_highlight
)
7132 || !f
->glyphs_initialized_p
)
7135 dpyinfo
->mouse_face_mouse_x
= x
;
7136 dpyinfo
->mouse_face_mouse_y
= y
;
7137 dpyinfo
->mouse_face_mouse_frame
= f
;
7139 if (dpyinfo
->mouse_face_defer
)
7144 dpyinfo
->mouse_face_deferred_gc
= 1;
7148 /* Which window is that in? */
7149 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7151 /* If we were displaying active text in another window, clear that. */
7152 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7153 clear_mouse_face (dpyinfo
);
7155 /* Not on a window -> return. */
7156 if (!WINDOWP (window
))
7159 /* Reset help_echo. It will get recomputed below. */
7162 /* Convert to window-relative pixel coordinates. */
7163 w
= XWINDOW (window
);
7164 frame_to_window_pixel_xy (w
, &x
, &y
);
7166 /* Handle tool-bar window differently since it doesn't display a
7168 if (EQ (window
, f
->tool_bar_window
))
7170 note_tool_bar_highlight (f
, x
, y
);
7174 /* Mouse is on the mode or header line? */
7175 if (portion
== 1 || portion
== 3)
7177 note_mode_line_highlight (w
, x
, portion
== 1);
7180 #if 0 /* TODO: mouse cursor */
7182 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7184 cursor
= f
->output_data
.x
->text_cursor
;
7186 /* Are we in a window whose display is up to date?
7187 And verify the buffer's text has not changed. */
7188 b
= XBUFFER (w
->buffer
);
7189 if (/* Within text portion of the window. */
7191 && EQ (w
->window_end_valid
, w
->buffer
)
7192 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7193 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7195 int hpos
, vpos
, pos
, i
, area
;
7196 struct glyph
*glyph
;
7198 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7199 Lisp_Object
*overlay_vec
= NULL
;
7201 struct buffer
*obuf
;
7202 int obegv
, ozv
, same_region
;
7204 /* Find the glyph under X/Y. */
7205 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7207 /* Clear mouse face if X/Y not over text. */
7209 || area
!= TEXT_AREA
7210 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7212 clear_mouse_face (dpyinfo
);
7213 /* TODO: mouse cursor */
7217 pos
= glyph
->charpos
;
7218 object
= glyph
->object
;
7219 if (!STRINGP (object
) && !BUFFERP (object
))
7222 /* If we get an out-of-range value, return now; avoid an error. */
7223 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7226 /* Make the window's buffer temporarily current for
7227 overlays_at and compute_char_face. */
7228 obuf
= current_buffer
;
7235 /* Is this char mouse-active or does it have help-echo? */
7236 position
= make_number (pos
);
7238 if (BUFFERP (object
))
7240 /* Put all the overlays we want in a vector in overlay_vec.
7241 Store the length in len. If there are more than 10, make
7242 enough space for all, and try again. */
7244 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7245 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7246 if (noverlays
> len
)
7249 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7250 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7253 /* Sort overlays into increasing priority order. */
7254 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7259 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7260 && vpos
>= dpyinfo
->mouse_face_beg_row
7261 && vpos
<= dpyinfo
->mouse_face_end_row
7262 && (vpos
> dpyinfo
->mouse_face_beg_row
7263 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7264 && (vpos
< dpyinfo
->mouse_face_end_row
7265 || hpos
< dpyinfo
->mouse_face_end_col
7266 || dpyinfo
->mouse_face_past_end
));
7268 /* TODO: if (same_region)
7271 /* Check mouse-face highlighting. */
7273 /* If there exists an overlay with mouse-face overlapping
7274 the one we are currently highlighting, we have to
7275 check if we enter the overlapping overlay, and then
7277 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7278 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7280 /* Find the highest priority overlay that has a mouse-face
7283 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7285 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7286 if (!NILP (mouse_face
))
7287 overlay
= overlay_vec
[i
];
7290 /* If we're actually highlighting the same overlay as
7291 before, there's no need to do that again. */
7293 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7294 goto check_help_echo
;
7296 dpyinfo
->mouse_face_overlay
= overlay
;
7298 /* Clear the display of the old active region, if any. */
7299 clear_mouse_face (dpyinfo
);
7300 /* TODO: mouse cursor changes. */
7302 /* If no overlay applies, get a text property. */
7304 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7306 /* Handle the overlay case. */
7307 if (!NILP (overlay
))
7309 /* Find the range of text around this char that
7310 should be active. */
7311 Lisp_Object before
, after
;
7314 before
= Foverlay_start (overlay
);
7315 after
= Foverlay_end (overlay
);
7316 /* Record this as the current active region. */
7317 fast_find_position (w
, XFASTINT (before
),
7318 &dpyinfo
->mouse_face_beg_col
,
7319 &dpyinfo
->mouse_face_beg_row
,
7320 &dpyinfo
->mouse_face_beg_x
,
7321 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7323 dpyinfo
->mouse_face_past_end
7324 = !fast_find_position (w
, XFASTINT (after
),
7325 &dpyinfo
->mouse_face_end_col
,
7326 &dpyinfo
->mouse_face_end_row
,
7327 &dpyinfo
->mouse_face_end_x
,
7328 &dpyinfo
->mouse_face_end_y
, Qnil
);
7329 dpyinfo
->mouse_face_window
= window
;
7331 dpyinfo
->mouse_face_face_id
7332 = face_at_buffer_position (w
, pos
, 0, 0,
7333 &ignore
, pos
+ 1, 1);
7335 /* Display it as active. */
7336 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7337 /* TODO: mouse cursor changes. */
7339 /* Handle the text property case. */
7340 else if (! NILP (mouse_face
) && BUFFERP (object
))
7342 /* Find the range of text around this char that
7343 should be active. */
7344 Lisp_Object before
, after
, beginning
, end
;
7347 beginning
= Fmarker_position (w
->start
);
7348 end
= make_number (BUF_Z (XBUFFER (object
))
7349 - XFASTINT (w
->window_end_pos
));
7351 = Fprevious_single_property_change (make_number (pos
+ 1),
7355 = Fnext_single_property_change (position
, Qmouse_face
,
7358 /* Record this as the current active region. */
7359 fast_find_position (w
, XFASTINT (before
),
7360 &dpyinfo
->mouse_face_beg_col
,
7361 &dpyinfo
->mouse_face_beg_row
,
7362 &dpyinfo
->mouse_face_beg_x
,
7363 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7364 dpyinfo
->mouse_face_past_end
7365 = !fast_find_position (w
, XFASTINT (after
),
7366 &dpyinfo
->mouse_face_end_col
,
7367 &dpyinfo
->mouse_face_end_row
,
7368 &dpyinfo
->mouse_face_end_x
,
7369 &dpyinfo
->mouse_face_end_y
, Qnil
);
7370 dpyinfo
->mouse_face_window
= window
;
7372 if (BUFFERP (object
))
7373 dpyinfo
->mouse_face_face_id
7374 = face_at_buffer_position (w
, pos
, 0, 0,
7375 &ignore
, pos
+ 1, 1);
7377 /* Display it as active. */
7378 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7379 /* TODO: mouse cursor changes. */
7381 else if (!NILP (mouse_face
) && STRINGP (object
))
7386 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7389 e
= Fnext_single_property_change (position
, Qmouse_face
,
7392 b
= make_number (0);
7394 e
= make_number (SCHARS (object
) - 1);
7395 fast_find_string_pos (w
, XINT (b
), object
,
7396 &dpyinfo
->mouse_face_beg_col
,
7397 &dpyinfo
->mouse_face_beg_row
,
7398 &dpyinfo
->mouse_face_beg_x
,
7399 &dpyinfo
->mouse_face_beg_y
, 0);
7400 fast_find_string_pos (w
, XINT (e
), object
,
7401 &dpyinfo
->mouse_face_end_col
,
7402 &dpyinfo
->mouse_face_end_row
,
7403 &dpyinfo
->mouse_face_end_x
,
7404 &dpyinfo
->mouse_face_end_y
, 1);
7405 dpyinfo
->mouse_face_past_end
= 0;
7406 dpyinfo
->mouse_face_window
= window
;
7407 dpyinfo
->mouse_face_face_id
7408 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7410 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7411 /* TODO: mouse cursor changes. */
7413 else if (STRINGP (object
) && NILP (mouse_face
))
7415 /* A string which doesn't have mouse-face, but
7416 the text ``under'' it might have. */
7417 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7418 int start
= MATRIX_ROW_START_CHARPOS (r
);
7420 pos
= string_buffer_position (w
, object
, start
);
7422 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7426 if (!NILP (mouse_face
) && !NILP (overlay
))
7428 Lisp_Object before
= Foverlay_start (overlay
);
7429 Lisp_Object after
= Foverlay_end (overlay
);
7432 /* Note that we might not be able to find position
7433 BEFORE in the glyph matrix if the overlay is
7434 entirely covered by a `display' property. In
7435 this case, we overshoot. So let's stop in
7436 the glyph matrix before glyphs for OBJECT. */
7437 fast_find_position (w
, XFASTINT (before
),
7438 &dpyinfo
->mouse_face_beg_col
,
7439 &dpyinfo
->mouse_face_beg_row
,
7440 &dpyinfo
->mouse_face_beg_x
,
7441 &dpyinfo
->mouse_face_beg_y
,
7444 dpyinfo
->mouse_face_past_end
7445 = !fast_find_position (w
, XFASTINT (after
),
7446 &dpyinfo
->mouse_face_end_col
,
7447 &dpyinfo
->mouse_face_end_row
,
7448 &dpyinfo
->mouse_face_end_x
,
7449 &dpyinfo
->mouse_face_end_y
,
7451 dpyinfo
->mouse_face_window
= window
;
7452 dpyinfo
->mouse_face_face_id
7453 = face_at_buffer_position (w
, pos
, 0, 0,
7454 &ignore
, pos
+ 1, 1);
7456 /* Display it as active. */
7457 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7458 /* TODO: mouse cursor changes. */
7465 /* Look for a `help-echo' property. */
7467 Lisp_Object help
, overlay
;
7469 /* Check overlays first. */
7470 help
= overlay
= Qnil
;
7471 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7473 overlay
= overlay_vec
[i
];
7474 help
= Foverlay_get (overlay
, Qhelp_echo
);
7480 help_echo_window
= window
;
7481 help_echo_object
= overlay
;
7482 help_echo_pos
= pos
;
7486 Lisp_Object object
= glyph
->object
;
7487 int charpos
= glyph
->charpos
;
7489 /* Try text properties. */
7490 if (STRINGP (object
)
7492 && charpos
< SCHARS (object
))
7494 help
= Fget_text_property (make_number (charpos
),
7495 Qhelp_echo
, object
);
7498 /* If the string itself doesn't specify a help-echo,
7499 see if the buffer text ``under'' it does. */
7501 = MATRIX_ROW (w
->current_matrix
, vpos
);
7502 int start
= MATRIX_ROW_START_CHARPOS (r
);
7503 int pos
= string_buffer_position (w
, object
, start
);
7506 help
= Fget_char_property (make_number (pos
),
7507 Qhelp_echo
, w
->buffer
);
7516 else if (BUFFERP (object
)
7519 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7525 help_echo_window
= window
;
7526 help_echo_object
= object
;
7527 help_echo_pos
= charpos
;
7534 current_buffer
= obuf
;
7538 /* TODO: mouse cursor changes. */
7543 redo_mouse_highlight ()
7545 if (!NILP (last_mouse_motion_frame
)
7546 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7547 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7548 last_mouse_motion_position
.h
,
7549 last_mouse_motion_position
.v
);
7554 /***********************************************************************
7556 ***********************************************************************/
7558 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7559 struct glyph
**, int *, int *, int *));
7561 /* Tool-bar item index of the item on which a mouse button was pressed
7564 static int last_tool_bar_item
;
7567 /* Get information about the tool-bar item at position X/Y on frame F.
7568 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7569 the current matrix of the tool-bar window of F, or NULL if not
7570 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7571 item in F->current_tool_bar_items. Value is
7573 -1 if X/Y is not on a tool-bar item
7574 0 if X/Y is on the same item that was highlighted before.
7578 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7581 struct glyph
**glyph
;
7582 int *hpos
, *vpos
, *prop_idx
;
7584 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7585 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7588 /* Find the glyph under X/Y. */
7589 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7593 /* Get the start of this tool-bar item's properties in
7594 f->current_tool_bar_items. */
7595 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7598 /* Is mouse on the highlighted item? */
7599 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7600 && *vpos
>= dpyinfo
->mouse_face_beg_row
7601 && *vpos
<= dpyinfo
->mouse_face_end_row
7602 && (*vpos
> dpyinfo
->mouse_face_beg_row
7603 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7604 && (*vpos
< dpyinfo
->mouse_face_end_row
7605 || *hpos
< dpyinfo
->mouse_face_end_col
7606 || dpyinfo
->mouse_face_past_end
))
7613 /* Handle mouse button event on the tool-bar of frame F, at
7614 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7618 x_handle_tool_bar_click (f
, button_event
)
7620 EventRecord
*button_event
;
7622 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7623 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7624 int hpos
, vpos
, prop_idx
;
7625 struct glyph
*glyph
;
7626 Lisp_Object enabled_p
;
7627 int x
= button_event
->where
.h
;
7628 int y
= button_event
->where
.v
;
7630 /* If not on the highlighted tool-bar item, return. */
7631 frame_to_window_pixel_xy (w
, &x
, &y
);
7632 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7635 /* If item is disabled, do nothing. */
7636 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7637 if (NILP (enabled_p
))
7640 if (button_event
->what
== mouseDown
)
7642 /* Show item in pressed state. */
7643 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7644 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7645 last_tool_bar_item
= prop_idx
;
7649 Lisp_Object key
, frame
;
7650 struct input_event event
;
7652 /* Show item in released state. */
7653 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7654 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7656 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7658 XSETFRAME (frame
, f
);
7659 event
.kind
= TOOL_BAR_EVENT
;
7660 event
.frame_or_window
= frame
;
7662 kbd_buffer_store_event (&event
);
7664 event
.kind
= TOOL_BAR_EVENT
;
7665 event
.frame_or_window
= frame
;
7667 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7668 button_event
->modifiers
);
7669 kbd_buffer_store_event (&event
);
7670 last_tool_bar_item
= -1;
7675 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7676 tool-bar window-relative coordinates X/Y. Called from
7677 note_mouse_highlight. */
7680 note_tool_bar_highlight (f
, x
, y
)
7684 Lisp_Object window
= f
->tool_bar_window
;
7685 struct window
*w
= XWINDOW (window
);
7686 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7688 struct glyph
*glyph
;
7689 struct glyph_row
*row
;
7691 Lisp_Object enabled_p
;
7693 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7694 int mouse_down_p
, rc
;
7696 /* Function note_mouse_highlight is called with negative x(y
7697 values when mouse moves outside of the frame. */
7698 if (x
<= 0 || y
<= 0)
7700 clear_mouse_face (dpyinfo
);
7704 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7707 /* Not on tool-bar item. */
7708 clear_mouse_face (dpyinfo
);
7712 /* On same tool-bar item as before. */
7715 clear_mouse_face (dpyinfo
);
7717 /* Mouse is down, but on different tool-bar item? */
7718 mouse_down_p
= (dpyinfo
->grabbed
7719 && f
== last_mouse_frame
7720 && FRAME_LIVE_P (f
));
7722 && last_tool_bar_item
!= prop_idx
)
7725 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7726 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7728 /* If tool-bar item is not enabled, don't highlight it. */
7729 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7730 if (!NILP (enabled_p
))
7732 /* Compute the x-position of the glyph. In front and past the
7733 image is a space. We include this is the highlighted area. */
7734 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7735 for (i
= x
= 0; i
< hpos
; ++i
)
7736 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7738 /* Record this as the current active region. */
7739 dpyinfo
->mouse_face_beg_col
= hpos
;
7740 dpyinfo
->mouse_face_beg_row
= vpos
;
7741 dpyinfo
->mouse_face_beg_x
= x
;
7742 dpyinfo
->mouse_face_beg_y
= row
->y
;
7743 dpyinfo
->mouse_face_past_end
= 0;
7745 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7746 dpyinfo
->mouse_face_end_row
= vpos
;
7747 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7748 dpyinfo
->mouse_face_end_y
= row
->y
;
7749 dpyinfo
->mouse_face_window
= window
;
7750 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7752 /* Display it as active. */
7753 show_mouse_face (dpyinfo
, draw
);
7754 dpyinfo
->mouse_face_image_state
= draw
;
7759 /* Set help_echo to a help string.to display for this tool-bar item.
7760 XTread_socket does the rest. */
7761 help_echo_object
= help_echo_window
= Qnil
;
7763 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7764 if (NILP (help_echo
))
7765 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7770 /* Find the glyph matrix position of buffer position CHARPOS in window
7771 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7772 current glyphs must be up to date. If CHARPOS is above window
7773 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7774 of last line in W. In the row containing CHARPOS, stop before glyphs
7775 having STOP as object. */
7777 #if 0 /* This is a version of fast_find_position that's more correct
7778 in the presence of hscrolling, for example. I didn't install
7779 it right away because the problem fixed is minor, it failed
7780 in 20.x as well, and I think it's too risky to install
7781 so near the release of 21.1. 2001-09-25 gerd. */
7784 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7787 int *hpos
, *vpos
, *x
, *y
;
7790 struct glyph_row
*row
, *first
;
7791 struct glyph
*glyph
, *end
;
7792 int i
, past_end
= 0;
7794 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7795 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7798 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7800 *x
= *y
= *hpos
= *vpos
= 0;
7805 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7812 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7814 glyph
= row
->glyphs
[TEXT_AREA
];
7815 end
= glyph
+ row
->used
[TEXT_AREA
];
7817 /* Skip over glyphs not having an object at the start of the row.
7818 These are special glyphs like truncation marks on terminal
7820 if (row
->displays_text_p
)
7822 && INTEGERP (glyph
->object
)
7823 && !EQ (stop
, glyph
->object
)
7824 && glyph
->charpos
< 0)
7826 *x
+= glyph
->pixel_width
;
7831 && !INTEGERP (glyph
->object
)
7832 && !EQ (stop
, glyph
->object
)
7833 && (!BUFFERP (glyph
->object
)
7834 || glyph
->charpos
< charpos
))
7836 *x
+= glyph
->pixel_width
;
7840 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7847 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7850 int *hpos
, *vpos
, *x
, *y
;
7855 int maybe_next_line_p
= 0;
7856 int line_start_position
;
7857 int yb
= window_text_bottom_y (w
);
7858 struct glyph_row
*row
, *best_row
;
7859 int row_vpos
, best_row_vpos
;
7862 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7863 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7867 if (row
->used
[TEXT_AREA
])
7868 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7870 line_start_position
= 0;
7872 if (line_start_position
> pos
)
7874 /* If the position sought is the end of the buffer,
7875 don't include the blank lines at the bottom of the window. */
7876 else if (line_start_position
== pos
7877 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7879 maybe_next_line_p
= 1;
7882 else if (line_start_position
> 0)
7885 best_row_vpos
= row_vpos
;
7888 if (row
->y
+ row
->height
>= yb
)
7895 /* Find the right column within BEST_ROW. */
7897 current_x
= best_row
->x
;
7898 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7900 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7901 int charpos
= glyph
->charpos
;
7903 if (BUFFERP (glyph
->object
))
7908 *vpos
= best_row_vpos
;
7913 else if (charpos
> pos
)
7916 else if (EQ (glyph
->object
, stop
))
7921 current_x
+= glyph
->pixel_width
;
7924 /* If we're looking for the end of the buffer,
7925 and we didn't find it in the line we scanned,
7926 use the start of the following line. */
7927 if (maybe_next_line_p
)
7932 current_x
= best_row
->x
;
7935 *vpos
= best_row_vpos
;
7936 *hpos
= lastcol
+ 1;
7945 /* Find the position of the glyph for position POS in OBJECT in
7946 window W's current matrix, and return in *X/*Y the pixel
7947 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7949 RIGHT_P non-zero means return the position of the right edge of the
7950 glyph, RIGHT_P zero means return the left edge position.
7952 If no glyph for POS exists in the matrix, return the position of
7953 the glyph with the next smaller position that is in the matrix, if
7954 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7955 exists in the matrix, return the position of the glyph with the
7956 next larger position in OBJECT.
7958 Value is non-zero if a glyph was found. */
7961 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7965 int *hpos
, *vpos
, *x
, *y
;
7968 int yb
= window_text_bottom_y (w
);
7969 struct glyph_row
*r
;
7970 struct glyph
*best_glyph
= NULL
;
7971 struct glyph_row
*best_row
= NULL
;
7974 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7975 r
->enabled_p
&& r
->y
< yb
;
7978 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7979 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7982 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7983 if (EQ (g
->object
, object
))
7985 if (g
->charpos
== pos
)
7992 else if (best_glyph
== NULL
7993 || ((abs (g
->charpos
- pos
)
7994 < abs (best_glyph
->charpos
- pos
))
7997 : g
->charpos
> pos
)))
8011 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
8015 *x
+= best_glyph
->pixel_width
;
8020 *vpos
= best_row
- w
->current_matrix
->rows
;
8023 return best_glyph
!= NULL
;
8027 /* Display the active region described by mouse_face_*
8028 in its mouse-face if HL > 0, in its normal face if HL = 0. */
8031 show_mouse_face (dpyinfo
, draw
)
8032 struct mac_display_info
*dpyinfo
;
8033 enum draw_glyphs_face draw
;
8035 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
8036 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8038 if (/* If window is in the process of being destroyed, don't bother
8040 w
->current_matrix
!= NULL
8041 /* Don't update mouse highlight if hidden */
8042 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
8043 /* Recognize when we are called to operate on rows that don't exist
8044 anymore. This can happen when a window is split. */
8045 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
8047 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
8048 struct glyph_row
*row
, *first
, *last
;
8050 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
8051 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
8053 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
8055 int start_hpos
, end_hpos
, start_x
;
8057 /* For all but the first row, the highlight starts at column 0. */
8060 start_hpos
= dpyinfo
->mouse_face_beg_col
;
8061 start_x
= dpyinfo
->mouse_face_beg_x
;
8070 end_hpos
= dpyinfo
->mouse_face_end_col
;
8072 end_hpos
= row
->used
[TEXT_AREA
];
8074 if (end_hpos
> start_hpos
)
8076 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
8077 start_hpos
, end_hpos
, draw
, 0);
8080 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8084 /* When we've written over the cursor, arrange for it to
8085 be displayed again. */
8086 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8087 x_display_cursor (w
, 1,
8088 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8089 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8092 #if 0 /* MAC_TODO: mouse cursor */
8093 /* Change the mouse cursor. */
8094 if (draw
== DRAW_NORMAL_TEXT
)
8095 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8096 f
->output_data
.x
->text_cursor
);
8097 else if (draw
== DRAW_MOUSE_FACE
)
8098 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8099 f
->output_data
.x
->cross_cursor
);
8101 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8102 f
->output_data
.x
->nontext_cursor
);
8106 /* Clear out the mouse-highlighted active region.
8107 Redraw it un-highlighted first. */
8110 clear_mouse_face (dpyinfo
)
8111 struct mac_display_info
*dpyinfo
;
8115 if (! NILP (dpyinfo
->mouse_face_window
))
8117 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8121 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8122 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8123 dpyinfo
->mouse_face_window
= Qnil
;
8124 dpyinfo
->mouse_face_overlay
= Qnil
;
8129 /* Clear any mouse-face on window W. This function is part of the
8130 redisplay interface, and is called from try_window_id and similar
8131 functions to ensure the mouse-highlight is off. */
8134 x_clear_mouse_face (w
)
8137 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
8141 XSETWINDOW (window
, w
);
8142 if (EQ (window
, dpyinfo
->mouse_face_window
))
8143 clear_mouse_face (dpyinfo
);
8148 /* Just discard the mouse face information for frame F, if any.
8149 This is used when the size of F is changed. */
8152 cancel_mouse_face (f
)
8156 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8158 window
= dpyinfo
->mouse_face_window
;
8159 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8161 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8162 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8163 dpyinfo
->mouse_face_window
= Qnil
;
8167 static struct scroll_bar
*x_window_to_scroll_bar ();
8168 static void x_scroll_bar_report_motion ();
8169 static void x_check_fullscreen
P_ ((struct frame
*));
8170 static void x_check_fullscreen_move
P_ ((struct frame
*));
8171 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
8174 /* Try to determine frame pixel position and size of the glyph under
8175 frame pixel coordinates X/Y on frame F . Return the position and
8176 size in *RECT. Value is non-zero if we could compute these
8180 glyph_rect (f
, x
, y
, rect
)
8188 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8191 struct window
*w
= XWINDOW (window
);
8192 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8193 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8195 frame_to_window_pixel_xy (w
, &x
, &y
);
8197 for (; r
< end
&& r
->enabled_p
; ++r
)
8198 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
8200 /* Found the row at y. */
8201 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8202 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8205 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8206 rect
->bottom
= rect
->top
+ r
->height
;
8210 /* x is to the left of the first glyph in the row. */
8211 rect
->left
= XINT (w
->left
);
8212 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
8216 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
8217 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
8219 /* x is on a glyph. */
8220 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8221 rect
->right
= rect
->left
+ g
->pixel_width
;
8225 /* x is to the right of the last glyph in the row. */
8226 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8227 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8232 /* The y is not on any row. */
8236 /* Record the position of the mouse in last_mouse_glyph. */
8238 remember_mouse_glyph (f1
, gx
, gy
)
8242 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8244 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8245 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8247 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8248 round down even for negative values. */
8254 /* This was the original code from XTmouse_position, but it seems
8255 to give the position of the glyph diagonally next to the one
8256 the mouse is over. */
8257 gx
= (gx
+ width
- 1) / width
* width
;
8258 gy
= (gy
+ height
- 1) / height
* height
;
8260 gx
= gx
/ width
* width
;
8261 gy
= gy
/ height
* height
;
8264 last_mouse_glyph
.left
= gx
;
8265 last_mouse_glyph
.top
= gy
;
8266 last_mouse_glyph
.right
= gx
+ width
;
8267 last_mouse_glyph
.bottom
= gy
+ height
;
8271 /* Return the current position of the mouse.
8272 *fp should be a frame which indicates which display to ask about.
8274 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8275 and *part to the frame, window, and scroll bar part that the mouse
8276 is over. Set *x and *y to the portion and whole of the mouse's
8277 position on the scroll bar.
8279 If the mouse movement started elsewhere, set *fp to the frame the
8280 mouse is on, *bar_window to nil, and *x and *y to the character cell
8283 Set *time to the server time-stamp for the time at which the mouse
8284 was at this position.
8286 Don't store anything if we don't have a valid set of values to report.
8288 This clears the mouse_moved flag, so we can wait for the next mouse
8292 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8295 Lisp_Object
*bar_window
;
8296 enum scroll_bar_part
*part
;
8298 unsigned long *time
;
8301 int ignore1
, ignore2
;
8302 WindowPtr wp
= FrontWindow ();
8304 Lisp_Object frame
, tail
;
8306 if (is_emacs_window(wp
))
8307 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8311 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8312 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8315 /* Clear the mouse-moved flag for every frame on this display. */
8316 FOR_EACH_FRAME (tail
, frame
)
8317 XFRAME (frame
)->mouse_moved
= 0;
8319 last_mouse_scroll_bar
= Qnil
;
8321 #if TARGET_API_MAC_CARBON
8322 SetPort (GetWindowPort (wp
));
8327 GetMouse (&mouse_pos
);
8329 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8330 &last_mouse_glyph
, insist
);
8333 *part
= scroll_bar_handle
;
8335 XSETINT (*x
, mouse_pos
.h
);
8336 XSETINT (*y
, mouse_pos
.v
);
8337 *time
= last_mouse_movement_time
;
8344 /************************************************************************
8345 Scroll bars, general
8346 ************************************************************************/
8348 /* Create a scroll bar and return the scroll bar vector for it. W is
8349 the Emacs window on which to create the scroll bar. TOP, LEFT,
8350 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8353 static struct scroll_bar
*
8354 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8356 int top
, left
, width
, height
, disp_top
, disp_height
;
8358 struct frame
*f
= XFRAME (w
->frame
);
8359 struct scroll_bar
*bar
8360 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8368 r
.right
= left
+ width
;
8369 r
.bottom
= disp_top
+ disp_height
;
8371 #ifdef TARGET_API_MAC_CARBON
8372 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8373 kControlScrollBarProc
, 0L);
8375 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8378 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8379 SetControlReference (ch
, (long) bar
);
8381 XSETWINDOW (bar
->window
, w
);
8382 XSETINT (bar
->top
, top
);
8383 XSETINT (bar
->left
, left
);
8384 XSETINT (bar
->width
, width
);
8385 XSETINT (bar
->height
, height
);
8386 XSETINT (bar
->start
, 0);
8387 XSETINT (bar
->end
, 0);
8388 bar
->dragging
= Qnil
;
8390 /* Add bar to its frame's list of scroll bars. */
8391 bar
->next
= FRAME_SCROLL_BARS (f
);
8393 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8394 if (!NILP (bar
->next
))
8395 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8402 /* Draw BAR's handle in the proper position.
8404 If the handle is already drawn from START to END, don't bother
8405 redrawing it, unless REBUILD is non-zero; in that case, always
8406 redraw it. (REBUILD is handy for drawing the handle after expose
8409 Normally, we want to constrain the start and end of the handle to
8410 fit inside its rectangle, but if the user is dragging the scroll
8411 bar handle, we want to let them drag it down all the way, so that
8412 the bar's top is as far down as it goes; otherwise, there's no way
8413 to move to the very end of the buffer. */
8416 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8417 struct scroll_bar
*bar
;
8421 int dragging
= ! NILP (bar
->dragging
);
8422 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8423 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8424 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8425 int length
= end
- start
;
8427 /* If the display is already accurate, do nothing. */
8429 && start
== XINT (bar
->start
)
8430 && end
== XINT (bar
->end
))
8435 /* Make sure the values are reasonable, and try to preserve the
8436 distance between start and end. */
8439 else if (start
> top_range
)
8441 end
= start
+ length
;
8445 else if (end
> top_range
&& ! dragging
)
8448 /* Store the adjusted setting in the scroll bar. */
8449 XSETINT (bar
->start
, start
);
8450 XSETINT (bar
->end
, end
);
8452 /* Clip the end position, just for display. */
8453 if (end
> top_range
)
8456 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8457 top positions, to make sure the handle is always at least that
8458 many pixels tall. */
8459 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8461 SetControlMinimum (ch
, 0);
8462 /* Don't inadvertently activate deactivated scroll bars */
8463 if (GetControlMaximum (ch
) != -1)
8464 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8466 SetControlValue (ch
, start
);
8467 #if TARGET_API_MAC_CARBON
8468 SetControlViewSize (ch
, end
- start
);
8475 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8479 x_scroll_bar_remove (bar
)
8480 struct scroll_bar
*bar
;
8482 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8486 /* Destroy the Mac scroll bar control */
8487 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8489 /* Disassociate this scroll bar from its window. */
8490 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8495 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8496 that we are displaying PORTION characters out of a total of WHOLE
8497 characters, starting at POSITION. If WINDOW has no scroll bar,
8500 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8502 int portion
, whole
, position
;
8504 struct frame
*f
= XFRAME (w
->frame
);
8505 struct scroll_bar
*bar
;
8506 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8507 int window_x
, window_y
, window_width
, window_height
;
8509 /* Get window dimensions. */
8510 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8515 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8517 height
= window_height
;
8519 /* Compute the left edge of the scroll bar area. */
8520 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8521 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8523 left
= XFASTINT (w
->left
);
8524 left
*= CANON_X_UNIT (f
);
8525 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8527 /* Compute the width of the scroll bar which might be less than
8528 the width of the area reserved for the scroll bar. */
8529 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8530 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8534 /* Compute the left edge of the scroll bar. */
8535 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8536 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8538 sb_left
= left
+ (width
- sb_width
) / 2;
8540 /* Adjustments according to Inside Macintosh to make it look nice */
8542 disp_height
= height
;
8548 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8554 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8557 /* Does the scroll bar exist yet? */
8558 if (NILP (w
->vertical_scroll_bar
))
8561 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8562 left
, top
, width
, height
, 0);
8564 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8566 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8570 /* It may just need to be moved and resized. */
8573 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8574 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8578 /* If already correctly positioned, do nothing. */
8579 if (XINT (bar
->left
) == sb_left
8580 && XINT (bar
->top
) == top
8581 && XINT (bar
->width
) == sb_width
8582 && XINT (bar
->height
) == height
)
8586 /* Clear areas not covered by the scroll bar because it's not as
8587 wide as the area reserved for it . This makes sure a
8588 previous mode line display is cleared after C-x 2 C-x 1, for
8590 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8591 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8592 left
, top
, area_width
, height
, 0);
8595 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8596 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8597 sb_left
- 1, top
, 1, height
, 0);
8601 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8602 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8606 /* Remember new settings. */
8607 XSETINT (bar
->left
, sb_left
);
8608 XSETINT (bar
->top
, top
);
8609 XSETINT (bar
->width
, sb_width
);
8610 XSETINT (bar
->height
, height
);
8616 /* Set the scroll bar's current state, unless we're currently being
8618 if (NILP (bar
->dragging
))
8620 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8623 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8626 int start
= ((double) position
* top_range
) / whole
;
8627 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8628 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8634 /* The following three hooks are used when we're doing a thorough
8635 redisplay of the frame. We don't explicitly know which scroll bars
8636 are going to be deleted, because keeping track of when windows go
8637 away is a real pain - "Can you say set-window-configuration, boys
8638 and girls?" Instead, we just assert at the beginning of redisplay
8639 that *all* scroll bars are to be removed, and then save a scroll bar
8640 from the fiery pit when we actually redisplay its window. */
8642 /* Arrange for all scroll bars on FRAME to be removed at the next call
8643 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8644 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8647 XTcondemn_scroll_bars (frame
)
8650 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8651 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8654 bar
= FRAME_SCROLL_BARS (frame
);
8655 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8656 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8657 XSCROLL_BAR (bar
)->prev
= Qnil
;
8658 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8659 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8660 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8665 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8666 Note that WINDOW isn't necessarily condemned at all. */
8669 XTredeem_scroll_bar (window
)
8670 struct window
*window
;
8672 struct scroll_bar
*bar
;
8674 /* We can't redeem this window's scroll bar if it doesn't have one. */
8675 if (NILP (window
->vertical_scroll_bar
))
8678 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8680 /* Unlink it from the condemned list. */
8682 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8684 if (NILP (bar
->prev
))
8686 /* If the prev pointer is nil, it must be the first in one of
8688 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8689 /* It's not condemned. Everything's fine. */
8691 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8692 window
->vertical_scroll_bar
))
8693 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8695 /* If its prev pointer is nil, it must be at the front of
8696 one or the other! */
8700 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8702 if (! NILP (bar
->next
))
8703 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8705 bar
->next
= FRAME_SCROLL_BARS (f
);
8707 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8708 if (! NILP (bar
->next
))
8709 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8713 /* Remove all scroll bars on FRAME that haven't been saved since the
8714 last call to `*condemn_scroll_bars_hook'. */
8717 XTjudge_scroll_bars (f
)
8720 Lisp_Object bar
, next
;
8722 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8724 /* Clear out the condemned list now so we won't try to process any
8725 more events on the hapless scroll bars. */
8726 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8728 for (; ! NILP (bar
); bar
= next
)
8730 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8732 x_scroll_bar_remove (b
);
8735 b
->next
= b
->prev
= Qnil
;
8738 /* Now there should be no references to the condemned scroll bars,
8739 and they should get garbage-collected. */
8744 activate_scroll_bars (frame
)
8750 bar
= FRAME_SCROLL_BARS (frame
);
8751 while (! NILP (bar
))
8753 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8754 #ifdef TARGET_API_MAC_CARBON
8755 ActivateControl (ch
);
8757 SetControlMaximum (ch
,
8758 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8759 XINT (XSCROLL_BAR (bar
)
8762 bar
= XSCROLL_BAR (bar
)->next
;
8768 deactivate_scroll_bars (frame
)
8774 bar
= FRAME_SCROLL_BARS (frame
);
8775 while (! NILP (bar
))
8777 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8778 #ifdef TARGET_API_MAC_CARBON
8779 DeactivateControl (ch
);
8781 SetControlMaximum (ch
, XINT (-1));
8783 bar
= XSCROLL_BAR (bar
)->next
;
8787 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8788 is set to something other than NO_EVENT, it is enqueued.
8790 This may be called from a signal handler, so we have to ignore GC
8794 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8795 struct scroll_bar
*bar
;
8798 struct input_event
*bufp
;
8800 if (! GC_WINDOWP (bar
->window
))
8803 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
8804 bufp
->frame_or_window
= bar
->window
;
8807 bar
->dragging
= Qnil
;
8811 case kControlUpButtonPart
:
8812 bufp
->part
= scroll_bar_up_arrow
;
8814 case kControlDownButtonPart
:
8815 bufp
->part
= scroll_bar_down_arrow
;
8817 case kControlPageUpPart
:
8818 bufp
->part
= scroll_bar_above_handle
;
8820 case kControlPageDownPart
:
8821 bufp
->part
= scroll_bar_below_handle
;
8823 #ifdef TARGET_API_MAC_CARBON
8826 case kControlIndicatorPart
:
8828 if (er
->what
== mouseDown
)
8829 bar
->dragging
= make_number (0);
8830 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8831 bufp
->part
= scroll_bar_handle
;
8837 /* Handle some mouse motion while someone is dragging the scroll bar.
8839 This may be called from a signal handler, so we have to ignore GC
8843 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8844 struct scroll_bar
*bar
;
8848 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8850 last_mouse_movement_time
= t
;
8853 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8855 /* If we're dragging the bar, display it. */
8856 if (! GC_NILP (bar
->dragging
))
8858 /* Where should the handle be now? */
8859 int new_start
= y_pos
- 24;
8861 if (new_start
!= XINT (bar
->start
))
8863 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8865 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8871 /* Return information to the user about the current position of the
8872 mouse on the scroll bar. */
8875 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8877 Lisp_Object
*bar_window
;
8878 enum scroll_bar_part
*part
;
8880 unsigned long *time
;
8882 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8883 WindowPtr wp
= FrontWindow ();
8885 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8886 int win_y
, top_range
;
8888 #if TARGET_API_MAC_CARBON
8889 SetPort (GetWindowPort (wp
));
8894 GetMouse (&mouse_pos
);
8896 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8897 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8899 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8903 if (! NILP (bar
->dragging
))
8904 win_y
-= XINT (bar
->dragging
);
8908 if (win_y
> top_range
)
8912 *bar_window
= bar
->window
;
8914 if (! NILP (bar
->dragging
))
8915 *part
= scroll_bar_handle
;
8916 else if (win_y
< XINT (bar
->start
))
8917 *part
= scroll_bar_above_handle
;
8918 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8919 *part
= scroll_bar_handle
;
8921 *part
= scroll_bar_below_handle
;
8923 XSETINT (*x
, win_y
);
8924 XSETINT (*y
, top_range
);
8927 last_mouse_scroll_bar
= Qnil
;
8929 *time
= last_mouse_movement_time
;
8932 /***********************************************************************
8934 ***********************************************************************/
8936 /* Notice if the text cursor of window W has been overwritten by a
8937 drawing operation that outputs glyphs starting at START_X and
8938 ending at END_X in the line given by output_cursor.vpos.
8939 Coordinates are area-relative. END_X < 0 means all the rest
8940 of the line after START_X has been written. */
8943 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8945 enum glyph_row_area area
;
8948 if (area
== TEXT_AREA
8949 && w
->phys_cursor_on_p
8950 && y0
<= w
->phys_cursor
.y
8951 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8952 && x0
<= w
->phys_cursor
.x
8953 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8954 w
->phys_cursor_on_p
= 0;
8958 /* Set clipping for output in glyph row ROW. W is the window in which
8959 we operate. GC is the graphics context to set clipping in.
8960 WHOLE_LINE_P non-zero means include the areas used for truncation
8961 mark display and alike in the clipping rectangle.
8963 ROW may be a text row or, e.g., a mode line. Text rows must be
8964 clipped to the interior of the window dedicated to text display,
8965 mode lines must be clipped to the whole window. */
8968 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8970 struct glyph_row
*row
;
8974 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8976 int window_x
, window_y
, window_width
, window_height
;
8978 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8980 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8981 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8982 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8983 clip_rect
.right
= clip_rect
.left
+ window_width
;
8984 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8986 /* If clipping to the whole line, including trunc marks, extend
8987 the rectangle to the left and increase its width. */
8990 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8991 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8994 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8998 /* Draw a hollow box cursor on window W in glyph row ROW. */
9001 x_draw_hollow_cursor (w
, row
)
9003 struct glyph_row
*row
;
9005 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
9006 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9007 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
9010 struct glyph
*cursor_glyph
;
9013 /* Compute frame-relative coordinates from window-relative
9015 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9016 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
9017 + row
->ascent
- w
->phys_cursor_ascent
);
9018 h
= row
->height
- 1;
9020 /* Get the glyph the cursor is on. If we can't tell because
9021 the current matrix is invalid or such, give up. */
9022 cursor_glyph
= get_phys_cursor_glyph (w
);
9023 if (cursor_glyph
== NULL
)
9026 /* Compute the width of the rectangle to draw. If on a stretch
9027 glyph, and `x-stretch-block-cursor' is nil, don't draw a
9028 rectangle as wide as the glyph, but use a canonical character
9030 wd
= cursor_glyph
->pixel_width
- 1;
9031 if (cursor_glyph
->type
== STRETCH_GLYPH
9032 && !x_stretch_cursor_p
)
9033 wd
= min (CANON_X_UNIT (f
), wd
);
9035 /* The foreground of cursor_gc is typically the same as the normal
9036 background color, which can cause the cursor box to be invisible. */
9037 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9038 if (dpyinfo
->scratch_cursor_gc
)
9039 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
9041 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
9042 GCForeground
, &xgcv
);
9043 gc
= dpyinfo
->scratch_cursor_gc
;
9045 /* Set clipping, draw the rectangle, and reset clipping again. */
9046 x_clip_to_row (w
, row
, gc
, 0);
9047 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
9048 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9052 /* Draw a bar cursor on window W in glyph row ROW.
9054 Implementation note: One would like to draw a bar cursor with an
9055 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9056 Unfortunately, I didn't find a font yet that has this property set.
9060 x_draw_bar_cursor (w
, row
, width
)
9062 struct glyph_row
*row
;
9065 /* If cursor hpos is out of bounds, don't draw garbage. This can
9066 happen in mini-buffer windows when switching between echo area
9067 glyphs and mini-buffer. */
9068 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9070 struct frame
*f
= XFRAME (w
->frame
);
9071 struct glyph
*cursor_glyph
;
9079 cursor_glyph
= get_phys_cursor_glyph (w
);
9080 if (cursor_glyph
== NULL
)
9083 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
9084 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9085 mask
= GCForeground
| GCBackground
;
9086 dpy
= FRAME_MAC_DISPLAY (f
);
9087 window
= FRAME_MAC_WINDOW (f
);
9088 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9091 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9094 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9095 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9099 width
= FRAME_CURSOR_WIDTH (f
);
9101 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9102 x_clip_to_row (w
, row
, gc
, 0);
9103 XFillRectangle (dpy
, window
, gc
,
9105 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9106 min (cursor_glyph
->pixel_width
, width
),
9108 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9113 /* Clear the cursor of window W to background color, and mark the
9114 cursor as not shown. This is used when the text where the cursor
9115 is is about to be rewritten. */
9121 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9122 x_update_window_cursor (w
, 0);
9126 /* Draw the cursor glyph of window W in glyph row ROW. See the
9127 comment of x_draw_glyphs for the meaning of HL. */
9130 x_draw_phys_cursor_glyph (w
, row
, hl
)
9132 struct glyph_row
*row
;
9133 enum draw_glyphs_face hl
;
9135 /* If cursor hpos is out of bounds, don't draw garbage. This can
9136 happen in mini-buffer windows when switching between echo area
9137 glyphs and mini-buffer. */
9138 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9140 int on_p
= w
->phys_cursor_on_p
;
9141 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9142 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9144 w
->phys_cursor_on_p
= on_p
;
9146 /* When we erase the cursor, and ROW is overlapped by other
9147 rows, make sure that these overlapping parts of other rows
9149 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9151 if (row
> w
->current_matrix
->rows
9152 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9153 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9155 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9156 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9157 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9163 /* Erase the image of a cursor of window W from the screen. */
9166 x_erase_phys_cursor (w
)
9169 struct frame
*f
= XFRAME (w
->frame
);
9170 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9171 int hpos
= w
->phys_cursor
.hpos
;
9172 int vpos
= w
->phys_cursor
.vpos
;
9173 int mouse_face_here_p
= 0;
9174 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9175 struct glyph_row
*cursor_row
;
9176 struct glyph
*cursor_glyph
;
9177 enum draw_glyphs_face hl
;
9179 /* No cursor displayed or row invalidated => nothing to do on the
9181 if (w
->phys_cursor_type
== NO_CURSOR
)
9182 goto mark_cursor_off
;
9184 /* VPOS >= active_glyphs->nrows means that window has been resized.
9185 Don't bother to erase the cursor. */
9186 if (vpos
>= active_glyphs
->nrows
)
9187 goto mark_cursor_off
;
9189 /* If row containing cursor is marked invalid, there is nothing we
9191 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9192 if (!cursor_row
->enabled_p
)
9193 goto mark_cursor_off
;
9195 /* If row is completely invisible, don't attempt to delete a cursor which
9196 isn't there. This may happen if cursor is at top of window, and
9197 we switch to a buffer with a header line in that window. */
9198 if (cursor_row
->visible_height
<= 0)
9199 goto mark_cursor_off
;
9201 /* This can happen when the new row is shorter than the old one.
9202 In this case, either x_draw_glyphs or clear_end_of_line
9203 should have cleared the cursor. Note that we wouldn't be
9204 able to erase the cursor in this case because we don't have a
9205 cursor glyph at hand. */
9206 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9207 goto mark_cursor_off
;
9209 /* If the cursor is in the mouse face area, redisplay that when
9210 we clear the cursor. */
9211 if (! NILP (dpyinfo
->mouse_face_window
)
9212 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9213 && (vpos
> dpyinfo
->mouse_face_beg_row
9214 || (vpos
== dpyinfo
->mouse_face_beg_row
9215 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9216 && (vpos
< dpyinfo
->mouse_face_end_row
9217 || (vpos
== dpyinfo
->mouse_face_end_row
9218 && hpos
< dpyinfo
->mouse_face_end_col
))
9219 /* Don't redraw the cursor's spot in mouse face if it is at the
9220 end of a line (on a newline). The cursor appears there, but
9221 mouse highlighting does not. */
9222 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9223 mouse_face_here_p
= 1;
9225 /* Maybe clear the display under the cursor. */
9226 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9229 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9231 cursor_glyph
= get_phys_cursor_glyph (w
);
9232 if (cursor_glyph
== NULL
)
9233 goto mark_cursor_off
;
9235 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9237 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9239 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9241 cursor_glyph
->pixel_width
,
9242 cursor_row
->visible_height
,
9246 /* Erase the cursor by redrawing the character underneath it. */
9247 if (mouse_face_here_p
)
9248 hl
= DRAW_MOUSE_FACE
;
9250 hl
= DRAW_NORMAL_TEXT
;
9251 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9254 w
->phys_cursor_on_p
= 0;
9255 w
->phys_cursor_type
= NO_CURSOR
;
9259 /* Non-zero if physical cursor of window W is within mouse face. */
9262 cursor_in_mouse_face_p (w
)
9265 struct mac_display_info
*dpyinfo
9266 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9267 int in_mouse_face
= 0;
9269 if (WINDOWP (dpyinfo
->mouse_face_window
)
9270 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9272 int hpos
= w
->phys_cursor
.hpos
;
9273 int vpos
= w
->phys_cursor
.vpos
;
9275 if (vpos
>= dpyinfo
->mouse_face_beg_row
9276 && vpos
<= dpyinfo
->mouse_face_end_row
9277 && (vpos
> dpyinfo
->mouse_face_beg_row
9278 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9279 && (vpos
< dpyinfo
->mouse_face_end_row
9280 || hpos
< dpyinfo
->mouse_face_end_col
9281 || dpyinfo
->mouse_face_past_end
))
9285 return in_mouse_face
;
9289 /* Display or clear cursor of window W. If ON is zero, clear the
9290 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9291 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9294 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9296 int on
, hpos
, vpos
, x
, y
;
9298 struct frame
*f
= XFRAME (w
->frame
);
9299 int new_cursor_type
;
9300 int new_cursor_width
;
9302 struct glyph_matrix
*current_glyphs
;
9303 struct glyph_row
*glyph_row
;
9304 struct glyph
*glyph
;
9306 /* This is pointless on invisible frames, and dangerous on garbaged
9307 windows and frames; in the latter case, the frame or window may
9308 be in the midst of changing its size, and x and y may be off the
9310 if (! FRAME_VISIBLE_P (f
)
9311 || FRAME_GARBAGED_P (f
)
9312 || vpos
>= w
->current_matrix
->nrows
9313 || hpos
>= w
->current_matrix
->matrix_w
)
9316 /* If cursor is off and we want it off, return quickly. */
9317 if (!on
&& !w
->phys_cursor_on_p
)
9320 current_glyphs
= w
->current_matrix
;
9321 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9322 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9324 /* If cursor row is not enabled, we don't really know where to
9325 display the cursor. */
9326 if (!glyph_row
->enabled_p
)
9328 w
->phys_cursor_on_p
= 0;
9332 xassert (interrupt_input_blocked
);
9334 /* Set new_cursor_type to the cursor we want to be displayed. */
9335 new_cursor_type
= get_window_cursor_type (w
, &new_cursor_width
, &active_cursor
);
9338 /* If cursor is currently being shown and we don't want it to be or
9339 it is in the wrong place, or the cursor type is not what we want,
9341 if (w
->phys_cursor_on_p
9343 || w
->phys_cursor
.x
!= x
9344 || w
->phys_cursor
.y
!= y
9345 || new_cursor_type
!= w
->phys_cursor_type
9346 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
9347 && new_cursor_width
!= w
->phys_cursor_width
)))
9348 x_erase_phys_cursor (w
);
9350 /* If the cursor is now invisible and we want it to be visible,
9352 if (on
&& !w
->phys_cursor_on_p
)
9354 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9355 w
->phys_cursor_height
= glyph_row
->height
;
9357 /* Set phys_cursor_.* before x_draw_.* is called because some
9358 of them may need the information. */
9359 w
->phys_cursor
.x
= x
;
9360 w
->phys_cursor
.y
= glyph_row
->y
;
9361 w
->phys_cursor
.hpos
= hpos
;
9362 w
->phys_cursor
.vpos
= vpos
;
9363 w
->phys_cursor_type
= new_cursor_type
;
9364 w
->phys_cursor_width
= new_cursor_width
;
9365 w
->phys_cursor_on_p
= 1;
9367 switch (new_cursor_type
)
9369 case HOLLOW_BOX_CURSOR
:
9370 x_draw_hollow_cursor (w
, glyph_row
);
9373 case FILLED_BOX_CURSOR
:
9374 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9378 /* TODO. For now, just draw bar cursor. */
9380 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9393 /* Display the cursor on window W, or clear it. X and Y are window
9394 relative pixel coordinates. HPOS and VPOS are glyph matrix
9395 positions. If W is not the selected window, display a hollow
9396 cursor. ON non-zero means display the cursor at X, Y which
9397 correspond to HPOS, VPOS, otherwise it is cleared. */
9400 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9402 int on
, hpos
, vpos
, x
, y
;
9405 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9410 /* Display the cursor on window W, or clear it, according to ON_P.
9411 Don't change the cursor's position. */
9414 x_update_cursor (f
, on_p
)
9418 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9422 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9423 in the window tree rooted at W. */
9426 x_update_cursor_in_window_tree (w
, on_p
)
9432 if (!NILP (w
->hchild
))
9433 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9434 else if (!NILP (w
->vchild
))
9435 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9437 x_update_window_cursor (w
, on_p
);
9439 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9444 /* Switch the display of W's cursor on or off, according to the value
9448 x_update_window_cursor (w
, on
)
9452 /* Don't update cursor in windows whose frame is in the process
9453 of being deleted. */
9454 if (w
->current_matrix
)
9457 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9458 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9469 #if 0 /* MAC_TODO: no icon support yet. */
9471 x_bitmap_icon (f
, icon
)
9477 if (FRAME_W32_WINDOW (f
) == 0)
9481 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9482 else if (STRINGP (icon
))
9483 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9484 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9485 else if (SYMBOLP (icon
))
9489 if (EQ (icon
, intern ("application")))
9490 name
= (LPCTSTR
) IDI_APPLICATION
;
9491 else if (EQ (icon
, intern ("hand")))
9492 name
= (LPCTSTR
) IDI_HAND
;
9493 else if (EQ (icon
, intern ("question")))
9494 name
= (LPCTSTR
) IDI_QUESTION
;
9495 else if (EQ (icon
, intern ("exclamation")))
9496 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9497 else if (EQ (icon
, intern ("asterisk")))
9498 name
= (LPCTSTR
) IDI_ASTERISK
;
9499 else if (EQ (icon
, intern ("winlogo")))
9500 name
= (LPCTSTR
) IDI_WINLOGO
;
9504 hicon
= LoadIcon (NULL
, name
);
9512 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9517 #endif /* MAC_TODO */
9519 /************************************************************************
9521 ************************************************************************/
9523 /* Display Error Handling functions not used on W32. Listing them here
9524 helps diff stay in step when comparing w32term.c with xterm.c.
9526 x_error_catcher (display, error)
9527 x_catch_errors (dpy)
9528 x_catch_errors_unwind (old_val)
9529 x_check_errors (dpy, format)
9530 x_had_errors_p (dpy)
9531 x_clear_errors (dpy)
9532 x_uncatch_errors (dpy, count)
9534 x_connection_signal (signalnum)
9535 x_connection_closed (dpy, error_message)
9536 x_error_quitter (display, error)
9537 x_error_handler (display, error)
9538 x_io_error_quitter (display)
9543 /* Changing the font of the frame. */
9545 /* Give frame F the font named FONTNAME as its default font, and
9546 return the full name of that font. FONTNAME may be a wildcard
9547 pattern; in that case, we choose some font that fits the pattern.
9548 The return value shows which font we chose. */
9551 x_new_font (f
, fontname
)
9553 register char *fontname
;
9555 struct font_info
*fontp
9556 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9561 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9562 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9563 FRAME_FONTSET (f
) = -1;
9565 /* Compute the scroll bar width in character columns. */
9566 if (f
->scroll_bar_pixel_width
> 0)
9568 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9569 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9573 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9574 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9577 /* Now make the frame display the given font. */
9578 if (FRAME_MAC_WINDOW (f
) != 0)
9580 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9581 f
->output_data
.mac
->font
);
9582 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9583 f
->output_data
.mac
->font
);
9584 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9585 f
->output_data
.mac
->font
);
9587 frame_update_line_height (f
);
9588 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9589 x_set_window_size (f
, 0, f
->width
, f
->height
);
9592 /* If we are setting a new frame's font for the first time,
9593 there are no faces yet, so this font's height is the line height. */
9594 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9596 return build_string (fontp
->full_name
);
9599 /* Give frame F the fontset named FONTSETNAME as its default font, and
9600 return the full name of that fontset. FONTSETNAME may be a wildcard
9601 pattern; in that case, we choose some fontset that fits the pattern.
9602 The return value shows which fontset we chose. */
9605 x_new_fontset (f
, fontsetname
)
9609 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9615 if (FRAME_FONTSET (f
) == fontset
)
9616 /* This fontset is already set in frame F. There's nothing more
9618 return fontset_name (fontset
);
9620 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
9622 if (!STRINGP (result
))
9623 /* Can't load ASCII font. */
9626 /* Since x_new_font doesn't update any fontset information, do it now. */
9627 FRAME_FONTSET(f
) = fontset
;
9629 return build_string (fontsetname
);
9632 /* Compute actual fringe widths */
9635 x_compute_fringe_widths (f
, redraw
)
9639 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9640 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9641 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9643 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9644 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9645 int left_fringe_width
, right_fringe_width
;
9647 if (!NILP (left_fringe
))
9648 left_fringe
= Fcdr (left_fringe
);
9649 if (!NILP (right_fringe
))
9650 right_fringe
= Fcdr (right_fringe
);
9652 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9653 XINT (left_fringe
));
9654 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9655 XINT (right_fringe
));
9657 if (left_fringe_width
|| right_fringe_width
)
9659 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9660 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9661 int conf_wid
= left_wid
+ right_wid
;
9662 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9663 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9664 int real_wid
= cols
* font_wid
;
9665 if (left_wid
&& right_wid
)
9667 if (left_fringe_width
< 0)
9669 /* Left fringe width is fixed, adjust right fringe if necessary */
9670 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9671 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9673 else if (right_fringe_width
< 0)
9675 /* Right fringe width is fixed, adjust left fringe if necessary */
9676 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9677 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9681 /* Adjust both fringes with an equal amount.
9682 Note that we are doing integer arithmetic here, so don't
9683 lose a pixel if the total width is an odd number. */
9684 int fill
= real_wid
- conf_wid
;
9685 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9686 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9689 else if (left_fringe_width
)
9691 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9692 f
->output_data
.mac
->right_fringe_width
= 0;
9696 f
->output_data
.mac
->left_fringe_width
= 0;
9697 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9699 f
->output_data
.mac
->fringe_cols
= cols
;
9700 f
->output_data
.mac
->fringes_extra
= real_wid
;
9704 f
->output_data
.mac
->left_fringe_width
= 0;
9705 f
->output_data
.mac
->right_fringe_width
= 0;
9706 f
->output_data
.mac
->fringe_cols
= 0;
9707 f
->output_data
.mac
->fringes_extra
= 0;
9710 if (redraw
&& FRAME_VISIBLE_P (f
))
9711 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9712 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9713 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9717 /***********************************************************************
9718 TODO: W32 Input Methods
9719 ***********************************************************************/
9720 /* Listing missing functions from xterm.c helps diff stay in step.
9722 xim_destroy_callback (xim, client_data, call_data)
9723 xim_open_dpy (dpyinfo, resource_name)
9725 xim_instantiate_callback (display, client_data, call_data)
9726 xim_initialize (dpyinfo, resource_name)
9727 xim_close_dpy (dpyinfo)
9732 /* Calculate the absolute position in frame F
9733 from its current recorded position values and gravity. */
9736 x_calc_absolute_position (f
)
9740 int flags
= f
->output_data
.mac
->size_hint_flags
;
9744 /* Find the position of the outside upper-left corner of
9745 the inner window, with respect to the outer window. */
9746 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9749 GetPort (&savePort
);
9751 #if TARGET_API_MAC_CARBON
9752 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9754 SetPort (FRAME_MAC_WINDOW (f
));
9757 #if TARGET_API_MAC_CARBON
9761 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9762 SetPt(&pt
, r
.left
, r
.top
);
9764 #else /* not TARGET_API_MAC_CARBON */
9765 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9766 #endif /* not TARGET_API_MAC_CARBON */
9767 LocalToGlobal (&pt
);
9771 /* Treat negative positions as relative to the leftmost bottommost
9772 position that fits on the screen. */
9773 if (flags
& XNegative
)
9774 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9775 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9777 + f
->output_data
.mac
->left_pos
);
9778 /* NTEMACS_TODO: Subtract menubar height? */
9779 if (flags
& YNegative
)
9780 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9781 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9783 + f
->output_data
.mac
->top_pos
);
9784 /* The left_pos and top_pos
9785 are now relative to the top and left screen edges,
9786 so the flags should correspond. */
9787 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9790 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9791 to really change the position, and 0 when calling from
9792 x_make_frame_visible (in that case, XOFF and YOFF are the current
9793 position values). It is -1 when calling from x_set_frame_parameters,
9794 which means, do adjust for borders but don't change the gravity. */
9797 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9799 register int xoff
, yoff
;
9802 int modified_top
, modified_left
;
9804 if (change_gravity
> 0)
9806 f
->output_data
.mac
->top_pos
= yoff
;
9807 f
->output_data
.mac
->left_pos
= xoff
;
9808 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9810 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9812 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9813 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9815 x_calc_absolute_position (f
);
9818 x_wm_set_size_hint (f
, (long) 0, 0);
9820 modified_left
= f
->output_data
.mac
->left_pos
;
9821 modified_top
= f
->output_data
.mac
->top_pos
;
9823 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9824 modified_top
+ 42, false);
9829 /* Call this to change the size of frame F's x-window.
9830 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9831 for this size change and subsequent size changes.
9832 Otherwise we leave the window gravity unchanged. */
9835 x_set_window_size (f
, change_gravity
, cols
, rows
)
9840 int pixelwidth
, pixelheight
;
9844 check_frame_size (f
, &rows
, &cols
);
9845 f
->output_data
.mac
->vertical_scroll_bar_extra
9846 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9848 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9850 x_compute_fringe_widths (f
, 0);
9852 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9853 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9855 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9856 x_wm_set_size_hint (f
, (long) 0, 0);
9858 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9860 /* Now, strictly speaking, we can't be sure that this is accurate,
9861 but the window manager will get around to dealing with the size
9862 change request eventually, and we'll hear how it went when the
9863 ConfigureNotify event gets here.
9865 We could just not bother storing any of this information here,
9866 and let the ConfigureNotify event set everything up, but that
9867 might be kind of confusing to the Lisp code, since size changes
9868 wouldn't be reported in the frame parameters until some random
9869 point in the future when the ConfigureNotify event arrives.
9871 We pass 1 for DELAY since we can't run Lisp code inside of
9873 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9874 PIXEL_WIDTH (f
) = pixelwidth
;
9875 PIXEL_HEIGHT (f
) = pixelheight
;
9877 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9878 receive in the ConfigureNotify event; if we get what we asked
9879 for, then the event won't cause the screen to become garbaged, so
9880 we have to make sure to do it here. */
9881 SET_FRAME_GARBAGED (f
);
9883 XFlush (FRAME_X_DISPLAY (f
));
9885 /* If cursor was outside the new size, mark it as off. */
9886 mark_window_cursors_off (XWINDOW (f
->root_window
));
9888 /* Clear out any recollection of where the mouse highlighting was,
9889 since it might be in a place that's outside the new frame size.
9890 Actually checking whether it is outside is a pain in the neck,
9891 so don't try--just let the highlighting be done afresh with new size. */
9892 cancel_mouse_face (f
);
9897 /* Mouse warping. */
9899 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9902 x_set_mouse_position (f
, x
, y
)
9908 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9909 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9911 if (pix_x
< 0) pix_x
= 0;
9912 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9914 if (pix_y
< 0) pix_y
= 0;
9915 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9917 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9921 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9925 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9928 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9929 0, 0, 0, 0, pix_x
, pix_y
);
9935 /* focus shifting, raising and lowering. */
9938 x_focus_on_frame (f
)
9941 #if 0 /* This proves to be unpleasant. */
9945 /* I don't think that the ICCCM allows programs to do things like this
9946 without the interaction of the window manager. Whatever you end up
9947 doing with this code, do it to x_unfocus_frame too. */
9948 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9949 RevertToPointerRoot
, CurrentTime
);
9959 /* Raise frame F. */
9964 if (f
->async_visible
)
9965 SelectWindow (FRAME_MAC_WINDOW (f
));
9968 /* Lower frame F. */
9973 if (f
->async_visible
)
9974 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9978 XTframe_raise_lower (f
, raise_flag
)
9988 /* Change of visibility. */
9990 /* This tries to wait until the frame is really visible.
9991 However, if the window manager asks the user where to position
9992 the frame, this will return before the user finishes doing that.
9993 The frame will not actually be visible at that time,
9994 but it will become visible later when the window manager
9995 finishes with it. */
9998 x_make_frame_visible (f
)
10002 int original_top
, original_left
;
10006 if (! FRAME_VISIBLE_P (f
))
10008 /* We test FRAME_GARBAGED_P here to make sure we don't
10009 call x_set_offset a second time
10010 if we get to x_make_frame_visible a second time
10011 before the window gets really visible. */
10012 if (! FRAME_ICONIFIED_P (f
)
10013 && ! f
->output_data
.mac
->asked_for_visible
)
10014 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
10015 f
->output_data
.mac
->top_pos
, 0);
10017 f
->output_data
.mac
->asked_for_visible
= 1;
10019 ShowWindow (FRAME_MAC_WINDOW (f
));
10022 XFlush (FRAME_MAC_DISPLAY (f
));
10024 #if 0 /* MAC_TODO */
10025 /* Synchronize to ensure Emacs knows the frame is visible
10026 before we do anything else. We do this loop with input not blocked
10027 so that incoming events are handled. */
10032 /* This must come after we set COUNT. */
10035 XSETFRAME (frame
, f
);
10037 /* Wait until the frame is visible. Process X events until a
10038 MapNotify event has been seen, or until we think we won't get a
10039 MapNotify at all.. */
10040 for (count
= input_signal_count
+ 10;
10041 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10043 /* Force processing of queued events. */
10046 /* Machines that do polling rather than SIGIO have been
10047 observed to go into a busy-wait here. So we'll fake an
10048 alarm signal to let the handler know that there's something
10049 to be read. We used to raise a real alarm, but it seems
10050 that the handler isn't always enabled here. This is
10052 if (input_polling_used ())
10054 /* It could be confusing if a real alarm arrives while
10055 processing the fake one. Turn it off and let the
10056 handler reset it. */
10057 extern void poll_for_input_1
P_ ((void));
10058 int old_poll_suppress_count
= poll_suppress_count
;
10059 poll_suppress_count
= 1;
10060 poll_for_input_1 ();
10061 poll_suppress_count
= old_poll_suppress_count
;
10064 /* See if a MapNotify event has been processed. */
10065 FRAME_SAMPLE_VISIBILITY (f
);
10068 #endif /* MAC_TODO */
10071 /* Change from mapped state to withdrawn state. */
10073 /* Make the frame visible (mapped and not iconified). */
10076 x_make_frame_invisible (f
)
10079 /* Don't keep the highlight on an invisible frame. */
10080 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10081 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10085 HideWindow (FRAME_MAC_WINDOW (f
));
10087 /* We can't distinguish this from iconification
10088 just by the event that we get from the server.
10089 So we can't win using the usual strategy of letting
10090 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10091 and synchronize with the server to make sure we agree. */
10093 FRAME_ICONIFIED_P (f
) = 0;
10094 f
->async_visible
= 0;
10095 f
->async_iconified
= 0;
10100 /* Change window state from mapped to iconified. */
10103 x_iconify_frame (f
)
10106 /* Don't keep the highlight on an invisible frame. */
10107 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10108 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10111 /* Review: Since window is still visible in dock, still allow updates? */
10112 if (f
->async_iconified
)
10118 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
10124 /* Destroy the X window of frame F. */
10127 x_destroy_window (f
)
10130 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10134 DisposeWindow (FRAME_MAC_WINDOW (f
));
10136 free_frame_menubar (f
);
10137 free_frame_faces (f
);
10139 xfree (f
->output_data
.mac
);
10140 f
->output_data
.mac
= 0;
10141 if (f
== dpyinfo
->x_focus_frame
)
10142 dpyinfo
->x_focus_frame
= 0;
10143 if (f
== dpyinfo
->x_focus_event_frame
)
10144 dpyinfo
->x_focus_event_frame
= 0;
10145 if (f
== dpyinfo
->x_highlight_frame
)
10146 dpyinfo
->x_highlight_frame
= 0;
10148 dpyinfo
->reference_count
--;
10150 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10152 dpyinfo
->mouse_face_beg_row
10153 = dpyinfo
->mouse_face_beg_col
= -1;
10154 dpyinfo
->mouse_face_end_row
10155 = dpyinfo
->mouse_face_end_col
= -1;
10156 dpyinfo
->mouse_face_window
= Qnil
;
10157 dpyinfo
->mouse_face_deferred_gc
= 0;
10158 dpyinfo
->mouse_face_mouse_frame
= 0;
10164 /* Setting window manager hints. */
10166 /* Set the normal size hints for the window manager, for frame F.
10167 FLAGS is the flags word to use--or 0 meaning preserve the flags
10168 that the window now has.
10169 If USER_POSITION is nonzero, we set the USPosition
10170 flag (this is useful when FLAGS is 0). */
10172 x_wm_set_size_hint (f
, flags
, user_position
)
10177 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10178 XSizeHints size_hints
;
10180 #ifdef USE_X_TOOLKIT
10183 Dimension widget_width
, widget_height
;
10184 Window window
= XtWindow (f
->output_data
.x
->widget
);
10185 #else /* not USE_X_TOOLKIT */
10186 Window window
= FRAME_X_WINDOW (f
);
10187 #endif /* not USE_X_TOOLKIT */
10189 /* Setting PMaxSize caused various problems. */
10190 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10192 size_hints
.x
= f
->output_data
.x
->left_pos
;
10193 size_hints
.y
= f
->output_data
.x
->top_pos
;
10195 #ifdef USE_X_TOOLKIT
10196 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10197 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10198 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10199 size_hints
.height
= widget_height
;
10200 size_hints
.width
= widget_width
;
10201 #else /* not USE_X_TOOLKIT */
10202 size_hints
.height
= PIXEL_HEIGHT (f
);
10203 size_hints
.width
= PIXEL_WIDTH (f
);
10204 #endif /* not USE_X_TOOLKIT */
10206 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10207 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10208 size_hints
.max_width
10209 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10210 size_hints
.max_height
10211 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10213 /* Calculate the base and minimum sizes.
10215 (When we use the X toolkit, we don't do it here.
10216 Instead we copy the values that the widgets are using, below.) */
10217 #ifndef USE_X_TOOLKIT
10219 int base_width
, base_height
;
10220 int min_rows
= 0, min_cols
= 0;
10222 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10223 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10225 check_frame_size (f
, &min_rows
, &min_cols
);
10227 /* The window manager uses the base width hints to calculate the
10228 current number of rows and columns in the frame while
10229 resizing; min_width and min_height aren't useful for this
10230 purpose, since they might not give the dimensions for a
10231 zero-row, zero-column frame.
10233 We use the base_width and base_height members if we have
10234 them; otherwise, we set the min_width and min_height members
10235 to the size for a zero x zero frame. */
10238 size_hints
.flags
|= PBaseSize
;
10239 size_hints
.base_width
= base_width
;
10240 size_hints
.base_height
= base_height
;
10241 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10242 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10244 size_hints
.min_width
= base_width
;
10245 size_hints
.min_height
= base_height
;
10249 /* If we don't need the old flags, we don't need the old hint at all. */
10252 size_hints
.flags
|= flags
;
10255 #endif /* not USE_X_TOOLKIT */
10258 XSizeHints hints
; /* Sometimes I hate X Windows... */
10259 long supplied_return
;
10263 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10266 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10269 #ifdef USE_X_TOOLKIT
10270 size_hints
.base_height
= hints
.base_height
;
10271 size_hints
.base_width
= hints
.base_width
;
10272 size_hints
.min_height
= hints
.min_height
;
10273 size_hints
.min_width
= hints
.min_width
;
10277 size_hints
.flags
|= flags
;
10282 if (hints
.flags
& PSize
)
10283 size_hints
.flags
|= PSize
;
10284 if (hints
.flags
& PPosition
)
10285 size_hints
.flags
|= PPosition
;
10286 if (hints
.flags
& USPosition
)
10287 size_hints
.flags
|= USPosition
;
10288 if (hints
.flags
& USSize
)
10289 size_hints
.flags
|= USSize
;
10293 #ifndef USE_X_TOOLKIT
10298 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10299 size_hints
.flags
|= PWinGravity
;
10303 size_hints
.flags
&= ~ PPosition
;
10304 size_hints
.flags
|= USPosition
;
10306 #endif /* PWinGravity */
10309 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10311 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10313 #endif /* MAC_TODO */
10316 #if 0 /* MAC_TODO: hide application instead of iconify? */
10317 /* Used for IconicState or NormalState */
10320 x_wm_set_window_state (f
, state
)
10324 #ifdef USE_X_TOOLKIT
10327 XtSetArg (al
[0], XtNinitialState
, state
);
10328 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10329 #else /* not USE_X_TOOLKIT */
10330 Window window
= FRAME_X_WINDOW (f
);
10332 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10333 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10335 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10336 #endif /* not USE_X_TOOLKIT */
10340 x_wm_set_icon_pixmap (f
, pixmap_id
)
10344 Pixmap icon_pixmap
;
10346 #ifndef USE_X_TOOLKIT
10347 Window window
= FRAME_X_WINDOW (f
);
10352 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10353 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10357 /* It seems there is no way to turn off use of an icon pixmap.
10358 The following line does it, only if no icon has yet been created,
10359 for some window managers. But with mwm it crashes.
10360 Some people say it should clear the IconPixmapHint bit in this case,
10361 but that doesn't work, and the X consortium said it isn't the
10362 right thing at all. Since there is no way to win,
10363 best to explicitly give up. */
10365 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10371 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10375 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10376 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10379 #else /* not USE_X_TOOLKIT */
10381 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10382 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10384 #endif /* not USE_X_TOOLKIT */
10387 #endif /* MAC_TODO */
10390 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10392 int icon_x
, icon_y
;
10394 #if 0 /* MAC_TODO: no icons on Mac */
10395 #ifdef USE_X_TOOLKIT
10396 Window window
= XtWindow (f
->output_data
.x
->widget
);
10398 Window window
= FRAME_X_WINDOW (f
);
10401 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10402 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10403 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10405 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10406 #endif /* MAC_TODO */
10410 /***********************************************************************
10412 ***********************************************************************/
10414 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10417 x_get_font_info (f
, font_idx
)
10421 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10424 /* the global font name table */
10425 char **font_name_table
= NULL
;
10426 int font_name_table_size
= 0;
10427 int font_name_count
= 0;
10429 /* compare two strings ignoring case */
10431 stricmp (const char *s
, const char *t
)
10433 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10436 return tolower (*s
) - tolower (*t
);
10439 /* compare two strings ignoring case and handling wildcard */
10441 wildstrieq (char *s1
, char *s2
)
10443 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10446 return stricmp (s1
, s2
) == 0;
10449 /* Assume parameter 1 is fully qualified, no wildcards. */
10451 mac_font_pattern_match (fontname
, pattern
)
10455 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10456 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10459 /* Copy fontname so we can modify it during comparison. */
10460 strcpy (font_name_copy
, fontname
);
10465 /* Turn pattern into a regexp and do a regexp match. */
10466 for (; *pattern
; pattern
++)
10468 if (*pattern
== '?')
10470 else if (*pattern
== '*')
10481 return (fast_c_string_match_ignore_case (build_string (regex
),
10482 font_name_copy
) >= 0);
10485 /* Two font specs are considered to match if their foundry, family,
10486 weight, slant, and charset match. */
10488 mac_font_match (char *mf
, char *xf
)
10490 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10491 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10493 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10494 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10495 return mac_font_pattern_match (mf
, xf
);
10497 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10498 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10499 return mac_font_pattern_match (mf
, xf
);
10501 return (wildstrieq (m_foundry
, x_foundry
)
10502 && wildstrieq (m_family
, x_family
)
10503 && wildstrieq (m_weight
, x_weight
)
10504 && wildstrieq (m_slant
, x_slant
)
10505 && wildstrieq (m_charset
, x_charset
))
10506 || mac_font_pattern_match (mf
, xf
);
10511 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10513 char foundry
[32], family
[32], cs
[32];
10514 char xf
[255], *result
, *p
;
10516 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10518 strcpy(foundry
, "Apple");
10519 strcpy(family
, name
);
10521 switch (scriptcode
)
10523 case smTradChinese
:
10524 strcpy(cs
, "big5-0");
10526 case smSimpChinese
:
10527 strcpy(cs
, "gb2312.1980-0");
10530 strcpy(cs
, "jisx0208.1983-sjis");
10533 /* Each Apple Japanese font is entered into the font table
10534 twice: once as a jisx0208.1983-sjis font and once as a
10535 jisx0201.1976-0 font. The latter can be used to display
10536 the ascii charset and katakana-jisx0201 charset. A
10537 negative script code signals that the name of this latter
10538 font is being built. */
10539 strcpy(cs
, "jisx0201.1976-0");
10542 strcpy(cs
, "ksc5601.1989-0");
10545 strcpy(cs
, "mac-roman");
10550 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10551 foundry
, family
, style
& bold
? "bold" : "medium",
10552 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10554 result
= (char *) xmalloc (strlen (xf
) + 1);
10555 strcpy (result
, xf
);
10556 for (p
= result
; *p
; p
++)
10562 /* Convert an X font spec to the corresponding mac font name, which
10563 can then be passed to GetFNum after conversion to a Pascal string.
10564 For ordinary Mac fonts, this should just be their names, like
10565 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10566 collection contain their charset designation in their names, like
10567 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10568 names are handled accordingly. */
10570 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10572 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10576 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10577 foundry
, family
, weight
, slant
, cs
) != 5 &&
10578 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10579 foundry
, family
, weight
, slant
, cs
) != 5)
10582 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10583 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10584 || strcmp (cs
, "jisx0201.1976-0") == 0
10585 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10586 strcpy(mf
, family
);
10588 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10593 add_font_name_table_entry (char *font_name
)
10595 if (font_name_table_size
== 0)
10597 font_name_table_size
= 16;
10598 font_name_table
= (char **)
10599 xmalloc (font_name_table_size
* sizeof (char *));
10601 else if (font_name_count
+ 1 >= font_name_table_size
)
10603 font_name_table_size
+= 16;
10604 font_name_table
= (char **)
10605 xrealloc (font_name_table
,
10606 font_name_table_size
* sizeof (char *));
10609 font_name_table
[font_name_count
++] = font_name
;
10612 /* Sets up the table font_name_table to contain the list of all fonts
10613 in the system the first time the table is used so that the Resource
10614 Manager need not be accessed every time this information is
10618 init_font_name_table ()
10620 #if TARGET_API_MAC_CARBON
10623 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10625 FMFontFamilyIterator ffi
;
10626 FMFontFamilyInstanceIterator ffii
;
10629 /* Create a dummy instance iterator here to avoid creating and
10630 destroying it in the loop. */
10631 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10633 /* Create an iterator to enumerate the font families. */
10634 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10637 FMDisposeFontFamilyInstanceIterator (&ffii
);
10641 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10649 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10653 sc
= FontToScript (ff
);
10655 /* Point the instance iterator at the current font family. */
10656 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10659 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
10663 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10665 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10667 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10669 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10675 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10677 if (smJapanese
== sc
)
10678 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10684 /* Dispose of the iterators. */
10685 FMDisposeFontFamilyIterator (&ffi
);
10686 FMDisposeFontFamilyInstanceIterator (&ffii
);
10690 #endif /* TARGET_API_MAC_CARBON */
10692 SInt16 fontnum
, old_fontnum
;
10693 int num_mac_fonts
= CountResources('FOND');
10695 Handle font_handle
, font_handle_2
;
10696 short id
, scriptcode
;
10699 struct FontAssoc
*fat
;
10700 struct AsscEntry
*assc_entry
;
10702 GetPort (&port
); /* save the current font number used */
10703 #if TARGET_API_MAC_CARBON
10704 old_fontnum
= GetPortTextFont (port
);
10706 old_fontnum
= port
->txFont
;
10709 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10711 font_handle
= GetIndResource ('FOND', i
);
10715 GetResInfo (font_handle
, &id
, &type
, name
);
10716 GetFNum (name
, &fontnum
);
10721 TextFont (fontnum
);
10722 scriptcode
= FontToScript (fontnum
);
10725 HLock (font_handle
);
10727 if (GetResourceSizeOnDisk (font_handle
)
10728 >= sizeof (struct FamRec
))
10730 fat
= (struct FontAssoc
*) (*font_handle
10731 + sizeof (struct FamRec
));
10733 = (struct AsscEntry
*) (*font_handle
10734 + sizeof (struct FamRec
)
10735 + sizeof (struct FontAssoc
));
10737 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10739 if (font_name_table_size
== 0)
10741 font_name_table_size
= 16;
10742 font_name_table
= (char **)
10743 xmalloc (font_name_table_size
* sizeof (char *));
10745 else if (font_name_count
>= font_name_table_size
)
10747 font_name_table_size
+= 16;
10748 font_name_table
= (char **)
10749 xrealloc (font_name_table
,
10750 font_name_table_size
* sizeof (char *));
10752 font_name_table
[font_name_count
++]
10753 = mac_to_x_fontname (name
,
10754 assc_entry
->fontSize
,
10755 assc_entry
->fontStyle
,
10757 /* Both jisx0208.1983-sjis and
10758 jisx0201.1976-sjis parts are contained in
10759 Apple Japanese (SJIS) font. */
10760 if (smJapanese
== scriptcode
)
10762 font_name_table
[font_name_count
++]
10763 = mac_to_x_fontname (name
,
10764 assc_entry
->fontSize
,
10765 assc_entry
->fontStyle
,
10771 HUnlock (font_handle
);
10772 font_handle_2
= GetNextFOND (font_handle
);
10773 ReleaseResource (font_handle
);
10774 font_handle
= font_handle_2
;
10776 while (ResError () == noErr
&& font_handle
);
10779 TextFont (old_fontnum
);
10780 #if TARGET_API_MAC_CARBON
10782 #endif /* TARGET_API_MAC_CARBON */
10786 /* Return a list of at most MAXNAMES font specs matching the one in
10787 PATTERN. Cache matching fonts for patterns in
10788 dpyinfo->name_list_element to avoid looking them up again by
10789 calling mac_font_pattern_match (slow). */
10792 x_list_fonts (struct frame
*f
,
10793 Lisp_Object pattern
,
10798 Lisp_Object newlist
= Qnil
, tem
, key
;
10801 struct gcpro gcpro1
, gcpro2
;
10802 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
10804 if (font_name_table
== NULL
) /* Initialize when first used. */
10805 init_font_name_table ();
10809 tem
= XCDR (dpyinfo
->name_list_element
);
10810 key
= Fcons (pattern
, make_number (maxnames
));
10812 newlist
= Fassoc (key
, tem
);
10813 if (!NILP (newlist
))
10815 newlist
= Fcdr_safe (newlist
);
10820 ptnstr
= SDATA (pattern
);
10822 GCPRO2 (pattern
, newlist
);
10824 /* Scan and matching bitmap fonts. */
10825 for (i
= 0; i
< font_name_count
; i
++)
10827 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10829 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10832 if (n_fonts
>= maxnames
)
10837 /* MAC_TODO: add code for matching outline fonts here */
10843 XSETCDR (dpyinfo
->name_list_element
,
10844 Fcons (Fcons (key
, newlist
),
10845 XCDR (dpyinfo
->name_list_element
)));
10855 /* Check that FONT is valid on frame F. It is if it can be found in F's
10859 x_check_font (f
, font
)
10864 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10866 xassert (font
!= NULL
);
10868 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10869 if (dpyinfo
->font_table
[i
].name
10870 && font
== dpyinfo
->font_table
[i
].font
)
10873 xassert (i
< dpyinfo
->n_fonts
);
10876 #endif /* GLYPH_DEBUG != 0 */
10878 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10879 Note: There are (broken) X fonts out there with invalid XFontStruct
10880 min_bounds contents. For example, handa@etl.go.jp reports that
10881 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10882 have font->min_bounds.width == 0. */
10885 x_font_min_bounds (font
, w
, h
)
10886 MacFontStruct
*font
;
10890 * TODO: Windows does not appear to offer min bound, only
10891 * average and maximum width, and maximum height.
10893 *h
= FONT_HEIGHT (font
);
10894 *w
= FONT_WIDTH (font
);
10898 /* Compute the smallest character width and smallest font height over
10899 all fonts available on frame F. Set the members smallest_char_width
10900 and smallest_font_height in F's x_display_info structure to
10901 the values computed. Value is non-zero if smallest_font_height or
10902 smallest_char_width become smaller than they were before. */
10905 x_compute_min_glyph_bounds (f
)
10909 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10910 MacFontStruct
*font
;
10911 int old_width
= dpyinfo
->smallest_char_width
;
10912 int old_height
= dpyinfo
->smallest_font_height
;
10914 dpyinfo
->smallest_font_height
= 100000;
10915 dpyinfo
->smallest_char_width
= 100000;
10917 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10918 if (dpyinfo
->font_table
[i
].name
)
10920 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10923 font
= (MacFontStruct
*) fontp
->font
;
10924 xassert (font
!= (MacFontStruct
*) ~0);
10925 x_font_min_bounds (font
, &w
, &h
);
10927 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10928 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10931 xassert (dpyinfo
->smallest_char_width
> 0
10932 && dpyinfo
->smallest_font_height
> 0);
10934 return (dpyinfo
->n_fonts
== 1
10935 || dpyinfo
->smallest_char_width
< old_width
10936 || dpyinfo
->smallest_font_height
< old_height
);
10940 /* Determine whether given string is a fully-specified XLFD: all 14
10941 fields are present, none is '*'. */
10944 is_fully_specified_xlfd (char *p
)
10952 for (i
= 0; i
< 13; i
++)
10954 q
= strchr (p
+ 1, '-');
10957 if (q
- p
== 2 && *(p
+ 1) == '*')
10962 if (strchr (p
+ 1, '-') != NULL
)
10965 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10972 const int kDefaultFontSize
= 9;
10975 /* XLoadQueryFont creates and returns an internal representation for a
10976 font in a MacFontStruct struct. There is really no concept
10977 corresponding to "loading" a font on the Mac. But we check its
10978 existence and find the font number and all other information for it
10979 and store them in the returned MacFontStruct. */
10981 static MacFontStruct
*
10982 XLoadQueryFont (Display
*dpy
, char *fontname
)
10984 int i
, size
, is_two_byte_font
, char_width
;
10987 SInt16 old_fontnum
, old_fontsize
;
10988 Style old_fontface
;
10991 Style fontface
= normal
;
10992 MacFontStruct
*font
;
10993 FontInfo the_fontinfo
;
10994 char s_weight
[7], c_slant
;
10996 if (is_fully_specified_xlfd (fontname
))
11000 for (i
= 0; i
< font_name_count
; i
++)
11001 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
11004 if (i
>= font_name_count
)
11007 name
= font_name_table
[i
];
11010 GetPort (&port
); /* save the current font number used */
11011 #if TARGET_API_MAC_CARBON
11012 old_fontnum
= GetPortTextFont (port
);
11013 old_fontsize
= GetPortTextSize (port
);
11014 old_fontface
= GetPortTextFace (port
);
11016 old_fontnum
= port
->txFont
;
11017 old_fontsize
= port
->txSize
;
11018 old_fontface
= port
->txFace
;
11021 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
11022 size
= kDefaultFontSize
;
11024 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
11025 if (strcmp (s_weight
, "bold") == 0)
11028 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
11029 if (c_slant
== 'i')
11030 fontface
|= italic
;
11032 x_font_name_to_mac_font_name (name
, mfontname
);
11033 c2pstr (mfontname
);
11034 GetFNum (mfontname
, &fontnum
);
11038 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
11040 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
11041 bcopy (name
, font
->fontname
, strlen (name
) + 1);
11043 font
->mac_fontnum
= fontnum
;
11044 font
->mac_fontsize
= size
;
11045 font
->mac_fontface
= fontface
;
11046 font
->mac_scriptcode
= FontToScript (fontnum
);
11048 /* Apple Japanese (SJIS) font is listed as both
11049 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
11050 (Roman script) in init_font_name_table (). The latter should be
11051 treated as a one-byte font. */
11056 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
11058 && 0 == strcmp (cs
, "jisx0201.1976-0"))
11059 font
->mac_scriptcode
= smRoman
;
11062 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
11063 font
->mac_scriptcode
== smTradChinese
||
11064 font
->mac_scriptcode
== smSimpChinese
||
11065 font
->mac_scriptcode
== smKorean
;
11067 TextFont (fontnum
);
11069 TextFace (fontface
);
11071 GetFontInfo (&the_fontinfo
);
11073 font
->ascent
= the_fontinfo
.ascent
;
11074 font
->descent
= the_fontinfo
.descent
;
11076 font
->min_byte1
= 0;
11077 if (is_two_byte_font
)
11078 font
->max_byte1
= 1;
11080 font
->max_byte1
= 0;
11081 font
->min_char_or_byte2
= 0x20;
11082 font
->max_char_or_byte2
= 0xff;
11084 if (is_two_byte_font
)
11086 /* Use the width of an "ideographic space" of that font because
11087 the_fontinfo.widMax returns the wrong width for some fonts. */
11088 switch (font
->mac_scriptcode
)
11091 char_width
= StringWidth("\p\x81\x40");
11093 case smTradChinese
:
11094 char_width
= StringWidth("\p\xa1\x40");
11096 case smSimpChinese
:
11097 char_width
= StringWidth("\p\xa1\xa1");
11100 char_width
= StringWidth("\p\xa1\xa1");
11105 /* Do this instead of use the_fontinfo.widMax, which incorrectly
11106 returns 15 for 12-point Monaco! */
11107 char_width
= CharWidth ('m');
11109 font
->max_bounds
.rbearing
= char_width
;
11110 font
->max_bounds
.lbearing
= 0;
11111 font
->max_bounds
.width
= char_width
;
11112 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
11113 font
->max_bounds
.descent
= the_fontinfo
.descent
;
11115 font
->min_bounds
= font
->max_bounds
;
11117 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
11118 font
->per_char
= NULL
;
11121 font
->per_char
= (XCharStruct
*)
11122 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
11126 for (c
= 0x20; c
<= 0xff; c
++)
11128 font
->per_char
[c
- 0x20] = font
->max_bounds
;
11129 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
11134 TextFont (old_fontnum
); /* restore previous font number, size and face */
11135 TextSize (old_fontsize
);
11136 TextFace (old_fontface
);
11142 /* Load font named FONTNAME of the size SIZE for frame F, and return a
11143 pointer to the structure font_info while allocating it dynamically.
11144 If SIZE is 0, load any size of font.
11145 If loading is failed, return NULL. */
11148 x_load_font (f
, fontname
, size
)
11150 register char *fontname
;
11153 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11154 Lisp_Object font_names
;
11156 /* Get a list of all the fonts that match this name. Once we
11157 have a list of matching fonts, we compare them against the fonts
11158 we already have by comparing names. */
11159 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
11161 if (!NILP (font_names
))
11166 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11167 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
11168 if (dpyinfo
->font_table
[i
].name
11169 && (!strcmp (dpyinfo
->font_table
[i
].name
,
11170 SDATA (XCAR (tail
)))
11171 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
11172 SDATA (XCAR (tail
)))))
11173 return (dpyinfo
->font_table
+ i
);
11176 /* Load the font and add it to the table. */
11179 struct MacFontStruct
*font
;
11180 struct font_info
*fontp
;
11181 unsigned long value
;
11184 /* If we have found fonts by x_list_font, load one of them. If
11185 not, we still try to load a font by the name given as FONTNAME
11186 because XListFonts (called in x_list_font) of some X server has
11187 a bug of not finding a font even if the font surely exists and
11188 is loadable by XLoadQueryFont. */
11189 if (size
> 0 && !NILP (font_names
))
11190 fontname
= (char *) SDATA (XCAR (font_names
));
11192 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
11196 /* Find a free slot in the font table. */
11197 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11198 if (dpyinfo
->font_table
[i
].name
== NULL
)
11201 /* If no free slot found, maybe enlarge the font table. */
11202 if (i
== dpyinfo
->n_fonts
11203 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
11206 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
11207 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
11208 dpyinfo
->font_table
11209 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
11212 fontp
= dpyinfo
->font_table
+ i
;
11213 if (i
== dpyinfo
->n_fonts
)
11214 ++dpyinfo
->n_fonts
;
11216 /* Now fill in the slots of *FONTP. */
11218 fontp
->font
= font
;
11219 fontp
->font_idx
= i
;
11220 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
11221 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
11223 fontp
->full_name
= fontp
->name
;
11225 fontp
->size
= font
->max_bounds
.width
;
11226 fontp
->height
= FONT_HEIGHT (font
);
11228 /* For some font, ascent and descent in max_bounds field is
11229 larger than the above value. */
11230 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
11231 if (max_height
> fontp
->height
)
11232 fontp
->height
= max_height
;
11235 /* The slot `encoding' specifies how to map a character
11236 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
11237 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
11238 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
11239 2:0xA020..0xFF7F). For the moment, we don't know which charset
11240 uses this font. So, we set information in fontp->encoding[1]
11241 which is never used by any charset. If mapping can't be
11242 decided, set FONT_ENCODING_NOT_DECIDED. */
11243 if (font
->mac_scriptcode
== smJapanese
)
11244 fontp
->encoding
[1] = 4;
11248 = (font
->max_byte1
== 0
11250 ? (font
->min_char_or_byte2
< 0x80
11251 ? (font
->max_char_or_byte2
< 0x80
11252 ? 0 /* 0x20..0x7F */
11253 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
11254 : 1) /* 0xA0..0xFF */
11256 : (font
->min_byte1
< 0x80
11257 ? (font
->max_byte1
< 0x80
11258 ? (font
->min_char_or_byte2
< 0x80
11259 ? (font
->max_char_or_byte2
< 0x80
11260 ? 0 /* 0x2020..0x7F7F */
11261 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
11262 : 3) /* 0x20A0..0x7FFF */
11263 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
11264 : (font
->min_char_or_byte2
< 0x80
11265 ? (font
->max_char_or_byte2
< 0x80
11266 ? 2 /* 0xA020..0xFF7F */
11267 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
11268 : 1))); /* 0xA0A0..0xFFFF */
11271 #if 0 /* MAC_TODO: fill these out with more reasonably values */
11272 fontp
->baseline_offset
11273 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
11274 ? (long) value
: 0);
11275 fontp
->relative_compose
11276 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
11277 ? (long) value
: 0);
11278 fontp
->default_ascent
11279 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
11280 ? (long) value
: 0);
11282 fontp
->baseline_offset
= 0;
11283 fontp
->relative_compose
= 0;
11284 fontp
->default_ascent
= 0;
11287 /* Set global flag fonts_changed_p to non-zero if the font loaded
11288 has a character with a smaller width than any other character
11289 before, or if the font loaded has a smalle>r height than any
11290 other font loaded before. If this happens, it will make a
11291 glyph matrix reallocation necessary. */
11292 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11299 /* Return a pointer to struct font_info of a font named FONTNAME for
11300 frame F. If no such font is loaded, return NULL. */
11303 x_query_font (f
, fontname
)
11305 register char *fontname
;
11307 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11310 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11311 if (dpyinfo
->font_table
[i
].name
11312 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11313 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11314 return (dpyinfo
->font_table
+ i
);
11319 /* Find a CCL program for a font specified by FONTP, and set the member
11320 `encoder' of the structure. */
11323 x_find_ccl_program (fontp
)
11324 struct font_info
*fontp
;
11326 Lisp_Object list
, elt
;
11328 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11332 && STRINGP (XCAR (elt
))
11333 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11339 struct ccl_program
*ccl
11340 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11342 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11345 fontp
->font_encoder
= ccl
;
11351 /***********************************************************************
11353 ***********************************************************************/
11355 #ifdef USE_X_TOOLKIT
11356 static XrmOptionDescRec emacs_options
[] = {
11357 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11358 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11360 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11361 XrmoptionSepArg
, NULL
},
11362 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11364 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11365 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11366 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11367 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11368 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11369 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11370 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11372 #endif /* USE_X_TOOLKIT */
11374 static int x_initialized
;
11376 #ifdef MULTI_KBOARD
11377 /* Test whether two display-name strings agree up to the dot that separates
11378 the screen number from the server number. */
11380 same_x_server (name1
, name2
)
11381 char *name1
, *name2
;
11383 int seen_colon
= 0;
11384 unsigned char *system_name
= SDATA (Vsystem_name
);
11385 int system_name_length
= strlen (system_name
);
11386 int length_until_period
= 0;
11388 while (system_name
[length_until_period
] != 0
11389 && system_name
[length_until_period
] != '.')
11390 length_until_period
++;
11392 /* Treat `unix' like an empty host name. */
11393 if (! strncmp (name1
, "unix:", 5))
11395 if (! strncmp (name2
, "unix:", 5))
11397 /* Treat this host's name like an empty host name. */
11398 if (! strncmp (name1
, system_name
, system_name_length
)
11399 && name1
[system_name_length
] == ':')
11400 name1
+= system_name_length
;
11401 if (! strncmp (name2
, system_name
, system_name_length
)
11402 && name2
[system_name_length
] == ':')
11403 name2
+= system_name_length
;
11404 /* Treat this host's domainless name like an empty host name. */
11405 if (! strncmp (name1
, system_name
, length_until_period
)
11406 && name1
[length_until_period
] == ':')
11407 name1
+= length_until_period
;
11408 if (! strncmp (name2
, system_name
, length_until_period
)
11409 && name2
[length_until_period
] == ':')
11410 name2
+= length_until_period
;
11412 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11416 if (seen_colon
&& *name1
== '.')
11420 && (*name1
== '.' || *name1
== '\0')
11421 && (*name2
== '.' || *name2
== '\0'));
11426 /* The Mac Event loop code */
11429 #include <Events.h>
11430 #include <Quickdraw.h>
11431 #include <Balloons.h>
11432 #include <Devices.h>
11434 #include <Gestalt.h>
11436 #include <Processes.h>
11438 #include <ToolUtils.h>
11439 #include <TextUtils.h>
11440 #include <Dialogs.h>
11441 #include <Script.h>
11443 #include <TextEncodingConverter.h>
11444 #include <Resources.h>
11449 #endif /* ! MAC_OSX */
11451 #define M_APPLE 128
11454 #define WINDOW_RESOURCE 128
11455 #define TERM_WINDOW_RESOURCE 129
11457 #define DEFAULT_NUM_COLS 80
11459 #define MIN_DOC_SIZE 64
11460 #define MAX_DOC_SIZE 32767
11462 /* sleep time for WaitNextEvent */
11463 #define WNE_SLEEP_AT_SUSPEND 10
11464 #define WNE_SLEEP_AT_RESUME 1
11466 /* true when cannot handle any Mac OS events */
11467 static int handling_window_update
= 0;
11469 /* the flag appl_is_suspended is used both for determining the sleep
11470 time to be passed to WaitNextEvent and whether the cursor should be
11471 drawn when updating the display. The cursor is turned off when
11472 Emacs is suspended. Redrawing it is unnecessary and what needs to
11473 be done depends on whether the cursor lies inside or outside the
11474 redraw region. So we might as well skip drawing it when Emacs is
11476 static Boolean app_is_suspended
= false;
11477 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11479 #define EXTRA_STACK_ALLOC (256 * 1024)
11481 #define ARGV_STRING_LIST_ID 129
11482 #define ABOUT_ALERT_ID 128
11483 #define RAM_TOO_LARGE_ALERT_ID 129
11485 Boolean terminate_flag
= false;
11487 /* True if using command key as meta key. */
11488 Lisp_Object Vmac_command_key_is_meta
;
11490 /* True if the ctrl and meta keys should be reversed. */
11491 Lisp_Object Vmac_reverse_ctrl_meta
;
11493 #if USE_CARBON_EVENTS
11494 /* True if the mouse wheel button (i.e. button 4) should map to
11495 mouse-2, instead of mouse-3. */
11496 Lisp_Object Vmac_wheel_button_is_mouse_2
;
11498 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
11499 for processing before Emacs sees it. */
11500 Lisp_Object Vmac_pass_command_to_system
;
11502 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
11503 for processing before Emacs sees it. */
11504 Lisp_Object Vmac_pass_control_to_system
;
11507 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11508 to this text encoding */
11509 int mac_keyboard_text_encoding
;
11510 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11512 /* Set in term/mac-win.el to indicate that event loop can now generate
11513 drag and drop events. */
11514 Lisp_Object Qmac_ready_for_drag_n_drop
;
11516 Lisp_Object drag_and_drop_file_list
;
11518 Point saved_menu_event_location
;
11521 static void init_required_apple_events (void);
11522 static pascal OSErr
11523 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
11524 static pascal OSErr
11525 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
11526 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
11527 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
11529 /* Drag and Drop */
11530 static OSErr
init_mac_drag_n_drop ();
11531 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
11533 #if USE_CARBON_EVENTS
11534 /* Preliminary Support for the OSX Services Menu */
11535 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
11536 static void init_service_handler ();
11539 extern void init_emacs_passwd_dir ();
11540 extern int emacs_main (int, char **, char **);
11541 extern void check_alarm ();
11543 extern void initialize_applescript();
11544 extern void terminate_applescript();
11546 static unsigned int
11547 #if USE_CARBON_EVENTS
11548 mac_to_emacs_modifiers (UInt32 mods
)
11550 mac_to_emacs_modifiers (EventModifiers mods
)
11553 unsigned int result
= 0;
11554 if (mods
& macShiftKey
)
11555 result
|= shift_modifier
;
11556 if (mods
& macCtrlKey
)
11557 result
|= ctrl_modifier
;
11558 if (mods
& macMetaKey
)
11559 result
|= meta_modifier
;
11560 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
11561 result
|= alt_modifier
;
11565 #if USE_CARBON_EVENTS
11566 /* Obtains the event modifiers from the event ref and then calls
11567 mac_to_emacs_modifiers. */
11569 mac_event_to_emacs_modifiers (EventRef eventRef
)
11572 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
11573 sizeof (UInt32
), NULL
, &mods
);
11574 return mac_to_emacs_modifiers (mods
);
11577 /* Given an event ref, return the code to use for the mouse button
11578 code in the emacs input_event. */
11580 mac_get_mouse_btn (EventRef ref
)
11582 EventMouseButton result
= kEventMouseButtonPrimary
;
11583 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
11584 sizeof (EventMouseButton
), NULL
, &result
);
11587 case kEventMouseButtonPrimary
:
11589 case kEventMouseButtonSecondary
:
11590 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
11591 case kEventMouseButtonTertiary
:
11592 case 4: /* 4 is the number for the mouse wheel button */
11593 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
11599 /* Normally, ConvertEventRefToEventRecord will correctly handle all
11600 events. However the click of the mouse wheel is not converted to a
11601 mouseDown or mouseUp event. This calls ConvertEventRef, but then
11602 checks to see if it is a mouse up or down carbon event that has not
11603 been converted, and if so, converts it by hand (to be picked up in
11604 the XTread_socket loop). */
11605 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
11607 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
11608 /* Do special case for mouse wheel button. */
11609 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
11611 UInt32 kind
= GetEventKind (eventRef
);
11612 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
11614 eventRec
->what
= mouseDown
;
11617 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
11619 eventRec
->what
= mouseUp
;
11624 /* Need where and when. */
11626 GetEventParameter (eventRef
, kEventParamMouseLocation
,
11627 typeQDPoint
, NULL
, sizeof (Point
),
11628 NULL
, &eventRec
->where
);
11629 /* Use two step process because new event modifiers are
11630 32-bit and old are 16-bit. Currently, only loss is
11632 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
11633 typeUInt32
, NULL
, sizeof (UInt32
),
11635 eventRec
->modifiers
= mods
;
11637 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
11646 do_get_menus (void)
11648 Handle menubar_handle
;
11649 MenuHandle menu_handle
;
11651 menubar_handle
= GetNewMBar (128);
11652 if(menubar_handle
== NULL
)
11654 SetMenuBar (menubar_handle
);
11657 menu_handle
= GetMenuHandle (M_APPLE
);
11658 if(menu_handle
!= NULL
)
11659 AppendResMenu (menu_handle
,'DRVR');
11666 do_init_managers (void)
11668 #if !TARGET_API_MAC_CARBON
11669 InitGraf (&qd
.thePort
);
11671 FlushEvents (everyEvent
, 0);
11675 InitDialogs (NULL
);
11676 #endif /* !TARGET_API_MAC_CARBON */
11679 #if !TARGET_API_MAC_CARBON
11680 /* set up some extra stack space for use by emacs */
11681 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11683 /* MaxApplZone must be called for AppleScript to execute more
11684 complicated scripts */
11687 #endif /* !TARGET_API_MAC_CARBON */
11691 do_check_ram_size (void)
11693 SInt32 physical_ram_size
, logical_ram_size
;
11695 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11696 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11697 || physical_ram_size
> 256 * 1024 * 1024
11698 || logical_ram_size
> 256 * 1024 * 1024)
11700 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11706 do_window_update (WindowPtr win
)
11708 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11709 struct frame
*f
= mwp
->mFP
;
11713 if (f
->async_visible
== 0)
11715 f
->async_visible
= 1;
11716 f
->async_iconified
= 0;
11717 SET_FRAME_GARBAGED (f
);
11719 /* An update event is equivalent to MapNotify on X, so report
11720 visibility changes properly. */
11721 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11722 /* Force a redisplay sooner or later to update the
11723 frame titles in case this is the second frame. */
11724 record_asynch_buffer_change ();
11729 handling_window_update
= 1;
11731 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
11733 expose_frame (f
, 0, 0, 0, 0);
11735 handling_window_update
= 0;
11742 is_emacs_window (WindowPtr win
)
11744 Lisp_Object tail
, frame
;
11749 FOR_EACH_FRAME (tail
, frame
)
11750 if (FRAME_MAC_P (XFRAME (frame
)))
11751 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11758 do_window_activate (WindowPtr win
)
11763 if (is_emacs_window (win
))
11765 mwp
= (mac_output
*) GetWRefCon (win
);
11770 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11771 activate_scroll_bars (f
);
11777 do_window_deactivate (WindowPtr win
)
11782 if (is_emacs_window (win
))
11784 mwp
= (mac_output
*) GetWRefCon (win
);
11787 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11789 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11790 deactivate_scroll_bars (f
);
11802 wp
= FrontWindow();
11803 if (is_emacs_window (wp
))
11805 mwp
= (mac_output
*) GetWRefCon (wp
);
11810 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11811 activate_scroll_bars (f
);
11815 app_is_suspended
= false;
11816 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11826 wp
= FrontWindow();
11827 if (is_emacs_window (wp
))
11829 mwp
= (mac_output
*) GetWRefCon (wp
);
11832 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11834 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11835 deactivate_scroll_bars (f
);
11839 app_is_suspended
= true;
11840 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11845 do_mouse_moved (Point mouse_pos
)
11847 WindowPtr wp
= FrontWindow ();
11850 if (is_emacs_window (wp
))
11852 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11854 #if TARGET_API_MAC_CARBON
11855 SetPort (GetWindowPort (wp
));
11860 GlobalToLocal (&mouse_pos
);
11862 note_mouse_movement (f
, &mouse_pos
);
11868 do_os_event (EventRecord
*erp
)
11870 switch((erp
->message
>> 24) & 0x000000FF)
11872 case suspendResumeMessage
:
11873 if((erp
->message
& resumeFlag
) == 1)
11879 case mouseMovedMessage
:
11880 do_mouse_moved (erp
->where
);
11886 do_events (EventRecord
*erp
)
11891 do_window_update ((WindowPtr
) erp
->message
);
11899 if ((erp
->modifiers
& activeFlag
) != 0)
11900 do_window_activate ((WindowPtr
) erp
->message
);
11902 do_window_deactivate ((WindowPtr
) erp
->message
);
11908 do_apple_menu (SInt16 menu_item
)
11910 #if !TARGET_API_MAC_CARBON
11912 SInt16 da_driver_refnum
;
11914 if (menu_item
== I_ABOUT
)
11915 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11918 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11919 da_driver_refnum
= OpenDeskAcc (item_name
);
11921 #endif /* !TARGET_API_MAC_CARBON */
11925 do_menu_choice (SInt32 menu_choice
)
11927 SInt16 menu_id
, menu_item
;
11929 menu_id
= HiWord (menu_choice
);
11930 menu_item
= LoWord (menu_choice
);
11938 do_apple_menu (menu_item
);
11943 WindowPtr wp
= FrontWindow ();
11944 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11945 MenuHandle menu
= GetMenuHandle (menu_id
);
11950 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11951 menubar_selection_callback (f
, refcon
);
11960 /* Handle drags in size box. Based on code contributed by Ben
11961 Mesander and IM - Window Manager A. */
11964 do_grow_window (WindowPtr w
, EventRecord
*e
)
11969 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11970 struct frame
*f
= mwp
->mFP
;
11972 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11974 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11976 /* see if it really changed size */
11977 if (grow_size
!= 0)
11979 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11980 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11982 x_set_window_size (f
, 0, columns
, rows
);
11987 /* Handle clicks in zoom box. Calculation of "standard state" based
11988 on code in IM - Window Manager A and code contributed by Ben
11989 Mesander. The standard state of an Emacs window is 80-characters
11990 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11993 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11996 Rect zoom_rect
, port_rect
;
11998 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11999 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
12000 struct frame
*f
= mwp
->mFP
;
12002 GetPort (&save_port
);
12004 #if TARGET_API_MAC_CARBON
12005 SetPort (GetWindowPort (w
));
12010 /* Clear window to avoid flicker. */
12011 #if TARGET_API_MAC_CARBON
12016 GetWindowPortBounds (w
, &r
);
12019 if (zoom_in_or_out
== inZoomOut
)
12021 /* calculate height of window's title bar (hard card it for now). */
12022 w_title_height
= 20 + GetMBarHeight ();
12024 /* get maximum height of window into zoom_rect.bottom -
12026 GetQDGlobalsScreenBits (&bm
);
12027 zoom_rect
= bm
.bounds
;
12028 zoom_rect
.top
+= w_title_height
;
12029 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
12031 zoom_rect
.right
= zoom_rect
.left
12032 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
12034 SetWindowStandardState (w
, &zoom_rect
);
12037 #else /* not TARGET_API_MAC_CARBON */
12038 EraseRect (&(w
->portRect
));
12039 if (zoom_in_or_out
== inZoomOut
)
12041 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
12042 LocalToGlobal (&top_left
);
12044 /* calculate height of window's title bar */
12045 w_title_height
= top_left
.v
- 1
12046 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
12048 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
12049 zoom_rect
= qd
.screenBits
.bounds
;
12050 zoom_rect
.top
+= w_title_height
;
12051 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
12053 zoom_rect
.right
= zoom_rect
.left
12054 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
12056 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
12059 #endif /* not TARGET_API_MAC_CARBON */
12061 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
12063 /* retrieve window size and update application values */
12064 #if TARGET_API_MAC_CARBON
12065 GetWindowPortBounds (w
, &port_rect
);
12067 port_rect
= w
->portRect
;
12069 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
12070 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
12071 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
12073 SetPort (save_port
);
12076 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
12078 init_mac_drag_n_drop ()
12080 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
12084 /* Intialize AppleEvent dispatcher table for the required events. */
12086 init_required_apple_events ()
12091 /* Make sure we have apple events before starting. */
12092 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
12096 if (!(result
& (1 << gestaltAppleEventsPresent
)))
12099 #if TARGET_API_MAC_CARBON
12100 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12101 NewAEEventHandlerUPP
12102 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12105 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12106 NewAEEventHandlerProc
12107 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12113 #if TARGET_API_MAC_CARBON
12114 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12115 NewAEEventHandlerUPP
12116 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12119 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12120 NewAEEventHandlerProc
12121 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12127 #if TARGET_API_MAC_CARBON
12128 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12129 NewAEEventHandlerUPP
12130 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12133 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12134 NewAEEventHandlerProc
12135 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12141 #if TARGET_API_MAC_CARBON
12142 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12143 NewAEEventHandlerUPP
12144 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12147 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12148 NewAEEventHandlerProc
12149 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12156 #if USE_CARBON_EVENTS
12159 init_service_handler ()
12161 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
12162 {kEventClassService
, kEventServiceCopy
},
12163 {kEventClassService
, kEventServicePaste
}};
12164 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
12165 3, specs
, NULL
, NULL
);
12169 MAC_TODO: Check to see if this is called by AEProcessDesc...
12172 mac_handle_service_event (EventHandlerCallRef callRef
,
12173 EventRef event
, void *data
)
12175 OSStatus err
= noErr
;
12176 switch (GetEventKind (event
))
12178 case kEventServiceGetTypes
:
12180 CFMutableArrayRef copyTypes
, pasteTypes
;
12182 Boolean selection
= true;
12184 GetEventParameter(event, kEventParamServicePasteTypes,
12185 typeCFMutableArrayRef, NULL,
12186 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
12188 GetEventParameter(event
, kEventParamServiceCopyTypes
,
12189 typeCFMutableArrayRef
, NULL
,
12190 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
12191 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
12193 CFArrayAppendValue (copyTypes
, type
);
12194 //CFArrayAppendValue (pasteTypes, type);
12198 case kEventServiceCopy
:
12200 ScrapRef currentScrap
, specificScrap
;
12202 Size byteCount
= 0;
12204 GetCurrentScrap (¤tScrap
);
12206 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
12209 void *buffer
= xmalloc (byteCount
);
12210 if (buffer
!= NULL
)
12212 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
12213 sizeof (ScrapRef
), NULL
, &specificScrap
);
12215 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
12216 &byteCount
, buffer
);
12218 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
12219 kScrapFlavorMaskNone
, byteCount
, buffer
);
12225 case kEventServicePaste
:
12228 // Get the current location
12230 ScrapRef specificScrap;
12231 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
12232 sizeof(ScrapRef), NULL, &specificScrap);
12233 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
12234 if (err == noErr) {
12235 void * buffer = xmalloc(byteCount);
12236 if (buffer != NULL ) {
12237 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
12238 &byteCount, buffer);
12239 if (err == noErr) {
12240 // Actually place in the buffer
12242 // Get the current "selection" string here
12255 /* Open Application Apple Event */
12256 static pascal OSErr
12257 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
12263 /* Defined in mac.c. */
12265 path_from_vol_dir_name (char *, int, short, long, char *);
12268 /* Called when we receive an AppleEvent with an ID of
12269 "kAEOpenDocuments". This routine gets the direct parameter,
12270 extracts the FSSpecs in it, and puts their names on a list. */
12271 static pascal OSErr
12272 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
12277 DescType actual_type
;
12280 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
12282 goto descriptor_error_exit
;
12284 /* Check to see that we got all of the required parameters from the
12285 event descriptor. For an 'odoc' event this should just be the
12287 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
12288 &actual_type
, (Ptr
) &keyword
,
12289 sizeof (keyword
), &actual_size
);
12290 /* No error means that we found some unused parameters.
12291 errAEDescNotFound means that there are no more parameters. If we
12292 get an error code other than that, flag it. */
12293 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
12295 err
= errAEEventNotHandled
;
12300 /* Got all the parameters we need. Now, go through the direct
12301 object list and parse it up. */
12303 long num_files_to_open
;
12305 err
= AECountItems (&the_desc
, &num_files_to_open
);
12310 /* AE file list is one based so just use that for indexing here. */
12311 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
12314 Str255 path_name
, unix_path_name
;
12319 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12320 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12321 if (err
!= noErr
) break;
12324 err
= FSpMakeFSRef (&fs
, &fref
);
12325 if (err
!= noErr
) break;
12327 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
12329 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12331 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12333 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12334 drag_and_drop_file_list
);
12340 /* Nuke the coerced file list in any case */
12341 err2
= AEDisposeDesc(&the_desc
);
12343 descriptor_error_exit
:
12344 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12349 static pascal OSErr
12350 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
12351 DragReference theDrag
)
12355 FlavorFlags theFlags
;
12358 ItemReference theItem
;
12361 Size size
= sizeof (HFSFlavor
);
12363 drag_and_drop_file_list
= Qnil
;
12364 GetDragMouse (theDrag
, &mouse
, 0L);
12365 CountDragItems (theDrag
, &items
);
12366 for (index
= 1; index
<= items
; index
++)
12368 /* Only handle file references. */
12369 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
12370 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
12371 if (result
== noErr
)
12378 Str255 unix_path_name
;
12379 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
12381 /* Use Carbon routines, otherwise it converts the file name
12382 to /Macintosh HD/..., which is not correct. */
12383 FSpMakeFSRef (&data
.fileSpec
, &fref
);
12384 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
12386 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
12387 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
12388 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12390 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12391 drag_and_drop_file_list
);
12396 /* If there are items in the list, construct an event and post it to
12397 the queue like an interrupt using kbd_buffer_store_event. */
12398 if (!NILP (drag_and_drop_file_list
))
12400 struct input_event event
;
12402 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
12403 SetPort (GetWindowPort (window
));
12404 GlobalToLocal (&mouse
);
12406 event
.kind
= DRAG_N_DROP_EVENT
;
12408 event
.modifiers
= 0;
12409 event
.timestamp
= TickCount () * (1000 / 60);
12410 XSETINT (event
.x
, mouse
.h
);
12411 XSETINT (event
.y
, mouse
.v
);
12412 XSETFRAME (frame
, f
);
12413 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12415 /* Post to the interrupt queue */
12416 kbd_buffer_store_event (&event
);
12417 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
12419 ProcessSerialNumber psn
;
12420 GetCurrentProcess (&psn
);
12421 SetFrontProcess (&psn
);
12427 /* Print Document Apple Event */
12428 static pascal OSErr
12429 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12431 return errAEEventNotHandled
;
12435 static pascal OSErr
12436 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12438 /* FixMe: Do we need an unwind-protect or something here? And what
12439 do we do about unsaved files. Currently just forces quit rather
12440 than doing recursive callback to get user input. */
12442 terminate_flag
= true;
12444 /* Fkill_emacs doesn't return. We have to return. (TI) */
12451 profiler_exit_proc ()
12453 ProfilerDump ("\pEmacs.prof");
12458 /* These few functions implement Emacs as a normal Mac application
12459 (almost): set up the heap and the Toolbox, handle necessary
12460 system events plus a few simple menu events. They also set up
12461 Emacs's access to functions defined in the rest of this file.
12462 Emacs uses function hooks to perform all its terminal I/O. A
12463 complete list of these functions appear in termhooks.h. For what
12464 they do, read the comments there and see also w32term.c and
12465 xterm.c. What's noticeably missing here is the event loop, which
12466 is normally present in most Mac application. After performing the
12467 necessary Mac initializations, main passes off control to
12468 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12469 mac_read_socket (defined further below) to read input. This is
12470 where WaitNextEvent is called to process Mac events. This is also
12471 where check_alarm in sysdep.c is called to simulate alarm signals.
12472 This makes the cursor jump back to its correct position after
12473 briefly jumping to that of the matching parenthesis, print useful
12474 hints and prompts in the minibuffer after the user stops typing for
12477 #if !TARGET_API_MAC_CARBON
12482 #if __profile__ /* is the profiler on? */
12483 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12488 /* set creator and type for files created by MSL */
12489 _fcreator
= 'EMAx';
12493 do_init_managers ();
12497 do_check_ram_size ();
12499 init_emacs_passwd_dir ();
12503 initialize_applescript ();
12505 init_required_apple_events ();
12511 /* set up argv array from STR# resource */
12512 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12516 /* free up AppleScript resources on exit */
12517 atexit (terminate_applescript
);
12519 #if __profile__ /* is the profiler on? */
12520 atexit (profiler_exit_proc
);
12523 /* 3rd param "envp" never used in emacs_main */
12524 (void) emacs_main (argc
, argv
, 0);
12527 /* Never reached - real exit in Fkill_emacs */
12532 /* Table for translating Mac keycode to X keysym values. Contributed
12533 by Sudhir Shenoy. */
12534 static unsigned char keycode_to_xkeysym_table
[] = {
12536 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12537 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12538 0, 0, 0, 0, '\x0d', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12539 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12541 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
12542 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
12543 0, 0, 0, '\xaf' /* kp/ */,
12544 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
12546 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
12547 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
12548 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
12549 '\xb9' /* kp9 */, 0, 0, 0,
12551 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
12552 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
12553 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
12554 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
12556 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
12557 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
12558 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
12559 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
12563 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12565 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12566 return *xKeySym
!= 0;
12569 /* Emacs calls this whenever it wants to read an input event from the
12572 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12575 #if USE_CARBON_EVENTS
12576 OSStatus rneResult
;
12578 EventMouseButton mouseBtn
;
12582 EventMask event_mask
;
12585 if (interrupt_input_blocked
)
12587 interrupt_input_pending
= 1;
12592 interrupt_input_pending
= 0;
12595 /* So people can tell when we have read the available input. */
12596 input_signal_count
++;
12601 /* Don't poll for events to process (specifically updateEvt) if
12602 window update currently already in progress. A call to redisplay
12603 (in do_window_update) can be preempted by another call to
12604 redisplay, causing blank regions to be left on the screen and the
12605 cursor to be left at strange places. */
12606 if (handling_window_update
)
12612 if (terminate_flag
)
12613 Fkill_emacs (make_number (1));
12615 /* It is necessary to set this (additional) argument slot of an
12616 event to nil because keyboard.c protects incompletely processed
12617 event from being garbage collected by placing them in the
12618 kbd_buffer_gcpro vector. */
12621 event_mask
= everyEvent
;
12622 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12623 event_mask
-= highLevelEventMask
;
12625 #if USE_CARBON_EVENTS
12626 rneResult
= ReceiveNextEvent (0, NULL
,
12628 ? TicksToEventTime (app_sleep_time
)
12633 /* Handle new events */
12634 if (!mac_convert_event_ref (eventRef
, &er
))
12635 switch (GetEventClass (eventRef
))
12637 case kEventClassMouse
:
12638 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
12642 WindowPtr window_ptr
= FrontNonFloatingWindow ();
12643 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12644 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
12645 typeSInt32
, NULL
, sizeof (SInt32
),
12647 GetEventParameter(eventRef
, kEventParamMouseLocation
,
12648 typeQDPoint
, NULL
, sizeof (Point
),
12650 bufp
->kind
= MOUSE_WHEEL_EVENT
;
12651 bufp
->code
= delta
;
12652 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
12653 SetPort (GetWindowPort (window_ptr
));
12654 GlobalToLocal (&point
);
12655 XSETINT (bufp
->x
, point
.h
);
12656 XSETINT (bufp
->y
, point
.v
);
12657 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12658 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
12662 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12666 /* Send the event to the appropriate receiver. */
12667 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12671 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
12672 #endif /* USE_CARBON_EVENTS */
12678 WindowPtr window_ptr
= FrontWindow ();
12681 #if USE_CARBON_EVENTS
12682 /* This is needed to send mouse events like aqua window buttons
12683 to the correct handler. */
12684 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
12688 if (!is_emacs_window(window_ptr
))
12692 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12693 && er
.what
== mouseUp
)
12695 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12696 Point mouse_loc
= er
.where
;
12698 /* Convert to local coordinates of new window. */
12699 #if TARGET_API_MAC_CARBON
12700 SetPort (GetWindowPort (window_ptr
));
12702 SetPort (window_ptr
);
12705 GlobalToLocal (&mouse_loc
);
12707 #if USE_CARBON_EVENTS
12708 bufp
->code
= mac_get_mouse_btn (eventRef
);
12710 bufp
->code
= 0; /* only one mouse button */
12712 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
12713 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12714 bufp
->part
= scroll_bar_handle
;
12715 #if USE_CARBON_EVENTS
12716 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12718 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12720 bufp
->modifiers
|= up_modifier
;
12721 bufp
->timestamp
= er
.when
* (1000 / 60);
12722 /* ticks to milliseconds */
12724 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12725 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12726 tracked_scroll_bar
->dragging
= Qnil
;
12727 mouse_tracking_in_progress
= mouse_tracking_none
;
12728 tracked_scroll_bar
= NULL
;
12733 part_code
= FindWindow (er
.where
, &window_ptr
);
12739 struct frame
*f
= ((mac_output
*)
12740 GetWRefCon (FrontWindow ()))->mFP
;
12741 saved_menu_event_location
= er
.where
;
12742 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
12743 XSETFRAME (bufp
->frame_or_window
, f
);
12749 if (window_ptr
!= FrontWindow ())
12750 SelectWindow (window_ptr
);
12753 SInt16 control_part_code
;
12755 struct mac_output
*mwp
= (mac_output
*)
12756 GetWRefCon (window_ptr
);
12757 Point mouse_loc
= er
.where
;
12759 /* convert to local coordinates of new window */
12760 #if TARGET_API_MAC_CARBON
12761 SetPort (GetWindowPort (window_ptr
));
12763 SetPort (window_ptr
);
12766 GlobalToLocal (&mouse_loc
);
12767 #if TARGET_API_MAC_CARBON
12768 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12769 &control_part_code
);
12771 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12774 #if USE_CARBON_EVENTS
12775 bufp
->code
= mac_get_mouse_btn (eventRef
);
12777 bufp
->code
= 0; /* only one mouse button */
12779 XSETINT (bufp
->x
, mouse_loc
.h
);
12780 XSETINT (bufp
->y
, mouse_loc
.v
);
12781 bufp
->timestamp
= er
.when
* (1000 / 60);
12782 /* ticks to milliseconds */
12784 #if TARGET_API_MAC_CARBON
12787 if (control_part_code
!= 0)
12790 struct scroll_bar
*bar
= (struct scroll_bar
*)
12791 GetControlReference (ch
);
12792 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12794 if (er
.what
== mouseDown
12795 && control_part_code
== kControlIndicatorPart
)
12797 mouse_tracking_in_progress
12798 = mouse_tracking_scroll_bar
;
12799 tracked_scroll_bar
= bar
;
12803 mouse_tracking_in_progress
= mouse_tracking_none
;
12804 tracked_scroll_bar
= NULL
;
12809 bufp
->kind
= MOUSE_CLICK_EVENT
;
12810 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12811 if (er
.what
== mouseDown
)
12812 mouse_tracking_in_progress
12813 = mouse_tracking_mouse_movement
;
12815 mouse_tracking_in_progress
= mouse_tracking_none
;
12818 #if USE_CARBON_EVENTS
12819 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12821 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12827 bufp
->modifiers
|= down_modifier
;
12830 bufp
->modifiers
|= up_modifier
;
12839 #if TARGET_API_MAC_CARBON
12843 GetQDGlobalsScreenBits (&bm
);
12844 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12846 #else /* not TARGET_API_MAC_CARBON */
12847 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12848 #endif /* not TARGET_API_MAC_CARBON */
12852 if (TrackGoAway (window_ptr
, er
.where
))
12854 bufp
->kind
= DELETE_WINDOW_EVENT
;
12855 XSETFRAME (bufp
->frame_or_window
,
12856 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12861 /* window resize handling added --ben */
12863 do_grow_window(window_ptr
, &er
);
12866 /* window zoom handling added --ben */
12869 if (TrackBox (window_ptr
, er
.where
, part_code
))
12870 do_zoom_window (window_ptr
, part_code
);
12882 #if USE_CARBON_EVENTS
12883 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
12891 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12894 #if USE_CARBON_EVENTS
12895 /* When using Carbon Events, we need to pass raw keyboard events
12896 to the TSM ourselves. If TSM handles it, it will pass back
12897 noErr, otherwise it will pass back "eventNotHandledErr" and
12898 we can process it normally. */
12899 if ((!NILP (Vmac_pass_command_to_system
)
12900 || !(er
.modifiers
& cmdKey
))
12901 && (!NILP (Vmac_pass_control_to_system
)
12902 || !(er
.modifiers
& controlKey
)))
12905 err
= SendEventToEventTarget (eventRef
,
12906 GetEventDispatcherTarget ());
12907 if (err
!= eventNotHandledErr
)
12912 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
12921 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12924 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12926 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12928 bufp
->code
= 0xff00 | xkeysym
;
12929 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
12931 else if (!NILP (Vmac_reverse_ctrl_meta
) && (er
.modifiers
& controlKey
))
12933 /* This is a special case to deal with converting from
12934 a control character to non-control character */
12935 int new_modifiers
= er
.modifiers
& ~controlKey
;
12936 int new_keycode
= keycode
| new_modifiers
;
12937 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12938 unsigned long some_state
= 0;
12939 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
, &some_state
) & 0xff;
12940 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12944 if (er
.modifiers
& macMetaKey
)
12946 /* This code comes from Keyboard Resource, Appendix
12947 C of IM - Text. This is necessary since shift is
12948 ignored in KCHR table translation when option or
12949 command is pressed. */
12950 int new_modifiers
= er
.modifiers
& 0xf600;
12951 /* mask off option and command */
12952 int new_keycode
= keycode
| new_modifiers
;
12953 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12954 unsigned long some_state
= 0;
12955 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12956 &some_state
) & 0xff;
12959 bufp
->code
= er
.message
& charCodeMask
;
12960 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12964 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12965 convert non-ASCII characters typed at the Mac keyboard
12966 (presumed to be in the Mac Roman encoding) to iso-latin-1
12967 encoding before they are passed to Emacs. This enables the
12968 Mac keyboard to be used to enter non-ASCII iso-latin-1
12969 characters directly. */
12970 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12971 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
12973 static TECObjectRef converter
= NULL
;
12974 OSStatus the_err
= noErr
;
12975 OSStatus convert_status
= noErr
;
12977 if (converter
== NULL
)
12979 the_err
= TECCreateConverter (&converter
,
12980 kTextEncodingMacRoman
,
12981 mac_keyboard_text_encoding
);
12982 current_mac_keyboard_text_encoding
12983 = mac_keyboard_text_encoding
;
12985 else if (mac_keyboard_text_encoding
12986 != current_mac_keyboard_text_encoding
)
12988 /* Free the converter for the current encoding before
12989 creating a new one. */
12990 TECDisposeConverter (converter
);
12991 the_err
= TECCreateConverter (&converter
,
12992 kTextEncodingMacRoman
,
12993 mac_keyboard_text_encoding
);
12994 current_mac_keyboard_text_encoding
12995 = mac_keyboard_text_encoding
;
12998 if (the_err
== noErr
)
13000 unsigned char ch
= bufp
->code
;
13001 ByteCount actual_input_length
, actual_output_length
;
13002 unsigned char outch
;
13004 convert_status
= TECConvertText (converter
, &ch
, 1,
13005 &actual_input_length
,
13007 &actual_output_length
);
13008 if (convert_status
== noErr
13009 && actual_input_length
== 1
13010 && actual_output_length
== 1)
13011 bufp
->code
= outch
;
13015 #if USE_CARBON_EVENTS
13016 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
13018 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
13023 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
13024 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
13027 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
13032 case kHighLevelEvent
:
13033 drag_and_drop_file_list
= Qnil
;
13035 AEProcessAppleEvent(&er
);
13037 /* Build a DRAG_N_DROP_EVENT type event as is done in
13038 constuct_drag_n_drop in w32term.c. */
13039 if (!NILP (drag_and_drop_file_list
))
13041 struct frame
*f
= NULL
;
13045 wp
= FrontNonFloatingWindow ();
13046 if (wp
&& is_emacs_window(wp
))
13047 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
13049 bufp
->kind
= DRAG_N_DROP_EVENT
;
13051 bufp
->timestamp
= er
.when
* (1000 / 60);
13052 /* ticks to milliseconds */
13053 #if USE_CARBON_EVENTS
13054 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
13056 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
13059 XSETINT (bufp
->x
, 0);
13060 XSETINT (bufp
->y
, 0);
13062 XSETFRAME (frame
, f
);
13063 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
13065 /* Regardless of whether Emacs was suspended or in the
13066 foreground, ask it to redraw its entire screen.
13067 Otherwise parts of the screen can be left in an
13068 inconsistent state. */
13070 #if TARGET_API_MAC_CARBON
13074 GetWindowPortBounds (wp
, &r
);
13075 InvalWindowRect (wp
, &r
);
13077 #else /* not TARGET_API_MAC_CARBON */
13078 InvalRect (&(wp
->portRect
));
13079 #endif /* not TARGET_API_MAC_CARBON */
13086 #if USE_CARBON_EVENTS
13087 ReleaseEvent (eventRef
);
13091 /* If the focus was just given to an autoraising frame,
13093 /* ??? This ought to be able to handle more than one such frame. */
13094 if (pending_autoraise_frame
)
13096 x_raise_frame (pending_autoraise_frame
);
13097 pending_autoraise_frame
= 0;
13100 #if !TARGET_API_MAC_CARBON
13101 check_alarm (); /* simulate the handling of a SIGALRM */
13105 static Point old_mouse_pos
= { -1, -1 };
13107 if (app_is_suspended
)
13109 old_mouse_pos
.h
= -1;
13110 old_mouse_pos
.v
= -1;
13118 struct scroll_bar
*sb
;
13120 wp
= FrontWindow ();
13121 if (is_emacs_window (wp
))
13123 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
13125 #if TARGET_API_MAC_CARBON
13126 SetPort (GetWindowPort (wp
));
13131 GetMouse (&mouse_pos
);
13133 if (!EqualPt (mouse_pos
, old_mouse_pos
))
13135 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
13136 && tracked_scroll_bar
)
13137 x_scroll_bar_note_movement (tracked_scroll_bar
,
13139 - XINT (tracked_scroll_bar
->top
),
13140 TickCount() * (1000 / 60));
13142 note_mouse_movement (f
, &mouse_pos
);
13144 old_mouse_pos
= mouse_pos
;
13156 /* Need to override CodeWarrior's input function so no conversion is
13157 done on newlines Otherwise compiled functions in .elc files will be
13158 read incorrectly. Defined in ...:MSL C:MSL
13159 Common:Source:buffer_io.c. */
13162 __convert_to_newlines (unsigned char * p
, size_t * n
)
13164 #pragma unused(p,n)
13168 __convert_from_newlines (unsigned char * p
, size_t * n
)
13170 #pragma unused(p,n)
13175 /* Initialize the struct pointed to by MW to represent a new COLS x
13176 ROWS Macintosh window, using font with name FONTNAME and size
13179 NewMacWindow (FRAME_PTR fp
)
13182 #if TARGET_API_MAC_CARBON
13183 static int making_terminal_window
= 0;
13185 static int making_terminal_window
= 1;
13188 mwp
= fp
->output_data
.mac
;
13190 if (making_terminal_window
)
13192 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
13195 making_terminal_window
= 0;
13198 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
13201 SetWRefCon (mwp
->mWP
, (long) mwp
);
13202 /* so that update events can find this mac_output struct */
13203 mwp
->mFP
= fp
; /* point back to emacs frame */
13205 #if TARGET_API_MAC_CARBON
13206 SetPort (GetWindowPort (mwp
->mWP
));
13208 SetPort (mwp
->mWP
);
13213 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
13214 ShowWindow (mwp
->mWP
);
13220 make_mac_frame (struct frame
*f
)
13222 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
13223 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
13225 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
13229 f
->output_data
.mac
->cursor_pixel
= 0;
13230 f
->output_data
.mac
->border_pixel
= 0x00ff00;
13231 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
13232 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
13234 f
->output_data
.mac
->fontset
= -1;
13235 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13236 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13237 f
->output_data
.mac
->left_pos
= 4;
13238 f
->output_data
.mac
->top_pos
= 4;
13239 f
->output_data
.mac
->border_width
= 0;
13240 f
->output_data
.mac
->explicit_parent
= 0;
13242 f
->output_data
.mac
->internal_border_width
= 0;
13244 f
->output_method
= output_mac
;
13254 make_mac_terminal_frame (struct frame
*f
)
13258 XSETFRAME (frame
, f
);
13260 f
->output_method
= output_mac
;
13261 f
->output_data
.mac
= (struct mac_output
*)
13262 xmalloc (sizeof (struct mac_output
));
13263 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
13264 f
->output_data
.mac
->fontset
= -1;
13265 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13266 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13268 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
13273 make_mac_frame (f
);
13277 /* Need to be initialized for unshow_buffer in window.c. */
13278 selected_window
= f
->selected_window
;
13280 Fmodify_frame_parameters (frame
,
13281 Fcons (Fcons (Qfont
,
13282 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
13283 Fmodify_frame_parameters (frame
,
13284 Fcons (Fcons (Qforeground_color
,
13285 build_string ("black")), Qnil
));
13286 Fmodify_frame_parameters (frame
,
13287 Fcons (Fcons (Qbackground_color
,
13288 build_string ("white")), Qnil
));
13292 /***********************************************************************
13294 ***********************************************************************/
13296 #ifdef USE_X_TOOLKIT
13297 static XrmOptionDescRec emacs_options
[] = {
13298 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13299 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13301 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13302 XrmoptionSepArg
, NULL
},
13303 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13305 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13306 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13307 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13308 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13309 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13310 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13311 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13313 #endif /* USE_X_TOOLKIT */
13315 #ifdef MULTI_KBOARD
13316 /* Test whether two display-name strings agree up to the dot that separates
13317 the screen number from the server number. */
13319 same_x_server (name1
, name2
)
13320 char *name1
, *name2
;
13322 int seen_colon
= 0;
13323 unsigned char *system_name
= SDATA (Vsystem_name
);
13324 int system_name_length
= strlen (system_name
);
13325 int length_until_period
= 0;
13327 while (system_name
[length_until_period
] != 0
13328 && system_name
[length_until_period
] != '.')
13329 length_until_period
++;
13331 /* Treat `unix' like an empty host name. */
13332 if (! strncmp (name1
, "unix:", 5))
13334 if (! strncmp (name2
, "unix:", 5))
13336 /* Treat this host's name like an empty host name. */
13337 if (! strncmp (name1
, system_name
, system_name_length
)
13338 && name1
[system_name_length
] == ':')
13339 name1
+= system_name_length
;
13340 if (! strncmp (name2
, system_name
, system_name_length
)
13341 && name2
[system_name_length
] == ':')
13342 name2
+= system_name_length
;
13343 /* Treat this host's domainless name like an empty host name. */
13344 if (! strncmp (name1
, system_name
, length_until_period
)
13345 && name1
[length_until_period
] == ':')
13346 name1
+= length_until_period
;
13347 if (! strncmp (name2
, system_name
, length_until_period
)
13348 && name2
[length_until_period
] == ':')
13349 name2
+= length_until_period
;
13351 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13355 if (seen_colon
&& *name1
== '.')
13359 && (*name1
== '.' || *name1
== '\0')
13360 && (*name2
== '.' || *name2
== '\0'));
13364 int mac_initialized
= 0;
13367 mac_initialize_display_info ()
13369 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
13370 GDHandle main_device_handle
;
13372 bzero (dpyinfo
, sizeof (*dpyinfo
));
13374 /* Put it on x_display_name_list. */
13375 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
13376 x_display_name_list
);
13377 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13380 dpyinfo
->mac_id_name
13381 = (char *) xmalloc (SCHARS (Vinvocation_name
)
13382 + SCHARS (Vsystem_name
)
13384 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
13385 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
13387 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
13388 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
13391 main_device_handle
= LMGetMainDevice();
13393 dpyinfo
->reference_count
= 0;
13394 dpyinfo
->resx
= 75.0;
13395 dpyinfo
->resy
= 75.0;
13396 dpyinfo
->n_planes
= 1;
13397 dpyinfo
->n_cbits
= 16;
13398 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13399 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13400 dpyinfo
->grabbed
= 0;
13401 dpyinfo
->root_window
= NULL
;
13403 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13404 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13405 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13406 dpyinfo
->mouse_face_window
= Qnil
;
13409 struct mac_display_info
*
13410 mac_term_init (display_name
, xrm_option
, resource_name
)
13411 Lisp_Object display_name
;
13413 char *resource_name
;
13415 struct mac_display_info
*dpyinfo
;
13416 GDHandle main_device_handle
;
13418 if (!mac_initialized
)
13421 mac_initialized
= 1;
13424 mac_initialize_display_info (display_name
);
13426 dpyinfo
= &one_mac_display_info
;
13428 main_device_handle
= LMGetMainDevice();
13430 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13431 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13438 MakeMeTheFrontProcess ()
13440 ProcessSerialNumber psn
;
13443 err
= GetCurrentProcess (&psn
);
13445 (void) SetFrontProcess (&psn
);
13447 #endif /* MAC_OSX */
13449 /* Set up use of X before we make the first connection. */
13451 static struct redisplay_interface x_redisplay_interface
=
13456 x_clear_end_of_line
,
13458 x_after_update_window_line
,
13459 x_update_window_begin
,
13460 x_update_window_end
,
13463 x_clear_mouse_face
,
13464 x_get_glyph_overhangs
,
13465 x_fix_overlapping_area
13471 rif
= &x_redisplay_interface
;
13473 clear_frame_hook
= x_clear_frame
;
13474 ins_del_lines_hook
= x_ins_del_lines
;
13475 delete_glyphs_hook
= x_delete_glyphs
;
13476 ring_bell_hook
= XTring_bell
;
13477 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13478 set_terminal_modes_hook
= XTset_terminal_modes
;
13479 update_begin_hook
= x_update_begin
;
13480 update_end_hook
= x_update_end
;
13481 set_terminal_window_hook
= XTset_terminal_window
;
13482 read_socket_hook
= XTread_socket
;
13483 frame_up_to_date_hook
= XTframe_up_to_date
;
13484 mouse_position_hook
= XTmouse_position
;
13485 frame_rehighlight_hook
= XTframe_rehighlight
;
13486 frame_raise_lower_hook
= XTframe_raise_lower
;
13488 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13489 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13490 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13491 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13493 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13495 scroll_region_ok
= 1; /* we'll scroll partial frames */
13496 char_ins_del_ok
= 1;
13497 line_ins_del_ok
= 1; /* we'll just blt 'em */
13498 fast_clear_end_of_line
= 1; /* X does this well */
13499 memory_below_frame
= 0; /* we don't remember what scrolls
13504 last_tool_bar_item
= -1;
13505 any_help_event_p
= 0;
13507 /* Try to use interrupt input; if we can't, then start polling. */
13508 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13510 #ifdef USE_X_TOOLKIT
13511 XtToolkitInitialize ();
13512 Xt_app_con
= XtCreateApplicationContext ();
13513 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13515 /* Install an asynchronous timer that processes Xt timeout events
13516 every 0.1s. This is necessary because some widget sets use
13517 timeouts internally, for example the LessTif menu bar, or the
13518 Xaw3d scroll bar. When Xt timouts aren't processed, these
13519 widgets don't behave normally. */
13521 EMACS_TIME interval
;
13522 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13523 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13527 #if USE_TOOLKIT_SCROLL_BARS
13528 xaw3d_arrow_scroll
= False
;
13529 xaw3d_pick_top
= True
;
13533 /* Note that there is no real way portable across R3/R4 to get the
13534 original error handler. */
13535 XSetErrorHandler (x_error_handler
);
13536 XSetIOErrorHandler (x_io_error_quitter
);
13538 /* Disable Window Change signals; they are handled by X events. */
13540 signal (SIGWINCH
, SIG_DFL
);
13541 #endif /* ! defined (SIGWINCH) */
13543 signal (SIGPIPE
, x_connection_signal
);
13546 mac_initialize_display_info ();
13548 #if TARGET_API_MAC_CARBON
13549 init_required_apple_events ();
13551 init_mac_drag_n_drop ();
13553 #if USE_CARBON_EVENTS
13554 init_service_handler ();
13557 DisableMenuCommand (NULL
, kHICommandQuit
);
13559 if (!inhibit_window_system
)
13560 MakeMeTheFrontProcess ();
13569 staticpro (&x_error_message_string
);
13570 x_error_message_string
= Qnil
;
13573 staticpro (&x_display_name_list
);
13574 x_display_name_list
= Qnil
;
13576 staticpro (&last_mouse_scroll_bar
);
13577 last_mouse_scroll_bar
= Qnil
;
13579 staticpro (&Qvendor_specific_keysyms
);
13580 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13582 staticpro (&last_mouse_press_frame
);
13583 last_mouse_press_frame
= Qnil
;
13585 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13586 staticpro (&Qmac_ready_for_drag_n_drop
);
13589 staticpro (&help_echo
);
13590 help_echo_object
= Qnil
;
13591 staticpro (&help_echo_object
);
13592 help_echo_window
= Qnil
;
13593 staticpro (&help_echo_window
);
13594 previous_help_echo
= Qnil
;
13595 staticpro (&previous_help_echo
);
13596 help_echo_pos
= -1;
13598 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13599 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13600 x_autoselect_window_p
= 0;
13602 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13603 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13604 For example, if a block cursor is over a tab, it will be drawn as
13605 wide as that tab on the display. */);
13606 x_stretch_cursor_p
= 0;
13608 #if 0 /* TODO: Setting underline position from font properties. */
13609 DEFVAR_BOOL ("x-use-underline-position-properties",
13610 &x_use_underline_position_properties
,
13611 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13612 nil means ignore them. If you encounter fonts with bogus
13613 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13614 to 4.1, set this to nil. */);
13615 x_use_underline_position_properties
= 1;
13618 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13619 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13620 Vx_toolkit_scroll_bars
= Qt
;
13622 staticpro (&last_mouse_motion_frame
);
13623 last_mouse_motion_frame
= Qnil
;
13625 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13626 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13627 Otherwise the option key is used. */);
13628 Vmac_command_key_is_meta
= Qt
;
13630 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
13631 doc
: /* Non-nil means that the control and meta keys are reversed. This is
13632 useful for non-standard keyboard layouts. */);
13633 Vmac_reverse_ctrl_meta
= Qnil
;
13635 #if USE_CARBON_EVENTS
13636 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
13637 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
13638 the right click will be mouse-3.
13639 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
13640 Vmac_wheel_button_is_mouse_2
= Qnil
;
13642 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
13643 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
13644 Toolbox for processing before Emacs sees it. */);
13645 Vmac_pass_command_to_system
= Qt
;
13647 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
13648 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
13649 Toolbox for processing before Emacs sees it. */);
13650 Vmac_pass_control_to_system
= Qt
;
13653 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13654 doc
: /* One of the Text Encoding Base constant values defined in the
13655 Basic Text Constants section of Inside Macintosh - Text Encoding
13656 Conversion Manager. Its value determines the encoding characters
13657 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13658 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13659 its default value, no conversion takes place. If it is set to
13660 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13661 characters typed on Mac keyboard are first converted into the
13662 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13663 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13664 command, this enables the Mac keyboard to be used to enter non-ASCII
13665 characters directly. */);
13666 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;