1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000 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@users.sourceforge.net). */
25 /* On 4.3 these lose if they come after xterm.h. */
26 /* Putting these at the beginning seems to be standard for other .c files. */
32 #include "blockinput.h"
34 /* Need syssignal.h for various externs and definitions that may be required
35 by some configurations for calls to signal later in this source file. */
36 #include "syssignal.h"
38 /* This may include sys/types.h, and that somehow loses
39 if this is not done before the other system files. */
46 #include <Quickdraw.h>
47 #include <ToolUtils.h>
51 #include <Resources.h>
53 #include <TextUtils.h>
56 #if defined (__MRC__) || defined (CODEWARRIOR_VERSION_6)
57 #include <ControlDefinitions.h>
64 #include <sys/types.h>
69 #ifndef INCLUDED_FCNTL
80 #include "dispextern.h"
82 #include "termhooks.h"
90 #include "intervals.h"
100 #ifndef USE_X_TOOLKIT
101 #define x_any_window_to_frame x_window_to_frame
102 #define x_top_window_to_frame x_window_to_frame
106 #define min(a,b) ((a) < (b) ? (a) : (b))
109 #define max(a,b) ((a) > (b) ? (a) : (b))
112 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
115 /* Fringe bitmaps. */
117 enum fringe_bitmap_type
120 LEFT_TRUNCATION_BITMAP
,
121 RIGHT_TRUNCATION_BITMAP
,
122 OVERLAY_ARROW_BITMAP
,
123 CONTINUED_LINE_BITMAP
,
124 CONTINUATION_LINE_BITMAP
,
128 /* Bitmap drawn to indicate lines not displaying text if
129 `indicate-empty-lines' is non-nil. */
134 static unsigned char zv_bits
[] = {
135 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
136 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
137 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
138 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
139 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
140 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
141 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
142 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
144 /* An arrow like this: `<-'. */
147 #define left_height 8
148 static unsigned char left_bits
[] = {
149 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
151 /* Right truncation arrow bitmap `->'. */
153 #define right_width 8
154 #define right_height 8
155 static unsigned char right_bits
[] = {
156 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
158 /* Marker for continued lines. */
160 #define continued_width 8
161 #define continued_height 8
162 static unsigned char continued_bits
[] = {
163 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
165 /* Marker for continuation lines. */
167 #define continuation_width 8
168 #define continuation_height 8
169 static unsigned char continuation_bits
[] = {
170 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
172 /* Overlay arrow bitmap. */
178 static unsigned char ov_bits
[] = {
179 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
181 /* A triangular arrow. */
184 static unsigned char ov_bits
[] = {
185 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
188 extern Lisp_Object Qhelp_echo
;
191 /* Non-zero means Emacs uses toolkit scroll bars. */
193 int x_toolkit_scroll_bars_p
;
195 /* If a string, XTread_socket generates an event to display that string.
196 (The display is done in read_char.) */
198 static Lisp_Object help_echo
;
199 static Lisp_Object help_echo_window
;
200 static Lisp_Object help_echo_object
;
201 static int help_echo_pos
;
203 /* Temporary variable for XTread_socket. */
205 static Lisp_Object previous_help_echo
;
207 /* Non-zero means that a HELP_EVENT has been generated since Emacs
210 static int any_help_event_p
;
212 /* Non-zero means draw block and hollow cursor as wide as the glyph
213 under it. For example, if a block cursor is over a tab, it will be
214 drawn as wide as that tab on the display. */
216 int x_stretch_cursor_p
;
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 /* This is a frame waiting to be auto-raised, within XTread_socket. */
242 struct frame
*pending_autoraise_frame
;
244 /* Nominal cursor position -- where to draw output.
245 HPOS and VPOS are window relative glyph matrix coordinates.
246 X and Y are window relative pixel coordinates. */
248 struct cursor_pos output_cursor
;
250 /* Non-zero means user is interacting with a toolkit scroll bar. */
252 static int toolkit_scroll_bar_interaction
;
256 Formerly, we used PointerMotionHintMask (in standard_event_mask)
257 so that we would have to call XQueryPointer after each MotionNotify
258 event to ask for another such event. However, this made mouse tracking
259 slow, and there was a bug that made it eventually stop.
261 Simply asking for MotionNotify all the time seems to work better.
263 In order to avoid asking for motion events and then throwing most
264 of them away or busy-polling the server for mouse positions, we ask
265 the server for pointer motion hints. This means that we get only
266 one event per group of mouse movements. "Groups" are delimited by
267 other kinds of events (focus changes and button clicks, for
268 example), or by XQueryPointer calls; when one of these happens, we
269 get another MotionNotify event the next time the mouse moves. This
270 is at least as efficient as getting motion events when mouse
271 tracking is on, and I suspect only negligibly worse when tracking
274 /* Where the mouse was last time we reported a mouse event. */
276 FRAME_PTR last_mouse_frame
;
277 static Rect last_mouse_glyph
;
278 static Lisp_Object last_mouse_press_frame
;
280 /* The scroll bar in which the last X motion event occurred.
282 If the last X motion event occurred in a scroll bar, we set this so
283 XTmouse_position can know whether to report a scroll bar motion or
286 If the last X motion event didn't occur in a scroll bar, we set
287 this to Qnil, to tell XTmouse_position to return an ordinary motion
290 static Lisp_Object last_mouse_scroll_bar
;
292 /* This is a hack. We would really prefer that XTmouse_position would
293 return the time associated with the position it returns, but there
294 doesn't seem to be any way to wrest the time-stamp from the server
295 along with the position query. So, we just keep track of the time
296 of the last movement we received, and return that in hopes that
297 it's somewhat accurate. */
299 static Time last_mouse_movement_time
;
301 enum mouse_tracking_type
{
303 mouse_tracking_mouse_movement
,
304 mouse_tracking_scroll_bar
307 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
309 struct scroll_bar
*tracked_scroll_bar
= NULL
;
311 /* Incremented by XTread_socket whenever it really tries to read
315 static int volatile input_signal_count
;
317 static int input_signal_count
;
320 /* Used locally within XTread_socket. */
322 static int x_noop_count
;
324 /* Initial values of argv and argc. */
326 extern char **initial_argv
;
327 extern int initial_argc
;
329 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
331 /* Tells if a window manager is present or not. */
333 extern Lisp_Object Vx_no_window_manager
;
335 extern Lisp_Object Qface
, Qmouse_face
;
339 /* A mask of extra modifier bits to put into every keyboard char. */
341 extern int extra_keyboard_modifiers
;
343 static Lisp_Object Qvendor_specific_keysyms
;
346 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
349 extern Lisp_Object x_icon_type
P_ ((struct frame
*));
353 QDGlobals qd
; /* QuickDraw global information structure. */
357 /* Enumeration for overriding/changing the face to use for drawing
358 glyphs in x_draw_glyphs. */
360 enum draw_glyphs_face
370 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
371 struct mac_display_info
*mac_display_info_for_display (Display
*);
372 static void x_update_window_end
P_ ((struct window
*, int, int));
373 static void frame_to_window_pixel_xy
P_ ((struct window
*, int *, int *));
374 void x_delete_display
P_ ((struct x_display_info
*));
375 static unsigned int x_mac_to_emacs_modifiers
P_ ((struct x_display_info
*,
377 static int fast_find_position
P_ ((struct window
*, int, int *, int *,
379 static void set_output_cursor
P_ ((struct cursor_pos
*));
380 static struct glyph
*x_y_to_hpos_vpos
P_ ((struct window
*, int, int,
381 int *, int *, int *));
382 static void note_mode_line_highlight
P_ ((struct window
*, int, int));
383 static void note_mouse_highlight
P_ ((struct frame
*, int, int));
384 static void note_tool_bar_highlight
P_ ((struct frame
*f
, int, int));
385 static void x_handle_tool_bar_click
P_ ((struct frame
*, XButtonEvent
*));
386 static void show_mouse_face
P_ ((struct x_display_info
*,
387 enum draw_glyphs_face
));
388 void clear_mouse_face
P_ ((struct mac_display_info
*));
389 static int x_io_error_quitter
P_ ((Display
*));
390 int x_catch_errors
P_ ((Display
*));
391 void x_uncatch_errors
P_ ((Display
*, int));
392 void x_lower_frame
P_ ((struct frame
*));
393 void x_scroll_bar_clear
P_ ((struct frame
*));
394 int x_had_errors_p
P_ ((Display
*));
395 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
396 void x_raise_frame
P_ ((struct frame
*));
397 void x_set_window_size
P_ ((struct frame
*, int, int, int));
398 void x_wm_set_window_state
P_ ((struct frame
*, int));
399 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
400 void x_initialize
P_ ((void));
401 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
402 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
403 enum text_cursor_kinds x_specified_cursor_type
P_ ((Lisp_Object
, int *));
404 static void x_draw_phys_cursor_glyph
P_ ((struct window
*,
406 enum draw_glyphs_face
));
407 static void x_update_end
P_ ((struct frame
*));
408 static void XTframe_up_to_date
P_ ((struct frame
*));
409 static void XTreassert_line_highlight
P_ ((int, int));
410 static void x_change_line_highlight
P_ ((int, int, int, int));
411 static void XTset_terminal_modes
P_ ((void));
412 static void XTreset_terminal_modes
P_ ((void));
413 static void XTcursor_to
P_ ((int, int, int, int));
414 static void x_write_glyphs
P_ ((struct glyph
*, int));
415 static void x_clear_end_of_line
P_ ((int));
416 static void x_clear_frame
P_ ((void));
417 static void x_clear_cursor
P_ ((struct window
*));
418 static void frame_highlight
P_ ((struct frame
*));
419 static void frame_unhighlight
P_ ((struct frame
*));
420 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
421 static void XTframe_rehighlight
P_ ((struct frame
*));
422 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
423 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
424 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
425 static int x_intersect_rectangles
P_ ((Rect
*, Rect
*, Rect
*));
426 static void expose_frame
P_ ((struct frame
*, int, int, int, int));
427 static void expose_window_tree
P_ ((struct window
*, Rect
*));
428 static void expose_window
P_ ((struct window
*, Rect
*));
429 static void expose_area
P_ ((struct window
*, struct glyph_row
*,
430 XRectangle
*, enum glyph_row_area
));
431 static void expose_line
P_ ((struct window
*, struct glyph_row
*,
433 void x_display_cursor (struct window
*, int, int, int, int, int);
434 void x_update_cursor
P_ ((struct frame
*, int));
435 static void x_update_cursor_in_window_tree
P_ ((struct window
*, int));
436 static void x_update_window_cursor
P_ ((struct window
*, int));
437 static void x_erase_phys_cursor
P_ ((struct window
*));
438 void x_display_and_set_cursor
P_ ((struct window
*, int, int, int, int, int));
439 static void x_draw_fringe_bitmap
P_ ((struct window
*, struct glyph_row
*,
440 enum fringe_bitmap_type
, int left_p
));
441 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
443 static int x_phys_cursor_in_rect_p
P_ ((struct window
*, Rect
*));
444 static void x_draw_row_fringe_bitmaps
P_ ((struct window
*, struct glyph_row
*));
445 static void note_overwritten_text_cursor
P_ ((struct window
*, int, int));
446 static void x_flush
P_ ((struct frame
*f
));
447 static void x_update_begin
P_ ((struct frame
*));
448 static void x_update_window_begin
P_ ((struct window
*));
449 static void x_draw_vertical_border
P_ ((struct window
*));
450 static void x_after_update_window_line
P_ ((struct glyph_row
*));
451 static INLINE
void take_vertical_position_into_account
P_ ((struct it
*));
452 static void x_produce_stretch_glyph
P_ ((struct it
*));
454 static void activate_scroll_bars (FRAME_PTR
);
455 static void deactivate_scroll_bars (FRAME_PTR
);
457 extern int image_ascent (struct image
*, struct face
*);
458 void x_set_offset (struct frame
*, int, int, int);
459 int x_bitmap_icon (struct frame
*, Lisp_Object
);
460 void x_make_frame_visible (struct frame
*);
462 extern void window_scroll (Lisp_Object
, int, int, int);
464 /* Defined in macmenu.h. */
465 extern void menubar_selection_callback (FRAME_PTR
, int);
466 extern void set_frame_menubar (FRAME_PTR
, int, int);
468 /* X display function emulation */
470 /* Structure borrowed from Xlib.h to represent two-byte characters in
479 XFreePixmap (display
, pixmap
)
483 PixMap
*p
= (PixMap
*) pixmap
;
490 /* Set foreground color for subsequent QuickDraw commands. Assume
491 graphic port has already been set. */
494 mac_set_forecolor (unsigned long color
)
498 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
499 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
500 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
502 RGBForeColor (&fg_color
);
506 /* Set background color for subsequent QuickDraw commands. Assume
507 graphic port has already been set. */
510 mac_set_backcolor (unsigned long color
)
514 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
515 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
516 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
518 RGBBackColor (&bg_color
);
521 /* Set foreground and background color for subsequent QuickDraw
522 commands. Assume that the graphic port has already been set. */
525 mac_set_colors (GC gc
)
527 mac_set_forecolor (gc
->foreground
);
528 mac_set_backcolor (gc
->background
);
531 /* Mac version of XDrawLine. */
534 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
547 /* Mac version of XClearArea. */
550 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
554 unsigned int width
, height
;
557 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
561 xgc
.foreground
= mwp
->foreground_pixel
;
562 xgc
.background
= mwp
->background_pixel
;
565 mac_set_colors (&xgc
);
566 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
571 /* Mac version of XClearWindow. */
574 XClearWindow (display
, w
)
578 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
581 xgc
.foreground
= mwp
->foreground_pixel
;
582 xgc
.background
= mwp
->background_pixel
;
585 mac_set_colors (&xgc
);
587 EraseRect (&(w
->portRect
));
591 /* Mac replacement for XCopyArea. */
594 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
605 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
607 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
611 /* Mac replacement for XSetClipRectangles. */
614 mac_set_clip_rectangle (display
, w
, r
)
625 /* Mac replacement for XSetClipMask. */
628 mac_reset_clipping (display
, w
)
636 SetRect (&r
, -32767, -32767, 32767, 32767);
641 /* Mac replacement for XCreateBitmapFromBitmapData. */
644 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
649 int bytes_per_row
, i
, j
;
651 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
652 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
653 if (!bitmap
->baseAddr
)
656 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
657 for (i
= 0; i
< h
; i
++)
658 for (j
= 0; j
< w
; j
++)
659 if (BitTst (bits
, i
* w
+ j
))
660 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
662 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
667 mac_free_bitmap (bitmap
)
670 xfree (bitmap
->baseAddr
);
673 /* Mac replacement for XFillRectangle. */
676 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
681 unsigned int width
, height
;
687 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
689 PaintRect (&r
); /* using foreground color of gc */
693 /* Mac replacement for XDrawRectangle: dest is a window. */
696 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
701 unsigned int width
, height
;
707 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
709 FrameRect (&r
); /* using foreground color of gc */
713 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
716 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
721 unsigned int width
, height
;
723 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
728 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
730 FrameRect (&r
); /* using foreground color of gc */
736 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
743 int nchars
, mode
, bytes_per_char
;
748 TextFont (gc
->font
->mac_fontnum
);
749 TextSize (gc
->font
->mac_fontsize
);
750 TextFace (gc
->font
->mac_fontface
);
754 DrawText (buf
, 0, nchars
* bytes_per_char
);
758 /* Mac replacement for XDrawString. */
761 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
769 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
773 /* Mac replacement for XDrawString16. */
776 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
784 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
789 /* Mac replacement for XDrawImageString. */
792 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
800 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
804 /* Mac replacement for XDrawString16. */
807 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
815 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
820 /* Mac replacement for XCopyArea: dest must be window. */
823 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
830 unsigned int width
, height
;
838 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
839 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
841 CopyBits ((BitMap
*) src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
846 /* Convert a pair of local coordinates to global (screen) coordinates.
847 Assume graphic port has been properly set. */
849 local_to_global_coord (short *h
, short *v
)
863 /* Mac replacement for XCopyArea: used only for scrolling. */
866 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
871 unsigned int width
, height
;
881 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
882 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
885 /* Need to use global coordinates and screenBits since src and dest
886 areas overlap in general. */
887 local_to_global_coord (&src_r
.left
, &src_r
.top
);
888 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
889 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
890 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
892 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
894 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
895 color mapping in CopyBits. Otherwise, it will be slow. */
896 ForeColor (blackColor
);
897 BackColor (whiteColor
);
898 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
905 /* Mac replacement for XCopyArea: dest must be Pixmap. */
908 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
915 unsigned int width
, height
;
919 int src_right
= ((PixMap
*) src
)->bounds
.right
;
920 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
921 int w
= src_right
- src_x
;
922 int h
= src_bottom
- src_y
;
926 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
927 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
929 CopyBits ((BitMap
*) src
, (BitMap
*) dest
, &src_r
, &dest_r
, srcCopy
, 0);
933 /* Mac replacement for XChangeGC. */
936 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
939 if (mask
& GCForeground
)
940 gc
->foreground
= xgcv
->foreground
;
941 if (mask
& GCBackground
)
942 gc
->background
= xgcv
->background
;
944 gc
->font
= xgcv
->font
;
948 /* Mac replacement for XCreateGC. */
951 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
954 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
955 bzero (gc
, sizeof (XGCValues
));
957 XChangeGC (ignore
, gc
, mask
, xgcv
);
963 /* Used in xfaces.c. */
966 XFreeGC (display
, gc
)
974 /* Mac replacement for XGetGCValues. */
977 XGetGCValues (void* ignore
, XGCValues
*gc
,
978 unsigned long mask
, XGCValues
*xgcv
)
980 XChangeGC (ignore
, xgcv
, mask
, gc
);
984 /* Mac replacement for XSetForeground. */
987 XSetForeground (display
, gc
, color
)
992 gc
->foreground
= color
;
996 /* Mac replacement for XSetFont. */
999 XSetFont (display
, gc
, font
)
1009 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1010 int *direction
,int *font_ascent
,
1011 int *font_descent
, XCharStruct
*cs
)
1013 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1017 /* x_sync is a no-op on Mac. */
1025 /* Flush display of frame F, or of all frames if F is null. */
1031 #if 0 /* Nothing to do for Mac OS (needed in OS X perhaps?). */
1035 Lisp_Object rest
, frame
;
1036 FOR_EACH_FRAME (rest
, frame
)
1037 x_flush (XFRAME (frame
));
1039 else if (FRAME_X_P (f
))
1040 XFlush (FRAME_MAC_DISPLAY (f
));
1046 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1047 Calls to XFlush should be unnecessary because the X output buffer
1048 is flushed automatically as needed by calls to XPending,
1049 XNextEvent, or XWindowEvent according to the XFlush man page.
1050 XTread_socket calls XPending. Removing XFlush improves
1053 #define XFlush(DISPLAY) (void) 0
1056 /* Return the struct mac_display_info corresponding to DPY. There's
1059 struct mac_display_info
*
1060 mac_display_info_for_display (dpy
)
1063 return &one_mac_display_info
;
1068 /***********************************************************************
1069 Starting and ending an update
1070 ***********************************************************************/
1072 /* Start an update of frame F. This function is installed as a hook
1073 for update_begin, i.e. it is called when update_begin is called.
1074 This function is called prior to calls to x_update_window_begin for
1075 each window being updated. Currently, there is nothing to do here
1076 because all interesting stuff is done on a window basis. */
1082 /* Nothing to do. */
1086 /* Start update of window W. Set the global variable updated_window
1087 to the window being updated and set output_cursor to the cursor
1091 x_update_window_begin (w
)
1094 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1095 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1098 set_output_cursor (&w
->cursor
);
1102 if (f
== display_info
->mouse_face_mouse_frame
)
1104 /* Don't do highlighting for mouse motion during the update. */
1105 display_info
->mouse_face_defer
= 1;
1107 /* If F needs to be redrawn, simply forget about any prior mouse
1109 if (FRAME_GARBAGED_P (f
))
1110 display_info
->mouse_face_window
= Qnil
;
1112 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1113 their mouse_face_p flag set, which means that they are always
1114 unequal to rows in a desired matrix which never have that
1115 flag set. So, rows containing mouse-face glyphs are never
1116 scrolled, and we don't have to switch the mouse highlight off
1117 here to prevent it from being scrolled. */
1119 /* Can we tell that this update does not affect the window
1120 where the mouse highlight is? If so, no need to turn off.
1121 Likewise, don't do anything if the frame is garbaged;
1122 in that case, the frame's current matrix that we would use
1123 is all wrong, and we will redisplay that line anyway. */
1124 if (!NILP (display_info
->mouse_face_window
)
1125 && w
== XWINDOW (display_info
->mouse_face_window
))
1129 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1130 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1133 if (i
< w
->desired_matrix
->nrows
)
1134 clear_mouse_face (display_info
);
1143 /* Draw a vertical window border to the right of window W if W doesn't
1144 have vertical scroll bars. */
1147 x_draw_vertical_border (w
)
1150 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1152 /* Redraw borders between horizontally adjacent windows. Don't
1153 do it for frames with vertical scroll bars because either the
1154 right scroll bar of a window, or the left scroll bar of its
1155 neighbor will suffice as a border. */
1156 if (!WINDOW_RIGHTMOST_P (w
)
1157 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1161 window_box_edges (w
, -1, &x0
, &y0
, &x1
, &y1
);
1162 x1
+= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1165 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1166 f
->output_data
.mac
->normal_gc
, x1
, y0
, x1
, y1
);
1171 /* End update of window W (which is equal to updated_window).
1173 Draw vertical borders between horizontally adjacent windows, and
1174 display W's cursor if CURSOR_ON_P is non-zero.
1176 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1177 glyphs in mouse-face were overwritten. In that case we have to
1178 make sure that the mouse-highlight is properly redrawn.
1180 W may be a menu bar pseudo-window in case we don't have X toolkit
1181 support. Such windows don't have a cursor, so don't display it
1185 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1187 int cursor_on_p
, mouse_face_overwritten_p
;
1189 if (!w
->pseudo_window_p
)
1191 struct mac_display_info
*dpyinfo
1192 = FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1196 /* If a row with mouse-face was overwritten, arrange for
1197 XTframe_up_to_date to redisplay the mouse highlight. */
1198 if (mouse_face_overwritten_p
)
1200 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1201 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1202 dpyinfo
->mouse_face_window
= Qnil
;
1206 x_display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1208 output_cursor
.x
, output_cursor
.y
);
1210 x_draw_vertical_border (w
);
1214 updated_window
= NULL
;
1218 /* End update of frame F. This function is installed as a hook in
1225 /* Reset the background color of Mac OS Window to that of the frame after
1226 update so that it is used by Mac Toolbox to clear the update region before
1227 an update event is generated. */
1228 SetPort (FRAME_MAC_WINDOW (f
));
1229 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1231 /* Mouse highlight may be displayed again. */
1232 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1235 XFlush (FRAME_MAC_DISPLAY (f
));
1240 /* This function is called from various places in xdisp.c whenever a
1241 complete update has been performed. The global variable
1242 updated_window is not available here. */
1245 XTframe_up_to_date (f
)
1250 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1252 if (dpyinfo
->mouse_face_deferred_gc
1253 || f
== dpyinfo
->mouse_face_mouse_frame
)
1256 if (dpyinfo
->mouse_face_mouse_frame
)
1257 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1258 dpyinfo
->mouse_face_mouse_x
,
1259 dpyinfo
->mouse_face_mouse_y
);
1260 dpyinfo
->mouse_face_deferred_gc
= 0;
1267 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1268 arrow bitmaps, or clear the fringes if no bitmaps are required
1269 before DESIRED_ROW is made current. The window being updated is
1270 found in updated_window. This function It is called from
1271 update_window_line only if it is known that there are differences
1272 between bitmaps to be drawn between current row and DESIRED_ROW. */
1275 x_after_update_window_line (desired_row
)
1276 struct glyph_row
*desired_row
;
1278 struct window
*w
= updated_window
;
1282 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1285 x_draw_row_fringe_bitmaps (w
, desired_row
);
1287 /* When a window has disappeared, make sure that no rest of
1288 full-width rows stays visible in the internal border. */
1289 if (windows_or_buffers_changed
)
1291 struct frame
*f
= XFRAME (w
->frame
);
1292 int width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1293 int height
= desired_row
->visible_height
;
1294 int x
= (window_box_right (w
, -1)
1295 + FRAME_X_RIGHT_FRINGE_WIDTH (f
));
1296 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1298 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1299 x
, y
, width
, height
, 0);
1307 /* Draw the bitmap WHICH in one of the left or right fringes of
1308 window W. ROW is the glyph row for which to display the bitmap; it
1309 determines the vertical position at which the bitmap has to be
1313 x_draw_fringe_bitmap (w
, row
, which
, left_p
)
1315 struct glyph_row
*row
;
1316 enum fringe_bitmap_type which
;
1319 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1320 Display
*display
= FRAME_MAC_DISPLAY (f
);
1321 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1322 int x
, y
, wd
, h
, dy
;
1324 unsigned char *bits
;
1329 /* Must clip because of partially visible lines. */
1330 x_clip_to_row (w
, row
, 1);
1332 /* Convert row to frame coordinates. */
1333 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1337 case NO_FRINGE_BITMAP
:
1342 case LEFT_TRUNCATION_BITMAP
:
1348 case OVERLAY_ARROW_BITMAP
:
1354 case RIGHT_TRUNCATION_BITMAP
:
1360 case CONTINUED_LINE_BITMAP
:
1361 wd
= continued_width
;
1362 h
= continued_height
;
1363 bits
= continued_bits
;
1366 case CONTINUATION_LINE_BITMAP
:
1367 wd
= continuation_width
;
1368 h
= continuation_height
;
1369 bits
= continuation_bits
;
1372 case ZV_LINE_BITMAP
:
1374 h
= zv_height
- (y
% zv_period
);
1375 bits
= zv_bits
+ (y
% zv_period
);
1382 /* Clip bitmap if too high. */
1383 if (h
> row
->height
)
1386 /* Set dy to the offset in the row to start drawing the bitmap. */
1387 dy
= (row
->height
- h
) / 2;
1389 /* Draw the bitmap. I believe these small pixmaps can be cached
1391 face
= FACE_FROM_ID (f
, FRINGE_FACE_ID
);
1392 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1394 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
1399 if (wd
> FRAME_X_LEFT_FRINGE_WIDTH (f
))
1400 wd
= FRAME_X_LEFT_FRINGE_WIDTH (f
);
1401 x
= (WINDOW_TO_FRAME_PIXEL_X (w
, 0)
1403 - (FRAME_X_LEFT_FRINGE_WIDTH (f
) - wd
) / 2);
1404 if (wd
< FRAME_X_LEFT_FRINGE_WIDTH (f
) || row
->height
> h
)
1406 /* If W has a vertical border to its left, don't draw over it. */
1407 int border
= ((XFASTINT (w
->left
) > 0
1408 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
1410 b1
= (window_box_left (w
, -1)
1411 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
1413 b2
= (FRAME_X_LEFT_FRINGE_WIDTH (f
) - border
);
1418 if (wd
> FRAME_X_RIGHT_FRINGE_WIDTH (f
))
1419 wd
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1420 x
= (window_box_right (w
, -1)
1421 + (FRAME_X_RIGHT_FRINGE_WIDTH (f
) - wd
) / 2);
1422 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
1424 if (wd
< FRAME_X_RIGHT_FRINGE_WIDTH (f
) || row
->height
> h
)
1426 b1
= window_box_right (w
, -1);
1427 b2
= FRAME_X_RIGHT_FRINGE_WIDTH (f
);
1433 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
1435 gcv
.foreground
= face
->background
;
1437 #if 0 /* MAC_TODO: stipple */
1438 /* In case the same realized face is used for fringes and
1439 for something displayed in the text (e.g. face `region' on
1440 mono-displays, the fill style may have been changed to
1441 FillSolid in x_draw_glyph_string_background. */
1443 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1445 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1448 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1451 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
1454 row
->visible_height
);
1456 #if 0 /* MAC_TODO: stipple */
1458 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1462 if (which
== NO_FRINGE_BITMAP
)
1465 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, wd
, h
);
1466 gcv
.foreground
= face
->foreground
;
1467 gcv
.background
= face
->background
;
1469 mac_draw_bitmap (display
, window
, &gcv
, x
, y
+ dy
, &bitmap
);
1471 mac_free_bitmap (&bitmap
);
1472 mac_reset_clipping (display
, window
);
1476 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
1477 function with input blocked. */
1480 x_draw_row_fringe_bitmaps (w
, row
)
1482 struct glyph_row
*row
;
1484 struct frame
*f
= XFRAME (w
->frame
);
1485 enum fringe_bitmap_type bitmap
;
1487 xassert (interrupt_input_blocked
);
1489 /* If row is completely invisible, because of vscrolling, we
1490 don't have to draw anything. */
1491 if (row
->visible_height
<= 0)
1494 if (FRAME_X_LEFT_FRINGE_WIDTH (f
) != 0)
1496 /* Decide which bitmap to draw in the left fringe. */
1497 if (row
->overlay_arrow_p
)
1498 bitmap
= OVERLAY_ARROW_BITMAP
;
1499 else if (row
->truncated_on_left_p
)
1500 bitmap
= LEFT_TRUNCATION_BITMAP
;
1501 else if (MATRIX_ROW_CONTINUATION_LINE_P (row
))
1502 bitmap
= CONTINUATION_LINE_BITMAP
;
1503 else if (row
->indicate_empty_line_p
)
1504 bitmap
= ZV_LINE_BITMAP
;
1506 bitmap
= NO_FRINGE_BITMAP
;
1508 x_draw_fringe_bitmap (w
, row
, bitmap
, 1);
1511 if (FRAME_X_RIGHT_FRINGE_WIDTH (f
) != 0)
1513 /* Decide which bitmap to draw in the right fringe. */
1514 if (row
->truncated_on_right_p
)
1515 bitmap
= RIGHT_TRUNCATION_BITMAP
;
1516 else if (row
->continued_p
)
1517 bitmap
= CONTINUED_LINE_BITMAP
;
1518 else if (row
->indicate_empty_line_p
&& FRAME_X_LEFT_FRINGE_WIDTH (f
) == 0)
1519 bitmap
= ZV_LINE_BITMAP
;
1521 bitmap
= NO_FRINGE_BITMAP
;
1523 x_draw_fringe_bitmap (w
, row
, bitmap
, 0);
1528 /***********************************************************************
1530 ***********************************************************************/
1532 /* External interface to control of standout mode. Not used for X
1533 frames. Aborts when called. */
1536 XTreassert_line_highlight (new, vpos
)
1543 /* Call this when about to modify line at position VPOS and change
1544 whether it is highlighted. Not used for X frames. Aborts when
1548 x_change_line_highlight (new_highlight
, vpos
, y
, first_unused_hpos
)
1549 int new_highlight
, vpos
, y
, first_unused_hpos
;
1555 /* This is called when starting Emacs and when restarting after
1556 suspend. When starting Emacs, no X window is mapped. And nothing
1557 must be done to Emacs's own window if it is suspended (though that
1561 XTset_terminal_modes ()
1565 /* This is called when exiting or suspending Emacs. Exiting will make
1566 the X-windows go away, and suspending requires no action. */
1569 XTreset_terminal_modes ()
1575 /***********************************************************************
1577 ***********************************************************************/
1579 /* Set the global variable output_cursor to CURSOR. All cursor
1580 positions are relative to updated_window. */
1583 set_output_cursor (cursor
)
1584 struct cursor_pos
*cursor
;
1586 output_cursor
.hpos
= cursor
->hpos
;
1587 output_cursor
.vpos
= cursor
->vpos
;
1588 output_cursor
.x
= cursor
->x
;
1589 output_cursor
.y
= cursor
->y
;
1593 /* Set a nominal cursor position.
1595 HPOS and VPOS are column/row positions in a window glyph matrix. X
1596 and Y are window text area relative pixel positions.
1598 If this is done during an update, updated_window will contain the
1599 window that is being updated and the position is the future output
1600 cursor position for that window. If updated_window is null, use
1601 selected_window and display the cursor at the given position. */
1604 XTcursor_to (vpos
, hpos
, y
, x
)
1605 int vpos
, hpos
, y
, x
;
1609 /* If updated_window is not set, work on selected_window. */
1613 w
= XWINDOW (selected_window
);
1615 /* Set the output cursor. */
1616 output_cursor
.hpos
= hpos
;
1617 output_cursor
.vpos
= vpos
;
1618 output_cursor
.x
= x
;
1619 output_cursor
.y
= y
;
1621 /* If not called as part of an update, really display the cursor.
1622 This will also set the cursor position of W. */
1623 if (updated_window
== NULL
)
1626 x_display_cursor (w
, 1, hpos
, vpos
, x
, y
);
1627 XFlush (FRAME_X_DISPLAY (SELECTED_FRAME ()));
1634 /***********************************************************************
1636 ***********************************************************************/
1638 /* Function prototypes of this page. */
1640 static struct face
*x_get_glyph_face_and_encoding
P_ ((struct frame
*,
1644 static struct face
*x_get_char_face_and_encoding
P_ ((struct frame
*, int,
1645 int, XChar2b
*, int));
1646 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1647 static void x_encode_char
P_ ((int, XChar2b
*, struct font_info
*));
1648 static void x_append_glyph
P_ ((struct it
*));
1649 static void x_append_composite_glyph
P_ ((struct it
*));
1650 static void x_append_stretch_glyph
P_ ((struct it
*it
, Lisp_Object
,
1652 static void x_produce_glyphs
P_ ((struct it
*));
1653 static void x_produce_image_glyph
P_ ((struct it
*it
));
1656 /* Return a pointer to per-char metric information in FONT of a
1657 character pointed by B which is a pointer to an XChar2b. */
1659 #define PER_CHAR_METRIC(font, b) \
1661 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1662 + (((font)->min_byte1 || (font)->max_byte1) \
1663 ? (((b)->byte1 - (font)->min_byte1) \
1664 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1666 : &((font)->max_bounds))
1669 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1670 is not contained in the font. */
1672 static INLINE XCharStruct
*
1673 x_per_char_metric (font
, char2b
)
1677 /* The result metric information. */
1678 XCharStruct
*pcm
= NULL
;
1680 xassert (font
&& char2b
);
1682 if (font
->per_char
!= NULL
)
1684 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1686 /* min_char_or_byte2 specifies the linear character index
1687 corresponding to the first element of the per_char array,
1688 max_char_or_byte2 is the index of the last character. A
1689 character with non-zero CHAR2B->byte1 is not in the font.
1690 A character with byte2 less than min_char_or_byte2 or
1691 greater max_char_or_byte2 is not in the font. */
1692 if (char2b
->byte1
== 0
1693 && char2b
->byte2
>= font
->min_char_or_byte2
1694 && char2b
->byte2
<= font
->max_char_or_byte2
)
1695 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1699 /* If either min_byte1 or max_byte1 are nonzero, both
1700 min_char_or_byte2 and max_char_or_byte2 are less than
1701 256, and the 2-byte character index values corresponding
1702 to the per_char array element N (counting from 0) are:
1704 byte1 = N/D + min_byte1
1705 byte2 = N\D + min_char_or_byte2
1709 D = max_char_or_byte2 - min_char_or_byte2 + 1
1710 / = integer division
1711 \ = integer modulus */
1712 if (char2b
->byte1
>= font
->min_byte1
1713 && char2b
->byte1
<= font
->max_byte1
1714 && char2b
->byte2
>= font
->min_char_or_byte2
1715 && char2b
->byte2
<= font
->max_char_or_byte2
)
1717 pcm
= (font
->per_char
1718 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1719 * (char2b
->byte1
- font
->min_byte1
))
1720 + (char2b
->byte2
- font
->min_char_or_byte2
));
1726 /* If the per_char pointer is null, all glyphs between the first
1727 and last character indexes inclusive have the same
1728 information, as given by both min_bounds and max_bounds. */
1729 if (char2b
->byte2
>= font
->min_char_or_byte2
1730 && char2b
->byte2
<= font
->max_char_or_byte2
)
1731 pcm
= &font
->max_bounds
;
1734 return ((pcm
== NULL
1735 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1740 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1741 the two-byte form of C. Encoding is returned in *CHAR2B. */
1744 x_encode_char (c
, char2b
, font_info
)
1747 struct font_info
*font_info
;
1749 int charset
= CHAR_CHARSET (c
);
1750 XFontStruct
*font
= font_info
->font
;
1752 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1753 This may be either a program in a special encoder language or a
1755 if (font_info
->font_encoder
)
1757 /* It's a program. */
1758 struct ccl_program
*ccl
= font_info
->font_encoder
;
1760 if (CHARSET_DIMENSION (charset
) == 1)
1762 ccl
->reg
[0] = charset
;
1763 ccl
->reg
[1] = char2b
->byte2
;
1767 ccl
->reg
[0] = charset
;
1768 ccl
->reg
[1] = char2b
->byte1
;
1769 ccl
->reg
[2] = char2b
->byte2
;
1772 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1774 /* We assume that MSBs are appropriately set/reset by CCL
1776 if (font
->max_byte1
== 0) /* 1-byte font */
1777 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1779 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1781 else if (font_info
->encoding
[charset
])
1783 /* Fixed encoding scheme. See fontset.h for the meaning of the
1784 encoding numbers. */
1785 int enc
= font_info
->encoding
[charset
];
1787 if ((enc
== 1 || enc
== 2)
1788 && CHARSET_DIMENSION (charset
) == 2)
1789 char2b
->byte1
|= 0x80;
1791 if (enc
== 1 || enc
== 3)
1792 char2b
->byte2
|= 0x80;
1798 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1799 char2b
->byte1
= sjis1
;
1800 char2b
->byte2
= sjis2
;
1806 /* Get face and two-byte form of character C in face FACE_ID on frame
1807 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1808 means we want to display multibyte text. Value is a pointer to a
1809 realized face that is ready for display. */
1811 static INLINE
struct face
*
1812 x_get_char_face_and_encoding (f
, c
, face_id
, char2b
, multibyte_p
)
1818 struct face
*face
= FACE_FROM_ID (f
, face_id
);
1822 /* Unibyte case. We don't have to encode, but we have to make
1823 sure to use a face suitable for unibyte. */
1826 face_id
= FACE_FOR_CHAR (f
, face
, c
);
1827 face
= FACE_FROM_ID (f
, face_id
);
1829 else if (c
< 128 && face_id
< BASIC_FACE_ID_SENTINEL
)
1831 /* Case of ASCII in a face known to fit ASCII. */
1837 int c1
, c2
, charset
;
1839 /* Split characters into bytes. If c2 is -1 afterwards, C is
1840 really a one-byte character so that byte1 is zero. */
1841 SPLIT_CHAR (c
, charset
, c1
, c2
);
1843 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1845 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1847 /* Maybe encode the character in *CHAR2B. */
1848 if (face
->font
!= NULL
)
1850 struct font_info
*font_info
1851 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1853 x_encode_char (c
, char2b
, font_info
);
1857 /* Make sure X resources of the face are allocated. */
1858 xassert (face
!= NULL
);
1859 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1865 /* Get face and two-byte form of character glyph GLYPH on frame F.
1866 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1867 a pointer to a realized face that is ready for display. */
1869 static INLINE
struct face
*
1870 x_get_glyph_face_and_encoding (f
, glyph
, char2b
, two_byte_p
)
1872 struct glyph
*glyph
;
1878 xassert (glyph
->type
== CHAR_GLYPH
);
1879 face
= FACE_FROM_ID (f
, glyph
->face_id
);
1884 if (!glyph
->multibyte_p
)
1886 /* Unibyte case. We don't have to encode, but we have to make
1887 sure to use a face suitable for unibyte. */
1889 char2b
->byte2
= glyph
->u
.ch
;
1891 else if (glyph
->u
.ch
< 128
1892 && glyph
->face_id
< BASIC_FACE_ID_SENTINEL
)
1894 /* Case of ASCII in a face known to fit ASCII. */
1896 char2b
->byte2
= glyph
->u
.ch
;
1900 int c1
, c2
, charset
;
1902 /* Split characters into bytes. If c2 is -1 afterwards, C is
1903 really a one-byte character so that byte1 is zero. */
1904 SPLIT_CHAR (glyph
->u
.ch
, charset
, c1
, c2
);
1906 char2b
->byte1
= c1
, char2b
->byte2
= c2
;
1908 char2b
->byte1
= 0, char2b
->byte2
= c1
;
1910 /* Maybe encode the character in *CHAR2B. */
1911 if (charset
!= CHARSET_ASCII
)
1913 struct font_info
*font_info
1914 = FONT_INFO_FROM_ID (f
, face
->font_info_id
);
1917 x_encode_char (glyph
->u
.ch
, char2b
, font_info
);
1920 = ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1925 /* Make sure X resources of the face are allocated. */
1926 xassert (face
!= NULL
);
1927 PREPARE_FACE_FOR_DISPLAY (f
, face
);
1932 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1933 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1939 struct glyph
*glyph
;
1940 enum glyph_row_area area
= it
->area
;
1942 xassert (it
->glyph_row
);
1943 xassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
1945 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1946 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1948 glyph
->charpos
= CHARPOS (it
->position
);
1949 glyph
->object
= it
->object
;
1950 glyph
->pixel_width
= it
->pixel_width
;
1951 glyph
->voffset
= it
->voffset
;
1952 glyph
->type
= CHAR_GLYPH
;
1953 glyph
->multibyte_p
= it
->multibyte_p
;
1954 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1955 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1956 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1957 || it
->phys_descent
> it
->descent
);
1958 glyph
->padding_p
= 0;
1959 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
1960 glyph
->face_id
= it
->face_id
;
1961 glyph
->u
.ch
= it
->char_to_display
;
1962 ++it
->glyph_row
->used
[area
];
1966 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1967 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1970 x_append_composite_glyph (it
)
1973 struct glyph
*glyph
;
1974 enum glyph_row_area area
= it
->area
;
1976 xassert (it
->glyph_row
);
1978 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
1979 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
1981 glyph
->charpos
= CHARPOS (it
->position
);
1982 glyph
->object
= it
->object
;
1983 glyph
->pixel_width
= it
->pixel_width
;
1984 glyph
->voffset
= it
->voffset
;
1985 glyph
->type
= COMPOSITE_GLYPH
;
1986 glyph
->multibyte_p
= it
->multibyte_p
;
1987 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
1988 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
1989 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
1990 || it
->phys_descent
> it
->descent
);
1991 glyph
->padding_p
= 0;
1992 glyph
->glyph_not_available_p
= 0;
1993 glyph
->face_id
= it
->face_id
;
1994 glyph
->u
.cmp_id
= it
->cmp_id
;
1995 ++it
->glyph_row
->used
[area
];
2000 /* Change IT->ascent and IT->height according to the setting of
2004 take_vertical_position_into_account (it
)
2009 if (it
->voffset
< 0)
2010 /* Increase the ascent so that we can display the text higher
2012 it
->ascent
+= abs (it
->voffset
);
2014 /* Increase the descent so that we can display the text lower
2016 it
->descent
+= it
->voffset
;
2021 /* Produce glyphs/get display metrics for the image IT is loaded with.
2022 See the description of struct display_iterator in dispextern.h for
2023 an overview of struct display_iterator. */
2026 x_produce_image_glyph (it
)
2032 xassert (it
->what
== IT_IMAGE
);
2034 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2035 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
2038 /* Make sure X resources of the face and image are loaded. */
2039 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2040 prepare_image_for_display (it
->f
, img
);
2042 it
->ascent
= it
->phys_ascent
= image_ascent (img
, face
);
2043 it
->descent
= it
->phys_descent
= img
->height
+ 2 * img
->vmargin
- it
->ascent
;
2044 it
->pixel_width
= img
->width
+ 2 * img
->hmargin
;
2048 if (face
->box
!= FACE_NO_BOX
)
2050 it
->ascent
+= face
->box_line_width
;
2051 it
->descent
+= face
->box_line_width
;
2053 if (it
->start_of_box_run_p
)
2054 it
->pixel_width
+= face
->box_line_width
;
2055 if (it
->end_of_box_run_p
)
2056 it
->pixel_width
+= face
->box_line_width
;
2059 take_vertical_position_into_account (it
);
2063 struct glyph
*glyph
;
2064 enum glyph_row_area area
= it
->area
;
2066 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2067 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2069 glyph
->charpos
= CHARPOS (it
->position
);
2070 glyph
->object
= it
->object
;
2071 glyph
->pixel_width
= it
->pixel_width
;
2072 glyph
->voffset
= it
->voffset
;
2073 glyph
->type
= IMAGE_GLYPH
;
2074 glyph
->multibyte_p
= it
->multibyte_p
;
2075 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2076 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2077 glyph
->overlaps_vertically_p
= 0;
2078 glyph
->padding_p
= 0;
2079 glyph
->glyph_not_available_p
= 0;
2080 glyph
->face_id
= it
->face_id
;
2081 glyph
->u
.img_id
= img
->id
;
2082 ++it
->glyph_row
->used
[area
];
2088 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
2089 of the glyph, WIDTH and HEIGHT are the width and height of the
2090 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
2091 ascent of the glyph (0 <= ASCENT <= 1). */
2094 x_append_stretch_glyph (it
, object
, width
, height
, ascent
)
2100 struct glyph
*glyph
;
2101 enum glyph_row_area area
= it
->area
;
2103 xassert (ascent
>= 0 && ascent
<= 1);
2105 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
2106 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
2108 glyph
->charpos
= CHARPOS (it
->position
);
2109 glyph
->object
= object
;
2110 glyph
->pixel_width
= width
;
2111 glyph
->voffset
= it
->voffset
;
2112 glyph
->type
= STRETCH_GLYPH
;
2113 glyph
->multibyte_p
= it
->multibyte_p
;
2114 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
2115 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
2116 glyph
->overlaps_vertically_p
= 0;
2117 glyph
->padding_p
= 0;
2118 glyph
->glyph_not_available_p
= 0;
2119 glyph
->face_id
= it
->face_id
;
2120 glyph
->u
.stretch
.ascent
= height
* ascent
;
2121 glyph
->u
.stretch
.height
= height
;
2122 ++it
->glyph_row
->used
[area
];
2127 /* Produce a stretch glyph for iterator IT. IT->object is the value
2128 of the glyph property displayed. The value must be a list
2129 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
2132 1. `:width WIDTH' specifies that the space should be WIDTH *
2133 canonical char width wide. WIDTH may be an integer or floating
2136 2. `:relative-width FACTOR' specifies that the width of the stretch
2137 should be computed from the width of the first character having the
2138 `glyph' property, and should be FACTOR times that width.
2140 3. `:align-to HPOS' specifies that the space should be wide enough
2141 to reach HPOS, a value in canonical character units.
2143 Exactly one of the above pairs must be present.
2145 4. `:height HEIGHT' specifies that the height of the stretch produced
2146 should be HEIGHT, measured in canonical character units.
2148 5. `:relative-height FACTOR' specifies that the height of the stretch
2149 should be FACTOR times the height of the characters having the glyph
2152 Either none or exactly one of 4 or 5 must be present.
2154 6. `:ascent ASCENT' specifies that ASCENT percent of the height
2155 of the stretch should be used for the ascent of the stretch.
2156 ASCENT must be in the range 0 <= ASCENT <= 100. */
2159 ((INTEGERP (X) || FLOATP (X)) \
2165 x_produce_stretch_glyph (it
)
2168 /* (space :width WIDTH :height HEIGHT. */
2170 extern Lisp_Object Qspace
;
2172 extern Lisp_Object QCwidth
, QCheight
, QCascent
;
2173 extern Lisp_Object QCrelative_width
, QCrelative_height
;
2174 extern Lisp_Object QCalign_to
;
2175 Lisp_Object prop
, plist
;
2176 double width
= 0, height
= 0, ascent
= 0;
2177 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2178 XFontStruct
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
2180 PREPARE_FACE_FOR_DISPLAY (it
->f
, face
);
2182 /* List should start with `space'. */
2183 xassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
2184 plist
= XCDR (it
->object
);
2186 /* Compute the width of the stretch. */
2187 if (prop
= Fplist_get (plist
, QCwidth
),
2189 /* Absolute width `:width WIDTH' specified and valid. */
2190 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
);
2191 else if (prop
= Fplist_get (plist
, QCrelative_width
),
2194 /* Relative width `:relative-width FACTOR' specified and valid.
2195 Compute the width of the characters having the `glyph'
2198 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
2201 if (it
->multibyte_p
)
2203 int maxlen
= ((IT_BYTEPOS (*it
) >= GPT
? ZV
: GPT
)
2204 - IT_BYTEPOS (*it
));
2205 it2
.c
= STRING_CHAR_AND_LENGTH (p
, maxlen
, it2
.len
);
2208 it2
.c
= *p
, it2
.len
= 1;
2210 it2
.glyph_row
= NULL
;
2211 it2
.what
= IT_CHARACTER
;
2212 x_produce_glyphs (&it2
);
2213 width
= NUMVAL (prop
) * it2
.pixel_width
;
2215 else if (prop
= Fplist_get (plist
, QCalign_to
),
2217 width
= NUMVAL (prop
) * CANON_X_UNIT (it
->f
) - it
->current_x
;
2219 /* Nothing specified -> width defaults to canonical char width. */
2220 width
= CANON_X_UNIT (it
->f
);
2222 /* Compute height. */
2223 if (prop
= Fplist_get (plist
, QCheight
),
2225 height
= NUMVAL (prop
) * CANON_Y_UNIT (it
->f
);
2226 else if (prop
= Fplist_get (plist
, QCrelative_height
),
2228 height
= FONT_HEIGHT (font
) * NUMVAL (prop
);
2230 height
= FONT_HEIGHT (font
);
2232 /* Compute percentage of height used for ascent. If
2233 `:ascent ASCENT' is present and valid, use that. Otherwise,
2234 derive the ascent from the font in use. */
2235 if (prop
= Fplist_get (plist
, QCascent
),
2236 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
2237 ascent
= NUMVAL (prop
) / 100.0;
2239 ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
2248 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
2249 if (!STRINGP (object
))
2250 object
= it
->w
->buffer
;
2251 x_append_stretch_glyph (it
, object
, width
, height
, ascent
);
2254 it
->pixel_width
= width
;
2255 it
->ascent
= it
->phys_ascent
= height
* ascent
;
2256 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
2259 if (face
->box
!= FACE_NO_BOX
)
2261 it
->ascent
+= face
->box_line_width
;
2262 it
->descent
+= face
->box_line_width
;
2264 if (it
->start_of_box_run_p
)
2265 it
->pixel_width
+= face
->box_line_width
;
2266 if (it
->end_of_box_run_p
)
2267 it
->pixel_width
+= face
->box_line_width
;
2270 take_vertical_position_into_account (it
);
2273 /* Return proper value to be used as baseline offset of font that has
2274 ASCENT and DESCENT to draw characters by the font at the vertical
2275 center of the line of frame F.
2277 Here, out task is to find the value of BOFF in the following figure;
2279 -------------------------+-----------+-
2280 -+-+---------+-+ | |
2282 | | | | F_ASCENT F_HEIGHT
2285 | | |-|-+------+-----------|------- baseline
2287 | |---------|-+-+ | |
2289 -+-+---------+-+ F_DESCENT |
2290 -------------------------+-----------+-
2292 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
2293 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
2294 DESCENT = FONT->descent
2295 HEIGHT = FONT_HEIGHT (FONT)
2296 F_DESCENT = (F->output_data.x->font->descent
2297 - F->output_data.x->baseline_offset)
2298 F_HEIGHT = FRAME_LINE_HEIGHT (F)
2301 #define VCENTER_BASELINE_OFFSET(FONT, F) \
2303 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
2304 - ((F)->output_data.mac->font->descent - (F)->output_data.mac->baseline_offset))
2306 /* Produce glyphs/get display metrics for the display element IT is
2307 loaded with. See the description of struct display_iterator in
2308 dispextern.h for an overview of struct display_iterator. */
2311 x_produce_glyphs (it
)
2314 it
->glyph_not_available_p
= 0;
2316 if (it
->what
== IT_CHARACTER
)
2320 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2322 int font_not_found_p
;
2323 struct font_info
*font_info
;
2324 int boff
; /* baseline offset */
2326 /* Maybe translate single-byte characters to multibyte, or the
2328 it
->char_to_display
= it
->c
;
2329 if (!ASCII_BYTE_P (it
->c
))
2331 if (unibyte_display_via_language_environment
2332 && SINGLE_BYTE_CHAR_P (it
->c
)
2334 || !NILP (Vnonascii_translation_table
)))
2336 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2337 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2338 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2340 else if (!SINGLE_BYTE_CHAR_P (it
->c
)
2341 && !it
->multibyte_p
)
2343 it
->char_to_display
= multibyte_char_to_unibyte (it
->c
, Qnil
);
2344 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2345 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2349 /* Get font to use. Encode IT->char_to_display. */
2350 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2351 it
->face_id
, &char2b
,
2355 /* When no suitable font found, use the default font. */
2356 font_not_found_p
= font
== NULL
;
2357 if (font_not_found_p
)
2359 font
= FRAME_FONT (it
->f
);
2360 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2365 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2366 boff
= font_info
->baseline_offset
;
2367 if (font_info
->vertical_centering
)
2368 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2371 if (it
->char_to_display
>= ' '
2372 && (!it
->multibyte_p
|| it
->char_to_display
< 128))
2374 /* Either unibyte or ASCII. */
2379 pcm
= x_per_char_metric (font
, &char2b
);
2380 it
->ascent
= font
->ascent
+ boff
;
2381 it
->descent
= font
->descent
- boff
;
2385 it
->phys_ascent
= pcm
->ascent
+ boff
;
2386 it
->phys_descent
= pcm
->descent
- boff
;
2387 it
->pixel_width
= pcm
->width
;
2391 it
->glyph_not_available_p
= 1;
2392 it
->phys_ascent
= font
->ascent
+ boff
;
2393 it
->phys_descent
= font
->descent
- boff
;
2394 it
->pixel_width
= FONT_WIDTH (font
);
2397 /* If this is a space inside a region of text with
2398 `space-width' property, change its width. */
2399 stretched_p
= it
->char_to_display
== ' ' && !NILP (it
->space_width
);
2401 it
->pixel_width
*= XFLOATINT (it
->space_width
);
2403 /* If face has a box, add the box thickness to the character
2404 height. If character has a box line to the left and/or
2405 right, add the box line width to the character's width. */
2406 if (face
->box
!= FACE_NO_BOX
)
2408 int thick
= face
->box_line_width
;
2410 it
->ascent
+= thick
;
2411 it
->descent
+= thick
;
2413 if (it
->start_of_box_run_p
)
2414 it
->pixel_width
+= thick
;
2415 if (it
->end_of_box_run_p
)
2416 it
->pixel_width
+= thick
;
2419 /* If face has an overline, add the height of the overline
2420 (1 pixel) and a 1 pixel margin to the character height. */
2421 if (face
->overline_p
)
2424 take_vertical_position_into_account (it
);
2426 /* If we have to actually produce glyphs, do it. */
2431 /* Translate a space with a `space-width' property
2432 into a stretch glyph. */
2433 double ascent
= (double) font
->ascent
/ FONT_HEIGHT (font
);
2434 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2435 it
->ascent
+ it
->descent
, ascent
);
2438 x_append_glyph (it
);
2440 /* If characters with lbearing or rbearing are displayed
2441 in this line, record that fact in a flag of the
2442 glyph row. This is used to optimize X output code. */
2443 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
2444 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2447 else if (it
->char_to_display
== '\n')
2449 /* A newline has no width but we need the height of the line. */
2450 it
->pixel_width
= 0;
2452 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
2453 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
2455 if (face
->box
!= FACE_NO_BOX
)
2457 int thick
= face
->box_line_width
;
2458 it
->ascent
+= thick
;
2459 it
->descent
+= thick
;
2462 else if (it
->char_to_display
== '\t')
2464 int tab_width
= it
->tab_width
* CANON_X_UNIT (it
->f
);
2465 int x
= it
->current_x
+ it
->continuation_lines_width
;
2466 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
2468 it
->pixel_width
= next_tab_x
- x
;
2470 it
->ascent
= it
->phys_ascent
= font
->ascent
+ boff
;
2471 it
->descent
= it
->phys_descent
= font
->descent
- boff
;
2475 double ascent
= (double) it
->ascent
/ (it
->ascent
+ it
->descent
);
2476 x_append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
2477 it
->ascent
+ it
->descent
, ascent
);
2482 /* A multi-byte character. Assume that the display width of the
2483 character is the width of the character multiplied by the
2484 width of the font. */
2486 /* If we found a font, this font should give us the right
2487 metrics. If we didn't find a font, use the frame's
2488 default font and calculate the width of the character
2489 from the charset width; this is what old redisplay code
2491 pcm
= x_per_char_metric (font
, &char2b
);
2492 if (font_not_found_p
|| !pcm
)
2494 int charset
= CHAR_CHARSET (it
->char_to_display
);
2496 it
->glyph_not_available_p
= 1;
2497 it
->pixel_width
= (FONT_WIDTH (FRAME_FONT (it
->f
))
2498 * CHARSET_WIDTH (charset
));
2499 it
->phys_ascent
= font
->ascent
+ boff
;
2500 it
->phys_descent
= font
->descent
- boff
;
2504 it
->pixel_width
= pcm
->width
;
2505 it
->phys_ascent
= pcm
->ascent
+ boff
;
2506 it
->phys_descent
= pcm
->descent
- boff
;
2508 && (pcm
->lbearing
< 0
2509 || pcm
->rbearing
> pcm
->width
))
2510 it
->glyph_row
->contains_overlapping_glyphs_p
= 1;
2513 it
->ascent
= font
->ascent
+ boff
;
2514 it
->descent
= font
->descent
- boff
;
2515 if (face
->box
!= FACE_NO_BOX
)
2517 int thick
= face
->box_line_width
;
2518 it
->ascent
+= thick
;
2519 it
->descent
+= thick
;
2521 if (it
->start_of_box_run_p
)
2522 it
->pixel_width
+= thick
;
2523 if (it
->end_of_box_run_p
)
2524 it
->pixel_width
+= thick
;
2527 /* If face has an overline, add the height of the overline
2528 (1 pixel) and a 1 pixel margin to the character height. */
2529 if (face
->overline_p
)
2532 take_vertical_position_into_account (it
);
2535 x_append_glyph (it
);
2538 else if (it
->what
== IT_COMPOSITION
)
2540 /* Note: A composition is represented as one glyph in the
2541 glyph matrix. There are no padding glyphs. */
2544 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2546 int font_not_found_p
;
2547 struct font_info
*font_info
;
2548 int boff
; /* baseline offset */
2549 struct composition
*cmp
= composition_table
[it
->cmp_id
];
2551 /* Maybe translate single-byte characters to multibyte. */
2552 it
->char_to_display
= it
->c
;
2553 if (unibyte_display_via_language_environment
2554 && SINGLE_BYTE_CHAR_P (it
->c
)
2557 && !NILP (Vnonascii_translation_table
))))
2559 it
->char_to_display
= unibyte_char_to_multibyte (it
->c
);
2562 /* Get face and font to use. Encode IT->char_to_display. */
2563 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, it
->char_to_display
);
2564 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
2565 x_get_char_face_and_encoding (it
->f
, it
->char_to_display
,
2566 it
->face_id
, &char2b
, it
->multibyte_p
);
2569 /* When no suitable font found, use the default font. */
2570 font_not_found_p
= font
== NULL
;
2571 if (font_not_found_p
)
2573 font
= FRAME_FONT (it
->f
);
2574 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2579 font_info
= FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2580 boff
= font_info
->baseline_offset
;
2581 if (font_info
->vertical_centering
)
2582 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2585 /* There are no padding glyphs, so there is only one glyph to
2586 produce for the composition. Important is that pixel_width,
2587 ascent and descent are the values of what is drawn by
2588 draw_glyphs (i.e. the values of the overall glyphs composed). */
2591 /* If we have not yet calculated pixel size data of glyphs of
2592 the composition for the current face font, calculate them
2593 now. Theoretically, we have to check all fonts for the
2594 glyphs, but that requires much time and memory space. So,
2595 here we check only the font of the first glyph. This leads
2596 to incorrect display very rarely, and C-l (recenter) can
2597 correct the display anyway. */
2598 if (cmp
->font
!= (void *) font
)
2600 /* Ascent and descent of the font of the first character of
2601 this composition (adjusted by baseline offset). Ascent
2602 and descent of overall glyphs should not be less than
2603 them respectively. */
2604 int font_ascent
= font
->ascent
+ boff
;
2605 int font_descent
= font
->descent
- boff
;
2606 /* Bounding box of the overall glyphs. */
2607 int leftmost
, rightmost
, lowest
, highest
;
2608 int i
, width
, ascent
, descent
;
2610 cmp
->font
= (void *) font
;
2612 /* Initialize the bounding box. */
2613 pcm
= x_per_char_metric (font
, &char2b
);
2617 ascent
= pcm
->ascent
;
2618 descent
= pcm
->descent
;
2622 width
= FONT_WIDTH (font
);
2623 ascent
= font
->ascent
;
2624 descent
= font
->descent
;
2628 lowest
= - descent
+ boff
;
2629 highest
= ascent
+ boff
;
2633 && font_info
->default_ascent
2634 && CHAR_TABLE_P (Vuse_default_ascent
)
2635 && !NILP (Faref (Vuse_default_ascent
,
2636 make_number (it
->char_to_display
))))
2637 highest
= font_info
->default_ascent
+ boff
;
2639 /* Draw the first glyph at the normal position. It may be
2640 shifted to right later if some other glyphs are drawn at
2642 cmp
->offsets
[0] = 0;
2643 cmp
->offsets
[1] = boff
;
2645 /* Set cmp->offsets for the remaining glyphs. */
2646 for (i
= 1; i
< cmp
->glyph_len
; i
++)
2648 int left
, right
, btm
, top
;
2649 int ch
= COMPOSITION_GLYPH (cmp
, i
);
2650 int face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
);
2652 face
= FACE_FROM_ID (it
->f
, face_id
);
2653 x_get_char_face_and_encoding (it
->f
, ch
, face
->id
, &char2b
,
2658 font
= FRAME_FONT (it
->f
);
2659 boff
= it
->f
->output_data
.mac
->baseline_offset
;
2665 = FONT_INFO_FROM_ID (it
->f
, face
->font_info_id
);
2666 boff
= font_info
->baseline_offset
;
2667 if (font_info
->vertical_centering
)
2668 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
2671 pcm
= x_per_char_metric (font
, &char2b
);
2675 ascent
= pcm
->ascent
;
2676 descent
= pcm
->descent
;
2680 width
= FONT_WIDTH (font
);
2681 ascent
= font
->ascent
;
2682 descent
= font
->descent
;
2685 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
2687 /* Relative composition with or without
2689 left
= (leftmost
+ rightmost
- width
) / 2;
2690 btm
= - descent
+ boff
;
2691 if (font_info
&& font_info
->relative_compose
2692 && (! CHAR_TABLE_P (Vignore_relative_composition
)
2693 || NILP (Faref (Vignore_relative_composition
,
2694 make_number (ch
)))))
2697 if (- descent
>= font_info
->relative_compose
)
2698 /* One extra pixel between two glyphs. */
2700 else if (ascent
<= 0)
2701 /* One extra pixel between two glyphs. */
2702 btm
= lowest
- 1 - ascent
- descent
;
2707 /* A composition rule is specified by an integer
2708 value that encodes global and new reference
2709 points (GREF and NREF). GREF and NREF are
2710 specified by numbers as below:
2718 ---3---4---5--- baseline
2720 6---7---8 -- descent
2722 int rule
= COMPOSITION_RULE (cmp
, i
);
2723 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
;
2725 COMPOSITION_DECODE_RULE (rule
, gref
, nref
);
2726 grefx
= gref
% 3, nrefx
= nref
% 3;
2727 grefy
= gref
/ 3, nrefy
= nref
/ 3;
2730 + grefx
* (rightmost
- leftmost
) / 2
2731 - nrefx
* width
/ 2);
2732 btm
= ((grefy
== 0 ? highest
2734 : grefy
== 2 ? lowest
2735 : (highest
+ lowest
) / 2)
2736 - (nrefy
== 0 ? ascent
+ descent
2737 : nrefy
== 1 ? descent
- boff
2739 : (ascent
+ descent
) / 2));
2742 cmp
->offsets
[i
* 2] = left
;
2743 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
2745 /* Update the bounding box of the overall glyphs. */
2746 right
= left
+ width
;
2747 top
= btm
+ descent
+ ascent
;
2748 if (left
< leftmost
)
2750 if (right
> rightmost
)
2758 /* If there are glyphs whose x-offsets are negative,
2759 shift all glyphs to the right and make all x-offsets
2763 for (i
= 0; i
< cmp
->glyph_len
; i
++)
2764 cmp
->offsets
[i
* 2] -= leftmost
;
2765 rightmost
-= leftmost
;
2768 cmp
->pixel_width
= rightmost
;
2769 cmp
->ascent
= highest
;
2770 cmp
->descent
= - lowest
;
2771 if (cmp
->ascent
< font_ascent
)
2772 cmp
->ascent
= font_ascent
;
2773 if (cmp
->descent
< font_descent
)
2774 cmp
->descent
= font_descent
;
2777 it
->pixel_width
= cmp
->pixel_width
;
2778 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
2779 it
->descent
= it
->phys_descent
= cmp
->descent
;
2781 if (face
->box
!= FACE_NO_BOX
)
2783 int thick
= face
->box_line_width
;
2784 it
->ascent
+= thick
;
2785 it
->descent
+= thick
;
2787 if (it
->start_of_box_run_p
)
2788 it
->pixel_width
+= thick
;
2789 if (it
->end_of_box_run_p
)
2790 it
->pixel_width
+= thick
;
2793 /* If face has an overline, add the height of the overline
2794 (1 pixel) and a 1 pixel margin to the character height. */
2795 if (face
->overline_p
)
2798 take_vertical_position_into_account (it
);
2801 x_append_composite_glyph (it
);
2803 else if (it
->what
== IT_IMAGE
)
2804 x_produce_image_glyph (it
);
2805 else if (it
->what
== IT_STRETCH
)
2806 x_produce_stretch_glyph (it
);
2808 /* Accumulate dimensions. Note: can't assume that it->descent > 0
2809 because this isn't true for images with `:ascent 100'. */
2810 xassert (it
->ascent
>= 0 && it
->descent
>= 0);
2811 if (it
->area
== TEXT_AREA
)
2812 it
->current_x
+= it
->pixel_width
;
2814 it
->descent
+= it
->extra_line_spacing
;
2816 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
2817 it
->max_descent
= max (it
->max_descent
, it
->descent
);
2818 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
2819 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
2823 /* Estimate the pixel height of the mode or top line on frame F.
2824 FACE_ID specifies what line's height to estimate. */
2827 x_estimate_mode_line_height (f
, face_id
)
2829 enum face_id face_id
;
2833 /* This function is called so early when Emacs starts that the face
2834 cache and mode line face are not yet initialized. */
2835 if (FRAME_FACE_CACHE (f
))
2837 struct face
*face
= FACE_FROM_ID (f
, face_id
);
2839 height
= FONT_HEIGHT (face
->font
) + 2 * face
->box_line_width
;
2846 /***********************************************************************
2848 ***********************************************************************/
2850 /* A sequence of glyphs to be drawn in the same face.
2852 This data structure is not really completely X specific, so it
2853 could possibly, at least partially, be useful for other systems. It
2854 is currently not part of the external redisplay interface because
2855 it's not clear what other systems will need. */
2859 /* X-origin of the string. */
2862 /* Y-origin and y-position of the base line of this string. */
2865 /* The width of the string, not including a face extension. */
2868 /* The width of the string, including a face extension. */
2869 int background_width
;
2871 /* The height of this string. This is the height of the line this
2872 string is drawn in, and can be different from the height of the
2873 font the string is drawn in. */
2876 /* Number of pixels this string overwrites in front of its x-origin.
2877 This number is zero if the string has an lbearing >= 0; it is
2878 -lbearing, if the string has an lbearing < 0. */
2881 /* Number of pixels this string overwrites past its right-most
2882 nominal x-position, i.e. x + width. Zero if the string's
2883 rbearing is <= its nominal width, rbearing - width otherwise. */
2886 /* The frame on which the glyph string is drawn. */
2889 /* The window on which the glyph string is drawn. */
2892 /* X display and window for convenience. */
2896 /* The glyph row for which this string was built. It determines the
2897 y-origin and height of the string. */
2898 struct glyph_row
*row
;
2900 /* The area within row. */
2901 enum glyph_row_area area
;
2903 /* Characters to be drawn, and number of characters. */
2907 /* A face-override for drawing cursors, mouse face and similar. */
2908 enum draw_glyphs_face hl
;
2910 /* Face in which this string is to be drawn. */
2913 /* Font in which this string is to be drawn. */
2916 /* Font info for this string. */
2917 struct font_info
*font_info
;
2919 /* Non-null means this string describes (part of) a composition.
2920 All characters from char2b are drawn composed. */
2921 struct composition
*cmp
;
2923 /* Index of this glyph string's first character in the glyph
2924 definition of CMP. If this is zero, this glyph string describes
2925 the first character of a composition. */
2928 /* 1 means this glyph strings face has to be drawn to the right end
2929 of the window's drawing area. */
2930 unsigned extends_to_end_of_line_p
: 1;
2932 /* 1 means the background of this string has been drawn. */
2933 unsigned background_filled_p
: 1;
2935 /* 1 means glyph string must be drawn with 16-bit functions. */
2936 unsigned two_byte_p
: 1;
2938 /* 1 means that the original font determined for drawing this glyph
2939 string could not be loaded. The member `font' has been set to
2940 the frame's default font in this case. */
2941 unsigned font_not_found_p
: 1;
2943 /* 1 means that the face in which this glyph string is drawn has a
2945 unsigned stippled_p
: 1;
2947 /* 1 means only the foreground of this glyph string must be drawn,
2948 and we should use the physical height of the line this glyph
2949 string appears in as clip rect. */
2950 unsigned for_overlaps_p
: 1;
2952 /* The GC to use for drawing this glyph string. */
2955 /* A pointer to the first glyph in the string. This glyph
2956 corresponds to char2b[0]. Needed to draw rectangles if
2957 font_not_found_p is 1. */
2958 struct glyph
*first_glyph
;
2960 /* Image, if any. */
2963 struct glyph_string
*next
, *prev
;
2970 x_dump_glyph_string (s
)
2971 struct glyph_string
*s
;
2973 fprintf (stderr
, "glyph string\n");
2974 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
2975 s
->x
, s
->y
, s
->width
, s
->height
);
2976 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
2977 fprintf (stderr
, " hl = %d\n", s
->hl
);
2978 fprintf (stderr
, " left overhang = %d, right = %d\n",
2979 s
->left_overhang
, s
->right_overhang
);
2980 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
2981 fprintf (stderr
, " extends to end of line = %d\n",
2982 s
->extends_to_end_of_line_p
);
2983 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
2984 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
2987 #endif /* GLYPH_DEBUG */
2991 static void x_append_glyph_string_lists
P_ ((struct glyph_string
**,
2992 struct glyph_string
**,
2993 struct glyph_string
*,
2994 struct glyph_string
*));
2995 static void x_prepend_glyph_string_lists
P_ ((struct glyph_string
**,
2996 struct glyph_string
**,
2997 struct glyph_string
*,
2998 struct glyph_string
*));
2999 static void x_append_glyph_string
P_ ((struct glyph_string
**,
3000 struct glyph_string
**,
3001 struct glyph_string
*));
3002 static int x_left_overwritten
P_ ((struct glyph_string
*));
3003 static int x_left_overwriting
P_ ((struct glyph_string
*));
3004 static int x_right_overwritten
P_ ((struct glyph_string
*));
3005 static int x_right_overwriting
P_ ((struct glyph_string
*));
3006 static int x_fill_glyph_string
P_ ((struct glyph_string
*, int, int, int,
3008 static void x_init_glyph_string
P_ ((struct glyph_string
*,
3009 XChar2b
*, struct window
*,
3011 enum glyph_row_area
, int,
3012 enum draw_glyphs_face
));
3013 static int x_draw_glyphs
P_ ((struct window
*, int , struct glyph_row
*,
3014 enum glyph_row_area
, int, int,
3015 enum draw_glyphs_face
, int *, int *, int));
3016 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
3017 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
3018 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
3020 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
3021 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
3022 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
3023 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
3024 static void x_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
3025 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
3026 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
3027 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
3028 static void x_get_glyph_overhangs
P_ ((struct glyph
*, struct frame
*,
3030 static void x_compute_overhangs_and_x
P_ ((struct glyph_string
*, int, int));
3031 static int x_alloc_lighter_color
P_ ((struct frame
*, Display
*, Colormap
,
3032 unsigned long *, double, int));
3033 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
3034 double, int, unsigned long));
3035 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
3036 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
3037 static void x_draw_image_relief
P_ ((struct glyph_string
*));
3038 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
3039 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
3040 static void x_fill_image_glyph_string
P_ ((struct glyph_string
*));
3041 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
3043 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
3044 int, int, int, int, XRectangle
*));
3045 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
3046 int, int, int, XRectangle
*));
3047 static void x_fix_overlapping_area
P_ ((struct window
*, struct glyph_row
*,
3048 enum glyph_row_area
));
3049 static int x_fill_stretch_glyph_string
P_ ((struct glyph_string
*,
3051 enum glyph_row_area
, int, int));
3054 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
3058 /* Append the list of glyph strings with head H and tail T to the list
3059 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
3062 x_append_glyph_string_lists (head
, tail
, h
, t
)
3063 struct glyph_string
**head
, **tail
;
3064 struct glyph_string
*h
, *t
;
3078 /* Prepend the list of glyph strings with head H and tail T to the
3079 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
3083 x_prepend_glyph_string_lists (head
, tail
, h
, t
)
3084 struct glyph_string
**head
, **tail
;
3085 struct glyph_string
*h
, *t
;
3099 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
3100 Set *HEAD and *TAIL to the resulting list. */
3103 x_append_glyph_string (head
, tail
, s
)
3104 struct glyph_string
**head
, **tail
;
3105 struct glyph_string
*s
;
3107 s
->next
= s
->prev
= NULL
;
3108 x_append_glyph_string_lists (head
, tail
, s
, s
);
3112 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
3117 struct glyph_string
*s
;
3119 if (s
->font
== FRAME_FONT (s
->f
)
3120 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
3121 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
3123 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
3126 /* Cursor on non-default face: must merge. */
3130 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
3131 xgcv
.foreground
= s
->face
->background
;
3133 /* If the glyph would be invisible, try a different foreground. */
3134 if (xgcv
.foreground
== xgcv
.background
)
3135 xgcv
.foreground
= s
->face
->foreground
;
3136 if (xgcv
.foreground
== xgcv
.background
)
3137 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
3138 if (xgcv
.foreground
== xgcv
.background
)
3139 xgcv
.foreground
= s
->face
->foreground
;
3141 /* Make sure the cursor is distinct from text in this face. */
3142 if (xgcv
.background
== s
->face
->background
3143 && xgcv
.foreground
== s
->face
->foreground
)
3145 xgcv
.background
= s
->face
->foreground
;
3146 xgcv
.foreground
= s
->face
->background
;
3149 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3150 xgcv
.font
= s
->font
;
3151 mask
= GCForeground
| GCBackground
| GCFont
;
3153 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3154 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3157 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3158 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3160 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3165 /* Set up S->gc of glyph string S for drawing text in mouse face. */
3168 x_set_mouse_face_gc (s
)
3169 struct glyph_string
*s
;
3174 /* What face has to be used for the mouse face? */
3175 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
3176 face
= FACE_FROM_ID (s
->f
, face_id
);
3177 if (s
->first_glyph
->type
== CHAR_GLYPH
)
3178 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
3180 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
3181 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
3182 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3184 /* If font in this face is same as S->font, use it. */
3185 if (s
->font
== s
->face
->font
)
3186 s
->gc
= s
->face
->gc
;
3189 /* Otherwise construct scratch_cursor_gc with values from FACE
3194 xgcv
.background
= s
->face
->background
;
3195 xgcv
.foreground
= s
->face
->foreground
;
3196 IF_DEBUG (x_check_font (s
->f
, s
->font
));
3197 xgcv
.font
= s
->font
;
3198 mask
= GCForeground
| GCBackground
| GCFont
;
3200 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
3201 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
3204 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
3205 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
3207 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
3210 xassert (s
->gc
!= 0);
3214 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
3215 Faces to use in the mode line have already been computed when the
3216 matrix was built, so there isn't much to do, here. */
3219 x_set_mode_line_face_gc (s
)
3220 struct glyph_string
*s
;
3222 s
->gc
= s
->face
->gc
;
3226 /* Set S->gc of glyph string S for drawing that glyph string. Set
3227 S->stippled_p to a non-zero value if the face of S has a stipple
3231 x_set_glyph_string_gc (s
)
3232 struct glyph_string
*s
;
3234 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
3236 if (s
->hl
== DRAW_NORMAL_TEXT
)
3238 s
->gc
= s
->face
->gc
;
3239 s
->stippled_p
= s
->face
->stipple
!= 0;
3241 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
3243 x_set_mode_line_face_gc (s
);
3244 s
->stippled_p
= s
->face
->stipple
!= 0;
3246 else if (s
->hl
== DRAW_CURSOR
)
3248 x_set_cursor_gc (s
);
3251 else if (s
->hl
== DRAW_MOUSE_FACE
)
3253 x_set_mouse_face_gc (s
);
3254 s
->stippled_p
= s
->face
->stipple
!= 0;
3256 else if (s
->hl
== DRAW_IMAGE_RAISED
3257 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3259 s
->gc
= s
->face
->gc
;
3260 s
->stippled_p
= s
->face
->stipple
!= 0;
3264 s
->gc
= s
->face
->gc
;
3265 s
->stippled_p
= s
->face
->stipple
!= 0;
3268 /* GC must have been set. */
3269 xassert (s
->gc
!= 0);
3273 /* Return in *R the clipping rectangle for glyph string S. */
3276 x_get_glyph_string_clip_rect (s
, r
)
3277 struct glyph_string
*s
;
3280 int r_height
, r_width
;
3282 if (s
->row
->full_width_p
)
3284 /* Draw full-width. X coordinates are relative to S->w->left. */
3285 int canon_x
= CANON_X_UNIT (s
->f
);
3287 r
->left
= WINDOW_LEFT_MARGIN (s
->w
) * canon_x
;
3288 r_width
= XFASTINT (s
->w
->width
) * canon_x
;
3290 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s
->f
))
3292 int width
= FRAME_SCROLL_BAR_WIDTH (s
->f
) * canon_x
;
3293 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s
->f
))
3297 r
->left
+= FRAME_INTERNAL_BORDER_WIDTH (s
->f
);
3299 /* Unless displaying a mode or menu bar line, which are always
3300 fully visible, clip to the visible part of the row. */
3301 if (s
->w
->pseudo_window_p
)
3302 r_height
= s
->row
->visible_height
;
3304 r_height
= s
->height
;
3308 /* This is a text line that may be partially visible. */
3309 r
->left
= WINDOW_AREA_TO_FRAME_PIXEL_X (s
->w
, s
->area
, 0);
3310 r_width
= window_box_width (s
->w
, s
->area
);
3311 r_height
= s
->row
->visible_height
;
3314 /* Don't use S->y for clipping because it doesn't take partially
3315 visible lines into account. For example, it can be negative for
3316 partially visible lines at the top of a window. */
3317 if (!s
->row
->full_width_p
3318 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
3319 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3321 r
->top
= max (0, s
->row
->y
);
3323 /* If drawing a tool-bar window, draw it over the internal border
3324 at the top of the window. */
3325 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
3326 r
->top
-= s
->f
->output_data
.mac
->internal_border_width
;
3328 /* If S draws overlapping rows, it's sufficient to use the top and
3329 bottom of the window for clipping because this glyph string
3330 intentionally draws over other lines. */
3331 if (s
->for_overlaps_p
)
3333 r
->top
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s
->w
);
3334 r_height
= window_text_bottom_y (s
->w
) - r
->top
;
3337 r
->top
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
->top
);
3339 r
->bottom
= r
->top
+ r_height
;
3340 r
->right
= r
->left
+ r_width
;
3344 /* Set clipping for output of glyph string S. S may be part of a mode
3345 line or menu if we don't have X toolkit support. */
3348 x_set_glyph_string_clipping (s
)
3349 struct glyph_string
*s
;
3352 x_get_glyph_string_clip_rect (s
, &r
);
3353 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3357 /* Compute left and right overhang of glyph string S. If S is a glyph
3358 string for a composition, assume overhangs don't exist. */
3361 x_compute_glyph_string_overhangs (s
)
3362 struct glyph_string
*s
;
3365 && s
->first_glyph
->type
== CHAR_GLYPH
)
3368 int direction
, font_ascent
, font_descent
;
3369 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
3370 &font_ascent
, &font_descent
, &cs
);
3371 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
3372 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
3377 /* Compute overhangs and x-positions for glyph string S and its
3378 predecessors, or successors. X is the starting x-position for S.
3379 BACKWARD_P non-zero means process predecessors. */
3382 x_compute_overhangs_and_x (s
, x
, backward_p
)
3383 struct glyph_string
*s
;
3391 x_compute_glyph_string_overhangs (s
);
3401 x_compute_glyph_string_overhangs (s
);
3410 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3411 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3412 assumed to be zero. */
3415 x_get_glyph_overhangs (glyph
, f
, left
, right
)
3416 struct glyph
*glyph
;
3422 if (glyph
->type
== CHAR_GLYPH
)
3426 struct font_info
*font_info
;
3430 face
= x_get_glyph_face_and_encoding (f
, glyph
, &char2b
, NULL
);
3432 font_info
= FONT_INFO_FROM_ID (f
, face
->font_info_id
);
3434 && (pcm
= x_per_char_metric (font
, &char2b
)))
3436 if (pcm
->rbearing
> pcm
->width
)
3437 *right
= pcm
->rbearing
- pcm
->width
;
3438 if (pcm
->lbearing
< 0)
3439 *left
= -pcm
->lbearing
;
3445 /* Return the index of the first glyph preceding glyph string S that
3446 is overwritten by S because of S's left overhang. Value is -1
3447 if no glyphs are overwritten. */
3450 x_left_overwritten (s
)
3451 struct glyph_string
*s
;
3455 if (s
->left_overhang
)
3458 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3459 int first
= s
->first_glyph
- glyphs
;
3461 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
3462 x
-= glyphs
[i
].pixel_width
;
3473 /* Return the index of the first glyph preceding glyph string S that
3474 is overwriting S because of its right overhang. Value is -1 if no
3475 glyph in front of S overwrites S. */
3478 x_left_overwriting (s
)
3479 struct glyph_string
*s
;
3482 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3483 int first
= s
->first_glyph
- glyphs
;
3487 for (i
= first
- 1; i
>= 0; --i
)
3490 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3493 x
-= glyphs
[i
].pixel_width
;
3500 /* Return the index of the last glyph following glyph string S that is
3501 not overwritten by S because of S's right overhang. Value is -1 if
3502 no such glyph is found. */
3505 x_right_overwritten (s
)
3506 struct glyph_string
*s
;
3510 if (s
->right_overhang
)
3513 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3514 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3515 int end
= s
->row
->used
[s
->area
];
3517 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
3518 x
+= glyphs
[i
].pixel_width
;
3527 /* Return the index of the last glyph following glyph string S that
3528 overwrites S because of its left overhang. Value is negative
3529 if no such glyph is found. */
3532 x_right_overwriting (s
)
3533 struct glyph_string
*s
;
3536 int end
= s
->row
->used
[s
->area
];
3537 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
3538 int first
= (s
->first_glyph
- glyphs
) + (s
->cmp
? 1 : s
->nchars
);
3542 for (i
= first
; i
< end
; ++i
)
3545 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
3548 x
+= glyphs
[i
].pixel_width
;
3555 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3558 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
3559 struct glyph_string
*s
;
3564 xgcv
.foreground
= s
->gc
->background
;
3565 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
3569 /* Draw the background of glyph_string S. If S->background_filled_p
3570 is non-zero don't draw it. FORCE_P non-zero means draw the
3571 background even if it wouldn't be drawn normally. This is used
3572 when a string preceding S draws into the background of S, or S
3573 contains the first component of a composition. */
3576 x_draw_glyph_string_background (s
, force_p
)
3577 struct glyph_string
*s
;
3580 /* Nothing to do if background has already been drawn or if it
3581 shouldn't be drawn in the first place. */
3582 if (!s
->background_filled_p
)
3584 #if 0 /* MAC_TODO: stipple */
3587 /* Fill background with a stipple pattern. */
3588 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3589 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
3590 s
->y
+ s
->face
->box_line_width
,
3591 s
->background_width
,
3592 s
->height
- 2 * s
->face
->box_line_width
);
3593 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3594 s
->background_filled_p
= 1;
3598 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * s
->face
->box_line_width
3599 || s
->font_not_found_p
3600 || s
->extends_to_end_of_line_p
3603 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ s
->face
->box_line_width
,
3604 s
->background_width
,
3605 s
->height
- 2 * s
->face
->box_line_width
);
3606 s
->background_filled_p
= 1;
3612 /* Draw the foreground of glyph string S. */
3615 x_draw_glyph_string_foreground (s
)
3616 struct glyph_string
*s
;
3620 /* If first glyph of S has a left box line, start drawing the text
3621 of S to the right of that box line. */
3622 if (s
->face
->box
!= FACE_NO_BOX
3623 && s
->first_glyph
->left_box_line_p
)
3624 x
= s
->x
+ s
->face
->box_line_width
;
3628 /* Draw characters of S as rectangles if S's font could not be
3630 if (s
->font_not_found_p
)
3632 for (i
= 0; i
< s
->nchars
; ++i
)
3634 struct glyph
*g
= s
->first_glyph
+ i
;
3635 mac_draw_rectangle (s
->display
, s
->window
,
3636 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
3638 x
+= g
->pixel_width
;
3643 char *char1b
= (char *) s
->char2b
;
3644 int boff
= s
->font_info
->baseline_offset
;
3646 if (s
->font_info
->vertical_centering
)
3647 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
3649 /* If we can use 8-bit functions, condense S->char2b. */
3651 for (i
= 0; i
< s
->nchars
; ++i
)
3652 char1b
[i
] = s
->char2b
[i
].byte2
;
3654 /* Draw text with XDrawString if background has already been
3655 filled. Otherwise, use XDrawImageString. (Note that
3656 XDrawImageString is usually faster than XDrawString.) Always
3657 use XDrawImageString when drawing the cursor so that there is
3658 no chance that characters under a box cursor are invisible. */
3659 if (s
->for_overlaps_p
3660 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
3662 /* Draw characters with 16-bit or 8-bit functions. */
3664 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
3665 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3667 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
3668 s
->ybase
- boff
, char1b
, s
->nchars
);
3673 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
3674 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
3676 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
3677 s
->ybase
- boff
, char1b
, s
->nchars
);
3682 /* Draw the foreground of composite glyph string S. */
3685 x_draw_composite_glyph_string_foreground (s
)
3686 struct glyph_string
*s
;
3690 /* If first glyph of S has a left box line, start drawing the text
3691 of S to the right of that box line. */
3692 if (s
->face
->box
!= FACE_NO_BOX
3693 && s
->first_glyph
->left_box_line_p
)
3694 x
= s
->x
+ s
->face
->box_line_width
;
3698 /* S is a glyph string for a composition. S->gidx is the index of
3699 the first character drawn for glyphs of this composition.
3700 S->gidx == 0 means we are drawing the very first character of
3701 this composition. */
3703 /* Draw a rectangle for the composition if the font for the very
3704 first character of the composition could not be loaded. */
3705 if (s
->font_not_found_p
)
3708 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
3709 s
->width
- 1, s
->height
- 1);
3713 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
3714 XDrawString16 (s
->display
, s
->window
, s
->gc
,
3715 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
3716 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
3722 #ifdef USE_X_TOOLKIT
3724 static struct frame
*x_frame_of_widget
P_ ((Widget
));
3727 /* Return the frame on which widget WIDGET is used.. Abort if frame
3728 cannot be determined. */
3730 static struct frame
*
3731 x_frame_of_widget (widget
)
3734 struct x_display_info
*dpyinfo
;
3738 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
3740 /* Find the top-level shell of the widget. Note that this function
3741 can be called when the widget is not yet realized, so XtWindow
3742 (widget) == 0. That's the reason we can't simply use
3743 x_any_window_to_frame. */
3744 while (!XtIsTopLevelShell (widget
))
3745 widget
= XtParent (widget
);
3747 /* Look for a frame with that top-level widget. Allocate the color
3748 on that frame to get the right gamma correction value. */
3749 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
3750 if (GC_FRAMEP (XCAR (tail
))
3751 && (f
= XFRAME (XCAR (tail
)),
3752 (f
->output_data
.nothing
!= 1
3753 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
3754 && f
->output_data
.x
->widget
== widget
)
3761 /* Allocate the color COLOR->pixel on the screen and display of
3762 widget WIDGET in colormap CMAP. If an exact match cannot be
3763 allocated, try the nearest color available. Value is non-zero
3764 if successful. This is called from lwlib. */
3767 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
3772 struct frame
*f
= x_frame_of_widget (widget
);
3773 return x_alloc_nearest_color (f
, cmap
, color
);
3777 #endif /* USE_X_TOOLKIT */
3781 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
3782 CMAP. If an exact match can't be allocated, try the nearest color
3783 available. Value is non-zero if successful. Set *COLOR to the
3787 x_alloc_nearest_color (f
, cmap
, color
)
3792 Display
*display
= FRAME_X_DISPLAY (f
);
3793 Screen
*screen
= FRAME_X_SCREEN (f
);
3796 gamma_correct (f
, color
);
3797 rc
= XAllocColor (display
, cmap
, color
);
3800 /* If we got to this point, the colormap is full, so we're going
3801 to try to get the next closest color. The algorithm used is
3802 a least-squares matching, which is what X uses for closest
3803 color matching with StaticColor visuals. */
3805 unsigned long nearest_delta
= ~0;
3806 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
3807 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
3809 for (i
= 0; i
< ncells
; ++i
)
3811 XQueryColors (display
, cmap
, cells
, ncells
);
3813 for (nearest
= i
= 0; i
< ncells
; ++i
)
3815 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
3816 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
3817 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
3818 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
3820 if (delta
< nearest_delta
)
3823 nearest_delta
= delta
;
3827 color
->red
= cells
[nearest
].red
;
3828 color
->green
= cells
[nearest
].green
;
3829 color
->blue
= cells
[nearest
].blue
;
3830 rc
= XAllocColor (display
, cmap
, color
);
3833 #ifdef DEBUG_X_COLORS
3835 register_color (color
->pixel
);
3836 #endif /* DEBUG_X_COLORS */
3842 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3843 It's necessary to do this instead of just using PIXEL directly to
3844 get color reference counts right. */
3847 x_copy_color (f
, pixel
)
3849 unsigned long pixel
;
3853 color
.pixel
= pixel
;
3855 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3856 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3858 #ifdef DEBUG_X_COLORS
3859 register_color (pixel
);
3865 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3866 It's necessary to do this instead of just using PIXEL directly to
3867 get color reference counts right. */
3870 x_copy_dpy_color (dpy
, cmap
, pixel
)
3873 unsigned long pixel
;
3877 color
.pixel
= pixel
;
3879 XQueryColor (dpy
, cmap
, &color
);
3880 XAllocColor (dpy
, cmap
, &color
);
3882 #ifdef DEBUG_X_COLORS
3883 register_color (pixel
);
3890 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3891 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3892 If this produces the same color as COLOR, try a color where all RGB
3893 values have DELTA added. Return the allocated color in *COLOR.
3894 DISPLAY is the X display, CMAP is the colormap to operate on.
3895 Value is non-zero if successful. */
3898 mac_alloc_lighter_color (f
, color
, factor
, delta
)
3900 unsigned long *color
;
3906 /* Change RGB values by specified FACTOR. Avoid overflow! */
3907 xassert (factor
>= 0);
3908 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
3909 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
3910 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
3912 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
3913 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
3914 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
3916 /* MAC_TODO: Map to palette and retry with delta if same? */
3917 /* MAC_TODO: Free colors (if using palette)? */
3928 /* Set up the foreground color for drawing relief lines of glyph
3929 string S. RELIEF is a pointer to a struct relief containing the GC
3930 with which lines will be drawn. Use a color that is FACTOR or
3931 DELTA lighter or darker than the relief's background which is found
3932 in S->f->output_data.x->relief_background. If such a color cannot
3933 be allocated, use DEFAULT_PIXEL, instead. */
3936 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3938 struct relief
*relief
;
3941 unsigned long default_pixel
;
3944 struct mac_output
*di
= f
->output_data
.mac
;
3945 unsigned long mask
= GCForeground
;
3946 unsigned long pixel
;
3947 unsigned long background
= di
->relief_background
;
3948 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
3950 /* MAC_TODO: Free colors (if using palette)? */
3952 /* Allocate new color. */
3953 xgcv
.foreground
= default_pixel
;
3955 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3957 relief
->allocated_p
= 1;
3958 xgcv
.foreground
= relief
->pixel
= pixel
;
3961 if (relief
->gc
== 0)
3963 #if 0 /* MAC_TODO: stipple */
3964 xgcv
.stipple
= dpyinfo
->gray
;
3967 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
3970 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3974 /* Set up colors for the relief lines around glyph string S. */
3977 x_setup_relief_colors (s
)
3978 struct glyph_string
*s
;
3980 struct mac_output
*di
= s
->f
->output_data
.mac
;
3981 unsigned long color
;
3983 if (s
->face
->use_box_color_for_shadows_p
)
3984 color
= s
->face
->box_color
;
3989 /* Get the background color of the face. */
3990 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3991 color
= xgcv
.background
;
3994 if (di
->white_relief
.gc
== 0
3995 || color
!= di
->relief_background
)
3997 di
->relief_background
= color
;
3998 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3999 WHITE_PIX_DEFAULT (s
->f
));
4000 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
4001 BLACK_PIX_DEFAULT (s
->f
));
4006 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
4007 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
4008 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
4009 relief. LEFT_P non-zero means draw a relief on the left side of
4010 the rectangle. RIGHT_P non-zero means draw a relief on the right
4011 side of the rectangle. CLIP_RECT is the clipping rectangle to use
4015 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
4016 raised_p
, left_p
, right_p
, clip_rect
)
4018 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
4025 gc
= f
->output_data
.mac
->white_relief
.gc
;
4027 gc
= f
->output_data
.mac
->black_relief
.gc
;
4028 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4031 for (i
= 0; i
< width
; ++i
)
4032 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4033 left_x
+ i
* left_p
, top_y
+ i
,
4034 right_x
+ 1 - i
* right_p
, top_y
+ i
);
4038 for (i
= 0; i
< width
; ++i
)
4039 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4040 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
4042 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4044 gc
= f
->output_data
.mac
->black_relief
.gc
;
4046 gc
= f
->output_data
.mac
->white_relief
.gc
;
4047 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
4050 for (i
= 0; i
< width
; ++i
)
4051 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4052 left_x
+ i
* left_p
, bottom_y
- i
,
4053 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
4057 for (i
= 0; i
< width
; ++i
)
4058 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
4059 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
4061 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
4065 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
4066 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
4067 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
4068 left side of the rectangle. RIGHT_P non-zero means draw a line
4069 on the right side of the rectangle. CLIP_RECT is the clipping
4070 rectangle to use when drawing. */
4073 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4074 left_p
, right_p
, clip_rect
)
4075 struct glyph_string
*s
;
4076 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
4081 xgcv
.foreground
= s
->face
->box_color
;
4082 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
4085 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4086 left_x
, top_y
, right_x
- left_x
, width
);
4090 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4091 left_x
, top_y
, width
, bottom_y
- top_y
);
4094 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4095 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
4099 XFillRectangle (s
->display
, s
->window
, &xgcv
,
4100 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
4102 mac_reset_clipping (s
->display
, s
->window
);
4106 /* Draw a box around glyph string S. */
4109 x_draw_glyph_string_box (s
)
4110 struct glyph_string
*s
;
4112 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
4113 int left_p
, right_p
;
4114 struct glyph
*last_glyph
;
4117 last_x
= window_box_right (s
->w
, s
->area
);
4118 if (s
->row
->full_width_p
4119 && !s
->w
->pseudo_window_p
)
4121 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
4122 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
4123 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
4126 /* The glyph that may have a right box line. */
4127 last_glyph
= (s
->cmp
|| s
->img
4129 : s
->first_glyph
+ s
->nchars
- 1);
4131 width
= s
->face
->box_line_width
;
4132 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
4134 right_x
= ((s
->row
->full_width_p
4136 : min (last_x
, s
->x
+ s
->background_width
) - 1));
4138 bottom_y
= top_y
+ s
->height
- 1;
4140 left_p
= (s
->first_glyph
->left_box_line_p
4141 || (s
->hl
== DRAW_MOUSE_FACE
4143 || s
->prev
->hl
!= s
->hl
)));
4144 right_p
= (last_glyph
->right_box_line_p
4145 || (s
->hl
== DRAW_MOUSE_FACE
4147 || s
->next
->hl
!= s
->hl
)));
4149 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4151 if (s
->face
->box
== FACE_SIMPLE_BOX
)
4152 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
4153 left_p
, right_p
, &clip_rect
);
4156 x_setup_relief_colors (s
);
4157 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
4158 width
, raised_p
, left_p
, right_p
, &clip_rect
);
4163 /* Draw foreground of image glyph string S. */
4166 x_draw_image_foreground (s
)
4167 struct glyph_string
*s
;
4170 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4172 /* If first glyph of S has a left box line, start drawing it to the
4173 right of that line. */
4174 if (s
->face
->box
!= FACE_NO_BOX
4175 && s
->first_glyph
->left_box_line_p
)
4176 x
= s
->x
+ s
->face
->box_line_width
;
4180 /* If there is a margin around the image, adjust x- and y-position
4182 x
+= s
->img
->hmargin
;
4183 y
+= s
->img
->vmargin
;
4187 #if 0 /* MAC_TODO: image mask */
4190 /* We can't set both a clip mask and use XSetClipRectangles
4191 because the latter also sets a clip mask. We also can't
4192 trust on the shape extension to be available
4193 (XShapeCombineRegion). So, compute the rectangle to draw
4195 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4198 XRectangle clip_rect
, image_rect
, r
;
4200 xgcv
.clip_mask
= s
->img
->mask
;
4201 xgcv
.clip_x_origin
= x
;
4202 xgcv
.clip_y_origin
= y
;
4203 xgcv
.function
= GXcopy
;
4204 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4206 x_get_glyph_string_clip_rect (s
, &clip_rect
);
4209 image_rect
.width
= s
->img
->width
;
4210 image_rect
.height
= s
->img
->height
;
4211 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
4212 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4213 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
4218 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
4219 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4221 /* When the image has a mask, we can expect that at
4222 least part of a mouse highlight or a block cursor will
4223 be visible. If the image doesn't have a mask, make
4224 a block cursor visible by drawing a rectangle around
4225 the image. I believe it's looking better if we do
4226 nothing here for mouse-face. */
4227 if (s
->hl
== DRAW_CURSOR
)
4228 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4229 s
->img
->width
- 1, s
->img
->height
- 1);
4233 /* Draw a rectangle if image could not be loaded. */
4234 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
4235 s
->img
->width
- 1, s
->img
->height
- 1);
4239 /* Draw a relief around the image glyph string S. */
4242 x_draw_image_relief (s
)
4243 struct glyph_string
*s
;
4245 int x0
, y0
, x1
, y1
, thick
, raised_p
;
4248 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
4250 /* If first glyph of S has a left box line, start drawing it to the
4251 right of that line. */
4252 if (s
->face
->box
!= FACE_NO_BOX
4253 && s
->first_glyph
->left_box_line_p
)
4254 x
= s
->x
+ s
->face
->box_line_width
;
4258 /* If there is a margin around the image, adjust x- and y-position
4260 x
+= s
->img
->hmargin
;
4261 y
+= s
->img
->vmargin
;
4263 if (s
->hl
== DRAW_IMAGE_SUNKEN
4264 || s
->hl
== DRAW_IMAGE_RAISED
)
4266 thick
= tool_bar_button_relief
> 0 ? tool_bar_button_relief
: 3;
4267 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
4271 thick
= abs (s
->img
->relief
);
4272 raised_p
= s
->img
->relief
> 0;
4277 x1
= x
+ s
->img
->width
+ thick
- 1;
4278 y1
= y
+ s
->img
->height
+ thick
- 1;
4280 x_setup_relief_colors (s
);
4281 x_get_glyph_string_clip_rect (s
, &r
);
4282 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
4286 /* Draw the foreground of image glyph string S to PIXMAP. */
4289 x_draw_image_foreground_1 (s
, pixmap
)
4290 struct glyph_string
*s
;
4294 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
4296 /* If first glyph of S has a left box line, start drawing it to the
4297 right of that line. */
4298 if (s
->face
->box
!= FACE_NO_BOX
4299 && s
->first_glyph
->left_box_line_p
)
4300 x
= s
->face
->box_line_width
;
4304 /* If there is a margin around the image, adjust x- and y-position
4306 x
+= s
->img
->hmargin
;
4307 y
+= s
->img
->vmargin
;
4311 #if 0 /* MAC_TODO: image mask */
4314 /* We can't set both a clip mask and use XSetClipRectangles
4315 because the latter also sets a clip mask. We also can't
4316 trust on the shape extension to be available
4317 (XShapeCombineRegion). So, compute the rectangle to draw
4319 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
4323 xgcv
.clip_mask
= s
->img
->mask
;
4324 xgcv
.clip_x_origin
= x
;
4325 xgcv
.clip_y_origin
= y
;
4326 xgcv
.function
= GXcopy
;
4327 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
4329 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4330 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4331 XSetClipMask (s
->display
, s
->gc
, None
);
4336 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
4337 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
4339 /* When the image has a mask, we can expect that at
4340 least part of a mouse highlight or a block cursor will
4341 be visible. If the image doesn't have a mask, make
4342 a block cursor visible by drawing a rectangle around
4343 the image. I believe it's looking better if we do
4344 nothing here for mouse-face. */
4345 if (s
->hl
== DRAW_CURSOR
)
4346 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4347 s
->img
->width
- 1, s
->img
->height
- 1);
4351 /* Draw a rectangle if image could not be loaded. */
4352 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
4353 s
->img
->width
- 1, s
->img
->height
- 1);
4357 /* Draw part of the background of glyph string S. X, Y, W, and H
4358 give the rectangle to draw. */
4361 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
4362 struct glyph_string
*s
;
4365 #if 0 /* MAC_TODO: stipple */
4368 /* Fill background with a stipple pattern. */
4369 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4370 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
4371 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4375 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
4379 /* Draw image glyph string S.
4382 s->x +-------------------------
4385 | +-------------------------
4388 | | +-------------------
4394 x_draw_image_glyph_string (s
)
4395 struct glyph_string
*s
;
4398 int box_line_width
= s
->face
->box_line_width
;
4402 height
= s
->height
- 2 * box_line_width
;
4404 /* Fill background with face under the image. Do it only if row is
4405 taller than image or if image has a clip mask to reduce
4407 s
->stippled_p
= s
->face
->stipple
!= 0;
4408 if (height
> s
->img
->height
4411 #if 0 /* MAC_TODO: image mask */
4414 || s
->img
->pixmap
== 0
4415 || s
->width
!= s
->background_width
)
4417 if (box_line_width
&& s
->first_glyph
->left_box_line_p
)
4418 x
= s
->x
+ box_line_width
;
4422 y
= s
->y
+ box_line_width
;
4424 #if 0 /* MAC_TODO: image mask */
4427 /* Create a pixmap as large as the glyph string Fill it with
4428 the background color. Copy the image to it, using its
4429 mask. Copy the temporary pixmap to the display. */
4430 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
4431 int depth
= DefaultDepthOfScreen (screen
);
4433 /* Create a pixmap as large as the glyph string. */
4434 pixmap
= XCreatePixmap (s
->display
, s
->window
,
4435 s
->background_width
,
4438 /* Don't clip in the following because we're working on the
4440 XSetClipMask (s
->display
, s
->gc
, None
);
4442 /* Fill the pixmap with the background color/stipple. */
4445 /* Fill background with a stipple pattern. */
4446 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
4447 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4448 0, 0, s
->background_width
, s
->height
);
4449 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
4454 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
4456 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
4457 XFillRectangle (s
->display
, pixmap
, s
->gc
,
4458 0, 0, s
->background_width
, s
->height
);
4459 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4464 /* Implementation idea: Is it possible to construct a mask?
4465 We could look at the color at the margins of the image, and
4466 say that this color is probably the background color of the
4468 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
4470 s
->background_filled_p
= 1;
4473 /* Draw the foreground. */
4476 x_draw_image_foreground_1 (s
, pixmap
);
4477 x_set_glyph_string_clipping (s
);
4478 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
4479 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
4480 XFreePixmap (s
->display
, pixmap
);
4483 x_draw_image_foreground (s
);
4485 /* If we must draw a relief around the image, do it. */
4487 || s
->hl
== DRAW_IMAGE_RAISED
4488 || s
->hl
== DRAW_IMAGE_SUNKEN
)
4489 x_draw_image_relief (s
);
4493 /* Draw stretch glyph string S. */
4496 x_draw_stretch_glyph_string (s
)
4497 struct glyph_string
*s
;
4499 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4500 s
->stippled_p
= s
->face
->stipple
!= 0;
4502 if (s
->hl
== DRAW_CURSOR
4503 && !x_stretch_cursor_p
)
4505 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4506 as wide as the stretch glyph. */
4507 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
4510 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
4512 /* Clear rest using the GC of the original non-cursor face. */
4513 if (width
< s
->background_width
)
4515 GC gc
= s
->face
->gc
;
4516 int x
= s
->x
+ width
, y
= s
->y
;
4517 int w
= s
->background_width
- width
, h
= s
->height
;
4520 x_get_glyph_string_clip_rect (s
, &r
);
4521 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
4523 #if 0 /* MAC_TODO: stipple */
4524 if (s
->face
->stipple
)
4526 /* Fill background with a stipple pattern. */
4527 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
4528 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4529 XSetFillStyle (s
->display
, gc
, FillSolid
);
4535 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
4536 XSetForeground (s
->display
, gc
, xgcv
.background
);
4537 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
4538 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
4543 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
4546 s
->background_filled_p
= 1;
4550 /* Draw glyph string S. */
4553 x_draw_glyph_string (s
)
4554 struct glyph_string
*s
;
4556 /* If S draws into the background of its successor, draw the
4557 background of the successor first so that S can draw into it.
4558 This makes S->next use XDrawString instead of XDrawImageString. */
4559 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
4561 xassert (s
->next
->img
== NULL
);
4562 x_set_glyph_string_gc (s
->next
);
4563 x_set_glyph_string_clipping (s
->next
);
4564 x_draw_glyph_string_background (s
->next
, 1);
4567 /* Set up S->gc, set clipping and draw S. */
4568 x_set_glyph_string_gc (s
);
4569 x_set_glyph_string_clipping (s
);
4571 switch (s
->first_glyph
->type
)
4574 x_draw_image_glyph_string (s
);
4578 x_draw_stretch_glyph_string (s
);
4582 if (s
->for_overlaps_p
)
4583 s
->background_filled_p
= 1;
4585 x_draw_glyph_string_background (s
, 0);
4586 x_draw_glyph_string_foreground (s
);
4589 case COMPOSITE_GLYPH
:
4590 if (s
->for_overlaps_p
|| s
->gidx
> 0)
4591 s
->background_filled_p
= 1;
4593 x_draw_glyph_string_background (s
, 1);
4594 x_draw_composite_glyph_string_foreground (s
);
4601 if (!s
->for_overlaps_p
)
4603 /* Draw underline. */
4604 if (s
->face
->underline_p
)
4606 unsigned long h
= 1;
4607 unsigned long dy
= s
->height
- h
;
4609 if (s
->face
->underline_defaulted_p
)
4610 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4615 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4616 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
4617 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4619 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4623 /* Draw overline. */
4624 if (s
->face
->overline_p
)
4626 unsigned long dy
= 0, h
= 1;
4628 if (s
->face
->overline_color_defaulted_p
)
4629 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4634 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4635 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
4636 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4638 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4642 /* Draw strike-through. */
4643 if (s
->face
->strike_through_p
)
4645 unsigned long h
= 1;
4646 unsigned long dy
= (s
->height
- h
) / 2;
4648 if (s
->face
->strike_through_color_defaulted_p
)
4649 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4654 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
4655 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
4656 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
4658 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
4663 if (s
->face
->box
!= FACE_NO_BOX
)
4664 x_draw_glyph_string_box (s
);
4667 /* Reset clipping. */
4668 mac_reset_clipping (s
->display
, s
->window
);
4672 static int x_fill_composite_glyph_string
P_ ((struct glyph_string
*,
4673 struct face
**, int));
4676 /* Fill glyph string S with composition components specified by S->cmp.
4678 FACES is an array of faces for all components of this composition.
4679 S->gidx is the index of the first component for S.
4680 OVERLAPS_P non-zero means S should draw the foreground only, and
4681 use its physical height for clipping.
4683 Value is the index of a component not in S. */
4686 x_fill_composite_glyph_string (s
, faces
, overlaps_p
)
4687 struct glyph_string
*s
;
4688 struct face
**faces
;
4695 s
->for_overlaps_p
= overlaps_p
;
4697 s
->face
= faces
[s
->gidx
];
4698 s
->font
= s
->face
->font
;
4699 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4701 /* For all glyphs of this composition, starting at the offset
4702 S->gidx, until we reach the end of the definition or encounter a
4703 glyph that requires the different face, add it to S. */
4705 for (i
= s
->gidx
+ 1; i
< s
->cmp
->glyph_len
&& faces
[i
] == s
->face
; ++i
)
4708 /* All glyph strings for the same composition has the same width,
4709 i.e. the width set for the first component of the composition. */
4711 s
->width
= s
->first_glyph
->pixel_width
;
4713 /* If the specified font could not be loaded, use the frame's
4714 default font, but record the fact that we couldn't load it in
4715 the glyph string so that we can draw rectangles for the
4716 characters of the glyph string. */
4717 if (s
->font
== NULL
)
4719 s
->font_not_found_p
= 1;
4720 s
->font
= FRAME_FONT (s
->f
);
4723 /* Adjust base line for subscript/superscript text. */
4724 s
->ybase
+= s
->first_glyph
->voffset
;
4726 xassert (s
->face
&& s
->face
->gc
);
4728 /* This glyph string must always be drawn with 16-bit functions. */
4731 return s
->gidx
+ s
->nchars
;
4735 /* Fill glyph string S from a sequence of character glyphs.
4737 FACE_ID is the face id of the string. START is the index of the
4738 first glyph to consider, END is the index of the last + 1.
4739 OVERLAPS_P non-zero means S should draw the foreground only, and
4740 use its physical height for clipping.
4742 Value is the index of the first glyph not in S. */
4745 x_fill_glyph_string (s
, face_id
, start
, end
, overlaps_p
)
4746 struct glyph_string
*s
;
4748 int start
, end
, overlaps_p
;
4750 struct glyph
*glyph
, *last
;
4752 int glyph_not_available_p
;
4754 xassert (s
->f
== XFRAME (s
->w
->frame
));
4755 xassert (s
->nchars
== 0);
4756 xassert (start
>= 0 && end
> start
);
4758 s
->for_overlaps_p
= overlaps_p
,
4759 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4760 last
= s
->row
->glyphs
[s
->area
] + end
;
4761 voffset
= glyph
->voffset
;
4763 glyph_not_available_p
= glyph
->glyph_not_available_p
;
4766 && glyph
->type
== CHAR_GLYPH
4767 && glyph
->voffset
== voffset
4768 /* Same face id implies same font, nowadays. */
4769 && glyph
->face_id
== face_id
4770 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
4774 s
->face
= x_get_glyph_face_and_encoding (s
->f
, glyph
,
4775 s
->char2b
+ s
->nchars
,
4777 s
->two_byte_p
= two_byte_p
;
4779 xassert (s
->nchars
<= end
- start
);
4780 s
->width
+= glyph
->pixel_width
;
4784 s
->font
= s
->face
->font
;
4785 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4787 /* If the specified font could not be loaded, use the frame's font,
4788 but record the fact that we couldn't load it in
4789 S->font_not_found_p so that we can draw rectangles for the
4790 characters of the glyph string. */
4791 if (s
->font
== NULL
|| glyph_not_available_p
)
4793 s
->font_not_found_p
= 1;
4794 s
->font
= FRAME_FONT (s
->f
);
4797 /* Adjust base line for subscript/superscript text. */
4798 s
->ybase
+= voffset
;
4800 xassert (s
->face
&& s
->face
->gc
);
4801 return glyph
- s
->row
->glyphs
[s
->area
];
4805 /* Fill glyph string S from image glyph S->first_glyph. */
4808 x_fill_image_glyph_string (s
)
4809 struct glyph_string
*s
;
4811 xassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
4812 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
4814 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
4815 s
->font
= s
->face
->font
;
4816 s
->width
= s
->first_glyph
->pixel_width
;
4818 /* Adjust base line for subscript/superscript text. */
4819 s
->ybase
+= s
->first_glyph
->voffset
;
4823 /* Fill glyph string S from a sequence of stretch glyphs.
4825 ROW is the glyph row in which the glyphs are found, AREA is the
4826 area within the row. START is the index of the first glyph to
4827 consider, END is the index of the last + 1.
4829 Value is the index of the first glyph not in S. */
4832 x_fill_stretch_glyph_string (s
, row
, area
, start
, end
)
4833 struct glyph_string
*s
;
4834 struct glyph_row
*row
;
4835 enum glyph_row_area area
;
4838 struct glyph
*glyph
, *last
;
4839 int voffset
, face_id
;
4841 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
4843 glyph
= s
->row
->glyphs
[s
->area
] + start
;
4844 last
= s
->row
->glyphs
[s
->area
] + end
;
4845 face_id
= glyph
->face_id
;
4846 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
4847 s
->font
= s
->face
->font
;
4848 s
->font_info
= FONT_INFO_FROM_ID (s
->f
, s
->face
->font_info_id
);
4849 s
->width
= glyph
->pixel_width
;
4850 voffset
= glyph
->voffset
;
4854 && glyph
->type
== STRETCH_GLYPH
4855 && glyph
->voffset
== voffset
4856 && glyph
->face_id
== face_id
);
4858 s
->width
+= glyph
->pixel_width
;
4860 /* Adjust base line for subscript/superscript text. */
4861 s
->ybase
+= voffset
;
4863 xassert (s
->face
&& s
->face
->gc
);
4864 return glyph
- s
->row
->glyphs
[s
->area
];
4868 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4869 of XChar2b structures for S; it can't be allocated in
4870 x_init_glyph_string because it must be allocated via `alloca'. W
4871 is the window on which S is drawn. ROW and AREA are the glyph row
4872 and area within the row from which S is constructed. START is the
4873 index of the first glyph structure covered by S. HL is a
4874 face-override for drawing S. */
4877 x_init_glyph_string (s
, char2b
, w
, row
, area
, start
, hl
)
4878 struct glyph_string
*s
;
4881 struct glyph_row
*row
;
4882 enum glyph_row_area area
;
4884 enum draw_glyphs_face hl
;
4886 bzero (s
, sizeof *s
);
4888 s
->f
= XFRAME (w
->frame
);
4889 s
->display
= FRAME_MAC_DISPLAY (s
->f
);
4890 s
->window
= FRAME_MAC_WINDOW (s
->f
);
4895 s
->first_glyph
= row
->glyphs
[area
] + start
;
4896 s
->height
= row
->height
;
4897 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4899 /* Display the internal border below the tool-bar window. */
4900 if (s
->w
== XWINDOW (s
->f
->tool_bar_window
))
4901 s
->y
-= s
->f
->output_data
.mac
->internal_border_width
;
4903 s
->ybase
= s
->y
+ row
->ascent
;
4907 /* Set background width of glyph string S. START is the index of the
4908 first glyph following S. LAST_X is the right-most x-position + 1
4909 in the drawing area. */
4912 x_set_glyph_string_background_width (s
, start
, last_x
)
4913 struct glyph_string
*s
;
4917 /* If the face of this glyph string has to be drawn to the end of
4918 the drawing area, set S->extends_to_end_of_line_p. */
4919 struct face
*default_face
= FACE_FROM_ID (s
->f
, DEFAULT_FACE_ID
);
4921 if (start
== s
->row
->used
[s
->area
]
4922 && s
->hl
== DRAW_NORMAL_TEXT
4923 && ((s
->area
== TEXT_AREA
&& s
->row
->fill_line_p
)
4924 || s
->face
->background
!= default_face
->background
4925 || s
->face
->stipple
!= default_face
->stipple
))
4926 s
->extends_to_end_of_line_p
= 1;
4928 /* If S extends its face to the end of the line, set its
4929 background_width to the distance to the right edge of the drawing
4931 if (s
->extends_to_end_of_line_p
)
4932 s
->background_width
= last_x
- s
->x
+ 1;
4934 s
->background_width
= s
->width
;
4938 /* Add a glyph string for a stretch glyph to the list of strings
4939 between HEAD and TAIL. START is the index of the stretch glyph in
4940 row area AREA of glyph row ROW. END is the index of the last glyph
4941 in that glyph row area. X is the current output position assigned
4942 to the new glyph string constructed. HL overrides that face of the
4943 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4944 is the right-most x-position of the drawing area. */
4946 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
4947 and below -- keep them on one line. */
4948 #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4951 s = (struct glyph_string *) alloca (sizeof *s); \
4952 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4953 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4954 x_append_glyph_string (&HEAD, &TAIL, s); \
4960 /* Add a glyph string for an image glyph to the list of strings
4961 between HEAD and TAIL. START is the index of the image glyph in
4962 row area AREA of glyph row ROW. END is the index of the last glyph
4963 in that glyph row area. X is the current output position assigned
4964 to the new glyph string constructed. HL overrides that face of the
4965 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4966 is the right-most x-position of the drawing area. */
4968 #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4971 s = (struct glyph_string *) alloca (sizeof *s); \
4972 x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \
4973 x_fill_image_glyph_string (s); \
4974 x_append_glyph_string (&HEAD, &TAIL, s); \
4981 /* Add a glyph string for a sequence of character glyphs to the list
4982 of strings between HEAD and TAIL. START is the index of the first
4983 glyph in row area AREA of glyph row ROW that is part of the new
4984 glyph string. END is the index of the last glyph in that glyph row
4985 area. X is the current output position assigned to the new glyph
4986 string constructed. HL overrides that face of the glyph; e.g. it
4987 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4988 right-most x-position of the drawing area. */
4990 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4996 c = (ROW)->glyphs[AREA][START].u.ch; \
4997 face_id = (ROW)->glyphs[AREA][START].face_id; \
4999 s = (struct glyph_string *) alloca (sizeof *s); \
5000 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
5001 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
5002 x_append_glyph_string (&HEAD, &TAIL, s); \
5004 START = x_fill_glyph_string (s, face_id, START, END, \
5010 /* Add a glyph string for a composite sequence to the list of strings
5011 between HEAD and TAIL. START is the index of the first glyph in
5012 row area AREA of glyph row ROW that is part of the new glyph
5013 string. END is the index of the last glyph in that glyph row area.
5014 X is the current output position assigned to the new glyph string
5015 constructed. HL overrides that face of the glyph; e.g. it is
5016 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
5017 x-position of the drawing area. */
5019 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5021 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
5022 int face_id = (ROW)->glyphs[AREA][START].face_id; \
5023 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
5024 struct composition *cmp = composition_table[cmp_id]; \
5025 int glyph_len = cmp->glyph_len; \
5027 struct face **faces; \
5028 struct glyph_string *first_s = NULL; \
5031 base_face = base_face->ascii_face; \
5032 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
5033 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
5034 /* At first, fill in `char2b' and `faces'. */ \
5035 for (n = 0; n < glyph_len; n++) \
5037 int c = COMPOSITION_GLYPH (cmp, n); \
5038 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
5039 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
5040 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
5041 this_face_id, char2b + n, 1); \
5044 /* Make glyph_strings for each glyph sequence that is drawable by \
5045 the same face, and append them to HEAD/TAIL. */ \
5046 for (n = 0; n < cmp->glyph_len;) \
5048 s = (struct glyph_string *) alloca (sizeof *s); \
5049 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
5050 x_append_glyph_string (&(HEAD), &(TAIL), s); \
5058 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
5066 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
5067 of AREA of glyph row ROW on window W between indices START and END.
5068 HL overrides the face for drawing glyph strings, e.g. it is
5069 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
5070 x-positions of the drawing area.
5072 This is an ugly monster macro construct because we must use alloca
5073 to allocate glyph strings (because x_draw_glyphs can be called
5076 #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
5079 HEAD = TAIL = NULL; \
5080 while (START < END) \
5082 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
5083 switch (first_glyph->type) \
5086 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
5087 TAIL, HL, X, LAST_X, \
5091 case COMPOSITE_GLYPH: \
5092 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
5093 HEAD, TAIL, HL, X, LAST_X,\
5097 case STRETCH_GLYPH: \
5098 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
5099 HEAD, TAIL, HL, X, LAST_X); \
5103 BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \
5104 TAIL, HL, X, LAST_X); \
5111 x_set_glyph_string_background_width (s, START, LAST_X); \
5118 /* Draw glyphs between START and END in AREA of ROW on window W,
5119 starting at x-position X. X is relative to AREA in W. HL is a
5120 face-override with the following meaning:
5122 DRAW_NORMAL_TEXT draw normally
5123 DRAW_CURSOR draw in cursor face
5124 DRAW_MOUSE_FACE draw in mouse face.
5125 DRAW_INVERSE_VIDEO draw in mode line face
5126 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5127 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5129 If REAL_START is non-null, return in *REAL_START the real starting
5130 position for display. This can be different from START in case
5131 overlapping glyphs must be displayed. If REAL_END is non-null,
5132 return in *REAL_END the real end position for display. This can be
5133 different from END in case overlapping glyphs must be displayed.
5135 If OVERLAPS_P is non-zero, draw only the foreground of characters
5136 and clip to the physical height of ROW.
5138 Value is the x-position reached, relative to AREA of W. */
5141 x_draw_glyphs (w
, x
, row
, area
, start
, end
, hl
, real_start
, real_end
,
5145 struct glyph_row
*row
;
5146 enum glyph_row_area area
;
5148 enum draw_glyphs_face hl
;
5149 int *real_start
, *real_end
;
5152 struct glyph_string
*head
, *tail
;
5153 struct glyph_string
*s
;
5154 int last_x
, area_width
;
5158 /* Let's rather be paranoid than getting a SEGV. */
5159 start
= max (0, start
);
5160 end
= min (end
, row
->used
[area
]);
5162 *real_start
= start
;
5166 /* Translate X to frame coordinates. Set last_x to the right
5167 end of the drawing area. */
5168 if (row
->full_width_p
)
5170 /* X is relative to the left edge of W, without scroll bars
5172 struct frame
*f
= XFRAME (w
->frame
);
5173 int window_left_x
= WINDOW_LEFT_MARGIN (w
) * CANON_X_UNIT (f
);
5176 area_width
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5177 last_x
= window_left_x
+ area_width
;
5179 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
5181 int width
= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5182 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
5188 x
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
5189 last_x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
5193 x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, x
);
5194 area_width
= window_box_width (w
, area
);
5195 last_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, area
, area_width
);
5198 /* Build a doubly-linked list of glyph_string structures between
5199 head and tail from what we have to draw. Note that the macro
5200 BUILD_GLYPH_STRINGS will modify its start parameter. That's
5201 the reason we use a separate variable `i'. */
5203 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, end
, head
, tail
, hl
, x
, last_x
,
5206 x_reached
= tail
->x
+ tail
->background_width
;
5210 /* If there are any glyphs with lbearing < 0 or rbearing > width in
5211 the row, redraw some glyphs in front or following the glyph
5212 strings built above. */
5213 if (!overlaps_p
&& row
->contains_overlapping_glyphs_p
)
5216 struct glyph_string
*h
, *t
;
5218 /* Compute overhangs for all glyph strings. */
5219 for (s
= head
; s
; s
= s
->next
)
5220 x_compute_glyph_string_overhangs (s
);
5222 /* Prepend glyph strings for glyphs in front of the first glyph
5223 string that are overwritten because of the first glyph
5224 string's left overhang. The background of all strings
5225 prepended must be drawn because the first glyph string
5227 i
= x_left_overwritten (head
);
5231 BUILD_GLYPH_STRINGS (w
, row
, area
, j
, start
, h
, t
,
5232 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5236 *real_start
= start
;
5237 x_compute_overhangs_and_x (t
, head
->x
, 1);
5238 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5241 /* Prepend glyph strings for glyphs in front of the first glyph
5242 string that overwrite that glyph string because of their
5243 right overhang. For these strings, only the foreground must
5244 be drawn, because it draws over the glyph string at `head'.
5245 The background must not be drawn because this would overwrite
5246 right overhangs of preceding glyphs for which no glyph
5248 i
= x_left_overwriting (head
);
5251 BUILD_GLYPH_STRINGS (w
, row
, area
, i
, start
, h
, t
,
5252 DRAW_NORMAL_TEXT
, dummy_x
, last_x
,
5254 for (s
= h
; s
; s
= s
->next
)
5255 s
->background_filled_p
= 1;
5258 x_compute_overhangs_and_x (t
, head
->x
, 1);
5259 x_prepend_glyph_string_lists (&head
, &tail
, h
, t
);
5262 /* Append glyphs strings for glyphs following the last glyph
5263 string tail that are overwritten by tail. The background of
5264 these strings has to be drawn because tail's foreground draws
5266 i
= x_right_overwritten (tail
);
5269 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5270 DRAW_NORMAL_TEXT
, x
, last_x
,
5272 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5273 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5278 /* Append glyph strings for glyphs following the last glyph
5279 string tail that overwrite tail. The foreground of such
5280 glyphs has to be drawn because it writes into the background
5281 of tail. The background must not be drawn because it could
5282 paint over the foreground of following glyphs. */
5283 i
= x_right_overwriting (tail
);
5286 BUILD_GLYPH_STRINGS (w
, row
, area
, end
, i
, h
, t
,
5287 DRAW_NORMAL_TEXT
, x
, last_x
,
5289 for (s
= h
; s
; s
= s
->next
)
5290 s
->background_filled_p
= 1;
5291 x_compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, 0);
5292 x_append_glyph_string_lists (&head
, &tail
, h
, t
);
5298 /* Draw all strings. */
5299 for (s
= head
; s
; s
= s
->next
)
5300 x_draw_glyph_string (s
);
5302 /* Value is the x-position up to which drawn, relative to AREA of W.
5303 This doesn't include parts drawn because of overhangs. */
5304 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
5305 if (!row
->full_width_p
)
5307 if (area
> LEFT_MARGIN_AREA
)
5308 x_reached
-= window_box_width (w
, LEFT_MARGIN_AREA
);
5309 if (area
> TEXT_AREA
)
5310 x_reached
-= window_box_width (w
, TEXT_AREA
);
5316 /* Fix the display of area AREA of overlapping row ROW in window W. */
5319 x_fix_overlapping_area (w
, row
, area
)
5321 struct glyph_row
*row
;
5322 enum glyph_row_area area
;
5328 if (area
== LEFT_MARGIN_AREA
)
5330 else if (area
== TEXT_AREA
)
5331 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5333 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5334 + window_box_width (w
, TEXT_AREA
));
5336 for (i
= 0; i
< row
->used
[area
];)
5338 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
5340 int start
= i
, start_x
= x
;
5344 x
+= row
->glyphs
[area
][i
].pixel_width
;
5347 while (i
< row
->used
[area
]
5348 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
5350 x_draw_glyphs (w
, start_x
, row
, area
, start
, i
,
5352 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5357 x
+= row
->glyphs
[area
][i
].pixel_width
;
5366 /* Output LEN glyphs starting at START at the nominal cursor position.
5367 Advance the nominal cursor over the text. The global variable
5368 updated_window contains the window being updated, updated_row is
5369 the glyph row being updated, and updated_area is the area of that
5370 row being updated. */
5373 x_write_glyphs (start
, len
)
5374 struct glyph
*start
;
5377 int x
, hpos
, real_start
, real_end
;
5379 xassert (updated_window
&& updated_row
);
5384 hpos
= start
- updated_row
->glyphs
[updated_area
];
5385 x
= x_draw_glyphs (updated_window
, output_cursor
.x
,
5386 updated_row
, updated_area
,
5388 (updated_row
->inverse_p
5389 ? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
),
5390 &real_start
, &real_end
, 0);
5392 /* If we drew over the cursor, note that it is not visible any more. */
5393 note_overwritten_text_cursor (updated_window
, real_start
,
5394 real_end
- real_start
);
5398 /* Advance the output cursor. */
5399 output_cursor
.hpos
+= len
;
5400 output_cursor
.x
= x
;
5404 /* Insert LEN glyphs from START at the nominal cursor position. */
5407 x_insert_glyphs (start
, len
)
5408 struct glyph
*start
;
5413 int line_height
, shift_by_width
, shifted_region_width
;
5414 struct glyph_row
*row
;
5415 struct glyph
*glyph
;
5416 int frame_x
, frame_y
, hpos
, real_start
, real_end
;
5418 xassert (updated_window
&& updated_row
);
5421 f
= XFRAME (WINDOW_FRAME (w
));
5423 /* Get the height of the line we are in. */
5425 line_height
= row
->height
;
5427 /* Get the width of the glyphs to insert. */
5429 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
5430 shift_by_width
+= glyph
->pixel_width
;
5432 /* Get the width of the region to shift right. */
5433 shifted_region_width
= (window_box_width (w
, updated_area
)
5438 frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, output_cursor
.x
);
5439 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, output_cursor
.y
);
5441 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5442 f
->output_data
.mac
->normal_gc
,
5444 shifted_region_width
, line_height
,
5445 frame_x
+ shift_by_width
, frame_y
);
5447 /* Write the glyphs. */
5448 hpos
= start
- row
->glyphs
[updated_area
];
5449 x_draw_glyphs (w
, output_cursor
.x
, row
, updated_area
, hpos
, hpos
+ len
,
5450 DRAW_NORMAL_TEXT
, &real_start
, &real_end
, 0);
5451 note_overwritten_text_cursor (w
, real_start
, real_end
- real_start
);
5453 /* Advance the output cursor. */
5454 output_cursor
.hpos
+= len
;
5455 output_cursor
.x
+= shift_by_width
;
5460 /* Delete N glyphs at the nominal cursor position. Not implemented
5471 /* Erase the current text line from the nominal cursor position
5472 (inclusive) to pixel column TO_X (exclusive). The idea is that
5473 everything from TO_X onward is already erased.
5475 TO_X is a pixel position relative to updated_area of
5476 updated_window. TO_X == -1 means clear to the end of this area. */
5479 x_clear_end_of_line (to_x
)
5483 struct window
*w
= updated_window
;
5484 int max_x
, min_y
, max_y
;
5485 int from_x
, from_y
, to_y
;
5487 xassert (updated_window
&& updated_row
);
5488 f
= XFRAME (w
->frame
);
5490 if (updated_row
->full_width_p
)
5492 max_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
);
5493 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
5494 && !w
->pseudo_window_p
)
5495 max_x
+= FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
);
5498 max_x
= window_box_width (w
, updated_area
);
5499 max_y
= window_text_bottom_y (w
);
5501 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5502 of window. For TO_X > 0, truncate to end of drawing area. */
5508 to_x
= min (to_x
, max_x
);
5510 to_y
= min (max_y
, output_cursor
.y
+ updated_row
->height
);
5512 /* Notice if the cursor will be cleared by this operation. */
5513 if (!updated_row
->full_width_p
)
5514 note_overwritten_text_cursor (w
, output_cursor
.hpos
, -1);
5516 from_x
= output_cursor
.x
;
5518 /* Translate to frame coordinates. */
5519 if (updated_row
->full_width_p
)
5521 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
5522 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
5526 from_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, from_x
);
5527 to_x
= WINDOW_AREA_TO_FRAME_PIXEL_X (w
, updated_area
, to_x
);
5530 min_y
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
5531 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, output_cursor
.y
));
5532 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
5534 /* Prevent inadvertently clearing to end of the X window. */
5535 if (to_x
> from_x
&& to_y
> from_y
)
5538 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5539 from_x
, from_y
, to_x
- from_x
, to_y
- from_y
,
5546 /* Clear entire frame. If updating_frame is non-null, clear that
5547 frame. Otherwise clear the selected frame. */
5557 f
= SELECTED_FRAME ();
5559 /* Clearing the frame will erase any cursor, so mark them all as no
5561 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5562 output_cursor
.hpos
= output_cursor
.vpos
= 0;
5563 output_cursor
.x
= -1;
5565 /* We don't set the output cursor here because there will always
5566 follow an explicit cursor_to. */
5568 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
5570 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
5571 /* We have to clear the scroll bars, too. If we have changed
5572 colors or something like that, then they should be notified. */
5573 x_scroll_bar_clear (f
);
5576 XFlush (FRAME_MAC_DISPLAY (f
));
5582 /* Invert the middle quarter of the frame for .15 sec. */
5584 /* We use the select system call to do the waiting, so we have to make
5585 sure it's available. If it isn't, we just won't do visual bells. */
5587 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5589 /* Subtract the `struct timeval' values X and Y, storing the result in
5590 *RESULT. Return 1 if the difference is negative, otherwise 0. */
5593 timeval_subtract (result
, x
, y
)
5594 struct timeval
*result
, x
, y
;
5596 /* Perform the carry for the later subtraction by updating y. This
5597 is safer because on some systems the tv_sec member is unsigned. */
5598 if (x
.tv_usec
< y
.tv_usec
)
5600 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
5601 y
.tv_usec
-= 1000000 * nsec
;
5605 if (x
.tv_usec
- y
.tv_usec
> 1000000)
5607 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
5608 y
.tv_usec
+= 1000000 * nsec
;
5612 /* Compute the time remaining to wait. tv_usec is certainly
5614 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
5615 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
5617 /* Return indication of whether the result should be considered
5619 return x
.tv_sec
< y
.tv_sec
;
5631 struct timeval wakeup
;
5633 EMACS_GET_TIME (wakeup
);
5635 /* Compute time to wait until, propagating carry from usecs. */
5636 wakeup
.tv_usec
+= 150000;
5637 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
5638 wakeup
.tv_usec
%= 1000000;
5640 /* Keep waiting until past the time wakeup. */
5643 struct timeval timeout
;
5645 EMACS_GET_TIME (timeout
);
5647 /* In effect, timeout = wakeup - timeout.
5648 Break if result would be negative. */
5649 if (timeval_subtract (&timeout
, wakeup
, timeout
))
5652 /* Try to wait that long--but we might wake up sooner. */
5653 select (0, NULL
, NULL
, NULL
, &timeout
);
5662 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
5665 /* Make audible bell. */
5670 struct frame
*f
= SELECTED_FRAME ();
5672 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
5680 XFlush (FRAME_MAC_DISPLAY (f
));
5687 /* Specify how many text lines, from the top of the window,
5688 should be affected by insert-lines and delete-lines operations.
5689 This, and those operations, are used only within an update
5690 that is bounded by calls to x_update_begin and x_update_end. */
5693 XTset_terminal_window (n
)
5696 /* This function intentionally left blank. */
5701 /***********************************************************************
5703 ***********************************************************************/
5705 /* Perform an insert-lines or delete-lines operation, inserting N
5706 lines or deleting -N lines at vertical position VPOS. */
5709 x_ins_del_lines (vpos
, n
)
5716 /* Scroll part of the display as described by RUN. */
5719 x_scroll_run (w
, run
)
5723 struct frame
*f
= XFRAME (w
->frame
);
5724 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
5726 /* Get frame-relative bounding box of the text display area of W,
5727 without mode lines. Include in this box the left and right
5729 window_box (w
, -1, &x
, &y
, &width
, &height
);
5730 width
+= FRAME_X_FRINGE_WIDTH (f
);
5731 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
5733 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
5734 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
5735 bottom_y
= y
+ height
;
5739 /* Scrolling up. Make sure we don't copy part of the mode
5740 line at the bottom. */
5741 if (from_y
+ run
->height
> bottom_y
)
5742 height
= bottom_y
- from_y
;
5744 height
= run
->height
;
5748 /* Scolling down. Make sure we don't copy over the mode line.
5750 if (to_y
+ run
->height
> bottom_y
)
5751 height
= bottom_y
- to_y
;
5753 height
= run
->height
;
5758 /* Cursor off. Will be switched on again in x_update_window_end. */
5762 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5763 f
->output_data
.mac
->normal_gc
,
5773 /***********************************************************************
5775 ***********************************************************************/
5777 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5778 corner of the exposed rectangle. W and H are width and height of
5779 the exposed area. All are pixel values. W or H zero means redraw
5780 the entire frame. */
5783 expose_frame (f
, x
, y
, w
, h
)
5789 TRACE ((stderr
, "expose_frame "));
5791 /* No need to redraw if frame will be redrawn soon. */
5792 if (FRAME_GARBAGED_P (f
))
5794 TRACE ((stderr
, " garbaged\n"));
5798 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
5799 or deactivated here, for unknown reasons, activated scroll bars
5800 are shown in deactivated frames in some instances. */
5801 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
5802 activate_scroll_bars (f
);
5804 deactivate_scroll_bars (f
);
5806 /* If basic faces haven't been realized yet, there is no point in
5807 trying to redraw anything. This can happen when we get an expose
5808 event while Emacs is starting, e.g. by moving another window. */
5809 if (FRAME_FACE_CACHE (f
) == NULL
5810 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
5812 TRACE ((stderr
, " no faces\n"));
5816 if (w
== 0 || h
== 0)
5819 r
.right
= CANON_X_UNIT (f
) * f
->width
;
5820 r
.bottom
= CANON_Y_UNIT (f
) * f
->height
;
5830 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.left
, r
.top
, r
.right
, r
.bottom
));
5831 expose_window_tree (XWINDOW (f
->root_window
), &r
);
5833 if (WINDOWP (f
->tool_bar_window
))
5835 struct window
*w
= XWINDOW (f
->tool_bar_window
);
5837 Rect intersection_rect
;
5838 int window_x
, window_y
, window_width
, window_height
;
5841 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5842 window_rect
.left
= window_x
;
5843 window_rect
.top
= window_y
;
5844 window_rect
.right
= window_x
+ window_width
;
5845 window_rect
.bottom
= window_y
+ window_height
;
5847 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5848 expose_window (w
, &intersection_rect
);
5851 #ifndef USE_X_TOOLKIT
5852 if (WINDOWP (f
->menu_bar_window
))
5854 struct window
*w
= XWINDOW (f
->menu_bar_window
);
5856 Rect intersection_rect
;
5857 int window_x
, window_y
, window_width
, window_height
;
5860 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
5861 window_rect
.left
= window_x
;
5862 window_rect
.top
= window_y
;
5863 window_rect
.right
= window_x
+ window_width
;
5864 window_rect
.bottom
= window_y
+ window_height
;
5866 if (x_intersect_rectangles (&r
, &window_rect
, &intersection_rect
))
5867 expose_window (w
, &intersection_rect
);
5869 #endif /* not USE_X_TOOLKIT */
5873 /* Redraw (parts) of all windows in the window tree rooted at W that
5874 intersect R. R contains frame pixel coordinates. */
5877 expose_window_tree (w
, r
)
5883 if (!NILP (w
->hchild
))
5884 expose_window_tree (XWINDOW (w
->hchild
), r
);
5885 else if (!NILP (w
->vchild
))
5886 expose_window_tree (XWINDOW (w
->vchild
), r
);
5890 Rect intersection_rect
;
5891 struct frame
*f
= XFRAME (w
->frame
);
5892 int window_x
, window_y
, window_width
, window_height
;
5894 /* Frame-relative pixel rectangle of W. */
5895 window_box (w
, -1, &window_x
, &window_y
, &window_width
,
5899 - FRAME_X_LEFT_FRINGE_WIDTH (f
)
5900 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_Y_UNIT (f
));
5901 window_rect
.top
= window_y
;
5902 window_rect
.right
= window_rect
.left
5904 + FRAME_X_FRINGE_WIDTH (f
)
5905 + FRAME_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
));
5906 window_rect
.bottom
= window_rect
.top
5907 + window_height
+ CURRENT_MODE_LINE_HEIGHT (w
);
5909 if (x_intersect_rectangles (r
, &window_rect
, &intersection_rect
))
5910 expose_window (w
, &intersection_rect
);
5913 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5918 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5919 which intersects rectangle R. R is in window-relative coordinates. */
5922 expose_area (w
, row
, r
, area
)
5924 struct glyph_row
*row
;
5926 enum glyph_row_area area
;
5929 struct glyph
*first
= row
->glyphs
[area
];
5930 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
5934 /* Set x to the window-relative start position for drawing glyphs of
5935 AREA. The first glyph of the text area can be partially visible.
5936 The first glyphs of other areas cannot. */
5937 if (area
== LEFT_MARGIN_AREA
)
5939 else if (area
== TEXT_AREA
)
5940 x
= row
->x
+ window_box_width (w
, LEFT_MARGIN_AREA
);
5942 x
= (window_box_width (w
, LEFT_MARGIN_AREA
)
5943 + window_box_width (w
, TEXT_AREA
));
5945 if (area
== TEXT_AREA
&& row
->fill_line_p
)
5946 /* If row extends face to end of line write the whole line. */
5947 x_draw_glyphs (w
, x
, row
, area
,
5949 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5953 /* Find the first glyph that must be redrawn. */
5955 && x
+ first
->pixel_width
< r
->left
)
5957 x
+= first
->pixel_width
;
5961 /* Find the last one. */
5967 x
+= last
->pixel_width
;
5973 x_draw_glyphs (w
, first_x
, row
, area
,
5974 first
- row
->glyphs
[area
],
5975 last
- row
->glyphs
[area
],
5976 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5982 /* Redraw the parts of the glyph row ROW on window W intersecting
5983 rectangle R. R is in window-relative coordinates. */
5986 expose_line (w
, row
, r
)
5988 struct glyph_row
*row
;
5991 xassert (row
->enabled_p
);
5993 if (row
->mode_line_p
|| w
->pseudo_window_p
)
5994 x_draw_glyphs (w
, 0, row
, TEXT_AREA
, 0, row
->used
[TEXT_AREA
],
5995 row
->inverse_p
? DRAW_INVERSE_VIDEO
: DRAW_NORMAL_TEXT
,
5999 if (row
->used
[LEFT_MARGIN_AREA
])
6000 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
6001 if (row
->used
[TEXT_AREA
])
6002 expose_area (w
, row
, r
, TEXT_AREA
);
6003 if (row
->used
[RIGHT_MARGIN_AREA
])
6004 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
6005 x_draw_row_fringe_bitmaps (w
, row
);
6010 /* Return non-zero if W's cursor intersects rectangle R. */
6013 x_phys_cursor_in_rect_p (w
, r
)
6018 struct glyph
*cursor_glyph
;
6020 cursor_glyph
= get_phys_cursor_glyph (w
);
6023 cr
.left
= w
->phys_cursor
.x
;
6024 cr
.top
= w
->phys_cursor
.y
;
6025 cr
.right
= cr
.left
+ cursor_glyph
->pixel_width
;
6026 cr
.bottom
= cr
.top
+ w
->phys_cursor_height
;
6027 return x_intersect_rectangles (&cr
, r
, &result
);
6034 /* Redraw a rectangle of window W. R is a rectangle in window
6035 relative coordinates. Call this function with input blocked. */
6038 expose_window (w
, r
)
6042 struct glyph_row
*row
;
6044 int yb
= window_text_bottom_y (w
);
6045 int cursor_cleared_p
;
6047 /* If window is not yet fully initialized, do nothing. This can
6048 happen when toolkit scroll bars are used and a window is split.
6049 Reconfiguring the scroll bar will generate an expose for a newly
6051 if (w
->current_matrix
== NULL
)
6054 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
6055 r
->left
, r
->top
, r
->right
, r
->bottom
));
6057 /* Convert to window coordinates. */
6058 r
->left
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->left
);
6059 r
->top
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->top
);
6060 r
->right
= FRAME_TO_WINDOW_PIXEL_X (w
, r
->right
);
6061 r
->bottom
= FRAME_TO_WINDOW_PIXEL_Y (w
, r
->bottom
);
6063 /* Turn off the cursor. */
6064 if (!w
->pseudo_window_p
6065 && x_phys_cursor_in_rect_p (w
, r
))
6068 cursor_cleared_p
= 1;
6071 cursor_cleared_p
= 0;
6073 /* Find the first row intersecting the rectangle R. */
6074 row
= w
->current_matrix
->rows
;
6076 while (row
->enabled_p
6078 && y
+ row
->height
< r
->top
)
6084 /* Display the text in the rectangle, one text line at a time. */
6085 while (row
->enabled_p
6089 expose_line (w
, row
, r
);
6094 /* Display the mode line if there is one. */
6095 if (WINDOW_WANTS_MODELINE_P (w
)
6096 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
6098 && row
->y
< r
->bottom
)
6099 expose_line (w
, row
, r
);
6101 if (!w
->pseudo_window_p
)
6103 /* Draw border between windows. */
6104 x_draw_vertical_border (w
);
6106 /* Turn the cursor on again. */
6107 if (cursor_cleared_p
)
6108 x_update_window_cursor (w
, 1);
6111 /* Display scroll bar for this window. */
6112 if (!NILP (w
->vertical_scroll_bar
))
6115 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w
->vertical_scroll_bar
));
6122 /* Determine the intersection of two rectangles R1 and R2. Return
6123 the intersection in *RESULT. Value is non-zero if RESULT is not
6127 x_intersect_rectangles (r1
, r2
, result
)
6128 Rect
*r1
, *r2
, *result
;
6131 Rect
*upper
, *lower
;
6132 int intersection_p
= 0;
6134 /* Rerrange so that R1 is the left-most rectangle. */
6135 if (r1
->left
< r2
->left
)
6136 left
= r1
, right
= r2
;
6138 left
= r2
, right
= r1
;
6140 /* X0 of the intersection is right.x0, if this is inside R1,
6141 otherwise there is no intersection. */
6142 if (right
->left
<= left
->right
)
6144 result
->left
= right
->left
;
6146 /* The right end of the intersection is the minimum of the
6147 the right ends of left and right. */
6148 result
->right
= min (left
->right
, right
->right
);
6150 /* Same game for Y. */
6151 if (r1
->top
< r2
->top
)
6152 upper
= r1
, lower
= r2
;
6154 upper
= r2
, lower
= r1
;
6156 /* The upper end of the intersection is lower.y0, if this is inside
6157 of upper. Otherwise, there is no intersection. */
6158 if (lower
->top
<= upper
->bottom
)
6160 result
->top
= lower
->top
;
6162 /* The lower end of the intersection is the minimum of the lower
6163 ends of upper and lower. */
6164 result
->bottom
= min (lower
->bottom
, upper
->bottom
);
6169 return intersection_p
;
6180 x_update_cursor (f
, 1);
6184 frame_unhighlight (f
)
6187 x_update_cursor (f
, 1);
6190 /* The focus has changed. Update the frames as necessary to reflect
6191 the new situation. Note that we can't change the selected frame
6192 here, because the Lisp code we are interrupting might become confused.
6193 Each event gets marked with the frame in which it occurred, so the
6194 Lisp code can tell when the switch took place by examining the events. */
6197 x_new_focus_frame (dpyinfo
, frame
)
6198 struct x_display_info
*dpyinfo
;
6199 struct frame
*frame
;
6201 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
6203 if (frame
!= dpyinfo
->x_focus_frame
)
6205 /* Set this before calling other routines, so that they see
6206 the correct value of x_focus_frame. */
6207 dpyinfo
->x_focus_frame
= frame
;
6209 if (old_focus
&& old_focus
->auto_lower
)
6210 x_lower_frame (old_focus
);
6213 selected_frame
= frame
;
6214 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
6216 Fselect_window (selected_frame
->selected_window
);
6217 choose_minibuf_frame ();
6220 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
6221 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
6223 pending_autoraise_frame
= 0;
6226 x_frame_rehighlight (dpyinfo
);
6229 /* Handle an event saying the mouse has moved out of an Emacs frame. */
6232 x_mouse_leave (dpyinfo
)
6233 struct x_display_info
*dpyinfo
;
6235 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
6238 /* The focus has changed, or we have redirected a frame's focus to
6239 another frame (this happens when a frame uses a surrogate
6240 mini-buffer frame). Shift the highlight as appropriate.
6242 The FRAME argument doesn't necessarily have anything to do with which
6243 frame is being highlighted or un-highlighted; we only use it to find
6244 the appropriate X display info. */
6247 XTframe_rehighlight (frame
)
6248 struct frame
*frame
;
6250 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
6254 x_frame_rehighlight (dpyinfo
)
6255 struct x_display_info
*dpyinfo
;
6257 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
6259 if (dpyinfo
->x_focus_frame
)
6261 dpyinfo
->x_highlight_frame
6262 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
6263 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
6264 : dpyinfo
->x_focus_frame
);
6265 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
6267 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
6268 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
6272 dpyinfo
->x_highlight_frame
= 0;
6274 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
6277 frame_unhighlight (old_highlight
);
6278 if (dpyinfo
->x_highlight_frame
)
6279 frame_highlight (dpyinfo
->x_highlight_frame
);
6285 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
6288 /* Initialize mode_switch_bit and modifier_meaning. */
6290 x_find_modifier_meanings (dpyinfo
)
6291 struct x_display_info
*dpyinfo
;
6293 int min_code
, max_code
;
6296 XModifierKeymap
*mods
;
6298 dpyinfo
->meta_mod_mask
= 0;
6299 dpyinfo
->shift_lock_mask
= 0;
6300 dpyinfo
->alt_mod_mask
= 0;
6301 dpyinfo
->super_mod_mask
= 0;
6302 dpyinfo
->hyper_mod_mask
= 0;
6305 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
6307 min_code
= dpyinfo
->display
->min_keycode
;
6308 max_code
= dpyinfo
->display
->max_keycode
;
6311 syms
= XGetKeyboardMapping (dpyinfo
->display
,
6312 min_code
, max_code
- min_code
+ 1,
6314 mods
= XGetModifierMapping (dpyinfo
->display
);
6316 /* Scan the modifier table to see which modifier bits the Meta and
6317 Alt keysyms are on. */
6319 int row
, col
; /* The row and column in the modifier table. */
6321 for (row
= 3; row
< 8; row
++)
6322 for (col
= 0; col
< mods
->max_keypermod
; col
++)
6325 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
6327 /* Zeroes are used for filler. Skip them. */
6331 /* Are any of this keycode's keysyms a meta key? */
6335 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
6337 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
6343 dpyinfo
->meta_mod_mask
|= (1 << row
);
6348 dpyinfo
->alt_mod_mask
|= (1 << row
);
6353 dpyinfo
->hyper_mod_mask
|= (1 << row
);
6358 dpyinfo
->super_mod_mask
|= (1 << row
);
6362 /* Ignore this if it's not on the lock modifier. */
6363 if ((1 << row
) == LockMask
)
6364 dpyinfo
->shift_lock_mask
= LockMask
;
6372 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
6373 if (! dpyinfo
->meta_mod_mask
)
6375 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
6376 dpyinfo
->alt_mod_mask
= 0;
6379 /* If some keys are both alt and meta,
6380 make them just meta, not alt. */
6381 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
6383 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
6386 XFree ((char *) syms
);
6387 XFreeModifiermap (mods
);
6392 /* Convert between the modifier bits X uses and the modifier bits
6396 x_mac_to_emacs_modifiers (dpyinfo
, state
)
6397 struct x_display_info
*dpyinfo
;
6398 unsigned short state
;
6400 return (((state
& shiftKey
) ? shift_modifier
: 0)
6401 | ((state
& controlKey
) ? ctrl_modifier
: 0)
6402 | ((state
& cmdKey
) ? meta_modifier
: 0)
6403 | ((state
& optionKey
) ? alt_modifier
: 0));
6407 static unsigned short
6408 x_emacs_to_x_modifiers (dpyinfo
, state
)
6409 struct x_display_info
*dpyinfo
;
6412 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
6413 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
6414 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
6415 | ((state
& shift_modifier
) ? ShiftMask
: 0)
6416 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
6417 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
6421 /* Convert a keysym to its name. */
6424 x_get_keysym_name (keysym
)
6431 value
= XKeysymToString (keysym
);
6442 /* Mouse clicks and mouse movement. Rah. */
6444 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
6445 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
6446 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
6447 not force the value into range. */
6450 pixel_to_glyph_coords (f
, pix_x
, pix_y
, x
, y
, bounds
, noclip
)
6452 register int pix_x
, pix_y
;
6453 register int *x
, *y
;
6457 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
6458 even for negative values. */
6460 pix_x
-= FONT_WIDTH ((f
)->output_data
.mac
->font
) - 1;
6462 pix_y
-= (f
)->output_data
.mac
->line_height
- 1;
6464 pix_x
= PIXEL_TO_CHAR_COL (f
, pix_x
);
6465 pix_y
= PIXEL_TO_CHAR_ROW (f
, pix_y
);
6469 bounds
->left
= CHAR_TO_PIXEL_COL (f
, pix_x
);
6470 bounds
->top
= CHAR_TO_PIXEL_ROW (f
, pix_y
);
6471 bounds
->right
= bounds
->left
+ FONT_WIDTH (f
->output_data
.mac
->font
);
6472 bounds
->bottom
= bounds
->top
+ f
->output_data
.mac
->line_height
;
6479 else if (pix_x
> FRAME_WINDOW_WIDTH (f
))
6480 pix_x
= FRAME_WINDOW_WIDTH (f
);
6484 else if (pix_y
> f
->height
)
6493 /* Given HPOS/VPOS in the current matrix of W, return corresponding
6494 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
6495 can't tell the positions because W's display is not up to date,
6499 glyph_to_pixel_coords (w
, hpos
, vpos
, frame_x
, frame_y
)
6502 int *frame_x
, *frame_y
;
6506 xassert (hpos
>= 0 && hpos
< w
->current_matrix
->matrix_w
);
6507 xassert (vpos
>= 0 && vpos
< w
->current_matrix
->matrix_h
);
6509 if (display_completed
)
6511 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
6512 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
6513 struct glyph
*end
= glyph
+ min (hpos
, row
->used
[TEXT_AREA
]);
6519 *frame_x
+= glyph
->pixel_width
;
6527 *frame_y
= *frame_x
= 0;
6531 *frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, *frame_y
);
6532 *frame_x
= WINDOW_TO_FRAME_PIXEL_X (w
, *frame_x
);
6537 /* Prepare a mouse-event in *RESULT for placement in the input queue.
6539 If the event is a button press, then note that we have grabbed
6543 construct_mouse_click (result
, event
, f
)
6544 struct input_event
*result
;
6550 result
->kind
= mouse_click
;
6551 result
->code
= 0; /* only one mouse button */
6552 result
->timestamp
= event
->when
;
6553 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
6555 mouseLoc
= event
->where
;
6556 SetPort (FRAME_MAC_WINDOW (f
));
6557 GlobalToLocal (&mouseLoc
);
6558 XSETINT (result
->x
, mouseLoc
.h
);
6559 XSETINT (result
->y
, mouseLoc
.v
);
6561 XSETFRAME (result
->frame_or_window
, f
);
6568 /* Function to report a mouse movement to the mainstream Emacs code.
6569 The input handler calls this.
6571 We have received a mouse movement event, which is given in *event.
6572 If the mouse is over a different glyph than it was last time, tell
6573 the mainstream emacs code by setting mouse_moved. If not, ask for
6574 another motion event, so we can check again the next time it moves. */
6576 static Point last_mouse_motion_position
;
6577 static Lisp_Object last_mouse_motion_frame
;
6580 note_mouse_movement (frame
, pos
)
6584 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
6585 last_mouse_motion_position
= *pos
;
6586 XSETFRAME (last_mouse_motion_frame
, frame
);
6588 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
6590 frame
->mouse_moved
= 1;
6591 last_mouse_scroll_bar
= Qnil
;
6592 note_mouse_highlight (frame
, -1, -1);
6594 /* Has the mouse moved off the glyph it was on at the last sighting? */
6595 else if (pos
->h
< last_mouse_glyph
.left
6596 || pos
->h
>= last_mouse_glyph
.right
6597 || pos
->v
< last_mouse_glyph
.top
6598 || pos
->v
>= last_mouse_glyph
.bottom
)
6600 frame
->mouse_moved
= 1;
6601 last_mouse_scroll_bar
= Qnil
;
6602 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
6606 /* This is used for debugging, to turn off note_mouse_highlight. */
6608 int disable_mouse_highlight
;
6612 /************************************************************************
6614 ************************************************************************/
6616 /* Find the glyph under window-relative coordinates X/Y in window W.
6617 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6618 strings. Return in *HPOS and *VPOS the row and column number of
6619 the glyph found. Return in *AREA the glyph area containing X.
6620 Value is a pointer to the glyph found or null if X/Y is not on
6621 text, or we can't tell because W's current matrix is not up to
6624 static struct glyph
*
6625 x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, area
)
6628 int *hpos
, *vpos
, *area
;
6630 struct glyph
*glyph
, *end
;
6631 struct glyph_row
*row
= NULL
;
6632 int x0
, i
, left_area_width
;
6634 /* Find row containing Y. Give up if some row is not enabled. */
6635 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
6637 row
= MATRIX_ROW (w
->current_matrix
, i
);
6638 if (!row
->enabled_p
)
6640 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
6647 /* Give up if Y is not in the window. */
6648 if (i
== w
->current_matrix
->nrows
)
6651 /* Get the glyph area containing X. */
6652 if (w
->pseudo_window_p
)
6659 left_area_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
6660 if (x
< left_area_width
)
6662 *area
= LEFT_MARGIN_AREA
;
6665 else if (x
< left_area_width
+ window_box_width (w
, TEXT_AREA
))
6668 x0
= row
->x
+ left_area_width
;
6672 *area
= RIGHT_MARGIN_AREA
;
6673 x0
= left_area_width
+ window_box_width (w
, TEXT_AREA
);
6677 /* Find glyph containing X. */
6678 glyph
= row
->glyphs
[*area
];
6679 end
= glyph
+ row
->used
[*area
];
6682 if (x
< x0
+ glyph
->pixel_width
)
6684 if (w
->pseudo_window_p
)
6686 else if (BUFFERP (glyph
->object
))
6690 x0
+= glyph
->pixel_width
;
6697 *hpos
= glyph
- row
->glyphs
[*area
];
6702 /* Convert frame-relative x/y to coordinates relative to window W.
6703 Takes pseudo-windows into account. */
6706 frame_to_window_pixel_xy (w
, x
, y
)
6710 if (w
->pseudo_window_p
)
6712 /* A pseudo-window is always full-width, and starts at the
6713 left edge of the frame, plus a frame border. */
6714 struct frame
*f
= XFRAME (w
->frame
);
6715 *x
-= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
);
6716 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6720 *x
= FRAME_TO_WINDOW_PIXEL_X (w
, *x
);
6721 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
6726 /* Take proper action when mouse has moved to the mode or top line of
6727 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6728 mode line. X is relative to the start of the text display area of
6729 W, so the width of fringes and scroll bars must be subtracted
6730 to get a position relative to the start of the mode line. */
6733 note_mode_line_highlight (w
, x
, mode_line_p
)
6737 struct frame
*f
= XFRAME (w
->frame
);
6738 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6739 Cursor cursor
= dpyinfo
->vertical_scroll_bar_cursor
;
6740 struct glyph_row
*row
;
6743 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
6745 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
6749 struct glyph
*glyph
, *end
;
6750 Lisp_Object help
, map
;
6753 /* Find the glyph under X. */
6754 glyph
= row
->glyphs
[TEXT_AREA
];
6755 end
= glyph
+ row
->used
[TEXT_AREA
];
6756 x0
= - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * CANON_X_UNIT (f
)
6757 + FRAME_X_LEFT_FRINGE_WIDTH (f
));
6759 && x
>= x0
+ glyph
->pixel_width
)
6761 x0
+= glyph
->pixel_width
;
6766 && STRINGP (glyph
->object
)
6767 && XSTRING (glyph
->object
)->intervals
6768 && glyph
->charpos
>= 0
6769 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
6771 /* If we're on a string with `help-echo' text property,
6772 arrange for the help to be displayed. This is done by
6773 setting the global variable help_echo to the help string. */
6774 help
= Fget_text_property (make_number (glyph
->charpos
),
6775 Qhelp_echo
, glyph
->object
);
6779 XSETWINDOW (help_echo_window
, w
);
6780 help_echo_object
= glyph
->object
;
6781 help_echo_pos
= glyph
->charpos
;
6784 /* Change the mouse pointer according to what is under X/Y. */
6785 map
= Fget_text_property (make_number (glyph
->charpos
),
6786 Qlocal_map
, glyph
->object
);
6788 cursor
= f
->output_data
.mac
->nontext_cursor
;
6791 map
= Fget_text_property (make_number (glyph
->charpos
),
6792 Qkeymap
, glyph
->object
);
6794 cursor
= f
->output_data
.mac
->nontext_cursor
;
6799 #if 0 /* MAC_TODO: mouse cursor */
6800 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), cursor
);
6805 /* Take proper action when the mouse has moved to position X, Y on
6806 frame F as regards highlighting characters that have mouse-face
6807 properties. Also de-highlighting chars where the mouse was before.
6808 X and Y can be negative or out of range. */
6811 note_mouse_highlight (f
, x
, y
)
6815 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6820 /* When a menu is active, don't highlight because this looks odd. */
6821 #ifdef USE_X_TOOLKIT
6822 if (popup_activated ())
6826 if (disable_mouse_highlight
6827 || !f
->glyphs_initialized_p
)
6830 dpyinfo
->mouse_face_mouse_x
= x
;
6831 dpyinfo
->mouse_face_mouse_y
= y
;
6832 dpyinfo
->mouse_face_mouse_frame
= f
;
6834 if (dpyinfo
->mouse_face_defer
)
6839 dpyinfo
->mouse_face_deferred_gc
= 1;
6843 /* Which window is that in? */
6844 window
= window_from_coordinates (f
, x
, y
, &portion
, 1);
6846 /* If we were displaying active text in another window, clear that. */
6847 if (! EQ (window
, dpyinfo
->mouse_face_window
))
6848 clear_mouse_face (dpyinfo
);
6850 /* Not on a window -> return. */
6851 if (!WINDOWP (window
))
6854 /* Convert to window-relative pixel coordinates. */
6855 w
= XWINDOW (window
);
6856 frame_to_window_pixel_xy (w
, &x
, &y
);
6858 /* Handle tool-bar window differently since it doesn't display a
6860 if (EQ (window
, f
->tool_bar_window
))
6862 note_tool_bar_highlight (f
, x
, y
);
6866 if (portion
== 1 || portion
== 3)
6868 /* Mouse is on the mode or top line. */
6869 note_mode_line_highlight (w
, x
, portion
== 1);
6872 #if 0 /* MAC_TODO: mouse cursor */
6874 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
6875 f
->output_data
.x
->text_cursor
);
6878 /* Are we in a window whose display is up to date?
6879 And verify the buffer's text has not changed. */
6880 if (/* Within text portion of the window. */
6882 && EQ (w
->window_end_valid
, w
->buffer
)
6883 && XFASTINT (w
->last_modified
) == BUF_MODIFF (XBUFFER (w
->buffer
))
6884 && (XFASTINT (w
->last_overlay_modified
)
6885 == BUF_OVERLAY_MODIFF (XBUFFER (w
->buffer
))))
6887 int hpos
, vpos
, pos
, i
, area
;
6888 struct glyph
*glyph
;
6890 /* Find the glyph under X/Y. */
6891 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &area
);
6893 /* Clear mouse face if X/Y not over text. */
6895 || area
!= TEXT_AREA
6896 || !MATRIX_ROW (w
->current_matrix
, vpos
)->displays_text_p
)
6898 clear_mouse_face (dpyinfo
);
6902 pos
= glyph
->charpos
;
6903 xassert (w
->pseudo_window_p
|| BUFFERP (glyph
->object
));
6905 /* Check for mouse-face and help-echo. */
6907 Lisp_Object mouse_face
, overlay
, position
;
6908 Lisp_Object
*overlay_vec
;
6910 struct buffer
*obuf
;
6913 /* If we get an out-of-range value, return now; avoid an error. */
6914 if (pos
> BUF_Z (XBUFFER (w
->buffer
)))
6917 /* Make the window's buffer temporarily current for
6918 overlays_at and compute_char_face. */
6919 obuf
= current_buffer
;
6920 current_buffer
= XBUFFER (w
->buffer
);
6926 /* Is this char mouse-active or does it have help-echo? */
6927 XSETINT (position
, pos
);
6929 /* Put all the overlays we want in a vector in overlay_vec.
6930 Store the length in len. If there are more than 10, make
6931 enough space for all, and try again. */
6933 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6934 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
6935 if (noverlays
> len
)
6938 overlay_vec
= (Lisp_Object
*) alloca (len
* sizeof (Lisp_Object
));
6939 noverlays
= overlays_at (pos
, 0, &overlay_vec
, &len
, NULL
, NULL
);
6942 /* Sort overlays into increasing priority order. */
6943 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
6945 /* Check mouse-face highlighting. */
6946 if (! (EQ (window
, dpyinfo
->mouse_face_window
)
6947 && vpos
>= dpyinfo
->mouse_face_beg_row
6948 && vpos
<= dpyinfo
->mouse_face_end_row
6949 && (vpos
> dpyinfo
->mouse_face_beg_row
6950 || hpos
>= dpyinfo
->mouse_face_beg_col
)
6951 && (vpos
< dpyinfo
->mouse_face_end_row
6952 || hpos
< dpyinfo
->mouse_face_end_col
6953 || dpyinfo
->mouse_face_past_end
)))
6955 /* Clear the display of the old active region, if any. */
6956 clear_mouse_face (dpyinfo
);
6958 /* Find the highest priority overlay that has a mouse-face prop. */
6960 for (i
= noverlays
- 1; i
>= 0; --i
)
6962 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
6963 if (!NILP (mouse_face
))
6965 overlay
= overlay_vec
[i
];
6970 /* If no overlay applies, get a text property. */
6972 mouse_face
= Fget_text_property (position
, Qmouse_face
, w
->buffer
);
6974 /* Handle the overlay case. */
6975 if (! NILP (overlay
))
6977 /* Find the range of text around this char that
6978 should be active. */
6979 Lisp_Object before
, after
;
6982 before
= Foverlay_start (overlay
);
6983 after
= Foverlay_end (overlay
);
6984 /* Record this as the current active region. */
6985 fast_find_position (w
, XFASTINT (before
),
6986 &dpyinfo
->mouse_face_beg_col
,
6987 &dpyinfo
->mouse_face_beg_row
,
6988 &dpyinfo
->mouse_face_beg_x
,
6989 &dpyinfo
->mouse_face_beg_y
);
6990 dpyinfo
->mouse_face_past_end
6991 = !fast_find_position (w
, XFASTINT (after
),
6992 &dpyinfo
->mouse_face_end_col
,
6993 &dpyinfo
->mouse_face_end_row
,
6994 &dpyinfo
->mouse_face_end_x
,
6995 &dpyinfo
->mouse_face_end_y
);
6996 dpyinfo
->mouse_face_window
= window
;
6997 dpyinfo
->mouse_face_face_id
6998 = face_at_buffer_position (w
, pos
, 0, 0,
6999 &ignore
, pos
+ 1, 1);
7001 /* Display it as active. */
7002 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7004 /* Handle the text property case. */
7005 else if (! NILP (mouse_face
))
7007 /* Find the range of text around this char that
7008 should be active. */
7009 Lisp_Object before
, after
, beginning
, end
;
7012 beginning
= Fmarker_position (w
->start
);
7013 XSETINT (end
, (BUF_Z (XBUFFER (w
->buffer
))
7014 - XFASTINT (w
->window_end_pos
)));
7016 = Fprevious_single_property_change (make_number (pos
+ 1),
7018 w
->buffer
, beginning
);
7020 = Fnext_single_property_change (position
, Qmouse_face
,
7022 /* Record this as the current active region. */
7023 fast_find_position (w
, XFASTINT (before
),
7024 &dpyinfo
->mouse_face_beg_col
,
7025 &dpyinfo
->mouse_face_beg_row
,
7026 &dpyinfo
->mouse_face_beg_x
,
7027 &dpyinfo
->mouse_face_beg_y
);
7028 dpyinfo
->mouse_face_past_end
7029 = !fast_find_position (w
, XFASTINT (after
),
7030 &dpyinfo
->mouse_face_end_col
,
7031 &dpyinfo
->mouse_face_end_row
,
7032 &dpyinfo
->mouse_face_end_x
,
7033 &dpyinfo
->mouse_face_end_y
);
7034 dpyinfo
->mouse_face_window
= window
;
7035 dpyinfo
->mouse_face_face_id
7036 = face_at_buffer_position (w
, pos
, 0, 0,
7037 &ignore
, pos
+ 1, 1);
7039 /* Display it as active. */
7040 show_mouse_face (dpyinfo
, DRAW_MOUSE_FACE
);
7044 /* Look for a `help-echo' property. */
7046 Lisp_Object help
, overlay
;
7048 /* Check overlays first. */
7050 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
7052 overlay
= overlay_vec
[i
];
7053 help
= Foverlay_get (overlay
, Qhelp_echo
);
7059 help_echo_window
= window
;
7060 help_echo_object
= overlay
;
7061 help_echo_pos
= pos
;
7065 /* Try text properties. */
7066 if ((STRINGP (glyph
->object
)
7067 && glyph
->charpos
>= 0
7068 && glyph
->charpos
< XSTRING (glyph
->object
)->size
)
7069 || (BUFFERP (glyph
->object
)
7070 && glyph
->charpos
>= BEGV
7071 && glyph
->charpos
< ZV
))
7072 help
= Fget_text_property (make_number (glyph
->charpos
),
7073 Qhelp_echo
, glyph
->object
);
7078 help_echo_window
= window
;
7079 help_echo_object
= glyph
->object
;
7080 help_echo_pos
= glyph
->charpos
;
7087 current_buffer
= obuf
;
7093 redo_mouse_highlight ()
7095 if (!NILP (last_mouse_motion_frame
)
7096 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
7097 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
7098 last_mouse_motion_position
.h
,
7099 last_mouse_motion_position
.v
);
7104 /***********************************************************************
7106 ***********************************************************************/
7108 static int x_tool_bar_item
P_ ((struct frame
*, int, int,
7109 struct glyph
**, int *, int *, int *));
7111 /* Tool-bar item index of the item on which a mouse button was pressed
7114 static int last_tool_bar_item
;
7117 /* Get information about the tool-bar item at position X/Y on frame F.
7118 Return in *GLYPH a pointer to the glyph of the tool-bar item in
7119 the current matrix of the tool-bar window of F, or NULL if not
7120 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
7121 item in F->current_tool_bar_items. Value is
7123 -1 if X/Y is not on a tool-bar item
7124 0 if X/Y is on the same item that was highlighted before.
7128 x_tool_bar_item (f
, x
, y
, glyph
, hpos
, vpos
, prop_idx
)
7131 struct glyph
**glyph
;
7132 int *hpos
, *vpos
, *prop_idx
;
7134 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7135 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7138 /* Find the glyph under X/Y. */
7139 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, &area
);
7143 /* Get the start of this tool-bar item's properties in
7144 f->current_tool_bar_items. */
7145 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
7148 /* Is mouse on the highlighted item? */
7149 if (EQ (f
->tool_bar_window
, dpyinfo
->mouse_face_window
)
7150 && *vpos
>= dpyinfo
->mouse_face_beg_row
7151 && *vpos
<= dpyinfo
->mouse_face_end_row
7152 && (*vpos
> dpyinfo
->mouse_face_beg_row
7153 || *hpos
>= dpyinfo
->mouse_face_beg_col
)
7154 && (*vpos
< dpyinfo
->mouse_face_end_row
7155 || *hpos
< dpyinfo
->mouse_face_end_col
7156 || dpyinfo
->mouse_face_past_end
))
7163 /* Handle mouse button event on the tool-bar of frame F, at
7164 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
7168 x_handle_tool_bar_click (f
, button_event
)
7170 EventRecord
*button_event
;
7172 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7173 struct window
*w
= XWINDOW (f
->tool_bar_window
);
7174 int hpos
, vpos
, prop_idx
;
7175 struct glyph
*glyph
;
7176 Lisp_Object enabled_p
;
7177 int x
= button_event
->where
.h
;
7178 int y
= button_event
->where
.v
;
7180 /* If not on the highlighted tool-bar item, return. */
7181 frame_to_window_pixel_xy (w
, &x
, &y
);
7182 if (x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
) != 0)
7185 /* If item is disabled, do nothing. */
7186 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7187 if (NILP (enabled_p
))
7190 if (button_event
->what
== mouseDown
)
7192 /* Show item in pressed state. */
7193 show_mouse_face (dpyinfo
, DRAW_IMAGE_SUNKEN
);
7194 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_SUNKEN
;
7195 last_tool_bar_item
= prop_idx
;
7199 Lisp_Object key
, frame
;
7200 struct input_event event
;
7202 /* Show item in released state. */
7203 show_mouse_face (dpyinfo
, DRAW_IMAGE_RAISED
);
7204 dpyinfo
->mouse_face_image_state
= DRAW_IMAGE_RAISED
;
7206 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
7208 XSETFRAME (frame
, f
);
7209 event
.kind
= TOOL_BAR_EVENT
;
7210 event
.frame_or_window
= frame
;
7212 kbd_buffer_store_event (&event
);
7214 event
.kind
= TOOL_BAR_EVENT
;
7215 event
.frame_or_window
= frame
;
7217 event
.modifiers
= x_mac_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f
),
7218 button_event
->modifiers
);
7219 kbd_buffer_store_event (&event
);
7220 last_tool_bar_item
= -1;
7225 /* Possibly highlight a tool-bar item on frame F when mouse moves to
7226 tool-bar window-relative coordinates X/Y. Called from
7227 note_mouse_highlight. */
7230 note_tool_bar_highlight (f
, x
, y
)
7234 Lisp_Object window
= f
->tool_bar_window
;
7235 struct window
*w
= XWINDOW (window
);
7236 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7238 struct glyph
*glyph
;
7239 struct glyph_row
*row
;
7241 Lisp_Object enabled_p
;
7243 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
7244 int mouse_down_p
, rc
;
7246 /* Function note_mouse_highlight is called with negative x(y
7247 values when mouse moves outside of the frame. */
7248 if (x
<= 0 || y
<= 0)
7250 clear_mouse_face (dpyinfo
);
7254 rc
= x_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
7257 /* Not on tool-bar item. */
7258 clear_mouse_face (dpyinfo
);
7262 /* On same tool-bar item as before. */
7265 clear_mouse_face (dpyinfo
);
7267 /* Mouse is down, but on different tool-bar item? */
7268 mouse_down_p
= (dpyinfo
->grabbed
7269 && f
== last_mouse_frame
7270 && FRAME_LIVE_P (f
));
7272 && last_tool_bar_item
!= prop_idx
)
7275 dpyinfo
->mouse_face_image_state
= DRAW_NORMAL_TEXT
;
7276 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
7278 /* If tool-bar item is not enabled, don't highlight it. */
7279 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
7280 if (!NILP (enabled_p
))
7282 /* Compute the x-position of the glyph. In front and past the
7283 image is a space. We include this is the highlighted area. */
7284 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
7285 for (i
= x
= 0; i
< hpos
; ++i
)
7286 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
7288 /* Record this as the current active region. */
7289 dpyinfo
->mouse_face_beg_col
= hpos
;
7290 dpyinfo
->mouse_face_beg_row
= vpos
;
7291 dpyinfo
->mouse_face_beg_x
= x
;
7292 dpyinfo
->mouse_face_beg_y
= row
->y
;
7293 dpyinfo
->mouse_face_past_end
= 0;
7295 dpyinfo
->mouse_face_end_col
= hpos
+ 1;
7296 dpyinfo
->mouse_face_end_row
= vpos
;
7297 dpyinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
7298 dpyinfo
->mouse_face_end_y
= row
->y
;
7299 dpyinfo
->mouse_face_window
= window
;
7300 dpyinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
7302 /* Display it as active. */
7303 show_mouse_face (dpyinfo
, draw
);
7304 dpyinfo
->mouse_face_image_state
= draw
;
7309 /* Set help_echo to a help string.to display for this tool-bar item.
7310 XTread_socket does the rest. */
7311 help_echo_object
= help_echo_window
= Qnil
;
7313 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
7314 if (NILP (help_echo
))
7315 help_echo
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
7320 /* Find the glyph matrix position of buffer position POS in window W.
7321 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
7322 current glyphs must be up to date. If POS is above window start
7323 return (0, 0, 0, 0). If POS is after end of W, return end of
7327 fast_find_position (w
, pos
, hpos
, vpos
, x
, y
)
7330 int *hpos
, *vpos
, *x
, *y
;
7334 int maybe_next_line_p
= 0;
7335 int line_start_position
;
7336 int yb
= window_text_bottom_y (w
);
7337 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, 0);
7338 struct glyph_row
*best_row
= row
;
7339 int row_vpos
= 0, best_row_vpos
= 0;
7344 if (row
->used
[TEXT_AREA
])
7345 line_start_position
= row
->glyphs
[TEXT_AREA
]->charpos
;
7347 line_start_position
= 0;
7349 if (line_start_position
> pos
)
7351 /* If the position sought is the end of the buffer,
7352 don't include the blank lines at the bottom of the window. */
7353 else if (line_start_position
== pos
7354 && pos
== BUF_ZV (XBUFFER (w
->buffer
)))
7356 maybe_next_line_p
= 1;
7359 else if (line_start_position
> 0)
7362 best_row_vpos
= row_vpos
;
7365 if (row
->y
+ row
->height
>= yb
)
7372 /* Find the right column within BEST_ROW. */
7374 current_x
= best_row
->x
;
7375 for (i
= 0; i
< best_row
->used
[TEXT_AREA
]; i
++)
7377 struct glyph
*glyph
= best_row
->glyphs
[TEXT_AREA
] + i
;
7380 charpos
= glyph
->charpos
;
7384 *vpos
= best_row_vpos
;
7389 else if (charpos
> pos
)
7391 else if (charpos
> 0)
7394 current_x
+= glyph
->pixel_width
;
7397 /* If we're looking for the end of the buffer,
7398 and we didn't find it in the line we scanned,
7399 use the start of the following line. */
7400 if (maybe_next_line_p
)
7405 current_x
= best_row
->x
;
7408 *vpos
= best_row_vpos
;
7409 *hpos
= lastcol
+ 1;
7416 /* Display the active region described by mouse_face_*
7417 in its mouse-face if HL > 0, in its normal face if HL = 0. */
7420 show_mouse_face (dpyinfo
, draw
)
7421 struct mac_display_info
*dpyinfo
;
7422 enum draw_glyphs_face draw
;
7424 struct window
*w
= XWINDOW (dpyinfo
->mouse_face_window
);
7425 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
7427 int cursor_off_p
= 0;
7428 struct cursor_pos saved_cursor
;
7430 saved_cursor
= output_cursor
;
7432 /* If window is in the process of being destroyed, don't bother
7434 if (w
->current_matrix
== NULL
)
7437 /* Recognize when we are called to operate on rows that don't exist
7438 anymore. This can happen when a window is split. */
7439 if (dpyinfo
->mouse_face_end_row
>= w
->current_matrix
->nrows
)
7442 set_output_cursor (&w
->phys_cursor
);
7444 /* Note that mouse_face_beg_row etc. are window relative. */
7445 for (i
= dpyinfo
->mouse_face_beg_row
;
7446 i
<= dpyinfo
->mouse_face_end_row
;
7449 int start_hpos
, end_hpos
, start_x
;
7450 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, i
);
7452 /* Don't do anything if row doesn't have valid contents. */
7453 if (!row
->enabled_p
)
7456 /* For all but the first row, the highlight starts at column 0. */
7457 if (i
== dpyinfo
->mouse_face_beg_row
)
7459 start_hpos
= dpyinfo
->mouse_face_beg_col
;
7460 start_x
= dpyinfo
->mouse_face_beg_x
;
7468 if (i
== dpyinfo
->mouse_face_end_row
)
7469 end_hpos
= dpyinfo
->mouse_face_end_col
;
7471 end_hpos
= row
->used
[TEXT_AREA
];
7473 /* If the cursor's in the text we are about to rewrite, turn the
7475 if (!w
->pseudo_window_p
7476 && i
== output_cursor
.vpos
7477 && output_cursor
.hpos
>= start_hpos
- 1
7478 && output_cursor
.hpos
<= end_hpos
)
7480 x_update_window_cursor (w
, 0);
7484 if (end_hpos
> start_hpos
)
7486 row
->mouse_face_p
= draw
== DRAW_MOUSE_FACE
;
7487 x_draw_glyphs (w
, start_x
, row
, TEXT_AREA
,
7488 start_hpos
, end_hpos
, draw
, NULL
, NULL
, 0);
7492 /* If we turned the cursor off, turn it back on. */
7494 x_display_cursor (w
, 1,
7495 output_cursor
.hpos
, output_cursor
.vpos
,
7496 output_cursor
.x
, output_cursor
.y
);
7498 output_cursor
= saved_cursor
;
7501 #if 0 /* MAC_TODO: mouse cursor */
7502 /* Change the mouse cursor. */
7503 if (draw
== DRAW_NORMAL_TEXT
)
7504 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7505 f
->output_data
.x
->text_cursor
);
7506 else if (draw
== DRAW_MOUSE_FACE
)
7507 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7508 f
->output_data
.x
->cross_cursor
);
7510 XDefineCursor (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
7511 f
->output_data
.x
->nontext_cursor
);
7516 /* Clear out the mouse-highlighted active region.
7517 Redraw it un-highlighted first. */
7520 clear_mouse_face (dpyinfo
)
7521 struct mac_display_info
*dpyinfo
;
7523 if (!NILP (tip_frame
))
7526 if (! NILP (dpyinfo
->mouse_face_window
))
7527 show_mouse_face (dpyinfo
, DRAW_NORMAL_TEXT
);
7529 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7530 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7531 dpyinfo
->mouse_face_window
= Qnil
;
7535 /* Clear any mouse-face on window W. This function is part of the
7536 redisplay interface, and is called from try_window_id and similar
7537 functions to ensure the mouse-highlight is off. */
7540 x_clear_mouse_face (w
)
7543 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
7546 XSETWINDOW (window
, w
);
7547 if (EQ (window
, dpyinfo
->mouse_face_window
))
7548 clear_mouse_face (dpyinfo
);
7552 /* Just discard the mouse face information for frame F, if any.
7553 This is used when the size of F is changed. */
7556 cancel_mouse_face (f
)
7560 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7562 window
= dpyinfo
->mouse_face_window
;
7563 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
7565 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
7566 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
7567 dpyinfo
->mouse_face_window
= Qnil
;
7571 static struct scroll_bar
*x_window_to_scroll_bar ();
7572 static void x_scroll_bar_report_motion ();
7574 /* Return the current position of the mouse.
7575 *fp should be a frame which indicates which display to ask about.
7577 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7578 and *part to the frame, window, and scroll bar part that the mouse
7579 is over. Set *x and *y to the portion and whole of the mouse's
7580 position on the scroll bar.
7582 If the mouse movement started elsewhere, set *fp to the frame the
7583 mouse is on, *bar_window to nil, and *x and *y to the character cell
7586 Set *time to the server time-stamp for the time at which the mouse
7587 was at this position.
7589 Don't store anything if we don't have a valid set of values to report.
7591 This clears the mouse_moved flag, so we can wait for the next mouse
7595 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
7598 Lisp_Object
*bar_window
;
7599 enum scroll_bar_part
*part
;
7601 unsigned long *time
;
7604 int ignore1
, ignore2
;
7605 WindowPtr wp
= FrontWindow ();
7606 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
7607 Lisp_Object frame
, tail
;
7611 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
7612 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
7615 /* Clear the mouse-moved flag for every frame on this display. */
7616 FOR_EACH_FRAME (tail
, frame
)
7617 XFRAME (frame
)->mouse_moved
= 0;
7619 last_mouse_scroll_bar
= Qnil
;
7622 GetMouse (&mouse_pos
);
7624 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
7625 &last_mouse_glyph
, insist
);
7628 *part
= scroll_bar_handle
;
7630 XSETINT (*x
, mouse_pos
.h
);
7631 XSETINT (*y
, mouse_pos
.v
);
7632 *time
= last_mouse_movement_time
;
7639 /************************************************************************
7640 Scroll bars, general
7641 ************************************************************************/
7643 /* Create a scroll bar and return the scroll bar vector for it. W is
7644 the Emacs window on which to create the scroll bar. TOP, LEFT,
7645 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7648 static struct scroll_bar
*
7649 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
7651 int top
, left
, width
, height
, disp_top
, disp_height
;
7653 struct frame
*f
= XFRAME (w
->frame
);
7654 struct scroll_bar
*bar
7655 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
7663 r
.right
= left
+ width
;
7664 r
.bottom
= disp_top
+ disp_height
;
7666 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
7668 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
7669 SetControlReference (ch
, (long) bar
);
7671 XSETWINDOW (bar
->window
, w
);
7672 XSETINT (bar
->top
, top
);
7673 XSETINT (bar
->left
, left
);
7674 XSETINT (bar
->width
, width
);
7675 XSETINT (bar
->height
, height
);
7676 XSETINT (bar
->start
, 0);
7677 XSETINT (bar
->end
, 0);
7678 bar
->dragging
= Qnil
;
7680 /* Add bar to its frame's list of scroll bars. */
7681 bar
->next
= FRAME_SCROLL_BARS (f
);
7683 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7684 if (!NILP (bar
->next
))
7685 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7692 /* Draw BAR's handle in the proper position.
7694 If the handle is already drawn from START to END, don't bother
7695 redrawing it, unless REBUILD is non-zero; in that case, always
7696 redraw it. (REBUILD is handy for drawing the handle after expose
7699 Normally, we want to constrain the start and end of the handle to
7700 fit inside its rectangle, but if the user is dragging the scroll
7701 bar handle, we want to let them drag it down all the way, so that
7702 the bar's top is as far down as it goes; otherwise, there's no way
7703 to move to the very end of the buffer. */
7706 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
7707 struct scroll_bar
*bar
;
7711 int dragging
= ! NILP (bar
->dragging
);
7712 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
7713 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7715 /* If the display is already accurate, do nothing. */
7717 && start
== XINT (bar
->start
)
7718 && end
== XINT (bar
->end
))
7724 int inside_width
= VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f
, XINT (bar
->width
));
7725 int inside_height
= VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f
, XINT (bar
->height
));
7726 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
7728 /* Make sure the values are reasonable, and try to preserve
7729 the distance between start and end. */
7731 int length
= end
- start
;
7735 else if (start
> top_range
)
7737 end
= start
+ length
;
7741 else if (end
> top_range
&& ! dragging
)
7745 /* Store the adjusted setting in the scroll bar. */
7746 XSETINT (bar
->start
, start
);
7747 XSETINT (bar
->end
, end
);
7749 /* Clip the end position, just for display. */
7750 if (end
> top_range
)
7753 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels
7754 below top positions, to make sure the handle is always at least
7755 that many pixels tall. */
7756 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
7758 SetControlMinimum (ch
, 0);
7759 /* Don't inadvertently activate deactivated scroll bars */
7760 if (GetControlMaximum (ch
) != -1)
7761 SetControlMaximum (ch
,
7762 VERTICAL_SCROLL_BAR_TOP_RANGE (f
,
7765 SetControlValue (ch
, start
);
7766 #if 0 /* MAC_TODO: detect Appearance Manager 1.1 before use. */
7767 SetControlViewSize (ch
, end
);
7775 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7779 x_scroll_bar_remove (bar
)
7780 struct scroll_bar
*bar
;
7782 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
7786 /* Destroy the Mac scroll bar control */
7787 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
7789 /* Disassociate this scroll bar from its window. */
7790 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
7796 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7797 that we are displaying PORTION characters out of a total of WHOLE
7798 characters, starting at POSITION. If WINDOW has no scroll bar,
7802 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
7804 int portion
, whole
, position
;
7806 struct frame
*f
= XFRAME (w
->frame
);
7807 struct scroll_bar
*bar
;
7808 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
7809 int window_x
, window_y
, window_width
, window_height
;
7811 /* Get window dimensions. */
7812 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
7814 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
7815 height
= window_height
;
7817 /* Compute the left edge of the scroll bar area. */
7818 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7819 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
7821 left
= XFASTINT (w
->left
);
7822 left
*= CANON_X_UNIT (f
);
7823 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
7825 /* Compute the width of the scroll bar which might be less than
7826 the width of the area reserved for the scroll bar. */
7827 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
7828 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
7832 /* Compute the left edge of the scroll bar. */
7833 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
7834 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
7836 sb_left
= left
+ (width
- sb_width
) / 2;
7838 /* Adjustments according to Inside Macintosh to make it look nice */
7840 disp_height
= height
;
7846 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
7852 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
7855 /* Does the scroll bar exist yet? */
7856 if (NILP (w
->vertical_scroll_bar
))
7859 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
7860 left
, top
, width
, height
, 0);
7862 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
7864 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
7868 /* It may just need to be moved and resized. */
7871 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
7872 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
7876 /* If already correctly positioned, do nothing. */
7877 if (XINT (bar
->left
) == sb_left
7878 && XINT (bar
->top
) == top
7879 && XINT (bar
->width
) == sb_width
7880 && XINT (bar
->height
) == height
)
7884 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
7885 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
7886 sb_left
- 1, top
, 1, height
, 0);
7889 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
7890 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
7894 /* Remember new settings. */
7895 XSETINT (bar
->left
, sb_left
);
7896 XSETINT (bar
->top
, top
);
7897 XSETINT (bar
->width
, sb_width
);
7898 XSETINT (bar
->height
, height
);
7904 /* Set the scroll bar's current state, unless we're currently being
7906 if (NILP (bar
->dragging
))
7908 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
7911 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
7914 int start
= ((double) position
* top_range
) / whole
;
7915 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
7916 x_scroll_bar_set_handle (bar
, start
, end
, 0);
7922 /* The following three hooks are used when we're doing a thorough
7923 redisplay of the frame. We don't explicitly know which scroll bars
7924 are going to be deleted, because keeping track of when windows go
7925 away is a real pain - "Can you say set-window-configuration, boys
7926 and girls?" Instead, we just assert at the beginning of redisplay
7927 that *all* scroll bars are to be removed, and then save a scroll bar
7928 from the fiery pit when we actually redisplay its window. */
7930 /* Arrange for all scroll bars on FRAME to be removed at the next call
7931 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7932 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7935 XTcondemn_scroll_bars (frame
)
7938 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7939 while (! NILP (FRAME_SCROLL_BARS (frame
)))
7942 bar
= FRAME_SCROLL_BARS (frame
);
7943 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
7944 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
7945 XSCROLL_BAR (bar
)->prev
= Qnil
;
7946 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
7947 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
7948 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
7952 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7953 Note that WINDOW isn't necessarily condemned at all. */
7955 XTredeem_scroll_bar (window
)
7956 struct window
*window
;
7958 struct scroll_bar
*bar
;
7960 /* We can't redeem this window's scroll bar if it doesn't have one. */
7961 if (NILP (window
->vertical_scroll_bar
))
7964 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
7966 /* Unlink it from the condemned list. */
7968 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
7970 if (NILP (bar
->prev
))
7972 /* If the prev pointer is nil, it must be the first in one of
7974 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
7975 /* It's not condemned. Everything's fine. */
7977 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
7978 window
->vertical_scroll_bar
))
7979 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
7981 /* If its prev pointer is nil, it must be at the front of
7982 one or the other! */
7986 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
7988 if (! NILP (bar
->next
))
7989 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
7991 bar
->next
= FRAME_SCROLL_BARS (f
);
7993 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
7994 if (! NILP (bar
->next
))
7995 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
7999 /* Remove all scroll bars on FRAME that haven't been saved since the
8000 last call to `*condemn_scroll_bars_hook'. */
8003 XTjudge_scroll_bars (f
)
8006 Lisp_Object bar
, next
;
8008 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
8010 /* Clear out the condemned list now so we won't try to process any
8011 more events on the hapless scroll bars. */
8012 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
8014 for (; ! NILP (bar
); bar
= next
)
8016 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
8018 x_scroll_bar_remove (b
);
8021 b
->next
= b
->prev
= Qnil
;
8024 /* Now there should be no references to the condemned scroll bars,
8025 and they should get garbage-collected. */
8030 activate_scroll_bars (frame
)
8036 bar
= FRAME_SCROLL_BARS (frame
);
8037 while (! NILP (bar
))
8039 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8040 SetControlMaximum (ch
,
8041 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
8042 XINT (XSCROLL_BAR (bar
)
8045 bar
= XSCROLL_BAR (bar
)->next
;
8051 deactivate_scroll_bars (frame
)
8057 bar
= FRAME_SCROLL_BARS (frame
);
8058 while (! NILP (bar
))
8060 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
8061 SetControlMaximum (ch
, XINT (-1));
8063 bar
= XSCROLL_BAR (bar
)->next
;
8067 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
8068 is set to something other than no_event, it is enqueued.
8070 This may be called from a signal handler, so we have to ignore GC
8074 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
8075 struct scroll_bar
*bar
;
8078 struct input_event
*bufp
;
8080 if (! GC_WINDOWP (bar
->window
))
8083 bufp
->kind
= scroll_bar_click
;
8084 bufp
->frame_or_window
= bar
->window
;
8087 bar
->dragging
= Qnil
;
8091 case kControlUpButtonPart
:
8092 bufp
->part
= scroll_bar_up_arrow
;
8094 case kControlDownButtonPart
:
8095 bufp
->part
= scroll_bar_down_arrow
;
8097 case kControlPageUpPart
:
8098 bufp
->part
= scroll_bar_above_handle
;
8100 case kControlPageDownPart
:
8101 bufp
->part
= scroll_bar_below_handle
;
8103 case kControlIndicatorPart
:
8104 if (er
->what
== mouseDown
)
8105 bar
->dragging
= make_number (0);
8106 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8107 bufp
->part
= scroll_bar_handle
;
8113 /* Handle some mouse motion while someone is dragging the scroll bar.
8115 This may be called from a signal handler, so we have to ignore GC
8119 x_scroll_bar_note_movement (bar
, y_pos
, t
)
8120 struct scroll_bar
*bar
;
8124 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
8126 last_mouse_movement_time
= t
;
8129 XSETVECTOR (last_mouse_scroll_bar
, bar
);
8131 /* If we're dragging the bar, display it. */
8132 if (! GC_NILP (bar
->dragging
))
8134 /* Where should the handle be now? */
8135 int new_start
= y_pos
- 24;
8137 if (new_start
!= XINT (bar
->start
))
8139 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
8141 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
8147 /* Return information to the user about the current position of the
8148 mouse on the scroll bar. */
8151 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
8153 Lisp_Object
*bar_window
;
8154 enum scroll_bar_part
*part
;
8156 unsigned long *time
;
8158 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
8159 WindowPtr wp
= FrontWindow ();
8161 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8162 int win_y
, top_range
;
8165 GetMouse (&mouse_pos
);
8167 win_y
= mouse_pos
.v
- XINT (bar
->top
);
8168 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
8170 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
8174 if (! NILP (bar
->dragging
))
8175 win_y
-= XINT (bar
->dragging
);
8179 if (win_y
> top_range
)
8183 *bar_window
= bar
->window
;
8185 if (! NILP (bar
->dragging
))
8186 *part
= scroll_bar_handle
;
8187 else if (win_y
< XINT (bar
->start
))
8188 *part
= scroll_bar_above_handle
;
8189 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
8190 *part
= scroll_bar_handle
;
8192 *part
= scroll_bar_below_handle
;
8194 XSETINT (*x
, win_y
);
8195 XSETINT (*y
, top_range
);
8198 last_mouse_scroll_bar
= Qnil
;
8200 *time
= last_mouse_movement_time
;
8203 /***********************************************************************
8205 ***********************************************************************/
8207 /* Note if the text cursor of window W has been overwritten by a
8208 drawing operation that outputs N glyphs starting at HPOS in the
8209 line given by output_cursor.vpos. N < 0 means all the rest of the
8210 line after HPOS has been written. */
8213 note_overwritten_text_cursor (w
, hpos
, n
)
8217 if (updated_area
== TEXT_AREA
8218 && output_cursor
.vpos
== w
->phys_cursor
.vpos
8219 && hpos
<= w
->phys_cursor
.hpos
8221 || hpos
+ n
> w
->phys_cursor
.hpos
))
8222 w
->phys_cursor_on_p
= 0;
8226 /* Set clipping for output in glyph row ROW. W is the window in which
8227 we operate. GC is the graphics context to set clipping in.
8228 WHOLE_LINE_P non-zero means include the areas used for truncation
8229 mark display and alike in the clipping rectangle.
8231 ROW may be a text row or, e.g., a mode line. Text rows must be
8232 clipped to the interior of the window dedicated to text display,
8233 mode lines must be clipped to the whole window. */
8236 x_clip_to_row (w
, row
, gc
, whole_line_p
)
8238 struct glyph_row
*row
;
8242 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8244 int window_x
, window_y
, window_width
, window_height
;
8246 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
8248 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
8249 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
8250 clip_rect
.top
= max (clip_rect
.top
, window_y
);
8251 clip_rect
.right
= clip_rect
.left
+ window_width
;
8252 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
8254 /* If clipping to the whole line, including trunc marks, extend
8255 the rectangle to the left and increase its width. */
8258 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
8259 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
8262 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
8266 /* Draw a hollow box cursor on window W in glyph row ROW. */
8269 x_draw_hollow_cursor (w
, row
)
8271 struct glyph_row
*row
;
8273 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
8274 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8275 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
8278 struct glyph
*cursor_glyph
;
8281 /* Compute frame-relative coordinates from window-relative
8283 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8284 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
8285 + row
->ascent
- w
->phys_cursor_ascent
);
8286 h
= row
->height
- 1;
8288 /* Get the glyph the cursor is on. If we can't tell because
8289 the current matrix is invalid or such, give up. */
8290 cursor_glyph
= get_phys_cursor_glyph (w
);
8291 if (cursor_glyph
== NULL
)
8294 /* Compute the width of the rectangle to draw. If on a stretch
8295 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8296 rectangle as wide as the glyph, but use a canonical character
8298 wd
= cursor_glyph
->pixel_width
- 1;
8299 if (cursor_glyph
->type
== STRETCH_GLYPH
8300 && !x_stretch_cursor_p
)
8301 wd
= min (CANON_X_UNIT (f
), wd
);
8303 /* The foreground of cursor_gc is typically the same as the normal
8304 background color, which can cause the cursor box to be invisible. */
8305 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8306 if (dpyinfo
->scratch_cursor_gc
)
8307 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
8309 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
8310 GCForeground
, &xgcv
);
8311 gc
= dpyinfo
->scratch_cursor_gc
;
8313 /* Set clipping, draw the rectangle, and reset clipping again. */
8314 x_clip_to_row (w
, row
, gc
, 0);
8315 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
8316 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8320 /* Draw a bar cursor on window W in glyph row ROW.
8322 Implementation note: One would like to draw a bar cursor with an
8323 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8324 Unfortunately, I didn't find a font yet that has this property set.
8328 x_draw_bar_cursor (w
, row
, width
)
8330 struct glyph_row
*row
;
8333 /* If cursor hpos is out of bounds, don't draw garbage. This can
8334 happen in mini-buffer windows when switching between echo area
8335 glyphs and mini-buffer. */
8336 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8338 struct frame
*f
= XFRAME (w
->frame
);
8339 struct glyph
*cursor_glyph
;
8347 cursor_glyph
= get_phys_cursor_glyph (w
);
8348 if (cursor_glyph
== NULL
)
8351 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
8352 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
8353 mask
= GCForeground
| GCBackground
;
8354 dpy
= FRAME_MAC_DISPLAY (f
);
8355 window
= FRAME_MAC_WINDOW (f
);
8356 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
8359 XChangeGC (dpy
, gc
, mask
, &xgcv
);
8362 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
8363 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
8367 width
= f
->output_data
.mac
->cursor_width
;
8369 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
8370 x_clip_to_row (w
, row
, gc
, 0);
8371 XFillRectangle (dpy
, window
, gc
,
8373 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
8374 min (cursor_glyph
->pixel_width
, width
),
8376 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
8381 /* Clear the cursor of window W to background color, and mark the
8382 cursor as not shown. This is used when the text where the cursor
8383 is is about to be rewritten. */
8389 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
8390 x_update_window_cursor (w
, 0);
8394 /* Draw the cursor glyph of window W in glyph row ROW. See the
8395 comment of x_draw_glyphs for the meaning of HL. */
8398 x_draw_phys_cursor_glyph (w
, row
, hl
)
8400 struct glyph_row
*row
;
8401 enum draw_glyphs_face hl
;
8403 /* If cursor hpos is out of bounds, don't draw garbage. This can
8404 happen in mini-buffer windows when switching between echo area
8405 glyphs and mini-buffer. */
8406 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
8408 x_draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
,
8409 w
->phys_cursor
.hpos
, w
->phys_cursor
.hpos
+ 1,
8412 /* When we erase the cursor, and ROW is overlapped by other
8413 rows, make sure that these overlapping parts of other rows
8415 if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
8417 if (row
> w
->current_matrix
->rows
8418 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
8419 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
);
8421 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
8422 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
8423 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
);
8429 /* Erase the image of a cursor of window W from the screen. */
8432 x_erase_phys_cursor (w
)
8435 struct frame
*f
= XFRAME (w
->frame
);
8436 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
8437 int hpos
= w
->phys_cursor
.hpos
;
8438 int vpos
= w
->phys_cursor
.vpos
;
8439 int mouse_face_here_p
= 0;
8440 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
8441 struct glyph_row
*cursor_row
;
8442 struct glyph
*cursor_glyph
;
8443 enum draw_glyphs_face hl
;
8445 /* No cursor displayed or row invalidated => nothing to do on the
8447 if (w
->phys_cursor_type
== NO_CURSOR
)
8448 goto mark_cursor_off
;
8450 /* VPOS >= active_glyphs->nrows means that window has been resized.
8451 Don't bother to erase the cursor. */
8452 if (vpos
>= active_glyphs
->nrows
)
8453 goto mark_cursor_off
;
8455 /* If row containing cursor is marked invalid, there is nothing we
8457 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
8458 if (!cursor_row
->enabled_p
)
8459 goto mark_cursor_off
;
8461 /* If row is completely invisible, don't attempt to delete a cursor which
8462 isn't there. This can happen if cursor is at top of a window, and
8463 we switch to a buffer with a header line in that window. */
8464 if (cursor_row
->visible_height
<= 0)
8465 goto mark_cursor_off
;
8467 /* This can happen when the new row is shorter than the old one.
8468 In this case, either x_draw_glyphs or clear_end_of_line
8469 should have cleared the cursor. Note that we wouldn't be
8470 able to erase the cursor in this case because we don't have a
8471 cursor glyph at hand. */
8472 if (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])
8473 goto mark_cursor_off
;
8475 /* If the cursor is in the mouse face area, redisplay that when
8476 we clear the cursor. */
8477 if (! NILP (dpyinfo
->mouse_face_window
)
8478 && w
== XWINDOW (dpyinfo
->mouse_face_window
)
8479 && (vpos
> dpyinfo
->mouse_face_beg_row
8480 || (vpos
== dpyinfo
->mouse_face_beg_row
8481 && hpos
>= dpyinfo
->mouse_face_beg_col
))
8482 && (vpos
< dpyinfo
->mouse_face_end_row
8483 || (vpos
== dpyinfo
->mouse_face_end_row
8484 && hpos
< dpyinfo
->mouse_face_end_col
))
8485 /* Don't redraw the cursor's spot in mouse face if it is at the
8486 end of a line (on a newline). The cursor appears there, but
8487 mouse highlighting does not. */
8488 && cursor_row
->used
[TEXT_AREA
] > hpos
)
8489 mouse_face_here_p
= 1;
8491 /* Maybe clear the display under the cursor. */
8492 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
8495 int header_line_height
= WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w
);
8497 cursor_glyph
= get_phys_cursor_glyph (w
);
8498 if (cursor_glyph
== NULL
)
8499 goto mark_cursor_off
;
8501 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
8503 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
8505 WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
8507 cursor_glyph
->pixel_width
,
8508 cursor_row
->visible_height
,
8512 /* Erase the cursor by redrawing the character underneath it. */
8513 if (mouse_face_here_p
)
8514 hl
= DRAW_MOUSE_FACE
;
8515 else if (cursor_row
->inverse_p
)
8516 hl
= DRAW_INVERSE_VIDEO
;
8518 hl
= DRAW_NORMAL_TEXT
;
8519 x_draw_phys_cursor_glyph (w
, cursor_row
, hl
);
8522 w
->phys_cursor_on_p
= 0;
8523 w
->phys_cursor_type
= NO_CURSOR
;
8527 /* Display or clear cursor of window W. If ON is zero, clear the
8528 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8529 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8532 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
)
8534 int on
, hpos
, vpos
, x
, y
;
8536 struct frame
*f
= XFRAME (w
->frame
);
8537 int new_cursor_type
;
8538 int new_cursor_width
;
8539 struct glyph_matrix
*current_glyphs
;
8540 struct glyph_row
*glyph_row
;
8541 struct glyph
*glyph
;
8543 /* This is pointless on invisible frames, and dangerous on garbaged
8544 windows and frames; in the latter case, the frame or window may
8545 be in the midst of changing its size, and x and y may be off the
8547 if (! FRAME_VISIBLE_P (f
)
8548 || FRAME_GARBAGED_P (f
)
8549 || vpos
>= w
->current_matrix
->nrows
8550 || hpos
>= w
->current_matrix
->matrix_w
)
8553 /* If cursor is off and we want it off, return quickly. */
8554 if (!on
&& !w
->phys_cursor_on_p
)
8557 current_glyphs
= w
->current_matrix
;
8558 glyph_row
= MATRIX_ROW (current_glyphs
, vpos
);
8559 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
8561 /* If cursor row is not enabled, we don't really know where to
8562 display the cursor. */
8563 if (!glyph_row
->enabled_p
)
8565 w
->phys_cursor_on_p
= 0;
8569 xassert (interrupt_input_blocked
);
8571 /* Set new_cursor_type to the cursor we want to be displayed. In a
8572 mini-buffer window, we want the cursor only to appear if we are
8573 reading input from this window. For the selected window, we want
8574 the cursor type given by the frame parameter. If explicitly
8575 marked off, draw no cursor. In all other cases, we want a hollow
8577 new_cursor_width
= -1;
8578 if (cursor_in_echo_area
8579 && FRAME_HAS_MINIBUF_P (f
)
8580 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
8582 if (w
== XWINDOW (echo_area_window
))
8583 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8585 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8589 if (w
!= XWINDOW (selected_window
)
8590 || f
!= FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
)
8592 extern int cursor_in_non_selected_windows
;
8594 if (MINI_WINDOW_P (w
) || !cursor_in_non_selected_windows
)
8595 new_cursor_type
= NO_CURSOR
;
8597 new_cursor_type
= HOLLOW_BOX_CURSOR
;
8599 else if (w
->cursor_off_p
)
8600 new_cursor_type
= NO_CURSOR
;
8603 struct buffer
*b
= XBUFFER (w
->buffer
);
8605 if (EQ (b
->cursor_type
, Qt
))
8606 new_cursor_type
= FRAME_DESIRED_CURSOR (f
);
8608 new_cursor_type
= x_specified_cursor_type (b
->cursor_type
,
8613 /* If cursor is currently being shown and we don't want it to be or
8614 it is in the wrong place, or the cursor type is not what we want,
8616 if (w
->phys_cursor_on_p
8618 || w
->phys_cursor
.x
!= x
8619 || w
->phys_cursor
.y
!= y
8620 || new_cursor_type
!= w
->phys_cursor_type
))
8621 x_erase_phys_cursor (w
);
8623 /* If the cursor is now invisible and we want it to be visible,
8625 if (on
&& !w
->phys_cursor_on_p
)
8627 w
->phys_cursor_ascent
= glyph_row
->ascent
;
8628 w
->phys_cursor_height
= glyph_row
->height
;
8630 /* Set phys_cursor_.* before x_draw_.* is called because some
8631 of them may need the information. */
8632 w
->phys_cursor
.x
= x
;
8633 w
->phys_cursor
.y
= glyph_row
->y
;
8634 w
->phys_cursor
.hpos
= hpos
;
8635 w
->phys_cursor
.vpos
= vpos
;
8636 w
->phys_cursor_type
= new_cursor_type
;
8637 w
->phys_cursor_on_p
= 1;
8639 switch (new_cursor_type
)
8641 case HOLLOW_BOX_CURSOR
:
8642 x_draw_hollow_cursor (w
, glyph_row
);
8645 case FILLED_BOX_CURSOR
:
8646 x_draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
8650 x_draw_bar_cursor (w
, glyph_row
, new_cursor_width
);
8661 if (w
== XWINDOW (f
->selected_window
))
8662 if (FRAME_XIC (f
) && (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
))
8663 xic_set_preeditarea (w
, x
, y
);
8668 if (updating_frame
!= f
)
8669 XFlush (FRAME_X_DISPLAY (f
));
8674 /* Display the cursor on window W, or clear it. X and Y are window
8675 relative pixel coordinates. HPOS and VPOS are glyph matrix
8676 positions. If W is not the selected window, display a hollow
8677 cursor. ON non-zero means display the cursor at X, Y which
8678 correspond to HPOS, VPOS, otherwise it is cleared. */
8681 x_display_cursor (w
, on
, hpos
, vpos
, x
, y
)
8683 int on
, hpos
, vpos
, x
, y
;
8686 x_display_and_set_cursor (w
, on
, hpos
, vpos
, x
, y
);
8691 /* Display the cursor on window W, or clear it, according to ON_P.
8692 Don't change the cursor's position. */
8695 x_update_cursor (f
, on_p
)
8698 x_update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
8702 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
8703 in the window tree rooted at W. */
8706 x_update_cursor_in_window_tree (w
, on_p
)
8712 if (!NILP (w
->hchild
))
8713 x_update_cursor_in_window_tree (XWINDOW (w
->hchild
), on_p
);
8714 else if (!NILP (w
->vchild
))
8715 x_update_cursor_in_window_tree (XWINDOW (w
->vchild
), on_p
);
8717 x_update_window_cursor (w
, on_p
);
8719 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
8724 /* Switch the display of W's cursor on or off, according to the value
8728 x_update_window_cursor (w
, on
)
8732 /* Don't update cursor in windows whose frame is in the process
8733 of being deleted. */
8734 if (w
->current_matrix
)
8737 x_display_and_set_cursor (w
, on
, w
->phys_cursor
.hpos
, w
->phys_cursor
.vpos
,
8738 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
8744 #if 0 /* MAC_TODO: no icon and X error handling (?) */
8747 /* Refresh bitmap kitchen sink icon for frame F
8748 when we get an expose event for it. */
8754 /* Normally, the window manager handles this function. */
8757 /* Make the x-window of frame F use the gnu icon bitmap. */
8760 x_bitmap_icon (f
, file
)
8766 if (FRAME_X_WINDOW (f
) == 0)
8769 /* Free up our existing icon bitmap if any. */
8770 if (f
->output_data
.x
->icon_bitmap
> 0)
8771 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
8772 f
->output_data
.x
->icon_bitmap
= 0;
8775 bitmap_id
= x_create_bitmap_from_file (f
, file
);
8778 /* Create the GNU bitmap if necessary. */
8779 if (FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
< 0)
8780 FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
8781 = x_create_bitmap_from_data (f
, gnu_bits
,
8782 gnu_width
, gnu_height
);
8784 /* The first time we create the GNU bitmap,
8785 this increments the ref-count one extra time.
8786 As a result, the GNU bitmap is never freed.
8787 That way, we don't have to worry about allocating it again. */
8788 x_reference_bitmap (f
, FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
);
8790 bitmap_id
= FRAME_X_DISPLAY_INFO (f
)->icon_bitmap_id
;
8793 x_wm_set_icon_pixmap (f
, bitmap_id
);
8794 f
->output_data
.x
->icon_bitmap
= bitmap_id
;
8800 /* Make the x-window of frame F use a rectangle with text.
8801 Use ICON_NAME as the text. */
8804 x_text_icon (f
, icon_name
)
8808 if (FRAME_X_WINDOW (f
) == 0)
8814 text
.value
= (unsigned char *) icon_name
;
8815 text
.encoding
= XA_STRING
;
8817 text
.nitems
= strlen (icon_name
);
8818 #ifdef USE_X_TOOLKIT
8819 XSetWMIconName (FRAME_X_DISPLAY (f
), XtWindow (f
->output_data
.x
->widget
),
8821 #else /* not USE_X_TOOLKIT */
8822 XSetWMIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), &text
);
8823 #endif /* not USE_X_TOOLKIT */
8825 #else /* not HAVE_X11R4 */
8826 XSetIconName (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
), icon_name
);
8827 #endif /* not HAVE_X11R4 */
8829 if (f
->output_data
.x
->icon_bitmap
> 0)
8830 x_destroy_bitmap (f
, f
->output_data
.x
->icon_bitmap
);
8831 f
->output_data
.x
->icon_bitmap
= 0;
8832 x_wm_set_icon_pixmap (f
, 0);
8837 #define X_ERROR_MESSAGE_SIZE 200
8839 /* If non-nil, this should be a string.
8840 It means catch X errors and store the error message in this string. */
8842 static Lisp_Object x_error_message_string
;
8844 /* An X error handler which stores the error message in
8845 x_error_message_string. This is called from x_error_handler if
8846 x_catch_errors is in effect. */
8849 x_error_catcher (display
, error
)
8853 XGetErrorText (display
, error
->error_code
,
8854 XSTRING (x_error_message_string
)->data
,
8855 X_ERROR_MESSAGE_SIZE
);
8858 /* Begin trapping X errors for display DPY. Actually we trap X errors
8859 for all displays, but DPY should be the display you are actually
8862 After calling this function, X protocol errors no longer cause
8863 Emacs to exit; instead, they are recorded in the string
8864 stored in x_error_message_string.
8866 Calling x_check_errors signals an Emacs error if an X error has
8867 occurred since the last call to x_catch_errors or x_check_errors.
8869 Calling x_uncatch_errors resumes the normal error handling. */
8871 void x_check_errors ();
8872 static Lisp_Object
x_catch_errors_unwind ();
8875 x_catch_errors (dpy
)
8878 int count
= specpdl_ptr
- specpdl
;
8880 /* Make sure any errors from previous requests have been dealt with. */
8883 record_unwind_protect (x_catch_errors_unwind
, x_error_message_string
);
8885 x_error_message_string
= make_uninit_string (X_ERROR_MESSAGE_SIZE
);
8886 XSTRING (x_error_message_string
)->data
[0] = 0;
8891 /* Unbind the binding that we made to check for X errors. */
8894 x_catch_errors_unwind (old_val
)
8895 Lisp_Object old_val
;
8897 x_error_message_string
= old_val
;
8901 /* If any X protocol errors have arrived since the last call to
8902 x_catch_errors or x_check_errors, signal an Emacs error using
8903 sprintf (a buffer, FORMAT, the x error message text) as the text. */
8906 x_check_errors (dpy
, format
)
8910 /* Make sure to catch any errors incurred so far. */
8913 if (XSTRING (x_error_message_string
)->data
[0])
8914 error (format
, XSTRING (x_error_message_string
)->data
);
8917 /* Nonzero if we had any X protocol errors
8918 since we did x_catch_errors on DPY. */
8921 x_had_errors_p (dpy
)
8924 /* Make sure to catch any errors incurred so far. */
8927 return XSTRING (x_error_message_string
)->data
[0] != 0;
8930 /* Forget about any errors we have had, since we did x_catch_errors on DPY. */
8933 x_clear_errors (dpy
)
8936 XSTRING (x_error_message_string
)->data
[0] = 0;
8939 /* Stop catching X protocol errors and let them make Emacs die.
8940 DPY should be the display that was passed to x_catch_errors.
8941 COUNT should be the value that was returned by
8942 the corresponding call to x_catch_errors. */
8945 x_uncatch_errors (dpy
, count
)
8949 unbind_to (count
, Qnil
);
8953 static unsigned int x_wire_count
;
8956 fprintf (stderr
, "Lib call: %d\n", ++x_wire_count
);
8961 /* Handle SIGPIPE, which can happen when the connection to a server
8962 simply goes away. SIGPIPE is handled by x_connection_signal.
8963 Don't need to do anything, because the write which caused the
8964 SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
8965 which will do the appropriate cleanup for us. */
8968 x_connection_signal (signalnum
) /* If we don't have an argument, */
8969 int signalnum
; /* some compilers complain in signal calls. */
8972 /* USG systems forget handlers when they are used;
8973 must reestablish each time */
8974 signal (signalnum
, x_connection_signal
);
8978 /* Handling X errors. */
8980 /* Handle the loss of connection to display DISPLAY. */
8983 x_connection_closed (display
, error_message
)
8985 char *error_message
;
8987 struct x_display_info
*dpyinfo
= x_display_info_for_display (display
);
8988 Lisp_Object frame
, tail
;
8990 /* Indicate that this display is dead. */
8992 #if 0 /* Closing the display caused a bus error on OpenWindows. */
8993 #ifdef USE_X_TOOLKIT
8994 XtCloseDisplay (display
);
8999 dpyinfo
->display
= 0;
9001 /* First delete frames whose mini-buffers are on frames
9002 that are on the dead display. */
9003 FOR_EACH_FRAME (tail
, frame
)
9005 Lisp_Object minibuf_frame
;
9007 = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame
))));
9008 if (FRAME_X_P (XFRAME (frame
))
9009 && FRAME_X_P (XFRAME (minibuf_frame
))
9010 && ! EQ (frame
, minibuf_frame
)
9011 && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame
)) == dpyinfo
)
9012 Fdelete_frame (frame
, Qt
);
9015 /* Now delete all remaining frames on the dead display.
9016 We are now sure none of these is used as the mini-buffer
9017 for another frame that we need to delete. */
9018 FOR_EACH_FRAME (tail
, frame
)
9019 if (FRAME_X_P (XFRAME (frame
))
9020 && FRAME_X_DISPLAY_INFO (XFRAME (frame
)) == dpyinfo
)
9022 /* Set this to t so that Fdelete_frame won't get confused
9023 trying to find a replacement. */
9024 FRAME_KBOARD (XFRAME (frame
))->Vdefault_minibuffer_frame
= Qt
;
9025 Fdelete_frame (frame
, Qt
);
9029 x_delete_display (dpyinfo
);
9031 if (x_display_list
== 0)
9033 fprintf (stderr
, "%s\n", error_message
);
9034 shut_down_emacs (0, 0, Qnil
);
9038 /* Ordinary stack unwind doesn't deal with these. */
9040 sigunblock (sigmask (SIGIO
));
9042 sigunblock (sigmask (SIGALRM
));
9043 TOTALLY_UNBLOCK_INPUT
;
9045 clear_waiting_for_input ();
9046 error ("%s", error_message
);
9049 /* This is the usual handler for X protocol errors.
9050 It kills all frames on the display that we got the error for.
9051 If that was the only one, it prints an error message and kills Emacs. */
9054 x_error_quitter (display
, error
)
9058 char buf
[256], buf1
[356];
9060 /* Note that there is no real way portable across R3/R4 to get the
9061 original error handler. */
9063 XGetErrorText (display
, error
->error_code
, buf
, sizeof (buf
));
9064 sprintf (buf1
, "X protocol error: %s on protocol request %d",
9065 buf
, error
->request_code
);
9066 x_connection_closed (display
, buf1
);
9069 /* This is the first-level handler for X protocol errors.
9070 It calls x_error_quitter or x_error_catcher. */
9073 x_error_handler (display
, error
)
9077 if (! NILP (x_error_message_string
))
9078 x_error_catcher (display
, error
);
9080 x_error_quitter (display
, error
);
9084 /* This is the handler for X IO errors, always.
9085 It kills all frames on the display that we lost touch with.
9086 If that was the only one, it prints an error message and kills Emacs. */
9089 x_io_error_quitter (display
)
9094 sprintf (buf
, "Connection lost to X server `%s'", DisplayString (display
));
9095 x_connection_closed (display
, buf
);
9100 /* Changing the font of the frame. */
9102 /* Give frame F the font named FONTNAME as its default font, and
9103 return the full name of that font. FONTNAME may be a wildcard
9104 pattern; in that case, we choose some font that fits the pattern.
9105 The return value shows which font we chose. */
9108 x_new_font (f
, fontname
)
9110 register char *fontname
;
9112 struct font_info
*fontp
9113 = FS_LOAD_FONT (f
, 0, fontname
, -1);
9118 f
->output_data
.mac
->font
= (XFontStruct
*) (fontp
->font
);
9119 f
->output_data
.mac
->baseline_offset
= fontp
->baseline_offset
;
9120 f
->output_data
.mac
->fontset
= -1;
9122 /* Compute the scroll bar width in character columns. */
9123 if (f
->scroll_bar_pixel_width
> 0)
9125 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9126 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
9130 int wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9131 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
9134 /* Now make the frame display the given font. */
9135 if (FRAME_MAC_WINDOW (f
) != 0)
9137 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
9138 f
->output_data
.mac
->font
);
9139 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
9140 f
->output_data
.mac
->font
);
9141 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
9142 f
->output_data
.mac
->font
);
9144 frame_update_line_height (f
);
9145 x_set_window_size (f
, 0, f
->width
, f
->height
);
9148 /* If we are setting a new frame's font for the first time, there
9149 are no faces yet, so this font's height is the line height. */
9150 f
->output_data
.mac
->line_height
= FONT_HEIGHT (f
->output_data
.mac
->font
);
9152 return build_string (fontp
->full_name
);
9155 /* Give frame F the fontset named FONTSETNAME as its default font, and
9156 return the full name of that fontset. FONTSETNAME may be a
9157 wildcard pattern; in that case, we choose some fontset that fits
9158 the pattern. The return value shows which fontset we chose. */
9161 x_new_fontset (f
, fontsetname
)
9165 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
9171 if (f
->output_data
.mac
->fontset
== fontset
)
9172 /* This fontset is already set in frame F. There's nothing more
9174 return fontset_name (fontset
);
9176 result
= x_new_font (f
, (XSTRING (fontset_ascii (fontset
))->data
));
9178 if (!STRINGP (result
))
9179 /* Can't load ASCII font. */
9182 /* Since x_new_font doesn't update any fontset information, do it
9184 f
->output_data
.mac
->fontset
= fontset
;
9188 && (FRAME_XIC_STYLE (f
) & (XIMPreeditPosition
| XIMStatusArea
)))
9189 xic_set_xfontset (f
, XSTRING (fontset_ascii (fontset
))->data
);
9192 return build_string (fontsetname
);
9195 /* Compute actual fringe widths */
9198 x_compute_fringe_widths (f
, redraw
)
9202 int o_left
= f
->output_data
.mac
->left_fringe_width
;
9203 int o_right
= f
->output_data
.mac
->right_fringe_width
;
9204 int o_cols
= f
->output_data
.mac
->fringe_cols
;
9206 Lisp_Object left_fringe
= Fassq (Qleft_fringe
, f
->param_alist
);
9207 Lisp_Object right_fringe
= Fassq (Qright_fringe
, f
->param_alist
);
9208 int left_fringe_width
, right_fringe_width
;
9210 if (!NILP (left_fringe
))
9211 left_fringe
= Fcdr (left_fringe
);
9212 if (!NILP (right_fringe
))
9213 right_fringe
= Fcdr (right_fringe
);
9215 left_fringe_width
= ((NILP (left_fringe
) || !INTEGERP (left_fringe
)) ? 8 :
9216 XINT (left_fringe
));
9217 right_fringe_width
= ((NILP (right_fringe
) || !INTEGERP (right_fringe
)) ? 8 :
9218 XINT (right_fringe
));
9220 if (left_fringe_width
|| right_fringe_width
)
9222 int left_wid
= left_fringe_width
>= 0 ? left_fringe_width
: -left_fringe_width
;
9223 int right_wid
= right_fringe_width
>= 0 ? right_fringe_width
: -right_fringe_width
;
9224 int conf_wid
= left_wid
+ right_wid
;
9225 int font_wid
= FONT_WIDTH (f
->output_data
.mac
->font
);
9226 int cols
= (left_wid
+ right_wid
+ font_wid
-1) / font_wid
;
9227 int real_wid
= cols
* font_wid
;
9228 if (left_wid
&& right_wid
)
9230 if (left_fringe_width
< 0)
9232 /* Left fringe width is fixed, adjust right fringe if necessary */
9233 f
->output_data
.mac
->left_fringe_width
= left_wid
;
9234 f
->output_data
.mac
->right_fringe_width
= real_wid
- left_wid
;
9236 else if (right_fringe_width
< 0)
9238 /* Right fringe width is fixed, adjust left fringe if necessary */
9239 f
->output_data
.mac
->left_fringe_width
= real_wid
- right_wid
;
9240 f
->output_data
.mac
->right_fringe_width
= right_wid
;
9244 /* Adjust both fringes with an equal amount.
9245 Note that we are doing integer arithmetic here, so don't
9246 lose a pixel if the total width is an odd number. */
9247 int fill
= real_wid
- conf_wid
;
9248 f
->output_data
.mac
->left_fringe_width
= left_wid
+ fill
/2;
9249 f
->output_data
.mac
->right_fringe_width
= right_wid
+ fill
- fill
/2;
9252 else if (left_fringe_width
)
9254 f
->output_data
.mac
->left_fringe_width
= real_wid
;
9255 f
->output_data
.mac
->right_fringe_width
= 0;
9259 f
->output_data
.mac
->left_fringe_width
= 0;
9260 f
->output_data
.mac
->right_fringe_width
= real_wid
;
9262 f
->output_data
.mac
->fringe_cols
= cols
;
9263 f
->output_data
.mac
->fringes_extra
= real_wid
;
9267 f
->output_data
.mac
->left_fringe_width
= 0;
9268 f
->output_data
.mac
->right_fringe_width
= 0;
9269 f
->output_data
.mac
->fringe_cols
= 0;
9270 f
->output_data
.mac
->fringes_extra
= 0;
9273 if (redraw
&& FRAME_VISIBLE_P (f
))
9274 if (o_left
!= f
->output_data
.mac
->left_fringe_width
||
9275 o_right
!= f
->output_data
.mac
->right_fringe_width
||
9276 o_cols
!= f
->output_data
.mac
->fringe_cols
)
9280 #if 0 /* MAC_TODO: inline input methods for Mac */
9281 /***********************************************************************
9283 ***********************************************************************/
9289 /* XIM destroy callback function, which is called whenever the
9290 connection to input method XIM dies. CLIENT_DATA contains a
9291 pointer to the x_display_info structure corresponding to XIM. */
9294 xim_destroy_callback (xim
, client_data
, call_data
)
9296 XPointer client_data
;
9299 struct x_display_info
*dpyinfo
= (struct x_display_info
*) client_data
;
9300 Lisp_Object frame
, tail
;
9304 /* No need to call XDestroyIC.. */
9305 FOR_EACH_FRAME (tail
, frame
)
9307 struct frame
*f
= XFRAME (frame
);
9308 if (FRAME_X_DISPLAY_INFO (f
) == dpyinfo
)
9310 FRAME_XIC (f
) = NULL
;
9311 if (FRAME_XIC_FONTSET (f
))
9313 XFreeFontSet (FRAME_X_DISPLAY (f
), FRAME_XIC_FONTSET (f
));
9314 FRAME_XIC_FONTSET (f
) = NULL
;
9319 /* No need to call XCloseIM. */
9320 dpyinfo
->xim
= NULL
;
9321 XFree (dpyinfo
->xim_styles
);
9325 #endif /* HAVE_X11R6 */
9327 /* Open the connection to the XIM server on display DPYINFO.
9328 RESOURCE_NAME is the resource name Emacs uses. */
9331 xim_open_dpy (dpyinfo
, resource_name
)
9332 struct x_display_info
*dpyinfo
;
9333 char *resource_name
;
9338 xim
= XOpenIM (dpyinfo
->display
, dpyinfo
->xrdb
, resource_name
, EMACS_CLASS
);
9344 XIMCallback destroy
;
9347 /* Get supported styles and XIM values. */
9348 XGetIMValues (xim
, XNQueryInputStyle
, &dpyinfo
->xim_styles
, NULL
);
9351 destroy
.callback
= xim_destroy_callback
;
9352 destroy
.client_data
= (XPointer
)dpyinfo
;
9353 /* This isn't prototyped in OSF 5.0. */
9354 XSetIMValues (xim
, XNDestroyCallback
, &destroy
, NULL
);
9358 #else /* not USE_XIM */
9359 dpyinfo
->xim
= NULL
;
9360 #endif /* not USE_XIM */
9364 #ifdef HAVE_X11R6_XIM
9368 struct x_display_info
*dpyinfo
;
9369 char *resource_name
;
9372 /* XIM instantiate callback function, which is called whenever an XIM
9373 server is available. DISPLAY is teh display of the XIM.
9374 CLIENT_DATA contains a pointer to an xim_inst_t structure created
9375 when the callback was registered. */
9378 xim_instantiate_callback (display
, client_data
, call_data
)
9380 XPointer client_data
;
9383 struct xim_inst_t
*xim_inst
= (struct xim_inst_t
*) client_data
;
9384 struct x_display_info
*dpyinfo
= xim_inst
->dpyinfo
;
9386 /* We don't support multiple XIM connections. */
9390 xim_open_dpy (dpyinfo
, xim_inst
->resource_name
);
9392 /* Create XIC for the existing frames on the same display, as long
9393 as they have no XIC. */
9394 if (dpyinfo
->xim
&& dpyinfo
->reference_count
> 0)
9396 Lisp_Object tail
, frame
;
9399 FOR_EACH_FRAME (tail
, frame
)
9401 struct frame
*f
= XFRAME (frame
);
9403 if (FRAME_X_DISPLAY_INFO (f
) == xim_inst
->dpyinfo
)
9404 if (FRAME_XIC (f
) == NULL
)
9406 create_frame_xic (f
);
9407 if (FRAME_XIC_STYLE (f
) & XIMStatusArea
)
9408 xic_set_statusarea (f
);
9409 if (FRAME_XIC_STYLE (f
) & XIMPreeditPosition
)
9411 struct window
*w
= XWINDOW (f
->selected_window
);
9412 xic_set_preeditarea (w
, w
->cursor
.x
, w
->cursor
.y
);
9421 #endif /* HAVE_X11R6_XIM */
9424 /* Open a connection to the XIM server on display DPYINFO.
9425 RESOURCE_NAME is the resource name for Emacs. On X11R5, open the
9426 connection only at the first time. On X11R6, open the connection
9427 in the XIM instantiate callback function. */
9430 xim_initialize (dpyinfo
, resource_name
)
9431 struct x_display_info
*dpyinfo
;
9432 char *resource_name
;
9435 #ifdef HAVE_X11R6_XIM
9436 struct xim_inst_t
*xim_inst
;
9439 dpyinfo
->xim
= NULL
;
9440 xim_inst
= (struct xim_inst_t
*) xmalloc (sizeof (struct xim_inst_t
));
9441 xim_inst
->dpyinfo
= dpyinfo
;
9442 len
= strlen (resource_name
);
9443 xim_inst
->resource_name
= (char *) xmalloc (len
+ 1);
9444 bcopy (resource_name
, xim_inst
->resource_name
, len
+ 1);
9445 XRegisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
9446 resource_name
, EMACS_CLASS
,
9447 xim_instantiate_callback
,
9448 /* Fixme: This is XPointer in
9449 XFree86 but (XPointer *) on
9451 (XPointer
) xim_inst
);
9452 #else /* not HAVE_X11R6_XIM */
9453 dpyinfo
->xim
= NULL
;
9454 xim_open_dpy (dpyinfo
, resource_name
);
9455 #endif /* not HAVE_X11R6_XIM */
9457 #else /* not USE_XIM */
9458 dpyinfo
->xim
= NULL
;
9459 #endif /* not USE_XIM */
9463 /* Close the connection to the XIM server on display DPYINFO. */
9466 xim_close_dpy (dpyinfo
)
9467 struct x_display_info
*dpyinfo
;
9470 #ifdef HAVE_X11R6_XIM
9471 XUnregisterIMInstantiateCallback (dpyinfo
->display
, dpyinfo
->xrdb
,
9473 xim_instantiate_callback
, NULL
);
9474 #endif /* not HAVE_X11R6_XIM */
9475 XCloseIM (dpyinfo
->xim
);
9476 dpyinfo
->xim
= NULL
;
9477 XFree (dpyinfo
->xim_styles
);
9478 #endif /* USE_XIM */
9481 #endif /* not HAVE_X11R6_XIM */
9485 /* Calculate the absolute position in frame F
9486 from its current recorded position values and gravity. */
9489 x_calc_absolute_position (f
)
9493 int flags
= f
->output_data
.mac
->size_hint_flags
;
9497 /* Find the position of the outside upper-left corner of
9498 the inner window, with respect to the outer window. */
9499 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
9502 GetPort (&savePort
);
9503 SetPort (FRAME_MAC_WINDOW (f
));
9504 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
9505 LocalToGlobal (&pt
);
9509 /* Treat negative positions as relative to the leftmost bottommost
9510 position that fits on the screen. */
9511 if (flags
& XNegative
)
9512 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
9513 - 2 * f
->output_data
.mac
->border_width
- pt
.h
9515 + f
->output_data
.mac
->left_pos
);
9516 /* NTEMACS_TODO: Subtract menubar height? */
9517 if (flags
& YNegative
)
9518 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
9519 - 2 * f
->output_data
.mac
->border_width
- pt
.v
9521 + f
->output_data
.mac
->top_pos
);
9522 /* The left_pos and top_pos
9523 are now relative to the top and left screen edges,
9524 so the flags should correspond. */
9525 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9528 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9529 to really change the position, and 0 when calling from
9530 x_make_frame_visible (in that case, XOFF and YOFF are the current
9531 position values). It is -1 when calling from x_set_frame_parameters,
9532 which means, do adjust for borders but don't change the gravity. */
9535 x_set_offset (f
, xoff
, yoff
, change_gravity
)
9537 register int xoff
, yoff
;
9540 if (change_gravity
> 0)
9542 f
->output_data
.mac
->top_pos
= yoff
;
9543 f
->output_data
.mac
->left_pos
= xoff
;
9544 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
9546 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
9548 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
9549 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9551 x_calc_absolute_position (f
);
9554 x_wm_set_size_hint (f
, (long) 0, 0);
9556 MoveWindow (f
->output_data
.mac
->mWP
, xoff
+ 6, yoff
+ 42, false);
9561 /* Call this to change the size of frame F's x-window.
9562 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9563 for this size change and subsequent size changes.
9564 Otherwise we leave the window gravity unchanged. */
9567 x_set_window_size (f
, change_gravity
, cols
, rows
)
9572 int pixelwidth
, pixelheight
;
9574 check_frame_size (f
, &rows
, &cols
);
9575 f
->output_data
.mac
->vertical_scroll_bar_extra
9576 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
9578 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
9579 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
9580 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
9582 x_compute_fringe_widths (f
, 0);
9584 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
9585 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
9587 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
9588 x_wm_set_size_hint (f
, (long) 0, 0);
9590 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
9592 /* Now, strictly speaking, we can't be sure that this is accurate,
9593 but the window manager will get around to dealing with the size
9594 change request eventually, and we'll hear how it went when the
9595 ConfigureNotify event gets here.
9597 We could just not bother storing any of this information here,
9598 and let the ConfigureNotify event set everything up, but that
9599 might be kind of confusing to the Lisp code, since size changes
9600 wouldn't be reported in the frame parameters until some random
9601 point in the future when the ConfigureNotify event arrives.
9603 We pass 1 for DELAY since we can't run Lisp code inside of
9605 change_frame_size (f
, rows
, cols
, 0, 1, 0);
9606 PIXEL_WIDTH (f
) = pixelwidth
;
9607 PIXEL_HEIGHT (f
) = pixelheight
;
9609 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9610 receive in the ConfigureNotify event; if we get what we asked
9611 for, then the event won't cause the screen to become garbaged, so
9612 we have to make sure to do it here. */
9613 SET_FRAME_GARBAGED (f
);
9615 XFlush (FRAME_X_DISPLAY (f
));
9617 /* If cursor was outside the new size, mark it as off. */
9618 mark_window_cursors_off (XWINDOW (f
->root_window
));
9620 /* Clear out any recollection of where the mouse highlighting was,
9621 since it might be in a place that's outside the new frame size.
9622 Actually checking whether it is outside is a pain in the neck,
9623 so don't try--just let the highlighting be done afresh with new size. */
9624 cancel_mouse_face (f
);
9627 /* Mouse warping. */
9629 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
9632 x_set_mouse_position (f
, x
, y
)
9638 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
9639 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
9641 if (pix_x
< 0) pix_x
= 0;
9642 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
9644 if (pix_y
< 0) pix_y
= 0;
9645 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
9647 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
9650 /* Move the mouse to position pixel PIX_X, PIX_Y relative to frame F. */
9653 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
9657 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
9660 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
9661 0, 0, 0, 0, pix_x
, pix_y
);
9666 /* focus shifting, raising and lowering. */
9669 x_focus_on_frame (f
)
9672 #if 0 /* This proves to be unpleasant. */
9676 /* I don't think that the ICCCM allows programs to do things like this
9677 without the interaction of the window manager. Whatever you end up
9678 doing with this code, do it to x_unfocus_frame too. */
9679 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
9680 RevertToPointerRoot
, CurrentTime
);
9689 /* Look at the remarks in x_focus_on_frame. */
9690 if (FRAME_X_DISPLAY_INFO (f
)->x_focus_frame
== f
)
9691 XSetInputFocus (FRAME_X_DISPLAY (f
), PointerRoot
,
9692 RevertToPointerRoot
, CurrentTime
);
9696 /* Raise frame F. */
9702 if (f
->async_visible
)
9703 SelectWindow (FRAME_MAC_WINDOW (f
));
9706 /* Lower frame F. */
9712 if (f
->async_visible
)
9713 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
9717 XTframe_raise_lower (f
, raise_flag
)
9727 /* Change of visibility. */
9729 /* This tries to wait until the frame is really visible.
9730 However, if the window manager asks the user where to position
9731 the frame, this will return before the user finishes doing that.
9732 The frame will not actually be visible at that time,
9733 but it will become visible later when the window manager
9734 finishes with it. */
9737 x_make_frame_visible (f
)
9741 int original_top
, original_left
;
9745 if (! FRAME_VISIBLE_P (f
))
9747 /* We test FRAME_GARBAGED_P here to make sure we don't
9748 call x_set_offset a second time
9749 if we get to x_make_frame_visible a second time
9750 before the window gets really visible. */
9751 if (! FRAME_ICONIFIED_P (f
)
9752 && ! f
->output_data
.mac
->asked_for_visible
)
9753 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
9754 f
->output_data
.mac
->top_pos
, 0);
9756 f
->output_data
.mac
->asked_for_visible
= 1;
9758 ShowWindow (FRAME_MAC_WINDOW (f
));
9761 XFlush (FRAME_MAC_DISPLAY (f
));
9763 /* Synchronize to ensure Emacs knows the frame is visible
9764 before we do anything else. We do this loop with input not blocked
9765 so that incoming events are handled. */
9770 /* This must come after we set COUNT. */
9773 XSETFRAME (frame
, f
);
9775 /* Wait until the frame is visible. Process X events until a
9776 MapNotify event has been seen, or until we think we won't get a
9777 MapNotify at all.. */
9778 for (count
= input_signal_count
+ 10;
9779 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
9781 /* Force processing of queued events. */
9784 /* Machines that do polling rather than SIGIO have been
9785 observed to go into a busy-wait here. So we'll fake an
9786 alarm signal to let the handler know that there's something
9787 to be read. We used to raise a real alarm, but it seems
9788 that the handler isn't always enabled here. This is
9790 if (input_polling_used ())
9792 /* It could be confusing if a real alarm arrives while
9793 processing the fake one. Turn it off and let the
9794 handler reset it. */
9795 extern void poll_for_input_1
P_ ((void));
9796 int old_poll_suppress_count
= poll_suppress_count
;
9797 poll_suppress_count
= 1;
9798 poll_for_input_1 ();
9799 poll_suppress_count
= old_poll_suppress_count
;
9802 /* See if a MapNotify event has been processed. */
9803 FRAME_SAMPLE_VISIBILITY (f
);
9808 /* Change from mapped state to withdrawn state. */
9810 /* Make the frame visible (mapped and not iconified). */
9813 x_make_frame_invisible (f
)
9816 /* Don't keep the highlight on an invisible frame. */
9817 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
9818 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
9822 HideWindow (FRAME_MAC_WINDOW (f
));
9824 /* We can't distinguish this from iconification
9825 just by the event that we get from the server.
9826 So we can't win using the usual strategy of letting
9827 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9828 and synchronize with the server to make sure we agree. */
9830 FRAME_ICONIFIED_P (f
) = 0;
9831 f
->async_visible
= 0;
9832 f
->async_iconified
= 0;
9837 /* Change window state from mapped to iconified. */
9843 #if 0 /* MAC_TODO: really no iconify on Mac */
9847 /* Don't keep the highlight on an invisible frame. */
9848 if (FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
9849 FRAME_X_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
9851 if (f
->async_iconified
)
9856 FRAME_SAMPLE_VISIBILITY (f
);
9858 type
= x_icon_type (f
);
9860 x_bitmap_icon (f
, type
);
9862 #ifdef USE_X_TOOLKIT
9864 if (! FRAME_VISIBLE_P (f
))
9866 if (! EQ (Vx_no_window_manager
, Qt
))
9867 x_wm_set_window_state (f
, IconicState
);
9868 /* This was XtPopup, but that did nothing for an iconified frame. */
9869 XtMapWidget (f
->output_data
.x
->widget
);
9870 /* The server won't give us any event to indicate
9871 that an invisible frame was changed to an icon,
9872 so we have to record it here. */
9875 f
->async_iconified
= 1;
9876 f
->async_visible
= 0;
9881 result
= XIconifyWindow (FRAME_X_DISPLAY (f
),
9882 XtWindow (f
->output_data
.x
->widget
),
9883 DefaultScreen (FRAME_X_DISPLAY (f
)));
9887 error ("Can't notify window manager of iconification");
9889 f
->async_iconified
= 1;
9890 f
->async_visible
= 0;
9894 XFlush (FRAME_X_DISPLAY (f
));
9896 #else /* not USE_X_TOOLKIT */
9898 /* Make sure the X server knows where the window should be positioned,
9899 in case the user deiconifies with the window manager. */
9900 if (! FRAME_VISIBLE_P (f
) && !FRAME_ICONIFIED_P (f
))
9901 x_set_offset (f
, f
->output_data
.x
->left_pos
, f
->output_data
.x
->top_pos
, 0);
9903 /* Since we don't know which revision of X we're running, we'll use both
9904 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
9906 /* X11R4: send a ClientMessage to the window manager using the
9907 WM_CHANGE_STATE type. */
9911 message
.xclient
.window
= FRAME_X_WINDOW (f
);
9912 message
.xclient
.type
= ClientMessage
;
9913 message
.xclient
.message_type
= FRAME_X_DISPLAY_INFO (f
)->Xatom_wm_change_state
;
9914 message
.xclient
.format
= 32;
9915 message
.xclient
.data
.l
[0] = IconicState
;
9917 if (! XSendEvent (FRAME_X_DISPLAY (f
),
9918 DefaultRootWindow (FRAME_X_DISPLAY (f
)),
9920 SubstructureRedirectMask
| SubstructureNotifyMask
,
9923 UNBLOCK_INPUT_RESIGNAL
;
9924 error ("Can't notify window manager of iconification");
9928 /* X11R3: set the initial_state field of the window manager hints to
9930 x_wm_set_window_state (f
, IconicState
);
9932 if (!FRAME_VISIBLE_P (f
))
9934 /* If the frame was withdrawn, before, we must map it. */
9935 XMapRaised (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
));
9938 f
->async_iconified
= 1;
9939 f
->async_visible
= 0;
9941 XFlush (FRAME_X_DISPLAY (f
));
9943 #endif /* not USE_X_TOOLKIT */
9947 /* Destroy the X window of frame F. */
9950 x_destroy_window (f
)
9953 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
9957 DisposeWindow (FRAME_MAC_WINDOW (f
));
9959 free_frame_menubar (f
);
9960 free_frame_faces (f
);
9962 xfree (f
->output_data
.mac
);
9963 f
->output_data
.mac
= 0;
9964 if (f
== dpyinfo
->x_focus_frame
)
9965 dpyinfo
->x_focus_frame
= 0;
9966 if (f
== dpyinfo
->x_focus_event_frame
)
9967 dpyinfo
->x_focus_event_frame
= 0;
9968 if (f
== dpyinfo
->x_highlight_frame
)
9969 dpyinfo
->x_highlight_frame
= 0;
9971 dpyinfo
->reference_count
--;
9973 if (f
== dpyinfo
->mouse_face_mouse_frame
)
9975 dpyinfo
->mouse_face_beg_row
9976 = dpyinfo
->mouse_face_beg_col
= -1;
9977 dpyinfo
->mouse_face_end_row
9978 = dpyinfo
->mouse_face_end_col
= -1;
9979 dpyinfo
->mouse_face_window
= Qnil
;
9980 dpyinfo
->mouse_face_deferred_gc
= 0;
9981 dpyinfo
->mouse_face_mouse_frame
= 0;
9987 /* Setting window manager hints. */
9989 /* Set the normal size hints for the window manager, for frame F.
9990 FLAGS is the flags word to use--or 0 meaning preserve the flags
9991 that the window now has.
9992 If USER_POSITION is nonzero, we set the USPosition
9993 flag (this is useful when FLAGS is 0). */
9996 x_wm_set_size_hint (f
, flags
, user_position
)
10001 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
10002 XSizeHints size_hints
;
10004 #ifdef USE_X_TOOLKIT
10007 Dimension widget_width
, widget_height
;
10008 Window window
= XtWindow (f
->output_data
.x
->widget
);
10009 #else /* not USE_X_TOOLKIT */
10010 Window window
= FRAME_X_WINDOW (f
);
10011 #endif /* not USE_X_TOOLKIT */
10013 /* Setting PMaxSize caused various problems. */
10014 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
10016 size_hints
.x
= f
->output_data
.x
->left_pos
;
10017 size_hints
.y
= f
->output_data
.x
->top_pos
;
10019 #ifdef USE_X_TOOLKIT
10020 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
10021 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
10022 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
10023 size_hints
.height
= widget_height
;
10024 size_hints
.width
= widget_width
;
10025 #else /* not USE_X_TOOLKIT */
10026 size_hints
.height
= PIXEL_HEIGHT (f
);
10027 size_hints
.width
= PIXEL_WIDTH (f
);
10028 #endif /* not USE_X_TOOLKIT */
10030 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
10031 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
10032 size_hints
.max_width
10033 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
10034 size_hints
.max_height
10035 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
10037 /* Calculate the base and minimum sizes.
10039 (When we use the X toolkit, we don't do it here.
10040 Instead we copy the values that the widgets are using, below.) */
10041 #ifndef USE_X_TOOLKIT
10043 int base_width
, base_height
;
10044 int min_rows
= 0, min_cols
= 0;
10046 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
10047 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
10049 check_frame_size (f
, &min_rows
, &min_cols
);
10051 /* The window manager uses the base width hints to calculate the
10052 current number of rows and columns in the frame while
10053 resizing; min_width and min_height aren't useful for this
10054 purpose, since they might not give the dimensions for a
10055 zero-row, zero-column frame.
10057 We use the base_width and base_height members if we have
10058 them; otherwise, we set the min_width and min_height members
10059 to the size for a zero x zero frame. */
10062 size_hints
.flags
|= PBaseSize
;
10063 size_hints
.base_width
= base_width
;
10064 size_hints
.base_height
= base_height
;
10065 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
10066 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
10068 size_hints
.min_width
= base_width
;
10069 size_hints
.min_height
= base_height
;
10073 /* If we don't need the old flags, we don't need the old hint at all. */
10076 size_hints
.flags
|= flags
;
10079 #endif /* not USE_X_TOOLKIT */
10082 XSizeHints hints
; /* Sometimes I hate X Windows... */
10083 long supplied_return
;
10087 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
10090 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
10093 #ifdef USE_X_TOOLKIT
10094 size_hints
.base_height
= hints
.base_height
;
10095 size_hints
.base_width
= hints
.base_width
;
10096 size_hints
.min_height
= hints
.min_height
;
10097 size_hints
.min_width
= hints
.min_width
;
10101 size_hints
.flags
|= flags
;
10106 if (hints
.flags
& PSize
)
10107 size_hints
.flags
|= PSize
;
10108 if (hints
.flags
& PPosition
)
10109 size_hints
.flags
|= PPosition
;
10110 if (hints
.flags
& USPosition
)
10111 size_hints
.flags
|= USPosition
;
10112 if (hints
.flags
& USSize
)
10113 size_hints
.flags
|= USSize
;
10117 #ifndef USE_X_TOOLKIT
10122 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
10123 size_hints
.flags
|= PWinGravity
;
10127 size_hints
.flags
&= ~ PPosition
;
10128 size_hints
.flags
|= USPosition
;
10130 #endif /* PWinGravity */
10133 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10135 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
10137 #endif /* MACTODO */
10140 #if 0 /* MACTODO: hide application instead of iconify? */
10141 /* Used for IconicState or NormalState */
10144 x_wm_set_window_state (f
, state
)
10148 #ifdef USE_X_TOOLKIT
10151 XtSetArg (al
[0], XtNinitialState
, state
);
10152 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10153 #else /* not USE_X_TOOLKIT */
10154 Window window
= FRAME_X_WINDOW (f
);
10156 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
10157 f
->output_data
.x
->wm_hints
.initial_state
= state
;
10159 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10160 #endif /* not USE_X_TOOLKIT */
10164 x_wm_set_icon_pixmap (f
, pixmap_id
)
10168 Pixmap icon_pixmap
;
10170 #ifndef USE_X_TOOLKIT
10171 Window window
= FRAME_X_WINDOW (f
);
10176 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
10177 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
10181 /* It seems there is no way to turn off use of an icon pixmap.
10182 The following line does it, only if no icon has yet been created,
10183 for some window managers. But with mwm it crashes.
10184 Some people say it should clear the IconPixmapHint bit in this case,
10185 but that doesn't work, and the X consortium said it isn't the
10186 right thing at all. Since there is no way to win,
10187 best to explicitly give up. */
10189 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
10195 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
10199 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
10200 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
10203 #else /* not USE_X_TOOLKIT */
10205 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
10206 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10208 #endif /* not USE_X_TOOLKIT */
10214 x_wm_set_icon_position (f
, icon_x
, icon_y
)
10216 int icon_x
, icon_y
;
10218 #if 0 /* MAC_TODO: no icons on Mac */
10219 #ifdef USE_X_TOOLKIT
10220 Window window
= XtWindow (f
->output_data
.x
->widget
);
10222 Window window
= FRAME_X_WINDOW (f
);
10225 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
10226 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
10227 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
10229 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
10234 /***********************************************************************
10236 ***********************************************************************/
10238 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
10241 x_get_font_info (f
, font_idx
)
10245 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
10248 /* the global font name table */
10249 char **font_name_table
= NULL
;
10250 int font_name_table_size
= 0;
10251 int font_name_count
= 0;
10253 /* compare two strings ignoring case */
10255 stricmp (const char *s
, const char *t
)
10257 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
10260 return tolower (*s
) - tolower (*t
);
10263 /* compare two strings ignoring case and handling wildcard */
10265 wildstrieq (char *s1
, char *s2
)
10267 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
10270 return stricmp (s1
, s2
) == 0;
10273 /* Assume parameter 1 is fully qualified, no wildcards. */
10275 mac_font_pattern_match (fontname
, pattern
)
10279 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
10280 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
10283 /* Copy fontname so we can modify it during comparison. */
10284 strcpy (font_name_copy
, fontname
);
10289 /* Turn pattern into a regexp and do a regexp match. */
10290 for (; *pattern
; pattern
++)
10292 if (*pattern
== '?')
10294 else if (*pattern
== '*')
10305 return (fast_c_string_match_ignore_case (build_string (regex
),
10306 font_name_copy
) >= 0);
10309 /* Two font specs are considered to match if their foundry, family,
10310 weight, slant, and charset match. */
10312 mac_font_match (char *mf
, char *xf
)
10314 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
10315 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
10317 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10318 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
10319 return mac_font_pattern_match (mf
, xf
);
10321 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
10322 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
10323 return mac_font_pattern_match (mf
, xf
);
10325 return (wildstrieq (m_foundry
, x_foundry
)
10326 && wildstrieq (m_family
, x_family
)
10327 && wildstrieq (m_weight
, x_weight
)
10328 && wildstrieq (m_slant
, x_slant
)
10329 && wildstrieq (m_charset
, x_charset
))
10330 || mac_font_pattern_match (mf
, xf
);
10335 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
10337 char foundry
[32], family
[32], cs
[32];
10338 char xf
[255], *result
, *p
;
10340 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
10342 strcpy(foundry
, "Apple");
10343 strcpy(family
, name
);
10345 switch (scriptcode
)
10347 case smTradChinese
:
10348 strcpy(cs
, "big5-0");
10350 case smSimpChinese
:
10351 strcpy(cs
, "gb2312.1980-0");
10354 strcpy(cs
, "jisx0208.1983-sjis");
10357 /* Each Apple Japanese font is entered into the font table
10358 twice: once as a jisx0208.1983-sjis font and once as a
10359 jisx0201.1976-0 font. The latter can be used to display
10360 the ascii charset and katakana-jisx0201 charset. A
10361 negative script code signals that the name of this latter
10362 font is being built. */
10363 strcpy(cs
, "jisx0201.1976-0");
10366 strcpy(cs
, "ksc5601.1989-0");
10369 strcpy(cs
, "mac-roman");
10374 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
10375 foundry
, family
, style
& bold
? "bold" : "medium",
10376 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
10378 result
= (char *) xmalloc (strlen (xf
) + 1);
10379 strcpy (result
, xf
);
10380 for (p
= result
; *p
; p
++)
10386 /* Convert an X font spec to the corresponding mac font name, which
10387 can then be passed to GetFNum after conversion to a Pascal string.
10388 For ordinary Mac fonts, this should just be their names, like
10389 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
10390 collection contain their charset designation in their names, like
10391 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
10392 names are handled accordingly. */
10394 x_font_name_to_mac_font_name (char *xf
, char *mf
)
10396 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
10400 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10401 foundry
, family
, weight
, slant
, cs
) != 5 &&
10402 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10403 foundry
, family
, weight
, slant
, cs
) != 5)
10406 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
10407 || strcmp (cs
, "jisx0208.1983-sjis") == 0
10408 || strcmp (cs
, "jisx0201.1976-0") == 0
10409 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
10410 strcpy(mf
, family
);
10412 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
10416 /* Sets up the table font_name_table to contain the list of all
10417 monospace fonts in the system the first time the table is used so
10418 that the Resource Manager need not be accessed every time this
10419 information is needed. */
10422 init_font_name_table ()
10425 SInt16 fontnum
, old_fontnum
;
10426 int num_mac_fonts
= CountResources('FOND');
10428 Handle font_handle
, font_handle_2
;
10429 short id
, scriptcode
;
10432 struct FontAssoc
*fat
;
10433 struct AsscEntry
*assc_entry
;
10435 GetPort (&port
); /* save the current font number used */
10436 old_fontnum
= port
->txFont
;
10438 for (i
= 1; i
<= num_mac_fonts
; i
++) /* loop to get all available fonts */
10440 font_handle
= GetIndResource ('FOND', i
);
10444 GetResInfo (font_handle
, &id
, &type
, name
);
10445 GetFNum (name
, &fontnum
);
10450 TextFont (fontnum
);
10451 scriptcode
= FontToScript (fontnum
);
10454 HLock (font_handle
);
10456 if (GetResourceSizeOnDisk (font_handle
) >= sizeof (struct FamRec
))
10458 fat
= (struct FontAssoc
*) (*font_handle
10459 + sizeof (struct FamRec
));
10460 assc_entry
= (struct AsscEntry
*) (*font_handle
10461 + sizeof (struct FamRec
)
10462 + sizeof (struct FontAssoc
));
10464 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
10466 if (font_name_table_size
== 0)
10468 font_name_table_size
= 16;
10469 font_name_table
= (char **)
10470 xmalloc (font_name_table_size
* sizeof (char *));
10472 else if (font_name_count
>= font_name_table_size
||
10473 /* fonts in Japanese scripts require two
10475 scriptcode
== smJapanese
&&
10476 font_name_count
+ 1 >= font_name_table_size
)
10478 font_name_table_size
+= 16;
10479 font_name_table
= (char **)
10480 xrealloc (font_name_table
,
10481 font_name_table_size
* sizeof (char *));
10483 font_name_table
[font_name_count
++]
10484 = mac_to_x_fontname (name
,
10485 assc_entry
->fontSize
,
10486 assc_entry
->fontStyle
,
10488 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts
10489 are contained in Apple Japanese (SJIS) font. */
10490 if (smJapanese
== scriptcode
)
10492 font_name_table
[font_name_count
++]
10493 = mac_to_x_fontname (name
,
10494 assc_entry
->fontSize
,
10495 assc_entry
->fontStyle
,
10501 HUnlock (font_handle
);
10502 font_handle_2
= GetNextFOND (font_handle
);
10503 ReleaseResource (font_handle
);
10504 font_handle
= font_handle_2
;
10506 while (ResError () == noErr
&& font_handle
);
10509 TextFont (old_fontnum
);
10513 /* Return a list of at most MAXNAMES font specs matching the one in
10514 PATTERN. Note that each '*' in the PATTERN matches exactly one
10515 field of the font spec, unlike X in which an '*' in a font spec can
10516 match a number of fields. The result is in the Mac implementation
10517 all fonts must be specified by a font spec with all 13 fields
10518 (although many of these can be "*'s"). */
10521 x_list_fonts (struct frame
*f
,
10522 Lisp_Object pattern
,
10527 Lisp_Object newlist
= Qnil
;
10530 struct gcpro gcpro1
, gcpro2
;
10532 if (font_name_table
== NULL
) /* Initialize when first used. */
10533 init_font_name_table ();
10535 ptnstr
= XSTRING (pattern
)->data
;
10537 GCPRO2 (pattern
, newlist
);
10539 /* Scan and matching bitmap fonts. */
10540 for (i
= 0; i
< font_name_count
; i
++)
10542 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
10544 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
10547 if (n_fonts
>= maxnames
)
10552 /* MAC_TODO: add code for matching outline fonts here */
10562 /* Check that FONT is valid on frame F. It is if it can be found in
10566 x_check_font (f
, font
)
10571 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
10573 xassert (font
!= NULL
);
10575 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10576 if (dpyinfo
->font_table
[i
].name
10577 && font
== dpyinfo
->font_table
[i
].font
)
10580 xassert (i
< dpyinfo
->n_fonts
);
10583 #endif /* GLYPH_DEBUG != 0 */
10586 /* Set *W to the minimum width, *H to the minimum font height of FONT.
10587 Note: There are (broken) X fonts out there with invalid XFontStruct
10588 min_bounds contents. For example, handa@etl.go.jp reports that
10589 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
10590 have font->min_bounds.width == 0. */
10593 x_font_min_bounds (font
, w
, h
)
10594 MacFontStruct
*font
;
10597 *h
= FONT_HEIGHT (font
);
10598 *w
= font
->min_bounds
.width
;
10600 /* Try to handle the case where FONT->min_bounds has invalid
10601 contents. Since the only font known to have invalid min_bounds
10602 is fixed-width, use max_bounds if min_bounds seems to be invalid. */
10604 *w
= font
->max_bounds
.width
;
10608 /* Compute the smallest character width and smallest font height over
10609 all fonts available on frame F. Set the members smallest_char_width
10610 and smallest_font_height in F's x_display_info structure to
10611 the values computed. Value is non-zero if smallest_font_height or
10612 smallest_char_width become smaller than they were before. */
10615 x_compute_min_glyph_bounds (f
)
10619 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10620 MacFontStruct
*font
;
10621 int old_width
= dpyinfo
->smallest_char_width
;
10622 int old_height
= dpyinfo
->smallest_font_height
;
10624 dpyinfo
->smallest_font_height
= 100000;
10625 dpyinfo
->smallest_char_width
= 100000;
10627 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10628 if (dpyinfo
->font_table
[i
].name
)
10630 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
10633 font
= (MacFontStruct
*) fontp
->font
;
10634 xassert (font
!= (MacFontStruct
*) ~0);
10635 x_font_min_bounds (font
, &w
, &h
);
10637 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
10638 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
10641 xassert (dpyinfo
->smallest_char_width
> 0
10642 && dpyinfo
->smallest_font_height
> 0);
10644 return (dpyinfo
->n_fonts
== 1
10645 || dpyinfo
->smallest_char_width
< old_width
10646 || dpyinfo
->smallest_font_height
< old_height
);
10650 /* Determine whether given string is a fully-specified XLFD: all 14
10651 fields are present, none is '*'. */
10654 is_fully_specified_xlfd (char *p
)
10662 for (i
= 0; i
< 13; i
++)
10664 q
= strchr (p
+ 1, '-');
10667 if (q
- p
== 2 && *(p
+ 1) == '*')
10672 if (strchr (p
+ 1, '-') != NULL
)
10675 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
10682 const int kDefaultFontSize
= 9;
10685 /* MacLoadQueryFont creates and returns an internal representation for
10686 a font in a MacFontStruct struct (similar in function to
10687 XLoadQueryFont in X). There is really no concept corresponding to
10688 "loading" a font on the Mac. But we check its existence and find
10689 the font number and all other information for it and store them in
10690 the returned MacFontStruct. */
10692 static MacFontStruct
*
10693 XLoadQueryFont (Display
*dpy
, char *fontname
)
10695 int i
, size
, is_two_byte_font
, char_width
;
10698 SInt16 old_fontnum
, old_fontsize
;
10699 Style old_fontface
;
10702 Style fontface
= normal
;
10703 MacFontStruct
*font
;
10704 FontInfo the_fontinfo
;
10705 char s_weight
[7], c_slant
;
10707 if (is_fully_specified_xlfd (fontname
))
10711 for (i
= 0; i
< font_name_count
; i
++)
10712 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
10715 if (i
>= font_name_count
)
10718 name
= font_name_table
[i
];
10721 GetPort (&port
); /* save the current font number used */
10722 old_fontnum
= port
->txFont
;
10723 old_fontsize
= port
->txSize
;
10724 old_fontface
= port
->txFace
;
10726 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
10727 size
= kDefaultFontSize
;
10729 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
10730 if (strcmp (s_weight
, "bold") == 0)
10733 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
10734 if (c_slant
== 'i')
10735 fontface
|= italic
;
10737 x_font_name_to_mac_font_name (name
, mfontname
);
10738 c2pstr (mfontname
);
10739 GetFNum (mfontname
, &fontnum
);
10743 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
10745 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
10746 bcopy (name
, font
->fontname
, strlen (name
) + 1);
10748 font
->mac_fontnum
= fontnum
;
10749 font
->mac_fontsize
= size
;
10750 font
->mac_fontface
= fontface
;
10751 font
->mac_scriptcode
= FontToScript (fontnum
);
10753 /* Apple Japanese (SJIS) font is listed as both
10754 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
10755 (Roman script) in init_font_name_table(). The latter should be
10756 treated as a one-byte font. */
10761 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
10763 && 0 == strcmp (cs
, "jisx0201.1976-0"))
10764 font
->mac_scriptcode
= smRoman
;
10767 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
10768 font
->mac_scriptcode
== smTradChinese
||
10769 font
->mac_scriptcode
== smSimpChinese
||
10770 font
->mac_scriptcode
== smKorean
;
10772 TextFont (fontnum
);
10774 TextFace (fontface
);
10776 GetFontInfo (&the_fontinfo
);
10778 font
->ascent
= the_fontinfo
.ascent
;
10779 font
->descent
= the_fontinfo
.descent
;
10781 font
->min_byte1
= 0;
10782 if (is_two_byte_font
)
10783 font
->max_byte1
= 1;
10785 font
->max_byte1
= 0;
10786 font
->min_char_or_byte2
= 0x20;
10787 font
->max_char_or_byte2
= 0xff;
10789 if (is_two_byte_font
)
10791 /* Use the width of an "ideographic space" of that font because
10792 the_fontinfo.widMax returns the wrong width for some fonts. */
10793 switch (font
->mac_scriptcode
)
10796 char_width
= StringWidth("\p\x81\x40");
10798 case smTradChinese
:
10799 char_width
= StringWidth("\p\xa1\x40");
10801 case smSimpChinese
:
10802 char_width
= StringWidth("\p\xa1\xa1");
10805 char_width
= StringWidth("\p\xa1\xa1");
10810 /* Do this instead of use the_fontinfo.widMax, which incorrectly
10811 returns 15 for 12-point Monaco! */
10812 char_width
= CharWidth ('m');
10814 font
->max_bounds
.rbearing
= char_width
;
10815 font
->max_bounds
.lbearing
= 0;
10816 font
->max_bounds
.width
= char_width
;
10817 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
10818 font
->max_bounds
.descent
= the_fontinfo
.descent
;
10820 font
->min_bounds
= font
->max_bounds
;
10822 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
10823 font
->per_char
= NULL
;
10826 font
->per_char
= (XCharStruct
*)
10827 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
10831 for (c
= 0x20; c
<= 0xff; c
++)
10833 font
->per_char
[c
- 0x20] = font
->max_bounds
;
10834 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
10839 TextFont (old_fontnum
); /* restore previous font number, size and face */
10840 TextSize (old_fontsize
);
10841 TextFace (old_fontface
);
10847 /* Load font named FONTNAME of the size SIZE for frame F, and return a
10848 pointer to the structure font_info while allocating it dynamically.
10849 If SIZE is 0, load any size of font.
10850 If loading is failed, return NULL. */
10853 x_load_font (f
, fontname
, size
)
10855 register char *fontname
;
10858 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
10859 Lisp_Object font_names
;
10861 /* Get a list of all the fonts that match this name. Once we
10862 have a list of matching fonts, we compare them against the fonts
10863 we already have by comparing names. */
10864 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
10866 if (!NILP (font_names
))
10871 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10872 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
10873 if (dpyinfo
->font_table
[i
].name
10874 && (!strcmp (dpyinfo
->font_table
[i
].name
,
10875 XSTRING (XCAR (tail
))->data
)
10876 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
10877 XSTRING (XCAR (tail
))->data
)))
10878 return (dpyinfo
->font_table
+ i
);
10881 /* Load the font and add it to the table. */
10884 struct MacFontStruct
*font
;
10885 struct font_info
*fontp
;
10886 unsigned long value
;
10889 /* If we have found fonts by x_list_font, load one of them. If
10890 not, we still try to load a font by the name given as FONTNAME
10891 because XListFonts (called in x_list_font) of some X server has
10892 a bug of not finding a font even if the font surely exists and
10893 is loadable by XLoadQueryFont. */
10894 if (size
> 0 && !NILP (font_names
))
10895 fontname
= (char *) XSTRING (XCAR (font_names
))->data
;
10897 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
10901 /* Find a free slot in the font table. */
10902 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
10903 if (dpyinfo
->font_table
[i
].name
== NULL
)
10906 /* If no free slot found, maybe enlarge the font table. */
10907 if (i
== dpyinfo
->n_fonts
10908 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
10911 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
10912 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
10913 dpyinfo
->font_table
10914 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
10917 fontp
= dpyinfo
->font_table
+ i
;
10918 if (i
== dpyinfo
->n_fonts
)
10919 ++dpyinfo
->n_fonts
;
10921 /* Now fill in the slots of *FONTP. */
10923 fontp
->font
= font
;
10924 fontp
->font_idx
= i
;
10925 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
10926 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
10928 fontp
->full_name
= fontp
->name
;
10930 fontp
->size
= font
->max_bounds
.width
;
10931 fontp
->height
= FONT_HEIGHT (font
);
10933 /* For some font, ascent and descent in max_bounds field is
10934 larger than the above value. */
10935 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
10936 if (max_height
> fontp
->height
)
10937 fontp
->height
= max_height
;
10940 /* The slot `encoding' specifies how to map a character
10941 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
10942 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
10943 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
10944 2:0xA020..0xFF7F). For the moment, we don't know which charset
10945 uses this font. So, we set information in fontp->encoding[1]
10946 which is never used by any charset. If mapping can't be
10947 decided, set FONT_ENCODING_NOT_DECIDED. */
10948 if (font
->mac_scriptcode
== smJapanese
)
10949 fontp
->encoding
[1] = 4;
10953 = (font
->max_byte1
== 0
10955 ? (font
->min_char_or_byte2
< 0x80
10956 ? (font
->max_char_or_byte2
< 0x80
10957 ? 0 /* 0x20..0x7F */
10958 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
10959 : 1) /* 0xA0..0xFF */
10961 : (font
->min_byte1
< 0x80
10962 ? (font
->max_byte1
< 0x80
10963 ? (font
->min_char_or_byte2
< 0x80
10964 ? (font
->max_char_or_byte2
< 0x80
10965 ? 0 /* 0x2020..0x7F7F */
10966 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
10967 : 3) /* 0x20A0..0x7FFF */
10968 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
10969 : (font
->min_char_or_byte2
< 0x80
10970 ? (font
->max_char_or_byte2
< 0x80
10971 ? 2 /* 0xA020..0xFF7F */
10972 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
10973 : 1))); /* 0xA0A0..0xFFFF */
10976 #if 0 /* MAC_TODO: fill these out with more reasonably values */
10977 fontp
->baseline_offset
10978 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
10979 ? (long) value
: 0);
10980 fontp
->relative_compose
10981 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
10982 ? (long) value
: 0);
10983 fontp
->default_ascent
10984 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
10985 ? (long) value
: 0);
10987 fontp
->baseline_offset
= 0;
10988 fontp
->relative_compose
= 0;
10989 fontp
->default_ascent
= 0;
10992 /* Set global flag fonts_changed_p to non-zero if the font loaded
10993 has a character with a smaller width than any other character
10994 before, or if the font loaded has a smalle>r height than any
10995 other font loaded before. If this happens, it will make a
10996 glyph matrix reallocation necessary. */
10997 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
11004 /* Return a pointer to struct font_info of a font named FONTNAME for
11005 frame F. If no such font is loaded, return NULL. */
11008 x_query_font (f
, fontname
)
11010 register char *fontname
;
11012 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
11015 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
11016 if (dpyinfo
->font_table
[i
].name
11017 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
11018 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
11019 return (dpyinfo
->font_table
+ i
);
11024 /* Find a CCL program for a font specified by FONTP, and set the member
11025 `encoder' of the structure. */
11028 x_find_ccl_program (fontp
)
11029 struct font_info
*fontp
;
11031 Lisp_Object list
, elt
;
11033 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
11037 && STRINGP (XCAR (elt
))
11038 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
11044 struct ccl_program
*ccl
11045 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
11047 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
11050 fontp
->font_encoder
= ccl
;
11056 /***********************************************************************
11058 ***********************************************************************/
11060 #ifdef USE_X_TOOLKIT
11061 static XrmOptionDescRec emacs_options
[] = {
11062 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
11063 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
11065 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
11066 XrmoptionSepArg
, NULL
},
11067 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
11069 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11070 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11071 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
11072 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11073 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
11074 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
11075 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
11077 #endif /* USE_X_TOOLKIT */
11079 static int x_initialized
;
11081 #ifdef MULTI_KBOARD
11082 /* Test whether two display-name strings agree up to the dot that separates
11083 the screen number from the server number. */
11085 same_x_server (name1
, name2
)
11086 char *name1
, *name2
;
11088 int seen_colon
= 0;
11089 unsigned char *system_name
= XSTRING (Vsystem_name
)->data
;
11090 int system_name_length
= strlen (system_name
);
11091 int length_until_period
= 0;
11093 while (system_name
[length_until_period
] != 0
11094 && system_name
[length_until_period
] != '.')
11095 length_until_period
++;
11097 /* Treat `unix' like an empty host name. */
11098 if (! strncmp (name1
, "unix:", 5))
11100 if (! strncmp (name2
, "unix:", 5))
11102 /* Treat this host's name like an empty host name. */
11103 if (! strncmp (name1
, system_name
, system_name_length
)
11104 && name1
[system_name_length
] == ':')
11105 name1
+= system_name_length
;
11106 if (! strncmp (name2
, system_name
, system_name_length
)
11107 && name2
[system_name_length
] == ':')
11108 name2
+= system_name_length
;
11109 /* Treat this host's domainless name like an empty host name. */
11110 if (! strncmp (name1
, system_name
, length_until_period
)
11111 && name1
[length_until_period
] == ':')
11112 name1
+= length_until_period
;
11113 if (! strncmp (name2
, system_name
, length_until_period
)
11114 && name2
[length_until_period
] == ':')
11115 name2
+= length_until_period
;
11117 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
11121 if (seen_colon
&& *name1
== '.')
11125 && (*name1
== '.' || *name1
== '\0')
11126 && (*name2
== '.' || *name2
== '\0'));
11130 struct mac_display_info
*
11131 x_term_init (display_name
, xrm_option
, resource_name
)
11132 Lisp_Object display_name
;
11134 char *resource_name
;
11136 if (!x_initialized
)
11142 return &one_mac_display_info
;
11145 /* Set up use of X before we make the first connection. */
11147 static struct redisplay_interface x_redisplay_interface
=
11152 x_clear_end_of_line
,
11154 x_after_update_window_line
,
11155 x_update_window_begin
,
11156 x_update_window_end
,
11159 x_clear_mouse_face
,
11160 x_get_glyph_overhangs
,
11161 x_fix_overlapping_area
11165 /* The Mac Event loop code */
11167 #include <Events.h>
11168 #include <Quickdraw.h>
11169 #include <Balloons.h>
11170 #include <Devices.h>
11172 #include <Gestalt.h>
11174 #include <Processes.h>
11176 #include <ToolUtils.h>
11177 #include <TextUtils.h>
11178 #include <Dialogs.h>
11179 #include <Script.h>
11182 #include <TextEncodingConverter.h>
11183 #include <Resources.h>
11189 #define M_APPLE 128
11192 #define WINDOW_RESOURCE 128
11193 #define TERM_WINDOW_RESOURCE 129
11195 #define DEFAULT_NUM_COLS 80
11197 #define MIN_DOC_SIZE 64
11198 #define MAX_DOC_SIZE 32767
11200 /* sleep time for WaitNextEvent */
11201 #define WNE_SLEEP_AT_SUSPEND 10
11202 #define WNE_SLEEP_AT_RESUME 1
11204 /* true when cannot handle any Mac OS events */
11205 static int handling_window_update
= 0;
11207 /* the flag appl_is_suspended is used both for determining the sleep
11208 time to be passed to WaitNextEvent and whether the cursor should be
11209 drawn when updating the display. The cursor is turned off when
11210 Emacs is suspended. Redrawing it is unnecessary and what needs to
11211 be done depends on whether the cursor lies inside or outside the
11212 redraw region. So we might as well skip drawing it when Emacs is
11214 static Boolean app_is_suspended
= false;
11215 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11217 #define EXTRA_STACK_ALLOC (256 * 1024)
11219 #define ARGV_STRING_LIST_ID 129
11220 #define ABOUT_ALERT_ID 128
11221 #define RAM_TOO_LARGE_ALERT_ID 129
11223 Boolean terminate_flag
= false;
11225 /* true if using command key as meta key */
11226 Lisp_Object Vmac_command_key_is_meta
;
11228 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
11229 to this text encoding */
11230 int mac_keyboard_text_encoding
;
11231 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
11233 /* Set in term/mac-win.el to indicate that event loop can now generate
11234 drag and drop events. */
11235 Lisp_Object Qmac_ready_for_drag_n_drop
;
11237 Lisp_Object drag_and_drop_file_list
;
11239 Point saved_menu_event_location
;
11242 static void init_required_apple_events(void);
11243 static pascal OSErr
do_ae_open_application(const AppleEvent
*, AppleEvent
*, long);
11244 static pascal OSErr
do_ae_print_documents(const AppleEvent
*, AppleEvent
*, long);
11245 static pascal OSErr
do_ae_open_documents(AppleEvent
*, AppleEvent
*, long);
11246 static pascal OSErr
do_ae_quit_application(AppleEvent
*, AppleEvent
*, long);
11248 extern void init_emacs_passwd_dir ();
11249 extern int emacs_main (int, char **, char **);
11250 extern void check_alarm ();
11252 extern void initialize_applescript();
11253 extern void terminate_applescript();
11257 do_get_menus (void)
11259 Handle menubar_handle
;
11260 MenuHandle menu_handle
;
11262 menubar_handle
= GetNewMBar (128);
11263 if(menubar_handle
== NULL
)
11265 SetMenuBar (menubar_handle
);
11268 menu_handle
= GetMenuHandle (M_APPLE
);
11269 if(menu_handle
!= NULL
)
11270 AppendResMenu (menu_handle
,'DRVR');
11277 do_init_managers (void)
11279 InitGraf (&qd
.thePort
);
11281 FlushEvents (everyEvent
, 0);
11285 InitDialogs (NULL
);
11288 /* set up some extra stack space for use by emacs */
11289 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
11291 /* MaxApplZone must be called for AppleScript to execute more
11292 complicated scripts */
11299 do_check_ram_size (void)
11301 SInt32 physical_ram_size
, logical_ram_size
;
11303 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
11304 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
11305 || physical_ram_size
> 256 * 1024 * 1024
11306 || logical_ram_size
> 256 * 1024 * 1024)
11308 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
11315 do_window_update (WindowPtr win
)
11317 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11318 struct frame
*f
= mwp
->mFP
;
11322 if (f
->async_visible
== 0)
11324 f
->async_visible
= 1;
11325 f
->async_iconified
= 0;
11326 SET_FRAME_GARBAGED (f
);
11328 /* An update event is equivalent to MapNotify on X, so report
11329 visibility changes properly. */
11330 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
11331 /* Force a redisplay sooner or later to update the
11332 frame titles in case this is the second frame. */
11333 record_asynch_buffer_change ();
11338 handling_window_update
= 1;
11340 expose_frame (f
, 0, 0, 0, 0);
11342 handling_window_update
= 0;
11349 do_window_activate (WindowPtr win
)
11351 mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11352 struct frame
*f
= mwp
->mFP
;
11356 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11357 activate_scroll_bars (f
);
11362 do_window_deactivate (WindowPtr win
)
11364 mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
11365 struct frame
*f
= mwp
->mFP
;
11367 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11369 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11370 deactivate_scroll_bars (f
);
11377 mac_output
*mwp
= (mac_output
*) GetWRefCon (FrontWindow ());
11378 struct frame
*f
= mwp
->mFP
;
11380 SetCursor (&qd
.arrow
);
11384 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
11385 activate_scroll_bars (f
);
11388 app_is_suspended
= false;
11389 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
11395 mac_output
*mwp
= (mac_output
*) GetWRefCon (FrontWindow ());
11396 struct frame
*f
= mwp
->mFP
;
11398 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
11400 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
11401 deactivate_scroll_bars (f
);
11404 app_is_suspended
= true;
11405 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
11410 do_mouse_moved (Point mouse_pos
)
11412 WindowPtr wp
= FrontWindow ();
11413 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11416 GlobalToLocal (&mouse_pos
);
11418 note_mouse_movement (f
, &mouse_pos
);
11423 do_os_event (EventRecord
*erp
)
11425 switch((erp
->message
>> 24) & 0x000000FF)
11427 case suspendResumeMessage
:
11428 if((erp
->message
& resumeFlag
) == 1)
11434 case mouseMovedMessage
: /* never reached */
11435 do_mouse_moved (erp
->where
);
11441 do_events (EventRecord
*erp
)
11446 do_window_update ((WindowPtr
) erp
->message
);
11454 if ((erp
->modifiers
& activeFlag
) != 0)
11455 do_window_activate ((WindowPtr
) erp
->message
);
11457 do_window_deactivate ((WindowPtr
) erp
->message
);
11463 do_apple_menu (SInt16 menu_item
)
11466 SInt16 da_driver_refnum
;
11468 if (menu_item
== I_ABOUT
)
11469 NoteAlert (ABOUT_ALERT_ID
, NULL
);
11472 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
11473 da_driver_refnum
= OpenDeskAcc (item_name
);
11478 do_menu_choice (SInt32 menu_choice
)
11480 SInt16 menu_id
, menu_item
;
11482 menu_id
= HiWord (menu_choice
);
11483 menu_item
= LoWord (menu_choice
);
11491 do_apple_menu (menu_item
);
11496 WindowPtr wp
= FrontWindow ();
11497 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
11498 MenuHandle menu
= GetMenuHandle (menu_id
);
11503 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
11504 menubar_selection_callback (f
, refcon
);
11513 /* Handle drags in size box. Based on code contributed by Ben
11514 Mesander and IM - Window Manager A. */
11517 do_grow_window (WindowPtr w
, EventRecord
*e
)
11522 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11523 struct frame
*f
= mwp
->mFP
;
11525 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
11527 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
11529 /* see if it really changed size */
11530 if (grow_size
!= 0)
11532 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
11533 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
11535 x_set_window_size (f
, 0, columns
, rows
);
11540 /* Handle clicks in zoom box. Calculation of "standard state" based
11541 on code in IM - Window Manager A and code contributed by Ben
11542 Mesander. The standard state of an Emacs window is 80-characters
11543 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
11546 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
11549 Rect zoom_rect
, port_rect
;
11551 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
11552 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
11553 struct frame
*f
= mwp
->mFP
;
11555 GetPort (&save_port
);
11557 EraseRect (&(w
->portRect
)); /* erase to avoid flicker */
11558 if (zoom_in_or_out
== inZoomOut
)
11560 SetPt(&top_left
, w
->portRect
.left
, w
->portRect
.top
);
11561 LocalToGlobal (&top_left
);
11563 /* calculate height of window's title bar */
11564 w_title_height
= top_left
.v
- 1
11565 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight();
11567 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
11568 zoom_rect
= qd
.screenBits
.bounds
;
11569 zoom_rect
.top
+= w_title_height
;
11570 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
11572 zoom_rect
.right
= zoom_rect
.left
11573 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
11575 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
= zoom_rect
;
11578 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow());
11580 /* retrieve window size and update application values */
11581 port_rect
= w
->portRect
;
11582 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
11583 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
11584 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
11586 SetPort (save_port
);
11590 /* Intialize AppleEvent dispatcher table for the required events. */
11592 init_required_apple_events ()
11597 /* Make sure we have apple events before starting. */
11598 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
11602 if (!(result
& (1 << gestaltAppleEventsPresent
)))
11605 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
11606 NewAEEventHandlerProc ((AEEventHandlerProcPtr
) do_ae_open_application
),
11611 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
11612 NewAEEventHandlerProc ((AEEventHandlerProcPtr
) do_ae_open_documents
),
11617 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
11618 NewAEEventHandlerProc ((AEEventHandlerProcPtr
) do_ae_print_documents
),
11623 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
11624 NewAEEventHandlerProc ((AEEventHandlerProcPtr
) do_ae_quit_application
),
11631 /* Open Application Apple Event */
11632 static pascal OSErr
11633 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
11639 /* Defined in mac.c. */
11641 path_from_vol_dir_name (char *, int, short, long, char *);
11644 /* Called when we receive an AppleEvent with an ID of
11645 "kAEOpenDocuments". This routine gets the direct parameter,
11646 extracts the FSSpecs in it, and puts their names on a list. */
11647 static pascal OSErr
11648 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
11653 DescType actual_type
;
11656 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
11658 goto descriptor_error_exit
;
11660 /* Check to see that we got all of the required parameters from the
11661 event descriptor. For an 'odoc' event this should just be the
11663 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
11664 &actual_type
, (Ptr
) &keyword
,
11665 sizeof (keyword
), &actual_size
);
11666 /* No error means that we found some unused parameters.
11667 errAEDescNotFound means that there are no more parameters. If we
11668 get an error code other than that, flag it. */
11669 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
11671 err
= errAEEventNotHandled
;
11676 /* Got all the parameters we need. Now, go through the direct
11677 object list and parse it up. */
11679 long num_files_to_open
;
11681 err
= AECountItems (&the_desc
, &num_files_to_open
);
11686 /* AE file list is one based so just use that for indexing here. */
11687 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++) {
11689 Str255 path_name
, unix_path_name
;
11691 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
11692 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
11693 if (err
!= noErr
) break;
11695 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
11697 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
11698 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
11699 drag_and_drop_file_list
);
11705 /* Nuke the coerced file list in any case */
11706 err2
= AEDisposeDesc(&the_desc
);
11708 descriptor_error_exit
:
11709 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
11714 /* Print Document Apple Event */
11715 static pascal OSErr
11716 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
11718 return errAEEventNotHandled
;
11722 static pascal OSErr
11723 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
11725 /* FixMe: Do we need an unwind-protect or something here? And what
11726 do we do about unsaved files. Currently just forces quit rather
11727 than doing recursive callback to get user input. */
11729 terminate_flag
= true;
11731 /* Fkill_emacs doesn't return. We have to return. (TI) */
11738 profiler_exit_proc ()
11740 ProfilerDump ("\pEmacs.prof");
11745 /* These few functions implement Emacs as a normal Mac application
11746 (almost): set up the heap and the Toolbox, handle necessary
11747 system events plus a few simple menu events. They also set up
11748 Emacs's access to functions defined in the rest of this file.
11749 Emacs uses function hooks to perform all its terminal I/O. A
11750 complete list of these functions appear in termhooks.h. For what
11751 they do, read the comments there and see also w32term.c and
11752 xterm.c. What's noticeably missing here is the event loop, which
11753 is normally present in most Mac application. After performing the
11754 necessary Mac initializations, main passes off control to
11755 emacs_main (corresponding to main in emacs.c). Emacs_main calls
11756 mac_read_socket (defined further below) to read input. This is
11757 where WaitNextEvent is called to process Mac events. This is also
11758 where check_alarm in sysdep.c is called to simulate alarm signals.
11759 This makes the cursor jump back to its correct position after
11760 briefly jumping to that of the matching parenthesis, print useful
11761 hints and prompts in the minibuffer after the user stops typing for
11768 #if __profile__ /* is the profiler on? */
11769 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
11774 /* set creator and type for files created by MSL */
11775 _fcreator
= 'EMAx';
11779 do_init_managers ();
11783 do_check_ram_size ();
11785 init_emacs_passwd_dir ();
11789 initialize_applescript ();
11791 init_required_apple_events ();
11797 /* set up argv array from STR# resource */
11798 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
11802 /* free up AppleScript resources on exit */
11803 atexit (terminate_applescript
);
11805 #if __profile__ /* is the profiler on? */
11806 atexit (profiler_exit_proc
);
11809 /* 3rd param "envp" never used in emacs_main */
11810 (void) emacs_main (argc
, argv
, 0);
11813 /* Never reached - real exit in Fkill_emacs */
11818 /* Table for translating Mac keycode to X keysym values. Contributed
11819 by Sudhir Shenoy. */
11820 static unsigned char keycode_to_xkeysym_table
[] = {
11822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11827 0, '\xae' /* kp. */, 0, '\xaa' /* kp* */,
11828 0, '\xab' /* kp+ */, 0, '\x7f' /* kp_clr */,
11829 0, 0, 0, '\xaf' /* kp/ */,
11830 '\x8d' /* kp_ent */, 0, '\xad' /* kp- */, 0,
11832 0, '\xbd' /* kp= */, '\xb0' /* kp0 */, '\xb1' /* kp1 */,
11833 '\xb2' /* kp2 */, '\xb3' /* kp3 */, '\xb4' /* kp4 */, '\xb5' /* kp5 */,
11834 '\xb6' /* kp6 */, '\xb7' /* kp7 */, 0, '\xb8' /* kp8 */,
11835 '\xb9' /* kp9 */, 0, 0, 0,
11837 '\xc2' /* F5 */, '\xc3' /* F6 */, '\xc4' /* F7 */, '\xc0' /* F3 */,
11838 '\xc5' /* F8 */, '\xc6' /* F9 */, 0, '\xc8' /* F11 */,
11839 0, '\xca' /* F13 */, 0, '\xcb' /* F14 */,
11840 0, '\xc7' /* F10 */, 0, '\xc9' /* F12 */,
11842 0, '\xcc' /* F15 */, '\x9e' /* ins */, '\x95' /* home */,
11843 '\x9a' /* pgup */, '\x9f' /* del */, '\xc1' /* F4 */, '\x9c' /* end */,
11844 '\xbf' /* F2 */, '\x9b' /* pgdown */, '\xbe' /* F1 */, '\x51' /* left */,
11845 '\x53' /* right */, '\x54' /* down */, '\x52' /* up */, 0
11849 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
11851 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
11852 return *xKeySym
!= 0;
11855 /* Emacs calls this whenever it wants to read an input event from the
11858 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
11863 EventMask event_mask
;
11865 if (interrupt_input_blocked
)
11867 interrupt_input_pending
= 1;
11871 interrupt_input_pending
= 0;
11874 /* So people can tell when we have read the available input. */
11875 input_signal_count
++;
11880 /* Don't poll for events to process (specifically updateEvt) if
11881 window update currently already in progress. A call to redisplay
11882 (in do_window_update) can be preempted by another call to
11883 redisplay, causing blank regions to be left on the screen and the
11884 cursor to be left at strange places. */
11885 if (handling_window_update
)
11891 if (terminate_flag
)
11892 Fkill_emacs (make_number (1));
11894 /* It is necessary to set this (additional) argument slot of an
11895 event to nil because keyboard.c protects incompletely processed
11896 event from being garbage collected by placing them in the
11897 kbd_buffer_gcpro vector. */
11900 event_mask
= everyEvent
;
11901 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
11902 event_mask
-= highLevelEventMask
;
11904 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
) && numchars
> 0)
11910 WindowPtr window_ptr
= FrontWindow ();
11913 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
11914 && er
.what
== mouseUp
)
11916 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
11917 Point mouse_loc
= er
.where
;
11919 /* Convert to local coordinates of new window. */
11920 SetPort (window_ptr
);
11921 GlobalToLocal (&mouse_loc
);
11923 bufp
->code
= 0; /* only one mouse button */
11924 bufp
->kind
= scroll_bar_click
;
11925 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
11926 bufp
->part
= scroll_bar_handle
;
11927 bufp
->modifiers
= up_modifier
;
11928 bufp
->timestamp
= er
.when
* (1000 / 60);
11929 /* ticks to milliseconds */
11931 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
11932 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
11933 tracked_scroll_bar
->dragging
= Qnil
;
11934 mouse_tracking_in_progress
= mouse_tracking_none
;
11935 tracked_scroll_bar
= NULL
;
11942 part_code
= FindWindow (er
.where
, &window_ptr
);
11948 struct frame
*f
= ((mac_output
*)
11949 GetWRefCon (FrontWindow ()))->mFP
;
11950 saved_menu_event_location
= er
.where
;
11951 bufp
->kind
= menu_bar_activate_event
;
11952 XSETFRAME (bufp
->frame_or_window
, f
);
11960 if (window_ptr
!= FrontWindow ())
11961 SelectWindow (window_ptr
);
11964 int control_part_code
;
11966 struct mac_output
*mwp
= (mac_output
*)
11967 GetWRefCon (window_ptr
);
11968 Point mouse_loc
= er
.where
;
11970 /* convert to local coordinates of new window */
11971 SetPort (window_ptr
);
11972 GlobalToLocal (&mouse_loc
);
11973 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
11975 bufp
->code
= 0; /* only one mouse button */
11976 XSETINT (bufp
->x
, mouse_loc
.h
);
11977 XSETINT (bufp
->y
, mouse_loc
.v
);
11978 bufp
->timestamp
= er
.when
* (1000 / 60);
11979 /* ticks to milliseconds */
11981 if (control_part_code
!= 0)
11983 struct scroll_bar
*bar
= (struct scroll_bar
*)
11984 GetControlReference (ch
);
11985 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
11987 if (er
.what
== mouseDown
11988 && control_part_code
== kControlIndicatorPart
)
11990 mouse_tracking_in_progress
= mouse_tracking_scroll_bar
;
11991 tracked_scroll_bar
= bar
;
11995 mouse_tracking_in_progress
= mouse_tracking_none
;
11996 tracked_scroll_bar
= NULL
;
12001 bufp
->kind
= mouse_click
;
12002 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12003 if (er
.what
== mouseDown
)
12004 mouse_tracking_in_progress
= mouse_tracking_mouse_movement
;
12006 mouse_tracking_in_progress
= mouse_tracking_none
;
12012 bufp
->modifiers
= down_modifier
;
12015 bufp
->modifiers
= up_modifier
;
12026 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
12030 if (TrackGoAway (window_ptr
, er
.where
))
12032 bufp
->kind
= delete_window_event
;
12033 XSETFRAME (bufp
->frame_or_window
,
12034 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
12041 /* window resize handling added --ben */
12043 do_grow_window(window_ptr
, &er
);
12046 /* window zoom handling added --ben */
12049 if (TrackBox (window_ptr
, er
.where
, part_code
))
12050 do_zoom_window (window_ptr
, part_code
);
12068 int keycode
= (er
.message
& keyCodeMask
) >> 8;
12073 if (keycode
== 0x33) /* delete key (charCode translated to 0x8) */
12076 bufp
->kind
= ascii_keystroke
;
12078 else if (keycode_to_xkeysym (keycode
, &xkeysym
))
12080 bufp
->code
= 0xff00 | xkeysym
;
12081 bufp
->kind
= non_ascii_keystroke
;
12086 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12088 /* This code comes from Keyboard Resource, Appendix
12089 C of IM - Text. This is necessary since shift is
12090 ignored in KCHR table translation when option or
12091 command is pressed. */
12092 int new_modifiers
= er
.modifiers
& 0xf600;
12093 /* mask off option and command */
12094 int new_keycode
= keycode
| new_modifiers
;
12095 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
12096 unsigned long some_state
= 0;
12097 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
12098 &some_state
) & 0xff;
12101 bufp
->code
= er
.message
& charCodeMask
;
12102 bufp
->kind
= ascii_keystroke
;
12106 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
12107 convert non-ASCII characters typed at the Mac keyboard
12108 (presumed to be in the Mac Roman encoding) to iso-latin-1
12109 encoding before they are passed to Emacs. This enables the
12110 Mac keyboard to be used to enter non-ASCII iso-latin-1
12111 characters directly. */
12112 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
12113 && bufp
->kind
== ascii_keystroke
&& bufp
->code
>= 128)
12115 static TECObjectRef converter
= NULL
;
12116 OSStatus the_err
= noErr
;
12117 OSStatus convert_status
= noErr
;
12119 if (converter
== NULL
)
12121 the_err
= TECCreateConverter (&converter
,
12122 kTextEncodingMacRoman
,
12123 mac_keyboard_text_encoding
);
12124 current_mac_keyboard_text_encoding
= mac_keyboard_text_encoding
;
12126 else if (mac_keyboard_text_encoding
!= current_mac_keyboard_text_encoding
)
12128 /* Free the converter for the current encoding before
12129 creating a new one. */
12130 TECDisposeConverter (converter
);
12131 the_err
= TECCreateConverter (&converter
,
12132 kTextEncodingMacRoman
,
12133 mac_keyboard_text_encoding
);
12134 current_mac_keyboard_text_encoding
= mac_keyboard_text_encoding
;
12137 if (the_err
== noErr
)
12139 unsigned char ch
= bufp
->code
;
12140 ByteCount actual_input_length
, actual_output_length
;
12141 unsigned char outch
;
12143 convert_status
= TECConvertText (converter
, &ch
, 1,
12144 &actual_input_length
,
12146 &actual_output_length
);
12147 if (convert_status
== noErr
12148 && actual_input_length
== 1
12149 && actual_output_length
== 1)
12150 bufp
->code
= outch
;
12155 if (er
.modifiers
& shiftKey
)
12156 the_modifiers
|= shift_modifier
;
12157 if (er
.modifiers
& controlKey
)
12158 the_modifiers
|= ctrl_modifier
;
12159 /* use option or command key as meta depending on value of
12160 mac-command-key-is-meta */
12162 & (NILP (Vmac_command_key_is_meta
) ? optionKey
: cmdKey
))
12163 the_modifiers
|= meta_modifier
;
12164 bufp
->modifiers
= the_modifiers
;
12167 mac_output
*mwp
= (mac_output
*) GetWRefCon (FrontWindow ());
12168 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
12171 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
12178 case kHighLevelEvent
:
12179 drag_and_drop_file_list
= Qnil
;
12181 AEProcessAppleEvent(&er
);
12183 /* Build a drag_n_drop type event as is done in
12184 constuct_drag_n_drop in w32term.c. */
12185 if (!NILP (drag_and_drop_file_list
))
12191 wp
= FrontWindow ();
12195 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12197 bufp
->kind
= drag_n_drop
;
12199 bufp
->timestamp
= er
.when
* (1000 / 60);
12200 /* ticks to milliseconds */
12201 bufp
->modifiers
= 0;
12203 XSETINT (bufp
->x
, 0);
12204 XSETINT (bufp
->y
, 0);
12206 XSETFRAME (frame
, f
);
12207 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
12209 /* Regardless of whether Emacs was suspended or in the
12210 foreground, ask it to redraw its entire screen.
12211 Otherwise parts of the screen can be left in an
12212 inconsistent state. */
12214 InvalRect (&(wp
->portRect
));
12225 /* If the focus was just given to an autoraising frame,
12227 /* ??? This ought to be able to handle more than one such frame. */
12228 if (pending_autoraise_frame
)
12230 x_raise_frame (pending_autoraise_frame
);
12231 pending_autoraise_frame
= 0;
12234 check_alarm (); /* simulate the handling of a SIGALRM */
12237 static Point old_mouse_pos
= { -1, -1 };
12239 if (app_is_suspended
)
12241 old_mouse_pos
.h
= -1;
12242 old_mouse_pos
.v
= -1;
12247 WindowPtr wp
= FrontWindow ();
12248 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
12250 struct scroll_bar
*sb
;
12253 GetMouse (&mouse_pos
);
12255 if (!EqualPt (mouse_pos
, old_mouse_pos
))
12257 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
12258 && tracked_scroll_bar
)
12259 x_scroll_bar_note_movement (tracked_scroll_bar
,
12261 - XINT (tracked_scroll_bar
->top
),
12262 TickCount() * (1000 / 60));
12264 note_mouse_movement (f
, &mouse_pos
);
12266 old_mouse_pos
= mouse_pos
;
12277 /* Need to override CodeWarrior's input function so no conversion is
12278 done on newlines Otherwise compiled functions in .elc files will be
12279 read incorrectly. Defined in ...:MSL C:MSL
12280 Common:Source:buffer_io.c. */
12283 __convert_to_newlines (unsigned char * p
, size_t * n
)
12285 #pragma unused(p,n)
12289 __convert_from_newlines (unsigned char * p
, size_t * n
)
12291 #pragma unused(p,n)
12296 /* Initialize the struct pointed to by MW to represent a new COLS x
12297 ROWS Macintosh window, using font with name FONTNAME and size
12300 NewMacWindow (FRAME_PTR fp
)
12303 static int making_terminal_window
= 1;
12305 mwp
= fp
->output_data
.mac
;
12307 if (making_terminal_window
)
12309 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
12312 making_terminal_window
= 0;
12315 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
12319 SetWRefCon (mwp
->mWP
, (long) mwp
);
12320 /* so that update events can find this mac_output struct */
12321 mwp
->mFP
= fp
; /* point back to emacs frame */
12323 SetPort (mwp
->mWP
);
12327 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
12328 ShowWindow (mwp
->mWP
);
12333 void make_mac_frame (struct frame
*f
)
12335 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
12336 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
12339 f
->output_data
.mac
->background_pixel
= 0xffffff;
12340 f
->output_data
.mac
->foreground_pixel
= 0;
12342 f
->output_data
.mac
->cursor_pixel
= 0;
12343 f
->output_data
.mac
->border_pixel
= 0x00ff00;
12344 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
12345 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
12347 f
->output_data
.mac
->desired_cursor
= FILLED_BOX_CURSOR
;
12349 f
->output_data
.mac
->fontset
= -1;
12350 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12351 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12352 f
->output_data
.mac
->left_pos
= 4;
12353 f
->output_data
.mac
->top_pos
= 4;
12354 f
->output_data
.mac
->border_width
= 0;
12355 f
->output_data
.mac
->explicit_parent
= 0;
12357 f
->output_data
.mac
->internal_border_width
= 0;
12359 f
->output_method
= output_mac
;
12368 void make_mac_terminal_frame (struct frame
*f
)
12372 XSETFRAME (frame
, f
);
12374 f
->output_method
= output_mac
;
12375 f
->output_data
.mac
= (struct mac_output
*)
12376 xmalloc (sizeof (struct mac_output
));
12377 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
12378 f
->output_data
.mac
->fontset
= -1;
12379 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
12380 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
12382 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
12387 make_mac_frame (f
);
12389 Fmodify_frame_parameters (frame
,
12390 Fcons (Fcons (Qfont
,
12391 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
12392 Fmodify_frame_parameters (frame
,
12393 Fcons (Fcons (Qforeground_color
,
12394 build_string ("black")), Qnil
));
12395 Fmodify_frame_parameters (frame
,
12396 Fcons (Fcons (Qbackground_color
,
12397 build_string ("white")), Qnil
));
12401 mac_initialize_display_info ()
12403 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
12404 GDHandle main_device_handle
;
12406 bzero (dpyinfo
, sizeof (*dpyinfo
));
12408 /* Put it on x_display_name_list. */
12409 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
12410 x_display_name_list
);
12411 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
12413 main_device_handle
= LMGetMainDevice();
12415 dpyinfo
->reference_count
= 0;
12416 dpyinfo
->resx
= 75.0;
12417 dpyinfo
->resy
= 75.0;
12418 dpyinfo
->n_planes
= 1;
12419 dpyinfo
->n_cbits
= 16;
12420 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
12421 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
12422 dpyinfo
->grabbed
= 0;
12423 dpyinfo
->root_window
= NULL
;
12425 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
12426 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
12427 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
12428 dpyinfo
->mouse_face_window
= Qnil
;
12435 rif
= &x_redisplay_interface
;
12437 clear_frame_hook
= x_clear_frame
;
12438 ins_del_lines_hook
= x_ins_del_lines
;
12439 change_line_highlight_hook
= x_change_line_highlight
;
12440 delete_glyphs_hook
= x_delete_glyphs
;
12441 ring_bell_hook
= XTring_bell
;
12442 reset_terminal_modes_hook
= XTreset_terminal_modes
;
12443 set_terminal_modes_hook
= XTset_terminal_modes
;
12444 update_begin_hook
= x_update_begin
;
12445 update_end_hook
= x_update_end
;
12446 set_terminal_window_hook
= XTset_terminal_window
;
12447 read_socket_hook
= XTread_socket
;
12448 frame_up_to_date_hook
= XTframe_up_to_date
;
12449 reassert_line_highlight_hook
= XTreassert_line_highlight
;
12450 mouse_position_hook
= XTmouse_position
;
12451 frame_rehighlight_hook
= XTframe_rehighlight
;
12452 frame_raise_lower_hook
= XTframe_raise_lower
;
12454 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
12455 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
12456 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
12457 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
12459 estimate_mode_line_height_hook
= x_estimate_mode_line_height
;
12461 scroll_region_ok
= 1; /* we'll scroll partial frames */
12462 char_ins_del_ok
= 0; /* just as fast to write the line */
12463 line_ins_del_ok
= 1; /* we'll just blt 'em */
12464 fast_clear_end_of_line
= 1; /* X does this well */
12465 memory_below_frame
= 0; /* we don't remember what scrolls
12470 last_tool_bar_item
= -1;
12471 any_help_event_p
= 0;
12473 /* Try to use interrupt input; if we can't, then start polling. */
12474 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
12476 #ifdef USE_X_TOOLKIT
12477 XtToolkitInitialize ();
12478 Xt_app_con
= XtCreateApplicationContext ();
12479 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
12481 /* Install an asynchronous timer that processes Xt timeout events
12482 every 0.1s. This is necessary because some widget sets use
12483 timeouts internally, for example the LessTif menu bar, or the
12484 Xaw3d scroll bar. When Xt timouts aren't processed, these
12485 widgets don't behave normally. */
12487 EMACS_TIME interval
;
12488 EMACS_SET_SECS_USECS (interval
, 0, 100000);
12489 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
12493 #if USE_TOOLKIT_SCROLL_BARS
12494 xaw3d_arrow_scroll
= False
;
12495 xaw3d_pick_top
= True
;
12499 /* Note that there is no real way portable across R3/R4 to get the
12500 original error handler. */
12501 XSetErrorHandler (x_error_handler
);
12502 XSetIOErrorHandler (x_io_error_quitter
);
12504 /* Disable Window Change signals; they are handled by X events. */
12506 signal (SIGWINCH
, SIG_DFL
);
12507 #endif /* ! defined (SIGWINCH) */
12509 signal (SIGPIPE
, x_connection_signal
);
12512 mac_initialize_display_info ();
12520 staticpro (&x_error_message_string
);
12521 x_error_message_string
= Qnil
;
12524 staticpro (&x_display_name_list
);
12525 x_display_name_list
= Qnil
;
12527 staticpro (&last_mouse_scroll_bar
);
12528 last_mouse_scroll_bar
= Qnil
;
12530 staticpro (&Qvendor_specific_keysyms
);
12531 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
12533 staticpro (&last_mouse_press_frame
);
12534 last_mouse_press_frame
= Qnil
;
12536 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
12537 staticpro (&Qmac_ready_for_drag_n_drop
);
12540 staticpro (&help_echo
);
12541 help_echo_object
= Qnil
;
12542 staticpro (&help_echo_object
);
12543 help_echo_window
= Qnil
;
12544 staticpro (&help_echo_window
);
12545 previous_help_echo
= Qnil
;
12546 staticpro (&previous_help_echo
);
12547 help_echo_pos
= -1;
12549 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p
,
12550 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
12551 For example, if a block cursor is over a tab, it will be drawn as\n\
12552 wide as that tab on the display.");
12553 x_stretch_cursor_p
= 0;
12555 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p
,
12556 "If not nil, Emacs uses toolkit scroll bars.");
12557 #if USE_TOOLKIT_SCROLL_BARS
12558 x_toolkit_scroll_bars_p
= 1;
12560 x_toolkit_scroll_bars_p
= 0;
12563 staticpro (&last_mouse_motion_frame
);
12564 last_mouse_motion_frame
= Qnil
;
12566 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
12567 "Non-nil means that the command key is used as the Emacs meta key.\n\
12568 Otherwise the option key is used.");
12569 Vmac_command_key_is_meta
= Qt
;
12571 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
12572 "One of the Text Encoding Base constant values defined in the\n\
12573 Basic Text Constants section of Inside Macintosh - Text Encoding\n\
12574 Conversion Manager. Its value determines the encoding characters\n\
12575 typed at the Mac keyboard (presumed to be in the MacRoman encoding)\n\
12576 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),\n\
12577 its default value, no conversion takes place. If it is set to\n\
12578 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),\n\
12579 characters typed on Mac keyboard are first converted into the\n\
12580 ISO Latin-1 or ISO Latin-2 encoding, respectively before being\n\
12581 passed to Emacs. Together with Emacs's set-keyboard-coding-system\n\
12582 command, this enables the Mac keyboard to be used to enter non-ASCII\n\
12583 characters directly.");
12584 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;