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. */
47 #include <Carbon/Carbon.h>
49 #define free unexec_free
51 #define malloc unexec_malloc
53 #define realloc unexec_realloc
55 #define min(a, b) ((a) < (b) ? (a) : (b))
57 #define max(a, b) ((a) > (b) ? (a) : (b))
58 #else /* not MAC_OSX */
59 #include <Quickdraw.h>
60 #include <ToolUtils.h>
64 #include <Resources.h>
66 #include <TextUtils.h>
69 #if defined (__MRC__) || (__MSL__ >= 0x6000)
70 #include <ControlDefinitions.h>
77 #endif /* not MAC_OSX */
91 #include "dispextern.h"
93 #include "termhooks.h"
100 #include "intervals.h"
101 #include "composite.h"
104 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
107 /* Fringe bitmaps. */
109 enum fringe_bitmap_type
112 LEFT_TRUNCATION_BITMAP
,
113 RIGHT_TRUNCATION_BITMAP
,
114 OVERLAY_ARROW_BITMAP
,
115 CONTINUED_LINE_BITMAP
,
116 CONTINUATION_LINE_BITMAP
,
120 /* Bitmap drawn to indicate lines not displaying text if
121 `indicate-empty-lines' is non-nil. */
126 static unsigned char zv_bits
[] = {
127 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
128 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
129 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
130 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
131 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
132 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
133 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
134 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
136 /* An arrow like this: `<-'. */
139 #define left_height 8
140 static unsigned char left_bits
[] = {
141 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
143 /* Right truncation arrow bitmap `->'. */
145 #define right_width 8
146 #define right_height 8
147 static unsigned char right_bits
[] = {
148 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
150 /* Marker for continued lines. */
152 #define continued_width 8
153 #define continued_height 8
154 static unsigned char continued_bits
[] = {
155 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
157 /* Marker for continuation lines. */
159 #define continuation_width 8
160 #define continuation_height 8
161 static unsigned char continuation_bits
[] = {
162 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
164 /* Overlay arrow bitmap. */
170 static unsigned char ov_bits
[] = {
171 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
173 /* A triangular arrow. */
176 static unsigned char ov_bits
[] = {
177 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
180 extern Lisp_Object Qhelp_echo
;
183 /* Non-nil means Emacs uses toolkit scroll bars. */
185 Lisp_Object Vx_toolkit_scroll_bars
;
187 /* If a string, XTread_socket generates an event to display that string.
188 (The display is done in read_char.) */
190 static Lisp_Object help_echo
;
191 static Lisp_Object help_echo_window
;
192 static Lisp_Object help_echo_object
;
193 static int help_echo_pos
;
195 /* Temporary variable for XTread_socket. */
197 static Lisp_Object previous_help_echo
;
199 /* Non-zero means that a HELP_EVENT has been generated since Emacs
202 static int any_help_event_p
;
204 /* Non-zero means autoselect window with the mouse cursor. */
206 int x_autoselect_window_p
;
208 /* Non-zero means draw block and hollow cursor as wide as the glyph
209 under it. For example, if a block cursor is over a tab, it will be
210 drawn as wide as that tab on the display. */
212 int x_stretch_cursor_p
;
214 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
216 int x_use_underline_position_properties
;
218 /* This is a chain of structures for all the X displays currently in
221 struct x_display_info
*x_display_list
;
223 /* This is a list of cons cells, each of the form (NAME
224 . FONT-LIST-CACHE), one for each element of x_display_list and in
225 the same order. NAME is the name of the frame. FONT-LIST-CACHE
226 records previous values returned by x-list-fonts. */
228 Lisp_Object x_display_name_list
;
230 /* This is display since Mac does not support multiple ones. */
231 struct mac_display_info one_mac_display_info
;
233 /* Frame being updated by update_frame. This is declared in term.c.
234 This is set by update_begin and looked at by all the XT functions.
235 It is zero while not inside an update. In that case, the XT
236 functions assume that `selected_frame' is the frame to apply to. */
238 extern struct frame
*updating_frame
;
240 extern int waiting_for_input
;
242 /* This is a frame waiting to be auto-raised, within XTread_socket. */
244 struct frame
*pending_autoraise_frame
;
246 /* Nominal cursor position -- where to draw output.
247 HPOS and VPOS are window relative glyph matrix coordinates.
248 X and Y are window relative pixel coordinates. */
250 struct cursor_pos output_cursor
;
252 /* Non-zero means user is interacting with a toolkit scroll bar. */
254 static int toolkit_scroll_bar_interaction
;
258 Formerly, we used PointerMotionHintMask (in standard_event_mask)
259 so that we would have to call XQueryPointer after each MotionNotify
260 event to ask for another such event. However, this made mouse tracking
261 slow, and there was a bug that made it eventually stop.
263 Simply asking for MotionNotify all the time seems to work better.
265 In order to avoid asking for motion events and then throwing most
266 of them away or busy-polling the server for mouse positions, we ask
267 the server for pointer motion hints. This means that we get only
268 one event per group of mouse movements. "Groups" are delimited by
269 other kinds of events (focus changes and button clicks, for
270 example), or by XQueryPointer calls; when one of these happens, we
271 get another MotionNotify event the next time the mouse moves. This
272 is at least as efficient as getting motion events when mouse
273 tracking is on, and I suspect only negligibly worse when tracking
276 /* Where the mouse was last time we reported a mouse event. */
278 FRAME_PTR last_mouse_frame
;
279 static Rect last_mouse_glyph
;
280 static Lisp_Object last_mouse_press_frame
;
282 /* The scroll bar in which the last X motion event occurred.
284 If the last X motion event occurred in a scroll bar, we set this so
285 XTmouse_position can know whether to report a scroll bar motion or
288 If the last X motion event didn't occur in a scroll bar, we set
289 this to Qnil, to tell XTmouse_position to return an ordinary motion
292 static Lisp_Object last_mouse_scroll_bar
;
294 /* This is a hack. We would really prefer that XTmouse_position would
295 return the time associated with the position it returns, but there
296 doesn't seem to be any way to wrest the time-stamp from the server
297 along with the position query. So, we just keep track of the time
298 of the last movement we received, and return that in hopes that
299 it's somewhat accurate. */
301 static Time last_mouse_movement_time
;
303 enum mouse_tracking_type
{
305 mouse_tracking_mouse_movement
,
306 mouse_tracking_scroll_bar
309 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
311 struct scroll_bar
*tracked_scroll_bar
= NULL
;
313 /* Incremented by XTread_socket whenever it really tries to read
317 static int volatile input_signal_count
;
319 static int input_signal_count
;
322 /* Used locally within XTread_socket. */
324 static int x_noop_count
;
326 /* Initial values of argv and argc. */
328 extern char **initial_argv
;
329 extern int initial_argc
;
331 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
333 /* Tells if a window manager is present or not. */
335 extern Lisp_Object Vx_no_window_manager
;
337 extern Lisp_Object Qface
, Qmouse_face
;
341 /* A mask of extra modifier bits to put into every keyboard char. */
343 extern int extra_keyboard_modifiers
;
345 static Lisp_Object Qvendor_specific_keysyms
;
348 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
351 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
355 QDGlobals qd
; /* QuickDraw global information structure. */
359 /* Enumeration for overriding/changing the face to use for drawing
360 glyphs in x_draw_glyphs. */
362 enum draw_glyphs_face
372 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
373 struct mac_display_info
*mac_display_info_for_display (Display
*);
374 static void x_update_window_end
P_ ((struct window
*, int, int));
375 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
376 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
377 int *, int *, Lisp_Object
));
378 static int fast_find_string_pos
P_ ((struct window
*, int, Lisp_Object
,
379 int *, int *, int *, int *, int));
380 static void set_output_cursor
P_ ((struct cursor_pos
*));
381 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
382 int *, int *, int *, int));
383 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
384 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
385 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
386 static void x_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
387 static void show_mouse_face
P_ ((struct x_display_info
*,
388 enum draw_glyphs_face
));
389 static int cursor_in_mouse_face_p
P_ ((struct window
*));
390 static int clear_mouse_face
P_ ((struct mac_display_info
*));
391 static int x_io_error_quitter
P_ ((Display
*));
392 int x_catch_errors
P_ ((Display
*));
393 void x_uncatch_errors
P_ ((Display
*, int));
394 void x_lower_frame
P_ ((struct frame
*));
395 void x_scroll_bar_clear
P_ ((struct frame
*));
396 int x_had_errors_p
P_ ((Display
*));
397 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
398 void x_raise_frame
P_ ((struct frame
*));
399 void x_set_window_size
P_ ((struct frame
*, int, int, int));
400 void x_wm_set_window_state
P_ ((struct frame
*, int));
401 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
402 void mac_initialize
P_ ((void));
403 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
404 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
405 enum text_cursor_kinds x_specified_cursor_type
P_ ((Lisp_Object
, int *));
406 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
408 enum draw_glyphs_face
));
409 static void x_update_end
P_ ((struct frame
*));
410 static void XTframe_up_to_date
P_ ((struct frame
*));
411 static void XTreassert_line_highlight
P_ ((int, int));
412 static void x_change_line_highlight
P_ ((int, int, int, int));
413 static void XTset_terminal_modes
P_ ((void));
414 static void XTreset_terminal_modes
P_ ((void));
415 static void XTcursor_to
P_ ((int, int, int, int));
416 static void x_write_glyphs
P_ ((struct glyph
*, int));
417 static void x_clear_end_of_line
P_ ((int));
418 static void x_clear_frame
P_ ((void));
419 static void x_clear_cursor
P_ ((struct window
*));
420 static void frame_highlight
P_ ((struct frame
*));
421 static void frame_unhighlight
P_ ((struct frame
*));
422 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
423 static void XTframe_rehighlight
P_ ((struct frame
*));
424 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
425 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
426 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
427 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
428 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
429 static int expose_window_tree
P_ ((struct window
*, Rect
*));
430 static int expose_window
P_ ((struct window
*, Rect
*));
431 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
432 Rect
*, enum glyph_row_area
));
433 static int expose_line
P_ ((struct window
*, struct glyph_row
*,
435 void x_display_cursor (struct window
*, int, int, int, int, int);
436 void x_update_cursor
P_ ((struct frame
*, int));
437 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
438 static void x_update_window_cursor
P_ ((struct window
*, int));
439 static void x_erase_phys_cursor
P_ ((struct window
*));
440 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
441 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
442 enum fringe_bitmap_type
, int left_p
));
443 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
445 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
446 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
447 static void notice_overwritten_cursor
P_ ((struct window
*,
449 int, int, int, int));
450 static void x_flush
P_ ((struct frame
*f
));
451 static void x_update_begin
P_ ((struct frame
*));
452 static void x_update_window_begin
P_ ((struct window
*));
453 static void x_draw_vertical_border
P_ ((struct window
*));
454 static void x_after_update_window_line
P_ ((struct glyph_row
*));
455 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
456 static void x_produce_stretch_glyph
P_ ((struct it
*));
458 static void activate_scroll_bars (FRAME_PTR
);
459 static void deactivate_scroll_bars (FRAME_PTR
);
461 extern int image_ascent (struct image
*, struct face
*);
462 void x_set_offset (struct frame
*, int, int, int);
463 int x_bitmap_icon (struct frame
*, Lisp_Object
);
464 void x_make_frame_visible (struct frame
*);
466 extern void window_scroll (Lisp_Object
, int, int, int);
468 /* Defined in macmenu.h. */
469 extern void menubar_selection_callback (FRAME_PTR
, int);
470 extern void set_frame_menubar (FRAME_PTR
, int, int);
472 /* X display function emulation */
474 /* Structure borrowed from Xlib.h to represent two-byte characters in
483 XFreePixmap (display
, pixmap
)
487 PixMap
*p
= (PixMap
*) pixmap
;
494 /* Set foreground color for subsequent QuickDraw commands. Assume
495 graphic port has already been set. */
498 mac_set_forecolor (unsigned long color
)
502 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
503 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
504 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
506 RGBForeColor (&fg_color
);
510 /* Set background color for subsequent QuickDraw commands. Assume
511 graphic port has already been set. */
514 mac_set_backcolor (unsigned long color
)
518 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
519 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
520 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
522 RGBBackColor (&bg_color
);
525 /* Set foreground and background color for subsequent QuickDraw
526 commands. Assume that the graphic port has already been set. */
529 mac_set_colors (GC gc
)
531 mac_set_forecolor (gc
->foreground
);
532 mac_set_backcolor (gc
->background
);
535 /* Mac version of XDrawLine. */
538 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
544 #if TARGET_API_MAC_CARBON
545 SetPort (GetWindowPort (w
));
556 /* Mac version of XClearArea. */
559 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
563 unsigned int width
, height
;
566 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
570 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
571 xgc
.background
= mwp
->x_compatible
.background_pixel
;
573 #if TARGET_API_MAC_CARBON
574 SetPort (GetWindowPort (w
));
579 mac_set_colors (&xgc
);
580 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
585 /* Mac version of XClearWindow. */
588 XClearWindow (display
, w
)
592 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
595 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
596 xgc
.background
= mwp
->x_compatible
.background_pixel
;
598 #if TARGET_API_MAC_CARBON
599 SetPort (GetWindowPort (w
));
604 mac_set_colors (&xgc
);
606 #if TARGET_API_MAC_CARBON
610 GetWindowPortBounds (w
, &r
);
613 #else /* not TARGET_API_MAC_CARBON */
614 EraseRect (&(w
->portRect
));
615 #endif /* not TARGET_API_MAC_CARBON */
619 /* Mac replacement for XCopyArea. */
622 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
631 #if TARGET_API_MAC_CARBON
632 SetPort (GetWindowPort (w
));
638 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
640 #if TARGET_API_MAC_CARBON
644 LockPortBits (GetWindowPort (w
));
645 pmh
= GetPortPixMap (GetWindowPort (w
));
646 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
647 UnlockPortBits (GetWindowPort (w
));
649 #else /* not TARGET_API_MAC_CARBON */
650 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
651 #endif /* not TARGET_API_MAC_CARBON */
655 /* Mac replacement for XSetClipRectangles. */
658 mac_set_clip_rectangle (display
, w
, r
)
663 #if TARGET_API_MAC_CARBON
664 SetPort (GetWindowPort (w
));
673 /* Mac replacement for XSetClipMask. */
676 mac_reset_clipping (display
, w
)
682 #if TARGET_API_MAC_CARBON
683 SetPort (GetWindowPort (w
));
688 SetRect (&r
, -32767, -32767, 32767, 32767);
693 /* Mac replacement for XCreateBitmapFromBitmapData. */
696 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
701 int bytes_per_row
, i
, j
;
703 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
704 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
705 if (!bitmap
->baseAddr
)
708 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
709 for (i
= 0; i
< h
; i
++)
710 for (j
= 0; j
< w
; j
++)
711 if (BitTst (bits
, i
* w
+ j
))
712 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
714 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
719 mac_free_bitmap (bitmap
)
722 xfree (bitmap
->baseAddr
);
725 /* Mac replacement for XFillRectangle. */
728 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
733 unsigned int width
, height
;
737 #if TARGET_API_MAC_CARBON
738 SetPort (GetWindowPort (w
));
744 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
746 PaintRect (&r
); /* using foreground color of gc */
750 /* Mac replacement for XDrawRectangle: dest is a window. */
753 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
758 unsigned int width
, height
;
762 #if TARGET_API_MAC_CARBON
763 SetPort (GetWindowPort (w
));
769 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
771 FrameRect (&r
); /* using foreground color of gc */
775 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
778 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
783 unsigned int width
, height
;
785 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
788 #if TARGET_API_MAC_CARBON
789 SetPort (GetWindowPort (w
));
795 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
797 FrameRect (&r
); /* using foreground color of gc */
803 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
810 int nchars
, mode
, bytes_per_char
;
812 #if TARGET_API_MAC_CARBON
813 SetPort (GetWindowPort (w
));
820 TextFont (gc
->font
->mac_fontnum
);
821 TextSize (gc
->font
->mac_fontsize
);
822 TextFace (gc
->font
->mac_fontface
);
826 DrawText (buf
, 0, nchars
* bytes_per_char
);
830 /* Mac replacement for XDrawString. */
833 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
841 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
845 /* Mac replacement for XDrawString16. */
848 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
856 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
861 /* Mac replacement for XDrawImageString. */
864 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
872 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
876 /* Mac replacement for XDrawString16. */
879 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
887 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
892 /* Mac replacement for XCopyArea: dest must be window. */
895 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
902 unsigned int width
, height
;
907 #if TARGET_API_MAC_CARBON
908 SetPort (GetWindowPort (dest
));
915 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
916 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
918 #if TARGET_API_MAC_CARBON
922 LockPortBits (GetWindowPort (dest
));
923 pmh
= GetPortPixMap (GetWindowPort (dest
));
924 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
925 UnlockPortBits (GetWindowPort (dest
));
927 #else /* not TARGET_API_MAC_CARBON */
928 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
929 #endif /* not TARGET_API_MAC_CARBON */
934 /* Convert a pair of local coordinates to global (screen) coordinates.
935 Assume graphic port has been properly set. */
937 local_to_global_coord (short *h
, short *v
)
951 /* Mac replacement for XCopyArea: used only for scrolling. */
954 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
959 unsigned int width
, height
;
962 #if TARGET_API_MAC_CARBON
963 Rect gw_r
, src_r
, dest_r
;
966 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
967 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
969 SetPort (GetWindowPort (w
));
972 LockPortBits (GetWindowPort (w
));
973 pmh
= GetPortPixMap (GetWindowPort (w
));
974 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
975 UnlockPortBits (GetWindowPort (w
));
976 #else /* not TARGET_API_MAC_CARBON */
984 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
985 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
988 /* Need to use global coordinates and screenBits since src and dest
989 areas overlap in general. */
990 local_to_global_coord (&src_r
.left
, &src_r
.top
);
991 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
992 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
993 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
995 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
997 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
998 color mapping in CopyBits. Otherwise, it will be slow. */
999 ForeColor (blackColor
);
1000 BackColor (whiteColor
);
1001 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1003 mac_set_colors (gc
);
1005 #endif /* not TARGET_API_MAC_CARBON */
1009 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1012 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1019 unsigned int width
, height
;
1023 int src_right
= ((PixMap
*) src
)->bounds
.right
;
1024 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
1025 int w
= src_right
- src_x
;
1026 int h
= src_bottom
- src_y
;
1028 mac_set_colors (gc
);
1030 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
1031 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
1033 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
1037 /* Mac replacement for XChangeGC. */
1040 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1043 if (mask
& GCForeground
)
1044 gc
->foreground
= xgcv
->foreground
;
1045 if (mask
& GCBackground
)
1046 gc
->background
= xgcv
->background
;
1048 gc
->font
= xgcv
->font
;
1052 /* Mac replacement for XCreateGC. */
1055 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1058 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1059 bzero (gc
, sizeof (XGCValues
));
1061 XChangeGC (ignore
, gc
, mask
, xgcv
);
1067 /* Used in xfaces.c. */
1070 XFreeGC (display
, gc
)
1078 /* Mac replacement for XGetGCValues. */
1081 XGetGCValues (void* ignore
, XGCValues
*gc
,
1082 unsigned long mask
, XGCValues
*xgcv
)
1084 XChangeGC (ignore
, xgcv
, mask
, gc
);
1088 /* Mac replacement for XSetForeground. */
1091 XSetForeground (display
, gc
, color
)
1094 unsigned long color
;
1096 gc
->foreground
= color
;
1100 /* Mac replacement for XSetFont. */
1103 XSetFont (display
, gc
, font
)
1113 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1114 int *direction
,int *font_ascent
,
1115 int *font_descent
, XCharStruct
*cs
)
1117 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1121 /* x_sync is a no-op on Mac. */
1129 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1130 Calls to XFlush should be unnecessary because the X output buffer
1131 is flushed automatically as needed by calls to XPending,
1132 XNextEvent, or XWindowEvent according to the XFlush man page.
1133 XTread_socket calls XPending. Removing XFlush improves
1136 #if TARGET_API_MAC_CARBON
1137 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1139 #define XFlush(DISPLAY) (void) 0
1142 /* Flush display of frame F, or of all frames if F is null. */
1148 #if TARGET_API_MAC_CARBON
1152 Lisp_Object rest
, frame
;
1153 FOR_EACH_FRAME (rest
, frame
)
1154 x_flush (XFRAME (frame
));
1156 else if (FRAME_X_P (f
))
1157 XFlush (FRAME_MAC_DISPLAY (f
));
1159 #endif /* TARGET_API_MAC_CARBON */
1164 /* Return the struct mac_display_info corresponding to DPY. There's
1167 struct mac_display_info
*
1168 mac_display_info_for_display (dpy
)
1171 return &one_mac_display_info
;
1176 /***********************************************************************
1177 Starting and ending an update
1178 ***********************************************************************/
1180 /* Start an update of frame F. This function is installed as a hook
1181 for update_begin, i.e. it is called when update_begin is called.
1182 This function is called prior to calls to x_update_window_begin for
1183 each window being updated. */
1189 /* Nothing to do. */
1193 /* Start update of window W. Set the global variable updated_window
1194 to the window being updated and set output_cursor to the cursor
1198 x_update_window_begin (w
)
1201 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1202 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1205 set_output_cursor (&w
->cursor
);
1209 if (f
== display_info
->mouse_face_mouse_frame
)
1211 /* Don't do highlighting for mouse motion during the update. */
1212 display_info
->mouse_face_defer
= 1;
1214 /* If F needs to be redrawn, simply forget about any prior mouse
1216 if (FRAME_GARBAGED_P (f
))
1217 display_info
->mouse_face_window
= Qnil
;
1219 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1220 their mouse_face_p flag set, which means that they are always
1221 unequal to rows in a desired matrix which never have that
1222 flag set. So, rows containing mouse-face glyphs are never
1223 scrolled, and we don't have to switch the mouse highlight off
1224 here to prevent it from being scrolled. */
1226 /* Can we tell that this update does not affect the window
1227 where the mouse highlight is? If so, no need to turn off.
1228 Likewise, don't do anything if the frame is garbaged;
1229 in that case, the frame's current matrix that we would use
1230 is all wrong, and we will redisplay that line anyway. */
1231 if (!NILP (display_info
->mouse_face_window
)
1232 && w
== XWINDOW (display_info
->mouse_face_window
))
1236 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1237 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1240 if (i
< w
->desired_matrix
->nrows
)
1241 clear_mouse_face (display_info
);
1250 /* Draw a vertical window border to the right of window W if W doesn't
1251 have vertical scroll bars. */
1254 x_draw_vertical_border (w
)
1257 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1259 /* Redraw borders between horizontally adjacent windows. Don't
1260 do it for frames with vertical scroll bars because either the
1261 right scroll bar of a window, or the left scroll bar of its
1262 neighbor will suffice as a border. */
1263 if (!WINDOW_RIGHTMOST_P (w
)
1264 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1268 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1269 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1272 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1273 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1278 /* End update of window W (which is equal to updated_window).
1280 Draw vertical borders between horizontally adjacent windows, and
1281 display W's cursor if CURSOR_ON_P is non-zero.
1283 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1284 glyphs in mouse-face were overwritten. In that case we have to
1285 make sure that the mouse-highlight is properly redrawn.
1287 W may be a menu bar pseudo-window in case we don't have X toolkit
1288 support. Such windows don't have a cursor, so don't display it
1292 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1294 int cursor_on_p
, mouse_face_overwritten_p
;
1296 struct mac_display_info
*dpyinfo
1297 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1299 if (!w
->pseudo_window_p
)
1304 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1306 output_cursor
.x
, output_cursor
.y
);
1308 x_draw_vertical_border (w
);
1312 /* If a row with mouse-face was overwritten, arrange for
1313 XTframe_up_to_date to redisplay the mouse highlight. */
1314 if (mouse_face_overwritten_p
)
1316 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1317 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1318 dpyinfo
->mouse_face_window
= Qnil
;
1322 /* Unhide the caret. This won't actually show the cursor, unless it
1323 was visible before the corresponding call to HideCaret in
1324 x_update_window_begin. */
1325 if (w32_use_visible_system_caret
)
1326 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1329 updated_window
= NULL
;
1333 /* End update of frame F. This function is installed as a hook in
1340 /* Reset the background color of Mac OS Window to that of the frame after
1341 update so that it is used by Mac Toolbox to clear the update region before
1342 an update event is generated. */
1343 #if TARGET_API_MAC_CARBON
1344 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1346 SetPort (FRAME_MAC_WINDOW (f
));
1349 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1351 /* Mouse highlight may be displayed again. */
1352 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1355 XFlush (FRAME_MAC_DISPLAY (f
));
1360 /* This function is called from various places in xdisp.c whenever a
1361 complete update has been performed. The global variable
1362 updated_window is not available here. */
1365 XTframe_up_to_date (f
)
1370 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1372 if (dpyinfo
->mouse_face_deferred_gc
1373 || f
== dpyinfo
->mouse_face_mouse_frame
)
1376 if (dpyinfo
->mouse_face_mouse_frame
)
1377 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1378 dpyinfo
->mouse_face_mouse_x
,
1379 dpyinfo
->mouse_face_mouse_y
);
1380 dpyinfo
->mouse_face_deferred_gc
= 0;
1387 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1388 arrow bitmaps, or clear the fringes if no bitmaps are required
1389 before DESIRED_ROW is made current. The window being updated is
1390 found in updated_window. This function is called from
1391 update_window_line only if it is known that there are differences
1392 between bitmaps to be drawn between current row and DESIRED_ROW. */
1395 x_after_update_window_line (desired_row
)
1396 struct glyph_row
*desired_row
;
1398 struct window
*w
= updated_window
;
1404 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1407 x_draw_row_fringe_bitmaps (w
, desired_row
);
1411 /* When a window has disappeared, make sure that no rest of
1412 full-width rows stays visible in the internal border. Could
1413 check here if updated_window is the leftmost/rightmost window,
1414 but I guess it's not worth doing since vertically split windows
1415 are almost never used, internal border is rarely set, and the
1416 overhead is very small. */
1417 if (windows_or_buffers_changed
1418 && desired_row
->full_width_p
1419 && (f
= XFRAME (w
->frame
),
1420 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1422 && (height
= desired_row
->visible_height
,
1425 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1426 /* Internal border is drawn below the tool bar. */
1427 if (WINDOWP (f
->tool_bar_window
)
1428 && w
== XWINDOW (f
->tool_bar_window
))
1433 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1434 0, y
, width
, height
, 0);
1435 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1436 f
->output_data
.mac
->pixel_width
- width
, y
,
1444 /* Draw the bitmap WHICH in one of the left or right fringes of
1445 window W. ROW is the glyph row for which to display the bitmap; it
1446 determines the vertical position at which the bitmap has to be
1450 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1452 struct glyph_row
*row
;
1453 enum fringe_bitmap_type which
;
1456 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1457 Display
*display
= FRAME_MAC_DISPLAY (f
);
1458 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1459 int x
, y
, wd
, h
, dy
;
1461 unsigned char *bits
;
1464 GC gc
= f
->output_data
.mac
->normal_gc
;
1467 /* Must clip because of partially visible lines. */
1468 x_clip_to_row (w
, row
, gc
, 1);
1470 /* Convert row to frame coordinates. */
1471 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1475 case NO_FRINGE_BITMAP
:
1480 case LEFT_TRUNCATION_BITMAP
:
1486 case OVERLAY_ARROW_BITMAP
:
1492 case RIGHT_TRUNCATION_BITMAP
:
1498 case CONTINUED_LINE_BITMAP
:
1499 wd
= continued_width
;
1500 h
= continued_height
;
1501 bits
= continued_bits
;
1504 case CONTINUATION_LINE_BITMAP
:
1505 wd
= continuation_width
;
1506 h
= continuation_height
;
1507 bits
= continuation_bits
;
1510 case ZV_LINE_BITMAP
:
1512 h
= zv_height
- (y
% zv_period
);
1513 bits
= zv_bits
+ (y
% zv_period
);
1520 /* Clip bitmap if too high. */
1521 if (h
> row
->height
)
1524 /* Set dy to the offset in the row to start drawing the bitmap. */
1525 dy
= (row
->height
- h
) / 2;
1527 /* Draw the bitmap. */
1528 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1529 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1531 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1536 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1537 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1538 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1540 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1541 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1543 /* If W has a vertical border to its left, don't draw over it. */
1544 int border
= ((XFASTINT (w
->left
) > 0
1545 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1547 b1
= (window_box_left (w
, -1)
1548 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1550 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1555 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1556 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1557 x
= (window_box_right (w
, -1)
1558 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1559 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1561 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1563 b1
= window_box_right (w
, -1);
1564 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1570 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1572 gcv
.foreground
= face
->background
;
1574 #if 0 /* MAC_TODO: stipple */
1575 /* In case the same realized face is used for fringes and
1576 for something displayed in the text (e.g. face `region' on
1577 mono-displays, the fill style may have been changed to
1578 FillSolid in x_draw_glyph_string_background. */
1580 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1582 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1585 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1588 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1591 row
->visible_height
);
1593 #if 0 /* MAC_TODO: stipple */
1595 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1599 if (which
== NO_FRINGE_BITMAP
)
1601 mac_reset_clipping (display
, window
);
1605 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1606 gcv
.foreground
= face
->foreground
;
1607 gcv
.background
= face
->background
;
1609 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1611 mac_free_bitmap (&bitmap
);
1612 mac_reset_clipping (display
, window
);
1616 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1617 function with input blocked. */
1620 x_draw_row_fringe_bitmaps (w
, row
)
1622 struct glyph_row
*row
;
1624 struct frame
*f
= XFRAME (w
->frame
);
1625 enum fringe_bitmap_type bitmap
;
1627 xassert (interrupt_input_blocked
);
1629 /* If row is completely invisible, because of vscrolling, we
1630 don't have to draw anything. */
1631 if (row
->visible_height
<= 0)
1634 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1636 /* Decide which bitmap to draw in the left fringe. */
1637 if (row
->overlay_arrow_p
)
1638 bitmap
= OVERLAY_ARROW_BITMAP
;
1639 else if (row
->truncated_on_left_p
)
1640 bitmap
= LEFT_TRUNCATION_BITMAP
;
1641 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1642 bitmap
= CONTINUATION_LINE_BITMAP
;
1643 else if (row
->indicate_empty_line_p
)
1644 bitmap
= ZV_LINE_BITMAP
;
1646 bitmap
= NO_FRINGE_BITMAP
;
1648 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1651 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1653 /* Decide which bitmap to draw in the right fringe. */
1654 if (row
->truncated_on_right_p
)
1655 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1656 else if (row
->continued_p
)
1657 bitmap
= CONTINUED_LINE_BITMAP
;
1658 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1659 bitmap
= ZV_LINE_BITMAP
;
1661 bitmap
= NO_FRINGE_BITMAP
;
1663 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1668 /* This is called when starting Emacs and when restarting after
1669 suspend. When starting Emacs, no window is mapped. And nothing
1670 must be done to Emacs's own window if it is suspended (though that
1674 XTset_terminal_modes ()
1678 /* This is called when exiting or suspending Emacs. Exiting will make
1679 the windows go away, and suspending requires no action. */
1682 XTreset_terminal_modes ()
1688 /***********************************************************************
1690 ***********************************************************************/
1692 /* Set the global variable output_cursor to CURSOR. All cursor
1693 positions are relative to updated_window. */
1696 set_output_cursor (cursor
)
1697 struct cursor_pos
*cursor
;
1699 output_cursor
.hpos
= cursor
->hpos
;
1700 output_cursor
.vpos
= cursor
->vpos
;
1701 output_cursor
.x
= cursor
->x
;
1702 output_cursor
.y
= cursor
->y
;
1706 /* Set a nominal cursor position.
1708 HPOS and VPOS are column/row positions in a window glyph matrix. X
1709 and Y are window text area relative pixel positions.
1711 If this is done during an update, updated_window will contain the
1712 window that is being updated and the position is the future output
1713 cursor position for that window. If updated_window is null, use
1714 selected_window and display the cursor at the given position. */
1717 XTcursor_to (vpos
, hpos
, y
, x
)
1718 int vpos
, hpos
, y
, x
;
1722 /* If updated_window is not set, work on selected_window. */
1726 w
= XWINDOW (selected_window
);
1728 /* Set the output cursor. */
1729 output_cursor
.hpos
= hpos
;
1730 output_cursor
.vpos
= vpos
;
1731 output_cursor
.x
= x
;
1732 output_cursor
.y
= y
;
1734 /* If not called as part of an update, really display the cursor.
1735 This will also set the cursor position of W. */
1736 if (updated_window
== NULL
)
1739 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1740 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1747 /***********************************************************************
1749 ***********************************************************************/
1751 /* Function prototypes of this page. */
1753 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1757 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1758 int, XChar2b
*, int));
1759 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1760 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1761 static void x_append_glyph
P_ ((struct it
*));
1762 static void x_append_composite_glyph
P_ ((struct it
*));
1763 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1765 static void x_produce_glyphs
P_ ((struct it
*));
1766 static void x_produce_image_glyph
P_ ((struct it
*it
));
1769 /* Return a pointer to per-char metric information in FONT of a
1770 character pointed by B which is a pointer to an XChar2b. */
1772 #define PER_CHAR_METRIC(font, b) \
1774 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1775 + (((font)->min_byte1 || (font)->max_byte1) \
1776 ? (((b)->byte1 - (font)->min_byte1) \
1777 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1779 : &((font)->max_bounds))
1782 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1783 is not contained in the font. */
1785 static INLINE XCharStruct
*
1786 x_per_char_metric (font
, char2b
)
1790 /* The result metric information. */
1791 XCharStruct
*pcm
= NULL
;
1793 xassert (font
&& char2b
);
1795 if (font
->per_char
!= NULL
)
1797 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1799 /* min_char_or_byte2 specifies the linear character index
1800 corresponding to the first element of the per_char array,
1801 max_char_or_byte2 is the index of the last character. A
1802 character with non-zero CHAR2B->byte1 is not in the font.
1803 A character with byte2 less than min_char_or_byte2 or
1804 greater max_char_or_byte2 is not in the font. */
1805 if (char2b
->byte1
== 0
1806 && char2b
->byte2
>= font
->min_char_or_byte2
1807 && char2b
->byte2
<= font
->max_char_or_byte2
)
1808 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1812 /* If either min_byte1 or max_byte1 are nonzero, both
1813 min_char_or_byte2 and max_char_or_byte2 are less than
1814 256, and the 2-byte character index values corresponding
1815 to the per_char array element N (counting from 0) are:
1817 byte1 = N/D + min_byte1
1818 byte2 = N\D + min_char_or_byte2
1822 D = max_char_or_byte2 - min_char_or_byte2 + 1
1823 / = integer division
1824 \ = integer modulus */
1825 if (char2b
->byte1
>= font
->min_byte1
1826 && char2b
->byte1
<= font
->max_byte1
1827 && char2b
->byte2
>= font
->min_char_or_byte2
1828 && char2b
->byte2
<= font
->max_char_or_byte2
)
1830 pcm
= (font
->per_char
1831 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1832 * (char2b
->byte1
- font
->min_byte1
))
1833 + (char2b
->byte2
- font
->min_char_or_byte2
));
1839 /* If the per_char pointer is null, all glyphs between the first
1840 and last character indexes inclusive have the same
1841 information, as given by both min_bounds and max_bounds. */
1842 if (char2b
->byte2
>= font
->min_char_or_byte2
1843 && char2b
->byte2
<= font
->max_char_or_byte2
)
1844 pcm
= &font
->max_bounds
;
1847 return ((pcm
== NULL
1848 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1853 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1854 the two-byte form of C. Encoding is returned in *CHAR2B. */
1857 x_encode_char (c
, char2b
, font_info
)
1860 struct font_info
*font_info
;
1862 int charset
= CHAR_CHARSET (c
);
1863 XFontStruct
*font
= font_info
->font
;
1865 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1866 This may be either a program in a special encoder language or a
1868 if (font_info
->font_encoder
)
1870 /* It's a program. */
1871 struct ccl_program
*ccl
= font_info
->font_encoder
;
1873 if (CHARSET_DIMENSION (charset
) == 1)
1875 ccl
->reg
[0] = charset
;
1876 ccl
->reg
[1] = char2b
->byte2
;
1880 ccl
->reg
[0] = charset
;
1881 ccl
->reg
[1] = char2b
->byte1
;
1882 ccl
->reg
[2] = char2b
->byte2
;
1885 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1887 /* We assume that MSBs are appropriately set/reset by CCL
1889 if (font
->max_byte1
== 0) /* 1-byte font */
1890 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1892 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1894 else if (font_info
->encoding
[charset
])
1896 /* Fixed encoding scheme. See fontset.h for the meaning of the
1897 encoding numbers. */
1898 int enc
= font_info
->encoding
[charset
];
1900 if ((enc
== 1 || enc
== 2)
1901 && CHARSET_DIMENSION (charset
) == 2)
1902 char2b
->byte1
|= 0x80;
1904 if (enc
== 1 || enc
== 3)
1905 char2b
->byte2
|= 0x80;
1911 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1912 char2b
->byte1
= sjis1
;
1913 char2b
->byte2
= sjis2
;
1919 /* Get face and two-byte form of character C in face FACE_ID on frame
1920 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1921 means we want to display multibyte text. Value is a pointer to a
1922 realized face that is ready for display. */
1924 static INLINE
struct face
*
1925 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1931 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1935 /* Unibyte case. We don't have to encode, but we have to make
1936 sure to use a face suitable for unibyte. */
1939 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1940 face
= FACE_FROM_ID (f
, face_id
);
1942 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1944 /* Case of ASCII in a face known to fit ASCII. */
1950 int c1
, c2
, charset
;
1952 /* Split characters into bytes. If c2 is -1 afterwards, C is
1953 really a one-byte character so that byte1 is zero. */
1954 SPLIT_CHAR (c
, charset
, c1
, c2
);
1956 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1958 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1960 /* Maybe encode the character in *CHAR2B. */
1961 if (face
->font
!= NULL
)
1963 struct font_info
*font_info
1964 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1966 x_encode_char (c
, char2b
, font_info
);
1970 /* Make sure X resources of the face are allocated. */
1971 xassert (face
!= NULL
);
1972 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1978 /* Get face and two-byte form of character glyph GLYPH on frame F.
1979 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1980 a pointer to a realized face that is ready for display. */
1982 static INLINE
struct face
*
1983 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1985 struct glyph
*glyph
;
1991 xassert (glyph
->type
== CHAR_GLYPH
);
1992 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1997 if (!glyph
->multibyte_p
)
1999 /* Unibyte case. We don't have to encode, but we have to make
2000 sure to use a face suitable for unibyte. */
2002 char2b
->byte2
= glyph
->u
.ch
;
2004 else if (glyph
->u
.ch
< 128
2005 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
2007 /* Case of ASCII in a face known to fit ASCII. */
2009 char2b
->byte2
= glyph
->u
.ch
;
2013 int c1
, c2
, charset
;
2015 /* Split characters into bytes. If c2 is -1 afterwards, C is
2016 really a one-byte character so that byte1 is zero. */
2017 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
2019 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
2021 char2b
->byte1
= 0, char2b
->byte2
= c1
;
2023 /* Maybe encode the character in *CHAR2B. */
2024 if (charset
!= CHARSET_ASCII
)
2026 struct font_info
*font_info
2027 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
2030 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
2033 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2038 /* Make sure X resources of the face are allocated. */
2039 xassert (face
!= NULL
);
2040 PREPARE_FACE_FOR_DISPLAY (f
, face
);
2045 /* Store one glyph for IT->char_to_display in IT->glyph_row.
2046 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2052 struct glyph
*glyph
;
2053 enum glyph_row_area area
= it
->area
;
2055 xassert (it
->glyph_row
);
2056 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
2058 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2059 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2061 glyph
->charpos
= CHARPOS (it
->position
);
2062 glyph
->object
= it
->object
;
2063 glyph
->pixel_width
= it
->pixel_width
;
2064 glyph
->voffset
= it
->voffset
;
2065 glyph
->type
= CHAR_GLYPH
;
2066 glyph
->multibyte_p
= it
->multibyte_p
;
2067 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2068 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2069 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2070 || it
->phys_descent
> it
->descent
);
2071 glyph
->padding_p
= 0;
2072 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
2073 glyph
->face_id
= it
->face_id
;
2074 glyph
->u
.ch
= it
->char_to_display
;
2075 ++it
->glyph_row
->used
[area
];
2079 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
2080 Called from x_produce_glyphs when IT->glyph_row is non-null. */
2083 x_append_composite_glyph (it
)
2086 struct glyph
*glyph
;
2087 enum glyph_row_area area
= it
->area
;
2089 xassert (it
->glyph_row
);
2091 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2092 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2094 glyph
->charpos
= CHARPOS (it
->position
);
2095 glyph
->object
= it
->object
;
2096 glyph
->pixel_width
= it
->pixel_width
;
2097 glyph
->voffset
= it
->voffset
;
2098 glyph
->type
= COMPOSITE_GLYPH
;
2099 glyph
->multibyte_p
= it
->multibyte_p
;
2100 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2101 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2102 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
2103 || it
->phys_descent
> it
->descent
);
2104 glyph
->padding_p
= 0;
2105 glyph
->glyph_not_available_p
= 0;
2106 glyph
->face_id
= it
->face_id
;
2107 glyph
->u
.cmp_id
= it
->cmp_id
;
2108 ++it
->glyph_row
->used
[area
];
2113 /* Change IT->ascent and IT->height according to the setting of
2117 take_vertical_position_into_account (it
)
2122 if (it
->voffset
< 0)
2123 /* Increase the ascent so that we can display the text higher
2125 it
->ascent
+= abs (it
->voffset
);
2127 /* Increase the descent so that we can display the text lower
2129 it
->descent
+= it
->voffset
;
2134 /* Produce glyphs/get display metrics for the image IT is loaded with.
2135 See the description of struct display_iterator in dispextern.h for
2136 an overview of struct display_iterator. */
2139 x_produce_image_glyph (it
)
2145 xassert (it
->what
== IT_IMAGE
);
2147 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2148 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2151 /* Make sure X resources of the face and image are loaded. */
2152 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2153 prepare_image_for_display (it
->f
, img
);
2155 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2156 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2157 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2161 if (face
->box
!= FACE_NO_BOX
)
2163 if (face
->box_line_width
> 0)
2165 it
->ascent
+= face
->box_line_width
;
2166 it
->descent
+= face
->box_line_width
;
2169 if (it
->start_of_box_run_p
)
2170 it
->pixel_width
+= abs (face
->box_line_width
);
2171 if (it
->end_of_box_run_p
)
2172 it
->pixel_width
+= abs (face
->box_line_width
);
2175 take_vertical_position_into_account (it
);
2179 struct glyph
*glyph
;
2180 enum glyph_row_area area
= it
->area
;
2182 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2183 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2185 glyph
->charpos
= CHARPOS (it
->position
);
2186 glyph
->object
= it
->object
;
2187 glyph
->pixel_width
= it
->pixel_width
;
2188 glyph
->voffset
= it
->voffset
;
2189 glyph
->type
= IMAGE_GLYPH
;
2190 glyph
->multibyte_p
= it
->multibyte_p
;
2191 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2192 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2193 glyph
->overlaps_vertically_p
= 0;
2194 glyph
->padding_p
= 0;
2195 glyph
->glyph_not_available_p
= 0;
2196 glyph
->face_id
= it
->face_id
;
2197 glyph
->u
.img_id
= img
->id
;
2198 ++it
->glyph_row
->used
[area
];
2204 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2205 of the glyph, WIDTH and HEIGHT are the width and height of the
2206 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2207 ascent of the glyph (0 <= ASCENT <= 1). */
2210 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2216 struct glyph
*glyph
;
2217 enum glyph_row_area area
= it
->area
;
2219 xassert (ascent
>= 0 && ascent
<= 1);
2221 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2222 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2224 glyph
->charpos
= CHARPOS (it
->position
);
2225 glyph
->object
= object
;
2226 glyph
->pixel_width
= width
;
2227 glyph
->voffset
= it
->voffset
;
2228 glyph
->type
= STRETCH_GLYPH
;
2229 glyph
->multibyte_p
= it
->multibyte_p
;
2230 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2231 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2232 glyph
->overlaps_vertically_p
= 0;
2233 glyph
->padding_p
= 0;
2234 glyph
->glyph_not_available_p
= 0;
2235 glyph
->face_id
= it
->face_id
;
2236 glyph
->u
.stretch
.ascent
= height
* ascent
;
2237 glyph
->u
.stretch
.height
= height
;
2238 ++it
->glyph_row
->used
[area
];
2243 /* Produce a stretch glyph for iterator IT. IT->object is the value
2244 of the glyph property displayed. The value must be a list
2245 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2248 1. `:width WIDTH' specifies that the space should be WIDTH *
2249 canonical char width wide. WIDTH may be an integer or floating
2252 2. `:relative-width FACTOR' specifies that the width of the stretch
2253 should be computed from the width of the first character having the
2254 `glyph' property, and should be FACTOR times that width.
2256 3. `:align-to HPOS' specifies that the space should be wide enough
2257 to reach HPOS, a value in canonical character units.
2259 Exactly one of the above pairs must be present.
2261 4. `:height HEIGHT' specifies that the height of the stretch produced
2262 should be HEIGHT, measured in canonical character units.
2264 5. `:relative-height FACTOR' specifies that the height of the
2265 stretch should be FACTOR times the height of the characters having
2268 Either none or exactly one of 4 or 5 must be present.
2270 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2271 of the stretch should be used for the ascent of the stretch.
2272 ASCENT must be in the range 0 <= ASCENT <= 100. */
2275 ((INTEGERP (X) || FLOATP (X)) \
2281 x_produce_stretch_glyph (it
)
2284 /* (space :width WIDTH :height HEIGHT. */
2286 extern Lisp_Object Qspace
;
2288 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2289 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2290 extern Lisp_Object QCalign_to
;
2291 Lisp_Object prop
, plist
;
2292 double width
= 0, height
= 0, ascent
= 0;
2293 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2294 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2296 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2298 /* List should start with `space'. */
2299 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2300 plist
= XCDR (it
->object
);
2302 /* Compute the width of the stretch. */
2303 if (prop
= Fplist_get (plist
, QCwidth
),
2305 /* Absolute width `:width WIDTH' specified and valid. */
2306 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2307 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2310 /* Relative width `:relative-width FACTOR' specified and valid.
2311 Compute the width of the characters having the `glyph'
2314 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2317 if (it
->multibyte_p
)
2319 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2320 - IT_BYTEPOS (*it
));
2321 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2324 it2
.c
= *p
, it2
.len
= 1;
2326 it2
.glyph_row
= NULL
;
2327 it2
.what
= IT_CHARACTER
;
2328 x_produce_glyphs (&it2
);
2329 width
= NUMVAL (prop
) * it2
.pixel_width
;
2331 else if (prop
= Fplist_get (plist
, QCalign_to
),
2333 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2335 /* Nothing specified -> width defaults to canonical char width. */
2336 width
= CANON_X_UNIT (it
->f
);
2338 /* Compute height. */
2339 if (prop
= Fplist_get (plist
, QCheight
),
2341 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2342 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2344 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2346 height
= FONT_HEIGHT (font
);
2348 /* Compute percentage of height used for ascent. If
2349 `:ascent ASCENT' is present and valid, use that. Otherwise,
2350 derive the ascent from the font in use. */
2351 if (prop
= Fplist_get (plist
, QCascent
),
2352 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2353 ascent
= NUMVAL (prop
) / 100.0;
2355 ascent
= (double) FONT_BASE (font
) / FONT_HEIGHT (font
);
2364 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2365 if (!STRINGP (object
))
2366 object
= it
->w
->buffer
;
2367 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2370 it
->pixel_width
= width
;
2371 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2372 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2375 if (face
->box
!= FACE_NO_BOX
)
2377 if (face
->box_line_width
> 0)
2379 it
->ascent
+= face
->box_line_width
;
2380 it
->descent
+= face
->box_line_width
;
2383 if (it
->start_of_box_run_p
)
2384 it
->pixel_width
+= abs (face
->box_line_width
);
2385 if (it
->end_of_box_run_p
)
2386 it
->pixel_width
+= abs (face
->box_line_width
);
2389 take_vertical_position_into_account (it
);
2392 /* Return proper value to be used as baseline offset of font that has
2393 ASCENT and DESCENT to draw characters by the font at the vertical
2394 center of the line of frame F.
2396 Here, out task is to find the value of BOFF in the following figure;
2398 -------------------------+-----------+-
2399 -+-+---------+-+ | |
2401 | | | | F_ASCENT F_HEIGHT
2404 | | |-|-+------+-----------|------- baseline
2406 | |---------|-+-+ | |
2408 -+-+---------+-+ F_DESCENT |
2409 -------------------------+-----------+-
2411 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2412 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2413 DESCENT = FONT->descent
2414 HEIGHT = FONT_HEIGHT (FONT)
2415 F_DESCENT = (F->output_data.x->font->descent
2416 - F->output_data.x->baseline_offset)
2417 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2420 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2421 (FONT_DESCENT (FONT) \
2422 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
2423 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
2424 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
2426 /* Produce glyphs/get display metrics for the display element IT is
2427 loaded with. See the description of struct display_iterator in
2428 dispextern.h for an overview of struct display_iterator. */
2431 x_produce_glyphs (it
)
2434 it
->glyph_not_available_p
= 0;
2436 if (it
->what
== IT_CHARACTER
)
2440 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2442 int font_not_found_p
;
2443 struct font_info
*font_info
;
2444 int boff
; /* baseline offset */
2445 /* We may change it->multibyte_p upon unibyte<->multibyte
2446 conversion. So, save the current value now and restore it
2449 Note: It seems that we don't have to record multibyte_p in
2450 struct glyph because the character code itself tells if or
2451 not the character is multibyte. Thus, in the future, we must
2452 consider eliminating the field `multibyte_p' in the struct
2455 int saved_multibyte_p
= it
->multibyte_p
;
2457 /* Maybe translate single-byte characters to multibyte, or the
2459 it
->char_to_display
= it
->c
;
2460 if (!ASCII_BYTE_P (it
->c
))
2462 if (unibyte_display_via_language_environment
2463 && SINGLE_BYTE_CHAR_P (it
->c
)
2465 || !NILP (Vnonascii_translation_table
)))
2467 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2468 it
->multibyte_p
= 1;
2469 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2470 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2472 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2473 && !it
->multibyte_p
)
2475 it
->multibyte_p
= 1;
2476 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2477 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2481 /* Get font to use. Encode IT->char_to_display. */
2482 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2483 it
->face_id
, &char2b
,
2487 /* When no suitable font found, use the default font. */
2488 font_not_found_p
= font
== NULL
;
2489 if (font_not_found_p
)
2491 font
= FRAME_FONT (it
->f
);
2492 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2497 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2498 boff
= font_info
->baseline_offset
;
2499 if (font_info
->vertical_centering
)
2500 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2503 if (it
->char_to_display
>= ' '
2504 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2506 /* Either unibyte or ASCII. */
2511 pcm
= x_per_char_metric (font
, &char2b
);
2512 it
->ascent
= FONT_BASE (font
) + boff
;
2513 it
->descent
= FONT_DESCENT (font
) - boff
;
2517 it
->phys_ascent
= pcm
->ascent
+ boff
;
2518 it
->phys_descent
= pcm
->descent
- boff
;
2519 it
->pixel_width
= pcm
->width
;
2523 it
->glyph_not_available_p
= 1;
2524 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2525 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2526 it
->pixel_width
= FONT_WIDTH (font
);
2529 /* If this is a space inside a region of text with
2530 `space-width' property, change its width. */
2531 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2533 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2535 /* If face has a box, add the box thickness to the character
2536 height. If character has a box line to the left and/or
2537 right, add the box line width to the character's width. */
2538 if (face
->box
!= FACE_NO_BOX
)
2540 int thick
= face
->box_line_width
;
2544 it
->ascent
+= thick
;
2545 it
->descent
+= thick
;
2550 if (it
->start_of_box_run_p
)
2551 it
->pixel_width
+= thick
;
2552 if (it
->end_of_box_run_p
)
2553 it
->pixel_width
+= thick
;
2556 /* If face has an overline, add the height of the overline
2557 (1 pixel) and a 1 pixel margin to the character height. */
2558 if (face
->overline_p
)
2561 take_vertical_position_into_account (it
);
2563 /* If we have to actually produce glyphs, do it. */
2568 /* Translate a space with a `space-width' property
2569 into a stretch glyph. */
2570 double ascent
= (double) FONT_BASE (font
)
2571 / FONT_HEIGHT (font
);
2572 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2573 it
->ascent
+ it
->descent
, ascent
);
2576 x_append_glyph (it
);
2578 /* If characters with lbearing or rbearing are displayed
2579 in this line, record that fact in a flag of the
2580 glyph row. This is used to optimize X output code. */
2581 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2582 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2585 else if (it
->char_to_display
== '\n')
2587 /* A newline has no width but we need the height of the line. */
2588 it
->pixel_width
= 0;
2590 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2591 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2593 if (face
->box
!= FACE_NO_BOX
2594 && face
->box_line_width
> 0)
2596 it
->ascent
+= face
->box_line_width
;
2597 it
->descent
+= face
->box_line_width
;
2600 else if (it
->char_to_display
== '\t')
2602 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2603 int x
= it
->current_x
+ it
->continuation_lines_width
;
2604 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2606 /* If the distance from the current position to the next tab
2607 stop is less than a canonical character width, use the
2608 tab stop after that. */
2609 if (next_tab_x
- x
< CANON_X_UNIT (it
->f
))
2610 next_tab_x
+= tab_width
;
2612 it
->pixel_width
= next_tab_x
- x
;
2614 it
->ascent
= it
->phys_ascent
= FONT_BASE (font
) + boff
;
2615 it
->descent
= it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2619 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2620 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2621 it
->ascent
+ it
->descent
, ascent
);
2626 /* A multi-byte character. Assume that the display width of the
2627 character is the width of the character multiplied by the
2628 width of the font. */
2630 /* If we found a font, this font should give us the right
2631 metrics. If we didn't find a font, use the frame's
2632 default font and calculate the width of the character
2633 from the charset width; this is what old redisplay code
2635 pcm
= x_per_char_metric (font
, &char2b
);
2636 if (font_not_found_p
|| !pcm
)
2638 int charset
= CHAR_CHARSET (it
->char_to_display
);
2640 it
->glyph_not_available_p
= 1;
2641 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2642 * CHARSET_WIDTH (charset
));
2643 it
->phys_ascent
= FONT_BASE (font
) + boff
;
2644 it
->phys_descent
= FONT_DESCENT (font
) - boff
;
2648 it
->pixel_width
= pcm
->width
;
2649 it
->phys_ascent
= pcm
->ascent
+ boff
;
2650 it
->phys_descent
= pcm
->descent
- boff
;
2652 && (pcm
->lbearing
< 0
2653 || pcm
->rbearing
> pcm
->width
))
2654 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2657 it
->ascent
= FONT_BASE (font
) + boff
;
2658 it
->descent
= FONT_DESCENT (font
) - boff
;
2659 if (face
->box
!= FACE_NO_BOX
)
2661 int thick
= face
->box_line_width
;
2665 it
->ascent
+= thick
;
2666 it
->descent
+= thick
;
2671 if (it
->start_of_box_run_p
)
2672 it
->pixel_width
+= thick
;
2673 if (it
->end_of_box_run_p
)
2674 it
->pixel_width
+= thick
;
2677 /* If face has an overline, add the height of the overline
2678 (1 pixel) and a 1 pixel margin to the character height. */
2679 if (face
->overline_p
)
2682 take_vertical_position_into_account (it
);
2685 x_append_glyph (it
);
2687 it
->multibyte_p
= saved_multibyte_p
;
2689 else if (it
->what
== IT_COMPOSITION
)
2691 /* Note: A composition is represented as one glyph in the
2692 glyph matrix. There are no padding glyphs. */
2695 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2697 int font_not_found_p
;
2698 struct font_info
*font_info
;
2699 int boff
; /* baseline offset */
2700 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2702 /* Maybe translate single-byte characters to multibyte. */
2703 it
->char_to_display
= it
->c
;
2704 if (unibyte_display_via_language_environment
2705 && SINGLE_BYTE_CHAR_P (it
->c
)
2708 && !NILP (Vnonascii_translation_table
))))
2710 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2713 /* Get face and font to use. Encode IT->char_to_display. */
2714 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2715 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2716 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2717 it
->face_id
, &char2b
, it
->multibyte_p
);
2720 /* When no suitable font found, use the default font. */
2721 font_not_found_p
= font
== NULL
;
2722 if (font_not_found_p
)
2724 font
= FRAME_FONT (it
->f
);
2725 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2730 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2731 boff
= font_info
->baseline_offset
;
2732 if (font_info
->vertical_centering
)
2733 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2736 /* There are no padding glyphs, so there is only one glyph to
2737 produce for the composition. Important is that pixel_width,
2738 ascent and descent are the values of what is drawn by
2739 draw_glyphs (i.e. the values of the overall glyphs composed). */
2742 /* If we have not yet calculated pixel size data of glyphs of
2743 the composition for the current face font, calculate them
2744 now. Theoretically, we have to check all fonts for the
2745 glyphs, but that requires much time and memory space. So,
2746 here we check only the font of the first glyph. This leads
2747 to incorrect display very rarely, and C-l (recenter) can
2748 correct the display anyway. */
2749 if (cmp
->font
!= (void *) font
)
2751 /* Ascent and descent of the font of the first character of
2752 this composition (adjusted by baseline offset). Ascent
2753 and descent of overall glyphs should not be less than
2754 them respectively. */
2755 int font_ascent
= FONT_BASE (font
) + boff
;
2756 int font_descent
= FONT_DESCENT (font
) - boff
;
2757 /* Bounding box of the overall glyphs. */
2758 int leftmost
, rightmost
, lowest
, highest
;
2759 int i
, width
, ascent
, descent
;
2761 cmp
->font
= (void *) font
;
2763 /* Initialize the bounding box. */
2764 pcm
= x_per_char_metric (font
, &char2b
);
2768 ascent
= pcm
->ascent
;
2769 descent
= pcm
->descent
;
2773 width
= FONT_WIDTH (font
);
2774 ascent
= FONT_BASE (font
);
2775 descent
= FONT_DESCENT (font
);
2779 lowest
= - descent
+ boff
;
2780 highest
= ascent
+ boff
;
2784 && font_info
->default_ascent
2785 && CHAR_TABLE_P (Vuse_default_ascent
)
2786 && !NILP (Faref (Vuse_default_ascent
,
2787 make_number (it
->char_to_display
))))
2788 highest
= font_info
->default_ascent
+ boff
;
2790 /* Draw the first glyph at the normal position. It may be
2791 shifted to right later if some other glyphs are drawn at
2793 cmp
->offsets
[0] = 0;
2794 cmp
->offsets
[1] = boff
;
2796 /* Set cmp->offsets for the remaining glyphs. */
2797 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2799 int left
, right
, btm
, top
;
2800 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2801 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2803 face
= FACE_FROM_ID (it
->f
, face_id
);
2804 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2809 font
= FRAME_FONT (it
->f
);
2810 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2816 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2817 boff
= font_info
->baseline_offset
;
2818 if (font_info
->vertical_centering
)
2819 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2822 pcm
= x_per_char_metric (font
, &char2b
);
2826 ascent
= pcm
->ascent
;
2827 descent
= pcm
->descent
;
2831 width
= FONT_WIDTH (font
);
2836 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2838 /* Relative composition with or without
2840 left
= (leftmost
+ rightmost
- width
) / 2;
2841 btm
= - descent
+ boff
;
2842 if (font_info
&& font_info
->relative_compose
2843 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2844 || NILP (Faref (Vignore_relative_composition
,
2845 make_number (ch
)))))
2848 if (- descent
>= font_info
->relative_compose
)
2849 /* One extra pixel between two glyphs. */
2851 else if (ascent
<= 0)
2852 /* One extra pixel between two glyphs. */
2853 btm
= lowest
- 1 - ascent
- descent
;
2858 /* A composition rule is specified by an integer
2859 value that encodes global and new reference
2860 points (GREF and NREF). GREF and NREF are
2861 specified by numbers as below:
2869 ---3---4---5--- baseline
2871 6---7---8 -- descent
2873 int rule
= COMPOSITION_RULE (cmp
, i
);
2874 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2876 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2877 grefx
= gref
% 3, nrefx
= nref
% 3;
2878 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2881 + grefx
* (rightmost
- leftmost
) / 2
2882 - nrefx
* width
/ 2);
2883 btm
= ((grefy
== 0 ? highest
2885 : grefy
== 2 ? lowest
2886 : (highest
+ lowest
) / 2)
2887 - (nrefy
== 0 ? ascent
+ descent
2888 : nrefy
== 1 ? descent
- boff
2890 : (ascent
+ descent
) / 2));
2893 cmp
->offsets
[i
* 2] = left
;
2894 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2896 /* Update the bounding box of the overall glyphs. */
2897 right
= left
+ width
;
2898 top
= btm
+ descent
+ ascent
;
2899 if (left
< leftmost
)
2901 if (right
> rightmost
)
2909 /* If there are glyphs whose x-offsets are negative,
2910 shift all glyphs to the right and make all x-offsets
2914 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2915 cmp
->offsets
[i
* 2] -= leftmost
;
2916 rightmost
-= leftmost
;
2919 cmp
->pixel_width
= rightmost
;
2920 cmp
->ascent
= highest
;
2921 cmp
->descent
= - lowest
;
2922 if (cmp
->ascent
< font_ascent
)
2923 cmp
->ascent
= font_ascent
;
2924 if (cmp
->descent
< font_descent
)
2925 cmp
->descent
= font_descent
;
2928 it
->pixel_width
= cmp
->pixel_width
;
2929 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2930 it
->descent
= it
->phys_descent
= cmp
->descent
;
2932 if (face
->box
!= FACE_NO_BOX
)
2934 int thick
= face
->box_line_width
;
2938 it
->ascent
+= thick
;
2939 it
->descent
+= thick
;
2944 if (it
->start_of_box_run_p
)
2945 it
->pixel_width
+= thick
;
2946 if (it
->end_of_box_run_p
)
2947 it
->pixel_width
+= thick
;
2950 /* If face has an overline, add the height of the overline
2951 (1 pixel) and a 1 pixel margin to the character height. */
2952 if (face
->overline_p
)
2955 take_vertical_position_into_account (it
);
2958 x_append_composite_glyph (it
);
2960 else if (it
->what
== IT_IMAGE
)
2961 x_produce_image_glyph (it
);
2962 else if (it
->what
== IT_STRETCH
)
2963 x_produce_stretch_glyph (it
);
2965 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2966 because this isn't true for images with `:ascent 100'. */
2967 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2968 if (it
->area
== TEXT_AREA
)
2969 it
->current_x
+= it
->pixel_width
;
2971 it
->descent
+= it
->extra_line_spacing
;
2973 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2974 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2975 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2976 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2980 /* Estimate the pixel height of the mode or top line on frame F.
2981 FACE_ID specifies what line's height to estimate. */
2984 x_estimate_mode_line_height (f
, face_id
)
2986 enum face_id face_id
;
2988 int height
= FONT_HEIGHT (FRAME_FONT (f
));
2990 /* This function is called so early when Emacs starts that the face
2991 cache and mode line face are not yet initialized. */
2992 if (FRAME_FACE_CACHE (f
))
2994 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2998 height
= FONT_HEIGHT (face
->font
);
2999 if (face
->box_line_width
> 0)
3000 height
+= 2 * face
->box_line_width
;
3008 /***********************************************************************
3010 ***********************************************************************/
3012 /* A sequence of glyphs to be drawn in the same face.
3014 This data structure is not really completely X specific, so it
3015 could possibly, at least partially, be useful for other systems. It
3016 is currently not part of the external redisplay interface because
3017 it's not clear what other systems will need. */
3021 /* X-origin of the string. */
3024 /* Y-origin and y-position of the base line of this string. */
3027 /* The width of the string, not including a face extension. */
3030 /* The width of the string, including a face extension. */
3031 int background_width
;
3033 /* The height of this string. This is the height of the line this
3034 string is drawn in, and can be different from the height of the
3035 font the string is drawn in. */
3038 /* Number of pixels this string overwrites in front of its x-origin.
3039 This number is zero if the string has an lbearing >= 0; it is
3040 -lbearing, if the string has an lbearing < 0. */
3043 /* Number of pixels this string overwrites past its right-most
3044 nominal x-position, i.e. x + width. Zero if the string's
3045 rbearing is <= its nominal width, rbearing - width otherwise. */
3048 /* The frame on which the glyph string is drawn. */
3051 /* The window on which the glyph string is drawn. */
3054 /* X display and window for convenience. */
3058 /* The glyph row for which this string was built. It determines the
3059 y-origin and height of the string. */
3060 struct glyph_row
*row
;
3062 /* The area within row. */
3063 enum glyph_row_area area
;
3065 /* Characters to be drawn, and number of characters. */
3069 /* A face-override for drawing cursors, mouse face and similar. */
3070 enum draw_glyphs_face hl
;
3072 /* Face in which this string is to be drawn. */
3075 /* Font in which this string is to be drawn. */
3078 /* Font info for this string. */
3079 struct font_info
*font_info
;
3081 /* Non-null means this string describes (part of) a composition.
3082 All characters from char2b are drawn composed. */
3083 struct composition
*cmp
;
3085 /* Index of this glyph string's first character in the glyph
3086 definition of CMP. If this is zero, this glyph string describes
3087 the first character of a composition. */
3090 /* 1 means this glyph strings face has to be drawn to the right end
3091 of the window's drawing area. */
3092 unsigned extends_to_end_of_line_p
: 1;
3094 /* 1 means the background of this string has been drawn. */
3095 unsigned background_filled_p
: 1;
3097 /* 1 means glyph string must be drawn with 16-bit functions. */
3098 unsigned two_byte_p
: 1;
3100 /* 1 means that the original font determined for drawing this glyph
3101 string could not be loaded. The member `font' has been set to
3102 the frame's default font in this case. */
3103 unsigned font_not_found_p
: 1;
3105 /* 1 means that the face in which this glyph string is drawn has a
3107 unsigned stippled_p
: 1;
3109 /* 1 means only the foreground of this glyph string must be drawn,
3110 and we should use the physical height of the line this glyph
3111 string appears in as clip rect. */
3112 unsigned for_overlaps_p
: 1;
3114 /* The GC to use for drawing this glyph string. */
3117 /* A pointer to the first glyph in the string. This glyph
3118 corresponds to char2b[0]. Needed to draw rectangles if
3119 font_not_found_p is 1. */
3120 struct glyph
*first_glyph
;
3122 /* Image, if any. */
3125 struct glyph_string
*next
, *prev
;
3132 x_dump_glyph_string (s
)
3133 struct glyph_string
*s
;
3135 fprintf (stderr
, "glyph string\n");
3136 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
3137 s
->x
, s
->y
, s
->width
, s
->height
);
3138 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
3139 fprintf (stderr
, " hl = %d\n", s
->hl
);
3140 fprintf (stderr
, " left overhang = %d, right = %d\n",
3141 s
->left_overhang
, s
->right_overhang
);
3142 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
3143 fprintf (stderr
, " extends to end of line = %d\n",
3144 s
->extends_to_end_of_line_p
);
3145 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
3146 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
3149 #endif /* GLYPH_DEBUG */
3153 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
3154 struct glyph_string
**,
3155 struct glyph_string
*,
3156 struct glyph_string
*));
3157 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
3158 struct glyph_string
**,
3159 struct glyph_string
*,
3160 struct glyph_string
*));
3161 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3162 struct glyph_string
**,
3163 struct glyph_string
*));
3164 static int x_left_overwritten
P_ ((struct glyph_string
*));
3165 static int x_left_overwriting
P_ ((struct glyph_string
*));
3166 static int x_right_overwritten
P_ ((struct glyph_string
*));
3167 static int x_right_overwriting
P_ ((struct glyph_string
*));
3168 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3170 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3171 XChar2b
*, struct window
*,
3173 enum glyph_row_area
, int,
3174 enum draw_glyphs_face
));
3175 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3176 enum glyph_row_area
, int, int,
3177 enum draw_glyphs_face
, int));
3178 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3179 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3180 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3182 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3183 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3184 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3185 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3186 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3187 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3188 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3189 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3190 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3192 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3193 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
3194 unsigned long *, double, int));*/
3195 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3196 double, int, unsigned long));
3197 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3198 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3199 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3200 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3201 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3202 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3203 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3205 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3206 int, int, int, int, Rect
*));
3207 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3208 int, int, int, Rect
*));
3209 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3210 enum glyph_row_area
));
3211 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3213 enum glyph_row_area
, int, int));
3216 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3220 /* Append the list of glyph strings with head H and tail T to the list
3221 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3224 x_append_glyph_string_lists (head
, tail
, h
, t
)
3225 struct glyph_string
**head
, **tail
;
3226 struct glyph_string
*h
, *t
;
3240 /* Prepend the list of glyph strings with head H and tail T to the
3241 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3245 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3246 struct glyph_string
**head
, **tail
;
3247 struct glyph_string
*h
, *t
;
3261 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3262 Set *HEAD and *TAIL to the resulting list. */
3265 x_append_glyph_string (head
, tail
, s
)
3266 struct glyph_string
**head
, **tail
;
3267 struct glyph_string
*s
;
3269 s
->next
= s
->prev
= NULL
;
3270 x_append_glyph_string_lists (head
, tail
, s
, s
);
3274 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3279 struct glyph_string
*s
;
3281 if (s
->font
== FRAME_FONT (s
->f
)
3282 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3283 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3285 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3288 /* Cursor on non-default face: must merge. */
3292 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3293 xgcv
.foreground
= s
->face
->background
;
3295 /* If the glyph would be invisible, try a different foreground. */
3296 if (xgcv
.foreground
== xgcv
.background
)
3297 xgcv
.foreground
= s
->face
->foreground
;
3298 if (xgcv
.foreground
== xgcv
.background
)
3299 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3300 if (xgcv
.foreground
== xgcv
.background
)
3301 xgcv
.foreground
= s
->face
->foreground
;
3303 /* Make sure the cursor is distinct from text in this face. */
3304 if (xgcv
.background
== s
->face
->background
3305 && xgcv
.foreground
== s
->face
->foreground
)
3307 xgcv
.background
= s
->face
->foreground
;
3308 xgcv
.foreground
= s
->face
->background
;
3311 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3312 xgcv
.font
= s
->font
;
3313 mask
= GCForeground
| GCBackground
| GCFont
;
3315 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3316 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3319 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3320 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3322 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3327 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3330 x_set_mouse_face_gc (s
)
3331 struct glyph_string
*s
;
3336 /* What face has to be used last for the mouse face? */
3337 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3338 face
= FACE_FROM_ID (s
->f
, face_id
);
3340 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
3342 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3343 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3345 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3346 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3347 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3349 /* If font in this face is same as S->font, use it. */
3350 if (s
->font
== s
->face
->font
)
3351 s
->gc
= s
->face
->gc
;
3354 /* Otherwise construct scratch_cursor_gc with values from FACE
3359 xgcv
.background
= s
->face
->background
;
3360 xgcv
.foreground
= s
->face
->foreground
;
3361 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3362 xgcv
.font
= s
->font
;
3363 mask
= GCForeground
| GCBackground
| GCFont
;
3365 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3366 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3369 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3370 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3372 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3375 xassert (s
->gc
!= 0);
3379 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3380 Faces to use in the mode line have already been computed when the
3381 matrix was built, so there isn't much to do, here. */
3384 x_set_mode_line_face_gc (s
)
3385 struct glyph_string
*s
;
3387 s
->gc
= s
->face
->gc
;
3391 /* Set S->gc of glyph string S for drawing that glyph string. Set
3392 S->stippled_p to a non-zero value if the face of S has a stipple
3396 x_set_glyph_string_gc (s
)
3397 struct glyph_string
*s
;
3399 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3401 if (s
->hl
== DRAW_NORMAL_TEXT
)
3403 s
->gc
= s
->face
->gc
;
3404 s
->stippled_p
= s
->face
->stipple
!= 0;
3406 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3408 x_set_mode_line_face_gc (s
);
3409 s
->stippled_p
= s
->face
->stipple
!= 0;
3411 else if (s
->hl
== DRAW_CURSOR
)
3413 x_set_cursor_gc (s
);
3416 else if (s
->hl
== DRAW_MOUSE_FACE
)
3418 x_set_mouse_face_gc (s
);
3419 s
->stippled_p
= s
->face
->stipple
!= 0;
3421 else if (s
->hl
== DRAW_IMAGE_RAISED
3422 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3424 s
->gc
= s
->face
->gc
;
3425 s
->stippled_p
= s
->face
->stipple
!= 0;
3429 s
->gc
= s
->face
->gc
;
3430 s
->stippled_p
= s
->face
->stipple
!= 0;
3433 /* GC must have been set. */
3434 xassert (s
->gc
!= 0);
3438 /* Return in *R the clipping rectangle for glyph string S. */
3441 x_get_glyph_string_clip_rect (s
, r
)
3442 struct glyph_string
*s
;
3445 int r_height
, r_width
;
3447 if (s
->row
->full_width_p
)
3449 /* Draw full-width. X coordinates are relative to S->w->left. */
3450 int canon_x
= CANON_X_UNIT (s
->f
);
3452 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3453 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3455 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3457 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3458 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3462 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3464 /* Unless displaying a mode or menu bar line, which are always
3465 fully visible, clip to the visible part of the row. */
3466 if (s
->w
->pseudo_window_p
)
3467 r_height
= s
->row
->visible_height
;
3469 r_height
= s
->height
;
3473 /* This is a text line that may be partially visible. */
3474 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3475 r_width
= window_box_width (s
->w
, s
->area
);
3476 r_height
= s
->row
->visible_height
;
3479 /* If S draws overlapping rows, it's sufficient to use the top and
3480 bottom of the window for clipping because this glyph string
3481 intentionally draws over other lines. */
3482 if (s
->for_overlaps_p
)
3484 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3485 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3489 /* Don't use S->y for clipping because it doesn't take partially
3490 visible lines into account. For example, it can be negative for
3491 partially visible lines at the top of a window. */
3492 if (!s
->row
->full_width_p
3493 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3494 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3496 r
->top
= max (0, s
->row
->y
);
3498 /* If drawing a tool-bar window, draw it over the internal border
3499 at the top of the window. */
3500 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3501 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3504 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3506 r
->bottom
= r
->top
+ r_height
;
3507 r
->right
= r
->left
+ r_width
;
3511 /* Set clipping for output of glyph string S. S may be part of a mode
3512 line or menu if we don't have X toolkit support. */
3515 x_set_glyph_string_clipping (s
)
3516 struct glyph_string
*s
;
3519 x_get_glyph_string_clip_rect (s
, &r
);
3520 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3524 /* Compute left and right overhang of glyph string S. If S is a glyph
3525 string for a composition, assume overhangs don't exist. */
3528 x_compute_glyph_string_overhangs (s
)
3529 struct glyph_string
*s
;
3532 && s
->first_glyph
->type
== CHAR_GLYPH
)
3535 int direction
, font_ascent
, font_descent
;
3536 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3537 &font_ascent
, &font_descent
, &cs
);
3538 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3539 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3544 /* Compute overhangs and x-positions for glyph string S and its
3545 predecessors, or successors. X is the starting x-position for S.
3546 BACKWARD_P non-zero means process predecessors. */
3549 x_compute_overhangs_and_x (s
, x
, backward_p
)
3550 struct glyph_string
*s
;
3558 x_compute_glyph_string_overhangs (s
);
3568 x_compute_glyph_string_overhangs (s
);
3577 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3578 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3579 assumed to be zero. */
3582 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3583 struct glyph
*glyph
;
3589 if (glyph
->type
== CHAR_GLYPH
)
3593 struct font_info
*font_info
;
3597 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3599 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3601 && (pcm
= x_per_char_metric (font
, &char2b
)))
3603 if (pcm
->rbearing
> pcm
->width
)
3604 *right
= pcm
->rbearing
- pcm
->width
;
3605 if (pcm
->lbearing
< 0)
3606 *left
= -pcm
->lbearing
;
3612 /* Return the index of the first glyph preceding glyph string S that
3613 is overwritten by S because of S's left overhang. Value is -1
3614 if no glyphs are overwritten. */
3617 x_left_overwritten (s
)
3618 struct glyph_string
*s
;
3622 if (s
->left_overhang
)
3625 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3626 int first
= s
->first_glyph
- glyphs
;
3628 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3629 x
-= glyphs
[i
].pixel_width
;
3640 /* Return the index of the first glyph preceding glyph string S that
3641 is overwriting S because of its right overhang. Value is -1 if no
3642 glyph in front of S overwrites S. */
3645 x_left_overwriting (s
)
3646 struct glyph_string
*s
;
3649 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3650 int first
= s
->first_glyph
- glyphs
;
3654 for (i
= first
- 1; i
>= 0; --i
)
3657 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3660 x
-= glyphs
[i
].pixel_width
;
3667 /* Return the index of the last glyph following glyph string S that is
3668 not overwritten by S because of S's right overhang. Value is -1 if
3669 no such glyph is found. */
3672 x_right_overwritten (s
)
3673 struct glyph_string
*s
;
3677 if (s
->right_overhang
)
3680 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3681 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3682 int end
= s
->row
->used
[s
->area
];
3684 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3685 x
+= glyphs
[i
].pixel_width
;
3694 /* Return the index of the last glyph following glyph string S that
3695 overwrites S because of its left overhang. Value is negative
3696 if no such glyph is found. */
3699 x_right_overwriting (s
)
3700 struct glyph_string
*s
;
3703 int end
= s
->row
->used
[s
->area
];
3704 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3705 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3709 for (i
= first
; i
< end
; ++i
)
3712 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3715 x
+= glyphs
[i
].pixel_width
;
3722 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3725 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3726 struct glyph_string
*s
;
3731 xgcv
.foreground
= s
->gc
->background
;
3732 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3736 /* Draw the background of glyph_string S. If S->background_filled_p
3737 is non-zero don't draw it. FORCE_P non-zero means draw the
3738 background even if it wouldn't be drawn normally. This is used
3739 when a string preceding S draws into the background of S, or S
3740 contains the first component of a composition. */
3743 x_draw_glyph_string_background (s
, force_p
)
3744 struct glyph_string
*s
;
3747 /* Nothing to do if background has already been drawn or if it
3748 shouldn't be drawn in the first place. */
3749 if (!s
->background_filled_p
)
3751 int box_line_width
= max (s
->face
->box_line_width
, 0);
3753 #if 0 /* MAC_TODO: stipple */
3756 /* Fill background with a stipple pattern. */
3757 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3758 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3759 s
->y
+ box_line_width
,
3760 s
->background_width
,
3761 s
->height
- 2 * box_line_width
);
3762 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3763 s
->background_filled_p
= 1;
3767 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
3768 || s
->font_not_found_p
3769 || s
->extends_to_end_of_line_p
3772 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
3773 s
->background_width
,
3774 s
->height
- 2 * box_line_width
);
3775 s
->background_filled_p
= 1;
3781 /* Draw the foreground of glyph string S. */
3784 x_draw_glyph_string_foreground (s
)
3785 struct glyph_string
*s
;
3789 /* If first glyph of S has a left box line, start drawing the text
3790 of S to the right of that box line. */
3791 if (s
->face
->box
!= FACE_NO_BOX
3792 && s
->first_glyph
->left_box_line_p
)
3793 x
= s
->x
+ abs (s
->face
->box_line_width
);
3797 /* Draw characters of S as rectangles if S's font could not be
3799 if (s
->font_not_found_p
)
3801 for (i
= 0; i
< s
->nchars
; ++i
)
3803 struct glyph
*g
= s
->first_glyph
+ i
;
3804 mac_draw_rectangle (s
->display
, s
->window
,
3805 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3807 x
+= g
->pixel_width
;
3812 char *char1b
= (char *) s
->char2b
;
3813 int boff
= s
->font_info
->baseline_offset
;
3815 if (s
->font_info
->vertical_centering
)
3816 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3818 /* If we can use 8-bit functions, condense S->char2b. */
3820 for (i
= 0; i
< s
->nchars
; ++i
)
3821 char1b
[i
] = s
->char2b
[i
].byte2
;
3823 /* Draw text with XDrawString if background has already been
3824 filled. Otherwise, use XDrawImageString. (Note that
3825 XDrawImageString is usually faster than XDrawString.) Always
3826 use XDrawImageString when drawing the cursor so that there is
3827 no chance that characters under a box cursor are invisible. */
3828 if (s
->for_overlaps_p
3829 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3831 /* Draw characters with 16-bit or 8-bit functions. */
3833 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3834 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3836 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3837 s
->ybase
- boff
, char1b
, s
->nchars
);
3842 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3843 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3845 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3846 s
->ybase
- boff
, char1b
, s
->nchars
);
3851 /* Draw the foreground of composite glyph string S. */
3854 x_draw_composite_glyph_string_foreground (s
)
3855 struct glyph_string
*s
;
3859 /* If first glyph of S has a left box line, start drawing the text
3860 of S to the right of that box line. */
3861 if (s
->face
->box
!= FACE_NO_BOX
3862 && s
->first_glyph
->left_box_line_p
)
3863 x
= s
->x
+ abs (s
->face
->box_line_width
);
3867 /* S is a glyph string for a composition. S->gidx is the index of
3868 the first character drawn for glyphs of this composition.
3869 S->gidx == 0 means we are drawing the very first character of
3870 this composition. */
3872 /* Draw a rectangle for the composition if the font for the very
3873 first character of the composition could not be loaded. */
3874 if (s
->font_not_found_p
)
3877 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3878 s
->width
- 1, s
->height
- 1);
3882 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3883 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3884 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3885 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3891 #ifdef USE_X_TOOLKIT
3893 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3896 /* Return the frame on which widget WIDGET is used.. Abort if frame
3897 cannot be determined. */
3899 static struct frame
*
3900 x_frame_of_widget (widget
)
3903 struct x_display_info
*dpyinfo
;
3907 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3909 /* Find the top-level shell of the widget. Note that this function
3910 can be called when the widget is not yet realized, so XtWindow
3911 (widget) == 0. That's the reason we can't simply use
3912 x_any_window_to_frame. */
3913 while (!XtIsTopLevelShell (widget
))
3914 widget
= XtParent (widget
);
3916 /* Look for a frame with that top-level widget. Allocate the color
3917 on that frame to get the right gamma correction value. */
3918 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3919 if (GC_FRAMEP (XCAR (tail
))
3920 && (f
= XFRAME (XCAR (tail
)),
3921 (f
->output_data
.nothing
!= 1
3922 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3923 && f
->output_data
.x
->widget
== widget
)
3930 /* Allocate the color COLOR->pixel on the screen and display of
3931 widget WIDGET in colormap CMAP. If an exact match cannot be
3932 allocated, try the nearest color available. Value is non-zero
3933 if successful. This is called from lwlib. */
3936 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3941 struct frame
*f
= x_frame_of_widget (widget
);
3942 return x_alloc_nearest_color (f
, cmap
, color
);
3946 #endif /* USE_X_TOOLKIT */
3948 #if 0 /* MAC_TODO */
3950 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3951 CMAP. If an exact match can't be allocated, try the nearest color
3952 available. Value is non-zero if successful. Set *COLOR to the
3956 x_alloc_nearest_color (f
, cmap
, color
)
3961 Display
*display
= FRAME_X_DISPLAY (f
);
3962 Screen
*screen
= FRAME_X_SCREEN (f
);
3965 gamma_correct (f
, color
);
3966 rc
= XAllocColor (display
, cmap
, color
);
3969 /* If we got to this point, the colormap is full, so we're going
3970 to try to get the next closest color. The algorithm used is
3971 a least-squares matching, which is what X uses for closest
3972 color matching with StaticColor visuals. */
3974 unsigned long nearest_delta
= ~0;
3975 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3976 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3978 for (i
= 0; i
< ncells
; ++i
)
3980 XQueryColors (display
, cmap
, cells
, ncells
);
3982 for (nearest
= i
= 0; i
< ncells
; ++i
)
3984 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3985 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3986 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3987 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3989 if (delta
< nearest_delta
)
3992 nearest_delta
= delta
;
3996 color
->red
= cells
[nearest
].red
;
3997 color
->green
= cells
[nearest
].green
;
3998 color
->blue
= cells
[nearest
].blue
;
3999 rc
= XAllocColor (display
, cmap
, color
);
4002 #ifdef DEBUG_X_COLORS
4004 register_color (color
->pixel
);
4005 #endif /* DEBUG_X_COLORS */
4011 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
4012 It's necessary to do this instead of just using PIXEL directly to
4013 get color reference counts right. */
4016 x_copy_color (f
, pixel
)
4018 unsigned long pixel
;
4022 color
.pixel
= pixel
;
4024 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4025 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
4027 #ifdef DEBUG_X_COLORS
4028 register_color (pixel
);
4034 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
4035 It's necessary to do this instead of just using PIXEL directly to
4036 get color reference counts right. */
4039 x_copy_dpy_color (dpy
, cmap
, pixel
)
4042 unsigned long pixel
;
4046 color
.pixel
= pixel
;
4048 XQueryColor (dpy
, cmap
, &color
);
4049 XAllocColor (dpy
, cmap
, &color
);
4051 #ifdef DEBUG_X_COLORS
4052 register_color (pixel
);
4057 #endif /* MAC_TODO */
4059 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
4060 or DELTA. Try a color with RGB values multiplied by FACTOR first.
4061 If this produces the same color as COLOR, try a color where all RGB
4062 values have DELTA added. Return the allocated color in *COLOR.
4063 DISPLAY is the X display, CMAP is the colormap to operate on.
4064 Value is non-zero if successful. */
4067 mac_alloc_lighter_color (f
, color
, factor
, delta
)
4069 unsigned long *color
;
4075 /* Change RGB values by specified FACTOR. Avoid overflow! */
4076 xassert (factor
>= 0);
4077 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
4078 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
4079 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
4081 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
4082 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
4083 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
4085 /* MAC_TODO: Map to palette and retry with delta if same? */
4086 /* MAC_TODO: Free colors (if using palette)? */
4097 /* Set up the foreground color for drawing relief lines of glyph
4098 string S. RELIEF is a pointer to a struct relief containing the GC
4099 with which lines will be drawn. Use a color that is FACTOR or
4100 DELTA lighter or darker than the relief's background which is found
4101 in S->f->output_data.x->relief_background. If such a color cannot
4102 be allocated, use DEFAULT_PIXEL, instead. */
4105 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
4107 struct relief
*relief
;
4110 unsigned long default_pixel
;
4113 struct mac_output
*di
= f
->output_data
.mac
;
4114 unsigned long mask
= GCForeground
;
4115 unsigned long pixel
;
4116 unsigned long background
= di
->relief_background
;
4117 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4119 /* MAC_TODO: Free colors (if using palette)? */
4121 /* Allocate new color. */
4122 xgcv
.foreground
= default_pixel
;
4124 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
4126 relief
->allocated_p
= 1;
4127 xgcv
.foreground
= relief
->pixel
= pixel
;
4130 if (relief
->gc
== 0)
4132 #if 0 /* MAC_TODO: stipple */
4133 xgcv
.stipple
= dpyinfo
->gray
;
4136 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
4139 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
4143 /* Set up colors for the relief lines around glyph string S. */
4146 x_setup_relief_colors (s
)
4147 struct glyph_string
*s
;
4149 struct mac_output
*di
= s
->f
->output_data
.mac
;
4150 unsigned long color
;
4152 if (s
->face
->use_box_color_for_shadows_p
)
4153 color
= s
->face
->box_color
;
4158 /* Get the background color of the face. */
4159 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
4160 color
= xgcv
.background
;
4163 if (di
->white_relief
.gc
== 0
4164 || color
!= di
->relief_background
)
4166 di
->relief_background
= color
;
4167 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
4168 WHITE_PIX_DEFAULT (s
->f
));
4169 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4170 BLACK_PIX_DEFAULT (s
->f
));
4175 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4176 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4177 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4178 relief. LEFT_P non-zero means draw a relief on the left side of
4179 the rectangle. RIGHT_P non-zero means draw a relief on the right
4180 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4184 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4185 raised_p
, left_p
, right_p
, clip_rect
)
4187 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4194 gc
= f
->output_data
.mac
->white_relief
.gc
;
4196 gc
= f
->output_data
.mac
->black_relief
.gc
;
4197 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4200 for (i
= 0; i
< width
; ++i
)
4201 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4202 left_x
+ i
* left_p
, top_y
+ i
,
4203 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4207 for (i
= 0; i
< width
; ++i
)
4208 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4209 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4211 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4213 gc
= f
->output_data
.mac
->black_relief
.gc
;
4215 gc
= f
->output_data
.mac
->white_relief
.gc
;
4216 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4220 for (i
= 0; i
< width
; ++i
)
4221 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4222 left_x
+ i
* left_p
, bottom_y
- i
,
4223 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4227 for (i
= 0; i
< width
; ++i
)
4228 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4229 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4231 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4235 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4236 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4237 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4238 left side of the rectangle. RIGHT_P non-zero means draw a line
4239 on the right side of the rectangle. CLIP_RECT is the clipping
4240 rectangle to use when drawing. */
4243 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4244 left_p
, right_p
, clip_rect
)
4245 struct glyph_string
*s
;
4246 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4251 xgcv
.foreground
= s
->face
->box_color
;
4252 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4255 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4256 left_x
, top_y
, right_x
- left_x
, width
);
4260 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4261 left_x
, top_y
, width
, bottom_y
- top_y
);
4264 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4265 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4269 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4270 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4272 mac_reset_clipping (s
->display
, s
->window
);
4276 /* Draw a box around glyph string S. */
4279 x_draw_glyph_string_box (s
)
4280 struct glyph_string
*s
;
4282 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4283 int left_p
, right_p
;
4284 struct glyph
*last_glyph
;
4287 last_x
= window_box_right (s
->w
, s
->area
);
4288 if (s
->row
->full_width_p
4289 && !s
->w
->pseudo_window_p
)
4291 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4292 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4293 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4296 /* The glyph that may have a right box line. */
4297 last_glyph
= (s
->cmp
|| s
->img
4299 : s
->first_glyph
+ s
->nchars
- 1);
4301 width
= abs (s
->face
->box_line_width
);
4302 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4304 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
4306 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4308 bottom_y
= top_y
+ s
->height
- 1;
4310 left_p
= (s
->first_glyph
->left_box_line_p
4311 || (s
->hl
== DRAW_MOUSE_FACE
4313 || s
->prev
->hl
!= s
->hl
)));
4314 right_p
= (last_glyph
->right_box_line_p
4315 || (s
->hl
== DRAW_MOUSE_FACE
4317 || s
->next
->hl
!= s
->hl
)));
4319 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4321 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4322 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4323 left_p
, right_p
, &clip_rect
);
4326 x_setup_relief_colors (s
);
4327 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4328 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4333 /* Draw foreground of image glyph string S. */
4336 x_draw_image_foreground (s
)
4337 struct glyph_string
*s
;
4340 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4342 /* If first glyph of S has a left box line, start drawing it to the
4343 right of that line. */
4344 if (s
->face
->box
!= FACE_NO_BOX
4345 && s
->first_glyph
->left_box_line_p
)
4346 x
= s
->x
+ abs (s
->face
->box_line_width
);
4350 /* If there is a margin around the image, adjust x- and y-position
4352 x
+= s
->img
->hmargin
;
4353 y
+= s
->img
->vmargin
;
4357 #if 0 /* MAC_TODO: image mask */
4360 /* We can't set both a clip mask and use XSetClipRectangles
4361 because the latter also sets a clip mask. We also can't
4362 trust on the shape extension to be available
4363 (XShapeCombineRegion). So, compute the rectangle to draw
4365 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4368 XRectangle clip_rect
, image_rect
, r
;
4370 xgcv
.clip_mask
= s
->img
->mask
;
4371 xgcv
.clip_x_origin
= x
;
4372 xgcv
.clip_y_origin
= y
;
4373 xgcv
.function
= GXcopy
;
4374 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4376 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4379 image_rect
.width
= s
->img
->width
;
4380 image_rect
.height
= s
->img
->height
;
4381 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4382 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4383 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4386 #endif /* MAC_TODO */
4388 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4389 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4391 /* When the image has a mask, we can expect that at
4392 least part of a mouse highlight or a block cursor will
4393 be visible. If the image doesn't have a mask, make
4394 a block cursor visible by drawing a rectangle around
4395 the image. I believe it's looking better if we do
4396 nothing here for mouse-face. */
4397 if (s
->hl
== DRAW_CURSOR
)
4398 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4399 s
->img
->width
- 1, s
->img
->height
- 1);
4403 /* Draw a rectangle if image could not be loaded. */
4404 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4405 s
->img
->width
- 1, s
->img
->height
- 1);
4410 /* Draw a relief around the image glyph string S. */
4413 x_draw_image_relief (s
)
4414 struct glyph_string
*s
;
4416 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4419 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4421 /* If first glyph of S has a left box line, start drawing it to the
4422 right of that line. */
4423 if (s
->face
->box
!= FACE_NO_BOX
4424 && s
->first_glyph
->left_box_line_p
)
4425 x
= s
->x
+ abs (s
->face
->box_line_width
);
4429 /* If there is a margin around the image, adjust x- and y-position
4431 x
+= s
->img
->hmargin
;
4432 y
+= s
->img
->vmargin
;
4434 if (s
->hl
== DRAW_IMAGE_SUNKEN
4435 || s
->hl
== DRAW_IMAGE_RAISED
)
4437 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
4438 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4442 thick
= abs (s
->img
->relief
);
4443 raised_p
= s
->img
->relief
> 0;
4448 x1
= x
+ s
->img
->width
+ thick
- 1;
4449 y1
= y
+ s
->img
->height
+ thick
- 1;
4451 x_setup_relief_colors (s
);
4452 x_get_glyph_string_clip_rect (s
, &r
);
4453 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4457 /* Draw the foreground of image glyph string S to PIXMAP. */
4460 x_draw_image_foreground_1 (s
, pixmap
)
4461 struct glyph_string
*s
;
4465 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4467 /* If first glyph of S has a left box line, start drawing it to the
4468 right of that line. */
4469 if (s
->face
->box
!= FACE_NO_BOX
4470 && s
->first_glyph
->left_box_line_p
)
4471 x
= abs (s
->face
->box_line_width
);
4475 /* If there is a margin around the image, adjust x- and y-position
4477 x
+= s
->img
->hmargin
;
4478 y
+= s
->img
->vmargin
;
4482 #if 0 /* MAC_TODO: image mask */
4485 /* We can't set both a clip mask and use XSetClipRectangles
4486 because the latter also sets a clip mask. We also can't
4487 trust on the shape extension to be available
4488 (XShapeCombineRegion). So, compute the rectangle to draw
4490 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4494 xgcv
.clip_mask
= s
->img
->mask
;
4495 xgcv
.clip_x_origin
= x
;
4496 xgcv
.clip_y_origin
= y
;
4497 xgcv
.function
= GXcopy
;
4498 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4500 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4501 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4502 XSetClipMask (s
->display
, s
->gc
, None
);
4505 #endif /* MAC_TODO */
4507 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4508 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4510 /* When the image has a mask, we can expect that at
4511 least part of a mouse highlight or a block cursor will
4512 be visible. If the image doesn't have a mask, make
4513 a block cursor visible by drawing a rectangle around
4514 the image. I believe it's looking better if we do
4515 nothing here for mouse-face. */
4516 if (s
->hl
== DRAW_CURSOR
)
4517 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4518 s
->img
->width
- 1, s
->img
->height
- 1);
4522 /* Draw a rectangle if image could not be loaded. */
4523 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4524 s
->img
->width
- 1, s
->img
->height
- 1);
4528 /* Draw part of the background of glyph string S. X, Y, W, and H
4529 give the rectangle to draw. */
4532 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4533 struct glyph_string
*s
;
4536 #if 0 /* MAC_TODO: stipple */
4539 /* Fill background with a stipple pattern. */
4540 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4541 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4542 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4545 #endif /* MAC_TODO */
4546 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4550 /* Draw image glyph string S.
4553 s->x +-------------------------
4556 | +-------------------------
4559 | | +-------------------
4565 x_draw_image_glyph_string (s
)
4566 struct glyph_string
*s
;
4569 int box_line_hwidth
= abs (s
->face
->box_line_width
);
4570 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
4574 height
= s
->height
- 2 * box_line_vwidth
;
4576 /* Fill background with face under the image. Do it only if row is
4577 taller than image or if image has a clip mask to reduce
4579 s
->stippled_p
= s
->face
->stipple
!= 0;
4580 if (height
> s
->img
->height
4583 #if 0 /* TODO: image mask */
4586 || s
->img
->pixmap
== 0
4587 || s
->width
!= s
->background_width
)
4589 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
4590 x
= s
->x
+ box_line_hwidth
;
4594 y
= s
->y
+ box_line_vwidth
;
4595 #if 0 /* TODO: image mask */
4598 /* Create a pixmap as large as the glyph string. Fill it
4599 with the background color. Copy the image to it, using
4600 its mask. Copy the temporary pixmap to the display. */
4601 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4602 int depth
= DefaultDepthOfScreen (screen
);
4604 /* Create a pixmap as large as the glyph string. */
4605 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4606 s
->background_width
,
4609 /* Don't clip in the following because we're working on the
4611 XSetClipMask (s
->display
, s
->gc
, None
);
4613 /* Fill the pixmap with the background color/stipple. */
4616 /* Fill background with a stipple pattern. */
4617 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4618 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4619 0, 0, s
->background_width
, s
->height
);
4620 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4625 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4627 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4628 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4629 0, 0, s
->background_width
, s
->height
);
4630 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4635 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4637 s
->background_filled_p
= 1;
4640 /* Draw the foreground. */
4643 x_draw_image_foreground_1 (s
, pixmap
);
4644 x_set_glyph_string_clipping (s
);
4645 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4646 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4647 mac_reset_clipping (s
->display
, s
->window
);
4648 XFreePixmap (s
->display
, pixmap
);
4651 x_draw_image_foreground (s
);
4653 /* If we must draw a relief around the image, do it. */
4655 || s
->hl
== DRAW_IMAGE_RAISED
4656 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4657 x_draw_image_relief (s
);
4661 /* Draw stretch glyph string S. */
4664 x_draw_stretch_glyph_string (s
)
4665 struct glyph_string
*s
;
4667 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4668 s
->stippled_p
= s
->face
->stipple
!= 0;
4670 if (s
->hl
== DRAW_CURSOR
4671 && !x_stretch_cursor_p
)
4673 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4674 as wide as the stretch glyph. */
4675 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4678 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4680 /* Clear rest using the GC of the original non-cursor face. */
4681 if (width
< s
->background_width
)
4683 GC gc
= s
->face
->gc
;
4684 int x
= s
->x
+ width
, y
= s
->y
;
4685 int w
= s
->background_width
- width
, h
= s
->height
;
4688 if (s
->row
->mouse_face_p
4689 && cursor_in_mouse_face_p (s
->w
))
4691 x_set_mouse_face_gc (s
);
4697 x_get_glyph_string_clip_rect (s
, &r
);
4698 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4700 #if 0 /* MAC_TODO: stipple */
4701 if (s
->face
->stipple
)
4703 /* Fill background with a stipple pattern. */
4704 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4705 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4706 XSetFillStyle (s
->display
, gc
, FillSolid
);
4709 #endif /* MAC_TODO */
4712 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4713 XSetForeground (s
->display
, gc
, xgcv
.background
);
4714 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4715 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4718 mac_reset_clipping (s
->display
, s
->window
);
4721 else if (!s
->background_filled_p
)
4722 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4725 s
->background_filled_p
= 1;
4729 /* Draw glyph string S. */
4732 x_draw_glyph_string (s
)
4733 struct glyph_string
*s
;
4735 int relief_drawn_p
= 0;
4737 /* If S draws into the background of its successor, draw the
4738 background of the successor first so that S can draw into it.
4739 This makes S->next use XDrawString instead of XDrawImageString. */
4740 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4742 xassert (s
->next
->img
== NULL
);
4743 x_set_glyph_string_gc (s
->next
);
4744 x_set_glyph_string_clipping (s
->next
);
4745 x_draw_glyph_string_background (s
->next
, 1);
4749 /* Set up S->gc, set clipping and draw S. */
4750 x_set_glyph_string_gc (s
);
4752 /* Draw relief (if any) in advance for char/composition so that the
4753 glyph string can be drawn over it. */
4754 if (!s
->for_overlaps_p
4755 && s
->face
->box
!= FACE_NO_BOX
4756 && (s
->first_glyph
->type
== CHAR_GLYPH
4757 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
4760 x_set_glyph_string_clipping (s
);
4761 x_draw_glyph_string_background (s
, 1);
4762 x_draw_glyph_string_box (s
);
4763 x_set_glyph_string_clipping (s
);
4767 x_set_glyph_string_clipping (s
);
4769 switch (s
->first_glyph
->type
)
4772 x_draw_image_glyph_string (s
);
4776 x_draw_stretch_glyph_string (s
);
4780 if (s
->for_overlaps_p
)
4781 s
->background_filled_p
= 1;
4783 x_draw_glyph_string_background (s
, 0);
4784 x_draw_glyph_string_foreground (s
);
4787 case COMPOSITE_GLYPH
:
4788 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4789 s
->background_filled_p
= 1;
4791 x_draw_glyph_string_background (s
, 1);
4792 x_draw_composite_glyph_string_foreground (s
);
4799 if (!s
->for_overlaps_p
)
4801 /* Draw underline. */
4802 if (s
->face
->underline_p
)
4804 unsigned long h
= 1;
4805 unsigned long dy
= s
->height
- h
;
4807 if (s
->face
->underline_defaulted_p
)
4808 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4813 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4814 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4815 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4817 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4821 /* Draw overline. */
4822 if (s
->face
->overline_p
)
4824 unsigned long dy
= 0, h
= 1;
4826 if (s
->face
->overline_color_defaulted_p
)
4827 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4832 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4833 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4834 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4836 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4840 /* Draw strike-through. */
4841 if (s
->face
->strike_through_p
)
4843 unsigned long h
= 1;
4844 unsigned long dy
= (s
->height
- h
) / 2;
4846 if (s
->face
->strike_through_color_defaulted_p
)
4847 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4852 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4853 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4854 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4856 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4861 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
4862 x_draw_glyph_string_box (s
);
4865 /* Reset clipping. */
4866 mac_reset_clipping (s
->display
, s
->window
);
4870 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4871 struct face
**, int));
4874 /* Fill glyph string S with composition components specified by S->cmp.
4876 FACES is an array of faces for all components of this composition.
4877 S->gidx is the index of the first component for S.
4878 OVERLAPS_P non-zero means S should draw the foreground only, and
4879 use its physical height for clipping.
4881 Value is the index of a component not in S. */
4884 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4885 struct glyph_string
*s
;
4886 struct face
**faces
;
4893 s
->for_overlaps_p
= overlaps_p
;
4895 s
->face
= faces
[s
->gidx
];
4896 s
->font
= s
->face
->font
;
4897 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4899 /* For all glyphs of this composition, starting at the offset
4900 S->gidx, until we reach the end of the definition or encounter a
4901 glyph that requires the different face, add it to S. */
4903 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4906 /* All glyph strings for the same composition has the same width,
4907 i.e. the width set for the first component of the composition. */
4909 s
->width
= s
->first_glyph
->pixel_width
;
4911 /* If the specified font could not be loaded, use the frame's
4912 default font, but record the fact that we couldn't load it in
4913 the glyph string so that we can draw rectangles for the
4914 characters of the glyph string. */
4915 if (s
->font
== NULL
)
4917 s
->font_not_found_p
= 1;
4918 s
->font
= FRAME_FONT (s
->f
);
4921 /* Adjust base line for subscript/superscript text. */
4922 s
->ybase
+= s
->first_glyph
->voffset
;
4924 xassert (s
->face
&& s
->face
->gc
);
4926 /* This glyph string must always be drawn with 16-bit functions. */
4929 return s
->gidx
+ s
->nchars
;
4933 /* Fill glyph string S from a sequence of character glyphs.
4935 FACE_ID is the face id of the string. START is the index of the
4936 first glyph to consider, END is the index of the last + 1.
4937 OVERLAPS_P non-zero means S should draw the foreground only, and
4938 use its physical height for clipping.
4940 Value is the index of the first glyph not in S. */
4943 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4944 struct glyph_string
*s
;
4946 int start
, end
, overlaps_p
;
4948 struct glyph
*glyph
, *last
;
4950 int glyph_not_available_p
;
4952 xassert (s
->f
== XFRAME (s
->w
->frame
));
4953 xassert (s
->nchars
== 0);
4954 xassert (start
>= 0 && end
> start
);
4956 s
->for_overlaps_p
= overlaps_p
;
4957 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4958 last
= s
->row
->glyphs
[s
->area
] + end
;
4959 voffset
= glyph
->voffset
;
4961 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4964 && glyph
->type
== CHAR_GLYPH
4965 && glyph
->voffset
== voffset
4966 /* Same face id implies same font, nowadays. */
4967 && glyph
->face_id
== face_id
4968 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4972 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4973 s
->char2b
+ s
->nchars
,
4975 s
->two_byte_p
= two_byte_p
;
4977 xassert (s
->nchars
<= end
- start
);
4978 s
->width
+= glyph
->pixel_width
;
4982 s
->font
= s
->face
->font
;
4983 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4985 /* If the specified font could not be loaded, use the frame's font,
4986 but record the fact that we couldn't load it in
4987 S->font_not_found_p so that we can draw rectangles for the
4988 characters of the glyph string. */
4989 if (s
->font
== NULL
|| glyph_not_available_p
)
4991 s
->font_not_found_p
= 1;
4992 s
->font
= FRAME_FONT (s
->f
);
4995 /* Adjust base line for subscript/superscript text. */
4996 s
->ybase
+= voffset
;
4998 xassert (s
->face
&& s
->face
->gc
);
4999 return glyph
- s
->row
->glyphs
[s
->area
];
5003 /* Fill glyph string S from image glyph S->first_glyph. */
5006 x_fill_image_glyph_string (s
)
5007 struct glyph_string
*s
;
5009 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
5010 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
5012 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
5013 s
->font
= s
->face
->font
;
5014 s
->width
= s
->first_glyph
->pixel_width
;
5016 /* Adjust base line for subscript/superscript text. */
5017 s
->ybase
+= s
->first_glyph
->voffset
;
5021 /* Fill glyph string S from a sequence of stretch glyphs.
5023 ROW is the glyph row in which the glyphs are found, AREA is the
5024 area within the row. START is the index of the first glyph to
5025 consider, END is the index of the last + 1.
5027 Value is the index of the first glyph not in S. */
5030 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
5031 struct glyph_string
*s
;
5032 struct glyph_row
*row
;
5033 enum glyph_row_area area
;
5036 struct glyph
*glyph
, *last
;
5037 int voffset
, face_id
;
5039 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
5041 glyph
= s
->row
->glyphs
[s
->area
] + start
;
5042 last
= s
->row
->glyphs
[s
->area
] + end
;
5043 face_id
= glyph
->face_id
;
5044 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
5045 s
->font
= s
->face
->font
;
5046 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
5047 s
->width
= glyph
->pixel_width
;
5048 voffset
= glyph
->voffset
;
5052 && glyph
->type
== STRETCH_GLYPH
5053 && glyph
->voffset
== voffset
5054 && glyph
->face_id
== face_id
);
5056 s
->width
+= glyph
->pixel_width
;
5058 /* Adjust base line for subscript/superscript text. */
5059 s
->ybase
+= voffset
;
5062 return glyph
- s
->row
->glyphs
[s
->area
];
5066 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
5067 of XChar2b structures for S; it can't be allocated in
5068 x_init_glyph_string because it must be allocated via `alloca'. W
5069 is the window on which S is drawn. ROW and AREA are the glyph row
5070 and area within the row from which S is constructed. START is the
5071 index of the first glyph structure covered by S. HL is a
5072 face-override for drawing S. */
5075 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
5076 struct glyph_string
*s
;
5079 struct glyph_row
*row
;
5080 enum glyph_row_area area
;
5082 enum draw_glyphs_face hl
;
5084 bzero (s
, sizeof *s
);
5086 s
->f
= XFRAME (w
->frame
);
5087 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
5088 s
->window
= FRAME_MAC_WINDOW (s
->f
);
5093 s
->first_glyph
= row
->glyphs
[area
] + start
;
5094 s
->height
= row
->height
;
5095 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5097 /* Display the internal border below the tool-bar window. */
5098 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
5099 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
5101 s
->ybase
= s
->y
+ row
->ascent
;
5105 /* Set background width of glyph string S. START is the index of the
5106 first glyph following S. LAST_X is the right-most x-position + 1
5107 in the drawing area. */
5110 x_set_glyph_string_background_width (s
, start
, last_x
)
5111 struct glyph_string
*s
;
5115 /* If the face of this glyph string has to be drawn to the end of
5116 the drawing area, set S->extends_to_end_of_line_p. */
5117 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
5119 if (start
== s
->row
->used
[s
->area
]
5120 && s
->area
== TEXT_AREA
5121 && ((s
->hl
== DRAW_NORMAL_TEXT
5122 && (s
->row
->fill_line_p
5123 || s
->face
->background
!= default_face
->background
5124 || s
->face
->stipple
!= default_face
->stipple
5125 || s
->row
->mouse_face_p
))
5126 || s
->hl
== DRAW_MOUSE_FACE
5127 || ((s
->hl
== DRAW_IMAGE_RAISED
|| s
->hl
== DRAW_IMAGE_SUNKEN
)
5128 && s
->row
->fill_line_p
)))
5129 s
->extends_to_end_of_line_p
= 1;
5131 /* If S extends its face to the end of the line, set its
5132 background_width to the distance to the right edge of the drawing
5134 if (s
->extends_to_end_of_line_p
)
5135 s
->background_width
= last_x
- s
->x
+ 1;
5137 s
->background_width
= s
->width
;
5141 /* Add a glyph string for a stretch glyph to the list of strings
5142 between HEAD and TAIL. START is the index of the stretch glyph in
5143 row area AREA of glyph row ROW. END is the index of the last glyph
5144 in that glyph row area. X is the current output position assigned
5145 to the new glyph string constructed. HL overrides that face of the
5146 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5147 is the right-most x-position of the drawing area. */
5149 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
5150 and below -- keep them on one line. */
5151 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5154 s = (struct glyph_string *) alloca (sizeof *s); \
5155 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5156 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
5157 x_append_glyph_string (&HEAD, &TAIL, s); \
5163 /* Add a glyph string for an image glyph to the list of strings
5164 between HEAD and TAIL. START is the index of the image glyph in
5165 row area AREA of glyph row ROW. END is the index of the last glyph
5166 in that glyph row area. X is the current output position assigned
5167 to the new glyph string constructed. HL overrides that face of the
5168 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
5169 is the right-most x-position of the drawing area. */
5171 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
5174 s = (struct glyph_string *) alloca (sizeof *s); \
5175 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
5176 x_fill_image_glyph_string (s); \
5177 x_append_glyph_string (&HEAD, &TAIL, s); \
5184 /* Add a glyph string for a sequence of character glyphs to the list
5185 of strings between HEAD and TAIL. START is the index of the first
5186 glyph in row area AREA of glyph row ROW that is part of the new
5187 glyph string. END is the index of the last glyph in that glyph row
5188 area. X is the current output position assigned to the new glyph
5189 string constructed. HL overrides that face of the glyph; e.g. it
5190 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
5191 right-most x-position of the drawing area. */
5193 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5199 c = (ROW)->glyphs[AREA][START].u.ch; \
5200 face_id = (ROW)->glyphs[AREA][START].face_id; \
5202 s = (struct glyph_string *) alloca (sizeof *s); \
5203 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5204 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5205 x_append_glyph_string (&HEAD, &TAIL, s); \
5207 START = x_fill_glyph_string (s, face_id, START, END, \
5213 /* Add a glyph string for a composite sequence to the list of strings
5214 between HEAD and TAIL. START is the index of the first glyph in
5215 row area AREA of glyph row ROW that is part of the new glyph
5216 string. END is the index of the last glyph in that glyph row area.
5217 X is the current output position assigned to the new glyph string
5218 constructed. HL overrides that face of the glyph; e.g. it is
5219 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5220 x-position of the drawing area. */
5222 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5224 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5225 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5226 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5227 struct composition *cmp = composition_table[cmp_id]; \
5228 int glyph_len = cmp->glyph_len; \
5230 struct face **faces; \
5231 struct glyph_string *first_s = NULL; \
5234 base_face = base_face->ascii_face; \
5235 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5236 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5237 /* At first, fill in `char2b' and `faces'. */ \
5238 for (n = 0; n < glyph_len; n++) \
5240 int c = COMPOSITION_GLYPH (cmp, n); \
5241 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5242 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5243 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5244 this_face_id, char2b + n, 1); \
5247 /* Make glyph_strings for each glyph sequence that is drawable by \
5248 the same face, and append them to HEAD/TAIL. */ \
5249 for (n = 0; n < cmp->glyph_len;) \
5251 s = (struct glyph_string *) alloca (sizeof *s); \
5252 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5253 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5261 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5269 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5270 of AREA of glyph row ROW on window W between indices START and END.
5271 HL overrides the face for drawing glyph strings, e.g. it is
5272 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5273 x-positions of the drawing area.
5275 This is an ugly monster macro construct because we must use alloca
5276 to allocate glyph strings (because x_draw_glyphs can be called
5279 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5282 HEAD = TAIL = NULL; \
5283 while (START < END) \
5285 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5286 switch (first_glyph->type) \
5289 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5290 TAIL, HL, X, LAST_X, \
5294 case COMPOSITE_GLYPH: \
5295 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5296 HEAD, TAIL, HL, X, LAST_X,\
5300 case STRETCH_GLYPH: \
5301 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5302 HEAD, TAIL, HL, X, LAST_X); \
5306 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5307 TAIL, HL, X, LAST_X); \
5314 x_set_glyph_string_background_width (s, START, LAST_X); \
5321 /* Draw glyphs between START and END in AREA of ROW on window W,
5322 starting at x-position X. X is relative to AREA in W. HL is a
5323 face-override with the following meaning:
5325 DRAW_NORMAL_TEXT draw normally
5326 DRAW_CURSOR draw in cursor face
5327 DRAW_MOUSE_FACE draw in mouse face.
5328 DRAW_INVERSE_VIDEO draw in mode line face
5329 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5330 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5332 If OVERLAPS_P is non-zero, draw only the foreground of characters
5333 and clip to the physical height of ROW.
5335 Value is the x-position reached, relative to AREA of W. */
5338 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, overlaps_p
)
5341 struct glyph_row
*row
;
5342 enum glyph_row_area area
;
5344 enum draw_glyphs_face hl
;
5347 struct glyph_string
*head
, *tail
;
5348 struct glyph_string
*s
;
5349 int last_x
, area_width
;
5353 /* Let's rather be paranoid than getting a SEGV. */
5354 end
= min (end
, row
->used
[area
]);
5355 start
= max (0, start
);
5356 start
= min (end
, start
);
5358 /* Translate X to frame coordinates. Set last_x to the right
5359 end of the drawing area. */
5360 if (row
->full_width_p
)
5362 /* X is relative to the left edge of W, without scroll bars
5364 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5365 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5368 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5369 last_x
= window_left_x
+ area_width
;
5371 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5373 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5374 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5380 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5381 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5385 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5386 area_width
= window_box_width (w
, area
);
5387 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5390 /* Build a doubly-linked list of glyph_string structures between
5391 head and tail from what we have to draw. Note that the macro
5392 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5393 the reason we use a separate variable `i'. */
5395 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5398 x_reached
= tail
->x
+ tail
->background_width
;
5402 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5403 the row, redraw some glyphs in front or following the glyph
5404 strings built above. */
5405 if (head
&& !overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5408 struct glyph_string
*h
, *t
;
5410 /* Compute overhangs for all glyph strings. */
5411 for (s
= head
; s
; s
= s
->next
)
5412 x_compute_glyph_string_overhangs (s
);
5414 /* Prepend glyph strings for glyphs in front of the first glyph
5415 string that are overwritten because of the first glyph
5416 string's left overhang. The background of all strings
5417 prepended must be drawn because the first glyph string
5419 i
= x_left_overwritten (head
);
5423 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5424 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5427 x_compute_overhangs_and_x (t
, head
->x
, 1);
5428 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5431 /* Prepend glyph strings for glyphs in front of the first glyph
5432 string that overwrite that glyph string because of their
5433 right overhang. For these strings, only the foreground must
5434 be drawn, because it draws over the glyph string at `head'.
5435 The background must not be drawn because this would overwrite
5436 right overhangs of preceding glyphs for which no glyph
5438 i
= x_left_overwriting (head
);
5441 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5442 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5444 for (s
= h
; s
; s
= s
->next
)
5445 s
->background_filled_p
= 1;
5446 x_compute_overhangs_and_x (t
, head
->x
, 1);
5447 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5450 /* Append glyphs strings for glyphs following the last glyph
5451 string tail that are overwritten by tail. The background of
5452 these strings has to be drawn because tail's foreground draws
5454 i
= x_right_overwritten (tail
);
5457 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5458 DRAW_NORMAL_TEXT
, x
, last_x
,
5460 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5461 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5464 /* Append glyph strings for glyphs following the last glyph
5465 string tail that overwrite tail. The foreground of such
5466 glyphs has to be drawn because it writes into the background
5467 of tail. The background must not be drawn because it could
5468 paint over the foreground of following glyphs. */
5469 i
= x_right_overwriting (tail
);
5472 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5473 DRAW_NORMAL_TEXT
, x
, last_x
,
5475 for (s
= h
; s
; s
= s
->next
)
5476 s
->background_filled_p
= 1;
5477 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5478 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5482 /* Draw all strings. */
5483 for (s
= head
; s
; s
= s
->next
)
5484 x_draw_glyph_string (s
);
5486 if (area
== TEXT_AREA
5487 && !row
->full_width_p
5488 /* When drawing overlapping rows, only the glyph strings'
5489 foreground is drawn, which doesn't erase a cursor
5493 int x0
= head
? head
->x
: x
;
5494 int x1
= tail
? tail
->x
+ tail
->background_width
: x
;
5496 x0
= FRAME_TO_WINDOW_PIXEL_X (w
, x0
);
5497 x1
= FRAME_TO_WINDOW_PIXEL_X (w
, x1
);
5499 if (!row
->full_width_p
&& XFASTINT (w
->left_margin_width
) != 0)
5501 int left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
5502 x0
-= left_area_width
;
5503 x1
-= left_area_width
;
5506 notice_overwritten_cursor (w
, area
, x0
, x1
,
5507 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
5510 /* Value is the x-position up to which drawn, relative to AREA of W.
5511 This doesn't include parts drawn because of overhangs. */
5512 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5513 if (!row
->full_width_p
)
5515 if (area
> LEFT_MARGIN_AREA
)
5516 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5517 if (area
> TEXT_AREA
)
5518 x_reached
-= window_box_width (w
, TEXT_AREA
);
5525 /* Fix the display of area AREA of overlapping row ROW in window W. */
5528 x_fix_overlapping_area (w
, row
, area
)
5530 struct glyph_row
*row
;
5531 enum glyph_row_area area
;
5537 if (area
== LEFT_MARGIN_AREA
)
5539 else if (area
== TEXT_AREA
)
5540 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5542 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5543 + window_box_width (w
, TEXT_AREA
));
5545 for (i
= 0; i
< row
->used
[area
];)
5547 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5549 int start
= i
, start_x
= x
;
5553 x
+= row
->glyphs
[area
][i
].pixel_width
;
5556 while (i
< row
->used
[area
]
5557 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5559 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5560 DRAW_NORMAL_TEXT
, 1);
5564 x
+= row
->glyphs
[area
][i
].pixel_width
;
5573 /* Output LEN glyphs starting at START at the nominal cursor position.
5574 Advance the nominal cursor over the text. The global variable
5575 updated_window contains the window being updated, updated_row is
5576 the glyph row being updated, and updated_area is the area of that
5577 row being updated. */
5580 x_write_glyphs (start
, len
)
5581 struct glyph
*start
;
5586 xassert (updated_window
&& updated_row
);
5591 hpos
= start
- updated_row
->glyphs
[updated_area
];
5592 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5593 updated_row
, updated_area
,
5595 DRAW_NORMAL_TEXT
, 0);
5599 /* Advance the output cursor. */
5600 output_cursor
.hpos
+= len
;
5601 output_cursor
.x
= x
;
5605 /* Insert LEN glyphs from START at the nominal cursor position. */
5608 x_insert_glyphs (start
, len
)
5609 struct glyph
*start
;
5614 int line_height
, shift_by_width
, shifted_region_width
;
5615 struct glyph_row
*row
;
5616 struct glyph
*glyph
;
5617 int frame_x
, frame_y
, hpos
;
5619 xassert (updated_window
&& updated_row
);
5622 f
= XFRAME (WINDOW_FRAME (w
));
5624 /* Get the height of the line we are in. */
5626 line_height
= row
->height
;
5628 /* Get the width of the glyphs to insert. */
5630 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5631 shift_by_width
+= glyph
->pixel_width
;
5633 /* Get the width of the region to shift right. */
5634 shifted_region_width
= (window_box_width (w
, updated_area
)
5639 frame_x
= window_box_left (w
, updated_area
) + output_cursor
.x
;
5640 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5642 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5643 f
->output_data
.mac
->normal_gc
,
5645 shifted_region_width
, line_height
,
5646 frame_x
+ shift_by_width
, frame_y
);
5648 /* Write the glyphs. */
5649 hpos
= start
- row
->glyphs
[updated_area
];
5650 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5651 DRAW_NORMAL_TEXT
, 0);
5653 /* Advance the output cursor. */
5654 output_cursor
.hpos
+= len
;
5655 output_cursor
.x
+= shift_by_width
;
5660 /* Delete N glyphs at the nominal cursor position. Not implemented
5671 /* Erase the current text line from the nominal cursor position
5672 (inclusive) to pixel column TO_X (exclusive). The idea is that
5673 everything from TO_X onward is already erased.
5675 TO_X is a pixel position relative to updated_area of
5676 updated_window. TO_X == -1 means clear to the end of this area. */
5679 x_clear_end_of_line (to_x
)
5683 struct window
*w
= updated_window
;
5684 int max_x
, min_y
, max_y
;
5685 int from_x
, from_y
, to_y
;
5687 xassert (updated_window
&& updated_row
);
5688 f
= XFRAME (w
->frame
);
5690 if (updated_row
->full_width_p
)
5692 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5693 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5694 && !w
->pseudo_window_p
)
5695 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5698 max_x
= window_box_width (w
, updated_area
);
5699 max_y
= window_text_bottom_y (w
);
5701 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5702 of window. For TO_X > 0, truncate to end of drawing area. */
5708 to_x
= min (to_x
, max_x
);
5710 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5712 /* Notice if the cursor will be cleared by this operation. */
5713 if (!updated_row
->full_width_p
)
5714 notice_overwritten_cursor (w
, updated_area
,
5715 output_cursor
.x
, -1,
5717 MATRIX_ROW_BOTTOM_Y (updated_row
));
5719 from_x
= output_cursor
.x
;
5721 /* Translate to frame coordinates. */
5722 if (updated_row
->full_width_p
)
5724 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5725 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5729 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5730 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5733 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5734 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5735 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5737 /* Prevent inadvertently clearing to end of the X window. */
5738 if (to_x
> from_x
&& to_y
> from_y
)
5741 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5742 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5749 /* Clear entire frame. If updating_frame is non-null, clear that
5750 frame. Otherwise clear the selected frame. */
5760 f
= SELECTED_FRAME ();
5762 /* Clearing the frame will erase any cursor, so mark them all as no
5764 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5765 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5766 output_cursor
.x
= -1;
5768 /* We don't set the output cursor here because there will always
5769 follow an explicit cursor_to. */
5771 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5773 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5774 /* We have to clear the scroll bars, too. If we have changed
5775 colors or something like that, then they should be notified. */
5776 x_scroll_bar_clear (f
);
5779 XFlush (FRAME_MAC_DISPLAY (f
));
5785 /* Invert the middle quarter of the frame for .15 sec. */
5787 /* We use the select system call to do the waiting, so we have to make
5788 sure it's available. If it isn't, we just won't do visual bells. */
5790 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5792 /* Subtract the `struct timeval' values X and Y, storing the result in
5793 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5796 timeval_subtract (result
, x
, y
)
5797 struct timeval
*result
, x
, y
;
5799 /* Perform the carry for the later subtraction by updating y. This
5800 is safer because on some systems the tv_sec member is unsigned. */
5801 if (x
.tv_usec
< y
.tv_usec
)
5803 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5804 y
.tv_usec
-= 1000000 * nsec
;
5808 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5810 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5811 y
.tv_usec
+= 1000000 * nsec
;
5815 /* Compute the time remaining to wait. tv_usec is certainly
5817 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5818 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5820 /* Return indication of whether the result should be considered
5822 return x
.tv_sec
< y
.tv_sec
;
5834 struct timeval wakeup
;
5836 EMACS_GET_TIME (wakeup
);
5838 /* Compute time to wait until, propagating carry from usecs. */
5839 wakeup
.tv_usec
+= 150000;
5840 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5841 wakeup
.tv_usec
%= 1000000;
5843 /* Keep waiting until past the time wakeup. */
5846 struct timeval timeout
;
5848 EMACS_GET_TIME (timeout
);
5850 /* In effect, timeout = wakeup - timeout.
5851 Break if result would be negative. */
5852 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5855 /* Try to wait that long--but we might wake up sooner. */
5856 select (0, NULL
, NULL
, NULL
, &timeout
);
5865 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5868 /* Make audible bell. */
5873 struct frame
*f
= SELECTED_FRAME ();
5875 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5883 XFlush (FRAME_MAC_DISPLAY (f
));
5890 /* Specify how many text lines, from the top of the window,
5891 should be affected by insert-lines and delete-lines operations.
5892 This, and those operations, are used only within an update
5893 that is bounded by calls to x_update_begin and x_update_end. */
5896 XTset_terminal_window (n
)
5899 /* This function intentionally left blank. */
5904 /***********************************************************************
5906 ***********************************************************************/
5908 /* Perform an insert-lines or delete-lines operation, inserting N
5909 lines or deleting -N lines at vertical position VPOS. */
5912 x_ins_del_lines (vpos
, n
)
5919 /* Scroll part of the display as described by RUN. */
5922 x_scroll_run (w
, run
)
5926 struct frame
*f
= XFRAME (w
->frame
);
5927 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5929 /* Get frame-relative bounding box of the text display area of W,
5930 without mode lines. Include in this box the left and right
5932 window_box (w
, -1, &x
, &y
, &width
, &height
);
5933 width
+= FRAME_X_FRINGE_WIDTH (f
);
5934 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5936 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5937 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5938 bottom_y
= y
+ height
;
5942 /* Scrolling up. Make sure we don't copy part of the mode
5943 line at the bottom. */
5944 if (from_y
+ run
->height
> bottom_y
)
5945 height
= bottom_y
- from_y
;
5947 height
= run
->height
;
5951 /* Scolling down. Make sure we don't copy over the mode line.
5953 if (to_y
+ run
->height
> bottom_y
)
5954 height
= bottom_y
- to_y
;
5956 height
= run
->height
;
5961 /* Cursor off. Will be switched on again in x_update_window_end. */
5965 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5966 f
->output_data
.mac
->normal_gc
,
5976 /***********************************************************************
5978 ***********************************************************************/
5980 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5981 corner of the exposed rectangle. W and H are width and height of
5982 the exposed area. All are pixel values. W or H zero means redraw
5983 the entire frame. */
5986 expose_frame (f
, x
, y
, w
, h
)
5991 int mouse_face_overwritten_p
= 0;
5993 TRACE ((stderr
, "expose_frame "));
5995 /* No need to redraw if frame will be redrawn soon. */
5996 if (FRAME_GARBAGED_P (f
))
5998 TRACE ((stderr
, " garbaged\n"));
6002 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
6003 or deactivated here, for unknown reasons, activated scroll bars
6004 are shown in deactivated frames in some instances. */
6005 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6006 activate_scroll_bars (f
);
6008 deactivate_scroll_bars (f
);
6010 /* If basic faces haven't been realized yet, there is no point in
6011 trying to redraw anything. This can happen when we get an expose
6012 event while Emacs is starting, e.g. by moving another window. */
6013 if (FRAME_FACE_CACHE (f
) == NULL
6014 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
6016 TRACE ((stderr
, " no faces\n"));
6020 if (w
== 0 || h
== 0)
6023 r
.right
= CANON_X_UNIT (f
) * f
->width
;
6024 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
6034 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
6035 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
6037 if (WINDOWP (f
->tool_bar_window
))
6038 mouse_face_overwritten_p
6039 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
6041 /* Some window managers support a focus-follows-mouse style with
6042 delayed raising of frames. Imagine a partially obscured frame,
6043 and moving the mouse into partially obscured mouse-face on that
6044 frame. The visible part of the mouse-face will be highlighted,
6045 then the WM raises the obscured frame. With at least one WM, KDE
6046 2.1, Emacs is not getting any event for the raising of the frame
6047 (even tried with SubstructureRedirectMask), only Expose events.
6048 These expose events will draw text normally, i.e. not
6049 highlighted. Which means we must redo the highlight here.
6050 Subsume it under ``we love X''. --gerd 2001-08-15 */
6051 /* Included in Windows version because Windows most likely does not
6052 do the right thing if any third party tool offers
6053 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
6054 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
6056 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6057 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6059 int x
= dpyinfo
->mouse_face_mouse_x
;
6060 int y
= dpyinfo
->mouse_face_mouse_y
;
6061 clear_mouse_face (dpyinfo
);
6062 note_mouse_highlight (f
, x
, y
);
6068 /* Redraw (parts) of all windows in the window tree rooted at W that
6069 intersect R. R contains frame pixel coordinates. */
6072 expose_window_tree (w
, r
)
6076 struct frame
*f
= XFRAME (w
->frame
);
6077 int mouse_face_overwritten_p
= 0;
6079 while (w
&& !FRAME_GARBAGED_P (f
))
6081 if (!NILP (w
->hchild
))
6082 mouse_face_overwritten_p
6083 |= expose_window_tree (XWINDOW (w
->hchild
), r
);
6084 else if (!NILP (w
->vchild
))
6085 mouse_face_overwritten_p
6086 |= expose_window_tree (XWINDOW (w
->vchild
), r
);
6088 mouse_face_overwritten_p
|= expose_window (w
, r
);
6090 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
6093 return mouse_face_overwritten_p
;
6097 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
6098 which intersects rectangle R. R is in window-relative coordinates. */
6101 expose_area (w
, row
, r
, area
)
6103 struct glyph_row
*row
;
6105 enum glyph_row_area area
;
6107 struct glyph
*first
= row
->glyphs
[area
];
6108 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
6110 int first_x
, start_x
, x
;
6112 if (area
== TEXT_AREA
&& row
->fill_line_p
)
6113 /* If row extends face to end of line write the whole line. */
6114 x_draw_glyphs (w
, 0, row
, area
,
6116 DRAW_NORMAL_TEXT
, 0);
6119 /* Set START_X to the window-relative start position for drawing glyphs of
6120 AREA. The first glyph of the text area can be partially visible.
6121 The first glyphs of other areas cannot. */
6122 if (area
== LEFT_MARGIN_AREA
)
6124 else if (area
== TEXT_AREA
)
6125 start_x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
6127 start_x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
6128 + window_box_width (w
, TEXT_AREA
));
6131 /* Find the first glyph that must be redrawn. */
6133 && x
+ first
->pixel_width
< r
->left
)
6135 x
+= first
->pixel_width
;
6139 /* Find the last one. */
6145 x
+= last
->pixel_width
;
6151 x_draw_glyphs (w
, first_x
- start_x
, row
, area
,
6152 first
- row
->glyphs
[area
],
6153 last
- row
->glyphs
[area
],
6154 DRAW_NORMAL_TEXT
, 0);
6159 /* Redraw the parts of the glyph row ROW on window W intersecting
6160 rectangle R. R is in window-relative coordinates. Value is
6161 non-zero if mouse face was overwritten. */
6164 expose_line (w
, row
, r
)
6166 struct glyph_row
*row
;
6169 xassert (row
->enabled_p
);
6171 if (row
->mode_line_p
|| w
->pseudo_window_p
)
6172 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
6173 DRAW_NORMAL_TEXT
, 0);
6176 if (row
->used
[LEFT_MARGIN_AREA
])
6177 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6178 if (row
->used
[TEXT_AREA
])
6179 expose_area (w
, row
, r
, TEXT_AREA
);
6180 if (row
->used
[RIGHT_MARGIN_AREA
])
6181 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6182 x_draw_row_fringe_bitmaps (w
, row
);
6185 return row
->mouse_face_p
;
6189 /* Return non-zero if W's cursor intersects rectangle R. */
6192 x_phys_cursor_in_rect_p (w
, r
)
6197 struct glyph
*cursor_glyph
;
6199 cursor_glyph
= get_phys_cursor_glyph (w
);
6202 cr
.left
= w
->phys_cursor
.x
;
6203 cr
.top
= w
->phys_cursor
.y
;
6204 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6205 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6206 return x_intersect_rectangles (&cr
, r
, &result
);
6213 /* Redraw the part of window W intersection rectagle FR. Pixel
6214 coordinates in FR are frame relative. Call this function with
6215 input blocked. Value is non-zero if the exposure overwrites
6219 expose_window (w
, fr
)
6223 struct frame
*f
= XFRAME (w
->frame
);
6225 int mouse_face_overwritten_p
= 0;
6227 /* If window is not yet fully initialized, do nothing. This can
6228 happen when toolkit scroll bars are used and a window is split.
6229 Reconfiguring the scroll bar will generate an expose for a newly
6231 if (w
->current_matrix
== NULL
)
6234 /* When we're currently updating the window, display and current
6235 matrix usually don't agree. Arrange for a thorough display
6237 if (w
== updated_window
)
6239 SET_FRAME_GARBAGED (f
);
6243 /* Frame-relative pixel rectangle of W. */
6244 wr
.left
= XFASTINT (w
->left
) * CANON_X_UNIT (f
);
6245 wr
.top
= XFASTINT (w
->top
) * CANON_Y_UNIT (f
);
6246 wr
.right
= wr
.left
+ XFASTINT (w
->width
) * CANON_X_UNIT (f
);
6247 wr
.bottom
= wr
.top
+ XFASTINT (w
->height
) * CANON_Y_UNIT (f
);
6249 if (x_intersect_rectangles (fr
, &wr
, &r
))
6251 int yb
= window_text_bottom_y (w
);
6252 struct glyph_row
*row
;
6253 int cursor_cleared_p
;
6255 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6256 r
.left
, r
.top
, r
.right
, r
.bottom
));
6258 /* Convert to window coordinates. */
6259 r
.left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.left
);
6260 r
.right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
.right
);
6261 r
.top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.top
);
6262 r
.bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
.bottom
);
6264 /* Turn off the cursor. */
6265 if (!w
->pseudo_window_p
6266 && x_phys_cursor_in_rect_p (w
, &r
))
6269 cursor_cleared_p
= 1;
6272 cursor_cleared_p
= 0;
6274 /* Find the first row intersecting the rectangle R. */
6275 for (row
= w
->current_matrix
->rows
;
6280 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
6282 if ((y0
>= r
.top
&& y0
< r
.bottom
)
6283 || (y1
> r
.top
&& y1
< r
.bottom
)
6284 || (r
.top
>= y0
&& r
.top
< y1
)
6285 || (r
.bottom
> y0
&& r
.bottom
< y1
))
6287 if (expose_line (w
, row
, &r
))
6288 mouse_face_overwritten_p
= 1;
6295 /* Display the mode line if there is one. */
6296 if (WINDOW_WANTS_MODELINE_P (w
)
6297 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6299 && row
->y
< r
.bottom
)
6301 if (expose_line (w
, row
, &r
))
6302 mouse_face_overwritten_p
= 1;
6305 if (!w
->pseudo_window_p
)
6307 /* Draw border between windows. */
6308 x_draw_vertical_border (w
);
6310 /* Turn the cursor on again. */
6311 if (cursor_cleared_p
)
6312 x_update_window_cursor (w
, 1);
6316 /* Display scroll bar for this window. */
6317 if (!NILP (w
->vertical_scroll_bar
))
6320 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6325 return mouse_face_overwritten_p
;
6329 x_intersect_rectangles (r1
, r2
, result
)
6330 Rect
*r1
, *r2
, *result
;
6333 Rect
*upper
, *lower
;
6334 int intersection_p
= 0;
6336 /* Rerrange so that R1 is the left-most rectangle. */
6337 if (r1
->left
< r2
->left
)
6338 left
= r1
, right
= r2
;
6340 left
= r2
, right
= r1
;
6342 /* X0 of the intersection is right.x0, if this is inside R1,
6343 otherwise there is no intersection. */
6344 if (right
->left
<= left
->right
)
6346 result
->left
= right
->left
;
6348 /* The right end of the intersection is the minimum of the
6349 the right ends of left and right. */
6350 result
->right
= min (left
->right
, right
->right
);
6352 /* Same game for Y. */
6353 if (r1
->top
< r2
->top
)
6354 upper
= r1
, lower
= r2
;
6356 upper
= r2
, lower
= r1
;
6358 /* The upper end of the intersection is lower.y0, if this is inside
6359 of upper. Otherwise, there is no intersection. */
6360 if (lower
->top
<= upper
->bottom
)
6362 result
->top
= lower
->top
;
6364 /* The lower end of the intersection is the minimum of the lower
6365 ends of upper and lower. */
6366 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6371 return intersection_p
;
6382 x_update_cursor (f
, 1);
6386 frame_unhighlight (f
)
6389 x_update_cursor (f
, 1);
6392 /* The focus has changed. Update the frames as necessary to reflect
6393 the new situation. Note that we can't change the selected frame
6394 here, because the Lisp code we are interrupting might become confused.
6395 Each event gets marked with the frame in which it occurred, so the
6396 Lisp code can tell when the switch took place by examining the events. */
6399 x_new_focus_frame (dpyinfo
, frame
)
6400 struct x_display_info
*dpyinfo
;
6401 struct frame
*frame
;
6403 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6405 if (frame
!= dpyinfo
->x_focus_frame
)
6407 /* Set this before calling other routines, so that they see
6408 the correct value of x_focus_frame. */
6409 dpyinfo
->x_focus_frame
= frame
;
6411 if (old_focus
&& old_focus
->auto_lower
)
6412 x_lower_frame (old_focus
);
6415 selected_frame
= frame
;
6416 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6418 Fselect_window (selected_frame
->selected_window
);
6419 choose_minibuf_frame ();
6422 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6423 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6425 pending_autoraise_frame
= 0;
6428 x_frame_rehighlight (dpyinfo
);
6431 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6434 x_mouse_leave (dpyinfo
)
6435 struct x_display_info
*dpyinfo
;
6437 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6440 /* The focus has changed, or we have redirected a frame's focus to
6441 another frame (this happens when a frame uses a surrogate
6442 mini-buffer frame). Shift the highlight as appropriate.
6444 The FRAME argument doesn't necessarily have anything to do with which
6445 frame is being highlighted or un-highlighted; we only use it to find
6446 the appropriate X display info. */
6449 XTframe_rehighlight (frame
)
6450 struct frame
*frame
;
6452 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6456 x_frame_rehighlight (dpyinfo
)
6457 struct x_display_info
*dpyinfo
;
6459 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6461 if (dpyinfo
->x_focus_frame
)
6463 dpyinfo
->x_highlight_frame
6464 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6465 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6466 : dpyinfo
->x_focus_frame
);
6467 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6469 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6470 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6474 dpyinfo
->x_highlight_frame
= 0;
6476 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6479 frame_unhighlight (old_highlight
);
6480 if (dpyinfo
->x_highlight_frame
)
6481 frame_highlight (dpyinfo
->x_highlight_frame
);
6487 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6489 #if 0 /* MAC_TODO */
6490 /* Initialize mode_switch_bit and modifier_meaning. */
6492 x_find_modifier_meanings (dpyinfo
)
6493 struct x_display_info
*dpyinfo
;
6495 int min_code
, max_code
;
6498 XModifierKeymap
*mods
;
6500 dpyinfo
->meta_mod_mask
= 0;
6501 dpyinfo
->shift_lock_mask
= 0;
6502 dpyinfo
->alt_mod_mask
= 0;
6503 dpyinfo
->super_mod_mask
= 0;
6504 dpyinfo
->hyper_mod_mask
= 0;
6507 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6509 min_code
= dpyinfo
->display
->min_keycode
;
6510 max_code
= dpyinfo
->display
->max_keycode
;
6513 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6514 min_code
, max_code
- min_code
+ 1,
6516 mods
= XGetModifierMapping (dpyinfo
->display
);
6518 /* Scan the modifier table to see which modifier bits the Meta and
6519 Alt keysyms are on. */
6521 int row
, col
; /* The row and column in the modifier table. */
6523 for (row
= 3; row
< 8; row
++)
6524 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6527 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6529 /* Zeroes are used for filler. Skip them. */
6533 /* Are any of this keycode's keysyms a meta key? */
6537 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6539 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6545 dpyinfo
->meta_mod_mask
|= (1 << row
);
6550 dpyinfo
->alt_mod_mask
|= (1 << row
);
6555 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6560 dpyinfo
->super_mod_mask
|= (1 << row
);
6564 /* Ignore this if it's not on the lock modifier. */
6565 if ((1 << row
) == LockMask
)
6566 dpyinfo
->shift_lock_mask
= LockMask
;
6574 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6575 if (! dpyinfo
->meta_mod_mask
)
6577 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6578 dpyinfo
->alt_mod_mask
= 0;
6581 /* If some keys are both alt and meta,
6582 make them just meta, not alt. */
6583 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6585 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6588 XFree ((char *) syms
);
6589 XFreeModifiermap (mods
);
6592 #endif /* MAC_TODO */
6594 /* Convert between the modifier bits X uses and the modifier bits
6598 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6599 struct x_display_info
*dpyinfo
;
6600 unsigned short state
;
6602 return (((state
& shiftKey
) ? shift_modifier
: 0)
6603 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6604 | ((state
& cmdKey
) ? meta_modifier
: 0)
6605 | ((state
& optionKey
) ? alt_modifier
: 0));
6608 #if 0 /* MAC_TODO */
6609 static unsigned short
6610 x_emacs_to_x_modifiers (dpyinfo
, state
)
6611 struct x_display_info
*dpyinfo
;
6614 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6615 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6616 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6617 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6618 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6619 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6621 #endif /* MAC_TODO */
6623 /* Convert a keysym to its name. */
6626 x_get_keysym_name (keysym
)
6633 value
= XKeysymToString (keysym
);
6644 /* Mouse clicks and mouse movement. Rah. */
6646 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6647 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6648 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6649 not force the value into range. */
6652 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6654 register int pix_x
, pix_y
;
6655 register int *x
, *y
;
6659 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
6660 if (NILP (Vwindow_system
))
6667 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6668 even for negative values. */
6670 pix_x
-= FONT_WIDTH (FRAME_FONT (f
)) - 1;
6672 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6674 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6675 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6679 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6680 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6681 bounds
->right
= bounds
->left
+ FONT_WIDTH (FRAME_FONT (f
)) - 1;
6682 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
- 1;
6689 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6690 pix_x
= FRAME_WINDOW_WIDTH (f
);
6694 else if (pix_y
> f
->height
)
6703 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6704 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6705 can't tell the positions because W's display is not up to date,
6709 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6712 int *frame_x
, *frame_y
;
6716 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6717 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6719 if (display_completed
)
6721 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6722 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6723 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6729 *frame_x
+= glyph
->pixel_width
;
6737 *frame_y
= *frame_x
= 0;
6741 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6742 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6747 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6749 If the event is a button press, then note that we have grabbed
6753 construct_mouse_click (result
, event
, f
)
6754 struct input_event
*result
;
6760 result
->kind
= mouse_click
;
6761 result
->code
= 0; /* only one mouse button */
6762 result
->timestamp
= event
->when
;
6763 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6765 mouseLoc
= event
->where
;
6767 #if TARGET_API_MAC_CARBON
6768 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
6770 SetPort (FRAME_MAC_WINDOW (f
));
6773 GlobalToLocal (&mouseLoc
);
6774 XSETINT (result
->x
, mouseLoc
.h
);
6775 XSETINT (result
->y
, mouseLoc
.v
);
6777 XSETFRAME (result
->frame_or_window
, f
);
6784 /* Function to report a mouse movement to the mainstream Emacs code.
6785 The input handler calls this.
6787 We have received a mouse movement event, which is given in *event.
6788 If the mouse is over a different glyph than it was last time, tell
6789 the mainstream emacs code by setting mouse_moved. If not, ask for
6790 another motion event, so we can check again the next time it moves. */
6792 static Point last_mouse_motion_position
;
6793 static Lisp_Object last_mouse_motion_frame
;
6796 note_mouse_movement (frame
, pos
)
6800 #if TARGET_API_MAC_CARBON
6804 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6805 last_mouse_motion_position
= *pos
;
6806 XSETFRAME (last_mouse_motion_frame
, frame
);
6808 #if TARGET_API_MAC_CARBON
6809 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
6811 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6814 frame
->mouse_moved
= 1;
6815 last_mouse_scroll_bar
= Qnil
;
6816 note_mouse_highlight (frame
, -1, -1);
6818 /* Has the mouse moved off the glyph it was on at the last sighting? */
6819 else if (pos
->h
< last_mouse_glyph
.left
6820 || pos
->h
>= last_mouse_glyph
.right
6821 || pos
->v
< last_mouse_glyph
.top
6822 || pos
->v
>= last_mouse_glyph
.bottom
)
6824 frame
->mouse_moved
= 1;
6825 last_mouse_scroll_bar
= Qnil
;
6826 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6830 /* This is used for debugging, to turn off note_mouse_highlight. */
6832 int disable_mouse_highlight
;
6836 /************************************************************************
6838 ************************************************************************/
6840 /* Find the glyph under window-relative coordinates X/Y in window W.
6841 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6842 strings. Return in *HPOS and *VPOS the row and column number of
6843 the glyph found. Return in *AREA the glyph area containing X.
6844 Value is a pointer to the glyph found or null if X/Y is not on
6845 text, or we can't tell because W's current matrix is not up to
6848 static struct glyph
*
6849 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
, buffer_only_p
)
6852 int *hpos
, *vpos
, *area
;
6855 struct glyph
*glyph
, *end
;
6856 struct glyph_row
*row
= NULL
;
6857 int x0
, i
, left_area_width
;
6859 /* Find row containing Y. Give up if some row is not enabled. */
6860 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6862 row
= MATRIX_ROW (w
->current_matrix
, i
);
6863 if (!row
->enabled_p
)
6865 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6872 /* Give up if Y is not in the window. */
6873 if (i
== w
->current_matrix
->nrows
)
6876 /* Get the glyph area containing X. */
6877 if (w
->pseudo_window_p
)
6884 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6885 if (x
< left_area_width
)
6887 *area
= LEFT_MARGIN_AREA
;
6890 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6893 x0
= row
->x
+ left_area_width
;
6897 *area
= RIGHT_MARGIN_AREA
;
6898 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6902 /* Find glyph containing X. */
6903 glyph
= row
->glyphs
[*area
];
6904 end
= glyph
+ row
->used
[*area
];
6907 if (x
< x0
+ glyph
->pixel_width
)
6909 if (w
->pseudo_window_p
)
6911 else if (!buffer_only_p
|| BUFFERP (glyph
->object
))
6915 x0
+= glyph
->pixel_width
;
6922 *hpos
= glyph
- row
->glyphs
[*area
];
6927 /* Convert frame-relative x/y to coordinates relative to window W.
6928 Takes pseudo-windows into account. */
6931 frame_to_window_pixel_xy (w
, x
, y
)
6935 if (w
->pseudo_window_p
)
6937 /* A pseudo-window is always full-width, and starts at the
6938 left edge of the frame, plus a frame border. */
6939 struct frame
*f
= XFRAME (w
->frame
);
6940 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6941 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6945 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6946 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6951 /* Take proper action when mouse has moved to the mode or header line of
6952 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6953 mode line. X is relative to the start of the text display area of
6954 W, so the width of fringes and scroll bars must be subtracted
6955 to get a position relative to the start of the mode line. */
6958 note_mode_line_highlight (w
, x
, mode_line_p
)
6962 struct frame
*f
= XFRAME (w
->frame
);
6963 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6964 struct Cursor
*cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6965 struct glyph_row
*row
;
6968 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6970 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6974 struct glyph
*glyph
, *end
;
6975 Lisp_Object help
, map
;
6978 /* Find the glyph under X. */
6979 glyph
= row
->glyphs
[TEXT_AREA
];
6980 end
= glyph
+ row
->used
[TEXT_AREA
];
6981 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6982 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6985 && x
>= x0
+ glyph
->pixel_width
)
6987 x0
+= glyph
->pixel_width
;
6992 && STRINGP (glyph
->object
)
6993 && XSTRING (glyph
->object
)->intervals
6994 && glyph
->charpos
>= 0
6995 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6997 /* If we're on a string with `help-echo' text property,
6998 arrange for the help to be displayed. This is done by
6999 setting the global variable help_echo to the help string. */
7000 help
= Fget_text_property (make_number (glyph
->charpos
),
7001 Qhelp_echo
, glyph
->object
);
7005 XSETWINDOW (help_echo_window
, w
);
7006 help_echo_object
= glyph
->object
;
7007 help_echo_pos
= glyph
->charpos
;
7010 /* Change the mouse pointer according to what is under X/Y. */
7011 map
= Fget_text_property (make_number (glyph
->charpos
),
7012 Qlocal_map
, glyph
->object
);
7014 cursor
= f
->output_data
.mac
->nontext_cursor
;
7017 map
= Fget_text_property (make_number (glyph
->charpos
),
7018 Qkeymap
, glyph
->object
);
7020 cursor
= f
->output_data
.mac
->nontext_cursor
;
7025 #if 0 /* MAC_TODO: mouse cursor */
7026 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
7031 /* Take proper action when the mouse has moved to position X, Y on
7032 frame F as regards highlighting characters that have mouse-face
7033 properties. Also de-highlighting chars where the mouse was before.
7034 X and Y can be negative or out of range. */
7037 note_mouse_highlight (f
, x
, y
)
7041 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7048 /* When a menu is active, don't highlight because this looks odd. */
7049 if (popup_activated ())
7053 if (NILP (Vmouse_highlight
)
7054 || !f
->glyphs_initialized_p
)
7057 dpyinfo
->mouse_face_mouse_x
= x
;
7058 dpyinfo
->mouse_face_mouse_y
= y
;
7059 dpyinfo
->mouse_face_mouse_frame
= f
;
7061 if (dpyinfo
->mouse_face_defer
)
7066 dpyinfo
->mouse_face_deferred_gc
= 1;
7070 /* Which window is that in? */
7071 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
7073 /* If we were displaying active text in another window, clear that. */
7074 if (! EQ (window
, dpyinfo
->mouse_face_window
))
7075 clear_mouse_face (dpyinfo
);
7077 /* Not on a window -> return. */
7078 if (!WINDOWP (window
))
7081 /* Reset help_echo. It will get recomputed below. */
7084 /* Convert to window-relative pixel coordinates. */
7085 w
= XWINDOW (window
);
7086 frame_to_window_pixel_xy (w
, &x
, &y
);
7088 /* Handle tool-bar window differently since it doesn't display a
7090 if (EQ (window
, f
->tool_bar_window
))
7092 note_tool_bar_highlight (f
, x
, y
);
7096 /* Mouse is on the mode or header line? */
7097 if (portion
== 1 || portion
== 3)
7099 note_mode_line_highlight (w
, x
, portion
== 1);
7102 #if 0 /* TODO: mouse cursor */
7104 cursor
= f
->output_data
.x
->horizontal_drag_cursor
;
7106 cursor
= f
->output_data
.x
->text_cursor
;
7108 /* Are we in a window whose display is up to date?
7109 And verify the buffer's text has not changed. */
7110 b
= XBUFFER (w
->buffer
);
7111 if (/* Within text portion of the window. */
7113 && EQ (w
->window_end_valid
, w
->buffer
)
7114 && XFASTINT (w
->last_modified
) == BUF_MODIFF (b
)
7115 && XFASTINT (w
->last_overlay_modified
) == BUF_OVERLAY_MODIFF (b
))
7117 int hpos
, vpos
, pos
, i
, area
;
7118 struct glyph
*glyph
;
7120 Lisp_Object mouse_face
= Qnil
, overlay
= Qnil
, position
;
7121 Lisp_Object
*overlay_vec
= NULL
;
7123 struct buffer
*obuf
;
7124 int obegv
, ozv
, same_region
;
7126 /* Find the glyph under X/Y. */
7127 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
, 0);
7129 /* Clear mouse face if X/Y not over text. */
7131 || area
!= TEXT_AREA
7132 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
7134 clear_mouse_face (dpyinfo
);
7135 /* TODO: mouse cursor */
7139 pos
= glyph
->charpos
;
7140 object
= glyph
->object
;
7141 if (!STRINGP (object
) && !BUFFERP (object
))
7144 /* If we get an out-of-range value, return now; avoid an error. */
7145 if (BUFFERP (object
) && pos
> BUF_Z (b
))
7148 /* Make the window's buffer temporarily current for
7149 overlays_at and compute_char_face. */
7150 obuf
= current_buffer
;
7157 /* Is this char mouse-active or does it have help-echo? */
7158 position
= make_number (pos
);
7160 if (BUFFERP (object
))
7162 /* Put all the overlays we want in a vector in overlay_vec.
7163 Store the length in len. If there are more than 10, make
7164 enough space for all, and try again. */
7166 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7167 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
, 0);
7168 if (noverlays
> len
)
7171 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
7172 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
,0);
7175 /* Sort overlays into increasing priority order. */
7176 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
7181 same_region
= (EQ (window
, dpyinfo
->mouse_face_window
)
7182 && vpos
>= dpyinfo
->mouse_face_beg_row
7183 && vpos
<= dpyinfo
->mouse_face_end_row
7184 && (vpos
> dpyinfo
->mouse_face_beg_row
7185 || hpos
>= dpyinfo
->mouse_face_beg_col
)
7186 && (vpos
< dpyinfo
->mouse_face_end_row
7187 || hpos
< dpyinfo
->mouse_face_end_col
7188 || dpyinfo
->mouse_face_past_end
));
7190 /* TODO: if (same_region)
7193 /* Check mouse-face highlighting. */
7195 /* If there exists an overlay with mouse-face overlapping
7196 the one we are currently highlighting, we have to
7197 check if we enter the overlapping overlay, and then
7199 || (OVERLAYP (dpyinfo
->mouse_face_overlay
)
7200 && mouse_face_overlay_overlaps (dpyinfo
->mouse_face_overlay
)))
7202 /* Find the highest priority overlay that has a mouse-face
7205 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
7207 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
7208 if (!NILP (mouse_face
))
7209 overlay
= overlay_vec
[i
];
7212 /* If we're actually highlighting the same overlay as
7213 before, there's no need to do that again. */
7215 && EQ (overlay
, dpyinfo
->mouse_face_overlay
))
7216 goto check_help_echo
;
7218 dpyinfo
->mouse_face_overlay
= overlay
;
7220 /* Clear the display of the old active region, if any. */
7221 clear_mouse_face (dpyinfo
);
7222 /* TODO: mouse cursor changes. */
7224 /* If no overlay applies, get a text property. */
7226 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
7228 /* Handle the overlay case. */
7229 if (!NILP (overlay
))
7231 /* Find the range of text around this char that
7232 should be active. */
7233 Lisp_Object before
, after
;
7236 before
= Foverlay_start (overlay
);
7237 after
= Foverlay_end (overlay
);
7238 /* Record this as the current active region. */
7239 fast_find_position (w
, XFASTINT (before
),
7240 &dpyinfo
->mouse_face_beg_col
,
7241 &dpyinfo
->mouse_face_beg_row
,
7242 &dpyinfo
->mouse_face_beg_x
,
7243 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7245 dpyinfo
->mouse_face_past_end
7246 = !fast_find_position (w
, XFASTINT (after
),
7247 &dpyinfo
->mouse_face_end_col
,
7248 &dpyinfo
->mouse_face_end_row
,
7249 &dpyinfo
->mouse_face_end_x
,
7250 &dpyinfo
->mouse_face_end_y
, Qnil
);
7251 dpyinfo
->mouse_face_window
= window
;
7253 dpyinfo
->mouse_face_face_id
7254 = face_at_buffer_position (w
, pos
, 0, 0,
7255 &ignore
, pos
+ 1, 1);
7257 /* Display it as active. */
7258 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7259 /* TODO: mouse cursor changes. */
7261 /* Handle the text property case. */
7262 else if (! NILP (mouse_face
) && BUFFERP (object
))
7264 /* Find the range of text around this char that
7265 should be active. */
7266 Lisp_Object before
, after
, beginning
, end
;
7269 beginning
= Fmarker_position (w
->start
);
7270 end
= make_number (BUF_Z (XBUFFER (object
))
7271 - XFASTINT (w
->window_end_pos
));
7273 = Fprevious_single_property_change (make_number (pos
+ 1),
7277 = Fnext_single_property_change (position
, Qmouse_face
,
7280 /* Record this as the current active region. */
7281 fast_find_position (w
, XFASTINT (before
),
7282 &dpyinfo
->mouse_face_beg_col
,
7283 &dpyinfo
->mouse_face_beg_row
,
7284 &dpyinfo
->mouse_face_beg_x
,
7285 &dpyinfo
->mouse_face_beg_y
, Qnil
);
7286 dpyinfo
->mouse_face_past_end
7287 = !fast_find_position (w
, XFASTINT (after
),
7288 &dpyinfo
->mouse_face_end_col
,
7289 &dpyinfo
->mouse_face_end_row
,
7290 &dpyinfo
->mouse_face_end_x
,
7291 &dpyinfo
->mouse_face_end_y
, Qnil
);
7292 dpyinfo
->mouse_face_window
= window
;
7294 if (BUFFERP (object
))
7295 dpyinfo
->mouse_face_face_id
7296 = face_at_buffer_position (w
, pos
, 0, 0,
7297 &ignore
, pos
+ 1, 1);
7299 /* Display it as active. */
7300 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7301 /* TODO: mouse cursor changes. */
7303 else if (!NILP (mouse_face
) && STRINGP (object
))
7308 b
= Fprevious_single_property_change (make_number (pos
+ 1),
7311 e
= Fnext_single_property_change (position
, Qmouse_face
,
7314 b
= make_number (0);
7316 e
= make_number (XSTRING (object
)->size
- 1);
7317 fast_find_string_pos (w
, XINT (b
), object
,
7318 &dpyinfo
->mouse_face_beg_col
,
7319 &dpyinfo
->mouse_face_beg_row
,
7320 &dpyinfo
->mouse_face_beg_x
,
7321 &dpyinfo
->mouse_face_beg_y
, 0);
7322 fast_find_string_pos (w
, XINT (e
), object
,
7323 &dpyinfo
->mouse_face_end_col
,
7324 &dpyinfo
->mouse_face_end_row
,
7325 &dpyinfo
->mouse_face_end_x
,
7326 &dpyinfo
->mouse_face_end_y
, 1);
7327 dpyinfo
->mouse_face_past_end
= 0;
7328 dpyinfo
->mouse_face_window
= window
;
7329 dpyinfo
->mouse_face_face_id
7330 = face_at_string_position (w
, object
, pos
, 0, 0, 0, &ignore
,
7332 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7333 /* TODO: mouse cursor changes. */
7335 else if (STRINGP (object
) && NILP (mouse_face
))
7337 /* A string which doesn't have mouse-face, but
7338 the text ``under'' it might have. */
7339 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
7340 int start
= MATRIX_ROW_START_CHARPOS (r
);
7342 pos
= string_buffer_position (w
, object
, start
);
7344 mouse_face
= get_char_property_and_overlay (make_number (pos
),
7348 if (!NILP (mouse_face
) && !NILP (overlay
))
7350 Lisp_Object before
= Foverlay_start (overlay
);
7351 Lisp_Object after
= Foverlay_end (overlay
);
7354 /* Note that we might not be able to find position
7355 BEFORE in the glyph matrix if the overlay is
7356 entirely covered by a `display' property. In
7357 this case, we overshoot. So let's stop in
7358 the glyph matrix before glyphs for OBJECT. */
7359 fast_find_position (w
, XFASTINT (before
),
7360 &dpyinfo
->mouse_face_beg_col
,
7361 &dpyinfo
->mouse_face_beg_row
,
7362 &dpyinfo
->mouse_face_beg_x
,
7363 &dpyinfo
->mouse_face_beg_y
,
7366 dpyinfo
->mouse_face_past_end
7367 = !fast_find_position (w
, XFASTINT (after
),
7368 &dpyinfo
->mouse_face_end_col
,
7369 &dpyinfo
->mouse_face_end_row
,
7370 &dpyinfo
->mouse_face_end_x
,
7371 &dpyinfo
->mouse_face_end_y
,
7373 dpyinfo
->mouse_face_window
= window
;
7374 dpyinfo
->mouse_face_face_id
7375 = face_at_buffer_position (w
, pos
, 0, 0,
7376 &ignore
, pos
+ 1, 1);
7378 /* Display it as active. */
7379 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7380 /* TODO: mouse cursor changes. */
7387 /* Look for a `help-echo' property. */
7389 Lisp_Object help
, overlay
;
7391 /* Check overlays first. */
7392 help
= overlay
= Qnil
;
7393 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7395 overlay
= overlay_vec
[i
];
7396 help
= Foverlay_get (overlay
, Qhelp_echo
);
7402 help_echo_window
= window
;
7403 help_echo_object
= overlay
;
7404 help_echo_pos
= pos
;
7408 Lisp_Object object
= glyph
->object
;
7409 int charpos
= glyph
->charpos
;
7411 /* Try text properties. */
7412 if (STRINGP (object
)
7414 && charpos
< XSTRING (object
)->size
)
7416 help
= Fget_text_property (make_number (charpos
),
7417 Qhelp_echo
, object
);
7420 /* If the string itself doesn't specify a help-echo,
7421 see if the buffer text ``under'' it does. */
7423 = MATRIX_ROW (w
->current_matrix
, vpos
);
7424 int start
= MATRIX_ROW_START_CHARPOS (r
);
7425 int pos
= string_buffer_position (w
, object
, start
);
7428 help
= Fget_char_property (make_number (pos
),
7429 Qhelp_echo
, w
->buffer
);
7438 else if (BUFFERP (object
)
7441 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
7447 help_echo_window
= window
;
7448 help_echo_object
= object
;
7449 help_echo_pos
= charpos
;
7456 current_buffer
= obuf
;
7460 /* TODO: mouse cursor changes. */
7465 redo_mouse_highlight ()
7467 if (!NILP (last_mouse_motion_frame
)
7468 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7469 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7470 last_mouse_motion_position
.h
,
7471 last_mouse_motion_position
.v
);
7476 /***********************************************************************
7478 ***********************************************************************/
7480 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7481 struct glyph
**, int *, int *, int *));
7483 /* Tool-bar item index of the item on which a mouse button was pressed
7486 static int last_tool_bar_item
;
7489 /* Get information about the tool-bar item at position X/Y on frame F.
7490 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7491 the current matrix of the tool-bar window of F, or NULL if not
7492 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7493 item in F->current_tool_bar_items. Value is
7495 -1 if X/Y is not on a tool-bar item
7496 0 if X/Y is on the same item that was highlighted before.
7500 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7503 struct glyph
**glyph
;
7504 int *hpos
, *vpos
, *prop_idx
;
7506 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7507 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7510 /* Find the glyph under X/Y. */
7511 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
, 0);
7515 /* Get the start of this tool-bar item's properties in
7516 f->current_tool_bar_items. */
7517 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7520 /* Is mouse on the highlighted item? */
7521 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7522 && *vpos
>= dpyinfo
->mouse_face_beg_row
7523 && *vpos
<= dpyinfo
->mouse_face_end_row
7524 && (*vpos
> dpyinfo
->mouse_face_beg_row
7525 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7526 && (*vpos
< dpyinfo
->mouse_face_end_row
7527 || *hpos
< dpyinfo
->mouse_face_end_col
7528 || dpyinfo
->mouse_face_past_end
))
7535 /* Handle mouse button event on the tool-bar of frame F, at
7536 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7540 x_handle_tool_bar_click (f
, button_event
)
7542 EventRecord
*button_event
;
7544 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7545 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7546 int hpos
, vpos
, prop_idx
;
7547 struct glyph
*glyph
;
7548 Lisp_Object enabled_p
;
7549 int x
= button_event
->where
.h
;
7550 int y
= button_event
->where
.v
;
7552 /* If not on the highlighted tool-bar item, return. */
7553 frame_to_window_pixel_xy (w
, &x
, &y
);
7554 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7557 /* If item is disabled, do nothing. */
7558 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7559 if (NILP (enabled_p
))
7562 if (button_event
->what
== mouseDown
)
7564 /* Show item in pressed state. */
7565 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7566 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7567 last_tool_bar_item
= prop_idx
;
7571 Lisp_Object key
, frame
;
7572 struct input_event event
;
7574 /* Show item in released state. */
7575 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7576 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7578 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7580 XSETFRAME (frame
, f
);
7581 event
.kind
= TOOL_BAR_EVENT
;
7582 event
.frame_or_window
= frame
;
7584 kbd_buffer_store_event (&event
);
7586 event
.kind
= TOOL_BAR_EVENT
;
7587 event
.frame_or_window
= frame
;
7589 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7590 button_event
->modifiers
);
7591 kbd_buffer_store_event (&event
);
7592 last_tool_bar_item
= -1;
7597 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7598 tool-bar window-relative coordinates X/Y. Called from
7599 note_mouse_highlight. */
7602 note_tool_bar_highlight (f
, x
, y
)
7606 Lisp_Object window
= f
->tool_bar_window
;
7607 struct window
*w
= XWINDOW (window
);
7608 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7610 struct glyph
*glyph
;
7611 struct glyph_row
*row
;
7613 Lisp_Object enabled_p
;
7615 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7616 int mouse_down_p
, rc
;
7618 /* Function note_mouse_highlight is called with negative x(y
7619 values when mouse moves outside of the frame. */
7620 if (x
<= 0 || y
<= 0)
7622 clear_mouse_face (dpyinfo
);
7626 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7629 /* Not on tool-bar item. */
7630 clear_mouse_face (dpyinfo
);
7634 /* On same tool-bar item as before. */
7637 clear_mouse_face (dpyinfo
);
7639 /* Mouse is down, but on different tool-bar item? */
7640 mouse_down_p
= (dpyinfo
->grabbed
7641 && f
== last_mouse_frame
7642 && FRAME_LIVE_P (f
));
7644 && last_tool_bar_item
!= prop_idx
)
7647 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7648 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7650 /* If tool-bar item is not enabled, don't highlight it. */
7651 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7652 if (!NILP (enabled_p
))
7654 /* Compute the x-position of the glyph. In front and past the
7655 image is a space. We include this is the highlighted area. */
7656 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7657 for (i
= x
= 0; i
< hpos
; ++i
)
7658 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7660 /* Record this as the current active region. */
7661 dpyinfo
->mouse_face_beg_col
= hpos
;
7662 dpyinfo
->mouse_face_beg_row
= vpos
;
7663 dpyinfo
->mouse_face_beg_x
= x
;
7664 dpyinfo
->mouse_face_beg_y
= row
->y
;
7665 dpyinfo
->mouse_face_past_end
= 0;
7667 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7668 dpyinfo
->mouse_face_end_row
= vpos
;
7669 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7670 dpyinfo
->mouse_face_end_y
= row
->y
;
7671 dpyinfo
->mouse_face_window
= window
;
7672 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7674 /* Display it as active. */
7675 show_mouse_face (dpyinfo
, draw
);
7676 dpyinfo
->mouse_face_image_state
= draw
;
7681 /* Set help_echo to a help string.to display for this tool-bar item.
7682 XTread_socket does the rest. */
7683 help_echo_object
= help_echo_window
= Qnil
;
7685 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7686 if (NILP (help_echo
))
7687 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7692 /* Find the glyph matrix position of buffer position CHARPOS in window
7693 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7694 current glyphs must be up to date. If CHARPOS is above window
7695 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
7696 of last line in W. In the row containing CHARPOS, stop before glyphs
7697 having STOP as object. */
7699 #if 0 /* This is a version of fast_find_position that's more correct
7700 in the presence of hscrolling, for example. I didn't install
7701 it right away because the problem fixed is minor, it failed
7702 in 20.x as well, and I think it's too risky to install
7703 so near the release of 21.1. 2001-09-25 gerd. */
7706 fast_find_position (w
, charpos
, hpos
, vpos
, x
, y
, stop
)
7709 int *hpos
, *vpos
, *x
, *y
;
7712 struct glyph_row
*row
, *first
;
7713 struct glyph
*glyph
, *end
;
7714 int i
, past_end
= 0;
7716 first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7717 row
= row_containing_pos (w
, charpos
, first
, NULL
, 0);
7720 if (charpos
< MATRIX_ROW_START_CHARPOS (first
))
7722 *x
= *y
= *hpos
= *vpos
= 0;
7727 row
= MATRIX_ROW (w
->current_matrix
, XFASTINT (w
->window_end_vpos
));
7734 *vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7736 glyph
= row
->glyphs
[TEXT_AREA
];
7737 end
= glyph
+ row
->used
[TEXT_AREA
];
7739 /* Skip over glyphs not having an object at the start of the row.
7740 These are special glyphs like truncation marks on terminal
7742 if (row
->displays_text_p
)
7744 && INTEGERP (glyph
->object
)
7745 && !EQ (stop
, glyph
->object
)
7746 && glyph
->charpos
< 0)
7748 *x
+= glyph
->pixel_width
;
7753 && !INTEGERP (glyph
->object
)
7754 && !EQ (stop
, glyph
->object
)
7755 && (!BUFFERP (glyph
->object
)
7756 || glyph
->charpos
< charpos
))
7758 *x
+= glyph
->pixel_width
;
7762 *hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
7769 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
, stop
)
7772 int *hpos
, *vpos
, *x
, *y
;
7777 int maybe_next_line_p
= 0;
7778 int line_start_position
;
7779 int yb
= window_text_bottom_y (w
);
7780 struct glyph_row
*row
, *best_row
;
7781 int row_vpos
, best_row_vpos
;
7784 row
= best_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7785 row_vpos
= best_row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
7789 if (row
->used
[TEXT_AREA
])
7790 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7792 line_start_position
= 0;
7794 if (line_start_position
> pos
)
7796 /* If the position sought is the end of the buffer,
7797 don't include the blank lines at the bottom of the window. */
7798 else if (line_start_position
== pos
7799 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7801 maybe_next_line_p
= 1;
7804 else if (line_start_position
> 0)
7807 best_row_vpos
= row_vpos
;
7810 if (row
->y
+ row
->height
>= yb
)
7817 /* Find the right column within BEST_ROW. */
7819 current_x
= best_row
->x
;
7820 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7822 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7823 int charpos
= glyph
->charpos
;
7825 if (BUFFERP (glyph
->object
))
7830 *vpos
= best_row_vpos
;
7835 else if (charpos
> pos
)
7838 else if (EQ (glyph
->object
, stop
))
7843 current_x
+= glyph
->pixel_width
;
7846 /* If we're looking for the end of the buffer,
7847 and we didn't find it in the line we scanned,
7848 use the start of the following line. */
7849 if (maybe_next_line_p
)
7854 current_x
= best_row
->x
;
7857 *vpos
= best_row_vpos
;
7858 *hpos
= lastcol
+ 1;
7867 /* Find the position of the glyph for position POS in OBJECT in
7868 window W's current matrix, and return in *X/*Y the pixel
7869 coordinates, and return in *HPOS/*VPOS the column/row of the glyph.
7871 RIGHT_P non-zero means return the position of the right edge of the
7872 glyph, RIGHT_P zero means return the left edge position.
7874 If no glyph for POS exists in the matrix, return the position of
7875 the glyph with the next smaller position that is in the matrix, if
7876 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
7877 exists in the matrix, return the position of the glyph with the
7878 next larger position in OBJECT.
7880 Value is non-zero if a glyph was found. */
7883 fast_find_string_pos (w
, pos
, object
, hpos
, vpos
, x
, y
, right_p
)
7887 int *hpos
, *vpos
, *x
, *y
;
7890 int yb
= window_text_bottom_y (w
);
7891 struct glyph_row
*r
;
7892 struct glyph
*best_glyph
= NULL
;
7893 struct glyph_row
*best_row
= NULL
;
7896 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
7897 r
->enabled_p
&& r
->y
< yb
;
7900 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
7901 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
7904 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
7905 if (EQ (g
->object
, object
))
7907 if (g
->charpos
== pos
)
7914 else if (best_glyph
== NULL
7915 || ((abs (g
->charpos
- pos
)
7916 < abs (best_glyph
->charpos
- pos
))
7919 : g
->charpos
> pos
)))
7933 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
7937 *x
+= best_glyph
->pixel_width
;
7942 *vpos
= best_row
- w
->current_matrix
->rows
;
7945 return best_glyph
!= NULL
;
7949 /* Display the active region described by mouse_face_*
7950 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7953 show_mouse_face (dpyinfo
, draw
)
7954 struct mac_display_info
*dpyinfo
;
7955 enum draw_glyphs_face draw
;
7957 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7958 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7960 if (/* If window is in the process of being destroyed, don't bother
7962 w
->current_matrix
!= NULL
7963 /* Don't update mouse highlight if hidden */
7964 && (draw
!= DRAW_MOUSE_FACE
|| !dpyinfo
->mouse_face_hidden
)
7965 /* Recognize when we are called to operate on rows that don't exist
7966 anymore. This can happen when a window is split. */
7967 && dpyinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
7969 int phys_cursor_on_p
= w
->phys_cursor_on_p
;
7970 struct glyph_row
*row
, *first
, *last
;
7972 first
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_beg_row
);
7973 last
= MATRIX_ROW (w
->current_matrix
, dpyinfo
->mouse_face_end_row
);
7975 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
7977 int start_hpos
, end_hpos
, start_x
;
7979 /* For all but the first row, the highlight starts at column 0. */
7982 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7983 start_x
= dpyinfo
->mouse_face_beg_x
;
7992 end_hpos
= dpyinfo
->mouse_face_end_col
;
7994 end_hpos
= row
->used
[TEXT_AREA
];
7996 if (end_hpos
> start_hpos
)
7998 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7999 start_hpos
, end_hpos
, draw
, 0);
8002 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
8006 /* When we've written over the cursor, arrange for it to
8007 be displayed again. */
8008 if (phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
8009 x_display_cursor (w
, 1,
8010 w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8011 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8014 #if 0 /* MAC_TODO: mouse cursor */
8015 /* Change the mouse cursor. */
8016 if (draw
== DRAW_NORMAL_TEXT
)
8017 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8018 f
->output_data
.x
->text_cursor
);
8019 else if (draw
== DRAW_MOUSE_FACE
)
8020 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8021 f
->output_data
.x
->cross_cursor
);
8023 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
8024 f
->output_data
.x
->nontext_cursor
);
8028 /* Clear out the mouse-highlighted active region.
8029 Redraw it un-highlighted first. */
8032 clear_mouse_face (dpyinfo
)
8033 struct mac_display_info
*dpyinfo
;
8037 if (! NILP (dpyinfo
->mouse_face_window
))
8039 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
8043 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8044 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8045 dpyinfo
->mouse_face_window
= Qnil
;
8046 dpyinfo
->mouse_face_overlay
= Qnil
;
8051 /* Clear any mouse-face on window W. This function is part of the
8052 redisplay interface, and is called from try_window_id and similar
8053 functions to ensure the mouse-highlight is off. */
8056 x_clear_mouse_face (w
)
8059 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
8063 XSETWINDOW (window
, w
);
8064 if (EQ (window
, dpyinfo
->mouse_face_window
))
8065 clear_mouse_face (dpyinfo
);
8070 /* Just discard the mouse face information for frame F, if any.
8071 This is used when the size of F is changed. */
8074 cancel_mouse_face (f
)
8078 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8080 window
= dpyinfo
->mouse_face_window
;
8081 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
8083 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8084 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8085 dpyinfo
->mouse_face_window
= Qnil
;
8089 static struct scroll_bar
*x_window_to_scroll_bar ();
8090 static void x_scroll_bar_report_motion ();
8091 static void x_check_fullscreen
P_ ((struct frame
*));
8092 static void x_check_fullscreen_move
P_ ((struct frame
*));
8093 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
8096 /* Try to determine frame pixel position and size of the glyph under
8097 frame pixel coordinates X/Y on frame F . Return the position and
8098 size in *RECT. Value is non-zero if we could compute these
8102 glyph_rect (f
, x
, y
, rect
)
8110 window
= window_from_coordinates (f
, x
, y
, &part
, 0);
8113 struct window
*w
= XWINDOW (window
);
8114 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
8115 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
8117 frame_to_window_pixel_xy (w
, &x
, &y
);
8119 for (; r
< end
&& r
->enabled_p
; ++r
)
8120 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
8122 /* Found the row at y. */
8123 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
8124 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
8127 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
8128 rect
->bottom
= rect
->top
+ r
->height
;
8132 /* x is to the left of the first glyph in the row. */
8133 rect
->left
= XINT (w
->left
);
8134 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
8138 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
8139 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
8141 /* x is on a glyph. */
8142 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8143 rect
->right
= rect
->left
+ g
->pixel_width
;
8147 /* x is to the right of the last glyph in the row. */
8148 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
8149 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
8154 /* The y is not on any row. */
8158 /* Record the position of the mouse in last_mouse_glyph. */
8160 remember_mouse_glyph (f1
, gx
, gy
)
8164 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
8166 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
8167 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
8169 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
8170 round down even for negative values. */
8176 /* This was the original code from XTmouse_position, but it seems
8177 to give the position of the glyph diagonally next to the one
8178 the mouse is over. */
8179 gx
= (gx
+ width
- 1) / width
* width
;
8180 gy
= (gy
+ height
- 1) / height
* height
;
8182 gx
= gx
/ width
* width
;
8183 gy
= gy
/ height
* height
;
8186 last_mouse_glyph
.left
= gx
;
8187 last_mouse_glyph
.top
= gy
;
8188 last_mouse_glyph
.right
= gx
+ width
;
8189 last_mouse_glyph
.bottom
= gy
+ height
;
8193 /* Return the current position of the mouse.
8194 *fp should be a frame which indicates which display to ask about.
8196 If the mouse movement started in a scroll bar, set *fp, *bar_window,
8197 and *part to the frame, window, and scroll bar part that the mouse
8198 is over. Set *x and *y to the portion and whole of the mouse's
8199 position on the scroll bar.
8201 If the mouse movement started elsewhere, set *fp to the frame the
8202 mouse is on, *bar_window to nil, and *x and *y to the character cell
8205 Set *time to the server time-stamp for the time at which the mouse
8206 was at this position.
8208 Don't store anything if we don't have a valid set of values to report.
8210 This clears the mouse_moved flag, so we can wait for the next mouse
8214 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
8217 Lisp_Object
*bar_window
;
8218 enum scroll_bar_part
*part
;
8220 unsigned long *time
;
8223 int ignore1
, ignore2
;
8224 WindowPtr wp
= FrontWindow ();
8225 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8226 Lisp_Object frame
, tail
;
8230 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
8231 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
8234 /* Clear the mouse-moved flag for every frame on this display. */
8235 FOR_EACH_FRAME (tail
, frame
)
8236 XFRAME (frame
)->mouse_moved
= 0;
8238 last_mouse_scroll_bar
= Qnil
;
8240 #if TARGET_API_MAC_CARBON
8241 SetPort (GetWindowPort (wp
));
8246 GetMouse (&mouse_pos
);
8248 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
8249 &last_mouse_glyph
, insist
);
8252 *part
= scroll_bar_handle
;
8254 XSETINT (*x
, mouse_pos
.h
);
8255 XSETINT (*y
, mouse_pos
.v
);
8256 *time
= last_mouse_movement_time
;
8263 /************************************************************************
8264 Scroll bars, general
8265 ************************************************************************/
8267 /* Create a scroll bar and return the scroll bar vector for it. W is
8268 the Emacs window on which to create the scroll bar. TOP, LEFT,
8269 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
8272 static struct scroll_bar
*
8273 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
8275 int top
, left
, width
, height
, disp_top
, disp_height
;
8277 struct frame
*f
= XFRAME (w
->frame
);
8278 struct scroll_bar
*bar
8279 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
8287 r
.right
= left
+ width
;
8288 r
.bottom
= disp_top
+ disp_height
;
8290 #ifdef TARGET_API_MAC_CARBON
8291 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
8292 kControlScrollBarProc
, 0L);
8294 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
8297 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
8298 SetControlReference (ch
, (long) bar
);
8300 XSETWINDOW (bar
->window
, w
);
8301 XSETINT (bar
->top
, top
);
8302 XSETINT (bar
->left
, left
);
8303 XSETINT (bar
->width
, width
);
8304 XSETINT (bar
->height
, height
);
8305 XSETINT (bar
->start
, 0);
8306 XSETINT (bar
->end
, 0);
8307 bar
->dragging
= Qnil
;
8309 /* Add bar to its frame's list of scroll bars. */
8310 bar
->next
= FRAME_SCROLL_BARS (f
);
8312 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8313 if (!NILP (bar
->next
))
8314 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8321 /* Draw BAR's handle in the proper position.
8323 If the handle is already drawn from START to END, don't bother
8324 redrawing it, unless REBUILD is non-zero; in that case, always
8325 redraw it. (REBUILD is handy for drawing the handle after expose
8328 Normally, we want to constrain the start and end of the handle to
8329 fit inside its rectangle, but if the user is dragging the scroll
8330 bar handle, we want to let them drag it down all the way, so that
8331 the bar's top is as far down as it goes; otherwise, there's no way
8332 to move to the very end of the buffer. */
8335 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
8336 struct scroll_bar
*bar
;
8340 int dragging
= ! NILP (bar
->dragging
);
8341 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8342 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8343 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8344 int length
= end
- start
;
8346 /* If the display is already accurate, do nothing. */
8348 && start
== XINT (bar
->start
)
8349 && end
== XINT (bar
->end
))
8354 /* Make sure the values are reasonable, and try to preserve the
8355 distance between start and end. */
8358 else if (start
> top_range
)
8360 end
= start
+ length
;
8364 else if (end
> top_range
&& ! dragging
)
8367 /* Store the adjusted setting in the scroll bar. */
8368 XSETINT (bar
->start
, start
);
8369 XSETINT (bar
->end
, end
);
8371 /* Clip the end position, just for display. */
8372 if (end
> top_range
)
8375 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
8376 top positions, to make sure the handle is always at least that
8377 many pixels tall. */
8378 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
8380 SetControlMinimum (ch
, 0);
8381 /* Don't inadvertently activate deactivated scroll bars */
8382 if (GetControlMaximum (ch
) != -1)
8383 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
8385 SetControlValue (ch
, start
);
8386 #if TARGET_API_MAC_CARBON
8387 SetControlViewSize (ch
, end
- start
);
8394 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
8398 x_scroll_bar_remove (bar
)
8399 struct scroll_bar
*bar
;
8401 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
8405 /* Destroy the Mac scroll bar control */
8406 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
8408 /* Disassociate this scroll bar from its window. */
8409 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
8414 /* Set the handle of the vertical scroll bar for WINDOW to indicate
8415 that we are displaying PORTION characters out of a total of WHOLE
8416 characters, starting at POSITION. If WINDOW has no scroll bar,
8419 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
8421 int portion
, whole
, position
;
8423 struct frame
*f
= XFRAME (w
->frame
);
8424 struct scroll_bar
*bar
;
8425 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
8426 int window_x
, window_y
, window_width
, window_height
;
8428 /* Get window dimensions. */
8429 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8434 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8436 height
= window_height
;
8438 /* Compute the left edge of the scroll bar area. */
8439 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8440 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
8442 left
= XFASTINT (w
->left
);
8443 left
*= CANON_X_UNIT (f
);
8444 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
8446 /* Compute the width of the scroll bar which might be less than
8447 the width of the area reserved for the scroll bar. */
8448 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
8449 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
8453 /* Compute the left edge of the scroll bar. */
8454 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
8455 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
8457 sb_left
= left
+ (width
- sb_width
) / 2;
8459 /* Adjustments according to Inside Macintosh to make it look nice */
8461 disp_height
= height
;
8467 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
8473 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
8476 /* Does the scroll bar exist yet? */
8477 if (NILP (w
->vertical_scroll_bar
))
8480 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8481 left
, top
, width
, height
, 0);
8483 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
8485 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
8489 /* It may just need to be moved and resized. */
8492 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
8493 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
8497 /* If already correctly positioned, do nothing. */
8498 if (XINT (bar
->left
) == sb_left
8499 && XINT (bar
->top
) == top
8500 && XINT (bar
->width
) == sb_width
8501 && XINT (bar
->height
) == height
)
8505 /* Clear areas not covered by the scroll bar because it's not as
8506 wide as the area reserved for it . This makes sure a
8507 previous mode line display is cleared after C-x 2 C-x 1, for
8509 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
8510 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8511 left
, top
, area_width
, height
, 0);
8514 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
8515 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8516 sb_left
- 1, top
, 1, height
, 0);
8520 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
8521 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
8525 /* Remember new settings. */
8526 XSETINT (bar
->left
, sb_left
);
8527 XSETINT (bar
->top
, top
);
8528 XSETINT (bar
->width
, sb_width
);
8529 XSETINT (bar
->height
, height
);
8535 /* Set the scroll bar's current state, unless we're currently being
8537 if (NILP (bar
->dragging
))
8539 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
8542 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
8545 int start
= ((double) position
* top_range
) / whole
;
8546 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
8547 x_scroll_bar_set_handle (bar
, start
, end
, 0);
8553 /* The following three hooks are used when we're doing a thorough
8554 redisplay of the frame. We don't explicitly know which scroll bars
8555 are going to be deleted, because keeping track of when windows go
8556 away is a real pain - "Can you say set-window-configuration, boys
8557 and girls?" Instead, we just assert at the beginning of redisplay
8558 that *all* scroll bars are to be removed, and then save a scroll bar
8559 from the fiery pit when we actually redisplay its window. */
8561 /* Arrange for all scroll bars on FRAME to be removed at the next call
8562 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
8563 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
8566 XTcondemn_scroll_bars (frame
)
8569 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
8570 while (! NILP (FRAME_SCROLL_BARS (frame
)))
8573 bar
= FRAME_SCROLL_BARS (frame
);
8574 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
8575 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
8576 XSCROLL_BAR (bar
)->prev
= Qnil
;
8577 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
8578 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
8579 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
8584 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
8585 Note that WINDOW isn't necessarily condemned at all. */
8588 XTredeem_scroll_bar (window
)
8589 struct window
*window
;
8591 struct scroll_bar
*bar
;
8593 /* We can't redeem this window's scroll bar if it doesn't have one. */
8594 if (NILP (window
->vertical_scroll_bar
))
8597 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
8599 /* Unlink it from the condemned list. */
8601 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
8603 if (NILP (bar
->prev
))
8605 /* If the prev pointer is nil, it must be the first in one of
8607 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
8608 /* It's not condemned. Everything's fine. */
8610 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
8611 window
->vertical_scroll_bar
))
8612 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
8614 /* If its prev pointer is nil, it must be at the front of
8615 one or the other! */
8619 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
8621 if (! NILP (bar
->next
))
8622 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
8624 bar
->next
= FRAME_SCROLL_BARS (f
);
8626 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
8627 if (! NILP (bar
->next
))
8628 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
8632 /* Remove all scroll bars on FRAME that haven't been saved since the
8633 last call to `*condemn_scroll_bars_hook'. */
8636 XTjudge_scroll_bars (f
)
8639 Lisp_Object bar
, next
;
8641 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8643 /* Clear out the condemned list now so we won't try to process any
8644 more events on the hapless scroll bars. */
8645 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8647 for (; ! NILP (bar
); bar
= next
)
8649 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8651 x_scroll_bar_remove (b
);
8654 b
->next
= b
->prev
= Qnil
;
8657 /* Now there should be no references to the condemned scroll bars,
8658 and they should get garbage-collected. */
8663 activate_scroll_bars (frame
)
8669 bar
= FRAME_SCROLL_BARS (frame
);
8670 while (! NILP (bar
))
8672 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8673 #ifdef TARGET_API_MAC_CARBON
8674 ActivateControl (ch
);
8676 SetControlMaximum (ch
,
8677 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8678 XINT (XSCROLL_BAR (bar
)
8681 bar
= XSCROLL_BAR (bar
)->next
;
8687 deactivate_scroll_bars (frame
)
8693 bar
= FRAME_SCROLL_BARS (frame
);
8694 while (! NILP (bar
))
8696 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8697 #ifdef TARGET_API_MAC_CARBON
8698 DeactivateControl (ch
);
8700 SetControlMaximum (ch
, XINT (-1));
8702 bar
= XSCROLL_BAR (bar
)->next
;
8706 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8707 is set to something other than no_event, it is enqueued.
8709 This may be called from a signal handler, so we have to ignore GC
8713 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8714 struct scroll_bar
*bar
;
8717 struct input_event
*bufp
;
8719 if (! GC_WINDOWP (bar
->window
))
8722 bufp
->kind
= scroll_bar_click
;
8723 bufp
->frame_or_window
= bar
->window
;
8726 bar
->dragging
= Qnil
;
8730 case kControlUpButtonPart
:
8731 bufp
->part
= scroll_bar_up_arrow
;
8733 case kControlDownButtonPart
:
8734 bufp
->part
= scroll_bar_down_arrow
;
8736 case kControlPageUpPart
:
8737 bufp
->part
= scroll_bar_above_handle
;
8739 case kControlPageDownPart
:
8740 bufp
->part
= scroll_bar_below_handle
;
8742 #ifdef TARGET_API_MAC_CARBON
8745 case kControlIndicatorPart
:
8747 if (er
->what
== mouseDown
)
8748 bar
->dragging
= make_number (0);
8749 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8750 bufp
->part
= scroll_bar_handle
;
8756 /* Handle some mouse motion while someone is dragging the scroll bar.
8758 This may be called from a signal handler, so we have to ignore GC
8762 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8763 struct scroll_bar
*bar
;
8767 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8769 last_mouse_movement_time
= t
;
8772 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8774 /* If we're dragging the bar, display it. */
8775 if (! GC_NILP (bar
->dragging
))
8777 /* Where should the handle be now? */
8778 int new_start
= y_pos
- 24;
8780 if (new_start
!= XINT (bar
->start
))
8782 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8784 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8790 /* Return information to the user about the current position of the
8791 mouse on the scroll bar. */
8794 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8796 Lisp_Object
*bar_window
;
8797 enum scroll_bar_part
*part
;
8799 unsigned long *time
;
8801 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8802 WindowPtr wp
= FrontWindow ();
8804 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8805 int win_y
, top_range
;
8807 #if TARGET_API_MAC_CARBON
8808 SetPort (GetWindowPort (wp
));
8813 GetMouse (&mouse_pos
);
8815 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8816 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8818 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8822 if (! NILP (bar
->dragging
))
8823 win_y
-= XINT (bar
->dragging
);
8827 if (win_y
> top_range
)
8831 *bar_window
= bar
->window
;
8833 if (! NILP (bar
->dragging
))
8834 *part
= scroll_bar_handle
;
8835 else if (win_y
< XINT (bar
->start
))
8836 *part
= scroll_bar_above_handle
;
8837 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8838 *part
= scroll_bar_handle
;
8840 *part
= scroll_bar_below_handle
;
8842 XSETINT (*x
, win_y
);
8843 XSETINT (*y
, top_range
);
8846 last_mouse_scroll_bar
= Qnil
;
8848 *time
= last_mouse_movement_time
;
8851 /***********************************************************************
8853 ***********************************************************************/
8855 /* Notice if the text cursor of window W has been overwritten by a
8856 drawing operation that outputs glyphs starting at START_X and
8857 ending at END_X in the line given by output_cursor.vpos.
8858 Coordinates are area-relative. END_X < 0 means all the rest
8859 of the line after START_X has been written. */
8862 notice_overwritten_cursor (w
, area
, x0
, x1
, y0
, y1
)
8864 enum glyph_row_area area
;
8867 if (area
== TEXT_AREA
8868 && w
->phys_cursor_on_p
8869 && y0
<= w
->phys_cursor
.y
8870 && y1
>= w
->phys_cursor
.y
+ w
->phys_cursor_height
8871 && x0
<= w
->phys_cursor
.x
8872 && (x1
< 0 || x1
> w
->phys_cursor
.x
))
8873 w
->phys_cursor_on_p
= 0;
8877 /* Set clipping for output in glyph row ROW. W is the window in which
8878 we operate. GC is the graphics context to set clipping in.
8879 WHOLE_LINE_P non-zero means include the areas used for truncation
8880 mark display and alike in the clipping rectangle.
8882 ROW may be a text row or, e.g., a mode line. Text rows must be
8883 clipped to the interior of the window dedicated to text display,
8884 mode lines must be clipped to the whole window. */
8887 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8889 struct glyph_row
*row
;
8893 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8895 int window_x
, window_y
, window_width
, window_height
;
8897 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8899 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8900 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8901 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8902 clip_rect
.right
= clip_rect
.left
+ window_width
;
8903 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8905 /* If clipping to the whole line, including trunc marks, extend
8906 the rectangle to the left and increase its width. */
8909 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8910 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8913 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8917 /* Draw a hollow box cursor on window W in glyph row ROW. */
8920 x_draw_hollow_cursor (w
, row
)
8922 struct glyph_row
*row
;
8924 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8925 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8926 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8929 struct glyph
*cursor_glyph
;
8932 /* Compute frame-relative coordinates from window-relative
8934 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8935 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8936 + row
->ascent
- w
->phys_cursor_ascent
);
8937 h
= row
->height
- 1;
8939 /* Get the glyph the cursor is on. If we can't tell because
8940 the current matrix is invalid or such, give up. */
8941 cursor_glyph
= get_phys_cursor_glyph (w
);
8942 if (cursor_glyph
== NULL
)
8945 /* Compute the width of the rectangle to draw. If on a stretch
8946 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8947 rectangle as wide as the glyph, but use a canonical character
8949 wd
= cursor_glyph
->pixel_width
- 1;
8950 if (cursor_glyph
->type
== STRETCH_GLYPH
8951 && !x_stretch_cursor_p
)
8952 wd
= min (CANON_X_UNIT (f
), wd
);
8954 /* The foreground of cursor_gc is typically the same as the normal
8955 background color, which can cause the cursor box to be invisible. */
8956 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8957 if (dpyinfo
->scratch_cursor_gc
)
8958 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8960 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8961 GCForeground
, &xgcv
);
8962 gc
= dpyinfo
->scratch_cursor_gc
;
8964 /* Set clipping, draw the rectangle, and reset clipping again. */
8965 x_clip_to_row (w
, row
, gc
, 0);
8966 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
8967 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8971 /* Draw a bar cursor on window W in glyph row ROW.
8973 Implementation note: One would like to draw a bar cursor with an
8974 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8975 Unfortunately, I didn't find a font yet that has this property set.
8979 x_draw_bar_cursor (w
, row
, width
)
8981 struct glyph_row
*row
;
8984 /* If cursor hpos is out of bounds, don't draw garbage. This can
8985 happen in mini-buffer windows when switching between echo area
8986 glyphs and mini-buffer. */
8987 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8989 struct frame
*f
= XFRAME (w
->frame
);
8990 struct glyph
*cursor_glyph
;
8998 cursor_glyph
= get_phys_cursor_glyph (w
);
8999 if (cursor_glyph
== NULL
)
9002 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
9003 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
9004 mask
= GCForeground
| GCBackground
;
9005 dpy
= FRAME_MAC_DISPLAY (f
);
9006 window
= FRAME_MAC_WINDOW (f
);
9007 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
9010 XChangeGC (dpy
, gc
, mask
, &xgcv
);
9013 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
9014 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
9018 width
= f
->output_data
.mac
->cursor_width
;
9020 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
9021 x_clip_to_row (w
, row
, gc
, 0);
9022 XFillRectangle (dpy
, window
, gc
,
9024 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
9025 min (cursor_glyph
->pixel_width
, width
),
9027 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
9032 /* Clear the cursor of window W to background color, and mark the
9033 cursor as not shown. This is used when the text where the cursor
9034 is is about to be rewritten. */
9040 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
9041 x_update_window_cursor (w
, 0);
9045 /* Draw the cursor glyph of window W in glyph row ROW. See the
9046 comment of x_draw_glyphs for the meaning of HL. */
9049 x_draw_phys_cursor_glyph (w
, row
, hl
)
9051 struct glyph_row
*row
;
9052 enum draw_glyphs_face hl
;
9054 /* If cursor hpos is out of bounds, don't draw garbage. This can
9055 happen in mini-buffer windows when switching between echo area
9056 glyphs and mini-buffer. */
9057 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
9059 int on_p
= w
->phys_cursor_on_p
;
9060 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
9061 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
9063 w
->phys_cursor_on_p
= on_p
;
9065 /* When we erase the cursor, and ROW is overlapped by other
9066 rows, make sure that these overlapping parts of other rows
9068 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
9070 if (row
> w
->current_matrix
->rows
9071 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
9072 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
9074 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
9075 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
9076 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
9082 /* Erase the image of a cursor of window W from the screen. */
9085 x_erase_phys_cursor (w
)
9088 struct frame
*f
= XFRAME (w
->frame
);
9089 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
9090 int hpos
= w
->phys_cursor
.hpos
;
9091 int vpos
= w
->phys_cursor
.vpos
;
9092 int mouse_face_here_p
= 0;
9093 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
9094 struct glyph_row
*cursor_row
;
9095 struct glyph
*cursor_glyph
;
9096 enum draw_glyphs_face hl
;
9098 /* No cursor displayed or row invalidated => nothing to do on the
9100 if (w
->phys_cursor_type
== NO_CURSOR
)
9101 goto mark_cursor_off
;
9103 /* VPOS >= active_glyphs->nrows means that window has been resized.
9104 Don't bother to erase the cursor. */
9105 if (vpos
>= active_glyphs
->nrows
)
9106 goto mark_cursor_off
;
9108 /* If row containing cursor is marked invalid, there is nothing we
9110 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
9111 if (!cursor_row
->enabled_p
)
9112 goto mark_cursor_off
;
9114 /* If row is completely invisible, don't attempt to delete a cursor which
9115 isn't there. This may happen if cursor is at top of window, and
9116 we switch to a buffer with a header line in that window. */
9117 if (cursor_row
->visible_height
<= 0)
9118 goto mark_cursor_off
;
9120 /* This can happen when the new row is shorter than the old one.
9121 In this case, either x_draw_glyphs or clear_end_of_line
9122 should have cleared the cursor. Note that we wouldn't be
9123 able to erase the cursor in this case because we don't have a
9124 cursor glyph at hand. */
9125 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
9126 goto mark_cursor_off
;
9128 /* If the cursor is in the mouse face area, redisplay that when
9129 we clear the cursor. */
9130 if (! NILP (dpyinfo
->mouse_face_window
)
9131 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
9132 && (vpos
> dpyinfo
->mouse_face_beg_row
9133 || (vpos
== dpyinfo
->mouse_face_beg_row
9134 && hpos
>= dpyinfo
->mouse_face_beg_col
))
9135 && (vpos
< dpyinfo
->mouse_face_end_row
9136 || (vpos
== dpyinfo
->mouse_face_end_row
9137 && hpos
< dpyinfo
->mouse_face_end_col
))
9138 /* Don't redraw the cursor's spot in mouse face if it is at the
9139 end of a line (on a newline). The cursor appears there, but
9140 mouse highlighting does not. */
9141 && cursor_row
->used
[TEXT_AREA
] > hpos
)
9142 mouse_face_here_p
= 1;
9144 /* Maybe clear the display under the cursor. */
9145 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
9148 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
9150 cursor_glyph
= get_phys_cursor_glyph (w
);
9151 if (cursor_glyph
== NULL
)
9152 goto mark_cursor_off
;
9154 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
9156 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
9158 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
9160 cursor_glyph
->pixel_width
,
9161 cursor_row
->visible_height
,
9165 /* Erase the cursor by redrawing the character underneath it. */
9166 if (mouse_face_here_p
)
9167 hl
= DRAW_MOUSE_FACE
;
9169 hl
= DRAW_NORMAL_TEXT
;
9170 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
9173 w
->phys_cursor_on_p
= 0;
9174 w
->phys_cursor_type
= NO_CURSOR
;
9178 /* Non-zero if physical cursor of window W is within mouse face. */
9181 cursor_in_mouse_face_p (w
)
9184 struct mac_display_info
*dpyinfo
9185 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
9186 int in_mouse_face
= 0;
9188 if (WINDOWP (dpyinfo
->mouse_face_window
)
9189 && XWINDOW (dpyinfo
->mouse_face_window
) == w
)
9191 int hpos
= w
->phys_cursor
.hpos
;
9192 int vpos
= w
->phys_cursor
.vpos
;
9194 if (vpos
>= dpyinfo
->mouse_face_beg_row
9195 && vpos
<= dpyinfo
->mouse_face_end_row
9196 && (vpos
> dpyinfo
->mouse_face_beg_row
9197 || hpos
>= dpyinfo
->mouse_face_beg_col
)
9198 && (vpos
< dpyinfo
->mouse_face_end_row
9199 || hpos
< dpyinfo
->mouse_face_end_col
9200 || dpyinfo
->mouse_face_past_end
))
9204 return in_mouse_face
;
9208 /* Display or clear cursor of window W. If ON is zero, clear the
9209 cursor. If it is non-zero, display the cursor. If ON is nonzero,
9210 where to put the cursor is specified by HPOS, VPOS, X and Y. */
9213 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
9215 int on
, hpos
, vpos
, x
, y
;
9217 struct frame
*f
= XFRAME (w
->frame
);
9218 int new_cursor_type
;
9219 int new_cursor_width
;
9220 struct glyph_matrix
*current_glyphs
;
9221 struct glyph_row
*glyph_row
;
9222 struct glyph
*glyph
;
9223 int cursor_non_selected
;
9224 int active_cursor
= 1;
9226 /* This is pointless on invisible frames, and dangerous on garbaged
9227 windows and frames; in the latter case, the frame or window may
9228 be in the midst of changing its size, and x and y may be off the
9230 if (! FRAME_VISIBLE_P (f
)
9231 || FRAME_GARBAGED_P (f
)
9232 || vpos
>= w
->current_matrix
->nrows
9233 || hpos
>= w
->current_matrix
->matrix_w
)
9236 /* If cursor is off and we want it off, return quickly. */
9237 if (!on
&& !w
->phys_cursor_on_p
)
9240 current_glyphs
= w
->current_matrix
;
9241 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
9242 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
9244 /* If cursor row is not enabled, we don't really know where to
9245 display the cursor. */
9246 if (!glyph_row
->enabled_p
)
9248 w
->phys_cursor_on_p
= 0;
9252 xassert (interrupt_input_blocked
);
9254 /* Set new_cursor_type to the cursor we want to be displayed. In a
9255 mini-buffer window, we want the cursor only to appear if we are
9256 reading input from this window. For the selected window, we want
9257 the cursor type given by the frame parameter. If explicitly
9258 marked off, draw no cursor. In all other cases, we want a hollow
9261 = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows
,
9263 new_cursor_width
= -1;
9264 if (cursor_in_echo_area
9265 && FRAME_HAS_MINIBUF_P (f
)
9266 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
9268 if (w
== XWINDOW (echo_area_window
))
9269 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9272 if (cursor_non_selected
)
9273 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9275 new_cursor_type
= NO_CURSOR
;
9281 if (f
!= FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
9282 || w
!= XWINDOW (f
->selected_window
))
9286 if (MINI_WINDOW_P (w
)
9287 || !cursor_non_selected
9288 || NILP (XBUFFER (w
->buffer
)->cursor_type
))
9289 new_cursor_type
= NO_CURSOR
;
9291 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9295 struct buffer
*b
= XBUFFER (w
->buffer
);
9297 if (EQ (b
->cursor_type
, Qt
))
9298 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
9300 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
9302 if (w
->cursor_off_p
)
9304 if (new_cursor_type
== FILLED_BOX_CURSOR
)
9305 new_cursor_type
= HOLLOW_BOX_CURSOR
;
9306 else if (new_cursor_type
== BAR_CURSOR
&& new_cursor_width
> 1)
9307 new_cursor_width
= 1;
9309 new_cursor_type
= NO_CURSOR
;
9314 /* If cursor is currently being shown and we don't want it to be or
9315 it is in the wrong place, or the cursor type is not what we want,
9317 if (w
->phys_cursor_on_p
9319 || w
->phys_cursor
.x
!= x
9320 || w
->phys_cursor
.y
!= y
9321 || new_cursor_type
!= w
->phys_cursor_type
9322 || (new_cursor_type
== BAR_CURSOR
9323 && new_cursor_width
!= w
->phys_cursor_width
)))
9324 x_erase_phys_cursor (w
);
9326 /* If the cursor is now invisible and we want it to be visible,
9328 if (on
&& !w
->phys_cursor_on_p
)
9330 w
->phys_cursor_ascent
= glyph_row
->ascent
;
9331 w
->phys_cursor_height
= glyph_row
->height
;
9333 /* Set phys_cursor_.* before x_draw_.* is called because some
9334 of them may need the information. */
9335 w
->phys_cursor
.x
= x
;
9336 w
->phys_cursor
.y
= glyph_row
->y
;
9337 w
->phys_cursor
.hpos
= hpos
;
9338 w
->phys_cursor
.vpos
= vpos
;
9339 w
->phys_cursor_type
= new_cursor_type
;
9340 w
->phys_cursor_width
= new_cursor_width
;
9341 w
->phys_cursor_on_p
= 1;
9343 switch (new_cursor_type
)
9345 case HOLLOW_BOX_CURSOR
:
9346 x_draw_hollow_cursor (w
, glyph_row
);
9349 case FILLED_BOX_CURSOR
:
9350 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
9354 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
9367 /* Display the cursor on window W, or clear it. X and Y are window
9368 relative pixel coordinates. HPOS and VPOS are glyph matrix
9369 positions. If W is not the selected window, display a hollow
9370 cursor. ON non-zero means display the cursor at X, Y which
9371 correspond to HPOS, VPOS, otherwise it is cleared. */
9374 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
9376 int on
, hpos
, vpos
, x
, y
;
9379 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
9384 /* Display the cursor on window W, or clear it, according to ON_P.
9385 Don't change the cursor's position. */
9388 x_update_cursor (f
, on_p
)
9392 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
9396 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9397 in the window tree rooted at W. */
9400 x_update_cursor_in_window_tree (w
, on_p
)
9406 if (!NILP (w
->hchild
))
9407 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
9408 else if (!NILP (w
->vchild
))
9409 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
9411 x_update_window_cursor (w
, on_p
);
9413 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
9418 /* Switch the display of W's cursor on or off, according to the value
9422 x_update_window_cursor (w
, on
)
9426 /* Don't update cursor in windows whose frame is in the process
9427 of being deleted. */
9428 if (w
->current_matrix
)
9431 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
,
9432 w
->phys_cursor
.vpos
, w
->phys_cursor
.x
,
9443 #if 0 /* MAC_TODO: no icon support yet. */
9445 x_bitmap_icon (f
, icon
)
9451 if (FRAME_W32_WINDOW (f
) == 0)
9455 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
9456 else if (STRINGP (icon
))
9457 hicon
= LoadImage (NULL
, (LPCTSTR
) XSTRING (icon
)->data
, IMAGE_ICON
, 0, 0,
9458 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9459 else if (SYMBOLP (icon
))
9463 if (EQ (icon
, intern ("application")))
9464 name
= (LPCTSTR
) IDI_APPLICATION
;
9465 else if (EQ (icon
, intern ("hand")))
9466 name
= (LPCTSTR
) IDI_HAND
;
9467 else if (EQ (icon
, intern ("question")))
9468 name
= (LPCTSTR
) IDI_QUESTION
;
9469 else if (EQ (icon
, intern ("exclamation")))
9470 name
= (LPCTSTR
) IDI_EXCLAMATION
;
9471 else if (EQ (icon
, intern ("asterisk")))
9472 name
= (LPCTSTR
) IDI_ASTERISK
;
9473 else if (EQ (icon
, intern ("winlogo")))
9474 name
= (LPCTSTR
) IDI_WINLOGO
;
9478 hicon
= LoadIcon (NULL
, name
);
9486 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
9491 #endif /* MAC_TODO */
9493 /************************************************************************
9495 ************************************************************************/
9497 /* Display Error Handling functions not used on W32. Listing them here
9498 helps diff stay in step when comparing w32term.c with xterm.c.
9500 x_error_catcher (display, error)
9501 x_catch_errors (dpy)
9502 x_catch_errors_unwind (old_val)
9503 x_check_errors (dpy, format)
9504 x_had_errors_p (dpy)
9505 x_clear_errors (dpy)
9506 x_uncatch_errors (dpy, count)
9508 x_connection_signal (signalnum)
9509 x_connection_closed (dpy, error_message)
9510 x_error_quitter (display, error)
9511 x_error_handler (display, error)
9512 x_io_error_quitter (display)
9517 /* Changing the font of the frame. */
9519 /* Give frame F the font named FONTNAME as its default font, and
9520 return the full name of that font. FONTNAME may be a wildcard
9521 pattern; in that case, we choose some font that fits the pattern.
9522 The return value shows which font we chose. */
9525 x_new_font (f
, fontname
)
9527 register char *fontname
;
9529 struct font_info
*fontp
9530 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9535 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
9536 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
9537 FRAME_FONTSET (f
) = -1;
9539 /* Compute the scroll bar width in character columns. */
9540 if (f
->scroll_bar_pixel_width
> 0)
9542 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9543 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9547 int wid
= FONT_WIDTH (FRAME_FONT (f
));
9548 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9551 /* Now make the frame display the given font. */
9552 if (FRAME_MAC_WINDOW (f
) != 0)
9554 frame_update_line_height (f
);
9555 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
9556 x_set_window_size (f
, 0, f
->width
, f
->height
);
9559 /* If we are setting a new frame's font for the first time,
9560 there are no faces yet, so this font's height is the line height. */
9561 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
9563 return build_string (fontp
->full_name
);
9566 /* Give frame F the fontset named FONTSETNAME as its default font, and
9567 return the full name of that fontset. FONTSETNAME may be a wildcard
9568 pattern; in that case, we choose some fontset that fits the pattern.
9569 The return value shows which fontset we chose. */
9572 x_new_fontset (f
, fontsetname
)
9576 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9582 if (FRAME_FONTSET (f
) == fontset
)
9583 /* This fontset is already set in frame F. There's nothing more
9585 return fontset_name (fontset
);
9587 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9589 if (!STRINGP (result
))
9590 /* Can't load ASCII font. */
9593 /* Since x_new_font doesn't update any fontset information, do it now. */
9594 FRAME_FONTSET(f
) = fontset
;
9596 return build_string (fontsetname
);
9599 /* Compute actual fringe widths */
9602 x_compute_fringe_widths (f
, redraw
)
9606 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9607 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9608 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9610 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9611 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9612 int left_fringe_width
, right_fringe_width
;
9614 if (!NILP (left_fringe
))
9615 left_fringe
= Fcdr (left_fringe
);
9616 if (!NILP (right_fringe
))
9617 right_fringe
= Fcdr (right_fringe
);
9619 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9620 XINT (left_fringe
));
9621 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9622 XINT (right_fringe
));
9624 if (left_fringe_width
|| right_fringe_width
)
9626 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9627 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9628 int conf_wid
= left_wid
+ right_wid
;
9629 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9630 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9631 int real_wid
= cols
* font_wid
;
9632 if (left_wid
&& right_wid
)
9634 if (left_fringe_width
< 0)
9636 /* Left fringe width is fixed, adjust right fringe if necessary */
9637 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9638 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9640 else if (right_fringe_width
< 0)
9642 /* Right fringe width is fixed, adjust left fringe if necessary */
9643 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9644 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9648 /* Adjust both fringes with an equal amount.
9649 Note that we are doing integer arithmetic here, so don't
9650 lose a pixel if the total width is an odd number. */
9651 int fill
= real_wid
- conf_wid
;
9652 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9653 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9656 else if (left_fringe_width
)
9658 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9659 f
->output_data
.mac
->right_fringe_width
= 0;
9663 f
->output_data
.mac
->left_fringe_width
= 0;
9664 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9666 f
->output_data
.mac
->fringe_cols
= cols
;
9667 f
->output_data
.mac
->fringes_extra
= real_wid
;
9671 f
->output_data
.mac
->left_fringe_width
= 0;
9672 f
->output_data
.mac
->right_fringe_width
= 0;
9673 f
->output_data
.mac
->fringe_cols
= 0;
9674 f
->output_data
.mac
->fringes_extra
= 0;
9677 if (redraw
&& FRAME_VISIBLE_P (f
))
9678 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9679 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9680 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9684 /***********************************************************************
9685 TODO: W32 Input Methods
9686 ***********************************************************************/
9687 /* Listing missing functions from xterm.c helps diff stay in step.
9689 xim_destroy_callback (xim, client_data, call_data)
9690 xim_open_dpy (dpyinfo, resource_name)
9692 xim_instantiate_callback (display, client_data, call_data)
9693 xim_initialize (dpyinfo, resource_name)
9694 xim_close_dpy (dpyinfo)
9699 /* Calculate the absolute position in frame F
9700 from its current recorded position values and gravity. */
9703 x_calc_absolute_position (f
)
9707 int flags
= f
->output_data
.mac
->size_hint_flags
;
9711 /* Find the position of the outside upper-left corner of
9712 the inner window, with respect to the outer window. */
9713 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9716 GetPort (&savePort
);
9718 #if TARGET_API_MAC_CARBON
9719 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
9721 SetPort (FRAME_MAC_WINDOW (f
));
9724 #if TARGET_API_MAC_CARBON
9728 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
9729 SetPt(&pt
, r
.left
, r
.top
);
9731 #else /* not TARGET_API_MAC_CARBON */
9732 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9733 #endif /* not TARGET_API_MAC_CARBON */
9734 LocalToGlobal (&pt
);
9738 /* Treat negative positions as relative to the leftmost bottommost
9739 position that fits on the screen. */
9740 if (flags
& XNegative
)
9741 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9742 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9744 + f
->output_data
.mac
->left_pos
);
9745 /* NTEMACS_TODO: Subtract menubar height? */
9746 if (flags
& YNegative
)
9747 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9748 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9750 + f
->output_data
.mac
->top_pos
);
9751 /* The left_pos and top_pos
9752 are now relative to the top and left screen edges,
9753 so the flags should correspond. */
9754 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9757 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9758 to really change the position, and 0 when calling from
9759 x_make_frame_visible (in that case, XOFF and YOFF are the current
9760 position values). It is -1 when calling from x_set_frame_parameters,
9761 which means, do adjust for borders but don't change the gravity. */
9764 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9766 register int xoff
, yoff
;
9769 int modified_top
, modified_left
;
9771 if (change_gravity
> 0)
9773 f
->output_data
.mac
->top_pos
= yoff
;
9774 f
->output_data
.mac
->left_pos
= xoff
;
9775 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9777 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9779 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9780 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9782 x_calc_absolute_position (f
);
9785 x_wm_set_size_hint (f
, (long) 0, 0);
9787 modified_left
= f
->output_data
.mac
->left_pos
;
9788 modified_top
= f
->output_data
.mac
->top_pos
;
9790 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
9791 modified_top
+ 42, false);
9796 /* Call this to change the size of frame F's x-window.
9797 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9798 for this size change and subsequent size changes.
9799 Otherwise we leave the window gravity unchanged. */
9802 x_set_window_size (f
, change_gravity
, cols
, rows
)
9807 int pixelwidth
, pixelheight
;
9811 check_frame_size (f
, &rows
, &cols
);
9812 f
->output_data
.mac
->vertical_scroll_bar_extra
9813 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9815 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9817 x_compute_fringe_widths (f
, 0);
9819 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9820 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9822 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9823 x_wm_set_size_hint (f
, (long) 0, 0);
9825 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9827 /* Now, strictly speaking, we can't be sure that this is accurate,
9828 but the window manager will get around to dealing with the size
9829 change request eventually, and we'll hear how it went when the
9830 ConfigureNotify event gets here.
9832 We could just not bother storing any of this information here,
9833 and let the ConfigureNotify event set everything up, but that
9834 might be kind of confusing to the Lisp code, since size changes
9835 wouldn't be reported in the frame parameters until some random
9836 point in the future when the ConfigureNotify event arrives.
9838 We pass 1 for DELAY since we can't run Lisp code inside of
9840 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9841 PIXEL_WIDTH (f
) = pixelwidth
;
9842 PIXEL_HEIGHT (f
) = pixelheight
;
9844 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9845 receive in the ConfigureNotify event; if we get what we asked
9846 for, then the event won't cause the screen to become garbaged, so
9847 we have to make sure to do it here. */
9848 SET_FRAME_GARBAGED (f
);
9850 XFlush (FRAME_X_DISPLAY (f
));
9852 /* If cursor was outside the new size, mark it as off. */
9853 mark_window_cursors_off (XWINDOW (f
->root_window
));
9855 /* Clear out any recollection of where the mouse highlighting was,
9856 since it might be in a place that's outside the new frame size.
9857 Actually checking whether it is outside is a pain in the neck,
9858 so don't try--just let the highlighting be done afresh with new size. */
9859 cancel_mouse_face (f
);
9864 /* Mouse warping. */
9866 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9869 x_set_mouse_position (f
, x
, y
)
9875 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9876 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9878 if (pix_x
< 0) pix_x
= 0;
9879 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9881 if (pix_y
< 0) pix_y
= 0;
9882 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9884 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9888 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9892 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9895 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9896 0, 0, 0, 0, pix_x
, pix_y
);
9902 /* focus shifting, raising and lowering. */
9905 x_focus_on_frame (f
)
9908 #if 0 /* This proves to be unpleasant. */
9912 /* I don't think that the ICCCM allows programs to do things like this
9913 without the interaction of the window manager. Whatever you end up
9914 doing with this code, do it to x_unfocus_frame too. */
9915 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9916 RevertToPointerRoot
, CurrentTime
);
9926 /* Raise frame F. */
9931 if (f
->async_visible
)
9932 SelectWindow (FRAME_MAC_WINDOW (f
));
9935 /* Lower frame F. */
9940 if (f
->async_visible
)
9941 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9945 XTframe_raise_lower (f
, raise_flag
)
9955 /* Change of visibility. */
9957 /* This tries to wait until the frame is really visible.
9958 However, if the window manager asks the user where to position
9959 the frame, this will return before the user finishes doing that.
9960 The frame will not actually be visible at that time,
9961 but it will become visible later when the window manager
9962 finishes with it. */
9965 x_make_frame_visible (f
)
9969 int original_top
, original_left
;
9973 if (! FRAME_VISIBLE_P (f
))
9975 /* We test FRAME_GARBAGED_P here to make sure we don't
9976 call x_set_offset a second time
9977 if we get to x_make_frame_visible a second time
9978 before the window gets really visible. */
9979 if (! FRAME_ICONIFIED_P (f
)
9980 && ! f
->output_data
.mac
->asked_for_visible
)
9981 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
9982 f
->output_data
.mac
->top_pos
, 0);
9984 f
->output_data
.mac
->asked_for_visible
= 1;
9986 ShowWindow (FRAME_MAC_WINDOW (f
));
9989 XFlush (FRAME_MAC_DISPLAY (f
));
9991 #if 0 /* MAC_TODO */
9992 /* Synchronize to ensure Emacs knows the frame is visible
9993 before we do anything else. We do this loop with input not blocked
9994 so that incoming events are handled. */
9999 /* This must come after we set COUNT. */
10002 XSETFRAME (frame
, f
);
10004 /* Wait until the frame is visible. Process X events until a
10005 MapNotify event has been seen, or until we think we won't get a
10006 MapNotify at all.. */
10007 for (count
= input_signal_count
+ 10;
10008 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
10010 /* Force processing of queued events. */
10013 /* Machines that do polling rather than SIGIO have been
10014 observed to go into a busy-wait here. So we'll fake an
10015 alarm signal to let the handler know that there's something
10016 to be read. We used to raise a real alarm, but it seems
10017 that the handler isn't always enabled here. This is
10019 if (input_polling_used ())
10021 /* It could be confusing if a real alarm arrives while
10022 processing the fake one. Turn it off and let the
10023 handler reset it. */
10024 extern void poll_for_input_1
P_ ((void));
10025 int old_poll_suppress_count
= poll_suppress_count
;
10026 poll_suppress_count
= 1;
10027 poll_for_input_1 ();
10028 poll_suppress_count
= old_poll_suppress_count
;
10031 /* See if a MapNotify event has been processed. */
10032 FRAME_SAMPLE_VISIBILITY (f
);
10035 #endif /* MAC_TODO */
10038 /* Change from mapped state to withdrawn state. */
10040 /* Make the frame visible (mapped and not iconified). */
10043 x_make_frame_invisible (f
)
10046 /* Don't keep the highlight on an invisible frame. */
10047 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10048 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10052 HideWindow (FRAME_MAC_WINDOW (f
));
10054 /* We can't distinguish this from iconification
10055 just by the event that we get from the server.
10056 So we can't win using the usual strategy of letting
10057 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
10058 and synchronize with the server to make sure we agree. */
10060 FRAME_ICONIFIED_P (f
) = 0;
10061 f
->async_visible
= 0;
10062 f
->async_iconified
= 0;
10067 /* Change window state from mapped to iconified. */
10070 x_iconify_frame (f
)
10073 #if 0 /* MAC_TODO: really no iconify on Mac */
10077 /* Don't keep the highlight on an invisible frame. */
10078 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
10079 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
10081 if (f
->async_iconified
)
10086 FRAME_SAMPLE_VISIBILITY (f
);
10088 type
= x_icon_type (f
);
10090 x_bitmap_icon (f
, type
);
10092 #ifdef USE_X_TOOLKIT
10094 if (! FRAME_VISIBLE_P (f
))
10096 if (! EQ (Vx_no_window_manager
, Qt
))
10097 x_wm_set_window_state (f
, IconicState
);
10098 /* This was XtPopup, but that did nothing for an iconified frame. */
10099 XtMapWidget (f
->output_data
.x
->widget
);
10100 /* The server won't give us any event to indicate
10101 that an invisible frame was changed to an icon,
10102 so we have to record it here. */
10105 f
->async_iconified
= 1;
10106 f
->async_visible
= 0;
10111 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
10112 XtWindow (f
->output_data
.x
->widget
),
10113 DefaultScreen (FRAME_X_DISPLAY (f
)));
10117 error ("Can't notify window manager of iconification");
10119 f
->async_iconified
= 1;
10120 f
->async_visible
= 0;
10124 XFlush (FRAME_X_DISPLAY (f
));
10126 #else /* not USE_X_TOOLKIT */
10128 /* Make sure the X server knows where the window should be positioned,
10129 in case the user deiconifies with the window manager. */
10130 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
10131 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
10133 /* Since we don't know which revision of X we're running, we'll use both
10134 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
10136 /* X11R4: send a ClientMessage to the window manager using the
10137 WM_CHANGE_STATE type. */
10141 message
.xclient
.window
= FRAME_X_WINDOW (f
);
10142 message
.xclient
.type
= ClientMessage
;
10143 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
10144 message
.xclient
.format
= 32;
10145 message
.xclient
.data
.l
[0] = IconicState
;
10147 if (! XSendEvent (FRAME_X_DISPLAY (f
),
10148 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
10150 SubstructureRedirectMask
| SubstructureNotifyMask
,
10153 UNBLOCK_INPUT_RESIGNAL
;
10154 error ("Can't notify window manager of iconification");
10158 /* X11R3: set the initial_state field of the window manager hints to
10160 x_wm_set_window_state (f
, IconicState
);
10162 if (!FRAME_VISIBLE_P (f
))
10164 /* If the frame was withdrawn, before, we must map it. */
10165 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
10168 f
->async_iconified
= 1;
10169 f
->async_visible
= 0;
10171 XFlush (FRAME_X_DISPLAY (f
));
10173 #endif /* not USE_X_TOOLKIT */
10174 #endif /* MAC_TODO */
10178 /* Destroy the X window of frame F. */
10181 x_destroy_window (f
)
10184 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10188 DisposeWindow (FRAME_MAC_WINDOW (f
));
10190 free_frame_menubar (f
);
10191 free_frame_faces (f
);
10193 xfree (f
->output_data
.mac
);
10194 f
->output_data
.mac
= 0;
10195 if (f
== dpyinfo
->x_focus_frame
)
10196 dpyinfo
->x_focus_frame
= 0;
10197 if (f
== dpyinfo
->x_focus_event_frame
)
10198 dpyinfo
->x_focus_event_frame
= 0;
10199 if (f
== dpyinfo
->x_highlight_frame
)
10200 dpyinfo
->x_highlight_frame
= 0;
10202 dpyinfo
->reference_count
--;
10204 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10206 dpyinfo
->mouse_face_beg_row
10207 = dpyinfo
->mouse_face_beg_col
= -1;
10208 dpyinfo
->mouse_face_end_row
10209 = dpyinfo
->mouse_face_end_col
= -1;
10210 dpyinfo
->mouse_face_window
= Qnil
;
10211 dpyinfo
->mouse_face_deferred_gc
= 0;
10212 dpyinfo
->mouse_face_mouse_frame
= 0;
10218 /* Setting window manager hints. */
10220 /* Set the normal size hints for the window manager, for frame F.
10221 FLAGS is the flags word to use--or 0 meaning preserve the flags
10222 that the window now has.
10223 If USER_POSITION is nonzero, we set the USPosition
10224 flag (this is useful when FLAGS is 0). */
10226 x_wm_set_size_hint (f
, flags
, user_position
)
10231 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10232 XSizeHints size_hints
;
10234 #ifdef USE_X_TOOLKIT
10237 Dimension widget_width
, widget_height
;
10238 Window window
= XtWindow (f
->output_data
.x
->widget
);
10239 #else /* not USE_X_TOOLKIT */
10240 Window window
= FRAME_X_WINDOW (f
);
10241 #endif /* not USE_X_TOOLKIT */
10243 /* Setting PMaxSize caused various problems. */
10244 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10246 size_hints
.x
= f
->output_data
.x
->left_pos
;
10247 size_hints
.y
= f
->output_data
.x
->top_pos
;
10249 #ifdef USE_X_TOOLKIT
10250 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10251 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10252 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10253 size_hints
.height
= widget_height
;
10254 size_hints
.width
= widget_width
;
10255 #else /* not USE_X_TOOLKIT */
10256 size_hints
.height
= PIXEL_HEIGHT (f
);
10257 size_hints
.width
= PIXEL_WIDTH (f
);
10258 #endif /* not USE_X_TOOLKIT */
10260 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10261 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10262 size_hints
.max_width
10263 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10264 size_hints
.max_height
10265 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10267 /* Calculate the base and minimum sizes.
10269 (When we use the X toolkit, we don't do it here.
10270 Instead we copy the values that the widgets are using, below.) */
10271 #ifndef USE_X_TOOLKIT
10273 int base_width
, base_height
;
10274 int min_rows
= 0, min_cols
= 0;
10276 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10277 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10279 check_frame_size (f
, &min_rows
, &min_cols
);
10281 /* The window manager uses the base width hints to calculate the
10282 current number of rows and columns in the frame while
10283 resizing; min_width and min_height aren't useful for this
10284 purpose, since they might not give the dimensions for a
10285 zero-row, zero-column frame.
10287 We use the base_width and base_height members if we have
10288 them; otherwise, we set the min_width and min_height members
10289 to the size for a zero x zero frame. */
10292 size_hints
.flags
|= PBaseSize
;
10293 size_hints
.base_width
= base_width
;
10294 size_hints
.base_height
= base_height
;
10295 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10296 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10298 size_hints
.min_width
= base_width
;
10299 size_hints
.min_height
= base_height
;
10303 /* If we don't need the old flags, we don't need the old hint at all. */
10306 size_hints
.flags
|= flags
;
10309 #endif /* not USE_X_TOOLKIT */
10312 XSizeHints hints
; /* Sometimes I hate X Windows... */
10313 long supplied_return
;
10317 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10320 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10323 #ifdef USE_X_TOOLKIT
10324 size_hints
.base_height
= hints
.base_height
;
10325 size_hints
.base_width
= hints
.base_width
;
10326 size_hints
.min_height
= hints
.min_height
;
10327 size_hints
.min_width
= hints
.min_width
;
10331 size_hints
.flags
|= flags
;
10336 if (hints
.flags
& PSize
)
10337 size_hints
.flags
|= PSize
;
10338 if (hints
.flags
& PPosition
)
10339 size_hints
.flags
|= PPosition
;
10340 if (hints
.flags
& USPosition
)
10341 size_hints
.flags
|= USPosition
;
10342 if (hints
.flags
& USSize
)
10343 size_hints
.flags
|= USSize
;
10347 #ifndef USE_X_TOOLKIT
10352 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10353 size_hints
.flags
|= PWinGravity
;
10357 size_hints
.flags
&= ~ PPosition
;
10358 size_hints
.flags
|= USPosition
;
10360 #endif /* PWinGravity */
10363 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10365 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10367 #endif /* MAC_TODO */
10370 #if 0 /* MAC_TODO: hide application instead of iconify? */
10371 /* Used for IconicState or NormalState */
10374 x_wm_set_window_state (f
, state
)
10378 #ifdef USE_X_TOOLKIT
10381 XtSetArg (al
[0], XtNinitialState
, state
);
10382 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10383 #else /* not USE_X_TOOLKIT */
10384 Window window
= FRAME_X_WINDOW (f
);
10386 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10387 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10389 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10390 #endif /* not USE_X_TOOLKIT */
10394 x_wm_set_icon_pixmap (f
, pixmap_id
)
10398 Pixmap icon_pixmap
;
10400 #ifndef USE_X_TOOLKIT
10401 Window window
= FRAME_X_WINDOW (f
);
10406 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10407 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10411 /* It seems there is no way to turn off use of an icon pixmap.
10412 The following line does it, only if no icon has yet been created,
10413 for some window managers. But with mwm it crashes.
10414 Some people say it should clear the IconPixmapHint bit in this case,
10415 but that doesn't work, and the X consortium said it isn't the
10416 right thing at all. Since there is no way to win,
10417 best to explicitly give up. */
10419 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10425 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10429 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10430 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10433 #else /* not USE_X_TOOLKIT */
10435 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10436 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10438 #endif /* not USE_X_TOOLKIT */
10441 #endif /* MAC_TODO */
10444 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10446 int icon_x
, icon_y
;
10448 #if 0 /* MAC_TODO: no icons on Mac */
10449 #ifdef USE_X_TOOLKIT
10450 Window window
= XtWindow (f
->output_data
.x
->widget
);
10452 Window window
= FRAME_X_WINDOW (f
);
10455 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10456 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10457 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10459 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10460 #endif /* MAC_TODO */
10464 /***********************************************************************
10466 ***********************************************************************/
10468 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10471 x_get_font_info (f
, font_idx
)
10475 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10478 /* the global font name table */
10479 char **font_name_table
= NULL
;
10480 int font_name_table_size
= 0;
10481 int font_name_count
= 0;
10483 /* compare two strings ignoring case */
10485 stricmp (const char *s
, const char *t
)
10487 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10490 return tolower (*s
) - tolower (*t
);
10493 /* compare two strings ignoring case and handling wildcard */
10495 wildstrieq (char *s1
, char *s2
)
10497 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10500 return stricmp (s1
, s2
) == 0;
10503 /* Assume parameter 1 is fully qualified, no wildcards. */
10505 mac_font_pattern_match (fontname
, pattern
)
10509 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10510 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10513 /* Copy fontname so we can modify it during comparison. */
10514 strcpy (font_name_copy
, fontname
);
10519 /* Turn pattern into a regexp and do a regexp match. */
10520 for (; *pattern
; pattern
++)
10522 if (*pattern
== '?')
10524 else if (*pattern
== '*')
10535 return (fast_c_string_match_ignore_case (build_string (regex
),
10536 font_name_copy
) >= 0);
10539 /* Two font specs are considered to match if their foundry, family,
10540 weight, slant, and charset match. */
10542 mac_font_match (char *mf
, char *xf
)
10544 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10545 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10547 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10548 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10549 return mac_font_pattern_match (mf
, xf
);
10551 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10552 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10553 return mac_font_pattern_match (mf
, xf
);
10555 return (wildstrieq (m_foundry
, x_foundry
)
10556 && wildstrieq (m_family
, x_family
)
10557 && wildstrieq (m_weight
, x_weight
)
10558 && wildstrieq (m_slant
, x_slant
)
10559 && wildstrieq (m_charset
, x_charset
))
10560 || mac_font_pattern_match (mf
, xf
);
10565 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10567 char foundry
[32], family
[32], cs
[32];
10568 char xf
[255], *result
, *p
;
10570 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10572 strcpy(foundry
, "Apple");
10573 strcpy(family
, name
);
10575 switch (scriptcode
)
10577 case smTradChinese
:
10578 strcpy(cs
, "big5-0");
10580 case smSimpChinese
:
10581 strcpy(cs
, "gb2312.1980-0");
10584 strcpy(cs
, "jisx0208.1983-sjis");
10587 /* Each Apple Japanese font is entered into the font table
10588 twice: once as a jisx0208.1983-sjis font and once as a
10589 jisx0201.1976-0 font. The latter can be used to display
10590 the ascii charset and katakana-jisx0201 charset. A
10591 negative script code signals that the name of this latter
10592 font is being built. */
10593 strcpy(cs
, "jisx0201.1976-0");
10596 strcpy(cs
, "ksc5601.1989-0");
10599 strcpy(cs
, "mac-roman");
10604 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10605 foundry
, family
, style
& bold
? "bold" : "medium",
10606 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10608 result
= (char *) xmalloc (strlen (xf
) + 1);
10609 strcpy (result
, xf
);
10610 for (p
= result
; *p
; p
++)
10616 /* Convert an X font spec to the corresponding mac font name, which
10617 can then be passed to GetFNum after conversion to a Pascal string.
10618 For ordinary Mac fonts, this should just be their names, like
10619 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10620 collection contain their charset designation in their names, like
10621 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10622 names are handled accordingly. */
10624 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10626 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10630 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10631 foundry
, family
, weight
, slant
, cs
) != 5 &&
10632 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10633 foundry
, family
, weight
, slant
, cs
) != 5)
10636 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10637 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10638 || strcmp (cs
, "jisx0201.1976-0") == 0
10639 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10640 strcpy(mf
, family
);
10642 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10646 /* Sets up the table font_name_table to contain the list of all
10647 monospace fonts in the system the first time the table is used so
10648 that the Resource Manager need not be accessed every time this
10649 information is needed. */
10652 init_font_name_table ()
10654 #if TARGET_API_MAC_CARBON
10657 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
10659 FMFontFamilyIterator ffi
;
10660 FMFontFamilyInstanceIterator ffii
;
10663 /* Create a dummy instance iterator here to avoid creating and
10664 destroying it in the loop. */
10665 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
10667 /* Create an iterator to enumerate the font families. */
10668 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
10671 FMDisposeFontFamilyInstanceIterator (&ffii
);
10675 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
10683 if (FMGetFontFamilyName (ff
, name
) != noErr
)
10687 sc
= FontToScript (ff
);
10689 /* Point the instance iterator at the current font family. */
10690 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
10693 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
10696 if (font_name_table_size
== 0)
10698 font_name_table_size
= 16;
10699 font_name_table
= (char **)
10700 xmalloc (font_name_table_size
* sizeof (char *));
10702 else if (font_name_count
+ 1 >= font_name_table_size
)
10704 font_name_table_size
+= 16;
10705 font_name_table
= (char **)
10706 xrealloc (font_name_table
,
10707 font_name_table_size
* sizeof (char *));
10709 font_name_table
[font_name_count
++]
10710 = mac_to_x_fontname (name
, size
, style
, sc
);
10714 /* Dispose of the iterators. */
10715 FMDisposeFontFamilyIterator (&ffi
);
10716 FMDisposeFontFamilyInstanceIterator (&ffii
);
10720 #endif /* TARGET_API_MAC_CARBON */
10722 SInt16 fontnum
, old_fontnum
;
10723 int num_mac_fonts
= CountResources('FOND');
10725 Handle font_handle
, font_handle_2
;
10726 short id
, scriptcode
;
10729 struct FontAssoc
*fat
;
10730 struct AsscEntry
*assc_entry
;
10732 GetPort (&port
); /* save the current font number used */
10733 #if TARGET_API_MAC_CARBON
10734 old_fontnum
= GetPortTextFont (port
);
10736 old_fontnum
= port
->txFont
;
10739 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
10741 font_handle
= GetIndResource ('FOND', i
);
10745 GetResInfo (font_handle
, &id
, &type
, name
);
10746 GetFNum (name
, &fontnum
);
10751 TextFont (fontnum
);
10752 scriptcode
= FontToScript (fontnum
);
10755 HLock (font_handle
);
10757 if (GetResourceSizeOnDisk (font_handle
)
10758 >= sizeof (struct FamRec
))
10760 fat
= (struct FontAssoc
*) (*font_handle
10761 + sizeof (struct FamRec
));
10763 = (struct AsscEntry
*) (*font_handle
10764 + sizeof (struct FamRec
)
10765 + sizeof (struct FontAssoc
));
10767 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10769 if (font_name_table_size
== 0)
10771 font_name_table_size
= 16;
10772 font_name_table
= (char **)
10773 xmalloc (font_name_table_size
* sizeof (char *));
10775 else if (font_name_count
>= font_name_table_size
)
10777 font_name_table_size
+= 16;
10778 font_name_table
= (char **)
10779 xrealloc (font_name_table
,
10780 font_name_table_size
* sizeof (char *));
10782 font_name_table
[font_name_count
++]
10783 = mac_to_x_fontname (name
,
10784 assc_entry
->fontSize
,
10785 assc_entry
->fontStyle
,
10787 /* Both jisx0208.1983-sjis and
10788 jisx0201.1976-sjis parts are contained in
10789 Apple Japanese (SJIS) font. */
10790 if (smJapanese
== scriptcode
)
10792 font_name_table
[font_name_count
++]
10793 = mac_to_x_fontname (name
,
10794 assc_entry
->fontSize
,
10795 assc_entry
->fontStyle
,
10801 HUnlock (font_handle
);
10802 font_handle_2
= GetNextFOND (font_handle
);
10803 ReleaseResource (font_handle
);
10804 font_handle
= font_handle_2
;
10806 while (ResError () == noErr
&& font_handle
);
10809 TextFont (old_fontnum
);
10810 #if TARGET_API_MAC_CARBON
10812 #endif /* TARGET_API_MAC_CARBON */
10816 /* Return a list of at most MAXNAMES font specs matching the one in
10817 PATTERN. Note that each '*' in the PATTERN matches exactly one
10818 field of the font spec, unlike X in which an '*' in a font spec can
10819 match a number of fields. The result is in the Mac implementation
10820 all fonts must be specified by a font spec with all 13 fields
10821 (although many of these can be "*'s"). */
10824 x_list_fonts (struct frame
*f
,
10825 Lisp_Object pattern
,
10830 Lisp_Object newlist
= Qnil
;
10833 struct gcpro gcpro1
, gcpro2
;
10835 if (font_name_table
== NULL
) /* Initialize when first used. */
10836 init_font_name_table ();
10838 ptnstr
= XSTRING (pattern
)->data
;
10840 GCPRO2 (pattern
, newlist
);
10842 /* Scan and matching bitmap fonts. */
10843 for (i
= 0; i
< font_name_count
; i
++)
10845 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10847 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10850 if (n_fonts
>= maxnames
)
10855 /* MAC_TODO: add code for matching outline fonts here */
10865 /* Check that FONT is valid on frame F. It is if it can be found in F's
10869 x_check_font (f
, font
)
10874 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10876 xassert (font
!= NULL
);
10878 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10879 if (dpyinfo
->font_table
[i
].name
10880 && font
== dpyinfo
->font_table
[i
].font
)
10883 xassert (i
< dpyinfo
->n_fonts
);
10886 #endif /* GLYPH_DEBUG != 0 */
10888 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10889 Note: There are (broken) X fonts out there with invalid XFontStruct
10890 min_bounds contents. For example, handa@etl.go.jp reports that
10891 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10892 have font->min_bounds.width == 0. */
10895 x_font_min_bounds (font
, w
, h
)
10896 MacFontStruct
*font
;
10900 * TODO: Windows does not appear to offer min bound, only
10901 * average and maximum width, and maximum height.
10903 *h
= FONT_HEIGHT (font
);
10904 *w
= FONT_WIDTH (font
);
10908 /* Compute the smallest character width and smallest font height over
10909 all fonts available on frame F. Set the members smallest_char_width
10910 and smallest_font_height in F's x_display_info structure to
10911 the values computed. Value is non-zero if smallest_font_height or
10912 smallest_char_width become smaller than they were before. */
10915 x_compute_min_glyph_bounds (f
)
10919 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10920 MacFontStruct
*font
;
10921 int old_width
= dpyinfo
->smallest_char_width
;
10922 int old_height
= dpyinfo
->smallest_font_height
;
10924 dpyinfo
->smallest_font_height
= 100000;
10925 dpyinfo
->smallest_char_width
= 100000;
10927 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10928 if (dpyinfo
->font_table
[i
].name
)
10930 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10933 font
= (MacFontStruct
*) fontp
->font
;
10934 xassert (font
!= (MacFontStruct
*) ~0);
10935 x_font_min_bounds (font
, &w
, &h
);
10937 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10938 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10941 xassert (dpyinfo
->smallest_char_width
> 0
10942 && dpyinfo
->smallest_font_height
> 0);
10944 return (dpyinfo
->n_fonts
== 1
10945 || dpyinfo
->smallest_char_width
< old_width
10946 || dpyinfo
->smallest_font_height
< old_height
);
10950 /* Determine whether given string is a fully-specified XLFD: all 14
10951 fields are present, none is '*'. */
10954 is_fully_specified_xlfd (char *p
)
10962 for (i
= 0; i
< 13; i
++)
10964 q
= strchr (p
+ 1, '-');
10967 if (q
- p
== 2 && *(p
+ 1) == '*')
10972 if (strchr (p
+ 1, '-') != NULL
)
10975 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10982 const int kDefaultFontSize
= 9;
10985 /* XLoadQueryFont creates and returns an internal representation for a
10986 font in a MacFontStruct struct. There is really no concept
10987 corresponding to "loading" a font on the Mac. But we check its
10988 existence and find the font number and all other information for it
10989 and store them in the returned MacFontStruct. */
10991 static MacFontStruct
*
10992 XLoadQueryFont (Display
*dpy
, char *fontname
)
10994 int i
, size
, is_two_byte_font
, char_width
;
10997 SInt16 old_fontnum
, old_fontsize
;
10998 Style old_fontface
;
11001 Style fontface
= normal
;
11002 MacFontStruct
*font
;
11003 FontInfo the_fontinfo
;
11004 char s_weight
[7], c_slant
;
11006 if (is_fully_specified_xlfd (fontname
))
11010 for (i
= 0; i
< font_name_count
; i
++)
11011 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
11014 if (i
>= font_name_count
)
11017 name
= font_name_table
[i
];
11020 GetPort (&port
); /* save the current font number used */
11021 #if TARGET_API_MAC_CARBON
11022 old_fontnum
= GetPortTextFont (port
);
11023 old_fontsize
= GetPortTextSize (port
);
11024 old_fontface
= GetPortTextFace (port
);
11026 old_fontnum
= port
->txFont
;
11027 old_fontsize
= port
->txSize
;
11028 old_fontface
= port
->txFace
;
11031 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
11032 size
= kDefaultFontSize
;
11034 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
11035 if (strcmp (s_weight
, "bold") == 0)
11038 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
11039 if (c_slant
== 'i')
11040 fontface
|= italic
;
11042 x_font_name_to_mac_font_name (name
, mfontname
);
11043 c2pstr (mfontname
);
11044 GetFNum (mfontname
, &fontnum
);
11048 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
11050 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
11051 bcopy (name
, font
->fontname
, strlen (name
) + 1);
11053 font
->mac_fontnum
= fontnum
;
11054 font
->mac_fontsize
= size
;
11055 font
->mac_fontface
= fontface
;
11056 font
->mac_scriptcode
= FontToScript (fontnum
);
11058 /* Apple Japanese (SJIS) font is listed as both
11059 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
11060 (Roman script) in init_font_name_table (). The latter should be
11061 treated as a one-byte font. */
11066 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
11068 && 0 == strcmp (cs
, "mac-roman"))
11069 font
->mac_scriptcode
= smRoman
;
11072 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
11073 font
->mac_scriptcode
== smTradChinese
||
11074 font
->mac_scriptcode
== smSimpChinese
||
11075 font
->mac_scriptcode
== smKorean
;
11077 TextFont (fontnum
);
11079 TextFace (fontface
);
11081 GetFontInfo (&the_fontinfo
);
11083 font
->ascent
= the_fontinfo
.ascent
;
11084 font
->descent
= the_fontinfo
.descent
;
11086 font
->min_byte1
= 0;
11087 if (is_two_byte_font
)
11088 font
->max_byte1
= 1;
11090 font
->max_byte1
= 0;
11091 font
->min_char_or_byte2
= 0x20;
11092 font
->max_char_or_byte2
= 0xff;
11094 if (is_two_byte_font
)
11096 /* Use the width of an "ideographic space" of that font because
11097 the_fontinfo.widMax returns the wrong width for some fonts. */
11098 switch (font
->mac_scriptcode
)
11101 char_width
= StringWidth("\p\x81\x40");
11103 case smTradChinese
:
11104 char_width
= StringWidth("\p\xa1\x40");
11106 case smSimpChinese
:
11107 char_width
= StringWidth("\p\xa1\xa1");
11110 char_width
= StringWidth("\p\xa1\xa1");
11115 /* Do this instead of use the_fontinfo.widMax, which incorrectly
11116 returns 15 for 12-point Monaco! */
11117 char_width
= CharWidth ('m');
11119 font
->max_bounds
.rbearing
= char_width
;
11120 font
->max_bounds
.lbearing
= 0;
11121 font
->max_bounds
.width
= char_width
;
11122 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
11123 font
->max_bounds
.descent
= the_fontinfo
.descent
;
11125 font
->min_bounds
= font
->max_bounds
;
11127 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
11128 font
->per_char
= NULL
;
11131 font
->per_char
= (XCharStruct
*)
11132 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
11136 for (c
= 0x20; c
<= 0xff; c
++)
11138 font
->per_char
[c
- 0x20] = font
->max_bounds
;
11139 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
11144 TextFont (old_fontnum
); /* restore previous font number, size and face */
11145 TextSize (old_fontsize
);
11146 TextFace (old_fontface
);
11152 /* Load font named FONTNAME of the size SIZE for frame F, and return a
11153 pointer to the structure font_info while allocating it dynamically.
11154 If SIZE is 0, load any size of font.
11155 If loading is failed, return NULL. */
11158 x_load_font (f
, fontname
, size
)
11160 register char *fontname
;
11163 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11164 Lisp_Object font_names
;
11166 /* Get a list of all the fonts that match this name. Once we
11167 have a list of matching fonts, we compare them against the fonts
11168 we already have by comparing names. */
11169 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
11171 if (!NILP (font_names
))
11176 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11177 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
11178 if (dpyinfo
->font_table
[i
].name
11179 && (!strcmp (dpyinfo
->font_table
[i
].name
,
11180 XSTRING (XCAR (tail
))->data
)
11181 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
11182 XSTRING (XCAR (tail
))->data
)))
11183 return (dpyinfo
->font_table
+ i
);
11186 /* Load the font and add it to the table. */
11189 struct MacFontStruct
*font
;
11190 struct font_info
*fontp
;
11191 unsigned long value
;
11194 /* If we have found fonts by x_list_font, load one of them. If
11195 not, we still try to load a font by the name given as FONTNAME
11196 because XListFonts (called in x_list_font) of some X server has
11197 a bug of not finding a font even if the font surely exists and
11198 is loadable by XLoadQueryFont. */
11199 if (size
> 0 && !NILP (font_names
))
11200 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
11202 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
11206 /* Find a free slot in the font table. */
11207 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
11208 if (dpyinfo
->font_table
[i
].name
== NULL
)
11211 /* If no free slot found, maybe enlarge the font table. */
11212 if (i
== dpyinfo
->n_fonts
11213 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
11216 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
11217 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
11218 dpyinfo
->font_table
11219 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
11222 fontp
= dpyinfo
->font_table
+ i
;
11223 if (i
== dpyinfo
->n_fonts
)
11224 ++dpyinfo
->n_fonts
;
11226 /* Now fill in the slots of *FONTP. */
11228 fontp
->font
= font
;
11229 fontp
->font_idx
= i
;
11230 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
11231 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
11233 fontp
->full_name
= fontp
->name
;
11235 fontp
->size
= font
->max_bounds
.width
;
11236 fontp
->height
= FONT_HEIGHT (font
);
11238 /* For some font, ascent and descent in max_bounds field is
11239 larger than the above value. */
11240 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
11241 if (max_height
> fontp
->height
)
11242 fontp
->height
= max_height
;
11245 /* The slot `encoding' specifies how to map a character
11246 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
11247 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
11248 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
11249 2:0xA020..0xFF7F). For the moment, we don't know which charset
11250 uses this font. So, we set information in fontp->encoding[1]
11251 which is never used by any charset. If mapping can't be
11252 decided, set FONT_ENCODING_NOT_DECIDED. */
11253 if (font
->mac_scriptcode
== smJapanese
)
11254 fontp
->encoding
[1] = 4;
11258 = (font
->max_byte1
== 0
11260 ? (font
->min_char_or_byte2
< 0x80
11261 ? (font
->max_char_or_byte2
< 0x80
11262 ? 0 /* 0x20..0x7F */
11263 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
11264 : 1) /* 0xA0..0xFF */
11266 : (font
->min_byte1
< 0x80
11267 ? (font
->max_byte1
< 0x80
11268 ? (font
->min_char_or_byte2
< 0x80
11269 ? (font
->max_char_or_byte2
< 0x80
11270 ? 0 /* 0x2020..0x7F7F */
11271 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
11272 : 3) /* 0x20A0..0x7FFF */
11273 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
11274 : (font
->min_char_or_byte2
< 0x80
11275 ? (font
->max_char_or_byte2
< 0x80
11276 ? 2 /* 0xA020..0xFF7F */
11277 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
11278 : 1))); /* 0xA0A0..0xFFFF */
11281 #if 0 /* MAC_TODO: fill these out with more reasonably values */
11282 fontp
->baseline_offset
11283 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
11284 ? (long) value
: 0);
11285 fontp
->relative_compose
11286 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
11287 ? (long) value
: 0);
11288 fontp
->default_ascent
11289 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
11290 ? (long) value
: 0);
11292 fontp
->baseline_offset
= 0;
11293 fontp
->relative_compose
= 0;
11294 fontp
->default_ascent
= 0;
11297 /* Set global flag fonts_changed_p to non-zero if the font loaded
11298 has a character with a smaller width than any other character
11299 before, or if the font loaded has a smalle>r height than any
11300 other font loaded before. If this happens, it will make a
11301 glyph matrix reallocation necessary. */
11302 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11309 /* Return a pointer to struct font_info of a font named FONTNAME for
11310 frame F. If no such font is loaded, return NULL. */
11313 x_query_font (f
, fontname
)
11315 register char *fontname
;
11317 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11320 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11321 if (dpyinfo
->font_table
[i
].name
11322 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11323 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11324 return (dpyinfo
->font_table
+ i
);
11329 /* Find a CCL program for a font specified by FONTP, and set the member
11330 `encoder' of the structure. */
11333 x_find_ccl_program (fontp
)
11334 struct font_info
*fontp
;
11336 Lisp_Object list
, elt
;
11338 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11342 && STRINGP (XCAR (elt
))
11343 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11349 struct ccl_program
*ccl
11350 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11352 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11355 fontp
->font_encoder
= ccl
;
11361 /***********************************************************************
11363 ***********************************************************************/
11365 #ifdef USE_X_TOOLKIT
11366 static XrmOptionDescRec emacs_options
[] = {
11367 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11368 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11370 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11371 XrmoptionSepArg
, NULL
},
11372 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11374 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11375 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11376 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11377 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11378 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11379 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11380 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11382 #endif /* USE_X_TOOLKIT */
11384 static int x_initialized
;
11386 #ifdef MULTI_KBOARD
11387 /* Test whether two display-name strings agree up to the dot that separates
11388 the screen number from the server number. */
11390 same_x_server (name1
, name2
)
11391 char *name1
, *name2
;
11393 int seen_colon
= 0;
11394 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
11395 int system_name_length
= strlen (system_name
);
11396 int length_until_period
= 0;
11398 while (system_name
[length_until_period
] != 0
11399 && system_name
[length_until_period
] != '.')
11400 length_until_period
++;
11402 /* Treat `unix' like an empty host name. */
11403 if (! strncmp (name1
, "unix:", 5))
11405 if (! strncmp (name2
, "unix:", 5))
11407 /* Treat this host's name like an empty host name. */
11408 if (! strncmp (name1
, system_name
, system_name_length
)
11409 && name1
[system_name_length
] == ':')
11410 name1
+= system_name_length
;
11411 if (! strncmp (name2
, system_name
, system_name_length
)
11412 && name2
[system_name_length
] == ':')
11413 name2
+= system_name_length
;
11414 /* Treat this host's domainless name like an empty host name. */
11415 if (! strncmp (name1
, system_name
, length_until_period
)
11416 && name1
[length_until_period
] == ':')
11417 name1
+= length_until_period
;
11418 if (! strncmp (name2
, system_name
, length_until_period
)
11419 && name2
[length_until_period
] == ':')
11420 name2
+= length_until_period
;
11422 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11426 if (seen_colon
&& *name1
== '.')
11430 && (*name1
== '.' || *name1
== '\0')
11431 && (*name2
== '.' || *name2
== '\0'));
11436 /* The Mac Event loop code */
11439 #include <Events.h>
11440 #include <Quickdraw.h>
11441 #include <Balloons.h>
11442 #include <Devices.h>
11444 #include <Gestalt.h>
11446 #include <Processes.h>
11448 #include <ToolUtils.h>
11449 #include <TextUtils.h>
11450 #include <Dialogs.h>
11451 #include <Script.h>
11453 #include <TextEncodingConverter.h>
11454 #include <Resources.h>
11459 #endif /* ! MAC_OSX */
11461 #define M_APPLE 128
11464 #define WINDOW_RESOURCE 128
11465 #define TERM_WINDOW_RESOURCE 129
11467 #define DEFAULT_NUM_COLS 80
11469 #define MIN_DOC_SIZE 64
11470 #define MAX_DOC_SIZE 32767
11472 /* sleep time for WaitNextEvent */
11473 #define WNE_SLEEP_AT_SUSPEND 10
11474 #define WNE_SLEEP_AT_RESUME 1
11476 /* true when cannot handle any Mac OS events */
11477 static int handling_window_update
= 0;
11479 /* the flag appl_is_suspended is used both for determining the sleep
11480 time to be passed to WaitNextEvent and whether the cursor should be
11481 drawn when updating the display. The cursor is turned off when
11482 Emacs is suspended. Redrawing it is unnecessary and what needs to
11483 be done depends on whether the cursor lies inside or outside the
11484 redraw region. So we might as well skip drawing it when Emacs is
11486 static Boolean app_is_suspended
= false;
11487 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11489 #define EXTRA_STACK_ALLOC (256 * 1024)
11491 #define ARGV_STRING_LIST_ID 129
11492 #define ABOUT_ALERT_ID 128
11493 #define RAM_TOO_LARGE_ALERT_ID 129
11495 Boolean terminate_flag
= false;
11497 /* true if using command key as meta key */
11498 Lisp_Object Vmac_command_key_is_meta
;
11500 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11501 to this text encoding */
11502 int mac_keyboard_text_encoding
;
11503 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11505 /* Set in term/mac-win.el to indicate that event loop can now generate
11506 drag and drop events. */
11507 Lisp_Object Qmac_ready_for_drag_n_drop
;
11509 Lisp_Object drag_and_drop_file_list
;
11511 Point saved_menu_event_location
;
11514 static void init_required_apple_events(void);
11515 static pascal OSErr
11516 do_ae_open_application(const AppleEvent
*, AppleEvent
*, long);
11517 static pascal OSErr
11518 do_ae_print_documents(const AppleEvent
*, AppleEvent
*, long);
11519 static pascal OSErr
do_ae_open_documents(AppleEvent
*, AppleEvent
*, long);
11520 static pascal OSErr
do_ae_quit_application(AppleEvent
*, AppleEvent
*, long);
11522 extern void init_emacs_passwd_dir ();
11523 extern int emacs_main (int, char **, char **);
11524 extern void check_alarm ();
11526 extern void initialize_applescript();
11527 extern void terminate_applescript();
11531 do_get_menus (void)
11533 Handle menubar_handle
;
11534 MenuHandle menu_handle
;
11536 menubar_handle
= GetNewMBar (128);
11537 if(menubar_handle
== NULL
)
11539 SetMenuBar (menubar_handle
);
11542 menu_handle
= GetMenuHandle (M_APPLE
);
11543 if(menu_handle
!= NULL
)
11544 AppendResMenu (menu_handle
,'DRVR');
11551 do_init_managers (void)
11553 #if !TARGET_API_MAC_CARBON
11554 InitGraf (&qd
.thePort
);
11556 FlushEvents (everyEvent
, 0);
11560 InitDialogs (NULL
);
11561 #endif /* !TARGET_API_MAC_CARBON */
11564 #if !TARGET_API_MAC_CARBON
11565 /* set up some extra stack space for use by emacs */
11566 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11568 /* MaxApplZone must be called for AppleScript to execute more
11569 complicated scripts */
11572 #endif /* !TARGET_API_MAC_CARBON */
11576 do_check_ram_size (void)
11578 SInt32 physical_ram_size
, logical_ram_size
;
11580 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11581 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11582 || physical_ram_size
> 256 * 1024 * 1024
11583 || logical_ram_size
> 256 * 1024 * 1024)
11585 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11591 do_window_update (WindowPtr win
)
11593 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11594 struct frame
*f
= mwp
->mFP
;
11598 if (f
->async_visible
== 0)
11600 f
->async_visible
= 1;
11601 f
->async_iconified
= 0;
11602 SET_FRAME_GARBAGED (f
);
11604 /* An update event is equivalent to MapNotify on X, so report
11605 visibility changes properly. */
11606 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11607 /* Force a redisplay sooner or later to update the
11608 frame titles in case this is the second frame. */
11609 record_asynch_buffer_change ();
11614 handling_window_update
= 1;
11616 expose_frame (f
, 0, 0, 0, 0);
11618 handling_window_update
= 0;
11625 is_emacs_window (WindowPtr win
)
11627 Lisp_Object tail
, frame
;
11632 FOR_EACH_FRAME (tail
, frame
)
11633 if (FRAME_MAC_P (XFRAME (frame
)))
11634 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
11641 do_window_activate (WindowPtr win
)
11646 if (is_emacs_window (win
))
11648 mwp
= (mac_output
*) GetWRefCon (win
);
11653 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11654 activate_scroll_bars (f
);
11660 do_window_deactivate (WindowPtr win
)
11665 if (is_emacs_window (win
))
11667 mwp
= (mac_output
*) GetWRefCon (win
);
11670 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11672 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11673 deactivate_scroll_bars (f
);
11685 wp
= FrontWindow();
11686 if (is_emacs_window (wp
))
11688 mwp
= (mac_output
*) GetWRefCon (wp
);
11693 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11694 activate_scroll_bars (f
);
11698 app_is_suspended
= false;
11699 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11709 wp
= FrontWindow();
11710 if (is_emacs_window (wp
))
11712 mwp
= (mac_output
*) GetWRefCon (wp
);
11715 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11717 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11718 deactivate_scroll_bars (f
);
11722 app_is_suspended
= true;
11723 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11728 do_mouse_moved (Point mouse_pos
)
11730 WindowPtr wp
= FrontWindow ();
11731 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11733 #if TARGET_API_MAC_CARBON
11734 SetPort (GetWindowPort (wp
));
11739 GlobalToLocal (&mouse_pos
);
11741 note_mouse_movement (f
, &mouse_pos
);
11746 do_os_event (EventRecord
*erp
)
11748 switch((erp
->message
>> 24) & 0x000000FF)
11750 case suspendResumeMessage
:
11751 if((erp
->message
& resumeFlag
) == 1)
11757 case mouseMovedMessage
:
11758 do_mouse_moved (erp
->where
);
11764 do_events (EventRecord
*erp
)
11769 do_window_update ((WindowPtr
) erp
->message
);
11777 if ((erp
->modifiers
& activeFlag
) != 0)
11778 do_window_activate ((WindowPtr
) erp
->message
);
11780 do_window_deactivate ((WindowPtr
) erp
->message
);
11786 do_apple_menu (SInt16 menu_item
)
11788 #if !TARGET_API_MAC_CARBON
11790 SInt16 da_driver_refnum
;
11792 if (menu_item
== I_ABOUT
)
11793 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11796 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11797 da_driver_refnum
= OpenDeskAcc (item_name
);
11799 #endif /* !TARGET_API_MAC_CARBON */
11803 do_menu_choice (SInt32 menu_choice
)
11805 SInt16 menu_id
, menu_item
;
11807 menu_id
= HiWord (menu_choice
);
11808 menu_item
= LoWord (menu_choice
);
11816 do_apple_menu (menu_item
);
11821 WindowPtr wp
= FrontWindow ();
11822 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11823 MenuHandle menu
= GetMenuHandle (menu_id
);
11828 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11829 menubar_selection_callback (f
, refcon
);
11838 /* Handle drags in size box. Based on code contributed by Ben
11839 Mesander and IM - Window Manager A. */
11842 do_grow_window (WindowPtr w
, EventRecord
*e
)
11847 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11848 struct frame
*f
= mwp
->mFP
;
11850 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11852 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11854 /* see if it really changed size */
11855 if (grow_size
!= 0)
11857 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11858 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11860 x_set_window_size (f
, 0, columns
, rows
);
11865 /* Handle clicks in zoom box. Calculation of "standard state" based
11866 on code in IM - Window Manager A and code contributed by Ben
11867 Mesander. The standard state of an Emacs window is 80-characters
11868 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11871 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11874 Rect zoom_rect
, port_rect
;
11876 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11877 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11878 struct frame
*f
= mwp
->mFP
;
11880 GetPort (&save_port
);
11882 #if TARGET_API_MAC_CARBON
11883 SetPort (GetWindowPort (w
));
11888 /* Clear window to avoid flicker. */
11889 #if TARGET_API_MAC_CARBON
11894 GetWindowPortBounds (w
, &r
);
11897 if (zoom_in_or_out
== inZoomOut
)
11899 /* calculate height of window's title bar (hard card it for now). */
11900 w_title_height
= 20 + GetMBarHeight ();
11902 /* get maximum height of window into zoom_rect.bottom -
11904 GetQDGlobalsScreenBits (&bm
);
11905 zoom_rect
= bm
.bounds
;
11906 zoom_rect
.top
+= w_title_height
;
11907 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11909 zoom_rect
.right
= zoom_rect
.left
11910 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11912 SetWindowStandardState (w
, &zoom_rect
);
11915 #else /* not TARGET_API_MAC_CARBON */
11916 EraseRect (&(w
->portRect
));
11917 if (zoom_in_or_out
== inZoomOut
)
11919 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
11920 LocalToGlobal (&top_left
);
11922 /* calculate height of window's title bar */
11923 w_title_height
= top_left
.v
- 1
11924 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
11926 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
11927 zoom_rect
= qd
.screenBits
.bounds
;
11928 zoom_rect
.top
+= w_title_height
;
11929 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11931 zoom_rect
.right
= zoom_rect
.left
11932 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11934 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
11937 #endif /* not TARGET_API_MAC_CARBON */
11939 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
11941 /* retrieve window size and update application values */
11942 #if TARGET_API_MAC_CARBON
11943 GetWindowPortBounds (w
, &port_rect
);
11945 port_rect
= w
->portRect
;
11947 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
11948 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
11949 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
11951 SetPort (save_port
);
11955 /* Intialize AppleEvent dispatcher table for the required events. */
11957 init_required_apple_events ()
11962 /* Make sure we have apple events before starting. */
11963 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
11967 if (!(result
& (1 << gestaltAppleEventsPresent
)))
11970 #if TARGET_API_MAC_CARBON
11971 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
11972 NewAEEventHandlerUPP
11973 ((AEEventHandlerProcPtr
) do_ae_open_application
),
11976 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
11977 NewAEEventHandlerProc
11978 ((AEEventHandlerProcPtr
) do_ae_open_application
),
11984 #if TARGET_API_MAC_CARBON
11985 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
11986 NewAEEventHandlerUPP
11987 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
11990 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
11991 NewAEEventHandlerProc
11992 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
11998 #if TARGET_API_MAC_CARBON
11999 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12000 NewAEEventHandlerUPP
12001 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12004 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
12005 NewAEEventHandlerProc
12006 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
12012 #if TARGET_API_MAC_CARBON
12013 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12014 NewAEEventHandlerUPP
12015 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12018 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
12019 NewAEEventHandlerProc
12020 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
12028 /* Open Application Apple Event */
12029 static pascal OSErr
12030 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
12036 /* Defined in mac.c. */
12038 path_from_vol_dir_name (char *, int, short, long, char *);
12041 /* Called when we receive an AppleEvent with an ID of
12042 "kAEOpenDocuments". This routine gets the direct parameter,
12043 extracts the FSSpecs in it, and puts their names on a list. */
12044 static pascal OSErr
12045 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
12050 DescType actual_type
;
12053 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
12055 goto descriptor_error_exit
;
12057 /* Check to see that we got all of the required parameters from the
12058 event descriptor. For an 'odoc' event this should just be the
12060 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
12061 &actual_type
, (Ptr
) &keyword
,
12062 sizeof (keyword
), &actual_size
);
12063 /* No error means that we found some unused parameters.
12064 errAEDescNotFound means that there are no more parameters. If we
12065 get an error code other than that, flag it. */
12066 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
12068 err
= errAEEventNotHandled
;
12073 /* Got all the parameters we need. Now, go through the direct
12074 object list and parse it up. */
12076 long num_files_to_open
;
12078 err
= AECountItems (&the_desc
, &num_files_to_open
);
12083 /* AE file list is one based so just use that for indexing here. */
12084 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++) {
12086 Str255 path_name
, unix_path_name
;
12088 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
12089 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
12090 if (err
!= noErr
) break;
12092 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
12094 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
12095 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
12096 drag_and_drop_file_list
);
12102 /* Nuke the coerced file list in any case */
12103 err2
= AEDisposeDesc(&the_desc
);
12105 descriptor_error_exit
:
12106 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
12111 /* Print Document Apple Event */
12112 static pascal OSErr
12113 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
12115 return errAEEventNotHandled
;
12119 static pascal OSErr
12120 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
12122 /* FixMe: Do we need an unwind-protect or something here? And what
12123 do we do about unsaved files. Currently just forces quit rather
12124 than doing recursive callback to get user input. */
12126 terminate_flag
= true;
12128 /* Fkill_emacs doesn't return. We have to return. (TI) */
12135 profiler_exit_proc ()
12137 ProfilerDump ("\pEmacs.prof");
12142 /* These few functions implement Emacs as a normal Mac application
12143 (almost): set up the heap and the Toolbox, handle necessary
12144 system events plus a few simple menu events. They also set up
12145 Emacs's access to functions defined in the rest of this file.
12146 Emacs uses function hooks to perform all its terminal I/O. A
12147 complete list of these functions appear in termhooks.h. For what
12148 they do, read the comments there and see also w32term.c and
12149 xterm.c. What's noticeably missing here is the event loop, which
12150 is normally present in most Mac application. After performing the
12151 necessary Mac initializations, main passes off control to
12152 emacs_main (corresponding to main in emacs.c). Emacs_main calls
12153 mac_read_socket (defined further below) to read input. This is
12154 where WaitNextEvent is called to process Mac events. This is also
12155 where check_alarm in sysdep.c is called to simulate alarm signals.
12156 This makes the cursor jump back to its correct position after
12157 briefly jumping to that of the matching parenthesis, print useful
12158 hints and prompts in the minibuffer after the user stops typing for
12161 #if !TARGET_API_MAC_CARBON
12166 #if __profile__ /* is the profiler on? */
12167 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
12172 /* set creator and type for files created by MSL */
12173 _fcreator
= 'EMAx';
12177 do_init_managers ();
12181 do_check_ram_size ();
12183 init_emacs_passwd_dir ();
12187 initialize_applescript ();
12189 init_required_apple_events ();
12195 /* set up argv array from STR# resource */
12196 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
12200 /* free up AppleScript resources on exit */
12201 atexit (terminate_applescript
);
12203 #if __profile__ /* is the profiler on? */
12204 atexit (profiler_exit_proc
);
12207 /* 3rd param "envp" never used in emacs_main */
12208 (void) emacs_main (argc
, argv
, 0);
12211 /* Never reached - real exit in Fkill_emacs */
12216 /* Table for translating Mac keycode to X keysym values. Contributed
12217 by Sudhir Shenoy. */
12218 static unsigned char keycode_to_xkeysym_table
[] = {
12220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12225 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
12226 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
12227 0, 0, 0, '\xaf' /* kp/ */,
12228 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
12230 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
12231 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
12232 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
12233 '\xb9' /* kp9 */, 0, 0, 0,
12235 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
12236 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
12237 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
12238 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
12240 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
12241 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
12242 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
12243 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
12247 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
12249 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
12250 return *xKeySym
!= 0;
12253 /* Emacs calls this whenever it wants to read an input event from the
12256 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
12261 EventMask event_mask
;
12264 if (interrupt_input_blocked
)
12266 interrupt_input_pending
= 1;
12271 interrupt_input_pending
= 0;
12274 /* So people can tell when we have read the available input. */
12275 input_signal_count
++;
12280 /* Don't poll for events to process (specifically updateEvt) if
12281 window update currently already in progress. A call to redisplay
12282 (in do_window_update) can be preempted by another call to
12283 redisplay, causing blank regions to be left on the screen and the
12284 cursor to be left at strange places. */
12285 if (handling_window_update
)
12291 if (terminate_flag
)
12292 Fkill_emacs (make_number (1));
12294 /* It is necessary to set this (additional) argument slot of an
12295 event to nil because keyboard.c protects incompletely processed
12296 event from being garbage collected by placing them in the
12297 kbd_buffer_gcpro vector. */
12300 event_mask
= everyEvent
;
12301 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
12302 event_mask
-= highLevelEventMask
;
12304 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
) && numchars
> 0)
12310 WindowPtr window_ptr
= FrontWindow ();
12313 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12314 && er
.what
== mouseUp
)
12316 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
12317 Point mouse_loc
= er
.where
;
12319 /* Convert to local coordinates of new window. */
12320 #if TARGET_API_MAC_CARBON
12321 SetPort (GetWindowPort (window_ptr
));
12323 SetPort (window_ptr
);
12326 GlobalToLocal (&mouse_loc
);
12328 bufp
->code
= 0; /* only one mouse button */
12329 bufp
->kind
= scroll_bar_click
;
12330 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
12331 bufp
->part
= scroll_bar_handle
;
12332 bufp
->modifiers
= up_modifier
;
12333 bufp
->timestamp
= er
.when
* (1000 / 60);
12334 /* ticks to milliseconds */
12336 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
12337 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
12338 tracked_scroll_bar
->dragging
= Qnil
;
12339 mouse_tracking_in_progress
= mouse_tracking_none
;
12340 tracked_scroll_bar
= NULL
;
12347 part_code
= FindWindow (er
.where
, &window_ptr
);
12353 struct frame
*f
= ((mac_output
*)
12354 GetWRefCon (FrontWindow ()))->mFP
;
12355 saved_menu_event_location
= er
.where
;
12356 bufp
->kind
= menu_bar_activate_event
;
12357 XSETFRAME (bufp
->frame_or_window
, f
);
12365 if (window_ptr
!= FrontWindow ())
12366 SelectWindow (window_ptr
);
12369 SInt16 control_part_code
;
12371 struct mac_output
*mwp
= (mac_output
*)
12372 GetWRefCon (window_ptr
);
12373 Point mouse_loc
= er
.where
;
12375 /* convert to local coordinates of new window */
12376 #if TARGET_API_MAC_CARBON
12377 SetPort (GetWindowPort (window_ptr
));
12379 SetPort (window_ptr
);
12382 GlobalToLocal (&mouse_loc
);
12383 #if TARGET_API_MAC_CARBON
12384 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
12385 &control_part_code
);
12387 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
12389 bufp
->code
= 0; /* only one mouse button */
12390 XSETINT (bufp
->x
, mouse_loc
.h
);
12391 XSETINT (bufp
->y
, mouse_loc
.v
);
12392 bufp
->timestamp
= er
.when
* (1000 / 60);
12393 /* ticks to milliseconds */
12395 #if TARGET_API_MAC_CARBON
12398 if (control_part_code
!= 0)
12401 struct scroll_bar
*bar
= (struct scroll_bar
*)
12402 GetControlReference (ch
);
12403 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
12405 if (er
.what
== mouseDown
12406 && control_part_code
== kControlIndicatorPart
)
12408 mouse_tracking_in_progress
12409 = mouse_tracking_scroll_bar
;
12410 tracked_scroll_bar
= bar
;
12414 mouse_tracking_in_progress
= mouse_tracking_none
;
12415 tracked_scroll_bar
= NULL
;
12420 bufp
->kind
= mouse_click
;
12421 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12422 if (er
.what
== mouseDown
)
12423 mouse_tracking_in_progress
12424 = mouse_tracking_mouse_movement
;
12426 mouse_tracking_in_progress
= mouse_tracking_none
;
12432 bufp
->modifiers
= down_modifier
;
12435 bufp
->modifiers
= up_modifier
;
12446 #if TARGET_API_MAC_CARBON
12450 GetQDGlobalsScreenBits (&bm
);
12451 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
12453 #else /* not TARGET_API_MAC_CARBON */
12454 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12455 #endif /* not TARGET_API_MAC_CARBON */
12459 if (TrackGoAway (window_ptr
, er
.where
))
12461 bufp
->kind
= delete_window_event
;
12462 XSETFRAME (bufp
->frame_or_window
,
12463 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12470 /* window resize handling added --ben */
12472 do_grow_window(window_ptr
, &er
);
12475 /* window zoom handling added --ben */
12478 if (TrackBox (window_ptr
, er
.where
, part_code
))
12479 do_zoom_window (window_ptr
, part_code
);
12497 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12502 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12505 bufp
->kind
= ascii_keystroke
;
12507 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12509 bufp
->code
= 0xff00 | xkeysym
;
12510 bufp
->kind
= non_ascii_keystroke
;
12515 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12517 /* This code comes from Keyboard Resource, Appendix
12518 C of IM - Text. This is necessary since shift is
12519 ignored in KCHR table translation when option or
12520 command is pressed. */
12521 int new_modifiers
= er
.modifiers
& 0xf600;
12522 /* mask off option and command */
12523 int new_keycode
= keycode
| new_modifiers
;
12524 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12525 unsigned long some_state
= 0;
12526 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12527 &some_state
) & 0xff;
12530 bufp
->code
= er
.message
& charCodeMask
;
12531 bufp
->kind
= ascii_keystroke
;
12535 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12536 convert non-ASCII characters typed at the Mac keyboard
12537 (presumed to be in the Mac Roman encoding) to iso-latin-1
12538 encoding before they are passed to Emacs. This enables the
12539 Mac keyboard to be used to enter non-ASCII iso-latin-1
12540 characters directly. */
12541 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12542 && bufp
->kind
== ascii_keystroke
&& bufp
->code
>= 128)
12544 static TECObjectRef converter
= NULL
;
12545 OSStatus the_err
= noErr
;
12546 OSStatus convert_status
= noErr
;
12548 if (converter
== NULL
)
12550 the_err
= TECCreateConverter (&converter
,
12551 kTextEncodingMacRoman
,
12552 mac_keyboard_text_encoding
);
12553 current_mac_keyboard_text_encoding
12554 = mac_keyboard_text_encoding
;
12556 else if (mac_keyboard_text_encoding
12557 != current_mac_keyboard_text_encoding
)
12559 /* Free the converter for the current encoding before
12560 creating a new one. */
12561 TECDisposeConverter (converter
);
12562 the_err
= TECCreateConverter (&converter
,
12563 kTextEncodingMacRoman
,
12564 mac_keyboard_text_encoding
);
12565 current_mac_keyboard_text_encoding
12566 = mac_keyboard_text_encoding
;
12569 if (the_err
== noErr
)
12571 unsigned char ch
= bufp
->code
;
12572 ByteCount actual_input_length
, actual_output_length
;
12573 unsigned char outch
;
12575 convert_status
= TECConvertText (converter
, &ch
, 1,
12576 &actual_input_length
,
12578 &actual_output_length
);
12579 if (convert_status
== noErr
12580 && actual_input_length
== 1
12581 && actual_output_length
== 1)
12582 bufp
->code
= outch
;
12587 if (er
.modifiers
& shiftKey
)
12588 the_modifiers
|= shift_modifier
;
12589 if (er
.modifiers
& controlKey
)
12590 the_modifiers
|= ctrl_modifier
;
12591 /* use option or command key as meta depending on value of
12592 mac-command-key-is-meta */
12594 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12595 the_modifiers
|= meta_modifier
;
12596 bufp
->modifiers
= the_modifiers
;
12599 mac_output
*mwp
= (mac_output
*) GetWRefCon (FrontWindow ());
12600 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12603 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
12610 case kHighLevelEvent
:
12611 drag_and_drop_file_list
= Qnil
;
12613 AEProcessAppleEvent(&er
);
12615 /* Build a drag_n_drop type event as is done in
12616 constuct_drag_n_drop in w32term.c. */
12617 if (!NILP (drag_and_drop_file_list
))
12623 wp
= FrontWindow ();
12627 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12629 bufp
->kind
= drag_n_drop
;
12631 bufp
->timestamp
= er
.when
* (1000 / 60);
12632 /* ticks to milliseconds */
12633 bufp
->modifiers
= 0;
12635 XSETINT (bufp
->x
, 0);
12636 XSETINT (bufp
->y
, 0);
12638 XSETFRAME (frame
, f
);
12639 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12641 /* Regardless of whether Emacs was suspended or in the
12642 foreground, ask it to redraw its entire screen.
12643 Otherwise parts of the screen can be left in an
12644 inconsistent state. */
12646 #if TARGET_API_MAC_CARBON
12650 GetWindowPortBounds (wp
, &r
);
12651 InvalWindowRect (wp
, &r
);
12653 #else /* not TARGET_API_MAC_CARBON */
12654 InvalRect (&(wp
->portRect
));
12655 #endif /* not TARGET_API_MAC_CARBON */
12666 /* If the focus was just given to an autoraising frame,
12668 /* ??? This ought to be able to handle more than one such frame. */
12669 if (pending_autoraise_frame
)
12671 x_raise_frame (pending_autoraise_frame
);
12672 pending_autoraise_frame
= 0;
12675 #if !TARGET_API_MAC_CARBON
12676 check_alarm (); /* simulate the handling of a SIGALRM */
12680 static Point old_mouse_pos
= { -1, -1 };
12682 if (app_is_suspended
)
12684 old_mouse_pos
.h
= -1;
12685 old_mouse_pos
.v
= -1;
12693 struct scroll_bar
*sb
;
12695 wp
= FrontWindow ();
12696 if (is_emacs_window (wp
))
12698 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12700 #if TARGET_API_MAC_CARBON
12701 SetPort (GetWindowPort (wp
));
12706 GetMouse (&mouse_pos
);
12708 if (!EqualPt (mouse_pos
, old_mouse_pos
))
12710 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12711 && tracked_scroll_bar
)
12712 x_scroll_bar_note_movement (tracked_scroll_bar
,
12714 - XINT (tracked_scroll_bar
->top
),
12715 TickCount() * (1000 / 60));
12717 note_mouse_movement (f
, &mouse_pos
);
12719 old_mouse_pos
= mouse_pos
;
12731 /* Need to override CodeWarrior's input function so no conversion is
12732 done on newlines Otherwise compiled functions in .elc files will be
12733 read incorrectly. Defined in ...:MSL C:MSL
12734 Common:Source:buffer_io.c. */
12737 __convert_to_newlines (unsigned char * p
, size_t * n
)
12739 #pragma unused(p,n)
12743 __convert_from_newlines (unsigned char * p
, size_t * n
)
12745 #pragma unused(p,n)
12750 /* Initialize the struct pointed to by MW to represent a new COLS x
12751 ROWS Macintosh window, using font with name FONTNAME and size
12754 NewMacWindow (FRAME_PTR fp
)
12757 #if TARGET_API_MAC_CARBON
12758 static int making_terminal_window
= 0;
12760 static int making_terminal_window
= 1;
12763 mwp
= fp
->output_data
.mac
;
12765 if (making_terminal_window
)
12767 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
12770 making_terminal_window
= 0;
12773 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
12777 SetWRefCon (mwp
->mWP
, (long) mwp
);
12778 /* so that update events can find this mac_output struct */
12779 mwp
->mFP
= fp
; /* point back to emacs frame */
12781 #if TARGET_API_MAC_CARBON
12782 SetPort (GetWindowPort (mwp
->mWP
));
12784 SetPort (mwp
->mWP
);
12789 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
12790 ShowWindow (mwp
->mWP
);
12795 void make_mac_frame (struct frame
*f
)
12797 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
12798 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
12801 FRAME_BACKGROUND_PIXEL (f
) = 0xffffff;
12802 FRAME_FOREGROUND_PIXEL (f
) = 0;
12804 f
->output_data
.mac
->cursor_pixel
= 0;
12805 f
->output_data
.mac
->border_pixel
= 0x00ff00;
12806 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
12807 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
12809 f
->output_data
.mac
->desired_cursor
= FILLED_BOX_CURSOR
;
12811 f
->output_data
.mac
->fontset
= -1;
12812 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12813 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12814 f
->output_data
.mac
->left_pos
= 4;
12815 f
->output_data
.mac
->top_pos
= 4;
12816 f
->output_data
.mac
->border_width
= 0;
12817 f
->output_data
.mac
->explicit_parent
= 0;
12819 f
->output_data
.mac
->internal_border_width
= 0;
12821 f
->output_method
= output_mac
;
12830 void make_mac_terminal_frame (struct frame
*f
)
12834 XSETFRAME (frame
, f
);
12836 f
->output_method
= output_mac
;
12837 f
->output_data
.mac
= (struct mac_output
*)
12838 xmalloc (sizeof (struct mac_output
));
12839 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
12840 f
->output_data
.mac
->fontset
= -1;
12841 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12842 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12844 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
12849 make_mac_frame (f
);
12853 /* Need to be initialized for unshow_buffer in window.c. */
12854 selected_window
= f
->selected_window
;
12856 Fmodify_frame_parameters (frame
,
12857 Fcons (Fcons (Qfont
,
12858 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
12859 Fmodify_frame_parameters (frame
,
12860 Fcons (Fcons (Qforeground_color
,
12861 build_string ("black")), Qnil
));
12862 Fmodify_frame_parameters (frame
,
12863 Fcons (Fcons (Qbackground_color
,
12864 build_string ("white")), Qnil
));
12868 /***********************************************************************
12870 ***********************************************************************/
12872 #ifdef USE_X_TOOLKIT
12873 static XrmOptionDescRec emacs_options
[] = {
12874 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
12875 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
12877 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
12878 XrmoptionSepArg
, NULL
},
12879 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
12881 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12882 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12883 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
12884 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12885 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
12886 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
12887 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
12889 #endif /* USE_X_TOOLKIT */
12891 #ifdef MULTI_KBOARD
12892 /* Test whether two display-name strings agree up to the dot that separates
12893 the screen number from the server number. */
12895 same_x_server (name1
, name2
)
12896 char *name1
, *name2
;
12898 int seen_colon
= 0;
12899 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
12900 int system_name_length
= strlen (system_name
);
12901 int length_until_period
= 0;
12903 while (system_name
[length_until_period
] != 0
12904 && system_name
[length_until_period
] != '.')
12905 length_until_period
++;
12907 /* Treat `unix' like an empty host name. */
12908 if (! strncmp (name1
, "unix:", 5))
12910 if (! strncmp (name2
, "unix:", 5))
12912 /* Treat this host's name like an empty host name. */
12913 if (! strncmp (name1
, system_name
, system_name_length
)
12914 && name1
[system_name_length
] == ':')
12915 name1
+= system_name_length
;
12916 if (! strncmp (name2
, system_name
, system_name_length
)
12917 && name2
[system_name_length
] == ':')
12918 name2
+= system_name_length
;
12919 /* Treat this host's domainless name like an empty host name. */
12920 if (! strncmp (name1
, system_name
, length_until_period
)
12921 && name1
[length_until_period
] == ':')
12922 name1
+= length_until_period
;
12923 if (! strncmp (name2
, system_name
, length_until_period
)
12924 && name2
[length_until_period
] == ':')
12925 name2
+= length_until_period
;
12927 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
12931 if (seen_colon
&& *name1
== '.')
12935 && (*name1
== '.' || *name1
== '\0')
12936 && (*name2
== '.' || *name2
== '\0'));
12940 int mac_initialized
= 0;
12943 mac_initialize_display_info ()
12945 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
12946 GDHandle main_device_handle
;
12948 bzero (dpyinfo
, sizeof (*dpyinfo
));
12950 /* Put it on x_display_name_list. */
12951 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
12952 x_display_name_list
);
12953 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
12956 dpyinfo
->mac_id_name
12957 = (char *) xmalloc (XSTRING (Vinvocation_name
)->size
12958 + XSTRING (Vsystem_name
)->size
12960 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
12961 XSTRING (Vinvocation_name
)->data
, XSTRING (Vsystem_name
)->data
);
12963 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
12964 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
12967 main_device_handle
= LMGetMainDevice();
12969 dpyinfo
->reference_count
= 0;
12970 dpyinfo
->resx
= 75.0;
12971 dpyinfo
->resy
= 75.0;
12972 dpyinfo
->n_planes
= 1;
12973 dpyinfo
->n_cbits
= 16;
12974 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
12975 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
12976 dpyinfo
->grabbed
= 0;
12977 dpyinfo
->root_window
= NULL
;
12979 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
12980 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
12981 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
12982 dpyinfo
->mouse_face_window
= Qnil
;
12985 struct mac_display_info
*
12986 mac_term_init (display_name
, xrm_option
, resource_name
)
12987 Lisp_Object display_name
;
12989 char *resource_name
;
12991 struct mac_display_info
*dpyinfo
;
12992 GDHandle main_device_handle
;
12994 if (!mac_initialized
)
12997 mac_initialized
= 1;
13000 mac_initialize_display_info (display_name
);
13002 dpyinfo
= &one_mac_display_info
;
13004 main_device_handle
= LMGetMainDevice();
13006 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
13007 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
13012 /* Set up use of X before we make the first connection. */
13014 static struct redisplay_interface x_redisplay_interface
=
13019 x_clear_end_of_line
,
13021 x_after_update_window_line
,
13022 x_update_window_begin
,
13023 x_update_window_end
,
13026 x_clear_mouse_face
,
13027 x_get_glyph_overhangs
,
13028 x_fix_overlapping_area
13034 rif
= &x_redisplay_interface
;
13036 clear_frame_hook
= x_clear_frame
;
13037 ins_del_lines_hook
= x_ins_del_lines
;
13038 delete_glyphs_hook
= x_delete_glyphs
;
13039 ring_bell_hook
= XTring_bell
;
13040 reset_terminal_modes_hook
= XTreset_terminal_modes
;
13041 set_terminal_modes_hook
= XTset_terminal_modes
;
13042 update_begin_hook
= x_update_begin
;
13043 update_end_hook
= x_update_end
;
13044 set_terminal_window_hook
= XTset_terminal_window
;
13045 read_socket_hook
= XTread_socket
;
13046 frame_up_to_date_hook
= XTframe_up_to_date
;
13047 mouse_position_hook
= XTmouse_position
;
13048 frame_rehighlight_hook
= XTframe_rehighlight
;
13049 frame_raise_lower_hook
= XTframe_raise_lower
;
13051 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
13052 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
13053 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
13054 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
13056 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
13058 scroll_region_ok
= 1; /* we'll scroll partial frames */
13059 char_ins_del_ok
= 1;
13060 line_ins_del_ok
= 1; /* we'll just blt 'em */
13061 fast_clear_end_of_line
= 1; /* X does this well */
13062 memory_below_frame
= 0; /* we don't remember what scrolls
13067 last_tool_bar_item
= -1;
13068 any_help_event_p
= 0;
13070 /* Try to use interrupt input; if we can't, then start polling. */
13071 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
13073 #ifdef USE_X_TOOLKIT
13074 XtToolkitInitialize ();
13075 Xt_app_con
= XtCreateApplicationContext ();
13076 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
13078 /* Install an asynchronous timer that processes Xt timeout events
13079 every 0.1s. This is necessary because some widget sets use
13080 timeouts internally, for example the LessTif menu bar, or the
13081 Xaw3d scroll bar. When Xt timouts aren't processed, these
13082 widgets don't behave normally. */
13084 EMACS_TIME interval
;
13085 EMACS_SET_SECS_USECS (interval
, 0, 100000);
13086 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
13090 #if USE_TOOLKIT_SCROLL_BARS
13091 xaw3d_arrow_scroll
= False
;
13092 xaw3d_pick_top
= True
;
13096 /* Note that there is no real way portable across R3/R4 to get the
13097 original error handler. */
13098 XSetErrorHandler (x_error_handler
);
13099 XSetIOErrorHandler (x_io_error_quitter
);
13101 /* Disable Window Change signals; they are handled by X events. */
13103 signal (SIGWINCH
, SIG_DFL
);
13104 #endif /* ! defined (SIGWINCH) */
13106 signal (SIGPIPE
, x_connection_signal
);
13109 mac_initialize_display_info ();
13117 staticpro (&x_error_message_string
);
13118 x_error_message_string
= Qnil
;
13121 staticpro (&x_display_name_list
);
13122 x_display_name_list
= Qnil
;
13124 staticpro (&last_mouse_scroll_bar
);
13125 last_mouse_scroll_bar
= Qnil
;
13127 staticpro (&Qvendor_specific_keysyms
);
13128 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
13130 staticpro (&last_mouse_press_frame
);
13131 last_mouse_press_frame
= Qnil
;
13133 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
13134 staticpro (&Qmac_ready_for_drag_n_drop
);
13137 staticpro (&help_echo
);
13138 help_echo_object
= Qnil
;
13139 staticpro (&help_echo_object
);
13140 help_echo_window
= Qnil
;
13141 staticpro (&help_echo_window
);
13142 previous_help_echo
= Qnil
;
13143 staticpro (&previous_help_echo
);
13144 help_echo_pos
= -1;
13146 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
13147 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
13148 x_autoselect_window_p
= 0;
13150 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
13151 doc
: /* *Non-nil means draw block cursor as wide as the glyph under it.
13152 For example, if a block cursor is over a tab, it will be drawn as
13153 wide as that tab on the display. */);
13154 x_stretch_cursor_p
= 0;
13156 #if 0 /* TODO: Setting underline position from font properties. */
13157 DEFVAR_BOOL ("x-use-underline-position-properties",
13158 &x_use_underline_position_properties
,
13159 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
13160 nil means ignore them. If you encounter fonts with bogus
13161 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
13162 to 4.1, set this to nil. */);
13163 x_use_underline_position_properties
= 1;
13166 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
13167 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
13168 Vx_toolkit_scroll_bars
= Qt
;
13170 staticpro (&last_mouse_motion_frame
);
13171 last_mouse_motion_frame
= Qnil
;
13173 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
13174 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
13175 Otherwise the option key is used. */);
13176 Vmac_command_key_is_meta
= Qt
;
13178 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
13179 doc
: /* One of the Text Encoding Base constant values defined in the
13180 Basic Text Constants section of Inside Macintosh - Text Encoding
13181 Conversion Manager. Its value determines the encoding characters
13182 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
13183 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
13184 its default value, no conversion takes place. If it is set to
13185 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
13186 characters typed on Mac keyboard are first converted into the
13187 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
13188 passed to Emacs. Together with Emacs's set-keyboard-coding-system
13189 command, this enables the Mac keyboard to be used to enter non-ASCII
13190 characters directly. */);
13191 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;