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
*));
371 QDGlobals qd
; /* QuickDraw global information structure. */
375 /* Enumeration for overriding/changing the face to use for drawing
376 glyphs in x_draw_glyphs. */
378 enum draw_glyphs_face
388 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
389 struct mac_display_info
*mac_display_info_for_display (Display
*);
390 static void x_update_window_end
P_ ((struct window
*, int, int));
391 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
392 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
393 int *, int *, Lisp_Object
));
394 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
395 int *, int *, int *, int *, int));
396 static void set_output_cursor
P_ ((struct cursor_pos
*));
397 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
398 int *, int *, int *, int));
399 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
400 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
401 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
402 static void x_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
403 static void show_mouse_face
P_ ((struct x_display_info
*,
404 enum draw_glyphs_face
));
405 static int cursor_in_mouse_face_p
P_ ((struct window
*));
406 static int clear_mouse_face
P_ ((struct mac_display_info
*));
407 static int x_io_error_quitter
P_ ((Display
*));
408 int x_catch_errors
P_ ((Display
*));
409 void x_uncatch_errors
P_ ((Display
*, int));
410 void x_lower_frame
P_ ((struct frame
*));
411 void x_scroll_bar_clear
P_ ((struct frame
*));
412 int x_had_errors_p
P_ ((Display
*));
413 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
414 void x_raise_frame
P_ ((struct frame
*));
415 void x_set_window_size
P_ ((struct frame
*, int, int, int));
416 void x_wm_set_window_state
P_ ((struct frame
*, int));
417 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
418 void mac_initialize
P_ ((void));
419 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
420 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
421 enum text_cursor_kinds x_specified_cursor_type
P_ ((Lisp_Object
, int *));
422 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
424 enum draw_glyphs_face
));
425 static void x_update_end
P_ ((struct frame
*));
426 static void XTframe_up_to_date
P_ ((struct frame
*));
427 static void XTreassert_line_highlight
P_ ((int, int));
428 static void x_change_line_highlight
P_ ((int, int, int, int));
429 static void XTset_terminal_modes
P_ ((void));
430 static void XTreset_terminal_modes
P_ ((void));
431 static void XTcursor_to
P_ ((int, int, int, int));
432 static void x_write_glyphs
P_ ((struct glyph
*, int));
433 static void x_clear_end_of_line
P_ ((int));
434 static void x_clear_frame
P_ ((void));
435 static void x_clear_cursor
P_ ((struct window
*));
436 static void frame_highlight
P_ ((struct frame
*));
437 static void frame_unhighlight
P_ ((struct frame
*));
438 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
439 static void XTframe_rehighlight
P_ ((struct frame
*));
440 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
441 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
442 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
443 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
444 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
445 static int expose_window_tree
P_ ((struct window
*, Rect
*));
446 static int expose_window
P_ ((struct window
*, Rect
*));
447 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
448 Rect
*, enum glyph_row_area
));
449 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
451 void x_display_cursor (struct window
*, int, int, int, int, int);
452 void x_update_cursor
P_ ((struct frame
*, int));
453 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
454 static void x_update_window_cursor
P_ ((struct window
*, int));
455 static void x_erase_phys_cursor
P_ ((struct window
*));
456 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
457 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
458 enum fringe_bitmap_type
, int left_p
));
459 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
461 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
462 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
463 static void notice_overwritten_cursor
P_ ((struct window
*,
465 int, int, int, int));
466 static void x_flush
P_ ((struct frame
*f
));
467 static void x_update_begin
P_ ((struct frame
*));
468 static void x_update_window_begin
P_ ((struct window
*));
469 static void x_draw_vertical_border
P_ ((struct window
*));
470 static void x_after_update_window_line
P_ ((struct glyph_row
*));
471 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
472 static void x_produce_stretch_glyph
P_ ((struct it
*));
474 static void activate_scroll_bars (FRAME_PTR
);
475 static void deactivate_scroll_bars (FRAME_PTR
);
477 extern int image_ascent (struct image
*, struct face
*);
478 void x_set_offset (struct frame
*, int, int, int);
479 int x_bitmap_icon (struct frame
*, Lisp_Object
);
480 void x_make_frame_visible (struct frame
*);
482 extern void window_scroll (Lisp_Object
, int, int, int);
484 /* Defined in macmenu.h. */
485 extern void menubar_selection_callback (FRAME_PTR
, int);
486 extern void set_frame_menubar (FRAME_PTR
, int, int);
488 /* X display function emulation */
490 /* Structure borrowed from Xlib.h to represent two-byte characters in
499 XFreePixmap (display
, pixmap
)
503 PixMap
*p
= (PixMap
*) pixmap
;
510 /* Set foreground color for subsequent QuickDraw commands. Assume
511 graphic port has already been set. */
514 mac_set_forecolor (unsigned long color
)
518 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
519 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
520 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
522 RGBForeColor (&fg_color
);
526 /* Set background color for subsequent QuickDraw commands. Assume
527 graphic port has already been set. */
530 mac_set_backcolor (unsigned long color
)
534 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
535 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
536 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
538 RGBBackColor (&bg_color
);
541 /* Set foreground and background color for subsequent QuickDraw
542 commands. Assume that the graphic port has already been set. */
545 mac_set_colors (GC gc
)
547 mac_set_forecolor (gc
->foreground
);
548 mac_set_backcolor (gc
->background
);
551 /* Mac version of XDrawLine. */
554 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
560 #if TARGET_API_MAC_CARBON
561 SetPort (GetWindowPort (w
));
572 /* Mac version of XClearArea. */
575 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
579 unsigned int width
, height
;
582 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
586 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
587 xgc
.background
= mwp
->x_compatible
.background_pixel
;
589 #if TARGET_API_MAC_CARBON
590 SetPort (GetWindowPort (w
));
595 mac_set_colors (&xgc
);
596 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
601 /* Mac version of XClearWindow. */
604 XClearWindow (display
, w
)
608 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
611 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
612 xgc
.background
= mwp
->x_compatible
.background_pixel
;
614 #if TARGET_API_MAC_CARBON
615 SetPort (GetWindowPort (w
));
620 mac_set_colors (&xgc
);
622 #if TARGET_API_MAC_CARBON
626 GetWindowPortBounds (w
, &r
);
629 #else /* not TARGET_API_MAC_CARBON */
630 EraseRect (&(w
->portRect
));
631 #endif /* not TARGET_API_MAC_CARBON */
635 /* Mac replacement for XCopyArea. */
638 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
647 #if TARGET_API_MAC_CARBON
648 SetPort (GetWindowPort (w
));
654 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
656 #if TARGET_API_MAC_CARBON
660 LockPortBits (GetWindowPort (w
));
661 pmh
= GetPortPixMap (GetWindowPort (w
));
662 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
663 UnlockPortBits (GetWindowPort (w
));
665 #else /* not TARGET_API_MAC_CARBON */
666 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
667 #endif /* not TARGET_API_MAC_CARBON */
671 /* Mac replacement for XSetClipRectangles. */
674 mac_set_clip_rectangle (display
, w
, r
)
679 #if TARGET_API_MAC_CARBON
680 SetPort (GetWindowPort (w
));
689 /* Mac replacement for XSetClipMask. */
692 mac_reset_clipping (display
, w
)
698 #if TARGET_API_MAC_CARBON
699 SetPort (GetWindowPort (w
));
704 SetRect (&r
, -32767, -32767, 32767, 32767);
709 /* Mac replacement for XCreateBitmapFromBitmapData. */
712 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
717 int bytes_per_row
, i
, j
;
719 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
720 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
721 if (!bitmap
->baseAddr
)
724 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
725 for (i
= 0; i
< h
; i
++)
726 for (j
= 0; j
< w
; j
++)
727 if (BitTst (bits
, i
* w
+ j
))
728 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
730 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
735 mac_free_bitmap (bitmap
)
738 xfree (bitmap
->baseAddr
);
741 /* Mac replacement for XFillRectangle. */
744 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
749 unsigned int width
, height
;
753 #if TARGET_API_MAC_CARBON
754 SetPort (GetWindowPort (w
));
760 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
762 PaintRect (&r
); /* using foreground color of gc */
766 /* Mac replacement for XDrawRectangle: dest is a window. */
769 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
774 unsigned int width
, height
;
778 #if TARGET_API_MAC_CARBON
779 SetPort (GetWindowPort (w
));
785 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
787 FrameRect (&r
); /* using foreground color of gc */
791 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
794 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
799 unsigned int width
, height
;
801 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
804 #if TARGET_API_MAC_CARBON
805 SetPort (GetWindowPort (w
));
811 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
813 FrameRect (&r
); /* using foreground color of gc */
819 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
826 int nchars
, mode
, bytes_per_char
;
828 #if TARGET_API_MAC_CARBON
829 SetPort (GetWindowPort (w
));
836 TextFont (gc
->font
->mac_fontnum
);
837 TextSize (gc
->font
->mac_fontsize
);
838 TextFace (gc
->font
->mac_fontface
);
842 DrawText (buf
, 0, nchars
* bytes_per_char
);
846 /* Mac replacement for XDrawString. */
849 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
857 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
861 /* Mac replacement for XDrawString16. */
864 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
872 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
877 /* Mac replacement for XDrawImageString. */
880 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
888 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
892 /* Mac replacement for XDrawString16. */
895 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
903 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
908 /* Mac replacement for XCopyArea: dest must be window. */
911 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
918 unsigned int width
, height
;
923 #if TARGET_API_MAC_CARBON
924 SetPort (GetWindowPort (dest
));
931 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
932 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
934 #if TARGET_API_MAC_CARBON
938 LockPortBits (GetWindowPort (dest
));
939 pmh
= GetPortPixMap (GetWindowPort (dest
));
940 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
941 UnlockPortBits (GetWindowPort (dest
));
943 #else /* not TARGET_API_MAC_CARBON */
944 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
945 #endif /* not TARGET_API_MAC_CARBON */
950 /* Convert a pair of local coordinates to global (screen) coordinates.
951 Assume graphic port has been properly set. */
953 local_to_global_coord (short *h
, short *v
)
967 /* Mac replacement for XCopyArea: used only for scrolling. */
970 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
975 unsigned int width
, height
;
978 #if TARGET_API_MAC_CARBON
979 Rect gw_r
, src_r
, dest_r
;
982 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
983 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
985 SetPort (GetWindowPort (w
));
987 ForeColor (blackColor
);
988 BackColor (whiteColor
);
990 LockPortBits (GetWindowPort (w
));
991 pmh
= GetPortPixMap (GetWindowPort (w
));
992 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
993 UnlockPortBits (GetWindowPort (w
));
996 #else /* not TARGET_API_MAC_CARBON */
1001 mac_set_colors (gc
);
1004 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1005 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1008 /* Need to use global coordinates and screenBits since src and dest
1009 areas overlap in general. */
1010 local_to_global_coord (&src_r
.left
, &src_r
.top
);
1011 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
1012 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
1013 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
1015 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
1017 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1018 color mapping in CopyBits. Otherwise, it will be slow. */
1019 ForeColor (blackColor
);
1020 BackColor (whiteColor
);
1021 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1023 mac_set_colors (gc
);
1025 #endif /* not TARGET_API_MAC_CARBON */
1029 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1032 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1039 unsigned int width
, height
;
1043 int src_right
= ((PixMap
*) src
)->bounds
.right
;
1044 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
1045 int w
= src_right
- src_x
;
1046 int h
= src_bottom
- src_y
;
1048 mac_set_colors (gc
);
1050 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
1051 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
1053 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
1057 /* Mac replacement for XChangeGC. */
1060 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1063 if (mask
& GCForeground
)
1064 gc
->foreground
= xgcv
->foreground
;
1065 if (mask
& GCBackground
)
1066 gc
->background
= xgcv
->background
;
1068 gc
->font
= xgcv
->font
;
1072 /* Mac replacement for XCreateGC. */
1075 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1078 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1079 bzero (gc
, sizeof (XGCValues
));
1081 XChangeGC (ignore
, gc
, mask
, xgcv
);
1087 /* Used in xfaces.c. */
1090 XFreeGC (display
, gc
)
1098 /* Mac replacement for XGetGCValues. */
1101 XGetGCValues (void* ignore
, XGCValues
*gc
,
1102 unsigned long mask
, XGCValues
*xgcv
)
1104 XChangeGC (ignore
, xgcv
, mask
, gc
);
1108 /* Mac replacement for XSetForeground. */
1111 XSetForeground (display
, gc
, color
)
1114 unsigned long color
;
1116 gc
->foreground
= color
;
1120 /* Mac replacement for XSetFont. */
1123 XSetFont (display
, gc
, font
)
1133 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1134 int *direction
,int *font_ascent
,
1135 int *font_descent
, XCharStruct
*cs
)
1137 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1141 /* x_sync is a no-op on Mac. */
1149 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1150 Calls to XFlush should be unnecessary because the X output buffer
1151 is flushed automatically as needed by calls to XPending,
1152 XNextEvent, or XWindowEvent according to the XFlush man page.
1153 XTread_socket calls XPending. Removing XFlush improves
1156 #if TARGET_API_MAC_CARBON
1157 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1159 #define XFlush(DISPLAY) (void) 0
1162 /* Flush display of frame F, or of all frames if F is null. */
1168 #if TARGET_API_MAC_CARBON
1172 Lisp_Object rest
, frame
;
1173 FOR_EACH_FRAME (rest
, frame
)
1174 x_flush (XFRAME (frame
));
1176 else if (FRAME_X_P (f
))
1177 XFlush (FRAME_MAC_DISPLAY (f
));
1179 #endif /* TARGET_API_MAC_CARBON */
1184 /* Return the struct mac_display_info corresponding to DPY. There's
1187 struct mac_display_info
*
1188 mac_display_info_for_display (dpy
)
1191 return &one_mac_display_info
;
1196 /***********************************************************************
1197 Starting and ending an update
1198 ***********************************************************************/
1200 /* Start an update of frame F. This function is installed as a hook
1201 for update_begin, i.e. it is called when update_begin is called.
1202 This function is called prior to calls to x_update_window_begin for
1203 each window being updated. */
1209 /* Nothing to do. */
1213 /* Start update of window W. Set the global variable updated_window
1214 to the window being updated and set output_cursor to the cursor
1218 x_update_window_begin (w
)
1221 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1222 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1225 set_output_cursor (&w
->cursor
);
1229 if (f
== display_info
->mouse_face_mouse_frame
)
1231 /* Don't do highlighting for mouse motion during the update. */
1232 display_info
->mouse_face_defer
= 1;
1234 /* If F needs to be redrawn, simply forget about any prior mouse
1236 if (FRAME_GARBAGED_P (f
))
1237 display_info
->mouse_face_window
= Qnil
;
1239 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1240 their mouse_face_p flag set, which means that they are always
1241 unequal to rows in a desired matrix which never have that
1242 flag set. So, rows containing mouse-face glyphs are never
1243 scrolled, and we don't have to switch the mouse highlight off
1244 here to prevent it from being scrolled. */
1246 /* Can we tell that this update does not affect the window
1247 where the mouse highlight is? If so, no need to turn off.
1248 Likewise, don't do anything if the frame is garbaged;
1249 in that case, the frame's current matrix that we would use
1250 is all wrong, and we will redisplay that line anyway. */
1251 if (!NILP (display_info
->mouse_face_window
)
1252 && w
== XWINDOW (display_info
->mouse_face_window
))
1256 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1257 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1260 if (i
< w
->desired_matrix
->nrows
)
1261 clear_mouse_face (display_info
);
1270 /* Draw a vertical window border to the right of window W if W doesn't
1271 have vertical scroll bars. */
1274 x_draw_vertical_border (w
)
1277 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1279 /* Redraw borders between horizontally adjacent windows. Don't
1280 do it for frames with vertical scroll bars because either the
1281 right scroll bar of a window, or the left scroll bar of its
1282 neighbor will suffice as a border. */
1283 if (!WINDOW_RIGHTMOST_P (w
)
1284 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1288 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1289 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1292 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1293 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1298 /* End update of window W (which is equal to updated_window).
1300 Draw vertical borders between horizontally adjacent windows, and
1301 display W's cursor if CURSOR_ON_P is non-zero.
1303 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1304 glyphs in mouse-face were overwritten. In that case we have to
1305 make sure that the mouse-highlight is properly redrawn.
1307 W may be a menu bar pseudo-window in case we don't have X toolkit
1308 support. Such windows don't have a cursor, so don't display it
1312 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1314 int cursor_on_p
, mouse_face_overwritten_p
;
1316 struct mac_display_info
*dpyinfo
1317 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1319 if (!w
->pseudo_window_p
)
1324 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1326 output_cursor
.x
, output_cursor
.y
);
1328 x_draw_vertical_border (w
);
1332 /* If a row with mouse-face was overwritten, arrange for
1333 XTframe_up_to_date to redisplay the mouse highlight. */
1334 if (mouse_face_overwritten_p
)
1336 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1337 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1338 dpyinfo
->mouse_face_window
= Qnil
;
1342 /* Unhide the caret. This won't actually show the cursor, unless it
1343 was visible before the corresponding call to HideCaret in
1344 x_update_window_begin. */
1345 if (w32_use_visible_system_caret
)
1346 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1349 updated_window
= NULL
;
1353 /* End update of frame F. This function is installed as a hook in
1360 /* Reset the background color of Mac OS Window to that of the frame after
1361 update so that it is used by Mac Toolbox to clear the update region before
1362 an update event is generated. */
1363 #if TARGET_API_MAC_CARBON
1364 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1366 SetPort (FRAME_MAC_WINDOW (f
));
1369 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1371 /* Mouse highlight may be displayed again. */
1372 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1375 XFlush (FRAME_MAC_DISPLAY (f
));
1380 /* This function is called from various places in xdisp.c whenever a
1381 complete update has been performed. The global variable
1382 updated_window is not available here. */
1385 XTframe_up_to_date (f
)
1390 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1392 if (dpyinfo
->mouse_face_deferred_gc
1393 || f
== dpyinfo
->mouse_face_mouse_frame
)
1396 if (dpyinfo
->mouse_face_mouse_frame
)
1397 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1398 dpyinfo
->mouse_face_mouse_x
,
1399 dpyinfo
->mouse_face_mouse_y
);
1400 dpyinfo
->mouse_face_deferred_gc
= 0;
1407 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1408 arrow bitmaps, or clear the fringes if no bitmaps are required
1409 before DESIRED_ROW is made current. The window being updated is
1410 found in updated_window. This function is called from
1411 update_window_line only if it is known that there are differences
1412 between bitmaps to be drawn between current row and DESIRED_ROW. */
1415 x_after_update_window_line (desired_row
)
1416 struct glyph_row
*desired_row
;
1418 struct window
*w
= updated_window
;
1424 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1427 x_draw_row_fringe_bitmaps (w
, desired_row
);
1431 /* When a window has disappeared, make sure that no rest of
1432 full-width rows stays visible in the internal border. Could
1433 check here if updated_window is the leftmost/rightmost window,
1434 but I guess it's not worth doing since vertically split windows
1435 are almost never used, internal border is rarely set, and the
1436 overhead is very small. */
1437 if (windows_or_buffers_changed
1438 && desired_row
->full_width_p
1439 && (f
= XFRAME (w
->frame
),
1440 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1442 && (height
= desired_row
->visible_height
,
1445 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1446 /* Internal border is drawn below the tool bar. */
1447 if (WINDOWP (f
->tool_bar_window
)
1448 && w
== XWINDOW (f
->tool_bar_window
))
1453 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1454 0, y
, width
, height
, 0);
1455 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1456 f
->output_data
.mac
->pixel_width
- width
, y
,
1464 /* Draw the bitmap WHICH in one of the left or right fringes of
1465 window W. ROW is the glyph row for which to display the bitmap; it
1466 determines the vertical position at which the bitmap has to be
1470 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1472 struct glyph_row
*row
;
1473 enum fringe_bitmap_type which
;
1476 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1477 Display
*display
= FRAME_MAC_DISPLAY (f
);
1478 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1479 int x
, y
, wd
, h
, dy
;
1481 unsigned char *bits
;
1484 GC gc
= f
->output_data
.mac
->normal_gc
;
1487 /* Must clip because of partially visible lines. */
1488 x_clip_to_row (w
, row
, gc
, 1);
1490 /* Convert row to frame coordinates. */
1491 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1495 case NO_FRINGE_BITMAP
:
1500 case LEFT_TRUNCATION_BITMAP
:
1506 case OVERLAY_ARROW_BITMAP
:
1512 case RIGHT_TRUNCATION_BITMAP
:
1518 case CONTINUED_LINE_BITMAP
:
1519 wd
= continued_width
;
1520 h
= continued_height
;
1521 bits
= continued_bits
;
1524 case CONTINUATION_LINE_BITMAP
:
1525 wd
= continuation_width
;
1526 h
= continuation_height
;
1527 bits
= continuation_bits
;
1530 case ZV_LINE_BITMAP
:
1532 h
= zv_height
- (y
% zv_period
);
1533 bits
= zv_bits
+ (y
% zv_period
);
1540 /* Clip bitmap if too high. */
1541 if (h
> row
->height
)
1544 /* Set dy to the offset in the row to start drawing the bitmap. */
1545 dy
= (row
->height
- h
) / 2;
1547 /* Draw the bitmap. */
1548 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1549 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1551 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1556 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1557 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1558 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1560 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1561 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1563 /* If W has a vertical border to its left, don't draw over it. */
1564 int border
= ((XFASTINT (w
->left
) > 0
1565 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1567 b1
= (window_box_left (w
, -1)
1568 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1570 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1575 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1576 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1577 x
= (window_box_right (w
, -1)
1578 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1579 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1581 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1583 b1
= window_box_right (w
, -1);
1584 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1590 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1592 gcv
.foreground
= face
->background
;
1594 #if 0 /* MAC_TODO: stipple */
1595 /* In case the same realized face is used for fringes and
1596 for something displayed in the text (e.g. face `region' on
1597 mono-displays, the fill style may have been changed to
1598 FillSolid in x_draw_glyph_string_background. */
1600 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1602 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1605 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1608 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1611 row
->visible_height
);
1613 #if 0 /* MAC_TODO: stipple */
1615 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1619 if (which
== NO_FRINGE_BITMAP
)
1621 mac_reset_clipping (display
, window
);
1625 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1626 gcv
.foreground
= face
->foreground
;
1627 gcv
.background
= face
->background
;
1629 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1631 mac_free_bitmap (&bitmap
);
1632 mac_reset_clipping (display
, window
);
1636 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1637 function with input blocked. */
1640 x_draw_row_fringe_bitmaps (w
, row
)
1642 struct glyph_row
*row
;
1644 struct frame
*f
= XFRAME (w
->frame
);
1645 enum fringe_bitmap_type bitmap
;
1647 xassert (interrupt_input_blocked
);
1649 /* If row is completely invisible, because of vscrolling, we
1650 don't have to draw anything. */
1651 if (row
->visible_height
<= 0)
1654 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1656 /* Decide which bitmap to draw in the left fringe. */
1657 if (row
->overlay_arrow_p
)
1658 bitmap
= OVERLAY_ARROW_BITMAP
;
1659 else if (row
->truncated_on_left_p
)
1660 bitmap
= LEFT_TRUNCATION_BITMAP
;
1661 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1662 bitmap
= CONTINUATION_LINE_BITMAP
;
1663 else if (row
->indicate_empty_line_p
)
1664 bitmap
= ZV_LINE_BITMAP
;
1666 bitmap
= NO_FRINGE_BITMAP
;
1668 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1671 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1673 /* Decide which bitmap to draw in the right fringe. */
1674 if (row
->truncated_on_right_p
)
1675 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1676 else if (row
->continued_p
)
1677 bitmap
= CONTINUED_LINE_BITMAP
;
1678 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1679 bitmap
= ZV_LINE_BITMAP
;
1681 bitmap
= NO_FRINGE_BITMAP
;
1683 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1688 /* This is called when starting Emacs and when restarting after
1689 suspend. When starting Emacs, no window is mapped. And nothing
1690 must be done to Emacs's own window if it is suspended (though that
1694 XTset_terminal_modes ()
1698 /* This is called when exiting or suspending Emacs. Exiting will make
1699 the windows go away, and suspending requires no action. */
1702 XTreset_terminal_modes ()
1708 /***********************************************************************
1710 ***********************************************************************/
1712 /* Set the global variable output_cursor to CURSOR. All cursor
1713 positions are relative to updated_window. */
1716 set_output_cursor (cursor
)
1717 struct cursor_pos
*cursor
;
1719 output_cursor
.hpos
= cursor
->hpos
;
1720 output_cursor
.vpos
= cursor
->vpos
;
1721 output_cursor
.x
= cursor
->x
;
1722 output_cursor
.y
= cursor
->y
;
1726 /* Set a nominal cursor position.
1728 HPOS and VPOS are column/row positions in a window glyph matrix. X
1729 and Y are window text area relative pixel positions.
1731 If this is done during an update, updated_window will contain the
1732 window that is being updated and the position is the future output
1733 cursor position for that window. If updated_window is null, use
1734 selected_window and display the cursor at the given position. */
1737 XTcursor_to (vpos
, hpos
, y
, x
)
1738 int vpos
, hpos
, y
, x
;
1742 /* If updated_window is not set, work on selected_window. */
1746 w
= XWINDOW (selected_window
);
1748 /* Set the output cursor. */
1749 output_cursor
.hpos
= hpos
;
1750 output_cursor
.vpos
= vpos
;
1751 output_cursor
.x
= x
;
1752 output_cursor
.y
= y
;
1754 /* If not called as part of an update, really display the cursor.
1755 This will also set the cursor position of W. */
1756 if (updated_window
== NULL
)
1759 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1760 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1767 /***********************************************************************
1769 ***********************************************************************/
1771 /* Function prototypes of this page. */
1773 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1777 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1778 int, XChar2b
*, int));
1779 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1780 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1781 static void x_append_glyph
P_ ((struct it
*));
1782 static void x_append_composite_glyph
P_ ((struct it
*));
1783 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1785 static void x_produce_glyphs
P_ ((struct it
*));
1786 static void x_produce_image_glyph
P_ ((struct it
*it
));
1789 /* Return a pointer to per-char metric information in FONT of a
1790 character pointed by B which is a pointer to an XChar2b. */
1792 #define PER_CHAR_METRIC(font, b) \
1794 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1795 + (((font)->min_byte1 || (font)->max_byte1) \
1796 ? (((b)->byte1 - (font)->min_byte1) \
1797 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1799 : &((font)->max_bounds))
1802 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1803 is not contained in the font. */
1805 static INLINE XCharStruct
*
1806 x_per_char_metric (font
, char2b
)
1810 /* The result metric information. */
1811 XCharStruct
*pcm
= NULL
;
1813 xassert (font
&& char2b
);
1815 if (font
->per_char
!= NULL
)
1817 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1819 /* min_char_or_byte2 specifies the linear character index
1820 corresponding to the first element of the per_char array,
1821 max_char_or_byte2 is the index of the last character. A
1822 character with non-zero CHAR2B->byte1 is not in the font.
1823 A character with byte2 less than min_char_or_byte2 or
1824 greater max_char_or_byte2 is not in the font. */
1825 if (char2b
->byte1
== 0
1826 && char2b
->byte2
>= font
->min_char_or_byte2
1827 && char2b
->byte2
<= font
->max_char_or_byte2
)
1828 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1832 /* If either min_byte1 or max_byte1 are nonzero, both
1833 min_char_or_byte2 and max_char_or_byte2 are less than
1834 256, and the 2-byte character index values corresponding
1835 to the per_char array element N (counting from 0) are:
1837 byte1 = N/D + min_byte1
1838 byte2 = N\D + min_char_or_byte2
1842 D = max_char_or_byte2 - min_char_or_byte2 + 1
1843 / = integer division
1844 \ = integer modulus */
1845 if (char2b
->byte1
>= font
->min_byte1
1846 && char2b
->byte1
<= font
->max_byte1
1847 && char2b
->byte2
>= font
->min_char_or_byte2
1848 && char2b
->byte2
<= font
->max_char_or_byte2
)
1850 pcm
= (font
->per_char
1851 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1852 * (char2b
->byte1
- font
->min_byte1
))
1853 + (char2b
->byte2
- font
->min_char_or_byte2
));
1859 /* If the per_char pointer is null, all glyphs between the first
1860 and last character indexes inclusive have the same
1861 information, as given by both min_bounds and max_bounds. */
1862 if (char2b
->byte2
>= font
->min_char_or_byte2
1863 && char2b
->byte2
<= font
->max_char_or_byte2
)
1864 pcm
= &font
->max_bounds
;
1867 return ((pcm
== NULL
1868 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1873 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1874 the two-byte form of C. Encoding is returned in *CHAR2B. */
1877 x_encode_char (c
, char2b
, font_info
)
1880 struct font_info
*font_info
;
1882 int charset
= CHAR_CHARSET (c
);
1883 XFontStruct
*font
= font_info
->font
;
1885 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1886 This may be either a program in a special encoder language or a
1888 if (font_info
->font_encoder
)
1890 /* It's a program. */
1891 struct ccl_program
*ccl
= font_info
->font_encoder
;
1893 if (CHARSET_DIMENSION (charset
) == 1)
1895 ccl
->reg
[0] = charset
;
1896 ccl
->reg
[1] = char2b
->byte2
;
1900 ccl
->reg
[0] = charset
;
1901 ccl
->reg
[1] = char2b
->byte1
;
1902 ccl
->reg
[2] = char2b
->byte2
;
1905 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1907 /* We assume that MSBs are appropriately set/reset by CCL
1909 if (font
->max_byte1
== 0) /* 1-byte font */
1910 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1912 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1914 else if (font_info
->encoding
[charset
])
1916 /* Fixed encoding scheme. See fontset.h for the meaning of the
1917 encoding numbers. */
1918 int enc
= font_info
->encoding
[charset
];
1920 if ((enc
== 1 || enc
== 2)
1921 && CHARSET_DIMENSION (charset
) == 2)
1922 char2b
->byte1
|= 0x80;
1924 if (enc
== 1 || enc
== 3)
1925 char2b
->byte2
|= 0x80;
1931 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1932 char2b
->byte1
= sjis1
;
1933 char2b
->byte2
= sjis2
;
1939 /* Get face and two-byte form of character C in face FACE_ID on frame
1940 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1941 means we want to display multibyte text. Value is a pointer to a
1942 realized face that is ready for display. */
1944 static INLINE
struct face
*
1945 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1951 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1955 /* Unibyte case. We don't have to encode, but we have to make
1956 sure to use a face suitable for unibyte. */
1959 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1960 face
= FACE_FROM_ID (f
, face_id
);
1962 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1964 /* Case of ASCII in a face known to fit ASCII. */
1970 int c1
, c2
, charset
;
1972 /* Split characters into bytes. If c2 is -1 afterwards, C is
1973 really a one-byte character so that byte1 is zero. */
1974 SPLIT_CHAR (c
, charset
, c1
, c2
);
1976 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1978 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1980 /* Maybe encode the character in *CHAR2B. */
1981 if (face
->font
!= NULL
)
1983 struct font_info
*font_info
1984 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1986 x_encode_char (c
, char2b
, font_info
);
1990 /* Make sure X resources of the face are allocated. */
1991 xassert (face
!= NULL
);
1992 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1998 /* Get face and two-byte form of character glyph GLYPH on frame F.
1999 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
2000 a pointer to a realized face that is ready for display. */
2002 static INLINE
struct face
*
2003 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
2005 struct glyph
*glyph
;
2011 xassert (glyph
->type
== CHAR_GLYPH
);
2012 face
= FACE_FROM_ID (f
, glyph
->face_id
);
2017 if (!glyph
->multibyte_p
)
2019 /* Unibyte case. We don't have to encode, but we have to make
2020 sure to use a face suitable for unibyte. */
2022 char2b
->byte2
= glyph
->u
.ch
;
2024 else if (glyph
->u
.ch
< 128
2025 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
2027 /* Case of ASCII in a face known to fit ASCII. */
2029 char2b
->byte2
= glyph
->u
.ch
;
2033 int c1
, c2
, charset
;
2035 /* Split characters into bytes. If c2 is -1 afterwards, C is
2036 really a one-byte character so that byte1 is zero. */
2037 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
2039 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
2041 char2b
->byte1
= 0, char2b
->byte2
= c1
;
2043 /* Maybe encode the character in *CHAR2B. */
2044 if (charset
!= CHARSET_ASCII
)
2046 struct font_info
*font_info
2047 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2050 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
2053 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2058 /* Make sure X resources of the face are allocated. */
2059 xassert (face
!= NULL
);
2060 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2065 /* Store one glyph for IT->char_to_display in IT->glyph_row.
2066 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2072 struct glyph
*glyph
;
2073 enum glyph_row_area area
= it
->area
;
2075 xassert (it
->glyph_row
);
2076 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
2078 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2079 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2081 glyph
->charpos
= CHARPOS (it
->position
);
2082 glyph
->object
= it
->object
;
2083 glyph
->pixel_width
= it
->pixel_width
;
2084 glyph
->voffset
= it
->voffset
;
2085 glyph
->type
= CHAR_GLYPH
;
2086 glyph
->multibyte_p
= it
->multibyte_p
;
2087 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2088 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2089 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2090 || it
->phys_descent
> it
->descent
);
2091 glyph
->padding_p
= 0;
2092 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
2093 glyph
->face_id
= it
->face_id
;
2094 glyph
->u
.ch
= it
->char_to_display
;
2095 ++it
->glyph_row
->used
[area
];
2099 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
2100 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2103 x_append_composite_glyph (it
)
2106 struct glyph
*glyph
;
2107 enum glyph_row_area area
= it
->area
;
2109 xassert (it
->glyph_row
);
2111 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2112 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2114 glyph
->charpos
= CHARPOS (it
->position
);
2115 glyph
->object
= it
->object
;
2116 glyph
->pixel_width
= it
->pixel_width
;
2117 glyph
->voffset
= it
->voffset
;
2118 glyph
->type
= COMPOSITE_GLYPH
;
2119 glyph
->multibyte_p
= it
->multibyte_p
;
2120 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2121 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2122 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2123 || it
->phys_descent
> it
->descent
);
2124 glyph
->padding_p
= 0;
2125 glyph
->glyph_not_available_p
= 0;
2126 glyph
->face_id
= it
->face_id
;
2127 glyph
->u
.cmp_id
= it
->cmp_id
;
2128 ++it
->glyph_row
->used
[area
];
2133 /* Change IT->ascent and IT->height according to the setting of
2137 take_vertical_position_into_account (it
)
2142 if (it
->voffset
< 0)
2143 /* Increase the ascent so that we can display the text higher
2145 it
->ascent
+= abs (it
->voffset
);
2147 /* Increase the descent so that we can display the text lower
2149 it
->descent
+= it
->voffset
;
2154 /* Produce glyphs/get display metrics for the image IT is loaded with.
2155 See the description of struct display_iterator in dispextern.h for
2156 an overview of struct display_iterator. */
2159 x_produce_image_glyph (it
)
2165 xassert (it
->what
== IT_IMAGE
);
2167 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2168 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2171 /* Make sure X resources of the face and image are loaded. */
2172 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2173 prepare_image_for_display (it
->f
, img
);
2175 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2176 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2177 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2181 if (face
->box
!= FACE_NO_BOX
)
2183 if (face
->box_line_width
> 0)
2185 it
->ascent
+= face
->box_line_width
;
2186 it
->descent
+= face
->box_line_width
;
2189 if (it
->start_of_box_run_p
)
2190 it
->pixel_width
+= abs (face
->box_line_width
);
2191 if (it
->end_of_box_run_p
)
2192 it
->pixel_width
+= abs (face
->box_line_width
);
2195 take_vertical_position_into_account (it
);
2199 struct glyph
*glyph
;
2200 enum glyph_row_area area
= it
->area
;
2202 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2203 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2205 glyph
->charpos
= CHARPOS (it
->position
);
2206 glyph
->object
= it
->object
;
2207 glyph
->pixel_width
= it
->pixel_width
;
2208 glyph
->voffset
= it
->voffset
;
2209 glyph
->type
= IMAGE_GLYPH
;
2210 glyph
->multibyte_p
= it
->multibyte_p
;
2211 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2212 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2213 glyph
->overlaps_vertically_p
= 0;
2214 glyph
->padding_p
= 0;
2215 glyph
->glyph_not_available_p
= 0;
2216 glyph
->face_id
= it
->face_id
;
2217 glyph
->u
.img_id
= img
->id
;
2218 ++it
->glyph_row
->used
[area
];
2224 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2225 of the glyph, WIDTH and HEIGHT are the width and height of the
2226 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2227 ascent of the glyph (0 <= ASCENT <= 1). */
2230 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2236 struct glyph
*glyph
;
2237 enum glyph_row_area area
= it
->area
;
2239 xassert (ascent
>= 0 && ascent
<= 1);
2241 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2242 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2244 glyph
->charpos
= CHARPOS (it
->position
);
2245 glyph
->object
= object
;
2246 glyph
->pixel_width
= width
;
2247 glyph
->voffset
= it
->voffset
;
2248 glyph
->type
= STRETCH_GLYPH
;
2249 glyph
->multibyte_p
= it
->multibyte_p
;
2250 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2251 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2252 glyph
->overlaps_vertically_p
= 0;
2253 glyph
->padding_p
= 0;
2254 glyph
->glyph_not_available_p
= 0;
2255 glyph
->face_id
= it
->face_id
;
2256 glyph
->u
.stretch
.ascent
= height
* ascent
;
2257 glyph
->u
.stretch
.height
= height
;
2258 ++it
->glyph_row
->used
[area
];
2263 /* Produce a stretch glyph for iterator IT. IT->object is the value
2264 of the glyph property displayed. The value must be a list
2265 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2268 1. `:width WIDTH' specifies that the space should be WIDTH *
2269 canonical char width wide. WIDTH may be an integer or floating
2272 2. `:relative-width FACTOR' specifies that the width of the stretch
2273 should be computed from the width of the first character having the
2274 `glyph' property, and should be FACTOR times that width.
2276 3. `:align-to HPOS' specifies that the space should be wide enough
2277 to reach HPOS, a value in canonical character units.
2279 Exactly one of the above pairs must be present.
2281 4. `:height HEIGHT' specifies that the height of the stretch produced
2282 should be HEIGHT, measured in canonical character units.
2284 5. `:relative-height FACTOR' specifies that the height of the
2285 stretch should be FACTOR times the height of the characters having
2288 Either none or exactly one of 4 or 5 must be present.
2290 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2291 of the stretch should be used for the ascent of the stretch.
2292 ASCENT must be in the range 0 <= ASCENT <= 100. */
2295 ((INTEGERP (X) || FLOATP (X)) \
2301 x_produce_stretch_glyph (it
)
2304 /* (space :width WIDTH :height HEIGHT. */
2306 extern Lisp_Object Qspace
;
2308 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2309 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2310 extern Lisp_Object QCalign_to
;
2311 Lisp_Object prop
, plist
;
2312 double width
= 0, height
= 0, ascent
= 0;
2313 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2314 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2316 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2318 /* List should start with `space'. */
2319 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2320 plist
= XCDR (it
->object
);
2322 /* Compute the width of the stretch. */
2323 if (prop
= Fplist_get (plist
, QCwidth
),
2325 /* Absolute width `:width WIDTH' specified and valid. */
2326 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2327 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2330 /* Relative width `:relative-width FACTOR' specified and valid.
2331 Compute the width of the characters having the `glyph'
2334 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2337 if (it
->multibyte_p
)
2339 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2340 - IT_BYTEPOS (*it
));
2341 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2344 it2
.c
= *p
, it2
.len
= 1;
2346 it2
.glyph_row
= NULL
;
2347 it2
.what
= IT_CHARACTER
;
2348 x_produce_glyphs (&it2
);
2349 width
= NUMVAL (prop
) * it2
.pixel_width
;
2351 else if (prop
= Fplist_get (plist
, QCalign_to
),
2353 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2355 /* Nothing specified -> width defaults to canonical char width. */
2356 width
= CANON_X_UNIT (it
->f
);
2358 /* Compute height. */
2359 if (prop
= Fplist_get (plist
, QCheight
),
2361 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2362 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2364 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2366 height
= FONT_HEIGHT (font
);
2368 /* Compute percentage of height used for ascent. If
2369 `:ascent ASCENT' is present and valid, use that. Otherwise,
2370 derive the ascent from the font in use. */
2371 if (prop
= Fplist_get (plist
, QCascent
),
2372 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2373 ascent
= NUMVAL (prop
) / 100.0;
2375 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2384 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2385 if (!STRINGP (object
))
2386 object
= it
->w
->buffer
;
2387 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2390 it
->pixel_width
= width
;
2391 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2392 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2395 if (face
->box
!= FACE_NO_BOX
)
2397 if (face
->box_line_width
> 0)
2399 it
->ascent
+= face
->box_line_width
;
2400 it
->descent
+= face
->box_line_width
;
2403 if (it
->start_of_box_run_p
)
2404 it
->pixel_width
+= abs (face
->box_line_width
);
2405 if (it
->end_of_box_run_p
)
2406 it
->pixel_width
+= abs (face
->box_line_width
);
2409 take_vertical_position_into_account (it
);
2412 /* Return proper value to be used as baseline offset of font that has
2413 ASCENT and DESCENT to draw characters by the font at the vertical
2414 center of the line of frame F.
2416 Here, out task is to find the value of BOFF in the following figure;
2418 -------------------------+-----------+-
2419 -+-+---------+-+ | |
2421 | | | | F_ASCENT F_HEIGHT
2424 | | |-|-+------+-----------|------- baseline
2426 | |---------|-+-+ | |
2428 -+-+---------+-+ F_DESCENT |
2429 -------------------------+-----------+-
2431 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2432 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2433 DESCENT = FONT->descent
2434 HEIGHT = FONT_HEIGHT (FONT)
2435 F_DESCENT = (F->output_data.x->font->descent
2436 - F->output_data.x->baseline_offset)
2437 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2440 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2441 (FONT_DESCENT (FONT) \
2442 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2443 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2444 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2446 /* Produce glyphs/get display metrics for the display element IT is
2447 loaded with. See the description of struct display_iterator in
2448 dispextern.h for an overview of struct display_iterator. */
2451 x_produce_glyphs (it
)
2454 it
->glyph_not_available_p
= 0;
2456 if (it
->what
== IT_CHARACTER
)
2460 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2462 int font_not_found_p
;
2463 struct font_info
*font_info
;
2464 int boff
; /* baseline offset */
2465 /* We may change it->multibyte_p upon unibyte<->multibyte
2466 conversion. So, save the current value now and restore it
2469 Note: It seems that we don't have to record multibyte_p in
2470 struct glyph because the character code itself tells if or
2471 not the character is multibyte. Thus, in the future, we must
2472 consider eliminating the field `multibyte_p' in the struct
2475 int saved_multibyte_p
= it
->multibyte_p
;
2477 /* Maybe translate single-byte characters to multibyte, or the
2479 it
->char_to_display
= it
->c
;
2480 if (!ASCII_BYTE_P (it
->c
))
2482 if (unibyte_display_via_language_environment
2483 && SINGLE_BYTE_CHAR_P (it
->c
)
2485 || !NILP (Vnonascii_translation_table
)))
2487 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2488 it
->multibyte_p
= 1;
2489 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2490 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2492 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2493 && !it
->multibyte_p
)
2495 it
->multibyte_p
= 1;
2496 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2497 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2501 /* Get font to use. Encode IT->char_to_display. */
2502 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2503 it
->face_id
, &char2b
,
2507 /* When no suitable font found, use the default font. */
2508 font_not_found_p
= font
== NULL
;
2509 if (font_not_found_p
)
2511 font
= FRAME_FONT (it
->f
);
2512 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2517 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2518 boff
= font_info
->baseline_offset
;
2519 if (font_info
->vertical_centering
)
2520 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2523 if (it
->char_to_display
>= ' '
2524 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2526 /* Either unibyte or ASCII. */
2531 pcm
= x_per_char_metric (font
, &char2b
);
2532 it
->ascent
= FONT_BASE (font
) + boff
;
2533 it
->descent
= FONT_DESCENT (font
) - boff
;
2537 it
->phys_ascent
= pcm
->ascent
+ boff
;
2538 it
->phys_descent
= pcm
->descent
- boff
;
2539 it
->pixel_width
= pcm
->width
;
2543 it
->glyph_not_available_p
= 1;
2544 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2545 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2546 it
->pixel_width
= FONT_WIDTH (font
);
2549 /* If this is a space inside a region of text with
2550 `space-width' property, change its width. */
2551 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2553 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2555 /* If face has a box, add the box thickness to the character
2556 height. If character has a box line to the left and/or
2557 right, add the box line width to the character's width. */
2558 if (face
->box
!= FACE_NO_BOX
)
2560 int thick
= face
->box_line_width
;
2564 it
->ascent
+= thick
;
2565 it
->descent
+= thick
;
2570 if (it
->start_of_box_run_p
)
2571 it
->pixel_width
+= thick
;
2572 if (it
->end_of_box_run_p
)
2573 it
->pixel_width
+= thick
;
2576 /* If face has an overline, add the height of the overline
2577 (1 pixel) and a 1 pixel margin to the character height. */
2578 if (face
->overline_p
)
2581 take_vertical_position_into_account (it
);
2583 /* If we have to actually produce glyphs, do it. */
2588 /* Translate a space with a `space-width' property
2589 into a stretch glyph. */
2590 double ascent
= (double) FONT_BASE (font
)
2591 / FONT_HEIGHT (font
);
2592 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2593 it
->ascent
+ it
->descent
, ascent
);
2596 x_append_glyph (it
);
2598 /* If characters with lbearing or rbearing are displayed
2599 in this line, record that fact in a flag of the
2600 glyph row. This is used to optimize X output code. */
2601 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2602 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2605 else if (it
->char_to_display
== '\n')
2607 /* A newline has no width but we need the height of the line. */
2608 it
->pixel_width
= 0;
2610 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2611 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2613 if (face
->box
!= FACE_NO_BOX
2614 && face
->box_line_width
> 0)
2616 it
->ascent
+= face
->box_line_width
;
2617 it
->descent
+= face
->box_line_width
;
2620 else if (it
->char_to_display
== '\t')
2622 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2623 int x
= it
->current_x
+ it
->continuation_lines_width
;
2624 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2626 /* If the distance from the current position to the next tab
2627 stop is less than a canonical character width, use the
2628 tab stop after that. */
2629 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2630 next_tab_x
+= tab_width
;
2632 it
->pixel_width
= next_tab_x
- x
;
2634 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2635 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2639 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2640 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2641 it
->ascent
+ it
->descent
, ascent
);
2646 /* A multi-byte character. Assume that the display width of the
2647 character is the width of the character multiplied by the
2648 width of the font. */
2650 /* If we found a font, this font should give us the right
2651 metrics. If we didn't find a font, use the frame's
2652 default font and calculate the width of the character
2653 from the charset width; this is what old redisplay code
2655 pcm
= x_per_char_metric (font
, &char2b
);
2656 if (font_not_found_p
|| !pcm
)
2658 int charset
= CHAR_CHARSET (it
->char_to_display
);
2660 it
->glyph_not_available_p
= 1;
2661 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2662 * CHARSET_WIDTH (charset
));
2663 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2664 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2668 it
->pixel_width
= pcm
->width
;
2669 it
->phys_ascent
= pcm
->ascent
+ boff
;
2670 it
->phys_descent
= pcm
->descent
- boff
;
2672 && (pcm
->lbearing
< 0
2673 || pcm
->rbearing
> pcm
->width
))
2674 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2677 it
->ascent
= FONT_BASE (font
) + boff
;
2678 it
->descent
= FONT_DESCENT (font
) - boff
;
2679 if (face
->box
!= FACE_NO_BOX
)
2681 int thick
= face
->box_line_width
;
2685 it
->ascent
+= thick
;
2686 it
->descent
+= thick
;
2691 if (it
->start_of_box_run_p
)
2692 it
->pixel_width
+= thick
;
2693 if (it
->end_of_box_run_p
)
2694 it
->pixel_width
+= thick
;
2697 /* If face has an overline, add the height of the overline
2698 (1 pixel) and a 1 pixel margin to the character height. */
2699 if (face
->overline_p
)
2702 take_vertical_position_into_account (it
);
2705 x_append_glyph (it
);
2707 it
->multibyte_p
= saved_multibyte_p
;
2709 else if (it
->what
== IT_COMPOSITION
)
2711 /* Note: A composition is represented as one glyph in the
2712 glyph matrix. There are no padding glyphs. */
2715 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2717 int font_not_found_p
;
2718 struct font_info
*font_info
;
2719 int boff
; /* baseline offset */
2720 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2722 /* Maybe translate single-byte characters to multibyte. */
2723 it
->char_to_display
= it
->c
;
2724 if (unibyte_display_via_language_environment
2725 && SINGLE_BYTE_CHAR_P (it
->c
)
2728 && !NILP (Vnonascii_translation_table
))))
2730 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2733 /* Get face and font to use. Encode IT->char_to_display. */
2734 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2735 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2736 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2737 it
->face_id
, &char2b
, it
->multibyte_p
);
2740 /* When no suitable font found, use the default font. */
2741 font_not_found_p
= font
== NULL
;
2742 if (font_not_found_p
)
2744 font
= FRAME_FONT (it
->f
);
2745 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2750 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2751 boff
= font_info
->baseline_offset
;
2752 if (font_info
->vertical_centering
)
2753 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2756 /* There are no padding glyphs, so there is only one glyph to
2757 produce for the composition. Important is that pixel_width,
2758 ascent and descent are the values of what is drawn by
2759 draw_glyphs (i.e. the values of the overall glyphs composed). */
2762 /* If we have not yet calculated pixel size data of glyphs of
2763 the composition for the current face font, calculate them
2764 now. Theoretically, we have to check all fonts for the
2765 glyphs, but that requires much time and memory space. So,
2766 here we check only the font of the first glyph. This leads
2767 to incorrect display very rarely, and C-l (recenter) can
2768 correct the display anyway. */
2769 if (cmp
->font
!= (void *) font
)
2771 /* Ascent and descent of the font of the first character of
2772 this composition (adjusted by baseline offset). Ascent
2773 and descent of overall glyphs should not be less than
2774 them respectively. */
2775 int font_ascent
= FONT_BASE (font
) + boff
;
2776 int font_descent
= FONT_DESCENT (font
) - boff
;
2777 /* Bounding box of the overall glyphs. */
2778 int leftmost
, rightmost
, lowest
, highest
;
2779 int i
, width
, ascent
, descent
;
2781 cmp
->font
= (void *) font
;
2783 /* Initialize the bounding box. */
2784 pcm
= x_per_char_metric (font
, &char2b
);
2788 ascent
= pcm
->ascent
;
2789 descent
= pcm
->descent
;
2793 width
= FONT_WIDTH (font
);
2794 ascent
= FONT_BASE (font
);
2795 descent
= FONT_DESCENT (font
);
2799 lowest
= - descent
+ boff
;
2800 highest
= ascent
+ boff
;
2804 && font_info
->default_ascent
2805 && CHAR_TABLE_P (Vuse_default_ascent
)
2806 && !NILP (Faref (Vuse_default_ascent
,
2807 make_number (it
->char_to_display
))))
2808 highest
= font_info
->default_ascent
+ boff
;
2810 /* Draw the first glyph at the normal position. It may be
2811 shifted to right later if some other glyphs are drawn at
2813 cmp
->offsets
[0] = 0;
2814 cmp
->offsets
[1] = boff
;
2816 /* Set cmp->offsets for the remaining glyphs. */
2817 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2819 int left
, right
, btm
, top
;
2820 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2821 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2823 face
= FACE_FROM_ID (it
->f
, face_id
);
2824 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2829 font
= FRAME_FONT (it
->f
);
2830 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2836 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2837 boff
= font_info
->baseline_offset
;
2838 if (font_info
->vertical_centering
)
2839 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2842 pcm
= x_per_char_metric (font
, &char2b
);
2846 ascent
= pcm
->ascent
;
2847 descent
= pcm
->descent
;
2851 width
= FONT_WIDTH (font
);
2856 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2858 /* Relative composition with or without
2860 left
= (leftmost
+ rightmost
- width
) / 2;
2861 btm
= - descent
+ boff
;
2862 if (font_info
&& font_info
->relative_compose
2863 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2864 || NILP (Faref (Vignore_relative_composition
,
2865 make_number (ch
)))))
2868 if (- descent
>= font_info
->relative_compose
)
2869 /* One extra pixel between two glyphs. */
2871 else if (ascent
<= 0)
2872 /* One extra pixel between two glyphs. */
2873 btm
= lowest
- 1 - ascent
- descent
;
2878 /* A composition rule is specified by an integer
2879 value that encodes global and new reference
2880 points (GREF and NREF). GREF and NREF are
2881 specified by numbers as below:
2889 ---3---4---5--- baseline
2891 6---7---8 -- descent
2893 int rule
= COMPOSITION_RULE (cmp
, i
);
2894 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2896 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2897 grefx
= gref
% 3, nrefx
= nref
% 3;
2898 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2901 + grefx
* (rightmost
- leftmost
) / 2
2902 - nrefx
* width
/ 2);
2903 btm
= ((grefy
== 0 ? highest
2905 : grefy
== 2 ? lowest
2906 : (highest
+ lowest
) / 2)
2907 - (nrefy
== 0 ? ascent
+ descent
2908 : nrefy
== 1 ? descent
- boff
2910 : (ascent
+ descent
) / 2));
2913 cmp
->offsets
[i
* 2] = left
;
2914 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2916 /* Update the bounding box of the overall glyphs. */
2917 right
= left
+ width
;
2918 top
= btm
+ descent
+ ascent
;
2919 if (left
< leftmost
)
2921 if (right
> rightmost
)
2929 /* If there are glyphs whose x-offsets are negative,
2930 shift all glyphs to the right and make all x-offsets
2934 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2935 cmp
->offsets
[i
* 2] -= leftmost
;
2936 rightmost
-= leftmost
;
2939 cmp
->pixel_width
= rightmost
;
2940 cmp
->ascent
= highest
;
2941 cmp
->descent
= - lowest
;
2942 if (cmp
->ascent
< font_ascent
)
2943 cmp
->ascent
= font_ascent
;
2944 if (cmp
->descent
< font_descent
)
2945 cmp
->descent
= font_descent
;
2948 it
->pixel_width
= cmp
->pixel_width
;
2949 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2950 it
->descent
= it
->phys_descent
= cmp
->descent
;
2952 if (face
->box
!= FACE_NO_BOX
)
2954 int thick
= face
->box_line_width
;
2958 it
->ascent
+= thick
;
2959 it
->descent
+= thick
;
2964 if (it
->start_of_box_run_p
)
2965 it
->pixel_width
+= thick
;
2966 if (it
->end_of_box_run_p
)
2967 it
->pixel_width
+= thick
;
2970 /* If face has an overline, add the height of the overline
2971 (1 pixel) and a 1 pixel margin to the character height. */
2972 if (face
->overline_p
)
2975 take_vertical_position_into_account (it
);
2978 x_append_composite_glyph (it
);
2980 else if (it
->what
== IT_IMAGE
)
2981 x_produce_image_glyph (it
);
2982 else if (it
->what
== IT_STRETCH
)
2983 x_produce_stretch_glyph (it
);
2985 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2986 because this isn't true for images with `:ascent 100'. */
2987 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2988 if (it
->area
== TEXT_AREA
)
2989 it
->current_x
+= it
->pixel_width
;
2991 it
->descent
+= it
->extra_line_spacing
;
2993 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2994 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2995 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2996 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
3000 /* Estimate the pixel height of the mode or top line on frame F.
3001 FACE_ID specifies what line's height to estimate. */
3004 x_estimate_mode_line_height (f
, face_id
)
3006 enum face_id face_id
;
3008 int height
= FONT_HEIGHT (FRAME_FONT (f
));
3010 /* This function is called so early when Emacs starts that the face
3011 cache and mode line face are not yet initialized. */
3012 if (FRAME_FACE_CACHE (f
))
3014 struct face
*face
= FACE_FROM_ID (f
, face_id
);
3018 height
= FONT_HEIGHT (face
->font
);
3019 if (face
->box_line_width
> 0)
3020 height
+= 2 * face
->box_line_width
;
3028 /***********************************************************************
3030 ***********************************************************************/
3032 /* A sequence of glyphs to be drawn in the same face.
3034 This data structure is not really completely X specific, so it
3035 could possibly, at least partially, be useful for other systems. It
3036 is currently not part of the external redisplay interface because
3037 it's not clear what other systems will need. */
3041 /* X-origin of the string. */
3044 /* Y-origin and y-position of the base line of this string. */
3047 /* The width of the string, not including a face extension. */
3050 /* The width of the string, including a face extension. */
3051 int background_width
;
3053 /* The height of this string. This is the height of the line this
3054 string is drawn in, and can be different from the height of the
3055 font the string is drawn in. */
3058 /* Number of pixels this string overwrites in front of its x-origin.
3059 This number is zero if the string has an lbearing >= 0; it is
3060 -lbearing, if the string has an lbearing < 0. */
3063 /* Number of pixels this string overwrites past its right-most
3064 nominal x-position, i.e. x + width. Zero if the string's
3065 rbearing is <= its nominal width, rbearing - width otherwise. */
3068 /* The frame on which the glyph string is drawn. */
3071 /* The window on which the glyph string is drawn. */
3074 /* X display and window for convenience. */
3078 /* The glyph row for which this string was built. It determines the
3079 y-origin and height of the string. */
3080 struct glyph_row
*row
;
3082 /* The area within row. */
3083 enum glyph_row_area area
;
3085 /* Characters to be drawn, and number of characters. */
3089 /* A face-override for drawing cursors, mouse face and similar. */
3090 enum draw_glyphs_face hl
;
3092 /* Face in which this string is to be drawn. */
3095 /* Font in which this string is to be drawn. */
3098 /* Font info for this string. */
3099 struct font_info
*font_info
;
3101 /* Non-null means this string describes (part of) a composition.
3102 All characters from char2b are drawn composed. */
3103 struct composition
*cmp
;
3105 /* Index of this glyph string's first character in the glyph
3106 definition of CMP. If this is zero, this glyph string describes
3107 the first character of a composition. */
3110 /* 1 means this glyph strings face has to be drawn to the right end
3111 of the window's drawing area. */
3112 unsigned extends_to_end_of_line_p
: 1;
3114 /* 1 means the background of this string has been drawn. */
3115 unsigned background_filled_p
: 1;
3117 /* 1 means glyph string must be drawn with 16-bit functions. */
3118 unsigned two_byte_p
: 1;
3120 /* 1 means that the original font determined for drawing this glyph
3121 string could not be loaded. The member `font' has been set to
3122 the frame's default font in this case. */
3123 unsigned font_not_found_p
: 1;
3125 /* 1 means that the face in which this glyph string is drawn has a
3127 unsigned stippled_p
: 1;
3129 /* 1 means only the foreground of this glyph string must be drawn,
3130 and we should use the physical height of the line this glyph
3131 string appears in as clip rect. */
3132 unsigned for_overlaps_p
: 1;
3134 /* The GC to use for drawing this glyph string. */
3137 /* A pointer to the first glyph in the string. This glyph
3138 corresponds to char2b[0]. Needed to draw rectangles if
3139 font_not_found_p is 1. */
3140 struct glyph
*first_glyph
;
3142 /* Image, if any. */
3145 struct glyph_string
*next
, *prev
;
3152 x_dump_glyph_string (s
)
3153 struct glyph_string
*s
;
3155 fprintf (stderr
, "glyph string\n");
3156 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
3157 s
->x
, s
->y
, s
->width
, s
->height
);
3158 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
3159 fprintf (stderr
, " hl = %d\n", s
->hl
);
3160 fprintf (stderr
, " left overhang = %d, right = %d\n",
3161 s
->left_overhang
, s
->right_overhang
);
3162 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
3163 fprintf (stderr
, " extends to end of line = %d\n",
3164 s
->extends_to_end_of_line_p
);
3165 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
3166 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
3169 #endif /* GLYPH_DEBUG */
3173 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
3174 struct glyph_string
**,
3175 struct glyph_string
*,
3176 struct glyph_string
*));
3177 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
3178 struct glyph_string
**,
3179 struct glyph_string
*,
3180 struct glyph_string
*));
3181 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3182 struct glyph_string
**,
3183 struct glyph_string
*));
3184 static int x_left_overwritten
P_ ((struct glyph_string
*));
3185 static int x_left_overwriting
P_ ((struct glyph_string
*));
3186 static int x_right_overwritten
P_ ((struct glyph_string
*));
3187 static int x_right_overwriting
P_ ((struct glyph_string
*));
3188 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3190 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3191 XChar2b
*, struct window
*,
3193 enum glyph_row_area
, int,
3194 enum draw_glyphs_face
));
3195 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3196 enum glyph_row_area
, int, int,
3197 enum draw_glyphs_face
, int));
3198 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3199 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3200 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3202 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3203 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3204 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3205 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3206 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3207 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3208 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3209 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3210 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3212 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3213 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
3214 unsigned long *, double, int));*/
3215 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3216 double, int, unsigned long));
3217 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3218 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3219 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3220 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3221 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3222 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3223 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3225 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3226 int, int, int, int, Rect
*));
3227 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3228 int, int, int, Rect
*));
3229 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3230 enum glyph_row_area
));
3231 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3233 enum glyph_row_area
, int, int));
3236 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3240 /* Append the list of glyph strings with head H and tail T to the list
3241 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3244 x_append_glyph_string_lists (head
, tail
, h
, t
)
3245 struct glyph_string
**head
, **tail
;
3246 struct glyph_string
*h
, *t
;
3260 /* Prepend the list of glyph strings with head H and tail T to the
3261 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3265 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3266 struct glyph_string
**head
, **tail
;
3267 struct glyph_string
*h
, *t
;
3281 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3282 Set *HEAD and *TAIL to the resulting list. */
3285 x_append_glyph_string (head
, tail
, s
)
3286 struct glyph_string
**head
, **tail
;
3287 struct glyph_string
*s
;
3289 s
->next
= s
->prev
= NULL
;
3290 x_append_glyph_string_lists (head
, tail
, s
, s
);
3294 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3299 struct glyph_string
*s
;
3301 if (s
->font
== FRAME_FONT (s
->f
)
3302 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3303 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3305 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3308 /* Cursor on non-default face: must merge. */
3312 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3313 xgcv
.foreground
= s
->face
->background
;
3315 /* If the glyph would be invisible, try a different foreground. */
3316 if (xgcv
.foreground
== xgcv
.background
)
3317 xgcv
.foreground
= s
->face
->foreground
;
3318 if (xgcv
.foreground
== xgcv
.background
)
3319 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3320 if (xgcv
.foreground
== xgcv
.background
)
3321 xgcv
.foreground
= s
->face
->foreground
;
3323 /* Make sure the cursor is distinct from text in this face. */
3324 if (xgcv
.background
== s
->face
->background
3325 && xgcv
.foreground
== s
->face
->foreground
)
3327 xgcv
.background
= s
->face
->foreground
;
3328 xgcv
.foreground
= s
->face
->background
;
3331 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3332 xgcv
.font
= s
->font
;
3333 mask
= GCForeground
| GCBackground
| GCFont
;
3335 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3336 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3339 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3340 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3342 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3347 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3350 x_set_mouse_face_gc (s
)
3351 struct glyph_string
*s
;
3356 /* What face has to be used last for the mouse face? */
3357 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3358 face
= FACE_FROM_ID (s
->f
, face_id
);
3360 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3362 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3363 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3365 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3366 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3367 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3369 /* If font in this face is same as S->font, use it. */
3370 if (s
->font
== s
->face
->font
)
3371 s
->gc
= s
->face
->gc
;
3374 /* Otherwise construct scratch_cursor_gc with values from FACE
3379 xgcv
.background
= s
->face
->background
;
3380 xgcv
.foreground
= s
->face
->foreground
;
3381 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3382 xgcv
.font
= s
->font
;
3383 mask
= GCForeground
| GCBackground
| GCFont
;
3385 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3386 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3389 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3390 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3392 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3395 xassert (s
->gc
!= 0);
3399 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3400 Faces to use in the mode line have already been computed when the
3401 matrix was built, so there isn't much to do, here. */
3404 x_set_mode_line_face_gc (s
)
3405 struct glyph_string
*s
;
3407 s
->gc
= s
->face
->gc
;
3411 /* Set S->gc of glyph string S for drawing that glyph string. Set
3412 S->stippled_p to a non-zero value if the face of S has a stipple
3416 x_set_glyph_string_gc (s
)
3417 struct glyph_string
*s
;
3419 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3421 if (s
->hl
== DRAW_NORMAL_TEXT
)
3423 s
->gc
= s
->face
->gc
;
3424 s
->stippled_p
= s
->face
->stipple
!= 0;
3426 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3428 x_set_mode_line_face_gc (s
);
3429 s
->stippled_p
= s
->face
->stipple
!= 0;
3431 else if (s
->hl
== DRAW_CURSOR
)
3433 x_set_cursor_gc (s
);
3436 else if (s
->hl
== DRAW_MOUSE_FACE
)
3438 x_set_mouse_face_gc (s
);
3439 s
->stippled_p
= s
->face
->stipple
!= 0;
3441 else if (s
->hl
== DRAW_IMAGE_RAISED
3442 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3444 s
->gc
= s
->face
->gc
;
3445 s
->stippled_p
= s
->face
->stipple
!= 0;
3449 s
->gc
= s
->face
->gc
;
3450 s
->stippled_p
= s
->face
->stipple
!= 0;
3453 /* GC must have been set. */
3454 xassert (s
->gc
!= 0);
3458 /* Return in *R the clipping rectangle for glyph string S. */
3461 x_get_glyph_string_clip_rect (s
, r
)
3462 struct glyph_string
*s
;
3465 int r_height
, r_width
;
3467 if (s
->row
->full_width_p
)
3469 /* Draw full-width. X coordinates are relative to S->w->left. */
3470 int canon_x
= CANON_X_UNIT (s
->f
);
3472 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3473 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3475 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3477 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3478 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3482 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3484 /* Unless displaying a mode or menu bar line, which are always
3485 fully visible, clip to the visible part of the row. */
3486 if (s
->w
->pseudo_window_p
)
3487 r_height
= s
->row
->visible_height
;
3489 r_height
= s
->height
;
3493 /* This is a text line that may be partially visible. */
3494 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3495 r_width
= window_box_width (s
->w
, s
->area
);
3496 r_height
= s
->row
->visible_height
;
3499 /* If S draws overlapping rows, it's sufficient to use the top and
3500 bottom of the window for clipping because this glyph string
3501 intentionally draws over other lines. */
3502 if (s
->for_overlaps_p
)
3504 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3505 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3509 /* Don't use S->y for clipping because it doesn't take partially
3510 visible lines into account. For example, it can be negative for
3511 partially visible lines at the top of a window. */
3512 if (!s
->row
->full_width_p
3513 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3514 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3516 r
->top
= max (0, s
->row
->y
);
3518 /* If drawing a tool-bar window, draw it over the internal border
3519 at the top of the window. */
3520 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3521 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3524 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3526 r
->bottom
= r
->top
+ r_height
;
3527 r
->right
= r
->left
+ r_width
;
3531 /* Set clipping for output of glyph string S. S may be part of a mode
3532 line or menu if we don't have X toolkit support. */
3535 x_set_glyph_string_clipping (s
)
3536 struct glyph_string
*s
;
3539 x_get_glyph_string_clip_rect (s
, &r
);
3540 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3544 /* Compute left and right overhang of glyph string S. If S is a glyph
3545 string for a composition, assume overhangs don't exist. */
3548 x_compute_glyph_string_overhangs (s
)
3549 struct glyph_string
*s
;
3552 && s
->first_glyph
->type
== CHAR_GLYPH
)
3555 int direction
, font_ascent
, font_descent
;
3556 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3557 &font_ascent
, &font_descent
, &cs
);
3558 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3559 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3564 /* Compute overhangs and x-positions for glyph string S and its
3565 predecessors, or successors. X is the starting x-position for S.
3566 BACKWARD_P non-zero means process predecessors. */
3569 x_compute_overhangs_and_x (s
, x
, backward_p
)
3570 struct glyph_string
*s
;
3578 x_compute_glyph_string_overhangs (s
);
3588 x_compute_glyph_string_overhangs (s
);
3597 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3598 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3599 assumed to be zero. */
3602 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3603 struct glyph
*glyph
;
3609 if (glyph
->type
== CHAR_GLYPH
)
3613 struct font_info
*font_info
;
3617 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3619 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3621 && (pcm
= x_per_char_metric (font
, &char2b
)))
3623 if (pcm
->rbearing
> pcm
->width
)
3624 *right
= pcm
->rbearing
- pcm
->width
;
3625 if (pcm
->lbearing
< 0)
3626 *left
= -pcm
->lbearing
;
3632 /* Return the index of the first glyph preceding glyph string S that
3633 is overwritten by S because of S's left overhang. Value is -1
3634 if no glyphs are overwritten. */
3637 x_left_overwritten (s
)
3638 struct glyph_string
*s
;
3642 if (s
->left_overhang
)
3645 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3646 int first
= s
->first_glyph
- glyphs
;
3648 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3649 x
-= glyphs
[i
].pixel_width
;
3660 /* Return the index of the first glyph preceding glyph string S that
3661 is overwriting S because of its right overhang. Value is -1 if no
3662 glyph in front of S overwrites S. */
3665 x_left_overwriting (s
)
3666 struct glyph_string
*s
;
3669 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3670 int first
= s
->first_glyph
- glyphs
;
3674 for (i
= first
- 1; i
>= 0; --i
)
3677 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3680 x
-= glyphs
[i
].pixel_width
;
3687 /* Return the index of the last glyph following glyph string S that is
3688 not overwritten by S because of S's right overhang. Value is -1 if
3689 no such glyph is found. */
3692 x_right_overwritten (s
)
3693 struct glyph_string
*s
;
3697 if (s
->right_overhang
)
3700 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3701 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3702 int end
= s
->row
->used
[s
->area
];
3704 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3705 x
+= glyphs
[i
].pixel_width
;
3714 /* Return the index of the last glyph following glyph string S that
3715 overwrites S because of its left overhang. Value is negative
3716 if no such glyph is found. */
3719 x_right_overwriting (s
)
3720 struct glyph_string
*s
;
3723 int end
= s
->row
->used
[s
->area
];
3724 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3725 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3729 for (i
= first
; i
< end
; ++i
)
3732 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3735 x
+= glyphs
[i
].pixel_width
;
3742 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3745 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3746 struct glyph_string
*s
;
3751 xgcv
.foreground
= s
->gc
->background
;
3752 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3756 /* Draw the background of glyph_string S. If S->background_filled_p
3757 is non-zero don't draw it. FORCE_P non-zero means draw the
3758 background even if it wouldn't be drawn normally. This is used
3759 when a string preceding S draws into the background of S, or S
3760 contains the first component of a composition. */
3763 x_draw_glyph_string_background (s
, force_p
)
3764 struct glyph_string
*s
;
3767 /* Nothing to do if background has already been drawn or if it
3768 shouldn't be drawn in the first place. */
3769 if (!s
->background_filled_p
)
3771 int box_line_width
= max (s
->face
->box_line_width
, 0);
3773 #if 0 /* MAC_TODO: stipple */
3776 /* Fill background with a stipple pattern. */
3777 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3778 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3779 s
->y
+ box_line_width
,
3780 s
->background_width
,
3781 s
->height
- 2 * box_line_width
);
3782 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3783 s
->background_filled_p
= 1;
3787 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3788 || s
->font_not_found_p
3789 || s
->extends_to_end_of_line_p
3792 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3793 s
->background_width
,
3794 s
->height
- 2 * box_line_width
);
3795 s
->background_filled_p
= 1;
3801 /* Draw the foreground of glyph string S. */
3804 x_draw_glyph_string_foreground (s
)
3805 struct glyph_string
*s
;
3809 /* If first glyph of S has a left box line, start drawing the text
3810 of S to the right of that box line. */
3811 if (s
->face
->box
!= FACE_NO_BOX
3812 && s
->first_glyph
->left_box_line_p
)
3813 x
= s
->x
+ abs (s
->face
->box_line_width
);
3817 /* Draw characters of S as rectangles if S's font could not be
3819 if (s
->font_not_found_p
)
3821 for (i
= 0; i
< s
->nchars
; ++i
)
3823 struct glyph
*g
= s
->first_glyph
+ i
;
3824 mac_draw_rectangle (s
->display
, s
->window
,
3825 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3827 x
+= g
->pixel_width
;
3832 char *char1b
= (char *) s
->char2b
;
3833 int boff
= s
->font_info
->baseline_offset
;
3835 if (s
->font_info
->vertical_centering
)
3836 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3838 /* If we can use 8-bit functions, condense S->char2b. */
3840 for (i
= 0; i
< s
->nchars
; ++i
)
3841 char1b
[i
] = s
->char2b
[i
].byte2
;
3843 /* Draw text with XDrawString if background has already been
3844 filled. Otherwise, use XDrawImageString. (Note that
3845 XDrawImageString is usually faster than XDrawString.) Always
3846 use XDrawImageString when drawing the cursor so that there is
3847 no chance that characters under a box cursor are invisible. */
3848 if (s
->for_overlaps_p
3849 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3851 /* Draw characters with 16-bit or 8-bit functions. */
3853 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3854 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3856 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3857 s
->ybase
- boff
, char1b
, s
->nchars
);
3862 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3863 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3865 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3866 s
->ybase
- boff
, char1b
, s
->nchars
);
3871 /* Draw the foreground of composite glyph string S. */
3874 x_draw_composite_glyph_string_foreground (s
)
3875 struct glyph_string
*s
;
3879 /* If first glyph of S has a left box line, start drawing the text
3880 of S to the right of that box line. */
3881 if (s
->face
->box
!= FACE_NO_BOX
3882 && s
->first_glyph
->left_box_line_p
)
3883 x
= s
->x
+ abs (s
->face
->box_line_width
);
3887 /* S is a glyph string for a composition. S->gidx is the index of
3888 the first character drawn for glyphs of this composition.
3889 S->gidx == 0 means we are drawing the very first character of
3890 this composition. */
3892 /* Draw a rectangle for the composition if the font for the very
3893 first character of the composition could not be loaded. */
3894 if (s
->font_not_found_p
)
3897 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3898 s
->width
- 1, s
->height
- 1);
3902 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3903 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3904 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3905 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3911 #ifdef USE_X_TOOLKIT
3913 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3916 /* Return the frame on which widget WIDGET is used.. Abort if frame
3917 cannot be determined. */
3919 static struct frame
*
3920 x_frame_of_widget (widget
)
3923 struct x_display_info
*dpyinfo
;
3927 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3929 /* Find the top-level shell of the widget. Note that this function
3930 can be called when the widget is not yet realized, so XtWindow
3931 (widget) == 0. That's the reason we can't simply use
3932 x_any_window_to_frame. */
3933 while (!XtIsTopLevelShell (widget
))
3934 widget
= XtParent (widget
);
3936 /* Look for a frame with that top-level widget. Allocate the color
3937 on that frame to get the right gamma correction value. */
3938 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3939 if (GC_FRAMEP (XCAR (tail
))
3940 && (f
= XFRAME (XCAR (tail
)),
3941 (f
->output_data
.nothing
!= 1
3942 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3943 && f
->output_data
.x
->widget
== widget
)
3950 /* Allocate the color COLOR->pixel on the screen and display of
3951 widget WIDGET in colormap CMAP. If an exact match cannot be
3952 allocated, try the nearest color available. Value is non-zero
3953 if successful. This is called from lwlib. */
3956 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3961 struct frame
*f
= x_frame_of_widget (widget
);
3962 return x_alloc_nearest_color (f
, cmap
, color
);
3966 #endif /* USE_X_TOOLKIT */
3968 #if 0 /* MAC_TODO */
3970 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3971 CMAP. If an exact match can't be allocated, try the nearest color
3972 available. Value is non-zero if successful. Set *COLOR to the
3976 x_alloc_nearest_color (f
, cmap
, color
)
3981 Display
*display
= FRAME_X_DISPLAY (f
);
3982 Screen
*screen
= FRAME_X_SCREEN (f
);
3985 gamma_correct (f
, color
);
3986 rc
= XAllocColor (display
, cmap
, color
);
3989 /* If we got to this point, the colormap is full, so we're going
3990 to try to get the next closest color. The algorithm used is
3991 a least-squares matching, which is what X uses for closest
3992 color matching with StaticColor visuals. */
3994 unsigned long nearest_delta
= ~0;
3995 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3996 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3998 for (i
= 0; i
< ncells
; ++i
)
4000 XQueryColors (display
, cmap
, cells
, ncells
);
4002 for (nearest
= i
= 0; i
< ncells
; ++i
)
4004 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
4005 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
4006 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
4007 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
4009 if (delta
< nearest_delta
)
4012 nearest_delta
= delta
;
4016 color
->red
= cells
[nearest
].red
;
4017 color
->green
= cells
[nearest
].green
;
4018 color
->blue
= cells
[nearest
].blue
;
4019 rc
= XAllocColor (display
, cmap
, color
);
4022 #ifdef DEBUG_X_COLORS
4024 register_color (color
->pixel
);
4025 #endif /* DEBUG_X_COLORS */
4031 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
4032 It's necessary to do this instead of just using PIXEL directly to
4033 get color reference counts right. */
4036 x_copy_color (f
, pixel
)
4038 unsigned long pixel
;
4042 color
.pixel
= pixel
;
4044 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4045 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4047 #ifdef DEBUG_X_COLORS
4048 register_color (pixel
);
4054 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
4055 It's necessary to do this instead of just using PIXEL directly to
4056 get color reference counts right. */
4059 x_copy_dpy_color (dpy
, cmap
, pixel
)
4062 unsigned long pixel
;
4066 color
.pixel
= pixel
;
4068 XQueryColor (dpy
, cmap
, &color
);
4069 XAllocColor (dpy
, cmap
, &color
);
4071 #ifdef DEBUG_X_COLORS
4072 register_color (pixel
);
4077 #endif /* MAC_TODO */
4079 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
4080 or DELTA. Try a color with RGB values multiplied by FACTOR first.
4081 If this produces the same color as COLOR, try a color where all RGB
4082 values have DELTA added. Return the allocated color in *COLOR.
4083 DISPLAY is the X display, CMAP is the colormap to operate on.
4084 Value is non-zero if successful. */
4087 mac_alloc_lighter_color (f
, color
, factor
, delta
)
4089 unsigned long *color
;
4095 /* Change RGB values by specified FACTOR. Avoid overflow! */
4096 xassert (factor
>= 0);
4097 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
4098 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
4099 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
4101 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
4102 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
4103 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
4105 /* MAC_TODO: Map to palette and retry with delta if same? */
4106 /* MAC_TODO: Free colors (if using palette)? */
4117 /* Set up the foreground color for drawing relief lines of glyph
4118 string S. RELIEF is a pointer to a struct relief containing the GC
4119 with which lines will be drawn. Use a color that is FACTOR or
4120 DELTA lighter or darker than the relief's background which is found
4121 in S->f->output_data.x->relief_background. If such a color cannot
4122 be allocated, use DEFAULT_PIXEL, instead. */
4125 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
4127 struct relief
*relief
;
4130 unsigned long default_pixel
;
4133 struct mac_output
*di
= f
->output_data
.mac
;
4134 unsigned long mask
= GCForeground
;
4135 unsigned long pixel
;
4136 unsigned long background
= di
->relief_background
;
4137 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4139 /* MAC_TODO: Free colors (if using palette)? */
4141 /* Allocate new color. */
4142 xgcv
.foreground
= default_pixel
;
4144 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
4146 relief
->allocated_p
= 1;
4147 xgcv
.foreground
= relief
->pixel
= pixel
;
4150 if (relief
->gc
== 0)
4152 #if 0 /* MAC_TODO: stipple */
4153 xgcv
.stipple
= dpyinfo
->gray
;
4156 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
4159 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
4163 /* Set up colors for the relief lines around glyph string S. */
4166 x_setup_relief_colors (s
)
4167 struct glyph_string
*s
;
4169 struct mac_output
*di
= s
->f
->output_data
.mac
;
4170 unsigned long color
;
4172 if (s
->face
->use_box_color_for_shadows_p
)
4173 color
= s
->face
->box_color
;
4178 /* Get the background color of the face. */
4179 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
4180 color
= xgcv
.background
;
4183 if (di
->white_relief
.gc
== 0
4184 || color
!= di
->relief_background
)
4186 di
->relief_background
= color
;
4187 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
4188 WHITE_PIX_DEFAULT (s
->f
));
4189 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4190 BLACK_PIX_DEFAULT (s
->f
));
4195 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4196 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4197 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4198 relief. LEFT_P non-zero means draw a relief on the left side of
4199 the rectangle. RIGHT_P non-zero means draw a relief on the right
4200 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4204 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4205 raised_p
, left_p
, right_p
, clip_rect
)
4207 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4214 gc
= f
->output_data
.mac
->white_relief
.gc
;
4216 gc
= f
->output_data
.mac
->black_relief
.gc
;
4217 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4220 for (i
= 0; i
< width
; ++i
)
4221 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4222 left_x
+ i
* left_p
, top_y
+ i
,
4223 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4227 for (i
= 0; i
< width
; ++i
)
4228 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4229 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4231 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4233 gc
= f
->output_data
.mac
->black_relief
.gc
;
4235 gc
= f
->output_data
.mac
->white_relief
.gc
;
4236 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4240 for (i
= 0; i
< width
; ++i
)
4241 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4242 left_x
+ i
* left_p
, bottom_y
- i
,
4243 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4247 for (i
= 0; i
< width
; ++i
)
4248 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4249 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4251 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4255 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4256 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4257 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4258 left side of the rectangle. RIGHT_P non-zero means draw a line
4259 on the right side of the rectangle. CLIP_RECT is the clipping
4260 rectangle to use when drawing. */
4263 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4264 left_p
, right_p
, clip_rect
)
4265 struct glyph_string
*s
;
4266 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4271 xgcv
.foreground
= s
->face
->box_color
;
4272 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4275 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4276 left_x
, top_y
, right_x
- left_x
, width
);
4280 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4281 left_x
, top_y
, width
, bottom_y
- top_y
);
4284 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4285 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4289 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4290 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4292 mac_reset_clipping (s
->display
, s
->window
);
4296 /* Draw a box around glyph string S. */
4299 x_draw_glyph_string_box (s
)
4300 struct glyph_string
*s
;
4302 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4303 int left_p
, right_p
;
4304 struct glyph
*last_glyph
;
4307 last_x
= window_box_right (s
->w
, s
->area
);
4308 if (s
->row
->full_width_p
4309 && !s
->w
->pseudo_window_p
)
4311 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4312 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4313 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4316 /* The glyph that may have a right box line. */
4317 last_glyph
= (s
->cmp
|| s
->img
4319 : s
->first_glyph
+ s
->nchars
- 1);
4321 width
= abs (s
->face
->box_line_width
);
4322 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4324 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4326 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4328 bottom_y
= top_y
+ s
->height
- 1;
4330 left_p
= (s
->first_glyph
->left_box_line_p
4331 || (s
->hl
== DRAW_MOUSE_FACE
4333 || s
->prev
->hl
!= s
->hl
)));
4334 right_p
= (last_glyph
->right_box_line_p
4335 || (s
->hl
== DRAW_MOUSE_FACE
4337 || s
->next
->hl
!= s
->hl
)));
4339 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4341 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4342 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4343 left_p
, right_p
, &clip_rect
);
4346 x_setup_relief_colors (s
);
4347 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4348 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4353 /* Draw foreground of image glyph string S. */
4356 x_draw_image_foreground (s
)
4357 struct glyph_string
*s
;
4360 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4362 /* If first glyph of S has a left box line, start drawing it to the
4363 right of that line. */
4364 if (s
->face
->box
!= FACE_NO_BOX
4365 && s
->first_glyph
->left_box_line_p
)
4366 x
= s
->x
+ abs (s
->face
->box_line_width
);
4370 /* If there is a margin around the image, adjust x- and y-position
4372 x
+= s
->img
->hmargin
;
4373 y
+= s
->img
->vmargin
;
4377 #if 0 /* MAC_TODO: image mask */
4380 /* We can't set both a clip mask and use XSetClipRectangles
4381 because the latter also sets a clip mask. We also can't
4382 trust on the shape extension to be available
4383 (XShapeCombineRegion). So, compute the rectangle to draw
4385 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4388 XRectangle clip_rect
, image_rect
, r
;
4390 xgcv
.clip_mask
= s
->img
->mask
;
4391 xgcv
.clip_x_origin
= x
;
4392 xgcv
.clip_y_origin
= y
;
4393 xgcv
.function
= GXcopy
;
4394 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4396 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4399 image_rect
.width
= s
->img
->width
;
4400 image_rect
.height
= s
->img
->height
;
4401 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4402 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4403 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4406 #endif /* MAC_TODO */
4408 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4409 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4411 /* When the image has a mask, we can expect that at
4412 least part of a mouse highlight or a block cursor will
4413 be visible. If the image doesn't have a mask, make
4414 a block cursor visible by drawing a rectangle around
4415 the image. I believe it's looking better if we do
4416 nothing here for mouse-face. */
4417 if (s
->hl
== DRAW_CURSOR
)
4419 int r
= s
->img
->relief
;
4421 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
4422 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4427 /* Draw a rectangle if image could not be loaded. */
4428 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4429 s
->img
->width
- 1, s
->img
->height
- 1);
4434 /* Draw a relief around the image glyph string S. */
4437 x_draw_image_relief (s
)
4438 struct glyph_string
*s
;
4440 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4443 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4445 /* If first glyph of S has a left box line, start drawing it to the
4446 right of that line. */
4447 if (s
->face
->box
!= FACE_NO_BOX
4448 && s
->first_glyph
->left_box_line_p
)
4449 x
= s
->x
+ abs (s
->face
->box_line_width
);
4453 /* If there is a margin around the image, adjust x- and y-position
4455 x
+= s
->img
->hmargin
;
4456 y
+= s
->img
->vmargin
;
4458 if (s
->hl
== DRAW_IMAGE_SUNKEN
4459 || s
->hl
== DRAW_IMAGE_RAISED
)
4461 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4462 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4466 thick
= abs (s
->img
->relief
);
4467 raised_p
= s
->img
->relief
> 0;
4472 x1
= x
+ s
->img
->width
+ thick
- 1;
4473 y1
= y
+ s
->img
->height
+ thick
- 1;
4475 x_setup_relief_colors (s
);
4476 x_get_glyph_string_clip_rect (s
, &r
);
4477 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4481 /* Draw the foreground of image glyph string S to PIXMAP. */
4484 x_draw_image_foreground_1 (s
, pixmap
)
4485 struct glyph_string
*s
;
4489 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4491 /* If first glyph of S has a left box line, start drawing it to the
4492 right of that line. */
4493 if (s
->face
->box
!= FACE_NO_BOX
4494 && s
->first_glyph
->left_box_line_p
)
4495 x
= abs (s
->face
->box_line_width
);
4499 /* If there is a margin around the image, adjust x- and y-position
4501 x
+= s
->img
->hmargin
;
4502 y
+= s
->img
->vmargin
;
4506 #if 0 /* MAC_TODO: image mask */
4509 /* We can't set both a clip mask and use XSetClipRectangles
4510 because the latter also sets a clip mask. We also can't
4511 trust on the shape extension to be available
4512 (XShapeCombineRegion). So, compute the rectangle to draw
4514 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4518 xgcv
.clip_mask
= s
->img
->mask
;
4519 xgcv
.clip_x_origin
= x
;
4520 xgcv
.clip_y_origin
= y
;
4521 xgcv
.function
= GXcopy
;
4522 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4524 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4525 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4526 XSetClipMask (s
->display
, s
->gc
, None
);
4529 #endif /* MAC_TODO */
4531 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4532 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4534 /* When the image has a mask, we can expect that at
4535 least part of a mouse highlight or a block cursor will
4536 be visible. If the image doesn't have a mask, make
4537 a block cursor visible by drawing a rectangle around
4538 the image. I believe it's looking better if we do
4539 nothing here for mouse-face. */
4540 if (s
->hl
== DRAW_CURSOR
)
4542 int r
= s
->img
->relief
;
4544 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
4545 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
4550 /* Draw a rectangle if image could not be loaded. */
4551 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4552 s
->img
->width
- 1, s
->img
->height
- 1);
4556 /* Draw part of the background of glyph string S. X, Y, W, and H
4557 give the rectangle to draw. */
4560 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4561 struct glyph_string
*s
;
4564 #if 0 /* MAC_TODO: stipple */
4567 /* Fill background with a stipple pattern. */
4568 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4569 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4570 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4573 #endif /* MAC_TODO */
4574 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4578 /* Draw image glyph string S.
4581 s->x +-------------------------
4584 | +-------------------------
4587 | | +-------------------
4593 x_draw_image_glyph_string (s
)
4594 struct glyph_string
*s
;
4597 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4598 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4602 height
= s
->height
- 2 * box_line_vwidth
;
4604 /* Fill background with face under the image. Do it only if row is
4605 taller than image or if image has a clip mask to reduce
4607 s
->stippled_p
= s
->face
->stipple
!= 0;
4608 if (height
> s
->img
->height
4611 #if 0 /* TODO: image mask */
4614 || s
->img
->pixmap
== 0
4615 || s
->width
!= s
->background_width
)
4617 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4618 x
= s
->x
+ box_line_hwidth
;
4622 y
= s
->y
+ box_line_vwidth
;
4623 #if 0 /* TODO: image mask */
4626 /* Create a pixmap as large as the glyph string. Fill it
4627 with the background color. Copy the image to it, using
4628 its mask. Copy the temporary pixmap to the display. */
4629 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4630 int depth
= DefaultDepthOfScreen (screen
);
4632 /* Create a pixmap as large as the glyph string. */
4633 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4634 s
->background_width
,
4637 /* Don't clip in the following because we're working on the
4639 XSetClipMask (s
->display
, s
->gc
, None
);
4641 /* Fill the pixmap with the background color/stipple. */
4644 /* Fill background with a stipple pattern. */
4645 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4646 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4647 0, 0, s
->background_width
, s
->height
);
4648 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4653 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4655 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4656 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4657 0, 0, s
->background_width
, s
->height
);
4658 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4663 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4665 s
->background_filled_p
= 1;
4668 /* Draw the foreground. */
4671 x_draw_image_foreground_1 (s
, pixmap
);
4672 x_set_glyph_string_clipping (s
);
4673 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4674 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4675 mac_reset_clipping (s
->display
, s
->window
);
4676 XFreePixmap (s
->display
, pixmap
);
4679 x_draw_image_foreground (s
);
4681 /* If we must draw a relief around the image, do it. */
4683 || s
->hl
== DRAW_IMAGE_RAISED
4684 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4685 x_draw_image_relief (s
);
4689 /* Draw stretch glyph string S. */
4692 x_draw_stretch_glyph_string (s
)
4693 struct glyph_string
*s
;
4695 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4696 s
->stippled_p
= s
->face
->stipple
!= 0;
4698 if (s
->hl
== DRAW_CURSOR
4699 && !x_stretch_cursor_p
)
4701 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4702 as wide as the stretch glyph. */
4703 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4706 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4708 /* Clear rest using the GC of the original non-cursor face. */
4709 if (width
< s
->background_width
)
4711 GC gc
= s
->face
->gc
;
4712 int x
= s
->x
+ width
, y
= s
->y
;
4713 int w
= s
->background_width
- width
, h
= s
->height
;
4716 if (s
->row
->mouse_face_p
4717 && cursor_in_mouse_face_p (s
->w
))
4719 x_set_mouse_face_gc (s
);
4725 x_get_glyph_string_clip_rect (s
, &r
);
4726 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4728 #if 0 /* MAC_TODO: stipple */
4729 if (s
->face
->stipple
)
4731 /* Fill background with a stipple pattern. */
4732 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4733 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4734 XSetFillStyle (s
->display
, gc
, FillSolid
);
4737 #endif /* MAC_TODO */
4740 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4741 XSetForeground (s
->display
, gc
, xgcv
.background
);
4742 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4743 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4746 mac_reset_clipping (s
->display
, s
->window
);
4749 else if (!s
->background_filled_p
)
4750 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4753 s
->background_filled_p
= 1;
4757 /* Draw glyph string S. */
4760 x_draw_glyph_string (s
)
4761 struct glyph_string
*s
;
4763 int relief_drawn_p
= 0;
4765 /* If S draws into the background of its successor, draw the
4766 background of the successor first so that S can draw into it.
4767 This makes S->next use XDrawString instead of XDrawImageString. */
4768 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4770 xassert (s
->next
->img
== NULL
);
4771 x_set_glyph_string_gc (s
->next
);
4772 x_set_glyph_string_clipping (s
->next
);
4773 x_draw_glyph_string_background (s
->next
, 1);
4777 /* Set up S->gc, set clipping and draw S. */
4778 x_set_glyph_string_gc (s
);
4780 /* Draw relief (if any) in advance for char/composition so that the
4781 glyph string can be drawn over it. */
4782 if (!s
->for_overlaps_p
4783 && s
->face
->box
!= FACE_NO_BOX
4784 && (s
->first_glyph
->type
== CHAR_GLYPH
4785 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4788 x_set_glyph_string_clipping (s
);
4789 x_draw_glyph_string_background (s
, 1);
4790 x_draw_glyph_string_box (s
);
4791 x_set_glyph_string_clipping (s
);
4795 x_set_glyph_string_clipping (s
);
4797 switch (s
->first_glyph
->type
)
4800 x_draw_image_glyph_string (s
);
4804 x_draw_stretch_glyph_string (s
);
4808 if (s
->for_overlaps_p
)
4809 s
->background_filled_p
= 1;
4811 x_draw_glyph_string_background (s
, 0);
4812 x_draw_glyph_string_foreground (s
);
4815 case COMPOSITE_GLYPH
:
4816 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4817 s
->background_filled_p
= 1;
4819 x_draw_glyph_string_background (s
, 1);
4820 x_draw_composite_glyph_string_foreground (s
);
4827 if (!s
->for_overlaps_p
)
4829 /* Draw underline. */
4830 if (s
->face
->underline_p
)
4832 unsigned long h
= 1;
4833 unsigned long dy
= s
->height
- h
;
4835 if (s
->face
->underline_defaulted_p
)
4836 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4841 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4842 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4843 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4845 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4849 /* Draw overline. */
4850 if (s
->face
->overline_p
)
4852 unsigned long dy
= 0, h
= 1;
4854 if (s
->face
->overline_color_defaulted_p
)
4855 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4860 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4861 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4862 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4864 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4868 /* Draw strike-through. */
4869 if (s
->face
->strike_through_p
)
4871 unsigned long h
= 1;
4872 unsigned long dy
= (s
->height
- h
) / 2;
4874 if (s
->face
->strike_through_color_defaulted_p
)
4875 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4880 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4881 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4882 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4884 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4889 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4890 x_draw_glyph_string_box (s
);
4893 /* Reset clipping. */
4894 mac_reset_clipping (s
->display
, s
->window
);
4898 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4899 struct face
**, int));
4902 /* Fill glyph string S with composition components specified by S->cmp.
4904 FACES is an array of faces for all components of this composition.
4905 S->gidx is the index of the first component for S.
4906 OVERLAPS_P non-zero means S should draw the foreground only, and
4907 use its physical height for clipping.
4909 Value is the index of a component not in S. */
4912 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4913 struct glyph_string
*s
;
4914 struct face
**faces
;
4921 s
->for_overlaps_p
= overlaps_p
;
4923 s
->face
= faces
[s
->gidx
];
4924 s
->font
= s
->face
->font
;
4925 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4927 /* For all glyphs of this composition, starting at the offset
4928 S->gidx, until we reach the end of the definition or encounter a
4929 glyph that requires the different face, add it to S. */
4931 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4934 /* All glyph strings for the same composition has the same width,
4935 i.e. the width set for the first component of the composition. */
4937 s
->width
= s
->first_glyph
->pixel_width
;
4939 /* If the specified font could not be loaded, use the frame's
4940 default font, but record the fact that we couldn't load it in
4941 the glyph string so that we can draw rectangles for the
4942 characters of the glyph string. */
4943 if (s
->font
== NULL
)
4945 s
->font_not_found_p
= 1;
4946 s
->font
= FRAME_FONT (s
->f
);
4949 /* Adjust base line for subscript/superscript text. */
4950 s
->ybase
+= s
->first_glyph
->voffset
;
4952 xassert (s
->face
&& s
->face
->gc
);
4954 /* This glyph string must always be drawn with 16-bit functions. */
4957 return s
->gidx
+ s
->nchars
;
4961 /* Fill glyph string S from a sequence of character glyphs.
4963 FACE_ID is the face id of the string. START is the index of the
4964 first glyph to consider, END is the index of the last + 1.
4965 OVERLAPS_P non-zero means S should draw the foreground only, and
4966 use its physical height for clipping.
4968 Value is the index of the first glyph not in S. */
4971 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4972 struct glyph_string
*s
;
4974 int start
, end
, overlaps_p
;
4976 struct glyph
*glyph
, *last
;
4978 int glyph_not_available_p
;
4980 xassert (s
->f
== XFRAME (s
->w
->frame
));
4981 xassert (s
->nchars
== 0);
4982 xassert (start
>= 0 && end
> start
);
4984 s
->for_overlaps_p
= overlaps_p
;
4985 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4986 last
= s
->row
->glyphs
[s
->area
] + end
;
4987 voffset
= glyph
->voffset
;
4989 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4992 && glyph
->type
== CHAR_GLYPH
4993 && glyph
->voffset
== voffset
4994 /* Same face id implies same font, nowadays. */
4995 && glyph
->face_id
== face_id
4996 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
5000 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
5001 s
->char2b
+ s
->nchars
,
5003 s
->two_byte_p
= two_byte_p
;
5005 xassert (s
->nchars
<= end
- start
);
5006 s
->width
+= glyph
->pixel_width
;
5010 s
->font
= s
->face
->font
;
5011 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5013 /* If the specified font could not be loaded, use the frame's font,
5014 but record the fact that we couldn't load it in
5015 S->font_not_found_p so that we can draw rectangles for the
5016 characters of the glyph string. */
5017 if (s
->font
== NULL
|| glyph_not_available_p
)
5019 s
->font_not_found_p
= 1;
5020 s
->font
= FRAME_FONT (s
->f
);
5023 /* Adjust base line for subscript/superscript text. */
5024 s
->ybase
+= voffset
;
5026 xassert (s
->face
&& s
->face
->gc
);
5027 return glyph
- s
->row
->glyphs
[s
->area
];
5031 /* Fill glyph string S from image glyph S->first_glyph. */
5034 x_fill_image_glyph_string (s
)
5035 struct glyph_string
*s
;
5037 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
5038 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
5040 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
5041 s
->font
= s
->face
->font
;
5042 s
->width
= s
->first_glyph
->pixel_width
;
5044 /* Adjust base line for subscript/superscript text. */
5045 s
->ybase
+= s
->first_glyph
->voffset
;
5049 /* Fill glyph string S from a sequence of stretch glyphs.
5051 ROW is the glyph row in which the glyphs are found, AREA is the
5052 area within the row. START is the index of the first glyph to
5053 consider, END is the index of the last + 1.
5055 Value is the index of the first glyph not in S. */
5058 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
5059 struct glyph_string
*s
;
5060 struct glyph_row
*row
;
5061 enum glyph_row_area area
;
5064 struct glyph
*glyph
, *last
;
5065 int voffset
, face_id
;
5067 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
5069 glyph
= s
->row
->glyphs
[s
->area
] + start
;
5070 last
= s
->row
->glyphs
[s
->area
] + end
;
5071 face_id
= glyph
->face_id
;
5072 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
5073 s
->font
= s
->face
->font
;
5074 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5075 s
->width
= glyph
->pixel_width
;
5076 voffset
= glyph
->voffset
;
5080 && glyph
->type
== STRETCH_GLYPH
5081 && glyph
->voffset
== voffset
5082 && glyph
->face_id
== face_id
);
5084 s
->width
+= glyph
->pixel_width
;
5086 /* Adjust base line for subscript/superscript text. */
5087 s
->ybase
+= voffset
;
5090 return glyph
- s
->row
->glyphs
[s
->area
];
5094 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
5095 of XChar2b structures for S; it can't be allocated in
5096 x_init_glyph_string because it must be allocated via `alloca'. W
5097 is the window on which S is drawn. ROW and AREA are the glyph row
5098 and area within the row from which S is constructed. START is the
5099 index of the first glyph structure covered by S. HL is a
5100 face-override for drawing S. */
5103 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
5104 struct glyph_string
*s
;
5107 struct glyph_row
*row
;
5108 enum glyph_row_area area
;
5110 enum draw_glyphs_face hl
;
5112 bzero (s
, sizeof *s
);
5114 s
->f
= XFRAME (w
->frame
);
5115 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
5116 s
->window
= FRAME_MAC_WINDOW (s
->f
);
5121 s
->first_glyph
= row
->glyphs
[area
] + start
;
5122 s
->height
= row
->height
;
5123 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5125 /* Display the internal border below the tool-bar window. */
5126 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
5127 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
5129 s
->ybase
= s
->y
+ row
->ascent
;
5133 /* Set background width of glyph string S. START is the index of the
5134 first glyph following S. LAST_X is the right-most x-position + 1
5135 in the drawing area. */
5138 x_set_glyph_string_background_width (s
, start
, last_x
)
5139 struct glyph_string
*s
;
5143 /* If the face of this glyph string has to be drawn to the end of
5144 the drawing area, set S->extends_to_end_of_line_p. */
5145 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
5147 if (start
== s
->row
->used
[s
->area
]
5148 && s
->area
== TEXT_AREA
5149 && ((s
->hl
== DRAW_NORMAL_TEXT
5150 && (s
->row
->fill_line_p
5151 || s
->face
->background
!= default_face
->background
5152 || s
->face
->stipple
!= default_face
->stipple
5153 || s
->row
->mouse_face_p
))
5154 || s
->hl
== DRAW_MOUSE_FACE
5155 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
5156 && s
->row
->fill_line_p
)))
5157 s
->extends_to_end_of_line_p
= 1;
5159 /* If S extends its face to the end of the line, set its
5160 background_width to the distance to the right edge of the drawing
5162 if (s
->extends_to_end_of_line_p
)
5163 s
->background_width
= last_x
- s
->x
+ 1;
5165 s
->background_width
= s
->width
;
5169 /* Add a glyph string for a stretch glyph to the list of strings
5170 between HEAD and TAIL. START is the index of the stretch glyph in
5171 row area AREA of glyph row ROW. END is the index of the last glyph
5172 in that glyph row area. X is the current output position assigned
5173 to the new glyph string constructed. HL overrides that face of the
5174 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5175 is the right-most x-position of the drawing area. */
5177 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
5178 and below -- keep them on one line. */
5179 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5182 s = (struct glyph_string *) alloca (sizeof *s); \
5183 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5184 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
5185 x_append_glyph_string (&HEAD, &TAIL, s); \
5191 /* Add a glyph string for an image glyph to the list of strings
5192 between HEAD and TAIL. START is the index of the image glyph in
5193 row area AREA of glyph row ROW. END is the index of the last glyph
5194 in that glyph row area. X is the current output position assigned
5195 to the new glyph string constructed. HL overrides that face of the
5196 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5197 is the right-most x-position of the drawing area. */
5199 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5202 s = (struct glyph_string *) alloca (sizeof *s); \
5203 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5204 x_fill_image_glyph_string (s); \
5205 x_append_glyph_string (&HEAD, &TAIL, s); \
5212 /* Add a glyph string for a sequence of character glyphs to the list
5213 of strings between HEAD and TAIL. START is the index of the first
5214 glyph in row area AREA of glyph row ROW that is part of the new
5215 glyph string. END is the index of the last glyph in that glyph row
5216 area. X is the current output position assigned to the new glyph
5217 string constructed. HL overrides that face of the glyph; e.g. it
5218 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
5219 right-most x-position of the drawing area. */
5221 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5227 c = (ROW)->glyphs[AREA][START].u.ch; \
5228 face_id = (ROW)->glyphs[AREA][START].face_id; \
5230 s = (struct glyph_string *) alloca (sizeof *s); \
5231 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5232 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5233 x_append_glyph_string (&HEAD, &TAIL, s); \
5235 START = x_fill_glyph_string (s, face_id, START, END, \
5241 /* Add a glyph string for a composite sequence to the list of strings
5242 between HEAD and TAIL. START is the index of the first glyph in
5243 row area AREA of glyph row ROW that is part of the new glyph
5244 string. END is the index of the last glyph in that glyph row area.
5245 X is the current output position assigned to the new glyph string
5246 constructed. HL overrides that face of the glyph; e.g. it is
5247 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5248 x-position of the drawing area. */
5250 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5252 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5253 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5254 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5255 struct composition *cmp = composition_table[cmp_id]; \
5256 int glyph_len = cmp->glyph_len; \
5258 struct face **faces; \
5259 struct glyph_string *first_s = NULL; \
5262 base_face = base_face->ascii_face; \
5263 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5264 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5265 /* At first, fill in `char2b' and `faces'. */ \
5266 for (n = 0; n < glyph_len; n++) \
5268 int c = COMPOSITION_GLYPH (cmp, n); \
5269 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5270 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5271 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5272 this_face_id, char2b + n, 1); \
5275 /* Make glyph_strings for each glyph sequence that is drawable by \
5276 the same face, and append them to HEAD/TAIL. */ \
5277 for (n = 0; n < cmp->glyph_len;) \
5279 s = (struct glyph_string *) alloca (sizeof *s); \
5280 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5281 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5289 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5297 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5298 of AREA of glyph row ROW on window W between indices START and END.
5299 HL overrides the face for drawing glyph strings, e.g. it is
5300 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5301 x-positions of the drawing area.
5303 This is an ugly monster macro construct because we must use alloca
5304 to allocate glyph strings (because x_draw_glyphs can be called
5307 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5310 HEAD = TAIL = NULL; \
5311 while (START < END) \
5313 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5314 switch (first_glyph->type) \
5317 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5318 TAIL, HL, X, LAST_X, \
5322 case COMPOSITE_GLYPH: \
5323 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5324 HEAD, TAIL, HL, X, LAST_X,\
5328 case STRETCH_GLYPH: \
5329 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5330 HEAD, TAIL, HL, X, LAST_X); \
5334 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5335 TAIL, HL, X, LAST_X); \
5342 x_set_glyph_string_background_width (s, START, LAST_X); \
5349 /* Draw glyphs between START and END in AREA of ROW on window W,
5350 starting at x-position X. X is relative to AREA in W. HL is a
5351 face-override with the following meaning:
5353 DRAW_NORMAL_TEXT draw normally
5354 DRAW_CURSOR draw in cursor face
5355 DRAW_MOUSE_FACE draw in mouse face.
5356 DRAW_INVERSE_VIDEO draw in mode line face
5357 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5358 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5360 If OVERLAPS_P is non-zero, draw only the foreground of characters
5361 and clip to the physical height of ROW.
5363 Value is the x-position reached, relative to AREA of W. */
5366 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5369 struct glyph_row
*row
;
5370 enum glyph_row_area area
;
5372 enum draw_glyphs_face hl
;
5375 struct glyph_string
*head
, *tail
;
5376 struct glyph_string
*s
;
5377 int last_x
, area_width
;
5381 /* Let's rather be paranoid than getting a SEGV. */
5382 end
= min (end
, row
->used
[area
]);
5383 start
= max (0, start
);
5384 start
= min (end
, start
);
5386 /* Translate X to frame coordinates. Set last_x to the right
5387 end of the drawing area. */
5388 if (row
->full_width_p
)
5390 /* X is relative to the left edge of W, without scroll bars
5392 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5393 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5396 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5397 last_x
= window_left_x
+ area_width
;
5399 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5401 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5402 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5408 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5409 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5413 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5414 area_width
= window_box_width (w
, area
);
5415 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5418 /* Build a doubly-linked list of glyph_string structures between
5419 head and tail from what we have to draw. Note that the macro
5420 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5421 the reason we use a separate variable `i'. */
5423 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5426 x_reached
= tail
->x
+ tail
->background_width
;
5430 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5431 the row, redraw some glyphs in front or following the glyph
5432 strings built above. */
5433 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5436 struct glyph_string
*h
, *t
;
5438 /* Compute overhangs for all glyph strings. */
5439 for (s
= head
; s
; s
= s
->next
)
5440 x_compute_glyph_string_overhangs (s
);
5442 /* Prepend glyph strings for glyphs in front of the first glyph
5443 string that are overwritten because of the first glyph
5444 string's left overhang. The background of all strings
5445 prepended must be drawn because the first glyph string
5447 i
= x_left_overwritten (head
);
5451 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5452 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5455 x_compute_overhangs_and_x (t
, head
->x
, 1);
5456 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5459 /* Prepend glyph strings for glyphs in front of the first glyph
5460 string that overwrite that glyph string because of their
5461 right overhang. For these strings, only the foreground must
5462 be drawn, because it draws over the glyph string at `head'.
5463 The background must not be drawn because this would overwrite
5464 right overhangs of preceding glyphs for which no glyph
5466 i
= x_left_overwriting (head
);
5469 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5470 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5472 for (s
= h
; s
; s
= s
->next
)
5473 s
->background_filled_p
= 1;
5474 x_compute_overhangs_and_x (t
, head
->x
, 1);
5475 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5478 /* Append glyphs strings for glyphs following the last glyph
5479 string tail that are overwritten by tail. The background of
5480 these strings has to be drawn because tail's foreground draws
5482 i
= x_right_overwritten (tail
);
5485 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5486 DRAW_NORMAL_TEXT
, x
, last_x
,
5488 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5489 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5492 /* Append glyph strings for glyphs following the last glyph
5493 string tail that overwrite tail. The foreground of such
5494 glyphs has to be drawn because it writes into the background
5495 of tail. The background must not be drawn because it could
5496 paint over the foreground of following glyphs. */
5497 i
= x_right_overwriting (tail
);
5500 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5501 DRAW_NORMAL_TEXT
, x
, last_x
,
5503 for (s
= h
; s
; s
= s
->next
)
5504 s
->background_filled_p
= 1;
5505 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5506 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5510 /* Draw all strings. */
5511 for (s
= head
; s
; s
= s
->next
)
5512 x_draw_glyph_string (s
);
5514 if (area
== TEXT_AREA
5515 && !row
->full_width_p
5516 /* When drawing overlapping rows, only the glyph strings'
5517 foreground is drawn, which doesn't erase a cursor
5521 int x0
= head
? head
->x
: x
;
5522 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5524 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5525 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5527 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5529 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5530 x0
-= left_area_width
;
5531 x1
-= left_area_width
;
5534 notice_overwritten_cursor (w
, area
, x0
, x1
,
5535 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5538 /* Value is the x-position up to which drawn, relative to AREA of W.
5539 This doesn't include parts drawn because of overhangs. */
5540 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5541 if (!row
->full_width_p
)
5543 if (area
> LEFT_MARGIN_AREA
)
5544 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5545 if (area
> TEXT_AREA
)
5546 x_reached
-= window_box_width (w
, TEXT_AREA
);
5553 /* Fix the display of area AREA of overlapping row ROW in window W. */
5556 x_fix_overlapping_area (w
, row
, area
)
5558 struct glyph_row
*row
;
5559 enum glyph_row_area area
;
5565 if (area
== LEFT_MARGIN_AREA
)
5567 else if (area
== TEXT_AREA
)
5568 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5570 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5571 + window_box_width (w
, TEXT_AREA
));
5573 for (i
= 0; i
< row
->used
[area
];)
5575 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5577 int start
= i
, start_x
= x
;
5581 x
+= row
->glyphs
[area
][i
].pixel_width
;
5584 while (i
< row
->used
[area
]
5585 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5587 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5588 DRAW_NORMAL_TEXT
, 1);
5592 x
+= row
->glyphs
[area
][i
].pixel_width
;
5601 /* Output LEN glyphs starting at START at the nominal cursor position.
5602 Advance the nominal cursor over the text. The global variable
5603 updated_window contains the window being updated, updated_row is
5604 the glyph row being updated, and updated_area is the area of that
5605 row being updated. */
5608 x_write_glyphs (start
, len
)
5609 struct glyph
*start
;
5614 xassert (updated_window
&& updated_row
);
5619 hpos
= start
- updated_row
->glyphs
[updated_area
];
5620 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5621 updated_row
, updated_area
,
5623 DRAW_NORMAL_TEXT
, 0);
5627 /* Advance the output cursor. */
5628 output_cursor
.hpos
+= len
;
5629 output_cursor
.x
= x
;
5633 /* Insert LEN glyphs from START at the nominal cursor position. */
5636 x_insert_glyphs (start
, len
)
5637 struct glyph
*start
;
5642 int line_height
, shift_by_width
, shifted_region_width
;
5643 struct glyph_row
*row
;
5644 struct glyph
*glyph
;
5645 int frame_x
, frame_y
, hpos
;
5647 xassert (updated_window
&& updated_row
);
5650 f
= XFRAME (WINDOW_FRAME (w
));
5652 /* Get the height of the line we are in. */
5654 line_height
= row
->height
;
5656 /* Get the width of the glyphs to insert. */
5658 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5659 shift_by_width
+= glyph
->pixel_width
;
5661 /* Get the width of the region to shift right. */
5662 shifted_region_width
= (window_box_width (w
, updated_area
)
5667 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5668 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5670 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5671 f
->output_data
.mac
->normal_gc
,
5673 shifted_region_width
, line_height
,
5674 frame_x
+ shift_by_width
, frame_y
);
5676 /* Write the glyphs. */
5677 hpos
= start
- row
->glyphs
[updated_area
];
5678 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5679 DRAW_NORMAL_TEXT
, 0);
5681 /* Advance the output cursor. */
5682 output_cursor
.hpos
+= len
;
5683 output_cursor
.x
+= shift_by_width
;
5688 /* Delete N glyphs at the nominal cursor position. Not implemented
5699 /* Erase the current text line from the nominal cursor position
5700 (inclusive) to pixel column TO_X (exclusive). The idea is that
5701 everything from TO_X onward is already erased.
5703 TO_X is a pixel position relative to updated_area of
5704 updated_window. TO_X == -1 means clear to the end of this area. */
5707 x_clear_end_of_line (to_x
)
5711 struct window
*w
= updated_window
;
5712 int max_x
, min_y
, max_y
;
5713 int from_x
, from_y
, to_y
;
5715 xassert (updated_window
&& updated_row
);
5716 f
= XFRAME (w
->frame
);
5718 if (updated_row
->full_width_p
)
5720 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5721 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5722 && !w
->pseudo_window_p
)
5723 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5726 max_x
= window_box_width (w
, updated_area
);
5727 max_y
= window_text_bottom_y (w
);
5729 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5730 of window. For TO_X > 0, truncate to end of drawing area. */
5736 to_x
= min (to_x
, max_x
);
5738 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5740 /* Notice if the cursor will be cleared by this operation. */
5741 if (!updated_row
->full_width_p
)
5742 notice_overwritten_cursor (w
, updated_area
,
5743 output_cursor
.x
, -1,
5745 MATRIX_ROW_BOTTOM_Y (updated_row
));
5747 from_x
= output_cursor
.x
;
5749 /* Translate to frame coordinates. */
5750 if (updated_row
->full_width_p
)
5752 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5753 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5757 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5758 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5761 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5762 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5763 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5765 /* Prevent inadvertently clearing to end of the X window. */
5766 if (to_x
> from_x
&& to_y
> from_y
)
5769 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5770 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5777 /* Clear entire frame. If updating_frame is non-null, clear that
5778 frame. Otherwise clear the selected frame. */
5788 f
= SELECTED_FRAME ();
5790 /* Clearing the frame will erase any cursor, so mark them all as no
5792 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5793 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5794 output_cursor
.x
= -1;
5796 /* We don't set the output cursor here because there will always
5797 follow an explicit cursor_to. */
5799 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5801 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5802 /* We have to clear the scroll bars, too. If we have changed
5803 colors or something like that, then they should be notified. */
5804 x_scroll_bar_clear (f
);
5807 XFlush (FRAME_MAC_DISPLAY (f
));
5813 /* Invert the middle quarter of the frame for .15 sec. */
5815 /* We use the select system call to do the waiting, so we have to make
5816 sure it's available. If it isn't, we just won't do visual bells. */
5818 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5820 /* Subtract the `struct timeval' values X and Y, storing the result in
5821 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5824 timeval_subtract (result
, x
, y
)
5825 struct timeval
*result
, x
, y
;
5827 /* Perform the carry for the later subtraction by updating y. This
5828 is safer because on some systems the tv_sec member is unsigned. */
5829 if (x
.tv_usec
< y
.tv_usec
)
5831 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5832 y
.tv_usec
-= 1000000 * nsec
;
5836 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5838 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5839 y
.tv_usec
+= 1000000 * nsec
;
5843 /* Compute the time remaining to wait. tv_usec is certainly
5845 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5846 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5848 /* Return indication of whether the result should be considered
5850 return x
.tv_sec
< y
.tv_sec
;
5862 struct timeval wakeup
;
5864 EMACS_GET_TIME (wakeup
);
5866 /* Compute time to wait until, propagating carry from usecs. */
5867 wakeup
.tv_usec
+= 150000;
5868 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5869 wakeup
.tv_usec
%= 1000000;
5871 /* Keep waiting until past the time wakeup. */
5874 struct timeval timeout
;
5876 EMACS_GET_TIME (timeout
);
5878 /* In effect, timeout = wakeup - timeout.
5879 Break if result would be negative. */
5880 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5883 /* Try to wait that long--but we might wake up sooner. */
5884 select (0, NULL
, NULL
, NULL
, &timeout
);
5893 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5896 /* Make audible bell. */
5901 struct frame
*f
= SELECTED_FRAME ();
5903 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5911 XFlush (FRAME_MAC_DISPLAY (f
));
5918 /* Specify how many text lines, from the top of the window,
5919 should be affected by insert-lines and delete-lines operations.
5920 This, and those operations, are used only within an update
5921 that is bounded by calls to x_update_begin and x_update_end. */
5924 XTset_terminal_window (n
)
5927 /* This function intentionally left blank. */
5932 /***********************************************************************
5934 ***********************************************************************/
5936 /* Perform an insert-lines or delete-lines operation, inserting N
5937 lines or deleting -N lines at vertical position VPOS. */
5940 x_ins_del_lines (vpos
, n
)
5947 /* Scroll part of the display as described by RUN. */
5950 x_scroll_run (w
, run
)
5954 struct frame
*f
= XFRAME (w
->frame
);
5955 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5957 /* Get frame-relative bounding box of the text display area of W,
5958 without mode lines. Include in this box the left and right
5960 window_box (w
, -1, &x
, &y
, &width
, &height
);
5961 width
+= FRAME_X_FRINGE_WIDTH (f
);
5962 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5964 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5965 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5966 bottom_y
= y
+ height
;
5970 /* Scrolling up. Make sure we don't copy part of the mode
5971 line at the bottom. */
5972 if (from_y
+ run
->height
> bottom_y
)
5973 height
= bottom_y
- from_y
;
5975 height
= run
->height
;
5979 /* Scolling down. Make sure we don't copy over the mode line.
5981 if (to_y
+ run
->height
> bottom_y
)
5982 height
= bottom_y
- to_y
;
5984 height
= run
->height
;
5989 /* Cursor off. Will be switched on again in x_update_window_end. */
5993 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5994 f
->output_data
.mac
->normal_gc
,
6004 /***********************************************************************
6006 ***********************************************************************/
6008 /* Redisplay an exposed area of frame F. X and Y are the upper-left
6009 corner of the exposed rectangle. W and H are width and height of
6010 the exposed area. All are pixel values. W or H zero means redraw
6011 the entire frame. */
6014 expose_frame (f
, x
, y
, w
, h
)
6019 int mouse_face_overwritten_p
= 0;
6021 TRACE ((stderr
, "expose_frame "));
6023 /* No need to redraw if frame will be redrawn soon. */
6024 if (FRAME_GARBAGED_P (f
))
6026 TRACE ((stderr
, " garbaged\n"));
6030 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
6031 or deactivated here, for unknown reasons, activated scroll bars
6032 are shown in deactivated frames in some instances. */
6033 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6034 activate_scroll_bars (f
);
6036 deactivate_scroll_bars (f
);
6038 /* If basic faces haven't been realized yet, there is no point in
6039 trying to redraw anything. This can happen when we get an expose
6040 event while Emacs is starting, e.g. by moving another window. */
6041 if (FRAME_FACE_CACHE (f
) == NULL
6042 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
6044 TRACE ((stderr
, " no faces\n"));
6048 if (w
== 0 || h
== 0)
6051 r
.right
= CANON_X_UNIT (f
) * f
->width
;
6052 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
6062 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
6063 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
6065 if (WINDOWP (f
->tool_bar_window
))
6066 mouse_face_overwritten_p
6067 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
6069 /* Some window managers support a focus-follows-mouse style with
6070 delayed raising of frames. Imagine a partially obscured frame,
6071 and moving the mouse into partially obscured mouse-face on that
6072 frame. The visible part of the mouse-face will be highlighted,
6073 then the WM raises the obscured frame. With at least one WM, KDE
6074 2.1, Emacs is not getting any event for the raising of the frame
6075 (even tried with SubstructureRedirectMask), only Expose events.
6076 These expose events will draw text normally, i.e. not
6077 highlighted. Which means we must redo the highlight here.
6078 Subsume it under ``we love X''. --gerd 2001-08-15 */
6079 /* Included in Windows version because Windows most likely does not
6080 do the right thing if any third party tool offers
6081 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
6082 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
6084 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6085 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6087 int x
= dpyinfo
->mouse_face_mouse_x
;
6088 int y
= dpyinfo
->mouse_face_mouse_y
;
6089 clear_mouse_face (dpyinfo
);
6090 note_mouse_highlight (f
, x
, y
);
6096 /* Redraw (parts) of all windows in the window tree rooted at W that
6097 intersect R. R contains frame pixel coordinates. */
6100 expose_window_tree (w
, r
)
6104 struct frame
*f
= XFRAME (w
->frame
);
6105 int mouse_face_overwritten_p
= 0;
6107 while (w
&& !FRAME_GARBAGED_P (f
))
6109 if (!NILP (w
->hchild
))
6110 mouse_face_overwritten_p
6111 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
6112 else if (!NILP (w
->vchild
))
6113 mouse_face_overwritten_p
6114 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
6116 mouse_face_overwritten_p
|= expose_window (w
, r
);
6118 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
6121 return mouse_face_overwritten_p
;
6125 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
6126 which intersects rectangle R. R is in window-relative coordinates. */
6129 expose_area (w
, row
, r
, area
)
6131 struct glyph_row
*row
;
6133 enum glyph_row_area area
;
6135 struct glyph
*first
= row
->glyphs
[area
];
6136 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
6138 int first_x
, start_x
, x
;
6140 if (area
== TEXT_AREA
&& row
->fill_line_p
)
6141 /* If row extends face to end of line write the whole line. */
6142 x_draw_glyphs (w
, 0, row
, area
,
6144 DRAW_NORMAL_TEXT
, 0);
6147 /* Set START_X to the window-relative start position for drawing glyphs of
6148 AREA. The first glyph of the text area can be partially visible.
6149 The first glyphs of other areas cannot. */
6150 if (area
== LEFT_MARGIN_AREA
)
6152 else if (area
== TEXT_AREA
)
6153 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6155 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6156 + window_box_width (w
, TEXT_AREA
));
6159 /* Find the first glyph that must be redrawn. */
6161 && x
+ first
->pixel_width
< r
->left
)
6163 x
+= first
->pixel_width
;
6167 /* Find the last one. */
6173 x
+= last
->pixel_width
;
6179 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6180 first
- row
->glyphs
[area
],
6181 last
- row
->glyphs
[area
],
6182 DRAW_NORMAL_TEXT
, 0);
6187 /* Redraw the parts of the glyph row ROW on window W intersecting
6188 rectangle R. R is in window-relative coordinates. Value is
6189 non-zero if mouse face was overwritten. */
6192 expose_line (w
, row
, r
)
6194 struct glyph_row
*row
;
6197 xassert (row
->enabled_p
);
6199 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6200 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6201 DRAW_NORMAL_TEXT
, 0);
6204 if (row
->used
[LEFT_MARGIN_AREA
])
6205 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6206 if (row
->used
[TEXT_AREA
])
6207 expose_area (w
, row
, r
, TEXT_AREA
);
6208 if (row
->used
[RIGHT_MARGIN_AREA
])
6209 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6210 x_draw_row_fringe_bitmaps (w
, row
);
6213 return row
->mouse_face_p
;
6217 /* Return non-zero if W's cursor intersects rectangle R. */
6220 x_phys_cursor_in_rect_p (w
, r
)
6225 struct glyph
*cursor_glyph
;
6227 cursor_glyph
= get_phys_cursor_glyph (w
);
6230 cr
.left
= w
->phys_cursor
.x
;
6231 cr
.top
= w
->phys_cursor
.y
;
6232 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6233 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6234 return x_intersect_rectangles (&cr
, r
, &result
);
6241 /* Redraw the part of window W intersection rectagle FR. Pixel
6242 coordinates in FR are frame relative. Call this function with
6243 input blocked. Value is non-zero if the exposure overwrites
6247 expose_window (w
, fr
)
6251 struct frame
*f
= XFRAME (w
->frame
);
6253 int mouse_face_overwritten_p
= 0;
6255 /* If window is not yet fully initialized, do nothing. This can
6256 happen when toolkit scroll bars are used and a window is split.
6257 Reconfiguring the scroll bar will generate an expose for a newly
6259 if (w
->current_matrix
== NULL
)
6262 /* When we're currently updating the window, display and current
6263 matrix usually don't agree. Arrange for a thorough display
6265 if (w
== updated_window
)
6267 SET_FRAME_GARBAGED (f
);
6271 /* Frame-relative pixel rectangle of W. */
6272 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6273 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6274 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6275 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6277 if (x_intersect_rectangles (fr
, &wr
, &r
))
6279 int yb
= window_text_bottom_y (w
);
6280 struct glyph_row
*row
;
6281 int cursor_cleared_p
;
6283 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6284 r
.left
, r
.top
, r
.right
, r
.bottom
));
6286 /* Convert to window coordinates. */
6287 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6288 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6289 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6290 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6292 /* Turn off the cursor. */
6293 if (!w
->pseudo_window_p
6294 && x_phys_cursor_in_rect_p (w
, &r
))
6297 cursor_cleared_p
= 1;
6300 cursor_cleared_p
= 0;
6302 /* Find the first row intersecting the rectangle R. */
6303 for (row
= w
->current_matrix
->rows
;
6308 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6310 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6311 || (y1
> r
.top
&& y1
< r
.bottom
)
6312 || (r
.top
>= y0
&& r
.top
< y1
)
6313 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6315 if (expose_line (w
, row
, &r
))
6316 mouse_face_overwritten_p
= 1;
6323 /* Display the mode line if there is one. */
6324 if (WINDOW_WANTS_MODELINE_P (w
)
6325 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6327 && row
->y
< r
.bottom
)
6329 if (expose_line (w
, row
, &r
))
6330 mouse_face_overwritten_p
= 1;
6333 if (!w
->pseudo_window_p
)
6335 /* Draw border between windows. */
6336 x_draw_vertical_border (w
);
6338 /* Turn the cursor on again. */
6339 if (cursor_cleared_p
)
6340 x_update_window_cursor (w
, 1);
6344 /* Display scroll bar for this window. */
6345 if (!NILP (w
->vertical_scroll_bar
))
6348 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6353 return mouse_face_overwritten_p
;
6357 x_intersect_rectangles (r1
, r2
, result
)
6358 Rect
*r1
, *r2
, *result
;
6361 Rect
*upper
, *lower
;
6362 int intersection_p
= 0;
6364 /* Rerrange so that R1 is the left-most rectangle. */
6365 if (r1
->left
< r2
->left
)
6366 left
= r1
, right
= r2
;
6368 left
= r2
, right
= r1
;
6370 /* X0 of the intersection is right.x0, if this is inside R1,
6371 otherwise there is no intersection. */
6372 if (right
->left
<= left
->right
)
6374 result
->left
= right
->left
;
6376 /* The right end of the intersection is the minimum of the
6377 the right ends of left and right. */
6378 result
->right
= min (left
->right
, right
->right
);
6380 /* Same game for Y. */
6381 if (r1
->top
< r2
->top
)
6382 upper
= r1
, lower
= r2
;
6384 upper
= r2
, lower
= r1
;
6386 /* The upper end of the intersection is lower.y0, if this is inside
6387 of upper. Otherwise, there is no intersection. */
6388 if (lower
->top
<= upper
->bottom
)
6390 result
->top
= lower
->top
;
6392 /* The lower end of the intersection is the minimum of the lower
6393 ends of upper and lower. */
6394 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6399 return intersection_p
;
6410 x_update_cursor (f
, 1);
6414 frame_unhighlight (f
)
6417 x_update_cursor (f
, 1);
6420 /* The focus has changed. Update the frames as necessary to reflect
6421 the new situation. Note that we can't change the selected frame
6422 here, because the Lisp code we are interrupting might become confused.
6423 Each event gets marked with the frame in which it occurred, so the
6424 Lisp code can tell when the switch took place by examining the events. */
6427 x_new_focus_frame (dpyinfo
, frame
)
6428 struct x_display_info
*dpyinfo
;
6429 struct frame
*frame
;
6431 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6433 if (frame
!= dpyinfo
->x_focus_frame
)
6435 /* Set this before calling other routines, so that they see
6436 the correct value of x_focus_frame. */
6437 dpyinfo
->x_focus_frame
= frame
;
6439 if (old_focus
&& old_focus
->auto_lower
)
6440 x_lower_frame (old_focus
);
6443 selected_frame
= frame
;
6444 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6446 Fselect_window (selected_frame
->selected_window
);
6447 choose_minibuf_frame ();
6450 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6451 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6453 pending_autoraise_frame
= 0;
6456 x_frame_rehighlight (dpyinfo
);
6459 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6462 x_mouse_leave (dpyinfo
)
6463 struct x_display_info
*dpyinfo
;
6465 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6468 /* The focus has changed, or we have redirected a frame's focus to
6469 another frame (this happens when a frame uses a surrogate
6470 mini-buffer frame). Shift the highlight as appropriate.
6472 The FRAME argument doesn't necessarily have anything to do with which
6473 frame is being highlighted or un-highlighted; we only use it to find
6474 the appropriate X display info. */
6477 XTframe_rehighlight (frame
)
6478 struct frame
*frame
;
6480 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6484 x_frame_rehighlight (dpyinfo
)
6485 struct x_display_info
*dpyinfo
;
6487 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6489 if (dpyinfo
->x_focus_frame
)
6491 dpyinfo
->x_highlight_frame
6492 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6493 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6494 : dpyinfo
->x_focus_frame
);
6495 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6497 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6498 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6502 dpyinfo
->x_highlight_frame
= 0;
6504 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6507 frame_unhighlight (old_highlight
);
6508 if (dpyinfo
->x_highlight_frame
)
6509 frame_highlight (dpyinfo
->x_highlight_frame
);
6515 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6517 #if 0 /* MAC_TODO */
6518 /* Initialize mode_switch_bit and modifier_meaning. */
6520 x_find_modifier_meanings (dpyinfo
)
6521 struct x_display_info
*dpyinfo
;
6523 int min_code
, max_code
;
6526 XModifierKeymap
*mods
;
6528 dpyinfo
->meta_mod_mask
= 0;
6529 dpyinfo
->shift_lock_mask
= 0;
6530 dpyinfo
->alt_mod_mask
= 0;
6531 dpyinfo
->super_mod_mask
= 0;
6532 dpyinfo
->hyper_mod_mask
= 0;
6535 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6537 min_code
= dpyinfo
->display
->min_keycode
;
6538 max_code
= dpyinfo
->display
->max_keycode
;
6541 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6542 min_code
, max_code
- min_code
+ 1,
6544 mods
= XGetModifierMapping (dpyinfo
->display
);
6546 /* Scan the modifier table to see which modifier bits the Meta and
6547 Alt keysyms are on. */
6549 int row
, col
; /* The row and column in the modifier table. */
6551 for (row
= 3; row
< 8; row
++)
6552 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6555 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6557 /* Zeroes are used for filler. Skip them. */
6561 /* Are any of this keycode's keysyms a meta key? */
6565 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6567 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6573 dpyinfo
->meta_mod_mask
|= (1 << row
);
6578 dpyinfo
->alt_mod_mask
|= (1 << row
);
6583 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6588 dpyinfo
->super_mod_mask
|= (1 << row
);
6592 /* Ignore this if it's not on the lock modifier. */
6593 if ((1 << row
) == LockMask
)
6594 dpyinfo
->shift_lock_mask
= LockMask
;
6602 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6603 if (! dpyinfo
->meta_mod_mask
)
6605 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6606 dpyinfo
->alt_mod_mask
= 0;
6609 /* If some keys are both alt and meta,
6610 make them just meta, not alt. */
6611 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6613 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6616 XFree ((char *) syms
);
6617 XFreeModifiermap (mods
);
6620 #endif /* MAC_TODO */
6622 /* Convert between the modifier bits X uses and the modifier bits
6626 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6627 struct x_display_info
*dpyinfo
;
6628 unsigned short state
;
6630 return (((state
& shiftKey
) ? shift_modifier
: 0)
6631 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6632 | ((state
& cmdKey
) ? meta_modifier
: 0)
6633 | ((state
& optionKey
) ? alt_modifier
: 0));
6636 #if 0 /* MAC_TODO */
6637 static unsigned short
6638 x_emacs_to_x_modifiers (dpyinfo
, state
)
6639 struct x_display_info
*dpyinfo
;
6642 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6643 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6644 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6645 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6646 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6647 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6649 #endif /* MAC_TODO */
6651 /* Convert a keysym to its name. */
6654 x_get_keysym_name (keysym
)
6661 value
= XKeysymToString (keysym
);
6672 /* Mouse clicks and mouse movement. Rah. */
6674 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6675 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6676 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6677 not force the value into range. */
6680 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6682 register int pix_x
, pix_y
;
6683 register int *x
, *y
;
6687 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6688 if (NILP (Vwindow_system
))
6695 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6696 even for negative values. */
6698 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6700 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6702 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6703 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6707 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6708 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6709 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6710 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6717 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6718 pix_x
= FRAME_WINDOW_WIDTH (f
);
6722 else if (pix_y
> f
->height
)
6731 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6732 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6733 can't tell the positions because W's display is not up to date,
6737 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6740 int *frame_x
, *frame_y
;
6744 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6745 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6747 if (display_completed
)
6749 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6750 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6751 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6757 *frame_x
+= glyph
->pixel_width
;
6765 *frame_y
= *frame_x
= 0;
6769 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6770 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6775 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6777 If the event is a button press, then note that we have grabbed
6781 construct_mouse_click (result
, event
, f
)
6782 struct input_event
*result
;
6788 result
->kind
= MOUSE_CLICK_EVENT
;
6789 result
->code
= 0; /* only one mouse button */
6790 result
->timestamp
= event
->when
;
6791 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6793 mouseLoc
= event
->where
;
6795 #if TARGET_API_MAC_CARBON
6796 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6798 SetPort (FRAME_MAC_WINDOW (f
));
6801 GlobalToLocal (&mouseLoc
);
6802 XSETINT (result
->x
, mouseLoc
.h
);
6803 XSETINT (result
->y
, mouseLoc
.v
);
6805 XSETFRAME (result
->frame_or_window
, f
);
6812 /* Function to report a mouse movement to the mainstream Emacs code.
6813 The input handler calls this.
6815 We have received a mouse movement event, which is given in *event.
6816 If the mouse is over a different glyph than it was last time, tell
6817 the mainstream emacs code by setting mouse_moved. If not, ask for
6818 another motion event, so we can check again the next time it moves. */
6820 static Point last_mouse_motion_position
;
6821 static Lisp_Object last_mouse_motion_frame
;
6824 note_mouse_movement (frame
, pos
)
6828 #if TARGET_API_MAC_CARBON
6832 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6833 last_mouse_motion_position
= *pos
;
6834 XSETFRAME (last_mouse_motion_frame
, frame
);
6836 #if TARGET_API_MAC_CARBON
6837 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6839 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6842 frame
->mouse_moved
= 1;
6843 last_mouse_scroll_bar
= Qnil
;
6844 note_mouse_highlight (frame
, -1, -1);
6846 /* Has the mouse moved off the glyph it was on at the last sighting? */
6847 else if (pos
->h
< last_mouse_glyph
.left
6848 || pos
->h
>= last_mouse_glyph
.right
6849 || pos
->v
< last_mouse_glyph
.top
6850 || pos
->v
>= last_mouse_glyph
.bottom
)
6852 frame
->mouse_moved
= 1;
6853 last_mouse_scroll_bar
= Qnil
;
6854 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6858 /* This is used for debugging, to turn off note_mouse_highlight. */
6860 int disable_mouse_highlight
;
6864 /************************************************************************
6866 ************************************************************************/
6868 /* Find the glyph under window-relative coordinates X/Y in window W.
6869 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6870 strings. Return in *HPOS and *VPOS the row and column number of
6871 the glyph found. Return in *AREA the glyph area containing X.
6872 Value is a pointer to the glyph found or null if X/Y is not on
6873 text, or we can't tell because W's current matrix is not up to
6876 static struct glyph
*
6877 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6880 int *hpos
, *vpos
, *area
;
6883 struct glyph
*glyph
, *end
;
6884 struct glyph_row
*row
= NULL
;
6885 int x0
, i
, left_area_width
;
6887 /* Find row containing Y. Give up if some row is not enabled. */
6888 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6890 row
= MATRIX_ROW (w
->current_matrix
, i
);
6891 if (!row
->enabled_p
)
6893 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6900 /* Give up if Y is not in the window. */
6901 if (i
== w
->current_matrix
->nrows
)
6904 /* Get the glyph area containing X. */
6905 if (w
->pseudo_window_p
)
6912 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6913 if (x
< left_area_width
)
6915 *area
= LEFT_MARGIN_AREA
;
6918 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6921 x0
= row
->x
+ left_area_width
;
6925 *area
= RIGHT_MARGIN_AREA
;
6926 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6930 /* Find glyph containing X. */
6931 glyph
= row
->glyphs
[*area
];
6932 end
= glyph
+ row
->used
[*area
];
6935 if (x
< x0
+ glyph
->pixel_width
)
6937 if (w
->pseudo_window_p
)
6939 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6943 x0
+= glyph
->pixel_width
;
6950 *hpos
= glyph
- row
->glyphs
[*area
];
6955 /* Convert frame-relative x/y to coordinates relative to window W.
6956 Takes pseudo-windows into account. */
6959 frame_to_window_pixel_xy (w
, x
, y
)
6963 if (w
->pseudo_window_p
)
6965 /* A pseudo-window is always full-width, and starts at the
6966 left edge of the frame, plus a frame border. */
6967 struct frame
*f
= XFRAME (w
->frame
);
6968 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6969 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6973 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6974 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6979 /* Take proper action when mouse has moved to the mode or header line of
6980 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6981 mode line. X is relative to the start of the text display area of
6982 W, so the width of fringes and scroll bars must be subtracted
6983 to get a position relative to the start of the mode line. */
6986 note_mode_line_highlight (w
, x
, mode_line_p
)
6990 struct frame
*f
= XFRAME (w
->frame
);
6991 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6992 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6993 struct glyph_row
*row
;
6996 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6998 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
7002 struct glyph
*glyph
, *end
;
7003 Lisp_Object help
, map
;
7006 /* Find the glyph under X. */
7007 glyph
= row
->glyphs
[TEXT_AREA
];
7008 end
= glyph
+ row
->used
[TEXT_AREA
];
7009 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
7010 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
7013 && x
>= x0
+ glyph
->pixel_width
)
7015 x0
+= glyph
->pixel_width
;
7020 && STRINGP (glyph
->object
)
7021 && STRING_INTERVALS (glyph
->object
)
7022 && glyph
->charpos
>= 0
7023 && glyph
->charpos
< SCHARS (glyph
->object
))
7025 /* If we're on a string with `help-echo' text property,
7026 arrange for the help to be displayed. This is done by
7027 setting the global variable help_echo to the help string. */
7028 help
= Fget_text_property (make_number (glyph
->charpos
),
7029 Qhelp_echo
, glyph
->object
);
7033 XSETWINDOW (help_echo_window
, w
);
7034 help_echo_object
= glyph
->object
;
7035 help_echo_pos
= glyph
->charpos
;
7038 /* Change the mouse pointer according to what is under X/Y. */
7039 map
= Fget_text_property (make_number (glyph
->charpos
),
7040 Qlocal_map
, glyph
->object
);
7042 cursor
= f
->output_data
.mac
->nontext_cursor
;
7045 map
= Fget_text_property (make_number (glyph
->charpos
),
7046 Qkeymap
, glyph
->object
);
7048 cursor
= f
->output_data
.mac
->nontext_cursor
;
7053 #if 0 /* MAC_TODO: mouse cursor */
7054 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7059 /* Take proper action when the mouse has moved to position X, Y on
7060 frame F as regards highlighting characters that have mouse-face
7061 properties. Also de-highlighting chars where the mouse was before.
7062 X and Y can be negative or out of range. */
7065 note_mouse_highlight (f
, x
, y
)
7069 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7076 /* When a menu is active, don't highlight because this looks odd. */
7077 if (popup_activated ())
7081 if (NILP (Vmouse_highlight
)
7082 || !f
->glyphs_initialized_p
)
7085 dpyinfo
->mouse_face_mouse_x
= x
;
7086 dpyinfo
->mouse_face_mouse_y
= y
;
7087 dpyinfo
->mouse_face_mouse_frame
= f
;
7089 if (dpyinfo
->mouse_face_defer
)
7094 dpyinfo
->mouse_face_deferred_gc
= 1;
7098 /* Which window is that in? */
7099 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7101 /* If we were displaying active text in another window, clear that. */
7102 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7103 clear_mouse_face (dpyinfo
);
7105 /* Not on a window -> return. */
7106 if (!WINDOWP (window
))
7109 /* Reset help_echo. It will get recomputed below. */
7112 /* Convert to window-relative pixel coordinates. */
7113 w
= XWINDOW (window
);
7114 frame_to_window_pixel_xy (w
, &x
, &y
);
7116 /* Handle tool-bar window differently since it doesn't display a
7118 if (EQ (window
, f
->tool_bar_window
))
7120 note_tool_bar_highlight (f
, x
, y
);
7124 /* Mouse is on the mode or header line? */
7125 if (portion
== 1 || portion
== 3)
7127 note_mode_line_highlight (w
, x
, portion
== 1);
7130 #if 0 /* TODO: mouse cursor */
7132 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7134 cursor
= f
->output_data
.x
->text_cursor
;
7136 /* Are we in a window whose display is up to date?
7137 And verify the buffer's text has not changed. */
7138 b
= XBUFFER (w
->buffer
);
7139 if (/* Within text portion of the window. */
7141 && EQ (w
->window_end_valid
, w
->buffer
)
7142 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7143 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7145 int hpos
, vpos
, pos
, i
, area
;
7146 struct glyph
*glyph
;
7148 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7149 Lisp_Object
*overlay_vec
= NULL
;
7151 struct buffer
*obuf
;
7152 int obegv
, ozv
, same_region
;
7154 /* Find the glyph under X/Y. */
7155 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7157 /* Clear mouse face if X/Y not over text. */
7159 || area
!= TEXT_AREA
7160 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7162 clear_mouse_face (dpyinfo
);
7163 /* TODO: mouse cursor */
7167 pos
= glyph
->charpos
;
7168 object
= glyph
->object
;
7169 if (!STRINGP (object
) && !BUFFERP (object
))
7172 /* If we get an out-of-range value, return now; avoid an error. */
7173 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7176 /* Make the window's buffer temporarily current for
7177 overlays_at and compute_char_face. */
7178 obuf
= current_buffer
;
7185 /* Is this char mouse-active or does it have help-echo? */
7186 position
= make_number (pos
);
7188 if (BUFFERP (object
))
7190 /* Put all the overlays we want in a vector in overlay_vec.
7191 Store the length in len. If there are more than 10, make
7192 enough space for all, and try again. */
7194 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7195 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7196 if (noverlays
> len
)
7199 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7200 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7203 /* Sort overlays into increasing priority order. */
7204 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7209 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7210 && vpos
>= dpyinfo
->mouse_face_beg_row
7211 && vpos
<= dpyinfo
->mouse_face_end_row
7212 && (vpos
> dpyinfo
->mouse_face_beg_row
7213 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7214 && (vpos
< dpyinfo
->mouse_face_end_row
7215 || hpos
< dpyinfo
->mouse_face_end_col
7216 || dpyinfo
->mouse_face_past_end
));
7218 /* TODO: if (same_region)
7221 /* Check mouse-face highlighting. */
7223 /* If there exists an overlay with mouse-face overlapping
7224 the one we are currently highlighting, we have to
7225 check if we enter the overlapping overlay, and then
7227 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7228 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7230 /* Find the highest priority overlay that has a mouse-face
7233 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7235 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7236 if (!NILP (mouse_face
))
7237 overlay
= overlay_vec
[i
];
7240 /* If we're actually highlighting the same overlay as
7241 before, there's no need to do that again. */
7243 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7244 goto check_help_echo
;
7246 dpyinfo
->mouse_face_overlay
= overlay
;
7248 /* Clear the display of the old active region, if any. */
7249 clear_mouse_face (dpyinfo
);
7250 /* TODO: mouse cursor changes. */
7252 /* If no overlay applies, get a text property. */
7254 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7256 /* Handle the overlay case. */
7257 if (!NILP (overlay
))
7259 /* Find the range of text around this char that
7260 should be active. */
7261 Lisp_Object before
, after
;
7264 before
= Foverlay_start (overlay
);
7265 after
= Foverlay_end (overlay
);
7266 /* Record this as the current active region. */
7267 fast_find_position (w
, XFASTINT (before
),
7268 &dpyinfo
->mouse_face_beg_col
,
7269 &dpyinfo
->mouse_face_beg_row
,
7270 &dpyinfo
->mouse_face_beg_x
,
7271 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7273 dpyinfo
->mouse_face_past_end
7274 = !fast_find_position (w
, XFASTINT (after
),
7275 &dpyinfo
->mouse_face_end_col
,
7276 &dpyinfo
->mouse_face_end_row
,
7277 &dpyinfo
->mouse_face_end_x
,
7278 &dpyinfo
->mouse_face_end_y
, Qnil
);
7279 dpyinfo
->mouse_face_window
= window
;
7281 dpyinfo
->mouse_face_face_id
7282 = face_at_buffer_position (w
, pos
, 0, 0,
7283 &ignore
, pos
+ 1, 1);
7285 /* Display it as active. */
7286 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7287 /* TODO: mouse cursor changes. */
7289 /* Handle the text property case. */
7290 else if (! NILP (mouse_face
) && BUFFERP (object
))
7292 /* Find the range of text around this char that
7293 should be active. */
7294 Lisp_Object before
, after
, beginning
, end
;
7297 beginning
= Fmarker_position (w
->start
);
7298 end
= make_number (BUF_Z (XBUFFER (object
))
7299 - XFASTINT (w
->window_end_pos
));
7301 = Fprevious_single_property_change (make_number (pos
+ 1),
7305 = Fnext_single_property_change (position
, Qmouse_face
,
7308 /* Record this as the current active region. */
7309 fast_find_position (w
, XFASTINT (before
),
7310 &dpyinfo
->mouse_face_beg_col
,
7311 &dpyinfo
->mouse_face_beg_row
,
7312 &dpyinfo
->mouse_face_beg_x
,
7313 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7314 dpyinfo
->mouse_face_past_end
7315 = !fast_find_position (w
, XFASTINT (after
),
7316 &dpyinfo
->mouse_face_end_col
,
7317 &dpyinfo
->mouse_face_end_row
,
7318 &dpyinfo
->mouse_face_end_x
,
7319 &dpyinfo
->mouse_face_end_y
, Qnil
);
7320 dpyinfo
->mouse_face_window
= window
;
7322 if (BUFFERP (object
))
7323 dpyinfo
->mouse_face_face_id
7324 = face_at_buffer_position (w
, pos
, 0, 0,
7325 &ignore
, pos
+ 1, 1);
7327 /* Display it as active. */
7328 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7329 /* TODO: mouse cursor changes. */
7331 else if (!NILP (mouse_face
) && STRINGP (object
))
7336 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7339 e
= Fnext_single_property_change (position
, Qmouse_face
,
7342 b
= make_number (0);
7344 e
= make_number (SCHARS (object
) - 1);
7345 fast_find_string_pos (w
, XINT (b
), object
,
7346 &dpyinfo
->mouse_face_beg_col
,
7347 &dpyinfo
->mouse_face_beg_row
,
7348 &dpyinfo
->mouse_face_beg_x
,
7349 &dpyinfo
->mouse_face_beg_y
, 0);
7350 fast_find_string_pos (w
, XINT (e
), object
,
7351 &dpyinfo
->mouse_face_end_col
,
7352 &dpyinfo
->mouse_face_end_row
,
7353 &dpyinfo
->mouse_face_end_x
,
7354 &dpyinfo
->mouse_face_end_y
, 1);
7355 dpyinfo
->mouse_face_past_end
= 0;
7356 dpyinfo
->mouse_face_window
= window
;
7357 dpyinfo
->mouse_face_face_id
7358 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7360 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7361 /* TODO: mouse cursor changes. */
7363 else if (STRINGP (object
) && NILP (mouse_face
))
7365 /* A string which doesn't have mouse-face, but
7366 the text ``under'' it might have. */
7367 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7368 int start
= MATRIX_ROW_START_CHARPOS (r
);
7370 pos
= string_buffer_position (w
, object
, start
);
7372 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7376 if (!NILP (mouse_face
) && !NILP (overlay
))
7378 Lisp_Object before
= Foverlay_start (overlay
);
7379 Lisp_Object after
= Foverlay_end (overlay
);
7382 /* Note that we might not be able to find position
7383 BEFORE in the glyph matrix if the overlay is
7384 entirely covered by a `display' property. In
7385 this case, we overshoot. So let's stop in
7386 the glyph matrix before glyphs for OBJECT. */
7387 fast_find_position (w
, XFASTINT (before
),
7388 &dpyinfo
->mouse_face_beg_col
,
7389 &dpyinfo
->mouse_face_beg_row
,
7390 &dpyinfo
->mouse_face_beg_x
,
7391 &dpyinfo
->mouse_face_beg_y
,
7394 dpyinfo
->mouse_face_past_end
7395 = !fast_find_position (w
, XFASTINT (after
),
7396 &dpyinfo
->mouse_face_end_col
,
7397 &dpyinfo
->mouse_face_end_row
,
7398 &dpyinfo
->mouse_face_end_x
,
7399 &dpyinfo
->mouse_face_end_y
,
7401 dpyinfo
->mouse_face_window
= window
;
7402 dpyinfo
->mouse_face_face_id
7403 = face_at_buffer_position (w
, pos
, 0, 0,
7404 &ignore
, pos
+ 1, 1);
7406 /* Display it as active. */
7407 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7408 /* TODO: mouse cursor changes. */
7415 /* Look for a `help-echo' property. */
7417 Lisp_Object help
, overlay
;
7419 /* Check overlays first. */
7420 help
= overlay
= Qnil
;
7421 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7423 overlay
= overlay_vec
[i
];
7424 help
= Foverlay_get (overlay
, Qhelp_echo
);
7430 help_echo_window
= window
;
7431 help_echo_object
= overlay
;
7432 help_echo_pos
= pos
;
7436 Lisp_Object object
= glyph
->object
;
7437 int charpos
= glyph
->charpos
;
7439 /* Try text properties. */
7440 if (STRINGP (object
)
7442 && charpos
< SCHARS (object
))
7444 help
= Fget_text_property (make_number (charpos
),
7445 Qhelp_echo
, object
);
7448 /* If the string itself doesn't specify a help-echo,
7449 see if the buffer text ``under'' it does. */
7451 = MATRIX_ROW (w
->current_matrix
, vpos
);
7452 int start
= MATRIX_ROW_START_CHARPOS (r
);
7453 int pos
= string_buffer_position (w
, object
, start
);
7456 help
= Fget_char_property (make_number (pos
),
7457 Qhelp_echo
, w
->buffer
);
7466 else if (BUFFERP (object
)
7469 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7475 help_echo_window
= window
;
7476 help_echo_object
= object
;
7477 help_echo_pos
= charpos
;
7484 current_buffer
= obuf
;
7488 /* TODO: mouse cursor changes. */
7493 redo_mouse_highlight ()
7495 if (!NILP (last_mouse_motion_frame
)
7496 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7497 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7498 last_mouse_motion_position
.h
,
7499 last_mouse_motion_position
.v
);
7504 /***********************************************************************
7506 ***********************************************************************/
7508 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7509 struct glyph
**, int *, int *, int *));
7511 /* Tool-bar item index of the item on which a mouse button was pressed
7514 static int last_tool_bar_item
;
7517 /* Get information about the tool-bar item at position X/Y on frame F.
7518 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7519 the current matrix of the tool-bar window of F, or NULL if not
7520 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7521 item in F->current_tool_bar_items. Value is
7523 -1 if X/Y is not on a tool-bar item
7524 0 if X/Y is on the same item that was highlighted before.
7528 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7531 struct glyph
**glyph
;
7532 int *hpos
, *vpos
, *prop_idx
;
7534 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7535 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7538 /* Find the glyph under X/Y. */
7539 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7543 /* Get the start of this tool-bar item's properties in
7544 f->current_tool_bar_items. */
7545 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7548 /* Is mouse on the highlighted item? */
7549 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7550 && *vpos
>= dpyinfo
->mouse_face_beg_row
7551 && *vpos
<= dpyinfo
->mouse_face_end_row
7552 && (*vpos
> dpyinfo
->mouse_face_beg_row
7553 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7554 && (*vpos
< dpyinfo
->mouse_face_end_row
7555 || *hpos
< dpyinfo
->mouse_face_end_col
7556 || dpyinfo
->mouse_face_past_end
))
7563 /* Handle mouse button event on the tool-bar of frame F, at
7564 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7568 x_handle_tool_bar_click (f
, button_event
)
7570 EventRecord
*button_event
;
7572 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7573 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7574 int hpos
, vpos
, prop_idx
;
7575 struct glyph
*glyph
;
7576 Lisp_Object enabled_p
;
7577 int x
= button_event
->where
.h
;
7578 int y
= button_event
->where
.v
;
7580 /* If not on the highlighted tool-bar item, return. */
7581 frame_to_window_pixel_xy (w
, &x
, &y
);
7582 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7585 /* If item is disabled, do nothing. */
7586 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7587 if (NILP (enabled_p
))
7590 if (button_event
->what
== mouseDown
)
7592 /* Show item in pressed state. */
7593 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7594 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7595 last_tool_bar_item
= prop_idx
;
7599 Lisp_Object key
, frame
;
7600 struct input_event event
;
7602 /* Show item in released state. */
7603 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7604 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7606 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7608 XSETFRAME (frame
, f
);
7609 event
.kind
= TOOL_BAR_EVENT
;
7610 event
.frame_or_window
= frame
;
7612 kbd_buffer_store_event (&event
);
7614 event
.kind
= TOOL_BAR_EVENT
;
7615 event
.frame_or_window
= frame
;
7617 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7618 button_event
->modifiers
);
7619 kbd_buffer_store_event (&event
);
7620 last_tool_bar_item
= -1;
7625 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7626 tool-bar window-relative coordinates X/Y. Called from
7627 note_mouse_highlight. */
7630 note_tool_bar_highlight (f
, x
, y
)
7634 Lisp_Object window
= f
->tool_bar_window
;
7635 struct window
*w
= XWINDOW (window
);
7636 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7638 struct glyph
*glyph
;
7639 struct glyph_row
*row
;
7641 Lisp_Object enabled_p
;
7643 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7644 int mouse_down_p
, rc
;
7646 /* Function note_mouse_highlight is called with negative x(y
7647 values when mouse moves outside of the frame. */
7648 if (x
<= 0 || y
<= 0)
7650 clear_mouse_face (dpyinfo
);
7654 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7657 /* Not on tool-bar item. */
7658 clear_mouse_face (dpyinfo
);
7662 /* On same tool-bar item as before. */
7665 clear_mouse_face (dpyinfo
);
7667 /* Mouse is down, but on different tool-bar item? */
7668 mouse_down_p
= (dpyinfo
->grabbed
7669 && f
== last_mouse_frame
7670 && FRAME_LIVE_P (f
));
7672 && last_tool_bar_item
!= prop_idx
)
7675 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7676 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7678 /* If tool-bar item is not enabled, don't highlight it. */
7679 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7680 if (!NILP (enabled_p
))
7682 /* Compute the x-position of the glyph. In front and past the
7683 image is a space. We include this is the highlighted area. */
7684 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7685 for (i
= x
= 0; i
< hpos
; ++i
)
7686 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7688 /* Record this as the current active region. */
7689 dpyinfo
->mouse_face_beg_col
= hpos
;
7690 dpyinfo
->mouse_face_beg_row
= vpos
;
7691 dpyinfo
->mouse_face_beg_x
= x
;
7692 dpyinfo
->mouse_face_beg_y
= row
->y
;
7693 dpyinfo
->mouse_face_past_end
= 0;
7695 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7696 dpyinfo
->mouse_face_end_row
= vpos
;
7697 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7698 dpyinfo
->mouse_face_end_y
= row
->y
;
7699 dpyinfo
->mouse_face_window
= window
;
7700 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7702 /* Display it as active. */
7703 show_mouse_face (dpyinfo
, draw
);
7704 dpyinfo
->mouse_face_image_state
= draw
;
7709 /* Set help_echo to a help string.to display for this tool-bar item.
7710 XTread_socket does the rest. */
7711 help_echo_object
= help_echo_window
= Qnil
;
7713 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7714 if (NILP (help_echo
))
7715 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7720 /* Find the glyph matrix position of buffer position CHARPOS in window
7721 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7722 current glyphs must be up to date. If CHARPOS is above window
7723 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7724 of last line in W. In the row containing CHARPOS, stop before glyphs
7725 having STOP as object. */
7727 #if 0 /* This is a version of fast_find_position that's more correct
7728 in the presence of hscrolling, for example. I didn't install
7729 it right away because the problem fixed is minor, it failed
7730 in 20.x as well, and I think it's too risky to install
7731 so near the release of 21.1. 2001-09-25 gerd. */
7734 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7737 int *hpos
, *vpos
, *x
, *y
;
7740 struct glyph_row
*row
, *first
;
7741 struct glyph
*glyph
, *end
;
7742 int i
, past_end
= 0;
7744 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7745 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7748 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7750 *x
= *y
= *hpos
= *vpos
= 0;
7755 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7762 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7764 glyph
= row
->glyphs
[TEXT_AREA
];
7765 end
= glyph
+ row
->used
[TEXT_AREA
];
7767 /* Skip over glyphs not having an object at the start of the row.
7768 These are special glyphs like truncation marks on terminal
7770 if (row
->displays_text_p
)
7772 && INTEGERP (glyph
->object
)
7773 && !EQ (stop
, glyph
->object
)
7774 && glyph
->charpos
< 0)
7776 *x
+= glyph
->pixel_width
;
7781 && !INTEGERP (glyph
->object
)
7782 && !EQ (stop
, glyph
->object
)
7783 && (!BUFFERP (glyph
->object
)
7784 || glyph
->charpos
< charpos
))
7786 *x
+= glyph
->pixel_width
;
7790 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7797 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7800 int *hpos
, *vpos
, *x
, *y
;
7805 int maybe_next_line_p
= 0;
7806 int line_start_position
;
7807 int yb
= window_text_bottom_y (w
);
7808 struct glyph_row
*row
, *best_row
;
7809 int row_vpos
, best_row_vpos
;
7812 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7813 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7817 if (row
->used
[TEXT_AREA
])
7818 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7820 line_start_position
= 0;
7822 if (line_start_position
> pos
)
7824 /* If the position sought is the end of the buffer,
7825 don't include the blank lines at the bottom of the window. */
7826 else if (line_start_position
== pos
7827 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7829 maybe_next_line_p
= 1;
7832 else if (line_start_position
> 0)
7835 best_row_vpos
= row_vpos
;
7838 if (row
->y
+ row
->height
>= yb
)
7845 /* Find the right column within BEST_ROW. */
7847 current_x
= best_row
->x
;
7848 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7850 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7851 int charpos
= glyph
->charpos
;
7853 if (BUFFERP (glyph
->object
))
7858 *vpos
= best_row_vpos
;
7863 else if (charpos
> pos
)
7866 else if (EQ (glyph
->object
, stop
))
7871 current_x
+= glyph
->pixel_width
;
7874 /* If we're looking for the end of the buffer,
7875 and we didn't find it in the line we scanned,
7876 use the start of the following line. */
7877 if (maybe_next_line_p
)
7882 current_x
= best_row
->x
;
7885 *vpos
= best_row_vpos
;
7886 *hpos
= lastcol
+ 1;
7895 /* Find the position of the glyph for position POS in OBJECT in
7896 window W's current matrix, and return in *X/*Y the pixel
7897 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7899 RIGHT_P non-zero means return the position of the right edge of the
7900 glyph, RIGHT_P zero means return the left edge position.
7902 If no glyph for POS exists in the matrix, return the position of
7903 the glyph with the next smaller position that is in the matrix, if
7904 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7905 exists in the matrix, return the position of the glyph with the
7906 next larger position in OBJECT.
7908 Value is non-zero if a glyph was found. */
7911 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7915 int *hpos
, *vpos
, *x
, *y
;
7918 int yb
= window_text_bottom_y (w
);
7919 struct glyph_row
*r
;
7920 struct glyph
*best_glyph
= NULL
;
7921 struct glyph_row
*best_row
= NULL
;
7924 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7925 r
->enabled_p
&& r
->y
< yb
;
7928 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7929 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7932 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7933 if (EQ (g
->object
, object
))
7935 if (g
->charpos
== pos
)
7942 else if (best_glyph
== NULL
7943 || ((abs (g
->charpos
- pos
)
7944 < abs (best_glyph
->charpos
- pos
))
7947 : g
->charpos
> pos
)))
7961 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7965 *x
+= best_glyph
->pixel_width
;
7970 *vpos
= best_row
- w
->current_matrix
->rows
;
7973 return best_glyph
!= NULL
;
7977 /* Display the active region described by mouse_face_*
7978 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7981 show_mouse_face (dpyinfo
, draw
)
7982 struct mac_display_info
*dpyinfo
;
7983 enum draw_glyphs_face draw
;
7985 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7986 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7988 if (/* If window is in the process of being destroyed, don't bother
7990 w
->current_matrix
!= NULL
7991 /* Don't update mouse highlight if hidden */
7992 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7993 /* Recognize when we are called to operate on rows that don't exist
7994 anymore. This can happen when a window is split. */
7995 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7997 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7998 struct glyph_row
*row
, *first
, *last
;
8000 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
8001 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
8003 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
8005 int start_hpos
, end_hpos
, start_x
;
8007 /* For all but the first row, the highlight starts at column 0. */
8010 start_hpos
= dpyinfo
->mouse_face_beg_col
;
8011 start_x
= dpyinfo
->mouse_face_beg_x
;
8020 end_hpos
= dpyinfo
->mouse_face_end_col
;
8022 end_hpos
= row
->used
[TEXT_AREA
];
8024 if (end_hpos
> start_hpos
)
8026 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
8027 start_hpos
, end_hpos
, draw
, 0);
8030 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8034 /* When we've written over the cursor, arrange for it to
8035 be displayed again. */
8036 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8037 x_display_cursor (w
, 1,
8038 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8039 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8042 #if 0 /* MAC_TODO: mouse cursor */
8043 /* Change the mouse cursor. */
8044 if (draw
== DRAW_NORMAL_TEXT
)
8045 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8046 f
->output_data
.x
->text_cursor
);
8047 else if (draw
== DRAW_MOUSE_FACE
)
8048 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8049 f
->output_data
.x
->cross_cursor
);
8051 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8052 f
->output_data
.x
->nontext_cursor
);
8056 /* Clear out the mouse-highlighted active region.
8057 Redraw it un-highlighted first. */
8060 clear_mouse_face (dpyinfo
)
8061 struct mac_display_info
*dpyinfo
;
8065 if (! NILP (dpyinfo
->mouse_face_window
))
8067 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8071 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8072 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8073 dpyinfo
->mouse_face_window
= Qnil
;
8074 dpyinfo
->mouse_face_overlay
= Qnil
;
8079 /* Clear any mouse-face on window W. This function is part of the
8080 redisplay interface, and is called from try_window_id and similar
8081 functions to ensure the mouse-highlight is off. */
8084 x_clear_mouse_face (w
)
8087 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
8091 XSETWINDOW (window
, w
);
8092 if (EQ (window
, dpyinfo
->mouse_face_window
))
8093 clear_mouse_face (dpyinfo
);
8098 /* Just discard the mouse face information for frame F, if any.
8099 This is used when the size of F is changed. */
8102 cancel_mouse_face (f
)
8106 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8108 window
= dpyinfo
->mouse_face_window
;
8109 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8111 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8112 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8113 dpyinfo
->mouse_face_window
= Qnil
;
8117 static struct scroll_bar
*x_window_to_scroll_bar ();
8118 static void x_scroll_bar_report_motion ();
8119 static void x_check_fullscreen
P_ ((struct frame
*));
8120 static void x_check_fullscreen_move
P_ ((struct frame
*));
8121 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
8124 /* Try to determine frame pixel position and size of the glyph under
8125 frame pixel coordinates X/Y on frame F . Return the position and
8126 size in *RECT. Value is non-zero if we could compute these
8130 glyph_rect (f
, x
, y
, rect
)
8138 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8141 struct window
*w
= XWINDOW (window
);
8142 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8143 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8145 frame_to_window_pixel_xy (w
, &x
, &y
);
8147 for (; r
< end
&& r
->enabled_p
; ++r
)
8148 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
8150 /* Found the row at y. */
8151 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8152 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8155 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8156 rect
->bottom
= rect
->top
+ r
->height
;
8160 /* x is to the left of the first glyph in the row. */
8161 rect
->left
= XINT (w
->left
);
8162 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
8166 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
8167 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
8169 /* x is on a glyph. */
8170 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8171 rect
->right
= rect
->left
+ g
->pixel_width
;
8175 /* x is to the right of the last glyph in the row. */
8176 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8177 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8182 /* The y is not on any row. */
8186 /* Record the position of the mouse in last_mouse_glyph. */
8188 remember_mouse_glyph (f1
, gx
, gy
)
8192 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8194 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8195 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8197 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8198 round down even for negative values. */
8204 /* This was the original code from XTmouse_position, but it seems
8205 to give the position of the glyph diagonally next to the one
8206 the mouse is over. */
8207 gx
= (gx
+ width
- 1) / width
* width
;
8208 gy
= (gy
+ height
- 1) / height
* height
;
8210 gx
= gx
/ width
* width
;
8211 gy
= gy
/ height
* height
;
8214 last_mouse_glyph
.left
= gx
;
8215 last_mouse_glyph
.top
= gy
;
8216 last_mouse_glyph
.right
= gx
+ width
;
8217 last_mouse_glyph
.bottom
= gy
+ height
;
8221 /* Return the current position of the mouse.
8222 *fp should be a frame which indicates which display to ask about.
8224 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8225 and *part to the frame, window, and scroll bar part that the mouse
8226 is over. Set *x and *y to the portion and whole of the mouse's
8227 position on the scroll bar.
8229 If the mouse movement started elsewhere, set *fp to the frame the
8230 mouse is on, *bar_window to nil, and *x and *y to the character cell
8233 Set *time to the server time-stamp for the time at which the mouse
8234 was at this position.
8236 Don't store anything if we don't have a valid set of values to report.
8238 This clears the mouse_moved flag, so we can wait for the next mouse
8242 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8245 Lisp_Object
*bar_window
;
8246 enum scroll_bar_part
*part
;
8248 unsigned long *time
;
8251 int ignore1
, ignore2
;
8252 WindowPtr wp
= FrontWindow ();
8253 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8254 Lisp_Object frame
, tail
;
8258 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8259 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8262 /* Clear the mouse-moved flag for every frame on this display. */
8263 FOR_EACH_FRAME (tail
, frame
)
8264 XFRAME (frame
)->mouse_moved
= 0;
8266 last_mouse_scroll_bar
= Qnil
;
8268 #if TARGET_API_MAC_CARBON
8269 SetPort (GetWindowPort (wp
));
8274 GetMouse (&mouse_pos
);
8276 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8277 &last_mouse_glyph
, insist
);
8280 *part
= scroll_bar_handle
;
8282 XSETINT (*x
, mouse_pos
.h
);
8283 XSETINT (*y
, mouse_pos
.v
);
8284 *time
= last_mouse_movement_time
;
8291 /************************************************************************
8292 Scroll bars, general
8293 ************************************************************************/
8295 /* Create a scroll bar and return the scroll bar vector for it. W is
8296 the Emacs window on which to create the scroll bar. TOP, LEFT,
8297 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8300 static struct scroll_bar
*
8301 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8303 int top
, left
, width
, height
, disp_top
, disp_height
;
8305 struct frame
*f
= XFRAME (w
->frame
);
8306 struct scroll_bar
*bar
8307 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8315 r
.right
= left
+ width
;
8316 r
.bottom
= disp_top
+ disp_height
;
8318 #ifdef TARGET_API_MAC_CARBON
8319 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8320 kControlScrollBarProc
, 0L);
8322 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8325 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8326 SetControlReference (ch
, (long) bar
);
8328 XSETWINDOW (bar
->window
, w
);
8329 XSETINT (bar
->top
, top
);
8330 XSETINT (bar
->left
, left
);
8331 XSETINT (bar
->width
, width
);
8332 XSETINT (bar
->height
, height
);
8333 XSETINT (bar
->start
, 0);
8334 XSETINT (bar
->end
, 0);
8335 bar
->dragging
= Qnil
;
8337 /* Add bar to its frame's list of scroll bars. */
8338 bar
->next
= FRAME_SCROLL_BARS (f
);
8340 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8341 if (!NILP (bar
->next
))
8342 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8349 /* Draw BAR's handle in the proper position.
8351 If the handle is already drawn from START to END, don't bother
8352 redrawing it, unless REBUILD is non-zero; in that case, always
8353 redraw it. (REBUILD is handy for drawing the handle after expose
8356 Normally, we want to constrain the start and end of the handle to
8357 fit inside its rectangle, but if the user is dragging the scroll
8358 bar handle, we want to let them drag it down all the way, so that
8359 the bar's top is as far down as it goes; otherwise, there's no way
8360 to move to the very end of the buffer. */
8363 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8364 struct scroll_bar
*bar
;
8368 int dragging
= ! NILP (bar
->dragging
);
8369 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8370 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8371 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8372 int length
= end
- start
;
8374 /* If the display is already accurate, do nothing. */
8376 && start
== XINT (bar
->start
)
8377 && end
== XINT (bar
->end
))
8382 /* Make sure the values are reasonable, and try to preserve the
8383 distance between start and end. */
8386 else if (start
> top_range
)
8388 end
= start
+ length
;
8392 else if (end
> top_range
&& ! dragging
)
8395 /* Store the adjusted setting in the scroll bar. */
8396 XSETINT (bar
->start
, start
);
8397 XSETINT (bar
->end
, end
);
8399 /* Clip the end position, just for display. */
8400 if (end
> top_range
)
8403 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8404 top positions, to make sure the handle is always at least that
8405 many pixels tall. */
8406 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8408 SetControlMinimum (ch
, 0);
8409 /* Don't inadvertently activate deactivated scroll bars */
8410 if (GetControlMaximum (ch
) != -1)
8411 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8413 SetControlValue (ch
, start
);
8414 #if TARGET_API_MAC_CARBON
8415 SetControlViewSize (ch
, end
- start
);
8422 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8426 x_scroll_bar_remove (bar
)
8427 struct scroll_bar
*bar
;
8429 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8433 /* Destroy the Mac scroll bar control */
8434 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8436 /* Disassociate this scroll bar from its window. */
8437 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8442 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8443 that we are displaying PORTION characters out of a total of WHOLE
8444 characters, starting at POSITION. If WINDOW has no scroll bar,
8447 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8449 int portion
, whole
, position
;
8451 struct frame
*f
= XFRAME (w
->frame
);
8452 struct scroll_bar
*bar
;
8453 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8454 int window_x
, window_y
, window_width
, window_height
;
8456 /* Get window dimensions. */
8457 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8462 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8464 height
= window_height
;
8466 /* Compute the left edge of the scroll bar area. */
8467 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8468 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8470 left
= XFASTINT (w
->left
);
8471 left
*= CANON_X_UNIT (f
);
8472 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8474 /* Compute the width of the scroll bar which might be less than
8475 the width of the area reserved for the scroll bar. */
8476 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8477 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8481 /* Compute the left edge of the scroll bar. */
8482 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8483 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8485 sb_left
= left
+ (width
- sb_width
) / 2;
8487 /* Adjustments according to Inside Macintosh to make it look nice */
8489 disp_height
= height
;
8495 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8501 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8504 /* Does the scroll bar exist yet? */
8505 if (NILP (w
->vertical_scroll_bar
))
8508 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8509 left
, top
, width
, height
, 0);
8511 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8513 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8517 /* It may just need to be moved and resized. */
8520 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8521 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8525 /* If already correctly positioned, do nothing. */
8526 if (XINT (bar
->left
) == sb_left
8527 && XINT (bar
->top
) == top
8528 && XINT (bar
->width
) == sb_width
8529 && XINT (bar
->height
) == height
)
8533 /* Clear areas not covered by the scroll bar because it's not as
8534 wide as the area reserved for it . This makes sure a
8535 previous mode line display is cleared after C-x 2 C-x 1, for
8537 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8538 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8539 left
, top
, area_width
, height
, 0);
8542 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8543 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8544 sb_left
- 1, top
, 1, height
, 0);
8548 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8549 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8553 /* Remember new settings. */
8554 XSETINT (bar
->left
, sb_left
);
8555 XSETINT (bar
->top
, top
);
8556 XSETINT (bar
->width
, sb_width
);
8557 XSETINT (bar
->height
, height
);
8563 /* Set the scroll bar's current state, unless we're currently being
8565 if (NILP (bar
->dragging
))
8567 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8570 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8573 int start
= ((double) position
* top_range
) / whole
;
8574 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8575 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8581 /* The following three hooks are used when we're doing a thorough
8582 redisplay of the frame. We don't explicitly know which scroll bars
8583 are going to be deleted, because keeping track of when windows go
8584 away is a real pain - "Can you say set-window-configuration, boys
8585 and girls?" Instead, we just assert at the beginning of redisplay
8586 that *all* scroll bars are to be removed, and then save a scroll bar
8587 from the fiery pit when we actually redisplay its window. */
8589 /* Arrange for all scroll bars on FRAME to be removed at the next call
8590 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8591 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8594 XTcondemn_scroll_bars (frame
)
8597 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8598 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8601 bar
= FRAME_SCROLL_BARS (frame
);
8602 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8603 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8604 XSCROLL_BAR (bar
)->prev
= Qnil
;
8605 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8606 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8607 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8612 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8613 Note that WINDOW isn't necessarily condemned at all. */
8616 XTredeem_scroll_bar (window
)
8617 struct window
*window
;
8619 struct scroll_bar
*bar
;
8621 /* We can't redeem this window's scroll bar if it doesn't have one. */
8622 if (NILP (window
->vertical_scroll_bar
))
8625 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8627 /* Unlink it from the condemned list. */
8629 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8631 if (NILP (bar
->prev
))
8633 /* If the prev pointer is nil, it must be the first in one of
8635 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8636 /* It's not condemned. Everything's fine. */
8638 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8639 window
->vertical_scroll_bar
))
8640 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8642 /* If its prev pointer is nil, it must be at the front of
8643 one or the other! */
8647 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8649 if (! NILP (bar
->next
))
8650 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8652 bar
->next
= FRAME_SCROLL_BARS (f
);
8654 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8655 if (! NILP (bar
->next
))
8656 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8660 /* Remove all scroll bars on FRAME that haven't been saved since the
8661 last call to `*condemn_scroll_bars_hook'. */
8664 XTjudge_scroll_bars (f
)
8667 Lisp_Object bar
, next
;
8669 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8671 /* Clear out the condemned list now so we won't try to process any
8672 more events on the hapless scroll bars. */
8673 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8675 for (; ! NILP (bar
); bar
= next
)
8677 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8679 x_scroll_bar_remove (b
);
8682 b
->next
= b
->prev
= Qnil
;
8685 /* Now there should be no references to the condemned scroll bars,
8686 and they should get garbage-collected. */
8691 activate_scroll_bars (frame
)
8697 bar
= FRAME_SCROLL_BARS (frame
);
8698 while (! NILP (bar
))
8700 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8701 #ifdef TARGET_API_MAC_CARBON
8702 ActivateControl (ch
);
8704 SetControlMaximum (ch
,
8705 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8706 XINT (XSCROLL_BAR (bar
)
8709 bar
= XSCROLL_BAR (bar
)->next
;
8715 deactivate_scroll_bars (frame
)
8721 bar
= FRAME_SCROLL_BARS (frame
);
8722 while (! NILP (bar
))
8724 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8725 #ifdef TARGET_API_MAC_CARBON
8726 DeactivateControl (ch
);
8728 SetControlMaximum (ch
, XINT (-1));
8730 bar
= XSCROLL_BAR (bar
)->next
;
8734 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8735 is set to something other than NO_EVENT, it is enqueued.
8737 This may be called from a signal handler, so we have to ignore GC
8741 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8742 struct scroll_bar
*bar
;
8745 struct input_event
*bufp
;
8747 if (! GC_WINDOWP (bar
->window
))
8750 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
8751 bufp
->frame_or_window
= bar
->window
;
8754 bar
->dragging
= Qnil
;
8758 case kControlUpButtonPart
:
8759 bufp
->part
= scroll_bar_up_arrow
;
8761 case kControlDownButtonPart
:
8762 bufp
->part
= scroll_bar_down_arrow
;
8764 case kControlPageUpPart
:
8765 bufp
->part
= scroll_bar_above_handle
;
8767 case kControlPageDownPart
:
8768 bufp
->part
= scroll_bar_below_handle
;
8770 #ifdef TARGET_API_MAC_CARBON
8773 case kControlIndicatorPart
:
8775 if (er
->what
== mouseDown
)
8776 bar
->dragging
= make_number (0);
8777 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8778 bufp
->part
= scroll_bar_handle
;
8784 /* Handle some mouse motion while someone is dragging the scroll bar.
8786 This may be called from a signal handler, so we have to ignore GC
8790 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8791 struct scroll_bar
*bar
;
8795 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8797 last_mouse_movement_time
= t
;
8800 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8802 /* If we're dragging the bar, display it. */
8803 if (! GC_NILP (bar
->dragging
))
8805 /* Where should the handle be now? */
8806 int new_start
= y_pos
- 24;
8808 if (new_start
!= XINT (bar
->start
))
8810 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8812 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8818 /* Return information to the user about the current position of the
8819 mouse on the scroll bar. */
8822 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8824 Lisp_Object
*bar_window
;
8825 enum scroll_bar_part
*part
;
8827 unsigned long *time
;
8829 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8830 WindowPtr wp
= FrontWindow ();
8832 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8833 int win_y
, top_range
;
8835 #if TARGET_API_MAC_CARBON
8836 SetPort (GetWindowPort (wp
));
8841 GetMouse (&mouse_pos
);
8843 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8844 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8846 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8850 if (! NILP (bar
->dragging
))
8851 win_y
-= XINT (bar
->dragging
);
8855 if (win_y
> top_range
)
8859 *bar_window
= bar
->window
;
8861 if (! NILP (bar
->dragging
))
8862 *part
= scroll_bar_handle
;
8863 else if (win_y
< XINT (bar
->start
))
8864 *part
= scroll_bar_above_handle
;
8865 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8866 *part
= scroll_bar_handle
;
8868 *part
= scroll_bar_below_handle
;
8870 XSETINT (*x
, win_y
);
8871 XSETINT (*y
, top_range
);
8874 last_mouse_scroll_bar
= Qnil
;
8876 *time
= last_mouse_movement_time
;
8879 /***********************************************************************
8881 ***********************************************************************/
8883 /* Notice if the text cursor of window W has been overwritten by a
8884 drawing operation that outputs glyphs starting at START_X and
8885 ending at END_X in the line given by output_cursor.vpos.
8886 Coordinates are area-relative. END_X < 0 means all the rest
8887 of the line after START_X has been written. */
8890 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8892 enum glyph_row_area area
;
8895 if (area
== TEXT_AREA
8896 && w
->phys_cursor_on_p
8897 && y0
<= w
->phys_cursor
.y
8898 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8899 && x0
<= w
->phys_cursor
.x
8900 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8901 w
->phys_cursor_on_p
= 0;
8905 /* Set clipping for output in glyph row ROW. W is the window in which
8906 we operate. GC is the graphics context to set clipping in.
8907 WHOLE_LINE_P non-zero means include the areas used for truncation
8908 mark display and alike in the clipping rectangle.
8910 ROW may be a text row or, e.g., a mode line. Text rows must be
8911 clipped to the interior of the window dedicated to text display,
8912 mode lines must be clipped to the whole window. */
8915 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8917 struct glyph_row
*row
;
8921 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8923 int window_x
, window_y
, window_width
, window_height
;
8925 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8927 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8928 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8929 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8930 clip_rect
.right
= clip_rect
.left
+ window_width
;
8931 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8933 /* If clipping to the whole line, including trunc marks, extend
8934 the rectangle to the left and increase its width. */
8937 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8938 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8941 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8945 /* Draw a hollow box cursor on window W in glyph row ROW. */
8948 x_draw_hollow_cursor (w
, row
)
8950 struct glyph_row
*row
;
8952 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8953 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8954 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8957 struct glyph
*cursor_glyph
;
8960 /* Compute frame-relative coordinates from window-relative
8962 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8963 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8964 + row
->ascent
- w
->phys_cursor_ascent
);
8965 h
= row
->height
- 1;
8967 /* Get the glyph the cursor is on. If we can't tell because
8968 the current matrix is invalid or such, give up. */
8969 cursor_glyph
= get_phys_cursor_glyph (w
);
8970 if (cursor_glyph
== NULL
)
8973 /* Compute the width of the rectangle to draw. If on a stretch
8974 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8975 rectangle as wide as the glyph, but use a canonical character
8977 wd
= cursor_glyph
->pixel_width
- 1;
8978 if (cursor_glyph
->type
== STRETCH_GLYPH
8979 && !x_stretch_cursor_p
)
8980 wd
= min (CANON_X_UNIT (f
), wd
);
8982 /* The foreground of cursor_gc is typically the same as the normal
8983 background color, which can cause the cursor box to be invisible. */
8984 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8985 if (dpyinfo
->scratch_cursor_gc
)
8986 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8988 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8989 GCForeground
, &xgcv
);
8990 gc
= dpyinfo
->scratch_cursor_gc
;
8992 /* Set clipping, draw the rectangle, and reset clipping again. */
8993 x_clip_to_row (w
, row
, gc
, 0);
8994 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
8995 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8999 /* Draw a bar cursor on window W in glyph row ROW.
9001 Implementation note: One would like to draw a bar cursor with an
9002 angle equal to the one given by the font property XA_ITALIC_ANGLE.
9003 Unfortunately, I didn't find a font yet that has this property set.
9007 x_draw_bar_cursor (w
, row
, width
)
9009 struct glyph_row
*row
;
9012 /* If cursor hpos is out of bounds, don't draw garbage. This can
9013 happen in mini-buffer windows when switching between echo area
9014 glyphs and mini-buffer. */
9015 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9017 struct frame
*f
= XFRAME (w
->frame
);
9018 struct glyph
*cursor_glyph
;
9026 cursor_glyph
= get_phys_cursor_glyph (w
);
9027 if (cursor_glyph
== NULL
)
9030 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
9031 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9032 mask
= GCForeground
| GCBackground
;
9033 dpy
= FRAME_MAC_DISPLAY (f
);
9034 window
= FRAME_MAC_WINDOW (f
);
9035 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9038 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9041 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9042 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9046 width
= f
->output_data
.mac
->cursor_width
;
9048 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9049 x_clip_to_row (w
, row
, gc
, 0);
9050 XFillRectangle (dpy
, window
, gc
,
9052 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9053 min (cursor_glyph
->pixel_width
, width
),
9055 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9060 /* Clear the cursor of window W to background color, and mark the
9061 cursor as not shown. This is used when the text where the cursor
9062 is is about to be rewritten. */
9068 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9069 x_update_window_cursor (w
, 0);
9073 /* Draw the cursor glyph of window W in glyph row ROW. See the
9074 comment of x_draw_glyphs for the meaning of HL. */
9077 x_draw_phys_cursor_glyph (w
, row
, hl
)
9079 struct glyph_row
*row
;
9080 enum draw_glyphs_face hl
;
9082 /* If cursor hpos is out of bounds, don't draw garbage. This can
9083 happen in mini-buffer windows when switching between echo area
9084 glyphs and mini-buffer. */
9085 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9087 int on_p
= w
->phys_cursor_on_p
;
9088 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9089 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9091 w
->phys_cursor_on_p
= on_p
;
9093 /* When we erase the cursor, and ROW is overlapped by other
9094 rows, make sure that these overlapping parts of other rows
9096 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9098 if (row
> w
->current_matrix
->rows
9099 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9100 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9102 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9103 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9104 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9110 /* Erase the image of a cursor of window W from the screen. */
9113 x_erase_phys_cursor (w
)
9116 struct frame
*f
= XFRAME (w
->frame
);
9117 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9118 int hpos
= w
->phys_cursor
.hpos
;
9119 int vpos
= w
->phys_cursor
.vpos
;
9120 int mouse_face_here_p
= 0;
9121 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9122 struct glyph_row
*cursor_row
;
9123 struct glyph
*cursor_glyph
;
9124 enum draw_glyphs_face hl
;
9126 /* No cursor displayed or row invalidated => nothing to do on the
9128 if (w
->phys_cursor_type
== NO_CURSOR
)
9129 goto mark_cursor_off
;
9131 /* VPOS >= active_glyphs->nrows means that window has been resized.
9132 Don't bother to erase the cursor. */
9133 if (vpos
>= active_glyphs
->nrows
)
9134 goto mark_cursor_off
;
9136 /* If row containing cursor is marked invalid, there is nothing we
9138 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9139 if (!cursor_row
->enabled_p
)
9140 goto mark_cursor_off
;
9142 /* If row is completely invisible, don't attempt to delete a cursor which
9143 isn't there. This may happen if cursor is at top of window, and
9144 we switch to a buffer with a header line in that window. */
9145 if (cursor_row
->visible_height
<= 0)
9146 goto mark_cursor_off
;
9148 /* This can happen when the new row is shorter than the old one.
9149 In this case, either x_draw_glyphs or clear_end_of_line
9150 should have cleared the cursor. Note that we wouldn't be
9151 able to erase the cursor in this case because we don't have a
9152 cursor glyph at hand. */
9153 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9154 goto mark_cursor_off
;
9156 /* If the cursor is in the mouse face area, redisplay that when
9157 we clear the cursor. */
9158 if (! NILP (dpyinfo
->mouse_face_window
)
9159 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9160 && (vpos
> dpyinfo
->mouse_face_beg_row
9161 || (vpos
== dpyinfo
->mouse_face_beg_row
9162 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9163 && (vpos
< dpyinfo
->mouse_face_end_row
9164 || (vpos
== dpyinfo
->mouse_face_end_row
9165 && hpos
< dpyinfo
->mouse_face_end_col
))
9166 /* Don't redraw the cursor's spot in mouse face if it is at the
9167 end of a line (on a newline). The cursor appears there, but
9168 mouse highlighting does not. */
9169 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9170 mouse_face_here_p
= 1;
9172 /* Maybe clear the display under the cursor. */
9173 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9176 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9178 cursor_glyph
= get_phys_cursor_glyph (w
);
9179 if (cursor_glyph
== NULL
)
9180 goto mark_cursor_off
;
9182 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9184 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9186 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9188 cursor_glyph
->pixel_width
,
9189 cursor_row
->visible_height
,
9193 /* Erase the cursor by redrawing the character underneath it. */
9194 if (mouse_face_here_p
)
9195 hl
= DRAW_MOUSE_FACE
;
9197 hl
= DRAW_NORMAL_TEXT
;
9198 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9201 w
->phys_cursor_on_p
= 0;
9202 w
->phys_cursor_type
= NO_CURSOR
;
9206 /* Non-zero if physical cursor of window W is within mouse face. */
9209 cursor_in_mouse_face_p (w
)
9212 struct mac_display_info
*dpyinfo
9213 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9214 int in_mouse_face
= 0;
9216 if (WINDOWP (dpyinfo
->mouse_face_window
)
9217 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9219 int hpos
= w
->phys_cursor
.hpos
;
9220 int vpos
= w
->phys_cursor
.vpos
;
9222 if (vpos
>= dpyinfo
->mouse_face_beg_row
9223 && vpos
<= dpyinfo
->mouse_face_end_row
9224 && (vpos
> dpyinfo
->mouse_face_beg_row
9225 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9226 && (vpos
< dpyinfo
->mouse_face_end_row
9227 || hpos
< dpyinfo
->mouse_face_end_col
9228 || dpyinfo
->mouse_face_past_end
))
9232 return in_mouse_face
;
9236 /* Display or clear cursor of window W. If ON is zero, clear the
9237 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9238 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9241 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9243 int on
, hpos
, vpos
, x
, y
;
9245 struct frame
*f
= XFRAME (w
->frame
);
9246 int new_cursor_type
;
9247 int new_cursor_width
;
9248 struct glyph_matrix
*current_glyphs
;
9249 struct glyph_row
*glyph_row
;
9250 struct glyph
*glyph
;
9251 int cursor_non_selected
;
9252 int active_cursor
= 1;
9254 /* This is pointless on invisible frames, and dangerous on garbaged
9255 windows and frames; in the latter case, the frame or window may
9256 be in the midst of changing its size, and x and y may be off the
9258 if (! FRAME_VISIBLE_P (f
)
9259 || FRAME_GARBAGED_P (f
)
9260 || vpos
>= w
->current_matrix
->nrows
9261 || hpos
>= w
->current_matrix
->matrix_w
)
9264 /* If cursor is off and we want it off, return quickly. */
9265 if (!on
&& !w
->phys_cursor_on_p
)
9268 current_glyphs
= w
->current_matrix
;
9269 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9270 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9272 /* If cursor row is not enabled, we don't really know where to
9273 display the cursor. */
9274 if (!glyph_row
->enabled_p
)
9276 w
->phys_cursor_on_p
= 0;
9280 xassert (interrupt_input_blocked
);
9282 /* Set new_cursor_type to the cursor we want to be displayed. In a
9283 mini-buffer window, we want the cursor only to appear if we are
9284 reading input from this window. For the selected window, we want
9285 the cursor type given by the frame parameter. If explicitly
9286 marked off, draw no cursor. In all other cases, we want a hollow
9289 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9291 new_cursor_width
= -1;
9292 if (cursor_in_echo_area
9293 && FRAME_HAS_MINIBUF_P (f
)
9294 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9296 if (w
== XWINDOW (echo_area_window
))
9297 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9300 if (cursor_non_selected
)
9301 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9303 new_cursor_type
= NO_CURSOR
;
9309 if (f
!= FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
9310 || w
!= XWINDOW (f
->selected_window
))
9314 if (MINI_WINDOW_P (w
)
9315 || !cursor_non_selected
9316 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9317 new_cursor_type
= NO_CURSOR
;
9319 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9323 struct buffer
*b
= XBUFFER (w
->buffer
);
9325 if (EQ (b
->cursor_type
, Qt
))
9326 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9328 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9330 if (w
->cursor_off_p
)
9332 if (new_cursor_type
== FILLED_BOX_CURSOR
)
9333 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9334 else if (new_cursor_type
== BAR_CURSOR
&& new_cursor_width
> 1)
9335 new_cursor_width
= 1;
9337 new_cursor_type
= NO_CURSOR
;
9342 /* If cursor is currently being shown and we don't want it to be or
9343 it is in the wrong place, or the cursor type is not what we want,
9345 if (w
->phys_cursor_on_p
9347 || w
->phys_cursor
.x
!= x
9348 || w
->phys_cursor
.y
!= y
9349 || new_cursor_type
!= w
->phys_cursor_type
9350 || (new_cursor_type
== BAR_CURSOR
9351 && new_cursor_width
!= w
->phys_cursor_width
)))
9352 x_erase_phys_cursor (w
);
9354 /* If the cursor is now invisible and we want it to be visible,
9356 if (on
&& !w
->phys_cursor_on_p
)
9358 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9359 w
->phys_cursor_height
= glyph_row
->height
;
9361 /* Set phys_cursor_.* before x_draw_.* is called because some
9362 of them may need the information. */
9363 w
->phys_cursor
.x
= x
;
9364 w
->phys_cursor
.y
= glyph_row
->y
;
9365 w
->phys_cursor
.hpos
= hpos
;
9366 w
->phys_cursor
.vpos
= vpos
;
9367 w
->phys_cursor_type
= new_cursor_type
;
9368 w
->phys_cursor_width
= new_cursor_width
;
9369 w
->phys_cursor_on_p
= 1;
9371 switch (new_cursor_type
)
9373 case HOLLOW_BOX_CURSOR
:
9374 x_draw_hollow_cursor (w
, glyph_row
);
9377 case FILLED_BOX_CURSOR
:
9378 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9382 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9395 /* Display the cursor on window W, or clear it. X and Y are window
9396 relative pixel coordinates. HPOS and VPOS are glyph matrix
9397 positions. If W is not the selected window, display a hollow
9398 cursor. ON non-zero means display the cursor at X, Y which
9399 correspond to HPOS, VPOS, otherwise it is cleared. */
9402 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9404 int on
, hpos
, vpos
, x
, y
;
9407 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9412 /* Display the cursor on window W, or clear it, according to ON_P.
9413 Don't change the cursor's position. */
9416 x_update_cursor (f
, on_p
)
9420 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9424 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9425 in the window tree rooted at W. */
9428 x_update_cursor_in_window_tree (w
, on_p
)
9434 if (!NILP (w
->hchild
))
9435 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9436 else if (!NILP (w
->vchild
))
9437 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9439 x_update_window_cursor (w
, on_p
);
9441 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9446 /* Switch the display of W's cursor on or off, according to the value
9450 x_update_window_cursor (w
, on
)
9454 /* Don't update cursor in windows whose frame is in the process
9455 of being deleted. */
9456 if (w
->current_matrix
)
9459 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9460 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9471 #if 0 /* MAC_TODO: no icon support yet. */
9473 x_bitmap_icon (f
, icon
)
9479 if (FRAME_W32_WINDOW (f
) == 0)
9483 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9484 else if (STRINGP (icon
))
9485 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
9486 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9487 else if (SYMBOLP (icon
))
9491 if (EQ (icon
, intern ("application")))
9492 name
= (LPCTSTR
) IDI_APPLICATION
;
9493 else if (EQ (icon
, intern ("hand")))
9494 name
= (LPCTSTR
) IDI_HAND
;
9495 else if (EQ (icon
, intern ("question")))
9496 name
= (LPCTSTR
) IDI_QUESTION
;
9497 else if (EQ (icon
, intern ("exclamation")))
9498 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9499 else if (EQ (icon
, intern ("asterisk")))
9500 name
= (LPCTSTR
) IDI_ASTERISK
;
9501 else if (EQ (icon
, intern ("winlogo")))
9502 name
= (LPCTSTR
) IDI_WINLOGO
;
9506 hicon
= LoadIcon (NULL
, name
);
9514 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9519 #endif /* MAC_TODO */
9521 /************************************************************************
9523 ************************************************************************/
9525 /* Display Error Handling functions not used on W32. Listing them here
9526 helps diff stay in step when comparing w32term.c with xterm.c.
9528 x_error_catcher (display, error)
9529 x_catch_errors (dpy)
9530 x_catch_errors_unwind (old_val)
9531 x_check_errors (dpy, format)
9532 x_had_errors_p (dpy)
9533 x_clear_errors (dpy)
9534 x_uncatch_errors (dpy, count)
9536 x_connection_signal (signalnum)
9537 x_connection_closed (dpy, error_message)
9538 x_error_quitter (display, error)
9539 x_error_handler (display, error)
9540 x_io_error_quitter (display)
9545 /* Changing the font of the frame. */
9547 /* Give frame F the font named FONTNAME as its default font, and
9548 return the full name of that font. FONTNAME may be a wildcard
9549 pattern; in that case, we choose some font that fits the pattern.
9550 The return value shows which font we chose. */
9553 x_new_font (f
, fontname
)
9555 register char *fontname
;
9557 struct font_info
*fontp
9558 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9563 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9564 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9565 FRAME_FONTSET (f
) = -1;
9567 /* Compute the scroll bar width in character columns. */
9568 if (f
->scroll_bar_pixel_width
> 0)
9570 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9571 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9575 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9576 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9579 /* Now make the frame display the given font. */
9580 if (FRAME_MAC_WINDOW (f
) != 0)
9582 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9583 f
->output_data
.mac
->font
);
9584 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9585 f
->output_data
.mac
->font
);
9586 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9587 f
->output_data
.mac
->font
);
9589 frame_update_line_height (f
);
9590 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9591 x_set_window_size (f
, 0, f
->width
, f
->height
);
9594 /* If we are setting a new frame's font for the first time,
9595 there are no faces yet, so this font's height is the line height. */
9596 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9598 return build_string (fontp
->full_name
);
9601 /* Give frame F the fontset named FONTSETNAME as its default font, and
9602 return the full name of that fontset. FONTSETNAME may be a wildcard
9603 pattern; in that case, we choose some fontset that fits the pattern.
9604 The return value shows which fontset we chose. */
9607 x_new_fontset (f
, fontsetname
)
9611 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9617 if (FRAME_FONTSET (f
) == fontset
)
9618 /* This fontset is already set in frame F. There's nothing more
9620 return fontset_name (fontset
);
9622 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
9624 if (!STRINGP (result
))
9625 /* Can't load ASCII font. */
9628 /* Since x_new_font doesn't update any fontset information, do it now. */
9629 FRAME_FONTSET(f
) = fontset
;
9631 return build_string (fontsetname
);
9634 /* Compute actual fringe widths */
9637 x_compute_fringe_widths (f
, redraw
)
9641 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9642 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9643 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9645 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9646 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9647 int left_fringe_width
, right_fringe_width
;
9649 if (!NILP (left_fringe
))
9650 left_fringe
= Fcdr (left_fringe
);
9651 if (!NILP (right_fringe
))
9652 right_fringe
= Fcdr (right_fringe
);
9654 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9655 XINT (left_fringe
));
9656 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9657 XINT (right_fringe
));
9659 if (left_fringe_width
|| right_fringe_width
)
9661 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9662 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9663 int conf_wid
= left_wid
+ right_wid
;
9664 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9665 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9666 int real_wid
= cols
* font_wid
;
9667 if (left_wid
&& right_wid
)
9669 if (left_fringe_width
< 0)
9671 /* Left fringe width is fixed, adjust right fringe if necessary */
9672 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9673 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9675 else if (right_fringe_width
< 0)
9677 /* Right fringe width is fixed, adjust left fringe if necessary */
9678 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9679 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9683 /* Adjust both fringes with an equal amount.
9684 Note that we are doing integer arithmetic here, so don't
9685 lose a pixel if the total width is an odd number. */
9686 int fill
= real_wid
- conf_wid
;
9687 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9688 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9691 else if (left_fringe_width
)
9693 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9694 f
->output_data
.mac
->right_fringe_width
= 0;
9698 f
->output_data
.mac
->left_fringe_width
= 0;
9699 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9701 f
->output_data
.mac
->fringe_cols
= cols
;
9702 f
->output_data
.mac
->fringes_extra
= real_wid
;
9706 f
->output_data
.mac
->left_fringe_width
= 0;
9707 f
->output_data
.mac
->right_fringe_width
= 0;
9708 f
->output_data
.mac
->fringe_cols
= 0;
9709 f
->output_data
.mac
->fringes_extra
= 0;
9712 if (redraw
&& FRAME_VISIBLE_P (f
))
9713 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9714 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9715 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9719 /***********************************************************************
9720 TODO: W32 Input Methods
9721 ***********************************************************************/
9722 /* Listing missing functions from xterm.c helps diff stay in step.
9724 xim_destroy_callback (xim, client_data, call_data)
9725 xim_open_dpy (dpyinfo, resource_name)
9727 xim_instantiate_callback (display, client_data, call_data)
9728 xim_initialize (dpyinfo, resource_name)
9729 xim_close_dpy (dpyinfo)
9734 /* Calculate the absolute position in frame F
9735 from its current recorded position values and gravity. */
9738 x_calc_absolute_position (f
)
9742 int flags
= f
->output_data
.mac
->size_hint_flags
;
9746 /* Find the position of the outside upper-left corner of
9747 the inner window, with respect to the outer window. */
9748 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9751 GetPort (&savePort
);
9753 #if TARGET_API_MAC_CARBON
9754 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9756 SetPort (FRAME_MAC_WINDOW (f
));
9759 #if TARGET_API_MAC_CARBON
9763 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9764 SetPt(&pt
, r
.left
, r
.top
);
9766 #else /* not TARGET_API_MAC_CARBON */
9767 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9768 #endif /* not TARGET_API_MAC_CARBON */
9769 LocalToGlobal (&pt
);
9773 /* Treat negative positions as relative to the leftmost bottommost
9774 position that fits on the screen. */
9775 if (flags
& XNegative
)
9776 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9777 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9779 + f
->output_data
.mac
->left_pos
);
9780 /* NTEMACS_TODO: Subtract menubar height? */
9781 if (flags
& YNegative
)
9782 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9783 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9785 + f
->output_data
.mac
->top_pos
);
9786 /* The left_pos and top_pos
9787 are now relative to the top and left screen edges,
9788 so the flags should correspond. */
9789 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9792 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9793 to really change the position, and 0 when calling from
9794 x_make_frame_visible (in that case, XOFF and YOFF are the current
9795 position values). It is -1 when calling from x_set_frame_parameters,
9796 which means, do adjust for borders but don't change the gravity. */
9799 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9801 register int xoff
, yoff
;
9804 int modified_top
, modified_left
;
9806 if (change_gravity
> 0)
9808 f
->output_data
.mac
->top_pos
= yoff
;
9809 f
->output_data
.mac
->left_pos
= xoff
;
9810 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9812 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9814 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9815 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9817 x_calc_absolute_position (f
);
9820 x_wm_set_size_hint (f
, (long) 0, 0);
9822 modified_left
= f
->output_data
.mac
->left_pos
;
9823 modified_top
= f
->output_data
.mac
->top_pos
;
9825 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9826 modified_top
+ 42, false);
9831 /* Call this to change the size of frame F's x-window.
9832 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9833 for this size change and subsequent size changes.
9834 Otherwise we leave the window gravity unchanged. */
9837 x_set_window_size (f
, change_gravity
, cols
, rows
)
9842 int pixelwidth
, pixelheight
;
9846 check_frame_size (f
, &rows
, &cols
);
9847 f
->output_data
.mac
->vertical_scroll_bar_extra
9848 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9850 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9852 x_compute_fringe_widths (f
, 0);
9854 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9855 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9857 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9858 x_wm_set_size_hint (f
, (long) 0, 0);
9860 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9862 /* Now, strictly speaking, we can't be sure that this is accurate,
9863 but the window manager will get around to dealing with the size
9864 change request eventually, and we'll hear how it went when the
9865 ConfigureNotify event gets here.
9867 We could just not bother storing any of this information here,
9868 and let the ConfigureNotify event set everything up, but that
9869 might be kind of confusing to the Lisp code, since size changes
9870 wouldn't be reported in the frame parameters until some random
9871 point in the future when the ConfigureNotify event arrives.
9873 We pass 1 for DELAY since we can't run Lisp code inside of
9875 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9876 PIXEL_WIDTH (f
) = pixelwidth
;
9877 PIXEL_HEIGHT (f
) = pixelheight
;
9879 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9880 receive in the ConfigureNotify event; if we get what we asked
9881 for, then the event won't cause the screen to become garbaged, so
9882 we have to make sure to do it here. */
9883 SET_FRAME_GARBAGED (f
);
9885 XFlush (FRAME_X_DISPLAY (f
));
9887 /* If cursor was outside the new size, mark it as off. */
9888 mark_window_cursors_off (XWINDOW (f
->root_window
));
9890 /* Clear out any recollection of where the mouse highlighting was,
9891 since it might be in a place that's outside the new frame size.
9892 Actually checking whether it is outside is a pain in the neck,
9893 so don't try--just let the highlighting be done afresh with new size. */
9894 cancel_mouse_face (f
);
9899 /* Mouse warping. */
9901 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9904 x_set_mouse_position (f
, x
, y
)
9910 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9911 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9913 if (pix_x
< 0) pix_x
= 0;
9914 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9916 if (pix_y
< 0) pix_y
= 0;
9917 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9919 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9923 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9927 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9930 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9931 0, 0, 0, 0, pix_x
, pix_y
);
9937 /* focus shifting, raising and lowering. */
9940 x_focus_on_frame (f
)
9943 #if 0 /* This proves to be unpleasant. */
9947 /* I don't think that the ICCCM allows programs to do things like this
9948 without the interaction of the window manager. Whatever you end up
9949 doing with this code, do it to x_unfocus_frame too. */
9950 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9951 RevertToPointerRoot
, CurrentTime
);
9961 /* Raise frame F. */
9966 if (f
->async_visible
)
9967 SelectWindow (FRAME_MAC_WINDOW (f
));
9970 /* Lower frame F. */
9975 if (f
->async_visible
)
9976 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9980 XTframe_raise_lower (f
, raise_flag
)
9990 /* Change of visibility. */
9992 /* This tries to wait until the frame is really visible.
9993 However, if the window manager asks the user where to position
9994 the frame, this will return before the user finishes doing that.
9995 The frame will not actually be visible at that time,
9996 but it will become visible later when the window manager
9997 finishes with it. */
10000 x_make_frame_visible (f
)
10004 int original_top
, original_left
;
10008 if (! FRAME_VISIBLE_P (f
))
10010 /* We test FRAME_GARBAGED_P here to make sure we don't
10011 call x_set_offset a second time
10012 if we get to x_make_frame_visible a second time
10013 before the window gets really visible. */
10014 if (! FRAME_ICONIFIED_P (f
)
10015 && ! f
->output_data
.mac
->asked_for_visible
)
10016 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
10017 f
->output_data
.mac
->top_pos
, 0);
10019 f
->output_data
.mac
->asked_for_visible
= 1;
10021 ShowWindow (FRAME_MAC_WINDOW (f
));
10024 XFlush (FRAME_MAC_DISPLAY (f
));
10026 #if 0 /* MAC_TODO */
10027 /* Synchronize to ensure Emacs knows the frame is visible
10028 before we do anything else. We do this loop with input not blocked
10029 so that incoming events are handled. */
10034 /* This must come after we set COUNT. */
10037 XSETFRAME (frame
, f
);
10039 /* Wait until the frame is visible. Process X events until a
10040 MapNotify event has been seen, or until we think we won't get a
10041 MapNotify at all.. */
10042 for (count
= input_signal_count
+ 10;
10043 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10045 /* Force processing of queued events. */
10048 /* Machines that do polling rather than SIGIO have been
10049 observed to go into a busy-wait here. So we'll fake an
10050 alarm signal to let the handler know that there's something
10051 to be read. We used to raise a real alarm, but it seems
10052 that the handler isn't always enabled here. This is
10054 if (input_polling_used ())
10056 /* It could be confusing if a real alarm arrives while
10057 processing the fake one. Turn it off and let the
10058 handler reset it. */
10059 extern void poll_for_input_1
P_ ((void));
10060 int old_poll_suppress_count
= poll_suppress_count
;
10061 poll_suppress_count
= 1;
10062 poll_for_input_1 ();
10063 poll_suppress_count
= old_poll_suppress_count
;
10066 /* See if a MapNotify event has been processed. */
10067 FRAME_SAMPLE_VISIBILITY (f
);
10070 #endif /* MAC_TODO */
10073 /* Change from mapped state to withdrawn state. */
10075 /* Make the frame visible (mapped and not iconified). */
10078 x_make_frame_invisible (f
)
10081 /* Don't keep the highlight on an invisible frame. */
10082 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10083 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10087 HideWindow (FRAME_MAC_WINDOW (f
));
10089 /* We can't distinguish this from iconification
10090 just by the event that we get from the server.
10091 So we can't win using the usual strategy of letting
10092 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10093 and synchronize with the server to make sure we agree. */
10095 FRAME_ICONIFIED_P (f
) = 0;
10096 f
->async_visible
= 0;
10097 f
->async_iconified
= 0;
10102 /* Change window state from mapped to iconified. */
10105 x_iconify_frame (f
)
10108 /* Don't keep the highlight on an invisible frame. */
10109 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10110 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10113 /* Review: Since window is still visible in dock, still allow updates? */
10114 if (f
->async_iconified
)
10120 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
10126 /* Destroy the X window of frame F. */
10129 x_destroy_window (f
)
10132 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10136 DisposeWindow (FRAME_MAC_WINDOW (f
));
10138 free_frame_menubar (f
);
10139 free_frame_faces (f
);
10141 xfree (f
->output_data
.mac
);
10142 f
->output_data
.mac
= 0;
10143 if (f
== dpyinfo
->x_focus_frame
)
10144 dpyinfo
->x_focus_frame
= 0;
10145 if (f
== dpyinfo
->x_focus_event_frame
)
10146 dpyinfo
->x_focus_event_frame
= 0;
10147 if (f
== dpyinfo
->x_highlight_frame
)
10148 dpyinfo
->x_highlight_frame
= 0;
10150 dpyinfo
->reference_count
--;
10152 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10154 dpyinfo
->mouse_face_beg_row
10155 = dpyinfo
->mouse_face_beg_col
= -1;
10156 dpyinfo
->mouse_face_end_row
10157 = dpyinfo
->mouse_face_end_col
= -1;
10158 dpyinfo
->mouse_face_window
= Qnil
;
10159 dpyinfo
->mouse_face_deferred_gc
= 0;
10160 dpyinfo
->mouse_face_mouse_frame
= 0;
10166 /* Setting window manager hints. */
10168 /* Set the normal size hints for the window manager, for frame F.
10169 FLAGS is the flags word to use--or 0 meaning preserve the flags
10170 that the window now has.
10171 If USER_POSITION is nonzero, we set the USPosition
10172 flag (this is useful when FLAGS is 0). */
10174 x_wm_set_size_hint (f
, flags
, user_position
)
10179 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10180 XSizeHints size_hints
;
10182 #ifdef USE_X_TOOLKIT
10185 Dimension widget_width
, widget_height
;
10186 Window window
= XtWindow (f
->output_data
.x
->widget
);
10187 #else /* not USE_X_TOOLKIT */
10188 Window window
= FRAME_X_WINDOW (f
);
10189 #endif /* not USE_X_TOOLKIT */
10191 /* Setting PMaxSize caused various problems. */
10192 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10194 size_hints
.x
= f
->output_data
.x
->left_pos
;
10195 size_hints
.y
= f
->output_data
.x
->top_pos
;
10197 #ifdef USE_X_TOOLKIT
10198 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10199 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10200 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10201 size_hints
.height
= widget_height
;
10202 size_hints
.width
= widget_width
;
10203 #else /* not USE_X_TOOLKIT */
10204 size_hints
.height
= PIXEL_HEIGHT (f
);
10205 size_hints
.width
= PIXEL_WIDTH (f
);
10206 #endif /* not USE_X_TOOLKIT */
10208 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10209 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10210 size_hints
.max_width
10211 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10212 size_hints
.max_height
10213 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10215 /* Calculate the base and minimum sizes.
10217 (When we use the X toolkit, we don't do it here.
10218 Instead we copy the values that the widgets are using, below.) */
10219 #ifndef USE_X_TOOLKIT
10221 int base_width
, base_height
;
10222 int min_rows
= 0, min_cols
= 0;
10224 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10225 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10227 check_frame_size (f
, &min_rows
, &min_cols
);
10229 /* The window manager uses the base width hints to calculate the
10230 current number of rows and columns in the frame while
10231 resizing; min_width and min_height aren't useful for this
10232 purpose, since they might not give the dimensions for a
10233 zero-row, zero-column frame.
10235 We use the base_width and base_height members if we have
10236 them; otherwise, we set the min_width and min_height members
10237 to the size for a zero x zero frame. */
10240 size_hints
.flags
|= PBaseSize
;
10241 size_hints
.base_width
= base_width
;
10242 size_hints
.base_height
= base_height
;
10243 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10244 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10246 size_hints
.min_width
= base_width
;
10247 size_hints
.min_height
= base_height
;
10251 /* If we don't need the old flags, we don't need the old hint at all. */
10254 size_hints
.flags
|= flags
;
10257 #endif /* not USE_X_TOOLKIT */
10260 XSizeHints hints
; /* Sometimes I hate X Windows... */
10261 long supplied_return
;
10265 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10268 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10271 #ifdef USE_X_TOOLKIT
10272 size_hints
.base_height
= hints
.base_height
;
10273 size_hints
.base_width
= hints
.base_width
;
10274 size_hints
.min_height
= hints
.min_height
;
10275 size_hints
.min_width
= hints
.min_width
;
10279 size_hints
.flags
|= flags
;
10284 if (hints
.flags
& PSize
)
10285 size_hints
.flags
|= PSize
;
10286 if (hints
.flags
& PPosition
)
10287 size_hints
.flags
|= PPosition
;
10288 if (hints
.flags
& USPosition
)
10289 size_hints
.flags
|= USPosition
;
10290 if (hints
.flags
& USSize
)
10291 size_hints
.flags
|= USSize
;
10295 #ifndef USE_X_TOOLKIT
10300 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10301 size_hints
.flags
|= PWinGravity
;
10305 size_hints
.flags
&= ~ PPosition
;
10306 size_hints
.flags
|= USPosition
;
10308 #endif /* PWinGravity */
10311 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10313 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10315 #endif /* MAC_TODO */
10318 #if 0 /* MAC_TODO: hide application instead of iconify? */
10319 /* Used for IconicState or NormalState */
10322 x_wm_set_window_state (f
, state
)
10326 #ifdef USE_X_TOOLKIT
10329 XtSetArg (al
[0], XtNinitialState
, state
);
10330 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10331 #else /* not USE_X_TOOLKIT */
10332 Window window
= FRAME_X_WINDOW (f
);
10334 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10335 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10337 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10338 #endif /* not USE_X_TOOLKIT */
10342 x_wm_set_icon_pixmap (f
, pixmap_id
)
10346 Pixmap icon_pixmap
;
10348 #ifndef USE_X_TOOLKIT
10349 Window window
= FRAME_X_WINDOW (f
);
10354 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10355 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10359 /* It seems there is no way to turn off use of an icon pixmap.
10360 The following line does it, only if no icon has yet been created,
10361 for some window managers. But with mwm it crashes.
10362 Some people say it should clear the IconPixmapHint bit in this case,
10363 but that doesn't work, and the X consortium said it isn't the
10364 right thing at all. Since there is no way to win,
10365 best to explicitly give up. */
10367 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10373 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10377 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10378 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10381 #else /* not USE_X_TOOLKIT */
10383 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10384 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10386 #endif /* not USE_X_TOOLKIT */
10389 #endif /* MAC_TODO */
10392 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10394 int icon_x
, icon_y
;
10396 #if 0 /* MAC_TODO: no icons on Mac */
10397 #ifdef USE_X_TOOLKIT
10398 Window window
= XtWindow (f
->output_data
.x
->widget
);
10400 Window window
= FRAME_X_WINDOW (f
);
10403 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10404 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10405 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10407 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10408 #endif /* MAC_TODO */
10412 /***********************************************************************
10414 ***********************************************************************/
10416 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10419 x_get_font_info (f
, font_idx
)
10423 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10426 /* the global font name table */
10427 char **font_name_table
= NULL
;
10428 int font_name_table_size
= 0;
10429 int font_name_count
= 0;
10431 /* compare two strings ignoring case */
10433 stricmp (const char *s
, const char *t
)
10435 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10438 return tolower (*s
) - tolower (*t
);
10441 /* compare two strings ignoring case and handling wildcard */
10443 wildstrieq (char *s1
, char *s2
)
10445 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10448 return stricmp (s1
, s2
) == 0;
10451 /* Assume parameter 1 is fully qualified, no wildcards. */
10453 mac_font_pattern_match (fontname
, pattern
)
10457 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10458 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10461 /* Copy fontname so we can modify it during comparison. */
10462 strcpy (font_name_copy
, fontname
);
10467 /* Turn pattern into a regexp and do a regexp match. */
10468 for (; *pattern
; pattern
++)
10470 if (*pattern
== '?')
10472 else if (*pattern
== '*')
10483 return (fast_c_string_match_ignore_case (build_string (regex
),
10484 font_name_copy
) >= 0);
10487 /* Two font specs are considered to match if their foundry, family,
10488 weight, slant, and charset match. */
10490 mac_font_match (char *mf
, char *xf
)
10492 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10493 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10495 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10496 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10497 return mac_font_pattern_match (mf
, xf
);
10499 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10500 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10501 return mac_font_pattern_match (mf
, xf
);
10503 return (wildstrieq (m_foundry
, x_foundry
)
10504 && wildstrieq (m_family
, x_family
)
10505 && wildstrieq (m_weight
, x_weight
)
10506 && wildstrieq (m_slant
, x_slant
)
10507 && wildstrieq (m_charset
, x_charset
))
10508 || mac_font_pattern_match (mf
, xf
);
10513 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10515 char foundry
[32], family
[32], cs
[32];
10516 char xf
[255], *result
, *p
;
10518 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10520 strcpy(foundry
, "Apple");
10521 strcpy(family
, name
);
10523 switch (scriptcode
)
10525 case smTradChinese
:
10526 strcpy(cs
, "big5-0");
10528 case smSimpChinese
:
10529 strcpy(cs
, "gb2312.1980-0");
10532 strcpy(cs
, "jisx0208.1983-sjis");
10535 /* Each Apple Japanese font is entered into the font table
10536 twice: once as a jisx0208.1983-sjis font and once as a
10537 jisx0201.1976-0 font. The latter can be used to display
10538 the ascii charset and katakana-jisx0201 charset. A
10539 negative script code signals that the name of this latter
10540 font is being built. */
10541 strcpy(cs
, "jisx0201.1976-0");
10544 strcpy(cs
, "ksc5601.1989-0");
10547 strcpy(cs
, "mac-roman");
10552 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10553 foundry
, family
, style
& bold
? "bold" : "medium",
10554 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10556 result
= (char *) xmalloc (strlen (xf
) + 1);
10557 strcpy (result
, xf
);
10558 for (p
= result
; *p
; p
++)
10564 /* Convert an X font spec to the corresponding mac font name, which
10565 can then be passed to GetFNum after conversion to a Pascal string.
10566 For ordinary Mac fonts, this should just be their names, like
10567 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10568 collection contain their charset designation in their names, like
10569 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10570 names are handled accordingly. */
10572 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10574 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10578 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10579 foundry
, family
, weight
, slant
, cs
) != 5 &&
10580 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10581 foundry
, family
, weight
, slant
, cs
) != 5)
10584 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10585 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10586 || strcmp (cs
, "jisx0201.1976-0") == 0
10587 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10588 strcpy(mf
, family
);
10590 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10595 add_font_name_table_entry (char *font_name
)
10597 if (font_name_table_size
== 0)
10599 font_name_table_size
= 16;
10600 font_name_table
= (char **)
10601 xmalloc (font_name_table_size
* sizeof (char *));
10603 else if (font_name_count
+ 1 >= font_name_table_size
)
10605 font_name_table_size
+= 16;
10606 font_name_table
= (char **)
10607 xrealloc (font_name_table
,
10608 font_name_table_size
* sizeof (char *));
10611 font_name_table
[font_name_count
++] = font_name
;
10614 /* Sets up the table font_name_table to contain the list of all fonts
10615 in the system the first time the table is used so that the Resource
10616 Manager need not be accessed every time this information is
10620 init_font_name_table ()
10622 #if TARGET_API_MAC_CARBON
10625 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10627 FMFontFamilyIterator ffi
;
10628 FMFontFamilyInstanceIterator ffii
;
10631 /* Create a dummy instance iterator here to avoid creating and
10632 destroying it in the loop. */
10633 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10635 /* Create an iterator to enumerate the font families. */
10636 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10639 FMDisposeFontFamilyInstanceIterator (&ffii
);
10643 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10651 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10655 sc
= FontToScript (ff
);
10657 /* Point the instance iterator at the current font family. */
10658 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10661 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &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
,
10671 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10677 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10679 if (smJapanese
== sc
)
10680 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
10686 /* Dispose of the iterators. */
10687 FMDisposeFontFamilyIterator (&ffi
);
10688 FMDisposeFontFamilyInstanceIterator (&ffii
);
10692 #endif /* TARGET_API_MAC_CARBON */
10694 SInt16 fontnum
, old_fontnum
;
10695 int num_mac_fonts
= CountResources('FOND');
10697 Handle font_handle
, font_handle_2
;
10698 short id
, scriptcode
;
10701 struct FontAssoc
*fat
;
10702 struct AsscEntry
*assc_entry
;
10704 GetPort (&port
); /* save the current font number used */
10705 #if TARGET_API_MAC_CARBON
10706 old_fontnum
= GetPortTextFont (port
);
10708 old_fontnum
= port
->txFont
;
10711 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10713 font_handle
= GetIndResource ('FOND', i
);
10717 GetResInfo (font_handle
, &id
, &type
, name
);
10718 GetFNum (name
, &fontnum
);
10723 TextFont (fontnum
);
10724 scriptcode
= FontToScript (fontnum
);
10727 HLock (font_handle
);
10729 if (GetResourceSizeOnDisk (font_handle
)
10730 >= sizeof (struct FamRec
))
10732 fat
= (struct FontAssoc
*) (*font_handle
10733 + sizeof (struct FamRec
));
10735 = (struct AsscEntry
*) (*font_handle
10736 + sizeof (struct FamRec
)
10737 + sizeof (struct FontAssoc
));
10739 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10741 if (font_name_table_size
== 0)
10743 font_name_table_size
= 16;
10744 font_name_table
= (char **)
10745 xmalloc (font_name_table_size
* sizeof (char *));
10747 else if (font_name_count
>= font_name_table_size
)
10749 font_name_table_size
+= 16;
10750 font_name_table
= (char **)
10751 xrealloc (font_name_table
,
10752 font_name_table_size
* sizeof (char *));
10754 font_name_table
[font_name_count
++]
10755 = mac_to_x_fontname (name
,
10756 assc_entry
->fontSize
,
10757 assc_entry
->fontStyle
,
10759 /* Both jisx0208.1983-sjis and
10760 jisx0201.1976-sjis parts are contained in
10761 Apple Japanese (SJIS) font. */
10762 if (smJapanese
== scriptcode
)
10764 font_name_table
[font_name_count
++]
10765 = mac_to_x_fontname (name
,
10766 assc_entry
->fontSize
,
10767 assc_entry
->fontStyle
,
10773 HUnlock (font_handle
);
10774 font_handle_2
= GetNextFOND (font_handle
);
10775 ReleaseResource (font_handle
);
10776 font_handle
= font_handle_2
;
10778 while (ResError () == noErr
&& font_handle
);
10781 TextFont (old_fontnum
);
10782 #if TARGET_API_MAC_CARBON
10784 #endif /* TARGET_API_MAC_CARBON */
10788 /* Return a list of at most MAXNAMES font specs matching the one in
10789 PATTERN. Cache matching fonts for patterns in
10790 dpyinfo->name_list_element to avoid looking them up again by
10791 calling mac_font_pattern_match (slow). */
10794 x_list_fonts (struct frame
*f
,
10795 Lisp_Object pattern
,
10800 Lisp_Object newlist
= Qnil
, tem
, key
;
10803 struct gcpro gcpro1
, gcpro2
;
10804 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
10806 if (font_name_table
== NULL
) /* Initialize when first used. */
10807 init_font_name_table ();
10811 tem
= XCDR (dpyinfo
->name_list_element
);
10812 key
= Fcons (pattern
, make_number (maxnames
));
10814 newlist
= Fassoc (key
, tem
);
10815 if (!NILP (newlist
))
10817 newlist
= Fcdr_safe (newlist
);
10822 ptnstr
= SDATA (pattern
);
10824 GCPRO2 (pattern
, newlist
);
10826 /* Scan and matching bitmap fonts. */
10827 for (i
= 0; i
< font_name_count
; i
++)
10829 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10831 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10834 if (n_fonts
>= maxnames
)
10839 /* MAC_TODO: add code for matching outline fonts here */
10845 XSETCDR (dpyinfo
->name_list_element
,
10846 Fcons (Fcons (key
, newlist
),
10847 XCDR (dpyinfo
->name_list_element
)));
10857 /* Check that FONT is valid on frame F. It is if it can be found in F's
10861 x_check_font (f
, font
)
10866 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10868 xassert (font
!= NULL
);
10870 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10871 if (dpyinfo
->font_table
[i
].name
10872 && font
== dpyinfo
->font_table
[i
].font
)
10875 xassert (i
< dpyinfo
->n_fonts
);
10878 #endif /* GLYPH_DEBUG != 0 */
10880 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10881 Note: There are (broken) X fonts out there with invalid XFontStruct
10882 min_bounds contents. For example, handa@etl.go.jp reports that
10883 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10884 have font->min_bounds.width == 0. */
10887 x_font_min_bounds (font
, w
, h
)
10888 MacFontStruct
*font
;
10892 * TODO: Windows does not appear to offer min bound, only
10893 * average and maximum width, and maximum height.
10895 *h
= FONT_HEIGHT (font
);
10896 *w
= FONT_WIDTH (font
);
10900 /* Compute the smallest character width and smallest font height over
10901 all fonts available on frame F. Set the members smallest_char_width
10902 and smallest_font_height in F's x_display_info structure to
10903 the values computed. Value is non-zero if smallest_font_height or
10904 smallest_char_width become smaller than they were before. */
10907 x_compute_min_glyph_bounds (f
)
10911 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10912 MacFontStruct
*font
;
10913 int old_width
= dpyinfo
->smallest_char_width
;
10914 int old_height
= dpyinfo
->smallest_font_height
;
10916 dpyinfo
->smallest_font_height
= 100000;
10917 dpyinfo
->smallest_char_width
= 100000;
10919 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10920 if (dpyinfo
->font_table
[i
].name
)
10922 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10925 font
= (MacFontStruct
*) fontp
->font
;
10926 xassert (font
!= (MacFontStruct
*) ~0);
10927 x_font_min_bounds (font
, &w
, &h
);
10929 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10930 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10933 xassert (dpyinfo
->smallest_char_width
> 0
10934 && dpyinfo
->smallest_font_height
> 0);
10936 return (dpyinfo
->n_fonts
== 1
10937 || dpyinfo
->smallest_char_width
< old_width
10938 || dpyinfo
->smallest_font_height
< old_height
);
10942 /* Determine whether given string is a fully-specified XLFD: all 14
10943 fields are present, none is '*'. */
10946 is_fully_specified_xlfd (char *p
)
10954 for (i
= 0; i
< 13; i
++)
10956 q
= strchr (p
+ 1, '-');
10959 if (q
- p
== 2 && *(p
+ 1) == '*')
10964 if (strchr (p
+ 1, '-') != NULL
)
10967 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10974 const int kDefaultFontSize
= 9;
10977 /* XLoadQueryFont creates and returns an internal representation for a
10978 font in a MacFontStruct struct. There is really no concept
10979 corresponding to "loading" a font on the Mac. But we check its
10980 existence and find the font number and all other information for it
10981 and store them in the returned MacFontStruct. */
10983 static MacFontStruct
*
10984 XLoadQueryFont (Display
*dpy
, char *fontname
)
10986 int i
, size
, is_two_byte_font
, char_width
;
10989 SInt16 old_fontnum
, old_fontsize
;
10990 Style old_fontface
;
10993 Style fontface
= normal
;
10994 MacFontStruct
*font
;
10995 FontInfo the_fontinfo
;
10996 char s_weight
[7], c_slant
;
10998 if (is_fully_specified_xlfd (fontname
))
11002 for (i
= 0; i
< font_name_count
; i
++)
11003 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
11006 if (i
>= font_name_count
)
11009 name
= font_name_table
[i
];
11012 GetPort (&port
); /* save the current font number used */
11013 #if TARGET_API_MAC_CARBON
11014 old_fontnum
= GetPortTextFont (port
);
11015 old_fontsize
= GetPortTextSize (port
);
11016 old_fontface
= GetPortTextFace (port
);
11018 old_fontnum
= port
->txFont
;
11019 old_fontsize
= port
->txSize
;
11020 old_fontface
= port
->txFace
;
11023 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
11024 size
= kDefaultFontSize
;
11026 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
11027 if (strcmp (s_weight
, "bold") == 0)
11030 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
11031 if (c_slant
== 'i')
11032 fontface
|= italic
;
11034 x_font_name_to_mac_font_name (name
, mfontname
);
11035 c2pstr (mfontname
);
11036 GetFNum (mfontname
, &fontnum
);
11040 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
11042 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
11043 bcopy (name
, font
->fontname
, strlen (name
) + 1);
11045 font
->mac_fontnum
= fontnum
;
11046 font
->mac_fontsize
= size
;
11047 font
->mac_fontface
= fontface
;
11048 font
->mac_scriptcode
= FontToScript (fontnum
);
11050 /* Apple Japanese (SJIS) font is listed as both
11051 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
11052 (Roman script) in init_font_name_table (). The latter should be
11053 treated as a one-byte font. */
11058 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
11060 && 0 == strcmp (cs
, "jisx0201.1976-0"))
11061 font
->mac_scriptcode
= smRoman
;
11064 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
11065 font
->mac_scriptcode
== smTradChinese
||
11066 font
->mac_scriptcode
== smSimpChinese
||
11067 font
->mac_scriptcode
== smKorean
;
11069 TextFont (fontnum
);
11071 TextFace (fontface
);
11073 GetFontInfo (&the_fontinfo
);
11075 font
->ascent
= the_fontinfo
.ascent
;
11076 font
->descent
= the_fontinfo
.descent
;
11078 font
->min_byte1
= 0;
11079 if (is_two_byte_font
)
11080 font
->max_byte1
= 1;
11082 font
->max_byte1
= 0;
11083 font
->min_char_or_byte2
= 0x20;
11084 font
->max_char_or_byte2
= 0xff;
11086 if (is_two_byte_font
)
11088 /* Use the width of an "ideographic space" of that font because
11089 the_fontinfo.widMax returns the wrong width for some fonts. */
11090 switch (font
->mac_scriptcode
)
11093 char_width
= StringWidth("\p\x81\x40");
11095 case smTradChinese
:
11096 char_width
= StringWidth("\p\xa1\x40");
11098 case smSimpChinese
:
11099 char_width
= StringWidth("\p\xa1\xa1");
11102 char_width
= StringWidth("\p\xa1\xa1");
11107 /* Do this instead of use the_fontinfo.widMax, which incorrectly
11108 returns 15 for 12-point Monaco! */
11109 char_width
= CharWidth ('m');
11111 font
->max_bounds
.rbearing
= char_width
;
11112 font
->max_bounds
.lbearing
= 0;
11113 font
->max_bounds
.width
= char_width
;
11114 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
11115 font
->max_bounds
.descent
= the_fontinfo
.descent
;
11117 font
->min_bounds
= font
->max_bounds
;
11119 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
11120 font
->per_char
= NULL
;
11123 font
->per_char
= (XCharStruct
*)
11124 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
11128 for (c
= 0x20; c
<= 0xff; c
++)
11130 font
->per_char
[c
- 0x20] = font
->max_bounds
;
11131 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
11136 TextFont (old_fontnum
); /* restore previous font number, size and face */
11137 TextSize (old_fontsize
);
11138 TextFace (old_fontface
);
11144 /* Load font named FONTNAME of the size SIZE for frame F, and return a
11145 pointer to the structure font_info while allocating it dynamically.
11146 If SIZE is 0, load any size of font.
11147 If loading is failed, return NULL. */
11150 x_load_font (f
, fontname
, size
)
11152 register char *fontname
;
11155 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11156 Lisp_Object font_names
;
11158 /* Get a list of all the fonts that match this name. Once we
11159 have a list of matching fonts, we compare them against the fonts
11160 we already have by comparing names. */
11161 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
11163 if (!NILP (font_names
))
11168 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11169 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
11170 if (dpyinfo
->font_table
[i
].name
11171 && (!strcmp (dpyinfo
->font_table
[i
].name
,
11172 SDATA (XCAR (tail
)))
11173 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
11174 SDATA (XCAR (tail
)))))
11175 return (dpyinfo
->font_table
+ i
);
11178 /* Load the font and add it to the table. */
11181 struct MacFontStruct
*font
;
11182 struct font_info
*fontp
;
11183 unsigned long value
;
11186 /* If we have found fonts by x_list_font, load one of them. If
11187 not, we still try to load a font by the name given as FONTNAME
11188 because XListFonts (called in x_list_font) of some X server has
11189 a bug of not finding a font even if the font surely exists and
11190 is loadable by XLoadQueryFont. */
11191 if (size
> 0 && !NILP (font_names
))
11192 fontname
= (char *) SDATA (XCAR (font_names
));
11194 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
11198 /* Find a free slot in the font table. */
11199 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11200 if (dpyinfo
->font_table
[i
].name
== NULL
)
11203 /* If no free slot found, maybe enlarge the font table. */
11204 if (i
== dpyinfo
->n_fonts
11205 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
11208 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
11209 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
11210 dpyinfo
->font_table
11211 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
11214 fontp
= dpyinfo
->font_table
+ i
;
11215 if (i
== dpyinfo
->n_fonts
)
11216 ++dpyinfo
->n_fonts
;
11218 /* Now fill in the slots of *FONTP. */
11220 fontp
->font
= font
;
11221 fontp
->font_idx
= i
;
11222 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
11223 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
11225 fontp
->full_name
= fontp
->name
;
11227 fontp
->size
= font
->max_bounds
.width
;
11228 fontp
->height
= FONT_HEIGHT (font
);
11230 /* For some font, ascent and descent in max_bounds field is
11231 larger than the above value. */
11232 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
11233 if (max_height
> fontp
->height
)
11234 fontp
->height
= max_height
;
11237 /* The slot `encoding' specifies how to map a character
11238 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
11239 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
11240 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
11241 2:0xA020..0xFF7F). For the moment, we don't know which charset
11242 uses this font. So, we set information in fontp->encoding[1]
11243 which is never used by any charset. If mapping can't be
11244 decided, set FONT_ENCODING_NOT_DECIDED. */
11245 if (font
->mac_scriptcode
== smJapanese
)
11246 fontp
->encoding
[1] = 4;
11250 = (font
->max_byte1
== 0
11252 ? (font
->min_char_or_byte2
< 0x80
11253 ? (font
->max_char_or_byte2
< 0x80
11254 ? 0 /* 0x20..0x7F */
11255 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
11256 : 1) /* 0xA0..0xFF */
11258 : (font
->min_byte1
< 0x80
11259 ? (font
->max_byte1
< 0x80
11260 ? (font
->min_char_or_byte2
< 0x80
11261 ? (font
->max_char_or_byte2
< 0x80
11262 ? 0 /* 0x2020..0x7F7F */
11263 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
11264 : 3) /* 0x20A0..0x7FFF */
11265 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
11266 : (font
->min_char_or_byte2
< 0x80
11267 ? (font
->max_char_or_byte2
< 0x80
11268 ? 2 /* 0xA020..0xFF7F */
11269 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
11270 : 1))); /* 0xA0A0..0xFFFF */
11273 #if 0 /* MAC_TODO: fill these out with more reasonably values */
11274 fontp
->baseline_offset
11275 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
11276 ? (long) value
: 0);
11277 fontp
->relative_compose
11278 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
11279 ? (long) value
: 0);
11280 fontp
->default_ascent
11281 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
11282 ? (long) value
: 0);
11284 fontp
->baseline_offset
= 0;
11285 fontp
->relative_compose
= 0;
11286 fontp
->default_ascent
= 0;
11289 /* Set global flag fonts_changed_p to non-zero if the font loaded
11290 has a character with a smaller width than any other character
11291 before, or if the font loaded has a smalle>r height than any
11292 other font loaded before. If this happens, it will make a
11293 glyph matrix reallocation necessary. */
11294 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11301 /* Return a pointer to struct font_info of a font named FONTNAME for
11302 frame F. If no such font is loaded, return NULL. */
11305 x_query_font (f
, fontname
)
11307 register char *fontname
;
11309 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11312 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11313 if (dpyinfo
->font_table
[i
].name
11314 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11315 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11316 return (dpyinfo
->font_table
+ i
);
11321 /* Find a CCL program for a font specified by FONTP, and set the member
11322 `encoder' of the structure. */
11325 x_find_ccl_program (fontp
)
11326 struct font_info
*fontp
;
11328 Lisp_Object list
, elt
;
11330 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11334 && STRINGP (XCAR (elt
))
11335 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11341 struct ccl_program
*ccl
11342 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11344 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11347 fontp
->font_encoder
= ccl
;
11353 /***********************************************************************
11355 ***********************************************************************/
11357 #ifdef USE_X_TOOLKIT
11358 static XrmOptionDescRec emacs_options
[] = {
11359 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11360 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11362 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11363 XrmoptionSepArg
, NULL
},
11364 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11366 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11367 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11368 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11369 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11370 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11371 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11372 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11374 #endif /* USE_X_TOOLKIT */
11376 static int x_initialized
;
11378 #ifdef MULTI_KBOARD
11379 /* Test whether two display-name strings agree up to the dot that separates
11380 the screen number from the server number. */
11382 same_x_server (name1
, name2
)
11383 char *name1
, *name2
;
11385 int seen_colon
= 0;
11386 unsigned char *system_name
= SDATA (Vsystem_name
);
11387 int system_name_length
= strlen (system_name
);
11388 int length_until_period
= 0;
11390 while (system_name
[length_until_period
] != 0
11391 && system_name
[length_until_period
] != '.')
11392 length_until_period
++;
11394 /* Treat `unix' like an empty host name. */
11395 if (! strncmp (name1
, "unix:", 5))
11397 if (! strncmp (name2
, "unix:", 5))
11399 /* Treat this host's name like an empty host name. */
11400 if (! strncmp (name1
, system_name
, system_name_length
)
11401 && name1
[system_name_length
] == ':')
11402 name1
+= system_name_length
;
11403 if (! strncmp (name2
, system_name
, system_name_length
)
11404 && name2
[system_name_length
] == ':')
11405 name2
+= system_name_length
;
11406 /* Treat this host's domainless name like an empty host name. */
11407 if (! strncmp (name1
, system_name
, length_until_period
)
11408 && name1
[length_until_period
] == ':')
11409 name1
+= length_until_period
;
11410 if (! strncmp (name2
, system_name
, length_until_period
)
11411 && name2
[length_until_period
] == ':')
11412 name2
+= length_until_period
;
11414 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11418 if (seen_colon
&& *name1
== '.')
11422 && (*name1
== '.' || *name1
== '\0')
11423 && (*name2
== '.' || *name2
== '\0'));
11428 /* The Mac Event loop code */
11431 #include <Events.h>
11432 #include <Quickdraw.h>
11433 #include <Balloons.h>
11434 #include <Devices.h>
11436 #include <Gestalt.h>
11438 #include <Processes.h>
11440 #include <ToolUtils.h>
11441 #include <TextUtils.h>
11442 #include <Dialogs.h>
11443 #include <Script.h>
11445 #include <TextEncodingConverter.h>
11446 #include <Resources.h>
11451 #endif /* ! MAC_OSX */
11453 #define M_APPLE 128
11456 #define WINDOW_RESOURCE 128
11457 #define TERM_WINDOW_RESOURCE 129
11459 #define DEFAULT_NUM_COLS 80
11461 #define MIN_DOC_SIZE 64
11462 #define MAX_DOC_SIZE 32767
11464 /* sleep time for WaitNextEvent */
11465 #define WNE_SLEEP_AT_SUSPEND 10
11466 #define WNE_SLEEP_AT_RESUME 1
11468 /* true when cannot handle any Mac OS events */
11469 static int handling_window_update
= 0;
11471 /* the flag appl_is_suspended is used both for determining the sleep
11472 time to be passed to WaitNextEvent and whether the cursor should be
11473 drawn when updating the display. The cursor is turned off when
11474 Emacs is suspended. Redrawing it is unnecessary and what needs to
11475 be done depends on whether the cursor lies inside or outside the
11476 redraw region. So we might as well skip drawing it when Emacs is
11478 static Boolean app_is_suspended
= false;
11479 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11481 #define EXTRA_STACK_ALLOC (256 * 1024)
11483 #define ARGV_STRING_LIST_ID 129
11484 #define ABOUT_ALERT_ID 128
11485 #define RAM_TOO_LARGE_ALERT_ID 129
11487 Boolean terminate_flag
= false;
11489 /* True if using command key as meta key. */
11490 Lisp_Object Vmac_command_key_is_meta
;
11492 /* True if the ctrl and meta keys should be reversed. */
11493 Lisp_Object Vmac_reverse_ctrl_meta
;
11495 #if USE_CARBON_EVENTS
11496 /* True if the mouse wheel button (i.e. button 4) should map to
11497 mouse-2, instead of mouse-3. */
11498 Lisp_Object Vmac_wheel_button_is_mouse_2
;
11501 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11502 to this text encoding */
11503 int mac_keyboard_text_encoding
;
11504 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11506 /* Set in term/mac-win.el to indicate that event loop can now generate
11507 drag and drop events. */
11508 Lisp_Object Qmac_ready_for_drag_n_drop
;
11510 Lisp_Object drag_and_drop_file_list
;
11512 Point saved_menu_event_location
;
11515 static void init_required_apple_events (void);
11516 static pascal OSErr
11517 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
11518 static pascal OSErr
11519 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
11520 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
11521 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
11523 /* Drag and Drop */
11524 static OSErr
init_mac_drag_n_drop ();
11525 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
11527 #if USE_CARBON_EVENTS
11528 /* Preliminary Support for the OSX Services Menu */
11529 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
11530 static void init_service_handler ();
11533 extern void init_emacs_passwd_dir ();
11534 extern int emacs_main (int, char **, char **);
11535 extern void check_alarm ();
11537 extern void initialize_applescript();
11538 extern void terminate_applescript();
11540 static unsigned int
11541 #if USE_CARBON_EVENTS
11542 mac_to_emacs_modifiers (UInt32 mods
)
11544 mac_to_emacs_modifiers (EventModifiers mods
)
11547 unsigned int result
= 0;
11548 if (mods
& macShiftKey
)
11549 result
|= shift_modifier
;
11550 if (mods
& macCtrlKey
)
11551 result
|= ctrl_modifier
;
11552 if (mods
& macMetaKey
)
11553 result
|= meta_modifier
;
11554 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
11555 result
|= alt_modifier
;
11559 #if USE_CARBON_EVENTS
11560 /* Obtains the event modifiers from the event ref and then calls
11561 mac_to_emacs_modifiers. */
11563 mac_event_to_emacs_modifiers (EventRef eventRef
)
11566 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
11567 sizeof (UInt32
), NULL
, &mods
);
11568 return mac_to_emacs_modifiers (mods
);
11571 /* Given an event ref, return the code to use for the mouse button
11572 code in the emacs input_event. */
11574 mac_get_mouse_btn (EventRef ref
)
11576 EventMouseButton result
= kEventMouseButtonPrimary
;
11577 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
11578 sizeof (EventMouseButton
), NULL
, &result
);
11581 case kEventMouseButtonPrimary
:
11583 case kEventMouseButtonSecondary
:
11584 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
11585 case kEventMouseButtonTertiary
:
11586 case 4: /* 4 is the number for the mouse wheel button */
11587 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
11593 /* Normally, ConvertEventRefToEventRecord will correctly handle all
11594 events. However the click of the mouse wheel is not converted to a
11595 mouseDown or mouseUp event. This calls ConvertEventRef, but then
11596 checks to see if it is a mouse up or down carbon event that has not
11597 been converted, and if so, converts it by hand (to be picked up in
11598 the XTread_socket loop). */
11599 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
11601 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
11602 /* Do special case for mouse wheel button. */
11603 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
11605 UInt32 kind
= GetEventKind (eventRef
);
11606 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
11608 eventRec
->what
= mouseDown
;
11611 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
11613 eventRec
->what
= mouseUp
;
11618 /* Need where and when. */
11620 GetEventParameter (eventRef
, kEventParamMouseLocation
,
11621 typeQDPoint
, NULL
, sizeof (Point
),
11622 NULL
, &eventRec
->where
);
11623 /* Use two step process because new event modifiers are
11624 32-bit and old are 16-bit. Currently, only loss is
11626 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
11627 typeUInt32
, NULL
, sizeof (UInt32
),
11629 eventRec
->modifiers
= mods
;
11631 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
11640 do_get_menus (void)
11642 Handle menubar_handle
;
11643 MenuHandle menu_handle
;
11645 menubar_handle
= GetNewMBar (128);
11646 if(menubar_handle
== NULL
)
11648 SetMenuBar (menubar_handle
);
11651 menu_handle
= GetMenuHandle (M_APPLE
);
11652 if(menu_handle
!= NULL
)
11653 AppendResMenu (menu_handle
,'DRVR');
11660 do_init_managers (void)
11662 #if !TARGET_API_MAC_CARBON
11663 InitGraf (&qd
.thePort
);
11665 FlushEvents (everyEvent
, 0);
11669 InitDialogs (NULL
);
11670 #endif /* !TARGET_API_MAC_CARBON */
11673 #if !TARGET_API_MAC_CARBON
11674 /* set up some extra stack space for use by emacs */
11675 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11677 /* MaxApplZone must be called for AppleScript to execute more
11678 complicated scripts */
11681 #endif /* !TARGET_API_MAC_CARBON */
11685 do_check_ram_size (void)
11687 SInt32 physical_ram_size
, logical_ram_size
;
11689 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11690 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11691 || physical_ram_size
> 256 * 1024 * 1024
11692 || logical_ram_size
> 256 * 1024 * 1024)
11694 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11700 do_window_update (WindowPtr win
)
11702 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11703 struct frame
*f
= mwp
->mFP
;
11707 if (f
->async_visible
== 0)
11709 f
->async_visible
= 1;
11710 f
->async_iconified
= 0;
11711 SET_FRAME_GARBAGED (f
);
11713 /* An update event is equivalent to MapNotify on X, so report
11714 visibility changes properly. */
11715 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11716 /* Force a redisplay sooner or later to update the
11717 frame titles in case this is the second frame. */
11718 record_asynch_buffer_change ();
11723 handling_window_update
= 1;
11725 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
11727 expose_frame (f
, 0, 0, 0, 0);
11729 handling_window_update
= 0;
11736 is_emacs_window (WindowPtr win
)
11738 Lisp_Object tail
, frame
;
11743 FOR_EACH_FRAME (tail
, frame
)
11744 if (FRAME_MAC_P (XFRAME (frame
)))
11745 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11752 do_window_activate (WindowPtr win
)
11757 if (is_emacs_window (win
))
11759 mwp
= (mac_output
*) GetWRefCon (win
);
11764 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11765 activate_scroll_bars (f
);
11771 do_window_deactivate (WindowPtr win
)
11776 if (is_emacs_window (win
))
11778 mwp
= (mac_output
*) GetWRefCon (win
);
11781 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11783 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11784 deactivate_scroll_bars (f
);
11796 wp
= FrontWindow();
11797 if (is_emacs_window (wp
))
11799 mwp
= (mac_output
*) GetWRefCon (wp
);
11804 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11805 activate_scroll_bars (f
);
11809 app_is_suspended
= false;
11810 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11820 wp
= FrontWindow();
11821 if (is_emacs_window (wp
))
11823 mwp
= (mac_output
*) GetWRefCon (wp
);
11826 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11828 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11829 deactivate_scroll_bars (f
);
11833 app_is_suspended
= true;
11834 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11839 do_mouse_moved (Point mouse_pos
)
11841 WindowPtr wp
= FrontWindow ();
11842 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11844 #if TARGET_API_MAC_CARBON
11845 SetPort (GetWindowPort (wp
));
11850 GlobalToLocal (&mouse_pos
);
11852 note_mouse_movement (f
, &mouse_pos
);
11857 do_os_event (EventRecord
*erp
)
11859 switch((erp
->message
>> 24) & 0x000000FF)
11861 case suspendResumeMessage
:
11862 if((erp
->message
& resumeFlag
) == 1)
11868 case mouseMovedMessage
:
11869 do_mouse_moved (erp
->where
);
11875 do_events (EventRecord
*erp
)
11880 do_window_update ((WindowPtr
) erp
->message
);
11888 if ((erp
->modifiers
& activeFlag
) != 0)
11889 do_window_activate ((WindowPtr
) erp
->message
);
11891 do_window_deactivate ((WindowPtr
) erp
->message
);
11897 do_apple_menu (SInt16 menu_item
)
11899 #if !TARGET_API_MAC_CARBON
11901 SInt16 da_driver_refnum
;
11903 if (menu_item
== I_ABOUT
)
11904 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11907 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11908 da_driver_refnum
= OpenDeskAcc (item_name
);
11910 #endif /* !TARGET_API_MAC_CARBON */
11914 do_menu_choice (SInt32 menu_choice
)
11916 SInt16 menu_id
, menu_item
;
11918 menu_id
= HiWord (menu_choice
);
11919 menu_item
= LoWord (menu_choice
);
11927 do_apple_menu (menu_item
);
11932 WindowPtr wp
= FrontWindow ();
11933 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11934 MenuHandle menu
= GetMenuHandle (menu_id
);
11939 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11940 menubar_selection_callback (f
, refcon
);
11949 /* Handle drags in size box. Based on code contributed by Ben
11950 Mesander and IM - Window Manager A. */
11953 do_grow_window (WindowPtr w
, EventRecord
*e
)
11958 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11959 struct frame
*f
= mwp
->mFP
;
11961 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11963 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11965 /* see if it really changed size */
11966 if (grow_size
!= 0)
11968 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11969 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11971 x_set_window_size (f
, 0, columns
, rows
);
11976 /* Handle clicks in zoom box. Calculation of "standard state" based
11977 on code in IM - Window Manager A and code contributed by Ben
11978 Mesander. The standard state of an Emacs window is 80-characters
11979 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11982 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11985 Rect zoom_rect
, port_rect
;
11987 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11988 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11989 struct frame
*f
= mwp
->mFP
;
11991 GetPort (&save_port
);
11993 #if TARGET_API_MAC_CARBON
11994 SetPort (GetWindowPort (w
));
11999 /* Clear window to avoid flicker. */
12000 #if TARGET_API_MAC_CARBON
12005 GetWindowPortBounds (w
, &r
);
12008 if (zoom_in_or_out
== inZoomOut
)
12010 /* calculate height of window's title bar (hard card it for now). */
12011 w_title_height
= 20 + GetMBarHeight ();
12013 /* get maximum height of window into zoom_rect.bottom -
12015 GetQDGlobalsScreenBits (&bm
);
12016 zoom_rect
= bm
.bounds
;
12017 zoom_rect
.top
+= w_title_height
;
12018 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
12020 zoom_rect
.right
= zoom_rect
.left
12021 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
12023 SetWindowStandardState (w
, &zoom_rect
);
12026 #else /* not TARGET_API_MAC_CARBON */
12027 EraseRect (&(w
->portRect
));
12028 if (zoom_in_or_out
== inZoomOut
)
12030 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
12031 LocalToGlobal (&top_left
);
12033 /* calculate height of window's title bar */
12034 w_title_height
= top_left
.v
- 1
12035 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
12037 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
12038 zoom_rect
= qd
.screenBits
.bounds
;
12039 zoom_rect
.top
+= w_title_height
;
12040 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
12042 zoom_rect
.right
= zoom_rect
.left
12043 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
12045 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
12048 #endif /* not TARGET_API_MAC_CARBON */
12050 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
12052 /* retrieve window size and update application values */
12053 #if TARGET_API_MAC_CARBON
12054 GetWindowPortBounds (w
, &port_rect
);
12056 port_rect
= w
->portRect
;
12058 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
12059 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
12060 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
12062 SetPort (save_port
);
12065 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
12067 init_mac_drag_n_drop ()
12069 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
12073 /* Intialize AppleEvent dispatcher table for the required events. */
12075 init_required_apple_events ()
12080 /* Make sure we have apple events before starting. */
12081 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
12085 if (!(result
& (1 << gestaltAppleEventsPresent
)))
12088 #if TARGET_API_MAC_CARBON
12089 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12090 NewAEEventHandlerUPP
12091 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12094 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
12095 NewAEEventHandlerProc
12096 ((AEEventHandlerProcPtr
) do_ae_open_application
),
12102 #if TARGET_API_MAC_CARBON
12103 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12104 NewAEEventHandlerUPP
12105 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12108 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
12109 NewAEEventHandlerProc
12110 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
12116 #if TARGET_API_MAC_CARBON
12117 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12118 NewAEEventHandlerUPP
12119 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12122 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12123 NewAEEventHandlerProc
12124 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12130 #if TARGET_API_MAC_CARBON
12131 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12132 NewAEEventHandlerUPP
12133 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12136 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12137 NewAEEventHandlerProc
12138 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12145 #if USE_CARBON_EVENTS
12147 void init_service_handler()
12149 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
12150 {kEventClassService
, kEventServiceCopy
},
12151 {kEventClassService
, kEventServicePaste
}};
12152 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
12153 3, specs
, NULL
, NULL
);
12157 MAC_TODO: Check to see if this is called by AEProcessDesc...
12159 OSStatus
mac_handle_service_event (EventHandlerCallRef callRef
,
12160 EventRef event
, void *data
)
12162 OSStatus err
= noErr
;
12163 switch (GetEventKind (event
))
12165 case kEventServiceGetTypes
:
12167 CFMutableArrayRef copyTypes
, pasteTypes
;
12169 Boolean selection
= true;
12171 GetEventParameter(event, kEventParamServicePasteTypes,
12172 typeCFMutableArrayRef, NULL,
12173 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
12175 GetEventParameter(event
, kEventParamServiceCopyTypes
,
12176 typeCFMutableArrayRef
, NULL
,
12177 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
12178 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
12180 CFArrayAppendValue (copyTypes
, type
);
12181 //CFArrayAppendValue (pasteTypes, type);
12185 case kEventServiceCopy
:
12187 ScrapRef currentScrap
, specificScrap
;
12189 Size byteCount
= 0;
12191 GetCurrentScrap (¤tScrap
);
12193 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
12196 void *buffer
= xmalloc (byteCount
);
12197 if (buffer
!= NULL
)
12199 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
12200 sizeof (ScrapRef
), NULL
, &specificScrap
);
12202 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
12203 &byteCount
, buffer
);
12205 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
12206 kScrapFlavorMaskNone
, byteCount
, buffer
);
12212 case kEventServicePaste
:
12215 // Get the current location
12217 ScrapRef specificScrap;
12218 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
12219 sizeof(ScrapRef), NULL, &specificScrap);
12220 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
12221 if (err == noErr) {
12222 void * buffer = xmalloc(byteCount);
12223 if (buffer != NULL ) {
12224 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
12225 &byteCount, buffer);
12226 if (err == noErr) {
12227 // Actually place in the buffer
12229 // Get the current "selection" string here
12242 /* Open Application Apple Event */
12243 static pascal OSErr
12244 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
12250 /* Defined in mac.c. */
12252 path_from_vol_dir_name (char *, int, short, long, char *);
12255 /* Called when we receive an AppleEvent with an ID of
12256 "kAEOpenDocuments". This routine gets the direct parameter,
12257 extracts the FSSpecs in it, and puts their names on a list. */
12258 static pascal OSErr
12259 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
12264 DescType actual_type
;
12267 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
12269 goto descriptor_error_exit
;
12271 /* Check to see that we got all of the required parameters from the
12272 event descriptor. For an 'odoc' event this should just be the
12274 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
12275 &actual_type
, (Ptr
) &keyword
,
12276 sizeof (keyword
), &actual_size
);
12277 /* No error means that we found some unused parameters.
12278 errAEDescNotFound means that there are no more parameters. If we
12279 get an error code other than that, flag it. */
12280 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
12282 err
= errAEEventNotHandled
;
12287 /* Got all the parameters we need. Now, go through the direct
12288 object list and parse it up. */
12290 long num_files_to_open
;
12292 err
= AECountItems (&the_desc
, &num_files_to_open
);
12297 /* AE file list is one based so just use that for indexing here. */
12298 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
12301 Str255 path_name
, unix_path_name
;
12306 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12307 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12308 if (err
!= noErr
) break;
12311 err
= FSpMakeFSRef (&fs
, &fref
);
12312 if (err
!= noErr
) break;
12314 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
12316 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12318 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12320 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12321 drag_and_drop_file_list
);
12327 /* Nuke the coerced file list in any case */
12328 err2
= AEDisposeDesc(&the_desc
);
12330 descriptor_error_exit
:
12331 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12336 static pascal OSErr
mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
12337 DragReference theDrag
)
12341 FlavorFlags theFlags
;
12344 ItemReference theItem
;
12347 Size size
= sizeof (HFSFlavor
);
12349 drag_and_drop_file_list
= Qnil
;
12350 GetDragMouse (theDrag
, &mouse
, 0L);
12351 CountDragItems (theDrag
, &items
);
12352 for (index
= 1; index
<= items
; index
++)
12354 /* Only handle file references. */
12355 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
12356 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
12357 if (result
== noErr
)
12364 Str255 unix_path_name
;
12365 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
12367 /* Use Carbon routines, otherwise it converts the file name
12368 to /Macintosh HD/..., which is not correct. */
12369 FSpMakeFSRef (&data
.fileSpec
, &fref
);
12370 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
12372 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
12373 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
12374 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12376 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12377 drag_and_drop_file_list
);
12382 /* If there are items in the list, construct an event and post it to
12383 the queue like an interrupt using kbd_buffer_store_event. */
12384 if (!NILP (drag_and_drop_file_list
))
12386 struct input_event event
;
12388 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
12389 SetPort (GetWindowPort (window
));
12390 GlobalToLocal (&mouse
);
12392 event
.kind
= DRAG_N_DROP_EVENT
;
12394 event
.modifiers
= 0;
12395 event
.timestamp
= TickCount () * (1000 / 60);
12396 XSETINT (event
.x
, mouse
.h
);
12397 XSETINT (event
.y
, mouse
.v
);
12398 XSETFRAME (frame
, f
);
12399 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12401 /* Post to the interrupt queue */
12402 kbd_buffer_store_event (&event
);
12403 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
12405 ProcessSerialNumber psn
;
12406 GetCurrentProcess (&psn
);
12407 SetFrontProcess (&psn
);
12413 /* Print Document Apple Event */
12414 static pascal OSErr
12415 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12417 return errAEEventNotHandled
;
12421 static pascal OSErr
12422 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12424 /* FixMe: Do we need an unwind-protect or something here? And what
12425 do we do about unsaved files. Currently just forces quit rather
12426 than doing recursive callback to get user input. */
12428 terminate_flag
= true;
12430 /* Fkill_emacs doesn't return. We have to return. (TI) */
12437 profiler_exit_proc ()
12439 ProfilerDump ("\pEmacs.prof");
12444 /* These few functions implement Emacs as a normal Mac application
12445 (almost): set up the heap and the Toolbox, handle necessary
12446 system events plus a few simple menu events. They also set up
12447 Emacs's access to functions defined in the rest of this file.
12448 Emacs uses function hooks to perform all its terminal I/O. A
12449 complete list of these functions appear in termhooks.h. For what
12450 they do, read the comments there and see also w32term.c and
12451 xterm.c. What's noticeably missing here is the event loop, which
12452 is normally present in most Mac application. After performing the
12453 necessary Mac initializations, main passes off control to
12454 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12455 mac_read_socket (defined further below) to read input. This is
12456 where WaitNextEvent is called to process Mac events. This is also
12457 where check_alarm in sysdep.c is called to simulate alarm signals.
12458 This makes the cursor jump back to its correct position after
12459 briefly jumping to that of the matching parenthesis, print useful
12460 hints and prompts in the minibuffer after the user stops typing for
12463 #if !TARGET_API_MAC_CARBON
12468 #if __profile__ /* is the profiler on? */
12469 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12474 /* set creator and type for files created by MSL */
12475 _fcreator
= 'EMAx';
12479 do_init_managers ();
12483 do_check_ram_size ();
12485 init_emacs_passwd_dir ();
12489 initialize_applescript ();
12491 init_required_apple_events ();
12497 /* set up argv array from STR# resource */
12498 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12502 /* free up AppleScript resources on exit */
12503 atexit (terminate_applescript
);
12505 #if __profile__ /* is the profiler on? */
12506 atexit (profiler_exit_proc
);
12509 /* 3rd param "envp" never used in emacs_main */
12510 (void) emacs_main (argc
, argv
, 0);
12513 /* Never reached - real exit in Fkill_emacs */
12518 /* Table for translating Mac keycode to X keysym values. Contributed
12519 by Sudhir Shenoy. */
12520 static unsigned char keycode_to_xkeysym_table
[] = {
12522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12523 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12524 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12527 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
12528 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
12529 0, 0, 0, '\xaf' /* kp/ */,
12530 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
12532 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
12533 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
12534 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
12535 '\xb9' /* kp9 */, 0, 0, 0,
12537 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
12538 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
12539 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
12540 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
12542 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
12543 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
12544 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
12545 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
12549 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12551 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12552 return *xKeySym
!= 0;
12555 /* Emacs calls this whenever it wants to read an input event from the
12558 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12561 #if USE_CARBON_EVENTS
12562 OSStatus rneResult
;
12564 EventMouseButton mouseBtn
;
12568 EventMask event_mask
;
12571 if (interrupt_input_blocked
)
12573 interrupt_input_pending
= 1;
12578 interrupt_input_pending
= 0;
12581 /* So people can tell when we have read the available input. */
12582 input_signal_count
++;
12587 /* Don't poll for events to process (specifically updateEvt) if
12588 window update currently already in progress. A call to redisplay
12589 (in do_window_update) can be preempted by another call to
12590 redisplay, causing blank regions to be left on the screen and the
12591 cursor to be left at strange places. */
12592 if (handling_window_update
)
12598 if (terminate_flag
)
12599 Fkill_emacs (make_number (1));
12601 /* It is necessary to set this (additional) argument slot of an
12602 event to nil because keyboard.c protects incompletely processed
12603 event from being garbage collected by placing them in the
12604 kbd_buffer_gcpro vector. */
12607 event_mask
= everyEvent
;
12608 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12609 event_mask
-= highLevelEventMask
;
12611 #if USE_CARBON_EVENTS
12612 rneResult
= ReceiveNextEvent (0, NULL
,
12614 ? TicksToEventTime (app_sleep_time
)
12619 /* Handle new events */
12620 if (!mac_convert_event_ref (eventRef
, &er
))
12621 switch (GetEventClass (eventRef
))
12623 case kEventClassMouse
:
12624 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
12628 WindowPtr window_ptr
= FrontWindow ();
12629 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12630 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
12631 typeSInt32
, NULL
, sizeof (SInt32
),
12633 GetEventParameter(eventRef
, kEventParamMouseLocation
,
12634 typeQDPoint
, NULL
, sizeof (Point
),
12636 bufp
->kind
= MOUSE_WHEEL_EVENT
;
12637 bufp
->code
= delta
;
12638 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
12639 SetPort (GetWindowPort (window_ptr
));
12640 GlobalToLocal (&point
);
12641 XSETINT (bufp
->x
, point
.h
);
12642 XSETINT (bufp
->y
, point
.v
);
12643 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12644 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
12648 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12652 /* Send the event to the appropriate receiver. */
12653 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12657 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
12658 #endif /* USE_CARBON_EVENTS */
12664 WindowPtr window_ptr
= FrontWindow ();
12667 #if USE_CARBON_EVENTS
12668 /* This is needed to correctly */
12669 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12672 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12673 && er
.what
== mouseUp
)
12675 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12676 Point mouse_loc
= er
.where
;
12678 /* Convert to local coordinates of new window. */
12679 #if TARGET_API_MAC_CARBON
12680 SetPort (GetWindowPort (window_ptr
));
12682 SetPort (window_ptr
);
12685 GlobalToLocal (&mouse_loc
);
12687 #if USE_CARBON_EVENTS
12688 bufp
->code
= mac_get_mouse_btn (eventRef
);
12690 bufp
->code
= 0; /* only one mouse button */
12692 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
12693 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12694 bufp
->part
= scroll_bar_handle
;
12695 #if USE_CARBON_EVENTS
12696 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12698 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12700 bufp
->modifiers
|= up_modifier
;
12701 bufp
->timestamp
= er
.when
* (1000 / 60);
12702 /* ticks to milliseconds */
12704 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12705 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12706 tracked_scroll_bar
->dragging
= Qnil
;
12707 mouse_tracking_in_progress
= mouse_tracking_none
;
12708 tracked_scroll_bar
= NULL
;
12713 part_code
= FindWindow (er
.where
, &window_ptr
);
12719 struct frame
*f
= ((mac_output
*)
12720 GetWRefCon (FrontWindow ()))->mFP
;
12721 saved_menu_event_location
= er
.where
;
12722 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
12723 XSETFRAME (bufp
->frame_or_window
, f
);
12729 if (window_ptr
!= FrontWindow ())
12730 SelectWindow (window_ptr
);
12733 SInt16 control_part_code
;
12735 struct mac_output
*mwp
= (mac_output
*)
12736 GetWRefCon (window_ptr
);
12737 Point mouse_loc
= er
.where
;
12739 /* convert to local coordinates of new window */
12740 #if TARGET_API_MAC_CARBON
12741 SetPort (GetWindowPort (window_ptr
));
12743 SetPort (window_ptr
);
12746 GlobalToLocal (&mouse_loc
);
12747 #if TARGET_API_MAC_CARBON
12748 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12749 &control_part_code
);
12751 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12754 #if USE_CARBON_EVENTS
12755 bufp
->code
= mac_get_mouse_btn (eventRef
);
12757 bufp
->code
= 0; /* only one mouse button */
12759 XSETINT (bufp
->x
, mouse_loc
.h
);
12760 XSETINT (bufp
->y
, mouse_loc
.v
);
12761 bufp
->timestamp
= er
.when
* (1000 / 60);
12762 /* ticks to milliseconds */
12764 #if TARGET_API_MAC_CARBON
12767 if (control_part_code
!= 0)
12770 struct scroll_bar
*bar
= (struct scroll_bar
*)
12771 GetControlReference (ch
);
12772 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12774 if (er
.what
== mouseDown
12775 && control_part_code
== kControlIndicatorPart
)
12777 mouse_tracking_in_progress
12778 = mouse_tracking_scroll_bar
;
12779 tracked_scroll_bar
= bar
;
12783 mouse_tracking_in_progress
= mouse_tracking_none
;
12784 tracked_scroll_bar
= NULL
;
12789 bufp
->kind
= MOUSE_CLICK_EVENT
;
12790 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12791 if (er
.what
== mouseDown
)
12792 mouse_tracking_in_progress
12793 = mouse_tracking_mouse_movement
;
12795 mouse_tracking_in_progress
= mouse_tracking_none
;
12798 #if USE_CARBON_EVENTS
12799 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12801 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12807 bufp
->modifiers
|= down_modifier
;
12810 bufp
->modifiers
|= up_modifier
;
12819 #if TARGET_API_MAC_CARBON
12823 GetQDGlobalsScreenBits (&bm
);
12824 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12826 #else /* not TARGET_API_MAC_CARBON */
12827 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12828 #endif /* not TARGET_API_MAC_CARBON */
12832 if (TrackGoAway (window_ptr
, er
.where
))
12834 bufp
->kind
= DELETE_WINDOW_EVENT
;
12835 XSETFRAME (bufp
->frame_or_window
,
12836 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12841 /* window resize handling added --ben */
12843 do_grow_window(window_ptr
, &er
);
12846 /* window zoom handling added --ben */
12849 if (TrackBox (window_ptr
, er
.where
, part_code
))
12850 do_zoom_window (window_ptr
, part_code
);
12862 #if USE_CARBON_EVENTS
12863 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12871 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12874 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
12883 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12886 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12888 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12890 bufp
->code
= 0xff00 | xkeysym
;
12891 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
12893 else if (!NILP (Vmac_reverse_ctrl_meta
) && (er
.modifiers
& controlKey
))
12895 /* This is a special case to deal with converting from
12896 a control character to non-control character */
12897 int new_modifiers
= er
.modifiers
& ~controlKey
;
12898 int new_keycode
= keycode
| new_modifiers
;
12899 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12900 unsigned long some_state
= 0;
12901 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
, &some_state
) & 0xff;
12902 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12906 if (er
.modifiers
& macMetaKey
)
12908 /* This code comes from Keyboard Resource, Appendix
12909 C of IM - Text. This is necessary since shift is
12910 ignored in KCHR table translation when option or
12911 command is pressed. */
12912 int new_modifiers
= er
.modifiers
& 0xf600;
12913 /* mask off option and command */
12914 int new_keycode
= keycode
| new_modifiers
;
12915 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12916 unsigned long some_state
= 0;
12917 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12918 &some_state
) & 0xff;
12920 #if USE_CARBON_EVENTS
12921 else if (er
.modifiers
& cmdKey
&&
12922 (NILP (Vmac_command_key_is_meta
)))
12924 /* If this is a command key (and we are not overriding it),
12925 send back to the operating system */
12926 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
12931 bufp
->code
= er
.message
& charCodeMask
;
12932 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
12936 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12937 convert non-ASCII characters typed at the Mac keyboard
12938 (presumed to be in the Mac Roman encoding) to iso-latin-1
12939 encoding before they are passed to Emacs. This enables the
12940 Mac keyboard to be used to enter non-ASCII iso-latin-1
12941 characters directly. */
12942 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12943 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
12945 static TECObjectRef converter
= NULL
;
12946 OSStatus the_err
= noErr
;
12947 OSStatus convert_status
= noErr
;
12949 if (converter
== NULL
)
12951 the_err
= TECCreateConverter (&converter
,
12952 kTextEncodingMacRoman
,
12953 mac_keyboard_text_encoding
);
12954 current_mac_keyboard_text_encoding
12955 = mac_keyboard_text_encoding
;
12957 else if (mac_keyboard_text_encoding
12958 != current_mac_keyboard_text_encoding
)
12960 /* Free the converter for the current encoding before
12961 creating a new one. */
12962 TECDisposeConverter (converter
);
12963 the_err
= TECCreateConverter (&converter
,
12964 kTextEncodingMacRoman
,
12965 mac_keyboard_text_encoding
);
12966 current_mac_keyboard_text_encoding
12967 = mac_keyboard_text_encoding
;
12970 if (the_err
== noErr
)
12972 unsigned char ch
= bufp
->code
;
12973 ByteCount actual_input_length
, actual_output_length
;
12974 unsigned char outch
;
12976 convert_status
= TECConvertText (converter
, &ch
, 1,
12977 &actual_input_length
,
12979 &actual_output_length
);
12980 if (convert_status
== noErr
12981 && actual_input_length
== 1
12982 && actual_output_length
== 1)
12983 bufp
->code
= outch
;
12987 #if USE_CARBON_EVENTS
12988 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
12990 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
12995 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
12996 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12999 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
13004 case kHighLevelEvent
:
13005 drag_and_drop_file_list
= Qnil
;
13007 AEProcessAppleEvent(&er
);
13009 /* Build a DRAG_N_DROP_EVENT type event as is done in
13010 constuct_drag_n_drop in w32term.c. */
13011 if (!NILP (drag_and_drop_file_list
))
13017 wp
= FrontWindow ();
13021 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
13023 bufp
->kind
= DRAG_N_DROP_EVENT
;
13025 bufp
->timestamp
= er
.when
* (1000 / 60);
13026 /* ticks to milliseconds */
13027 #if USE_CARBON_EVENTS
13028 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
13030 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
13033 XSETINT (bufp
->x
, 0);
13034 XSETINT (bufp
->y
, 0);
13036 XSETFRAME (frame
, f
);
13037 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
13039 /* Regardless of whether Emacs was suspended or in the
13040 foreground, ask it to redraw its entire screen.
13041 Otherwise parts of the screen can be left in an
13042 inconsistent state. */
13044 #if TARGET_API_MAC_CARBON
13048 GetWindowPortBounds (wp
, &r
);
13049 InvalWindowRect (wp
, &r
);
13051 #else /* not TARGET_API_MAC_CARBON */
13052 InvalRect (&(wp
->portRect
));
13053 #endif /* not TARGET_API_MAC_CARBON */
13060 #if USE_CARBON_EVENTS
13061 ReleaseEvent (eventRef
);
13065 /* If the focus was just given to an autoraising frame,
13067 /* ??? This ought to be able to handle more than one such frame. */
13068 if (pending_autoraise_frame
)
13070 x_raise_frame (pending_autoraise_frame
);
13071 pending_autoraise_frame
= 0;
13074 #if !TARGET_API_MAC_CARBON
13075 check_alarm (); /* simulate the handling of a SIGALRM */
13079 static Point old_mouse_pos
= { -1, -1 };
13081 if (app_is_suspended
)
13083 old_mouse_pos
.h
= -1;
13084 old_mouse_pos
.v
= -1;
13092 struct scroll_bar
*sb
;
13094 wp
= FrontWindow ();
13095 if (is_emacs_window (wp
))
13097 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
13099 #if TARGET_API_MAC_CARBON
13100 SetPort (GetWindowPort (wp
));
13105 GetMouse (&mouse_pos
);
13107 if (!EqualPt (mouse_pos
, old_mouse_pos
))
13109 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
13110 && tracked_scroll_bar
)
13111 x_scroll_bar_note_movement (tracked_scroll_bar
,
13113 - XINT (tracked_scroll_bar
->top
),
13114 TickCount() * (1000 / 60));
13116 note_mouse_movement (f
, &mouse_pos
);
13118 old_mouse_pos
= mouse_pos
;
13130 /* Need to override CodeWarrior's input function so no conversion is
13131 done on newlines Otherwise compiled functions in .elc files will be
13132 read incorrectly. Defined in ...:MSL C:MSL
13133 Common:Source:buffer_io.c. */
13136 __convert_to_newlines (unsigned char * p
, size_t * n
)
13138 #pragma unused(p,n)
13142 __convert_from_newlines (unsigned char * p
, size_t * n
)
13144 #pragma unused(p,n)
13149 /* Initialize the struct pointed to by MW to represent a new COLS x
13150 ROWS Macintosh window, using font with name FONTNAME and size
13153 NewMacWindow (FRAME_PTR fp
)
13156 #if TARGET_API_MAC_CARBON
13157 static int making_terminal_window
= 0;
13159 static int making_terminal_window
= 1;
13162 mwp
= fp
->output_data
.mac
;
13164 if (making_terminal_window
)
13166 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
13169 making_terminal_window
= 0;
13172 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
13175 SetWRefCon (mwp
->mWP
, (long) mwp
);
13176 /* so that update events can find this mac_output struct */
13177 mwp
->mFP
= fp
; /* point back to emacs frame */
13179 #if TARGET_API_MAC_CARBON
13180 SetPort (GetWindowPort (mwp
->mWP
));
13182 SetPort (mwp
->mWP
);
13187 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
13188 ShowWindow (mwp
->mWP
);
13193 void make_mac_frame (struct frame
*f
)
13195 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
13196 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
13200 f
->output_data
.mac
->cursor_pixel
= 0;
13201 f
->output_data
.mac
->border_pixel
= 0x00ff00;
13202 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
13203 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
13205 f
->output_data
.mac
->desired_cursor
= FILLED_BOX_CURSOR
;
13207 f
->output_data
.mac
->fontset
= -1;
13208 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13209 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13210 f
->output_data
.mac
->left_pos
= 4;
13211 f
->output_data
.mac
->top_pos
= 4;
13212 f
->output_data
.mac
->border_width
= 0;
13213 f
->output_data
.mac
->explicit_parent
= 0;
13215 f
->output_data
.mac
->internal_border_width
= 0;
13217 f
->output_method
= output_mac
;
13226 void make_mac_terminal_frame (struct frame
*f
)
13230 XSETFRAME (frame
, f
);
13232 f
->output_method
= output_mac
;
13233 f
->output_data
.mac
= (struct mac_output
*)
13234 xmalloc (sizeof (struct mac_output
));
13235 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
13236 f
->output_data
.mac
->fontset
= -1;
13237 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
13238 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
13240 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
13245 make_mac_frame (f
);
13249 /* Need to be initialized for unshow_buffer in window.c. */
13250 selected_window
= f
->selected_window
;
13252 Fmodify_frame_parameters (frame
,
13253 Fcons (Fcons (Qfont
,
13254 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
13255 Fmodify_frame_parameters (frame
,
13256 Fcons (Fcons (Qforeground_color
,
13257 build_string ("black")), Qnil
));
13258 Fmodify_frame_parameters (frame
,
13259 Fcons (Fcons (Qbackground_color
,
13260 build_string ("white")), Qnil
));
13264 /***********************************************************************
13266 ***********************************************************************/
13268 #ifdef USE_X_TOOLKIT
13269 static XrmOptionDescRec emacs_options
[] = {
13270 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
13271 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
13273 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
13274 XrmoptionSepArg
, NULL
},
13275 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
13277 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13278 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13279 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
13280 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13281 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
13282 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
13283 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
13285 #endif /* USE_X_TOOLKIT */
13287 #ifdef MULTI_KBOARD
13288 /* Test whether two display-name strings agree up to the dot that separates
13289 the screen number from the server number. */
13291 same_x_server (name1
, name2
)
13292 char *name1
, *name2
;
13294 int seen_colon
= 0;
13295 unsigned char *system_name
= SDATA (Vsystem_name
);
13296 int system_name_length
= strlen (system_name
);
13297 int length_until_period
= 0;
13299 while (system_name
[length_until_period
] != 0
13300 && system_name
[length_until_period
] != '.')
13301 length_until_period
++;
13303 /* Treat `unix' like an empty host name. */
13304 if (! strncmp (name1
, "unix:", 5))
13306 if (! strncmp (name2
, "unix:", 5))
13308 /* Treat this host's name like an empty host name. */
13309 if (! strncmp (name1
, system_name
, system_name_length
)
13310 && name1
[system_name_length
] == ':')
13311 name1
+= system_name_length
;
13312 if (! strncmp (name2
, system_name
, system_name_length
)
13313 && name2
[system_name_length
] == ':')
13314 name2
+= system_name_length
;
13315 /* Treat this host's domainless name like an empty host name. */
13316 if (! strncmp (name1
, system_name
, length_until_period
)
13317 && name1
[length_until_period
] == ':')
13318 name1
+= length_until_period
;
13319 if (! strncmp (name2
, system_name
, length_until_period
)
13320 && name2
[length_until_period
] == ':')
13321 name2
+= length_until_period
;
13323 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
13327 if (seen_colon
&& *name1
== '.')
13331 && (*name1
== '.' || *name1
== '\0')
13332 && (*name2
== '.' || *name2
== '\0'));
13336 int mac_initialized
= 0;
13339 mac_initialize_display_info ()
13341 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
13342 GDHandle main_device_handle
;
13344 bzero (dpyinfo
, sizeof (*dpyinfo
));
13346 /* Put it on x_display_name_list. */
13347 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
13348 x_display_name_list
);
13349 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
13352 dpyinfo
->mac_id_name
13353 = (char *) xmalloc (SCHARS (Vinvocation_name
)
13354 + SCHARS (Vsystem_name
)
13356 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
13357 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
13359 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
13360 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
13363 main_device_handle
= LMGetMainDevice();
13365 dpyinfo
->reference_count
= 0;
13366 dpyinfo
->resx
= 75.0;
13367 dpyinfo
->resy
= 75.0;
13368 dpyinfo
->n_planes
= 1;
13369 dpyinfo
->n_cbits
= 16;
13370 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13371 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13372 dpyinfo
->grabbed
= 0;
13373 dpyinfo
->root_window
= NULL
;
13375 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
13376 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
13377 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
13378 dpyinfo
->mouse_face_window
= Qnil
;
13381 struct mac_display_info
*
13382 mac_term_init (display_name
, xrm_option
, resource_name
)
13383 Lisp_Object display_name
;
13385 char *resource_name
;
13387 struct mac_display_info
*dpyinfo
;
13388 GDHandle main_device_handle
;
13390 if (!mac_initialized
)
13393 mac_initialized
= 1;
13396 mac_initialize_display_info (display_name
);
13398 dpyinfo
= &one_mac_display_info
;
13400 main_device_handle
= LMGetMainDevice();
13402 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13403 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13408 /* Set up use of X before we make the first connection. */
13410 static struct redisplay_interface x_redisplay_interface
=
13415 x_clear_end_of_line
,
13417 x_after_update_window_line
,
13418 x_update_window_begin
,
13419 x_update_window_end
,
13422 x_clear_mouse_face
,
13423 x_get_glyph_overhangs
,
13424 x_fix_overlapping_area
13430 rif
= &x_redisplay_interface
;
13432 clear_frame_hook
= x_clear_frame
;
13433 ins_del_lines_hook
= x_ins_del_lines
;
13434 delete_glyphs_hook
= x_delete_glyphs
;
13435 ring_bell_hook
= XTring_bell
;
13436 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13437 set_terminal_modes_hook
= XTset_terminal_modes
;
13438 update_begin_hook
= x_update_begin
;
13439 update_end_hook
= x_update_end
;
13440 set_terminal_window_hook
= XTset_terminal_window
;
13441 read_socket_hook
= XTread_socket
;
13442 frame_up_to_date_hook
= XTframe_up_to_date
;
13443 mouse_position_hook
= XTmouse_position
;
13444 frame_rehighlight_hook
= XTframe_rehighlight
;
13445 frame_raise_lower_hook
= XTframe_raise_lower
;
13447 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13448 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13449 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13450 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13452 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13454 scroll_region_ok
= 1; /* we'll scroll partial frames */
13455 char_ins_del_ok
= 1;
13456 line_ins_del_ok
= 1; /* we'll just blt 'em */
13457 fast_clear_end_of_line
= 1; /* X does this well */
13458 memory_below_frame
= 0; /* we don't remember what scrolls
13463 last_tool_bar_item
= -1;
13464 any_help_event_p
= 0;
13466 /* Try to use interrupt input; if we can't, then start polling. */
13467 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13469 #ifdef USE_X_TOOLKIT
13470 XtToolkitInitialize ();
13471 Xt_app_con
= XtCreateApplicationContext ();
13472 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13474 /* Install an asynchronous timer that processes Xt timeout events
13475 every 0.1s. This is necessary because some widget sets use
13476 timeouts internally, for example the LessTif menu bar, or the
13477 Xaw3d scroll bar. When Xt timouts aren't processed, these
13478 widgets don't behave normally. */
13480 EMACS_TIME interval
;
13481 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13482 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13486 #if USE_TOOLKIT_SCROLL_BARS
13487 xaw3d_arrow_scroll
= False
;
13488 xaw3d_pick_top
= True
;
13492 /* Note that there is no real way portable across R3/R4 to get the
13493 original error handler. */
13494 XSetErrorHandler (x_error_handler
);
13495 XSetIOErrorHandler (x_io_error_quitter
);
13497 /* Disable Window Change signals; they are handled by X events. */
13499 signal (SIGWINCH
, SIG_DFL
);
13500 #endif /* ! defined (SIGWINCH) */
13502 signal (SIGPIPE
, x_connection_signal
);
13505 mac_initialize_display_info ();
13507 #if TARGET_API_MAC_CARBON
13508 init_required_apple_events ();
13510 init_mac_drag_n_drop ();
13512 #if USE_CARBON_EVENTS
13513 init_service_handler ();
13516 DisableMenuCommand (NULL
, kHICommandQuit
);
13525 staticpro (&x_error_message_string
);
13526 x_error_message_string
= Qnil
;
13529 staticpro (&x_display_name_list
);
13530 x_display_name_list
= Qnil
;
13532 staticpro (&last_mouse_scroll_bar
);
13533 last_mouse_scroll_bar
= Qnil
;
13535 staticpro (&Qvendor_specific_keysyms
);
13536 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13538 staticpro (&last_mouse_press_frame
);
13539 last_mouse_press_frame
= Qnil
;
13541 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13542 staticpro (&Qmac_ready_for_drag_n_drop
);
13545 staticpro (&help_echo
);
13546 help_echo_object
= Qnil
;
13547 staticpro (&help_echo_object
);
13548 help_echo_window
= Qnil
;
13549 staticpro (&help_echo_window
);
13550 previous_help_echo
= Qnil
;
13551 staticpro (&previous_help_echo
);
13552 help_echo_pos
= -1;
13554 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13555 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13556 x_autoselect_window_p
= 0;
13558 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13559 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13560 For example, if a block cursor is over a tab, it will be drawn as
13561 wide as that tab on the display. */);
13562 x_stretch_cursor_p
= 0;
13564 #if 0 /* TODO: Setting underline position from font properties. */
13565 DEFVAR_BOOL ("x-use-underline-position-properties",
13566 &x_use_underline_position_properties
,
13567 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13568 nil means ignore them. If you encounter fonts with bogus
13569 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13570 to 4.1, set this to nil. */);
13571 x_use_underline_position_properties
= 1;
13574 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13575 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13576 Vx_toolkit_scroll_bars
= Qt
;
13578 staticpro (&last_mouse_motion_frame
);
13579 last_mouse_motion_frame
= Qnil
;
13581 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13582 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13583 Otherwise the option key is used. */);
13584 Vmac_command_key_is_meta
= Qt
;
13586 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
13587 doc
: /* Non-nil means that the control and meta keys are reversed. This is
13588 useful for non-standard keyboard layouts. */);
13589 Vmac_reverse_ctrl_meta
= Qnil
;
13591 #if USE_CARBON_EVENTS
13592 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
13593 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
13594 the right click will be mouse-3.
13595 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
13596 Vmac_wheel_button_is_mouse_2
= Qt
;
13599 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13600 doc
: /* One of the Text Encoding Base constant values defined in the
13601 Basic Text Constants section of Inside Macintosh - Text Encoding
13602 Conversion Manager. Its value determines the encoding characters
13603 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13604 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13605 its default value, no conversion takes place. If it is set to
13606 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13607 characters typed on Mac keyboard are first converted into the
13608 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13609 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13610 command, this enables the Mac keyboard to be used to enter non-ASCII
13611 characters directly. */);
13612 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;