1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
43 /* Macros max and min defined in lisp.h conflict with those in
44 precompiled header Carbon.h. */
48 #include <Carbon/Carbon.h>
50 #define free unexec_free
52 #define malloc unexec_malloc
54 #define realloc unexec_realloc
56 #define min(a, b) ((a) < (b) ? (a) : (b))
58 #define max(a, b) ((a) > (b) ? (a) : (b))
60 #define init_process emacs_init_process
61 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
62 obtain events from the event queue. If set to 0, WaitNextEvent is
64 #define USE_CARBON_EVENTS 1
65 #else /* not MAC_OSX */
66 #include <Quickdraw.h>
67 #include <ToolUtils.h>
71 #include <Resources.h>
73 #include <TextUtils.h>
76 #if defined (__MRC__) || (__MSL__ >= 0x6000)
77 #include <ControlDefinitions.h>
84 #endif /* not MAC_OSX */
98 #include "dispextern.h"
100 #include "termhooks.h"
101 #include "termopts.h"
102 #include "termchar.h"
107 #include "intervals.h"
108 #include "composite.h"
111 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
112 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
113 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
114 #define macShiftKey (shiftKey)
115 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
116 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
118 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
122 /* Non-nil means Emacs uses toolkit scroll bars. */
124 Lisp_Object Vx_toolkit_scroll_bars
;
126 /* Non-zero means that a HELP_EVENT has been generated since Emacs
129 static int any_help_event_p
;
131 /* Non-zero means autoselect window with the mouse cursor. */
133 int x_autoselect_window_p
;
135 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
137 int x_use_underline_position_properties
;
139 /* Non-zero means draw block and hollow cursor as wide as the glyph
140 under it. For example, if a block cursor is over a tab, it will be
141 drawn as wide as that tab on the display. */
144 /* This is a chain of structures for all the X displays currently in
147 struct x_display_info
*x_display_list
;
149 /* This is a list of cons cells, each of the form (NAME
150 . FONT-LIST-CACHE), one for each element of x_display_list and in
151 the same order. NAME is the name of the frame. FONT-LIST-CACHE
152 records previous values returned by x-list-fonts. */
154 Lisp_Object x_display_name_list
;
156 /* This is display since Mac does not support multiple ones. */
157 struct mac_display_info one_mac_display_info
;
159 /* Frame being updated by update_frame. This is declared in term.c.
160 This is set by update_begin and looked at by all the XT functions.
161 It is zero while not inside an update. In that case, the XT
162 functions assume that `selected_frame' is the frame to apply to. */
164 extern struct frame
*updating_frame
;
166 extern int waiting_for_input
;
168 /* This is a frame waiting to be auto-raised, within XTread_socket. */
170 struct frame
*pending_autoraise_frame
;
172 /* Non-zero means user is interacting with a toolkit scroll bar. */
174 static int toolkit_scroll_bar_interaction
;
178 Formerly, we used PointerMotionHintMask (in standard_event_mask)
179 so that we would have to call XQueryPointer after each MotionNotify
180 event to ask for another such event. However, this made mouse tracking
181 slow, and there was a bug that made it eventually stop.
183 Simply asking for MotionNotify all the time seems to work better.
185 In order to avoid asking for motion events and then throwing most
186 of them away or busy-polling the server for mouse positions, we ask
187 the server for pointer motion hints. This means that we get only
188 one event per group of mouse movements. "Groups" are delimited by
189 other kinds of events (focus changes and button clicks, for
190 example), or by XQueryPointer calls; when one of these happens, we
191 get another MotionNotify event the next time the mouse moves. This
192 is at least as efficient as getting motion events when mouse
193 tracking is on, and I suspect only negligibly worse when tracking
196 /* Where the mouse was last time we reported a mouse event. */
198 static Rect last_mouse_glyph
;
199 static Lisp_Object last_mouse_press_frame
;
201 /* The scroll bar in which the last X motion event occurred.
203 If the last X motion event occurred in a scroll bar, we set this so
204 XTmouse_position can know whether to report a scroll bar motion or
207 If the last X motion event didn't occur in a scroll bar, we set
208 this to Qnil, to tell XTmouse_position to return an ordinary motion
211 static Lisp_Object last_mouse_scroll_bar
;
213 /* This is a hack. We would really prefer that XTmouse_position would
214 return the time associated with the position it returns, but there
215 doesn't seem to be any way to wrest the time-stamp from the server
216 along with the position query. So, we just keep track of the time
217 of the last movement we received, and return that in hopes that
218 it's somewhat accurate. */
220 static Time last_mouse_movement_time
;
222 enum mouse_tracking_type
{
224 mouse_tracking_mouse_movement
,
225 mouse_tracking_scroll_bar
228 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
230 struct scroll_bar
*tracked_scroll_bar
= NULL
;
232 /* Incremented by XTread_socket whenever it really tries to read
236 static int volatile input_signal_count
;
238 static int input_signal_count
;
241 /* Used locally within XTread_socket. */
243 static int x_noop_count
;
245 /* Initial values of argv and argc. */
247 extern char **initial_argv
;
248 extern int initial_argc
;
250 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
252 /* Tells if a window manager is present or not. */
254 extern Lisp_Object Vx_no_window_manager
;
256 extern Lisp_Object Qface
, Qmouse_face
;
260 /* A mask of extra modifier bits to put into every keyboard char. */
262 extern int extra_keyboard_modifiers
;
264 static Lisp_Object Qvendor_specific_keysyms
;
267 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
270 extern int inhibit_window_system
;
273 QDGlobals qd
; /* QuickDraw global information structure. */
277 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
278 struct mac_display_info
*mac_display_info_for_display (Display
*);
279 static void x_update_window_end
P_ ((struct window
*, int, int));
280 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
281 static int x_io_error_quitter
P_ ((Display
*));
282 int x_catch_errors
P_ ((Display
*));
283 void x_uncatch_errors
P_ ((Display
*, int));
284 void x_lower_frame
P_ ((struct frame
*));
285 void x_scroll_bar_clear
P_ ((struct frame
*));
286 int x_had_errors_p
P_ ((Display
*));
287 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
288 void x_raise_frame
P_ ((struct frame
*));
289 void x_set_window_size
P_ ((struct frame
*, int, int, int));
290 void x_wm_set_window_state
P_ ((struct frame
*, int));
291 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
292 void mac_initialize
P_ ((void));
293 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
294 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
295 static void x_update_end
P_ ((struct frame
*));
296 static void XTframe_up_to_date
P_ ((struct frame
*));
297 static void XTreassert_line_highlight
P_ ((int, int));
298 static void x_change_line_highlight
P_ ((int, int, int, int));
299 static void XTset_terminal_modes
P_ ((void));
300 static void XTreset_terminal_modes
P_ ((void));
301 static void x_clear_frame
P_ ((void));
302 static void frame_highlight
P_ ((struct frame
*));
303 static void frame_unhighlight
P_ ((struct frame
*));
304 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
305 static void XTframe_rehighlight
P_ ((struct frame
*));
306 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
307 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
308 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
309 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*,
311 static void x_flush
P_ ((struct frame
*f
));
312 static void x_update_begin
P_ ((struct frame
*));
313 static void x_update_window_begin
P_ ((struct window
*));
314 static void x_after_update_window_line
P_ ((struct glyph_row
*));
316 void activate_scroll_bars (FRAME_PTR
);
317 void deactivate_scroll_bars (FRAME_PTR
);
319 static int is_emacs_window (WindowPtr
);
321 extern int image_ascent (struct image
*, struct face
*);
322 int x_bitmap_icon (struct frame
*, Lisp_Object
);
323 void x_make_frame_visible (struct frame
*);
325 extern void window_scroll (Lisp_Object
, int, int, int);
327 /* Defined in macmenu.h. */
328 extern void menubar_selection_callback (FRAME_PTR
, int);
329 extern void set_frame_menubar (FRAME_PTR
, int, int);
331 /* X display function emulation */
334 XFreePixmap (display
, pixmap
)
338 PixMap
*p
= (PixMap
*) pixmap
;
345 /* Set foreground color for subsequent QuickDraw commands. Assume
346 graphic port has already been set. */
349 mac_set_forecolor (unsigned long color
)
353 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
354 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
355 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
357 RGBForeColor (&fg_color
);
361 /* Set background color for subsequent QuickDraw commands. Assume
362 graphic port has already been set. */
365 mac_set_backcolor (unsigned long color
)
369 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
370 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
371 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
373 RGBBackColor (&bg_color
);
376 /* Set foreground and background color for subsequent QuickDraw
377 commands. Assume that the graphic port has already been set. */
380 mac_set_colors (GC gc
)
382 mac_set_forecolor (gc
->foreground
);
383 mac_set_backcolor (gc
->background
);
386 /* Mac version of XDrawLine. */
389 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
395 #if TARGET_API_MAC_CARBON
396 SetPort (GetWindowPort (w
));
407 /* Mac version of XClearArea. */
410 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
414 unsigned int width
, height
;
417 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
421 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
422 xgc
.background
= mwp
->x_compatible
.background_pixel
;
424 #if TARGET_API_MAC_CARBON
425 SetPort (GetWindowPort (w
));
430 mac_set_colors (&xgc
);
431 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
436 /* Mac version of XClearWindow. */
439 XClearWindow (display
, w
)
443 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
446 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
447 xgc
.background
= mwp
->x_compatible
.background_pixel
;
449 #if TARGET_API_MAC_CARBON
450 SetPort (GetWindowPort (w
));
455 mac_set_colors (&xgc
);
457 #if TARGET_API_MAC_CARBON
461 GetWindowPortBounds (w
, &r
);
464 #else /* not TARGET_API_MAC_CARBON */
465 EraseRect (&(w
->portRect
));
466 #endif /* not TARGET_API_MAC_CARBON */
470 /* Mac replacement for XCopyArea. */
473 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
482 #if TARGET_API_MAC_CARBON
483 SetPort (GetWindowPort (w
));
489 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
491 #if TARGET_API_MAC_CARBON
495 LockPortBits (GetWindowPort (w
));
496 pmh
= GetPortPixMap (GetWindowPort (w
));
497 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
498 UnlockPortBits (GetWindowPort (w
));
500 #else /* not TARGET_API_MAC_CARBON */
501 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
502 #endif /* not TARGET_API_MAC_CARBON */
506 /* Mac replacement for XSetClipRectangles. */
509 mac_set_clip_rectangle (display
, w
, r
)
514 #if TARGET_API_MAC_CARBON
515 SetPort (GetWindowPort (w
));
524 /* Mac replacement for XSetClipMask. */
527 mac_reset_clipping (display
, w
)
533 #if TARGET_API_MAC_CARBON
534 SetPort (GetWindowPort (w
));
539 SetRect (&r
, -32767, -32767, 32767, 32767);
544 /* Mac replacement for XCreateBitmapFromBitmapData. */
547 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
552 int bytes_per_row
, i
, j
;
554 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
555 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
556 if (!bitmap
->baseAddr
)
559 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
560 for (i
= 0; i
< h
; i
++)
561 for (j
= 0; j
< w
; j
++)
562 if (BitTst (bits
, i
* w
+ j
))
563 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
565 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
570 mac_free_bitmap (bitmap
)
573 xfree (bitmap
->baseAddr
);
576 /* Mac replacement for XFillRectangle. */
579 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
584 unsigned int width
, height
;
588 #if TARGET_API_MAC_CARBON
589 SetPort (GetWindowPort (w
));
595 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
597 PaintRect (&r
); /* using foreground color of gc */
601 /* Mac replacement for XDrawRectangle: dest is a window. */
604 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
609 unsigned int width
, height
;
613 #if TARGET_API_MAC_CARBON
614 SetPort (GetWindowPort (w
));
620 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
622 FrameRect (&r
); /* using foreground color of gc */
626 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
629 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
634 unsigned int width
, height
;
636 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
639 #if TARGET_API_MAC_CARBON
640 SetPort (GetWindowPort (w
));
646 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
648 FrameRect (&r
); /* using foreground color of gc */
654 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
661 int nchars
, mode
, bytes_per_char
;
663 #if TARGET_API_MAC_CARBON
664 SetPort (GetWindowPort (w
));
671 TextFont (gc
->font
->mac_fontnum
);
672 TextSize (gc
->font
->mac_fontsize
);
673 TextFace (gc
->font
->mac_fontface
);
677 DrawText (buf
, 0, nchars
* bytes_per_char
);
681 /* Mac replacement for XDrawString. */
684 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
692 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
696 /* Mac replacement for XDrawString16. */
699 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
707 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
712 /* Mac replacement for XDrawImageString. */
715 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
723 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
727 /* Mac replacement for XDrawString16. */
730 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
738 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
743 /* Mac replacement for XCopyArea: dest must be window. */
746 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
753 unsigned int width
, height
;
758 #if TARGET_API_MAC_CARBON
759 SetPort (GetWindowPort (dest
));
766 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
767 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
769 #if TARGET_API_MAC_CARBON
773 LockPortBits (GetWindowPort (dest
));
774 pmh
= GetPortPixMap (GetWindowPort (dest
));
775 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
776 UnlockPortBits (GetWindowPort (dest
));
778 #else /* not TARGET_API_MAC_CARBON */
779 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
780 #endif /* not TARGET_API_MAC_CARBON */
785 /* Convert a pair of local coordinates to global (screen) coordinates.
786 Assume graphic port has been properly set. */
788 local_to_global_coord (short *h
, short *v
)
802 /* Mac replacement for XCopyArea: used only for scrolling. */
805 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
810 unsigned int width
, height
;
813 #if TARGET_API_MAC_CARBON
814 Rect gw_r
, src_r
, dest_r
;
817 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
818 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
820 SetPort (GetWindowPort (w
));
822 ForeColor (blackColor
);
823 BackColor (whiteColor
);
825 LockPortBits (GetWindowPort (w
));
826 pmh
= GetPortPixMap (GetWindowPort (w
));
827 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
828 UnlockPortBits (GetWindowPort (w
));
831 #else /* not TARGET_API_MAC_CARBON */
839 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
840 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
843 /* Need to use global coordinates and screenBits since src and dest
844 areas overlap in general. */
845 local_to_global_coord (&src_r
.left
, &src_r
.top
);
846 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
847 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
848 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
850 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
852 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
853 color mapping in CopyBits. Otherwise, it will be slow. */
854 ForeColor (blackColor
);
855 BackColor (whiteColor
);
856 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
860 #endif /* not TARGET_API_MAC_CARBON */
864 /* Mac replacement for XCopyArea: dest must be Pixmap. */
867 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
874 unsigned int width
, height
;
878 int src_right
= ((PixMap
*) src
)->bounds
.right
;
879 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
880 int w
= src_right
- src_x
;
881 int h
= src_bottom
- src_y
;
885 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
886 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
888 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
892 /* Mac replacement for XChangeGC. */
895 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
898 if (mask
& GCForeground
)
899 gc
->foreground
= xgcv
->foreground
;
900 if (mask
& GCBackground
)
901 gc
->background
= xgcv
->background
;
903 gc
->font
= xgcv
->font
;
907 /* Mac replacement for XCreateGC. */
910 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
913 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
914 bzero (gc
, sizeof (XGCValues
));
916 XChangeGC (ignore
, gc
, mask
, xgcv
);
922 /* Used in xfaces.c. */
925 XFreeGC (display
, gc
)
933 /* Mac replacement for XGetGCValues. */
936 XGetGCValues (void* ignore
, XGCValues
*gc
,
937 unsigned long mask
, XGCValues
*xgcv
)
939 XChangeGC (ignore
, xgcv
, mask
, gc
);
943 /* Mac replacement for XSetForeground. */
946 XSetForeground (display
, gc
, color
)
951 gc
->foreground
= color
;
955 /* Mac replacement for XSetFont. */
958 XSetFont (display
, gc
, font
)
968 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
969 int *direction
,int *font_ascent
,
970 int *font_descent
, XCharStruct
*cs
)
972 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
976 /* x_sync is a no-op on Mac. */
984 /* Remove calls to XFlush by defining XFlush to an empty replacement.
985 Calls to XFlush should be unnecessary because the X output buffer
986 is flushed automatically as needed by calls to XPending,
987 XNextEvent, or XWindowEvent according to the XFlush man page.
988 XTread_socket calls XPending. Removing XFlush improves
991 #if TARGET_API_MAC_CARBON
992 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
994 #define XFlush(DISPLAY) (void) 0
997 /* Flush display of frame F, or of all frames if F is null. */
1003 #if TARGET_API_MAC_CARBON
1007 Lisp_Object rest
, frame
;
1008 FOR_EACH_FRAME (rest
, frame
)
1009 x_flush (XFRAME (frame
));
1011 else if (FRAME_X_P (f
))
1012 XFlush (FRAME_MAC_DISPLAY (f
));
1014 #endif /* TARGET_API_MAC_CARBON */
1019 /* Return the struct mac_display_info corresponding to DPY. There's
1022 struct mac_display_info
*
1023 mac_display_info_for_display (dpy
)
1026 return &one_mac_display_info
;
1031 /***********************************************************************
1032 Starting and ending an update
1033 ***********************************************************************/
1035 /* Start an update of frame F. This function is installed as a hook
1036 for update_begin, i.e. it is called when update_begin is called.
1037 This function is called prior to calls to x_update_window_begin for
1038 each window being updated. */
1044 /* Nothing to do. */
1048 /* Start update of window W. Set the global variable updated_window
1049 to the window being updated and set output_cursor to the cursor
1053 x_update_window_begin (w
)
1056 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1057 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1060 set_output_cursor (&w
->cursor
);
1064 if (f
== display_info
->mouse_face_mouse_frame
)
1066 /* Don't do highlighting for mouse motion during the update. */
1067 display_info
->mouse_face_defer
= 1;
1069 /* If F needs to be redrawn, simply forget about any prior mouse
1071 if (FRAME_GARBAGED_P (f
))
1072 display_info
->mouse_face_window
= Qnil
;
1074 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1075 their mouse_face_p flag set, which means that they are always
1076 unequal to rows in a desired matrix which never have that
1077 flag set. So, rows containing mouse-face glyphs are never
1078 scrolled, and we don't have to switch the mouse highlight off
1079 here to prevent it from being scrolled. */
1081 /* Can we tell that this update does not affect the window
1082 where the mouse highlight is? If so, no need to turn off.
1083 Likewise, don't do anything if the frame is garbaged;
1084 in that case, the frame's current matrix that we would use
1085 is all wrong, and we will redisplay that line anyway. */
1086 if (!NILP (display_info
->mouse_face_window
)
1087 && w
== XWINDOW (display_info
->mouse_face_window
))
1091 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1092 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1095 if (i
< w
->desired_matrix
->nrows
)
1096 clear_mouse_face (display_info
);
1105 /* Draw a vertical window border from (x,y0) to (x,y1) */
1108 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1112 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1114 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1115 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1119 /* End update of window W (which is equal to updated_window).
1121 Draw vertical borders between horizontally adjacent windows, and
1122 display W's cursor if CURSOR_ON_P is non-zero.
1124 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1125 glyphs in mouse-face were overwritten. In that case we have to
1126 make sure that the mouse-highlight is properly redrawn.
1128 W may be a menu bar pseudo-window in case we don't have X toolkit
1129 support. Such windows don't have a cursor, so don't display it
1133 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1135 int cursor_on_p
, mouse_face_overwritten_p
;
1137 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1139 if (!w
->pseudo_window_p
)
1144 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1146 output_cursor
.x
, output_cursor
.y
);
1148 x_draw_vertical_border (w
);
1152 /* If a row with mouse-face was overwritten, arrange for
1153 XTframe_up_to_date to redisplay the mouse highlight. */
1154 if (mouse_face_overwritten_p
)
1156 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1157 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1158 dpyinfo
->mouse_face_window
= Qnil
;
1162 /* Unhide the caret. This won't actually show the cursor, unless it
1163 was visible before the corresponding call to HideCaret in
1164 x_update_window_begin. */
1165 if (w32_use_visible_system_caret
)
1166 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1169 updated_window
= NULL
;
1173 /* End update of frame F. This function is installed as a hook in
1180 /* Reset the background color of Mac OS Window to that of the frame after
1181 update so that it is used by Mac Toolbox to clear the update region before
1182 an update event is generated. */
1183 #if TARGET_API_MAC_CARBON
1184 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1186 SetPort (FRAME_MAC_WINDOW (f
));
1189 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1191 /* Mouse highlight may be displayed again. */
1192 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1195 XFlush (FRAME_MAC_DISPLAY (f
));
1200 /* This function is called from various places in xdisp.c whenever a
1201 complete update has been performed. The global variable
1202 updated_window is not available here. */
1205 XTframe_up_to_date (f
)
1210 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1212 if (dpyinfo
->mouse_face_deferred_gc
1213 || f
== dpyinfo
->mouse_face_mouse_frame
)
1216 if (dpyinfo
->mouse_face_mouse_frame
)
1217 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1218 dpyinfo
->mouse_face_mouse_x
,
1219 dpyinfo
->mouse_face_mouse_y
);
1220 dpyinfo
->mouse_face_deferred_gc
= 0;
1227 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1228 arrow bitmaps, or clear the fringes if no bitmaps are required
1229 before DESIRED_ROW is made current. The window being updated is
1230 found in updated_window. This function is called from
1231 update_window_line only if it is known that there are differences
1232 between bitmaps to be drawn between current row and DESIRED_ROW. */
1235 x_after_update_window_line (desired_row
)
1236 struct glyph_row
*desired_row
;
1238 struct window
*w
= updated_window
;
1244 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1247 draw_row_fringe_bitmaps (w
, desired_row
);
1251 /* When a window has disappeared, make sure that no rest of
1252 full-width rows stays visible in the internal border. Could
1253 check here if updated_window is the leftmost/rightmost window,
1254 but I guess it's not worth doing since vertically split windows
1255 are almost never used, internal border is rarely set, and the
1256 overhead is very small. */
1257 if (windows_or_buffers_changed
1258 && desired_row
->full_width_p
1259 && (f
= XFRAME (w
->frame
),
1260 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1262 && (height
= desired_row
->visible_height
,
1265 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1266 /* Internal border is drawn below the tool bar. */
1267 if (WINDOWP (f
->tool_bar_window
)
1268 && w
== XWINDOW (f
->tool_bar_window
))
1273 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1274 0, y
, width
, height
, 0);
1275 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1276 f
->output_data
.mac
->pixel_width
- width
, y
,
1284 /* Draw the bitmap WHICH in one of the left or right fringes of
1285 window W. ROW is the glyph row for which to display the bitmap; it
1286 determines the vertical position at which the bitmap has to be
1290 x_draw_fringe_bitmap (w
, row
, p
)
1292 struct glyph_row
*row
;
1293 struct draw_fringe_bitmap_params
*p
;
1295 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1296 Display
*display
= FRAME_MAC_DISPLAY (f
);
1297 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1299 GC gc
= f
->output_data
.mac
->normal_gc
;
1300 struct face
*face
= p
->face
;
1302 /* Must clip because of partially visible lines. */
1303 x_clip_to_row (w
, row
, gc
, 1);
1308 gcv
.foreground
= face
->background
;
1310 #if 0 /* MAC_TODO: stipple */
1311 /* In case the same realized face is used for fringes and
1312 for something displayed in the text (e.g. face `region' on
1313 mono-displays, the fill style may have been changed to
1314 FillSolid in x_draw_glyph_string_background. */
1316 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1318 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1321 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1323 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1325 #if 0 /* MAC_TODO: stipple */
1327 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1331 if (p
->which
!= NO_FRINGE_BITMAP
)
1333 unsigned char *bits
= fringe_bitmaps
[p
->which
].bits
+ p
->dh
;
1336 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, p
->wd
, p
->h
);
1337 gcv
.foreground
= face
->foreground
;
1338 gcv
.background
= face
->background
;
1340 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
, &bitmap
);
1342 mac_free_bitmap (&bitmap
);
1345 mac_reset_clipping (display
, window
);
1349 /* This is called when starting Emacs and when restarting after
1350 suspend. When starting Emacs, no window is mapped. And nothing
1351 must be done to Emacs's own window if it is suspended (though that
1355 XTset_terminal_modes ()
1359 /* This is called when exiting or suspending Emacs. Exiting will make
1360 the windows go away, and suspending requires no action. */
1363 XTreset_terminal_modes ()
1368 /***********************************************************************
1370 ***********************************************************************/
1372 /* Function prototypes of this page. */
1374 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1375 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1378 /* Return a pointer to per-char metric information in FONT of a
1379 character pointed by B which is a pointer to an XChar2b. */
1381 #define PER_CHAR_METRIC(font, b) \
1383 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1384 + (((font)->min_byte1 || (font)->max_byte1) \
1385 ? (((b)->byte1 - (font)->min_byte1) \
1386 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1388 : &((font)->max_bounds))
1391 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1392 is not contained in the font. */
1394 static INLINE XCharStruct
*
1395 x_per_char_metric (font
, char2b
)
1399 /* The result metric information. */
1400 XCharStruct
*pcm
= NULL
;
1402 xassert (font
&& char2b
);
1404 if (font
->per_char
!= NULL
)
1406 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1408 /* min_char_or_byte2 specifies the linear character index
1409 corresponding to the first element of the per_char array,
1410 max_char_or_byte2 is the index of the last character. A
1411 character with non-zero CHAR2B->byte1 is not in the font.
1412 A character with byte2 less than min_char_or_byte2 or
1413 greater max_char_or_byte2 is not in the font. */
1414 if (char2b
->byte1
== 0
1415 && char2b
->byte2
>= font
->min_char_or_byte2
1416 && char2b
->byte2
<= font
->max_char_or_byte2
)
1417 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1421 /* If either min_byte1 or max_byte1 are nonzero, both
1422 min_char_or_byte2 and max_char_or_byte2 are less than
1423 256, and the 2-byte character index values corresponding
1424 to the per_char array element N (counting from 0) are:
1426 byte1 = N/D + min_byte1
1427 byte2 = N\D + min_char_or_byte2
1431 D = max_char_or_byte2 - min_char_or_byte2 + 1
1432 / = integer division
1433 \ = integer modulus */
1434 if (char2b
->byte1
>= font
->min_byte1
1435 && char2b
->byte1
<= font
->max_byte1
1436 && char2b
->byte2
>= font
->min_char_or_byte2
1437 && char2b
->byte2
<= font
->max_char_or_byte2
)
1439 pcm
= (font
->per_char
1440 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1441 * (char2b
->byte1
- font
->min_byte1
))
1442 + (char2b
->byte2
- font
->min_char_or_byte2
));
1448 /* If the per_char pointer is null, all glyphs between the first
1449 and last character indexes inclusive have the same
1450 information, as given by both min_bounds and max_bounds. */
1451 if (char2b
->byte2
>= font
->min_char_or_byte2
1452 && char2b
->byte2
<= font
->max_char_or_byte2
)
1453 pcm
= &font
->max_bounds
;
1456 return ((pcm
== NULL
1457 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1464 static XCharStruct
*
1465 mac_per_char_metric (font
, char2b
, font_type
)
1470 return x_per_char_metric (font
, char2b
);
1474 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1475 the two-byte form of C. Encoding is returned in *CHAR2B. */
1478 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1481 struct font_info
*font_info
;
1484 int charset
= CHAR_CHARSET (c
);
1485 XFontStruct
*font
= font_info
->font
;
1487 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1488 This may be either a program in a special encoder language or a
1490 if (font_info
->font_encoder
)
1492 /* It's a program. */
1493 struct ccl_program
*ccl
= font_info
->font_encoder
;
1495 if (CHARSET_DIMENSION (charset
) == 1)
1497 ccl
->reg
[0] = charset
;
1498 ccl
->reg
[1] = char2b
->byte2
;
1502 ccl
->reg
[0] = charset
;
1503 ccl
->reg
[1] = char2b
->byte1
;
1504 ccl
->reg
[2] = char2b
->byte2
;
1507 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1509 /* We assume that MSBs are appropriately set/reset by CCL
1511 if (font
->max_byte1
== 0) /* 1-byte font */
1512 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1514 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1516 else if (font_info
->encoding
[charset
])
1518 /* Fixed encoding scheme. See fontset.h for the meaning of the
1519 encoding numbers. */
1520 int enc
= font_info
->encoding
[charset
];
1522 if ((enc
== 1 || enc
== 2)
1523 && CHARSET_DIMENSION (charset
) == 2)
1524 char2b
->byte1
|= 0x80;
1526 if (enc
== 1 || enc
== 3)
1527 char2b
->byte2
|= 0x80;
1533 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1534 char2b
->byte1
= sjis1
;
1535 char2b
->byte2
= sjis2
;
1540 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1542 return FONT_TYPE_UNKNOWN
;
1547 /***********************************************************************
1549 ***********************************************************************/
1552 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1553 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1554 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1556 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1557 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1558 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1559 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1560 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1561 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1562 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1563 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1564 unsigned long *, double, int));*/
1565 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1566 double, int, unsigned long));
1567 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1568 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1569 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1570 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1571 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1572 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1574 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1575 int, int, int, int, Rect
*));
1576 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1577 int, int, int, Rect
*));
1580 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1584 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1589 struct glyph_string
*s
;
1591 if (s
->font
== FRAME_FONT (s
->f
)
1592 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1593 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1595 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1598 /* Cursor on non-default face: must merge. */
1602 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1603 xgcv
.foreground
= s
->face
->background
;
1605 /* If the glyph would be invisible, try a different foreground. */
1606 if (xgcv
.foreground
== xgcv
.background
)
1607 xgcv
.foreground
= s
->face
->foreground
;
1608 if (xgcv
.foreground
== xgcv
.background
)
1609 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1610 if (xgcv
.foreground
== xgcv
.background
)
1611 xgcv
.foreground
= s
->face
->foreground
;
1613 /* Make sure the cursor is distinct from text in this face. */
1614 if (xgcv
.background
== s
->face
->background
1615 && xgcv
.foreground
== s
->face
->foreground
)
1617 xgcv
.background
= s
->face
->foreground
;
1618 xgcv
.foreground
= s
->face
->background
;
1621 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1622 xgcv
.font
= s
->font
;
1623 mask
= GCForeground
| GCBackground
| GCFont
;
1625 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1626 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1629 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1630 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1632 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1637 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1640 x_set_mouse_face_gc (s
)
1641 struct glyph_string
*s
;
1646 /* What face has to be used last for the mouse face? */
1647 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1648 face
= FACE_FROM_ID (s
->f
, face_id
);
1650 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1652 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1653 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1655 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1656 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1657 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1659 /* If font in this face is same as S->font, use it. */
1660 if (s
->font
== s
->face
->font
)
1661 s
->gc
= s
->face
->gc
;
1664 /* Otherwise construct scratch_cursor_gc with values from FACE
1669 xgcv
.background
= s
->face
->background
;
1670 xgcv
.foreground
= s
->face
->foreground
;
1671 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1672 xgcv
.font
= s
->font
;
1673 mask
= GCForeground
| GCBackground
| GCFont
;
1675 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1676 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1679 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1680 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1682 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1685 xassert (s
->gc
!= 0);
1689 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1690 Faces to use in the mode line have already been computed when the
1691 matrix was built, so there isn't much to do, here. */
1694 x_set_mode_line_face_gc (s
)
1695 struct glyph_string
*s
;
1697 s
->gc
= s
->face
->gc
;
1701 /* Set S->gc of glyph string S for drawing that glyph string. Set
1702 S->stippled_p to a non-zero value if the face of S has a stipple
1706 x_set_glyph_string_gc (s
)
1707 struct glyph_string
*s
;
1709 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1711 if (s
->hl
== DRAW_NORMAL_TEXT
)
1713 s
->gc
= s
->face
->gc
;
1714 s
->stippled_p
= s
->face
->stipple
!= 0;
1716 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1718 x_set_mode_line_face_gc (s
);
1719 s
->stippled_p
= s
->face
->stipple
!= 0;
1721 else if (s
->hl
== DRAW_CURSOR
)
1723 x_set_cursor_gc (s
);
1726 else if (s
->hl
== DRAW_MOUSE_FACE
)
1728 x_set_mouse_face_gc (s
);
1729 s
->stippled_p
= s
->face
->stipple
!= 0;
1731 else if (s
->hl
== DRAW_IMAGE_RAISED
1732 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1734 s
->gc
= s
->face
->gc
;
1735 s
->stippled_p
= s
->face
->stipple
!= 0;
1739 s
->gc
= s
->face
->gc
;
1740 s
->stippled_p
= s
->face
->stipple
!= 0;
1743 /* GC must have been set. */
1744 xassert (s
->gc
!= 0);
1748 /* Set clipping for output of glyph string S. S may be part of a mode
1749 line or menu if we don't have X toolkit support. */
1752 x_set_glyph_string_clipping (s
)
1753 struct glyph_string
*s
;
1756 get_glyph_string_clip_rect (s
, &r
);
1757 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1762 Compute left and right overhang of glyph string S. If S is a glyph
1763 string for a composition, assume overhangs don't exist. */
1766 mac_compute_glyph_string_overhangs (s
)
1767 struct glyph_string
*s
;
1770 /* MAC_TODO: XTextExtents16 does nothing yet... */
1773 && s
->first_glyph
->type
== CHAR_GLYPH
)
1776 int direction
, font_ascent
, font_descent
;
1777 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1778 &font_ascent
, &font_descent
, &cs
);
1779 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1780 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1786 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1789 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1790 struct glyph_string
*s
;
1795 xgcv
.foreground
= s
->gc
->background
;
1796 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1800 /* Draw the background of glyph_string S. If S->background_filled_p
1801 is non-zero don't draw it. FORCE_P non-zero means draw the
1802 background even if it wouldn't be drawn normally. This is used
1803 when a string preceding S draws into the background of S, or S
1804 contains the first component of a composition. */
1807 x_draw_glyph_string_background (s
, force_p
)
1808 struct glyph_string
*s
;
1811 /* Nothing to do if background has already been drawn or if it
1812 shouldn't be drawn in the first place. */
1813 if (!s
->background_filled_p
)
1815 int box_line_width
= max (s
->face
->box_line_width
, 0);
1817 #if 0 /* MAC_TODO: stipple */
1820 /* Fill background with a stipple pattern. */
1821 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1822 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1823 s
->y
+ box_line_width
,
1824 s
->background_width
,
1825 s
->height
- 2 * box_line_width
);
1826 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1827 s
->background_filled_p
= 1;
1831 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1832 || s
->font_not_found_p
1833 || s
->extends_to_end_of_line_p
1836 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1837 s
->background_width
,
1838 s
->height
- 2 * box_line_width
);
1839 s
->background_filled_p
= 1;
1845 /* Draw the foreground of glyph string S. */
1848 x_draw_glyph_string_foreground (s
)
1849 struct glyph_string
*s
;
1853 /* If first glyph of S has a left box line, start drawing the text
1854 of S to the right of that box line. */
1855 if (s
->face
->box
!= FACE_NO_BOX
1856 && s
->first_glyph
->left_box_line_p
)
1857 x
= s
->x
+ abs (s
->face
->box_line_width
);
1861 /* Draw characters of S as rectangles if S's font could not be
1863 if (s
->font_not_found_p
)
1865 for (i
= 0; i
< s
->nchars
; ++i
)
1867 struct glyph
*g
= s
->first_glyph
+ i
;
1868 mac_draw_rectangle (s
->display
, s
->window
,
1869 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
1871 x
+= g
->pixel_width
;
1876 char *char1b
= (char *) s
->char2b
;
1877 int boff
= s
->font_info
->baseline_offset
;
1879 if (s
->font_info
->vertical_centering
)
1880 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
1882 /* If we can use 8-bit functions, condense S->char2b. */
1884 for (i
= 0; i
< s
->nchars
; ++i
)
1885 char1b
[i
] = s
->char2b
[i
].byte2
;
1887 /* Draw text with XDrawString if background has already been
1888 filled. Otherwise, use XDrawImageString. (Note that
1889 XDrawImageString is usually faster than XDrawString.) Always
1890 use XDrawImageString when drawing the cursor so that there is
1891 no chance that characters under a box cursor are invisible. */
1892 if (s
->for_overlaps_p
1893 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
1895 /* Draw characters with 16-bit or 8-bit functions. */
1897 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
1898 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1900 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
1901 s
->ybase
- boff
, char1b
, s
->nchars
);
1906 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
1907 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1909 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
1910 s
->ybase
- boff
, char1b
, s
->nchars
);
1915 /* Draw the foreground of composite glyph string S. */
1918 x_draw_composite_glyph_string_foreground (s
)
1919 struct glyph_string
*s
;
1923 /* If first glyph of S has a left box line, start drawing the text
1924 of S to the right of that box line. */
1925 if (s
->face
->box
!= FACE_NO_BOX
1926 && s
->first_glyph
->left_box_line_p
)
1927 x
= s
->x
+ abs (s
->face
->box_line_width
);
1931 /* S is a glyph string for a composition. S->gidx is the index of
1932 the first character drawn for glyphs of this composition.
1933 S->gidx == 0 means we are drawing the very first character of
1934 this composition. */
1936 /* Draw a rectangle for the composition if the font for the very
1937 first character of the composition could not be loaded. */
1938 if (s
->font_not_found_p
)
1941 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
1942 s
->width
- 1, s
->height
- 1);
1946 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
1947 XDrawString16 (s
->display
, s
->window
, s
->gc
,
1948 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
1949 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
1955 #ifdef USE_X_TOOLKIT
1957 static struct frame
*x_frame_of_widget
P_ ((Widget
));
1960 /* Return the frame on which widget WIDGET is used.. Abort if frame
1961 cannot be determined. */
1963 static struct frame
*
1964 x_frame_of_widget (widget
)
1967 struct x_display_info
*dpyinfo
;
1971 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
1973 /* Find the top-level shell of the widget. Note that this function
1974 can be called when the widget is not yet realized, so XtWindow
1975 (widget) == 0. That's the reason we can't simply use
1976 x_any_window_to_frame. */
1977 while (!XtIsTopLevelShell (widget
))
1978 widget
= XtParent (widget
);
1980 /* Look for a frame with that top-level widget. Allocate the color
1981 on that frame to get the right gamma correction value. */
1982 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
1983 if (GC_FRAMEP (XCAR (tail
))
1984 && (f
= XFRAME (XCAR (tail
)),
1985 (f
->output_data
.nothing
!= 1
1986 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
1987 && f
->output_data
.x
->widget
== widget
)
1994 /* Allocate the color COLOR->pixel on the screen and display of
1995 widget WIDGET in colormap CMAP. If an exact match cannot be
1996 allocated, try the nearest color available. Value is non-zero
1997 if successful. This is called from lwlib. */
2000 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2005 struct frame
*f
= x_frame_of_widget (widget
);
2006 return x_alloc_nearest_color (f
, cmap
, color
);
2010 #endif /* USE_X_TOOLKIT */
2012 #if 0 /* MAC_TODO */
2014 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2015 CMAP. If an exact match can't be allocated, try the nearest color
2016 available. Value is non-zero if successful. Set *COLOR to the
2020 x_alloc_nearest_color (f
, cmap
, color
)
2025 Display
*display
= FRAME_X_DISPLAY (f
);
2026 Screen
*screen
= FRAME_X_SCREEN (f
);
2029 gamma_correct (f
, color
);
2030 rc
= XAllocColor (display
, cmap
, color
);
2033 /* If we got to this point, the colormap is full, so we're going
2034 to try to get the next closest color. The algorithm used is
2035 a least-squares matching, which is what X uses for closest
2036 color matching with StaticColor visuals. */
2038 unsigned long nearest_delta
= ~0;
2039 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2040 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2042 for (i
= 0; i
< ncells
; ++i
)
2044 XQueryColors (display
, cmap
, cells
, ncells
);
2046 for (nearest
= i
= 0; i
< ncells
; ++i
)
2048 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2049 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2050 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2051 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2053 if (delta
< nearest_delta
)
2056 nearest_delta
= delta
;
2060 color
->red
= cells
[nearest
].red
;
2061 color
->green
= cells
[nearest
].green
;
2062 color
->blue
= cells
[nearest
].blue
;
2063 rc
= XAllocColor (display
, cmap
, color
);
2066 #ifdef DEBUG_X_COLORS
2068 register_color (color
->pixel
);
2069 #endif /* DEBUG_X_COLORS */
2075 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2076 It's necessary to do this instead of just using PIXEL directly to
2077 get color reference counts right. */
2080 x_copy_color (f
, pixel
)
2082 unsigned long pixel
;
2086 color
.pixel
= pixel
;
2088 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2089 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2091 #ifdef DEBUG_X_COLORS
2092 register_color (pixel
);
2098 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2099 It's necessary to do this instead of just using PIXEL directly to
2100 get color reference counts right. */
2103 x_copy_dpy_color (dpy
, cmap
, pixel
)
2106 unsigned long pixel
;
2110 color
.pixel
= pixel
;
2112 XQueryColor (dpy
, cmap
, &color
);
2113 XAllocColor (dpy
, cmap
, &color
);
2115 #ifdef DEBUG_X_COLORS
2116 register_color (pixel
);
2121 #endif /* MAC_TODO */
2123 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2124 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2125 If this produces the same color as COLOR, try a color where all RGB
2126 values have DELTA added. Return the allocated color in *COLOR.
2127 DISPLAY is the X display, CMAP is the colormap to operate on.
2128 Value is non-zero if successful. */
2131 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2133 unsigned long *color
;
2139 /* Change RGB values by specified FACTOR. Avoid overflow! */
2140 xassert (factor
>= 0);
2141 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2142 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2143 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2145 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2146 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2147 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2149 /* MAC_TODO: Map to palette and retry with delta if same? */
2150 /* MAC_TODO: Free colors (if using palette)? */
2161 /* Set up the foreground color for drawing relief lines of glyph
2162 string S. RELIEF is a pointer to a struct relief containing the GC
2163 with which lines will be drawn. Use a color that is FACTOR or
2164 DELTA lighter or darker than the relief's background which is found
2165 in S->f->output_data.x->relief_background. If such a color cannot
2166 be allocated, use DEFAULT_PIXEL, instead. */
2169 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2171 struct relief
*relief
;
2174 unsigned long default_pixel
;
2177 struct mac_output
*di
= f
->output_data
.mac
;
2178 unsigned long mask
= GCForeground
;
2179 unsigned long pixel
;
2180 unsigned long background
= di
->relief_background
;
2181 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2183 /* MAC_TODO: Free colors (if using palette)? */
2185 /* Allocate new color. */
2186 xgcv
.foreground
= default_pixel
;
2188 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2190 relief
->allocated_p
= 1;
2191 xgcv
.foreground
= relief
->pixel
= pixel
;
2194 if (relief
->gc
== 0)
2196 #if 0 /* MAC_TODO: stipple */
2197 xgcv
.stipple
= dpyinfo
->gray
;
2200 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2203 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2207 /* Set up colors for the relief lines around glyph string S. */
2210 x_setup_relief_colors (s
)
2211 struct glyph_string
*s
;
2213 struct mac_output
*di
= s
->f
->output_data
.mac
;
2214 unsigned long color
;
2216 if (s
->face
->use_box_color_for_shadows_p
)
2217 color
= s
->face
->box_color
;
2222 /* Get the background color of the face. */
2223 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2224 color
= xgcv
.background
;
2227 if (di
->white_relief
.gc
== 0
2228 || color
!= di
->relief_background
)
2230 di
->relief_background
= color
;
2231 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2232 WHITE_PIX_DEFAULT (s
->f
));
2233 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2234 BLACK_PIX_DEFAULT (s
->f
));
2239 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2240 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2241 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2242 relief. LEFT_P non-zero means draw a relief on the left side of
2243 the rectangle. RIGHT_P non-zero means draw a relief on the right
2244 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2248 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2249 raised_p
, left_p
, right_p
, clip_rect
)
2251 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
2258 gc
= f
->output_data
.mac
->white_relief
.gc
;
2260 gc
= f
->output_data
.mac
->black_relief
.gc
;
2261 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
2264 for (i
= 0; i
< width
; ++i
)
2265 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2266 left_x
+ i
* left_p
, top_y
+ i
,
2267 right_x
+ 1 - i
* right_p
, top_y
+ i
);
2271 for (i
= 0; i
< width
; ++i
)
2272 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2273 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2275 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2277 gc
= f
->output_data
.mac
->black_relief
.gc
;
2279 gc
= f
->output_data
.mac
->white_relief
.gc
;
2280 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2284 for (i
= 0; i
< width
; ++i
)
2285 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2286 left_x
+ i
* left_p
, bottom_y
- i
,
2287 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
2291 for (i
= 0; i
< width
; ++i
)
2292 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2293 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
2295 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2299 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2300 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2301 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2302 left side of the rectangle. RIGHT_P non-zero means draw a line
2303 on the right side of the rectangle. CLIP_RECT is the clipping
2304 rectangle to use when drawing. */
2307 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2308 left_p
, right_p
, clip_rect
)
2309 struct glyph_string
*s
;
2310 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
2315 xgcv
.foreground
= s
->face
->box_color
;
2316 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2319 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2320 left_x
, top_y
, right_x
- left_x
, width
);
2324 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2325 left_x
, top_y
, width
, bottom_y
- top_y
);
2328 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2329 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
2333 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2334 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
2336 mac_reset_clipping (s
->display
, s
->window
);
2340 /* Draw a box around glyph string S. */
2343 x_draw_glyph_string_box (s
)
2344 struct glyph_string
*s
;
2346 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2347 int left_p
, right_p
;
2348 struct glyph
*last_glyph
;
2351 last_x
= window_box_right (s
->w
, s
->area
);
2352 if (s
->row
->full_width_p
2353 && !s
->w
->pseudo_window_p
)
2355 last_x
+= FRAME_X_RIGHT_FRINGE_WIDTH (s
->f
);
2356 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s
->f
))
2357 last_x
+= FRAME_SCROLL_BAR_WIDTH (s
->f
) * CANON_X_UNIT (s
->f
);
2360 /* The glyph that may have a right box line. */
2361 last_glyph
= (s
->cmp
|| s
->img
2363 : s
->first_glyph
+ s
->nchars
- 1);
2365 width
= abs (s
->face
->box_line_width
);
2366 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2368 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2370 : min (last_x
, s
->x
+ s
->background_width
) - 1));
2372 bottom_y
= top_y
+ s
->height
- 1;
2374 left_p
= (s
->first_glyph
->left_box_line_p
2375 || (s
->hl
== DRAW_MOUSE_FACE
2377 || s
->prev
->hl
!= s
->hl
)));
2378 right_p
= (last_glyph
->right_box_line_p
2379 || (s
->hl
== DRAW_MOUSE_FACE
2381 || s
->next
->hl
!= s
->hl
)));
2383 get_glyph_string_clip_rect (s
, &clip_rect
);
2385 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2386 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2387 left_p
, right_p
, &clip_rect
);
2390 x_setup_relief_colors (s
);
2391 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2392 width
, raised_p
, left_p
, right_p
, &clip_rect
);
2397 /* Draw foreground of image glyph string S. */
2400 x_draw_image_foreground (s
)
2401 struct glyph_string
*s
;
2404 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2406 /* If first glyph of S has a left box line, start drawing it to the
2407 right of that line. */
2408 if (s
->face
->box
!= FACE_NO_BOX
2409 && s
->first_glyph
->left_box_line_p
)
2410 x
= s
->x
+ abs (s
->face
->box_line_width
);
2414 /* If there is a margin around the image, adjust x- and y-position
2416 x
+= s
->img
->hmargin
;
2417 y
+= s
->img
->vmargin
;
2421 #if 0 /* MAC_TODO: image mask */
2424 /* We can't set both a clip mask and use XSetClipRectangles
2425 because the latter also sets a clip mask. We also can't
2426 trust on the shape extension to be available
2427 (XShapeCombineRegion). So, compute the rectangle to draw
2429 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
2432 XRectangle clip_rect
, image_rect
, r
;
2434 xgcv
.clip_mask
= s
->img
->mask
;
2435 xgcv
.clip_x_origin
= x
;
2436 xgcv
.clip_y_origin
= y
;
2437 xgcv
.function
= GXcopy
;
2438 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
2440 get_glyph_string_clip_rect (s
, &clip_rect
);
2443 image_rect
.width
= s
->img
->width
;
2444 image_rect
.height
= s
->img
->height
;
2445 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2446 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2447 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
2450 #endif /* MAC_TODO */
2452 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2453 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2455 /* When the image has a mask, we can expect that at
2456 least part of a mouse highlight or a block cursor will
2457 be visible. If the image doesn't have a mask, make
2458 a block cursor visible by drawing a rectangle around
2459 the image. I believe it's looking better if we do
2460 nothing here for mouse-face. */
2461 if (s
->hl
== DRAW_CURSOR
)
2463 int r
= s
->img
->relief
;
2465 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2466 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
2471 /* Draw a rectangle if image could not be loaded. */
2472 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2473 s
->img
->width
- 1, s
->img
->height
- 1);
2478 /* Draw a relief around the image glyph string S. */
2481 x_draw_image_relief (s
)
2482 struct glyph_string
*s
;
2484 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2487 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2489 /* If first glyph of S has a left box line, start drawing it to the
2490 right of that line. */
2491 if (s
->face
->box
!= FACE_NO_BOX
2492 && s
->first_glyph
->left_box_line_p
)
2493 x
= s
->x
+ abs (s
->face
->box_line_width
);
2497 /* If there is a margin around the image, adjust x- and y-position
2499 x
+= s
->img
->hmargin
;
2500 y
+= s
->img
->vmargin
;
2502 if (s
->hl
== DRAW_IMAGE_SUNKEN
2503 || s
->hl
== DRAW_IMAGE_RAISED
)
2505 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2506 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2510 thick
= abs (s
->img
->relief
);
2511 raised_p
= s
->img
->relief
> 0;
2516 x1
= x
+ s
->img
->width
+ thick
- 1;
2517 y1
= y
+ s
->img
->height
+ thick
- 1;
2519 x_setup_relief_colors (s
);
2520 get_glyph_string_clip_rect (s
, &r
);
2521 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
2525 /* Draw the foreground of image glyph string S to PIXMAP. */
2528 x_draw_image_foreground_1 (s
, pixmap
)
2529 struct glyph_string
*s
;
2533 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
2535 /* If first glyph of S has a left box line, start drawing it to the
2536 right of that line. */
2537 if (s
->face
->box
!= FACE_NO_BOX
2538 && s
->first_glyph
->left_box_line_p
)
2539 x
= abs (s
->face
->box_line_width
);
2543 /* If there is a margin around the image, adjust x- and y-position
2545 x
+= s
->img
->hmargin
;
2546 y
+= s
->img
->vmargin
;
2550 #if 0 /* MAC_TODO: image mask */
2553 /* We can't set both a clip mask and use XSetClipRectangles
2554 because the latter also sets a clip mask. We also can't
2555 trust on the shape extension to be available
2556 (XShapeCombineRegion). So, compute the rectangle to draw
2558 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
2562 xgcv
.clip_mask
= s
->img
->mask
;
2563 xgcv
.clip_x_origin
= x
;
2564 xgcv
.clip_y_origin
= y
;
2565 xgcv
.function
= GXcopy
;
2566 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
2568 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2569 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2570 XSetClipMask (s
->display
, s
->gc
, None
);
2573 #endif /* MAC_TODO */
2575 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2576 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2578 /* When the image has a mask, we can expect that at
2579 least part of a mouse highlight or a block cursor will
2580 be visible. If the image doesn't have a mask, make
2581 a block cursor visible by drawing a rectangle around
2582 the image. I believe it's looking better if we do
2583 nothing here for mouse-face. */
2584 if (s
->hl
== DRAW_CURSOR
)
2586 int r
= s
->img
->relief
;
2588 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
2589 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
2594 /* Draw a rectangle if image could not be loaded. */
2595 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2596 s
->img
->width
- 1, s
->img
->height
- 1);
2600 /* Draw part of the background of glyph string S. X, Y, W, and H
2601 give the rectangle to draw. */
2604 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2605 struct glyph_string
*s
;
2608 #if 0 /* MAC_TODO: stipple */
2611 /* Fill background with a stipple pattern. */
2612 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2613 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2614 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2617 #endif /* MAC_TODO */
2618 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2622 /* Draw image glyph string S.
2625 s->x +-------------------------
2628 | +-------------------------
2631 | | +-------------------
2637 x_draw_image_glyph_string (s
)
2638 struct glyph_string
*s
;
2641 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2642 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2646 height
= s
->height
- 2 * box_line_vwidth
;
2648 /* Fill background with face under the image. Do it only if row is
2649 taller than image or if image has a clip mask to reduce
2651 s
->stippled_p
= s
->face
->stipple
!= 0;
2652 if (height
> s
->img
->height
2655 #if 0 /* TODO: image mask */
2658 || s
->img
->pixmap
== 0
2659 || s
->width
!= s
->background_width
)
2661 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
2662 x
= s
->x
+ box_line_hwidth
;
2666 y
= s
->y
+ box_line_vwidth
;
2667 #if 0 /* TODO: image mask */
2670 /* Create a pixmap as large as the glyph string. Fill it
2671 with the background color. Copy the image to it, using
2672 its mask. Copy the temporary pixmap to the display. */
2673 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
2674 int depth
= DefaultDepthOfScreen (screen
);
2676 /* Create a pixmap as large as the glyph string. */
2677 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2678 s
->background_width
,
2681 /* Don't clip in the following because we're working on the
2683 XSetClipMask (s
->display
, s
->gc
, None
);
2685 /* Fill the pixmap with the background color/stipple. */
2688 /* Fill background with a stipple pattern. */
2689 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2690 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2691 0, 0, s
->background_width
, s
->height
);
2692 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2697 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2699 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2700 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2701 0, 0, s
->background_width
, s
->height
);
2702 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2707 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2709 s
->background_filled_p
= 1;
2712 /* Draw the foreground. */
2715 x_draw_image_foreground_1 (s
, pixmap
);
2716 x_set_glyph_string_clipping (s
);
2717 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2718 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2719 mac_reset_clipping (s
->display
, s
->window
);
2720 XFreePixmap (s
->display
, pixmap
);
2723 x_draw_image_foreground (s
);
2725 /* If we must draw a relief around the image, do it. */
2727 || s
->hl
== DRAW_IMAGE_RAISED
2728 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2729 x_draw_image_relief (s
);
2733 /* Draw stretch glyph string S. */
2736 x_draw_stretch_glyph_string (s
)
2737 struct glyph_string
*s
;
2739 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2740 s
->stippled_p
= s
->face
->stipple
!= 0;
2742 if (s
->hl
== DRAW_CURSOR
2743 && !x_stretch_cursor_p
)
2745 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2746 as wide as the stretch glyph. */
2747 int width
= min (CANON_X_UNIT (s
->f
), s
->background_width
);
2750 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2752 /* Clear rest using the GC of the original non-cursor face. */
2753 if (width
< s
->background_width
)
2755 GC gc
= s
->face
->gc
;
2756 int x
= s
->x
+ width
, y
= s
->y
;
2757 int w
= s
->background_width
- width
, h
= s
->height
;
2760 if (s
->row
->mouse_face_p
2761 && cursor_in_mouse_face_p (s
->w
))
2763 x_set_mouse_face_gc (s
);
2769 get_glyph_string_clip_rect (s
, &r
);
2770 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2772 #if 0 /* MAC_TODO: stipple */
2773 if (s
->face
->stipple
)
2775 /* Fill background with a stipple pattern. */
2776 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2777 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2778 XSetFillStyle (s
->display
, gc
, FillSolid
);
2781 #endif /* MAC_TODO */
2784 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
2785 XSetForeground (s
->display
, gc
, xgcv
.background
);
2786 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2787 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
2790 mac_reset_clipping (s
->display
, s
->window
);
2793 else if (!s
->background_filled_p
)
2794 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2797 s
->background_filled_p
= 1;
2801 /* Draw glyph string S. */
2804 x_draw_glyph_string (s
)
2805 struct glyph_string
*s
;
2807 int relief_drawn_p
= 0;
2809 /* If S draws into the background of its successor, draw the
2810 background of the successor first so that S can draw into it.
2811 This makes S->next use XDrawString instead of XDrawImageString. */
2812 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
2814 xassert (s
->next
->img
== NULL
);
2815 x_set_glyph_string_gc (s
->next
);
2816 x_set_glyph_string_clipping (s
->next
);
2817 x_draw_glyph_string_background (s
->next
, 1);
2821 /* Set up S->gc, set clipping and draw S. */
2822 x_set_glyph_string_gc (s
);
2824 /* Draw relief (if any) in advance for char/composition so that the
2825 glyph string can be drawn over it. */
2826 if (!s
->for_overlaps_p
2827 && s
->face
->box
!= FACE_NO_BOX
2828 && (s
->first_glyph
->type
== CHAR_GLYPH
2829 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
2832 x_set_glyph_string_clipping (s
);
2833 x_draw_glyph_string_background (s
, 1);
2834 x_draw_glyph_string_box (s
);
2835 x_set_glyph_string_clipping (s
);
2839 x_set_glyph_string_clipping (s
);
2841 switch (s
->first_glyph
->type
)
2844 x_draw_image_glyph_string (s
);
2848 x_draw_stretch_glyph_string (s
);
2852 if (s
->for_overlaps_p
)
2853 s
->background_filled_p
= 1;
2855 x_draw_glyph_string_background (s
, 0);
2856 x_draw_glyph_string_foreground (s
);
2859 case COMPOSITE_GLYPH
:
2860 if (s
->for_overlaps_p
|| s
->gidx
> 0)
2861 s
->background_filled_p
= 1;
2863 x_draw_glyph_string_background (s
, 1);
2864 x_draw_composite_glyph_string_foreground (s
);
2871 if (!s
->for_overlaps_p
)
2873 /* Draw underline. */
2874 if (s
->face
->underline_p
)
2876 unsigned long h
= 1;
2877 unsigned long dy
= s
->height
- h
;
2879 if (s
->face
->underline_defaulted_p
)
2880 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2885 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2886 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
2887 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2889 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2893 /* Draw overline. */
2894 if (s
->face
->overline_p
)
2896 unsigned long dy
= 0, h
= 1;
2898 if (s
->face
->overline_color_defaulted_p
)
2899 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2904 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2905 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
2906 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2908 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2912 /* Draw strike-through. */
2913 if (s
->face
->strike_through_p
)
2915 unsigned long h
= 1;
2916 unsigned long dy
= (s
->height
- h
) / 2;
2918 if (s
->face
->strike_through_color_defaulted_p
)
2919 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2924 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2925 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
2926 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2928 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2933 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
2934 x_draw_glyph_string_box (s
);
2937 /* Reset clipping. */
2938 mac_reset_clipping (s
->display
, s
->window
);
2941 /* Shift display to make room for inserted glyphs. */
2944 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
2946 int x
, y
, width
, height
, shift_by
;
2948 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2949 f
->output_data
.mac
->normal_gc
,
2950 x
, y
, width
, height
,
2955 /* Delete N glyphs at the nominal cursor position. Not implemented
2966 /* Clear entire frame. If updating_frame is non-null, clear that
2967 frame. Otherwise clear the selected frame. */
2977 f
= SELECTED_FRAME ();
2979 /* Clearing the frame will erase any cursor, so mark them all as no
2981 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2982 output_cursor
.hpos
= output_cursor
.vpos
= 0;
2983 output_cursor
.x
= -1;
2985 /* We don't set the output cursor here because there will always
2986 follow an explicit cursor_to. */
2988 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2990 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
2991 /* We have to clear the scroll bars, too. If we have changed
2992 colors or something like that, then they should be notified. */
2993 x_scroll_bar_clear (f
);
2996 XFlush (FRAME_MAC_DISPLAY (f
));
3002 /* Invert the middle quarter of the frame for .15 sec. */
3004 /* We use the select system call to do the waiting, so we have to make
3005 sure it's available. If it isn't, we just won't do visual bells. */
3007 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3009 /* Subtract the `struct timeval' values X and Y, storing the result in
3010 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3013 timeval_subtract (result
, x
, y
)
3014 struct timeval
*result
, x
, y
;
3016 /* Perform the carry for the later subtraction by updating y. This
3017 is safer because on some systems the tv_sec member is unsigned. */
3018 if (x
.tv_usec
< y
.tv_usec
)
3020 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3021 y
.tv_usec
-= 1000000 * nsec
;
3025 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3027 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3028 y
.tv_usec
+= 1000000 * nsec
;
3032 /* Compute the time remaining to wait. tv_usec is certainly
3034 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3035 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3037 /* Return indication of whether the result should be considered
3039 return x
.tv_sec
< y
.tv_sec
;
3051 struct timeval wakeup
;
3053 EMACS_GET_TIME (wakeup
);
3055 /* Compute time to wait until, propagating carry from usecs. */
3056 wakeup
.tv_usec
+= 150000;
3057 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3058 wakeup
.tv_usec
%= 1000000;
3060 /* Keep waiting until past the time wakeup. */
3063 struct timeval timeout
;
3065 EMACS_GET_TIME (timeout
);
3067 /* In effect, timeout = wakeup - timeout.
3068 Break if result would be negative. */
3069 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3072 /* Try to wait that long--but we might wake up sooner. */
3073 select (0, NULL
, NULL
, NULL
, &timeout
);
3082 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3085 /* Make audible bell. */
3090 struct frame
*f
= SELECTED_FRAME ();
3092 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3100 XFlush (FRAME_MAC_DISPLAY (f
));
3107 /* Specify how many text lines, from the top of the window,
3108 should be affected by insert-lines and delete-lines operations.
3109 This, and those operations, are used only within an update
3110 that is bounded by calls to x_update_begin and x_update_end. */
3113 XTset_terminal_window (n
)
3116 /* This function intentionally left blank. */
3121 /***********************************************************************
3123 ***********************************************************************/
3125 /* Perform an insert-lines or delete-lines operation, inserting N
3126 lines or deleting -N lines at vertical position VPOS. */
3129 x_ins_del_lines (vpos
, n
)
3136 /* Scroll part of the display as described by RUN. */
3139 x_scroll_run (w
, run
)
3143 struct frame
*f
= XFRAME (w
->frame
);
3144 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3146 /* Get frame-relative bounding box of the text display area of W,
3147 without mode lines. Include in this box the left and right
3149 window_box (w
, -1, &x
, &y
, &width
, &height
);
3150 width
+= FRAME_X_FRINGE_WIDTH (f
);
3151 x
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
3153 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3154 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3155 bottom_y
= y
+ height
;
3159 /* Scrolling up. Make sure we don't copy part of the mode
3160 line at the bottom. */
3161 if (from_y
+ run
->height
> bottom_y
)
3162 height
= bottom_y
- from_y
;
3164 height
= run
->height
;
3168 /* Scolling down. Make sure we don't copy over the mode line.
3170 if (to_y
+ run
->height
> bottom_y
)
3171 height
= bottom_y
- to_y
;
3173 height
= run
->height
;
3178 /* Cursor off. Will be switched on again in x_update_window_end. */
3182 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3183 f
->output_data
.mac
->normal_gc
,
3193 /***********************************************************************
3195 ***********************************************************************/
3202 x_update_cursor (f
, 1);
3206 frame_unhighlight (f
)
3209 x_update_cursor (f
, 1);
3212 /* The focus has changed. Update the frames as necessary to reflect
3213 the new situation. Note that we can't change the selected frame
3214 here, because the Lisp code we are interrupting might become confused.
3215 Each event gets marked with the frame in which it occurred, so the
3216 Lisp code can tell when the switch took place by examining the events. */
3219 x_new_focus_frame (dpyinfo
, frame
)
3220 struct x_display_info
*dpyinfo
;
3221 struct frame
*frame
;
3223 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3225 if (frame
!= dpyinfo
->x_focus_frame
)
3227 /* Set this before calling other routines, so that they see
3228 the correct value of x_focus_frame. */
3229 dpyinfo
->x_focus_frame
= frame
;
3231 if (old_focus
&& old_focus
->auto_lower
)
3232 x_lower_frame (old_focus
);
3235 selected_frame
= frame
;
3236 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3238 Fselect_window (selected_frame
->selected_window
);
3239 choose_minibuf_frame ();
3242 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3243 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3245 pending_autoraise_frame
= 0;
3248 x_frame_rehighlight (dpyinfo
);
3251 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3254 x_mouse_leave (dpyinfo
)
3255 struct x_display_info
*dpyinfo
;
3257 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3260 /* The focus has changed, or we have redirected a frame's focus to
3261 another frame (this happens when a frame uses a surrogate
3262 mini-buffer frame). Shift the highlight as appropriate.
3264 The FRAME argument doesn't necessarily have anything to do with which
3265 frame is being highlighted or un-highlighted; we only use it to find
3266 the appropriate X display info. */
3269 XTframe_rehighlight (frame
)
3270 struct frame
*frame
;
3274 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3278 x_frame_rehighlight (dpyinfo
)
3279 struct x_display_info
*dpyinfo
;
3281 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3283 if (dpyinfo
->x_focus_frame
)
3285 dpyinfo
->x_highlight_frame
3286 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3287 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3288 : dpyinfo
->x_focus_frame
);
3289 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3291 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3292 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3296 dpyinfo
->x_highlight_frame
= 0;
3298 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3301 frame_unhighlight (old_highlight
);
3302 if (dpyinfo
->x_highlight_frame
)
3303 frame_highlight (dpyinfo
->x_highlight_frame
);
3309 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3311 #if 0 /* MAC_TODO */
3312 /* Initialize mode_switch_bit and modifier_meaning. */
3314 x_find_modifier_meanings (dpyinfo
)
3315 struct x_display_info
*dpyinfo
;
3317 int min_code
, max_code
;
3320 XModifierKeymap
*mods
;
3322 dpyinfo
->meta_mod_mask
= 0;
3323 dpyinfo
->shift_lock_mask
= 0;
3324 dpyinfo
->alt_mod_mask
= 0;
3325 dpyinfo
->super_mod_mask
= 0;
3326 dpyinfo
->hyper_mod_mask
= 0;
3329 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3331 min_code
= dpyinfo
->display
->min_keycode
;
3332 max_code
= dpyinfo
->display
->max_keycode
;
3335 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3336 min_code
, max_code
- min_code
+ 1,
3338 mods
= XGetModifierMapping (dpyinfo
->display
);
3340 /* Scan the modifier table to see which modifier bits the Meta and
3341 Alt keysyms are on. */
3343 int row
, col
; /* The row and column in the modifier table. */
3345 for (row
= 3; row
< 8; row
++)
3346 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3349 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3351 /* Zeroes are used for filler. Skip them. */
3355 /* Are any of this keycode's keysyms a meta key? */
3359 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3361 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3367 dpyinfo
->meta_mod_mask
|= (1 << row
);
3372 dpyinfo
->alt_mod_mask
|= (1 << row
);
3377 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3382 dpyinfo
->super_mod_mask
|= (1 << row
);
3386 /* Ignore this if it's not on the lock modifier. */
3387 if ((1 << row
) == LockMask
)
3388 dpyinfo
->shift_lock_mask
= LockMask
;
3396 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3397 if (! dpyinfo
->meta_mod_mask
)
3399 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3400 dpyinfo
->alt_mod_mask
= 0;
3403 /* If some keys are both alt and meta,
3404 make them just meta, not alt. */
3405 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3407 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3410 XFree ((char *) syms
);
3411 XFreeModifiermap (mods
);
3414 #endif /* MAC_TODO */
3416 /* Convert between the modifier bits X uses and the modifier bits
3420 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3421 struct x_display_info
*dpyinfo
;
3422 unsigned short state
;
3424 return (((state
& shiftKey
) ? shift_modifier
: 0)
3425 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3426 | ((state
& cmdKey
) ? meta_modifier
: 0)
3427 | ((state
& optionKey
) ? alt_modifier
: 0));
3430 #if 0 /* MAC_TODO */
3431 static unsigned short
3432 x_emacs_to_x_modifiers (dpyinfo
, state
)
3433 struct x_display_info
*dpyinfo
;
3436 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3437 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3438 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3439 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3440 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3441 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3443 #endif /* MAC_TODO */
3445 /* Convert a keysym to its name. */
3448 x_get_keysym_name (keysym
)
3455 value
= XKeysymToString (keysym
);
3466 /* Mouse clicks and mouse movement. Rah. */
3468 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3470 If the event is a button press, then note that we have grabbed
3474 construct_mouse_click (result
, event
, f
)
3475 struct input_event
*result
;
3481 result
->kind
= MOUSE_CLICK_EVENT
;
3482 result
->code
= 0; /* only one mouse button */
3483 result
->timestamp
= event
->when
;
3484 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3486 mouseLoc
= event
->where
;
3488 #if TARGET_API_MAC_CARBON
3489 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
3491 SetPort (FRAME_MAC_WINDOW (f
));
3494 GlobalToLocal (&mouseLoc
);
3495 XSETINT (result
->x
, mouseLoc
.h
);
3496 XSETINT (result
->y
, mouseLoc
.v
);
3498 XSETFRAME (result
->frame_or_window
, f
);
3505 /* Function to report a mouse movement to the mainstream Emacs code.
3506 The input handler calls this.
3508 We have received a mouse movement event, which is given in *event.
3509 If the mouse is over a different glyph than it was last time, tell
3510 the mainstream emacs code by setting mouse_moved. If not, ask for
3511 another motion event, so we can check again the next time it moves. */
3513 static Point last_mouse_motion_position
;
3514 static Lisp_Object last_mouse_motion_frame
;
3517 note_mouse_movement (frame
, pos
)
3521 #if TARGET_API_MAC_CARBON
3525 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3526 last_mouse_motion_position
= *pos
;
3527 XSETFRAME (last_mouse_motion_frame
, frame
);
3529 #if TARGET_API_MAC_CARBON
3530 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3532 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3535 frame
->mouse_moved
= 1;
3536 last_mouse_scroll_bar
= Qnil
;
3537 note_mouse_highlight (frame
, -1, -1);
3539 /* Has the mouse moved off the glyph it was on at the last sighting? */
3540 else if (pos
->h
< last_mouse_glyph
.left
3541 || pos
->h
>= last_mouse_glyph
.right
3542 || pos
->v
< last_mouse_glyph
.top
3543 || pos
->v
>= last_mouse_glyph
.bottom
)
3545 frame
->mouse_moved
= 1;
3546 last_mouse_scroll_bar
= Qnil
;
3547 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3551 /* This is used for debugging, to turn off note_mouse_highlight. */
3553 int disable_mouse_highlight
;
3557 /************************************************************************
3559 ************************************************************************/
3561 static struct scroll_bar
*x_window_to_scroll_bar ();
3562 static void x_scroll_bar_report_motion ();
3563 static void x_check_fullscreen
P_ ((struct frame
*));
3564 static void x_check_fullscreen_move
P_ ((struct frame
*));
3565 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3568 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3571 redo_mouse_highlight ()
3573 if (!NILP (last_mouse_motion_frame
)
3574 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3575 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3576 last_mouse_motion_position
.h
,
3577 last_mouse_motion_position
.v
);
3581 /* Try to determine frame pixel position and size of the glyph under
3582 frame pixel coordinates X/Y on frame F . Return the position and
3583 size in *RECT. Value is non-zero if we could compute these
3587 glyph_rect (f
, x
, y
, rect
)
3594 window
= window_from_coordinates (f
, x
, y
, 0, 0);
3597 struct window
*w
= XWINDOW (window
);
3598 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3599 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3601 frame_to_window_pixel_xy (w
, &x
, &y
);
3603 for (; r
< end
&& r
->enabled_p
; ++r
)
3604 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3606 /* Found the row at y. */
3607 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3608 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3611 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3612 rect
->bottom
= rect
->top
+ r
->height
;
3616 /* x is to the left of the first glyph in the row. */
3617 rect
->left
= XINT (w
->left
);
3618 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3622 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3623 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3625 /* x is on a glyph. */
3626 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3627 rect
->right
= rect
->left
+ g
->pixel_width
;
3631 /* x is to the right of the last glyph in the row. */
3632 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3633 rect
->right
= XINT (w
->left
) + XINT (w
->width
);
3638 /* The y is not on any row. */
3642 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3644 /* Record the position of the mouse in last_mouse_glyph. */
3646 remember_mouse_glyph (f1
, gx
, gy
)
3650 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3652 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3653 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3655 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
3656 round down even for negative values. */
3662 /* This was the original code from XTmouse_position, but it seems
3663 to give the position of the glyph diagonally next to the one
3664 the mouse is over. */
3665 gx
= (gx
+ width
- 1) / width
* width
;
3666 gy
= (gy
+ height
- 1) / height
* height
;
3668 gx
= gx
/ width
* width
;
3669 gy
= gy
/ height
* height
;
3672 last_mouse_glyph
.left
= gx
;
3673 last_mouse_glyph
.top
= gy
;
3674 last_mouse_glyph
.right
= gx
+ width
;
3675 last_mouse_glyph
.bottom
= gy
+ height
;
3680 /* Return the current position of the mouse.
3681 *fp should be a frame which indicates which display to ask about.
3683 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3684 and *part to the frame, window, and scroll bar part that the mouse
3685 is over. Set *x and *y to the portion and whole of the mouse's
3686 position on the scroll bar.
3688 If the mouse movement started elsewhere, set *fp to the frame the
3689 mouse is on, *bar_window to nil, and *x and *y to the character cell
3692 Set *time to the server time-stamp for the time at which the mouse
3693 was at this position.
3695 Don't store anything if we don't have a valid set of values to report.
3697 This clears the mouse_moved flag, so we can wait for the next mouse
3701 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3704 Lisp_Object
*bar_window
;
3705 enum scroll_bar_part
*part
;
3707 unsigned long *time
;
3710 int ignore1
, ignore2
;
3711 WindowPtr wp
= FrontWindow ();
3713 Lisp_Object frame
, tail
;
3715 if (is_emacs_window(wp
))
3716 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
3720 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3721 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3724 /* Clear the mouse-moved flag for every frame on this display. */
3725 FOR_EACH_FRAME (tail
, frame
)
3726 XFRAME (frame
)->mouse_moved
= 0;
3728 last_mouse_scroll_bar
= Qnil
;
3730 #if TARGET_API_MAC_CARBON
3731 SetPort (GetWindowPort (wp
));
3736 GetMouse (&mouse_pos
);
3738 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3739 &last_mouse_glyph
, insist
);
3742 *part
= scroll_bar_handle
;
3744 XSETINT (*x
, mouse_pos
.h
);
3745 XSETINT (*y
, mouse_pos
.v
);
3746 *time
= last_mouse_movement_time
;
3753 /***********************************************************************
3755 ***********************************************************************/
3757 /* Handle mouse button event on the tool-bar of frame F, at
3758 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3762 mac_handle_tool_bar_click (f
, button_event
)
3764 EventRecord
*button_event
;
3766 int x
= button_event
->where
.h
;
3767 int y
= button_event
->where
.v
;
3769 if (button_event
->what
== mouseDown
)
3770 handle_tool_bar_click (f
, x
, y
, 1, 0);
3772 handle_tool_bar_click (f
, x
, y
, 0,
3773 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3774 button_event
->modifiers
));
3778 /************************************************************************
3779 Scroll bars, general
3780 ************************************************************************/
3782 /* Create a scroll bar and return the scroll bar vector for it. W is
3783 the Emacs window on which to create the scroll bar. TOP, LEFT,
3784 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
3787 static struct scroll_bar
*
3788 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
3790 int top
, left
, width
, height
, disp_top
, disp_height
;
3792 struct frame
*f
= XFRAME (w
->frame
);
3793 struct scroll_bar
*bar
3794 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
3802 r
.right
= left
+ width
;
3803 r
.bottom
= disp_top
+ disp_height
;
3805 #ifdef TARGET_API_MAC_CARBON
3806 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
3807 kControlScrollBarProc
, 0L);
3809 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
3812 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
3813 SetControlReference (ch
, (long) bar
);
3815 XSETWINDOW (bar
->window
, w
);
3816 XSETINT (bar
->top
, top
);
3817 XSETINT (bar
->left
, left
);
3818 XSETINT (bar
->width
, width
);
3819 XSETINT (bar
->height
, height
);
3820 XSETINT (bar
->start
, 0);
3821 XSETINT (bar
->end
, 0);
3822 bar
->dragging
= Qnil
;
3824 /* Add bar to its frame's list of scroll bars. */
3825 bar
->next
= FRAME_SCROLL_BARS (f
);
3827 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
3828 if (!NILP (bar
->next
))
3829 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
3836 /* Draw BAR's handle in the proper position.
3838 If the handle is already drawn from START to END, don't bother
3839 redrawing it, unless REBUILD is non-zero; in that case, always
3840 redraw it. (REBUILD is handy for drawing the handle after expose
3843 Normally, we want to constrain the start and end of the handle to
3844 fit inside its rectangle, but if the user is dragging the scroll
3845 bar handle, we want to let them drag it down all the way, so that
3846 the bar's top is as far down as it goes; otherwise, there's no way
3847 to move to the very end of the buffer. */
3850 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
3851 struct scroll_bar
*bar
;
3855 int dragging
= ! NILP (bar
->dragging
);
3856 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
3857 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3858 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
3859 int length
= end
- start
;
3861 /* If the display is already accurate, do nothing. */
3863 && start
== XINT (bar
->start
)
3864 && end
== XINT (bar
->end
))
3869 /* Make sure the values are reasonable, and try to preserve the
3870 distance between start and end. */
3873 else if (start
> top_range
)
3875 end
= start
+ length
;
3879 else if (end
> top_range
&& ! dragging
)
3882 /* Store the adjusted setting in the scroll bar. */
3883 XSETINT (bar
->start
, start
);
3884 XSETINT (bar
->end
, end
);
3886 /* Clip the end position, just for display. */
3887 if (end
> top_range
)
3890 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
3891 top positions, to make sure the handle is always at least that
3892 many pixels tall. */
3893 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
3895 SetControlMinimum (ch
, 0);
3896 /* Don't inadvertently activate deactivated scroll bars */
3897 if (GetControlMaximum (ch
) != -1)
3898 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
3900 SetControlValue (ch
, start
);
3901 #if TARGET_API_MAC_CARBON
3902 SetControlViewSize (ch
, end
- start
);
3909 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
3913 x_scroll_bar_remove (bar
)
3914 struct scroll_bar
*bar
;
3916 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3920 /* Destroy the Mac scroll bar control */
3921 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
3923 /* Disassociate this scroll bar from its window. */
3924 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
3929 /* Set the handle of the vertical scroll bar for WINDOW to indicate
3930 that we are displaying PORTION characters out of a total of WHOLE
3931 characters, starting at POSITION. If WINDOW has no scroll bar,
3934 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
3936 int portion
, whole
, position
;
3938 struct frame
*f
= XFRAME (w
->frame
);
3939 struct scroll_bar
*bar
;
3940 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
3941 int window_x
, window_y
, window_width
, window_height
;
3943 /* Get window dimensions. */
3944 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
3949 width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
3951 height
= window_height
;
3953 /* Compute the left edge of the scroll bar area. */
3954 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
3955 left
= XINT (w
->left
) + XINT (w
->width
) - FRAME_SCROLL_BAR_COLS (f
);
3957 left
= XFASTINT (w
->left
);
3958 left
*= CANON_X_UNIT (f
);
3959 left
+= FRAME_INTERNAL_BORDER_WIDTH (f
);
3961 /* Compute the width of the scroll bar which might be less than
3962 the width of the area reserved for the scroll bar. */
3963 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0)
3964 sb_width
= FRAME_SCROLL_BAR_PIXEL_WIDTH (f
);
3968 /* Compute the left edge of the scroll bar. */
3969 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
3970 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
3972 sb_left
= left
+ (width
- sb_width
) / 2;
3974 /* Adjustments according to Inside Macintosh to make it look nice */
3976 disp_height
= height
;
3982 else if (disp_top
== PIXEL_HEIGHT (f
) - 16)
3988 if (sb_left
+ sb_width
== PIXEL_WIDTH (f
))
3991 /* Does the scroll bar exist yet? */
3992 if (NILP (w
->vertical_scroll_bar
))
3995 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3996 left
, top
, width
, height
, 0);
3998 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4000 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4004 /* It may just need to be moved and resized. */
4007 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4008 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4012 /* If already correctly positioned, do nothing. */
4013 if (XINT (bar
->left
) == sb_left
4014 && XINT (bar
->top
) == top
4015 && XINT (bar
->width
) == sb_width
4016 && XINT (bar
->height
) == height
)
4020 /* Clear areas not covered by the scroll bar because it's not as
4021 wide as the area reserved for it . This makes sure a
4022 previous mode line display is cleared after C-x 2 C-x 1, for
4024 int area_width
= FRAME_SCROLL_BAR_COLS (f
) * CANON_X_UNIT (f
);
4025 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4026 left
, top
, area_width
, height
, 0);
4029 if (sb_left
+ sb_width
>= PIXEL_WIDTH (f
))
4030 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4031 sb_left
- 1, top
, 1, height
, 0);
4035 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4036 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4040 /* Remember new settings. */
4041 XSETINT (bar
->left
, sb_left
);
4042 XSETINT (bar
->top
, top
);
4043 XSETINT (bar
->width
, sb_width
);
4044 XSETINT (bar
->height
, height
);
4050 /* Set the scroll bar's current state, unless we're currently being
4052 if (NILP (bar
->dragging
))
4054 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4057 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4060 int start
= ((double) position
* top_range
) / whole
;
4061 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4062 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4068 /* The following three hooks are used when we're doing a thorough
4069 redisplay of the frame. We don't explicitly know which scroll bars
4070 are going to be deleted, because keeping track of when windows go
4071 away is a real pain - "Can you say set-window-configuration, boys
4072 and girls?" Instead, we just assert at the beginning of redisplay
4073 that *all* scroll bars are to be removed, and then save a scroll bar
4074 from the fiery pit when we actually redisplay its window. */
4076 /* Arrange for all scroll bars on FRAME to be removed at the next call
4077 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4078 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4081 XTcondemn_scroll_bars (frame
)
4084 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4085 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4088 bar
= FRAME_SCROLL_BARS (frame
);
4089 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4090 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4091 XSCROLL_BAR (bar
)->prev
= Qnil
;
4092 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4093 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4094 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4099 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4100 Note that WINDOW isn't necessarily condemned at all. */
4103 XTredeem_scroll_bar (window
)
4104 struct window
*window
;
4106 struct scroll_bar
*bar
;
4108 /* We can't redeem this window's scroll bar if it doesn't have one. */
4109 if (NILP (window
->vertical_scroll_bar
))
4112 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4114 /* Unlink it from the condemned list. */
4116 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4118 if (NILP (bar
->prev
))
4120 /* If the prev pointer is nil, it must be the first in one of
4122 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4123 /* It's not condemned. Everything's fine. */
4125 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4126 window
->vertical_scroll_bar
))
4127 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4129 /* If its prev pointer is nil, it must be at the front of
4130 one or the other! */
4134 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4136 if (! NILP (bar
->next
))
4137 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4139 bar
->next
= FRAME_SCROLL_BARS (f
);
4141 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4142 if (! NILP (bar
->next
))
4143 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4147 /* Remove all scroll bars on FRAME that haven't been saved since the
4148 last call to `*condemn_scroll_bars_hook'. */
4151 XTjudge_scroll_bars (f
)
4154 Lisp_Object bar
, next
;
4156 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4158 /* Clear out the condemned list now so we won't try to process any
4159 more events on the hapless scroll bars. */
4160 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4162 for (; ! NILP (bar
); bar
= next
)
4164 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4166 x_scroll_bar_remove (b
);
4169 b
->next
= b
->prev
= Qnil
;
4172 /* Now there should be no references to the condemned scroll bars,
4173 and they should get garbage-collected. */
4178 activate_scroll_bars (frame
)
4184 bar
= FRAME_SCROLL_BARS (frame
);
4185 while (! NILP (bar
))
4187 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4188 #ifdef TARGET_API_MAC_CARBON
4189 ActivateControl (ch
);
4191 SetControlMaximum (ch
,
4192 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4193 XINT (XSCROLL_BAR (bar
)
4196 bar
= XSCROLL_BAR (bar
)->next
;
4202 deactivate_scroll_bars (frame
)
4208 bar
= FRAME_SCROLL_BARS (frame
);
4209 while (! NILP (bar
))
4211 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4212 #ifdef TARGET_API_MAC_CARBON
4213 DeactivateControl (ch
);
4215 SetControlMaximum (ch
, XINT (-1));
4217 bar
= XSCROLL_BAR (bar
)->next
;
4221 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4222 is set to something other than NO_EVENT, it is enqueued.
4224 This may be called from a signal handler, so we have to ignore GC
4228 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4229 struct scroll_bar
*bar
;
4232 struct input_event
*bufp
;
4234 if (! GC_WINDOWP (bar
->window
))
4237 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4238 bufp
->frame_or_window
= bar
->window
;
4241 bar
->dragging
= Qnil
;
4245 case kControlUpButtonPart
:
4246 bufp
->part
= scroll_bar_up_arrow
;
4248 case kControlDownButtonPart
:
4249 bufp
->part
= scroll_bar_down_arrow
;
4251 case kControlPageUpPart
:
4252 bufp
->part
= scroll_bar_above_handle
;
4254 case kControlPageDownPart
:
4255 bufp
->part
= scroll_bar_below_handle
;
4257 #ifdef TARGET_API_MAC_CARBON
4260 case kControlIndicatorPart
:
4262 if (er
->what
== mouseDown
)
4263 bar
->dragging
= make_number (0);
4264 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4265 bufp
->part
= scroll_bar_handle
;
4271 /* Handle some mouse motion while someone is dragging the scroll bar.
4273 This may be called from a signal handler, so we have to ignore GC
4277 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4278 struct scroll_bar
*bar
;
4282 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4284 last_mouse_movement_time
= t
;
4287 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4289 /* If we're dragging the bar, display it. */
4290 if (! GC_NILP (bar
->dragging
))
4292 /* Where should the handle be now? */
4293 int new_start
= y_pos
- 24;
4295 if (new_start
!= XINT (bar
->start
))
4297 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4299 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4305 /* Return information to the user about the current position of the
4306 mouse on the scroll bar. */
4309 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4311 Lisp_Object
*bar_window
;
4312 enum scroll_bar_part
*part
;
4314 unsigned long *time
;
4316 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4317 WindowPtr wp
= FrontWindow ();
4319 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
4320 int win_y
, top_range
;
4322 #if TARGET_API_MAC_CARBON
4323 SetPort (GetWindowPort (wp
));
4328 GetMouse (&mouse_pos
);
4330 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4331 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4333 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4337 if (! NILP (bar
->dragging
))
4338 win_y
-= XINT (bar
->dragging
);
4342 if (win_y
> top_range
)
4346 *bar_window
= bar
->window
;
4348 if (! NILP (bar
->dragging
))
4349 *part
= scroll_bar_handle
;
4350 else if (win_y
< XINT (bar
->start
))
4351 *part
= scroll_bar_above_handle
;
4352 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4353 *part
= scroll_bar_handle
;
4355 *part
= scroll_bar_below_handle
;
4357 XSETINT (*x
, win_y
);
4358 XSETINT (*y
, top_range
);
4361 last_mouse_scroll_bar
= Qnil
;
4363 *time
= last_mouse_movement_time
;
4366 /***********************************************************************
4368 ***********************************************************************/
4370 /* Set clipping for output in glyph row ROW. W is the window in which
4371 we operate. GC is the graphics context to set clipping in.
4372 WHOLE_LINE_P non-zero means include the areas used for truncation
4373 mark display and alike in the clipping rectangle.
4375 ROW may be a text row or, e.g., a mode line. Text rows must be
4376 clipped to the interior of the window dedicated to text display,
4377 mode lines must be clipped to the whole window. */
4380 x_clip_to_row (w
, row
, gc
, whole_line_p
)
4382 struct glyph_row
*row
;
4386 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4388 int window_x
, window_y
, window_width
, window_height
;
4390 window_box (w
, -1, &window_x
, &window_y
, &window_width
, &window_height
);
4392 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4393 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4394 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4395 clip_rect
.right
= clip_rect
.left
+ window_width
;
4396 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4398 /* If clipping to the whole line, including trunc marks, extend
4399 the rectangle to the left and increase its width. */
4402 clip_rect
.left
-= FRAME_X_LEFT_FRINGE_WIDTH (f
);
4403 clip_rect
.right
+= FRAME_X_FRINGE_WIDTH (f
);
4406 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4410 /* Draw a hollow box cursor on window W in glyph row ROW. */
4413 x_draw_hollow_cursor (w
, row
)
4415 struct glyph_row
*row
;
4417 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4418 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4419 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4422 struct glyph
*cursor_glyph
;
4425 /* Compute frame-relative coordinates from window-relative
4427 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4428 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
4429 + row
->ascent
- w
->phys_cursor_ascent
);
4430 h
= row
->height
- 1;
4432 /* Get the glyph the cursor is on. If we can't tell because
4433 the current matrix is invalid or such, give up. */
4434 cursor_glyph
= get_phys_cursor_glyph (w
);
4435 if (cursor_glyph
== NULL
)
4438 /* Compute the width of the rectangle to draw. If on a stretch
4439 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4440 rectangle as wide as the glyph, but use a canonical character
4442 wd
= cursor_glyph
->pixel_width
- 1;
4443 if (cursor_glyph
->type
== STRETCH_GLYPH
4444 && !x_stretch_cursor_p
)
4445 wd
= min (CANON_X_UNIT (f
), wd
);
4447 /* The foreground of cursor_gc is typically the same as the normal
4448 background color, which can cause the cursor box to be invisible. */
4449 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4450 if (dpyinfo
->scratch_cursor_gc
)
4451 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4453 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4454 GCForeground
, &xgcv
);
4455 gc
= dpyinfo
->scratch_cursor_gc
;
4457 /* Set clipping, draw the rectangle, and reset clipping again. */
4458 x_clip_to_row (w
, row
, gc
, 0);
4459 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4460 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4464 /* Draw a bar cursor on window W in glyph row ROW.
4466 Implementation note: One would like to draw a bar cursor with an
4467 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4468 Unfortunately, I didn't find a font yet that has this property set.
4472 x_draw_bar_cursor (w
, row
, width
)
4474 struct glyph_row
*row
;
4477 /* If cursor hpos is out of bounds, don't draw garbage. This can
4478 happen in mini-buffer windows when switching between echo area
4479 glyphs and mini-buffer. */
4480 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
4482 struct frame
*f
= XFRAME (w
->frame
);
4483 struct glyph
*cursor_glyph
;
4491 cursor_glyph
= get_phys_cursor_glyph (w
);
4492 if (cursor_glyph
== NULL
)
4495 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
4496 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4497 mask
= GCForeground
| GCBackground
;
4498 dpy
= FRAME_MAC_DISPLAY (f
);
4499 window
= FRAME_MAC_WINDOW (f
);
4500 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4503 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4506 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4507 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4511 width
= FRAME_CURSOR_WIDTH (f
);
4513 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4514 x_clip_to_row (w
, row
, gc
, 0);
4515 XFillRectangle (dpy
, window
, gc
,
4517 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4518 min (cursor_glyph
->pixel_width
, width
),
4520 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4525 /* RIF: Define cursor CURSOR on frame F. */
4528 mac_define_frame_cursor (f
, cursor
)
4536 /* RIF: Clear area on frame F. */
4539 mac_clear_frame_area (f
, x
, y
, width
, height
)
4541 int x
, y
, width
, height
;
4543 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4544 x
, y
, width
, height
, 0);
4548 /* RIF: Draw cursor on window W. */
4551 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4553 struct glyph_row
*glyph_row
;
4555 int cursor_type
, cursor_width
;
4560 w
->phys_cursor_type
= cursor_type
;
4561 w
->phys_cursor_width
= cursor_width
;
4562 w
->phys_cursor_on_p
= 1;
4564 switch (cursor_type
)
4566 case HOLLOW_BOX_CURSOR
:
4567 x_draw_hollow_cursor (w
, glyph_row
);
4570 case FILLED_BOX_CURSOR
:
4571 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4575 /* TODO. For now, just draw bar cursor. */
4577 x_draw_bar_cursor (w
, glyph_row
, cursor_width
);
4592 #if 0 /* MAC_TODO: no icon support yet. */
4594 x_bitmap_icon (f
, icon
)
4600 if (FRAME_W32_WINDOW (f
) == 0)
4604 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4605 else if (STRINGP (icon
))
4606 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4607 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4608 else if (SYMBOLP (icon
))
4612 if (EQ (icon
, intern ("application")))
4613 name
= (LPCTSTR
) IDI_APPLICATION
;
4614 else if (EQ (icon
, intern ("hand")))
4615 name
= (LPCTSTR
) IDI_HAND
;
4616 else if (EQ (icon
, intern ("question")))
4617 name
= (LPCTSTR
) IDI_QUESTION
;
4618 else if (EQ (icon
, intern ("exclamation")))
4619 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4620 else if (EQ (icon
, intern ("asterisk")))
4621 name
= (LPCTSTR
) IDI_ASTERISK
;
4622 else if (EQ (icon
, intern ("winlogo")))
4623 name
= (LPCTSTR
) IDI_WINLOGO
;
4627 hicon
= LoadIcon (NULL
, name
);
4635 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4640 #endif /* MAC_TODO */
4642 /************************************************************************
4644 ************************************************************************/
4646 /* Display Error Handling functions not used on W32. Listing them here
4647 helps diff stay in step when comparing w32term.c with xterm.c.
4649 x_error_catcher (display, error)
4650 x_catch_errors (dpy)
4651 x_catch_errors_unwind (old_val)
4652 x_check_errors (dpy, format)
4653 x_had_errors_p (dpy)
4654 x_clear_errors (dpy)
4655 x_uncatch_errors (dpy, count)
4657 x_connection_signal (signalnum)
4658 x_connection_closed (dpy, error_message)
4659 x_error_quitter (display, error)
4660 x_error_handler (display, error)
4661 x_io_error_quitter (display)
4666 /* Changing the font of the frame. */
4668 /* Give frame F the font named FONTNAME as its default font, and
4669 return the full name of that font. FONTNAME may be a wildcard
4670 pattern; in that case, we choose some font that fits the pattern.
4671 The return value shows which font we chose. */
4674 x_new_font (f
, fontname
)
4676 register char *fontname
;
4678 struct font_info
*fontp
4679 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4684 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4685 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4686 FRAME_FONTSET (f
) = -1;
4688 /* Compute the scroll bar width in character columns. */
4689 if (f
->scroll_bar_pixel_width
> 0)
4691 int wid
= FONT_WIDTH (FRAME_FONT (f
));
4692 f
->scroll_bar_cols
= (f
->scroll_bar_pixel_width
+ wid
-1) / wid
;
4696 int wid
= FONT_WIDTH (FRAME_FONT (f
));
4697 f
->scroll_bar_cols
= (14 + wid
- 1) / wid
;
4700 /* Now make the frame display the given font. */
4701 if (FRAME_MAC_WINDOW (f
) != 0)
4703 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4704 f
->output_data
.mac
->font
);
4705 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4706 f
->output_data
.mac
->font
);
4707 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4708 f
->output_data
.mac
->font
);
4710 frame_update_line_height (f
);
4711 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4712 x_set_window_size (f
, 0, f
->width
, f
->height
);
4715 /* If we are setting a new frame's font for the first time,
4716 there are no faces yet, so this font's height is the line height. */
4717 f
->output_data
.mac
->line_height
= FONT_HEIGHT (FRAME_FONT (f
));
4719 return build_string (fontp
->full_name
);
4722 /* Give frame F the fontset named FONTSETNAME as its default font, and
4723 return the full name of that fontset. FONTSETNAME may be a wildcard
4724 pattern; in that case, we choose some fontset that fits the pattern.
4725 The return value shows which fontset we chose. */
4728 x_new_fontset (f
, fontsetname
)
4732 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
4738 if (FRAME_FONTSET (f
) == fontset
)
4739 /* This fontset is already set in frame F. There's nothing more
4741 return fontset_name (fontset
);
4743 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
4745 if (!STRINGP (result
))
4746 /* Can't load ASCII font. */
4749 /* Since x_new_font doesn't update any fontset information, do it now. */
4750 FRAME_FONTSET(f
) = fontset
;
4752 return build_string (fontsetname
);
4756 /***********************************************************************
4757 TODO: W32 Input Methods
4758 ***********************************************************************/
4759 /* Listing missing functions from xterm.c helps diff stay in step.
4761 xim_destroy_callback (xim, client_data, call_data)
4762 xim_open_dpy (dpyinfo, resource_name)
4764 xim_instantiate_callback (display, client_data, call_data)
4765 xim_initialize (dpyinfo, resource_name)
4766 xim_close_dpy (dpyinfo)
4771 /* Calculate the absolute position in frame F
4772 from its current recorded position values and gravity. */
4775 x_calc_absolute_position (f
)
4779 int flags
= f
->output_data
.mac
->size_hint_flags
;
4783 /* Find the position of the outside upper-left corner of
4784 the inner window, with respect to the outer window. */
4785 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
4788 GetPort (&savePort
);
4790 #if TARGET_API_MAC_CARBON
4791 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
4793 SetPort (FRAME_MAC_WINDOW (f
));
4796 #if TARGET_API_MAC_CARBON
4800 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
4801 SetPt(&pt
, r
.left
, r
.top
);
4803 #else /* not TARGET_API_MAC_CARBON */
4804 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
4805 #endif /* not TARGET_API_MAC_CARBON */
4806 LocalToGlobal (&pt
);
4810 /* Treat negative positions as relative to the leftmost bottommost
4811 position that fits on the screen. */
4812 if (flags
& XNegative
)
4813 f
->output_data
.mac
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
4814 - 2 * f
->output_data
.mac
->border_width
- pt
.h
4816 + f
->output_data
.mac
->left_pos
);
4817 /* NTEMACS_TODO: Subtract menubar height? */
4818 if (flags
& YNegative
)
4819 f
->output_data
.mac
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
4820 - 2 * f
->output_data
.mac
->border_width
- pt
.v
4822 + f
->output_data
.mac
->top_pos
);
4823 /* The left_pos and top_pos
4824 are now relative to the top and left screen edges,
4825 so the flags should correspond. */
4826 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4829 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
4830 to really change the position, and 0 when calling from
4831 x_make_frame_visible (in that case, XOFF and YOFF are the current
4832 position values). It is -1 when calling from x_set_frame_parameters,
4833 which means, do adjust for borders but don't change the gravity. */
4836 x_set_offset (f
, xoff
, yoff
, change_gravity
)
4838 register int xoff
, yoff
;
4841 int modified_top
, modified_left
;
4843 if (change_gravity
> 0)
4845 f
->output_data
.mac
->top_pos
= yoff
;
4846 f
->output_data
.mac
->left_pos
= xoff
;
4847 f
->output_data
.mac
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4849 f
->output_data
.mac
->size_hint_flags
|= XNegative
;
4851 f
->output_data
.mac
->size_hint_flags
|= YNegative
;
4852 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4854 x_calc_absolute_position (f
);
4857 x_wm_set_size_hint (f
, (long) 0, 0);
4859 modified_left
= f
->output_data
.mac
->left_pos
;
4860 modified_top
= f
->output_data
.mac
->top_pos
;
4862 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
4863 modified_top
+ 42, false);
4868 /* Call this to change the size of frame F's x-window.
4869 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
4870 for this size change and subsequent size changes.
4871 Otherwise we leave the window gravity unchanged. */
4874 x_set_window_size (f
, change_gravity
, cols
, rows
)
4879 int pixelwidth
, pixelheight
;
4883 check_frame_size (f
, &rows
, &cols
);
4884 f
->output_data
.mac
->vertical_scroll_bar_extra
4885 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
4887 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.mac
->font
)));
4889 compute_fringe_widths (f
, 0);
4891 pixelwidth
= CHAR_TO_PIXEL_WIDTH (f
, cols
);
4892 pixelheight
= CHAR_TO_PIXEL_HEIGHT (f
, rows
);
4894 f
->output_data
.mac
->win_gravity
= NorthWestGravity
;
4895 x_wm_set_size_hint (f
, (long) 0, 0);
4897 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
4899 /* Now, strictly speaking, we can't be sure that this is accurate,
4900 but the window manager will get around to dealing with the size
4901 change request eventually, and we'll hear how it went when the
4902 ConfigureNotify event gets here.
4904 We could just not bother storing any of this information here,
4905 and let the ConfigureNotify event set everything up, but that
4906 might be kind of confusing to the Lisp code, since size changes
4907 wouldn't be reported in the frame parameters until some random
4908 point in the future when the ConfigureNotify event arrives.
4910 We pass 1 for DELAY since we can't run Lisp code inside of
4912 change_frame_size (f
, rows
, cols
, 0, 1, 0);
4913 PIXEL_WIDTH (f
) = pixelwidth
;
4914 PIXEL_HEIGHT (f
) = pixelheight
;
4916 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
4917 receive in the ConfigureNotify event; if we get what we asked
4918 for, then the event won't cause the screen to become garbaged, so
4919 we have to make sure to do it here. */
4920 SET_FRAME_GARBAGED (f
);
4922 XFlush (FRAME_X_DISPLAY (f
));
4924 /* If cursor was outside the new size, mark it as off. */
4925 mark_window_cursors_off (XWINDOW (f
->root_window
));
4927 /* Clear out any recollection of where the mouse highlighting was,
4928 since it might be in a place that's outside the new frame size.
4929 Actually checking whether it is outside is a pain in the neck,
4930 so don't try--just let the highlighting be done afresh with new size. */
4931 cancel_mouse_face (f
);
4936 /* Mouse warping. */
4938 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
4941 x_set_mouse_position (f
, x
, y
)
4947 pix_x
= CHAR_TO_PIXEL_COL (f
, x
) + FONT_WIDTH (f
->output_data
.mac
->font
) / 2;
4948 pix_y
= CHAR_TO_PIXEL_ROW (f
, y
) + f
->output_data
.mac
->line_height
/ 2;
4950 if (pix_x
< 0) pix_x
= 0;
4951 if (pix_x
> PIXEL_WIDTH (f
)) pix_x
= PIXEL_WIDTH (f
);
4953 if (pix_y
< 0) pix_y
= 0;
4954 if (pix_y
> PIXEL_HEIGHT (f
)) pix_y
= PIXEL_HEIGHT (f
);
4956 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
4960 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
4964 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
4967 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
4968 0, 0, 0, 0, pix_x
, pix_y
);
4974 /* focus shifting, raising and lowering. */
4977 x_focus_on_frame (f
)
4980 #if 0 /* This proves to be unpleasant. */
4984 /* I don't think that the ICCCM allows programs to do things like this
4985 without the interaction of the window manager. Whatever you end up
4986 doing with this code, do it to x_unfocus_frame too. */
4987 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4988 RevertToPointerRoot
, CurrentTime
);
4998 /* Raise frame F. */
5003 if (f
->async_visible
)
5004 SelectWindow (FRAME_MAC_WINDOW (f
));
5007 /* Lower frame F. */
5012 if (f
->async_visible
)
5013 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5017 XTframe_raise_lower (f
, raise_flag
)
5027 /* Change of visibility. */
5029 /* This tries to wait until the frame is really visible.
5030 However, if the window manager asks the user where to position
5031 the frame, this will return before the user finishes doing that.
5032 The frame will not actually be visible at that time,
5033 but it will become visible later when the window manager
5034 finishes with it. */
5037 x_make_frame_visible (f
)
5041 int original_top
, original_left
;
5045 if (! FRAME_VISIBLE_P (f
))
5047 /* We test FRAME_GARBAGED_P here to make sure we don't
5048 call x_set_offset a second time
5049 if we get to x_make_frame_visible a second time
5050 before the window gets really visible. */
5051 if (! FRAME_ICONIFIED_P (f
)
5052 && ! f
->output_data
.mac
->asked_for_visible
)
5053 x_set_offset (f
, f
->output_data
.mac
->left_pos
,
5054 f
->output_data
.mac
->top_pos
, 0);
5056 f
->output_data
.mac
->asked_for_visible
= 1;
5058 ShowWindow (FRAME_MAC_WINDOW (f
));
5061 XFlush (FRAME_MAC_DISPLAY (f
));
5063 #if 0 /* MAC_TODO */
5064 /* Synchronize to ensure Emacs knows the frame is visible
5065 before we do anything else. We do this loop with input not blocked
5066 so that incoming events are handled. */
5071 /* This must come after we set COUNT. */
5074 XSETFRAME (frame
, f
);
5076 /* Wait until the frame is visible. Process X events until a
5077 MapNotify event has been seen, or until we think we won't get a
5078 MapNotify at all.. */
5079 for (count
= input_signal_count
+ 10;
5080 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5082 /* Force processing of queued events. */
5085 /* Machines that do polling rather than SIGIO have been
5086 observed to go into a busy-wait here. So we'll fake an
5087 alarm signal to let the handler know that there's something
5088 to be read. We used to raise a real alarm, but it seems
5089 that the handler isn't always enabled here. This is
5091 if (input_polling_used ())
5093 /* It could be confusing if a real alarm arrives while
5094 processing the fake one. Turn it off and let the
5095 handler reset it. */
5096 extern void poll_for_input_1
P_ ((void));
5097 int old_poll_suppress_count
= poll_suppress_count
;
5098 poll_suppress_count
= 1;
5099 poll_for_input_1 ();
5100 poll_suppress_count
= old_poll_suppress_count
;
5103 /* See if a MapNotify event has been processed. */
5104 FRAME_SAMPLE_VISIBILITY (f
);
5107 #endif /* MAC_TODO */
5110 /* Change from mapped state to withdrawn state. */
5112 /* Make the frame visible (mapped and not iconified). */
5115 x_make_frame_invisible (f
)
5118 /* Don't keep the highlight on an invisible frame. */
5119 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5120 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5124 HideWindow (FRAME_MAC_WINDOW (f
));
5126 /* We can't distinguish this from iconification
5127 just by the event that we get from the server.
5128 So we can't win using the usual strategy of letting
5129 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5130 and synchronize with the server to make sure we agree. */
5132 FRAME_ICONIFIED_P (f
) = 0;
5133 f
->async_visible
= 0;
5134 f
->async_iconified
= 0;
5139 /* Change window state from mapped to iconified. */
5145 /* Don't keep the highlight on an invisible frame. */
5146 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5147 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5150 /* Review: Since window is still visible in dock, still allow updates? */
5151 if (f
->async_iconified
)
5157 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5163 /* Destroy the X window of frame F. */
5166 x_destroy_window (f
)
5169 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5173 DisposeWindow (FRAME_MAC_WINDOW (f
));
5175 free_frame_menubar (f
);
5176 free_frame_faces (f
);
5178 xfree (f
->output_data
.mac
);
5179 f
->output_data
.mac
= 0;
5180 if (f
== dpyinfo
->x_focus_frame
)
5181 dpyinfo
->x_focus_frame
= 0;
5182 if (f
== dpyinfo
->x_focus_event_frame
)
5183 dpyinfo
->x_focus_event_frame
= 0;
5184 if (f
== dpyinfo
->x_highlight_frame
)
5185 dpyinfo
->x_highlight_frame
= 0;
5187 dpyinfo
->reference_count
--;
5189 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5191 dpyinfo
->mouse_face_beg_row
5192 = dpyinfo
->mouse_face_beg_col
= -1;
5193 dpyinfo
->mouse_face_end_row
5194 = dpyinfo
->mouse_face_end_col
= -1;
5195 dpyinfo
->mouse_face_window
= Qnil
;
5196 dpyinfo
->mouse_face_deferred_gc
= 0;
5197 dpyinfo
->mouse_face_mouse_frame
= 0;
5203 /* Setting window manager hints. */
5205 /* Set the normal size hints for the window manager, for frame F.
5206 FLAGS is the flags word to use--or 0 meaning preserve the flags
5207 that the window now has.
5208 If USER_POSITION is nonzero, we set the USPosition
5209 flag (this is useful when FLAGS is 0). */
5211 x_wm_set_size_hint (f
, flags
, user_position
)
5216 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5217 XSizeHints size_hints
;
5219 #ifdef USE_X_TOOLKIT
5222 Dimension widget_width
, widget_height
;
5223 Window window
= XtWindow (f
->output_data
.x
->widget
);
5224 #else /* not USE_X_TOOLKIT */
5225 Window window
= FRAME_X_WINDOW (f
);
5226 #endif /* not USE_X_TOOLKIT */
5228 /* Setting PMaxSize caused various problems. */
5229 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5231 size_hints
.x
= f
->output_data
.x
->left_pos
;
5232 size_hints
.y
= f
->output_data
.x
->top_pos
;
5234 #ifdef USE_X_TOOLKIT
5235 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5236 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5237 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5238 size_hints
.height
= widget_height
;
5239 size_hints
.width
= widget_width
;
5240 #else /* not USE_X_TOOLKIT */
5241 size_hints
.height
= PIXEL_HEIGHT (f
);
5242 size_hints
.width
= PIXEL_WIDTH (f
);
5243 #endif /* not USE_X_TOOLKIT */
5245 size_hints
.width_inc
= FONT_WIDTH (f
->output_data
.x
->font
);
5246 size_hints
.height_inc
= f
->output_data
.x
->line_height
;
5247 size_hints
.max_width
5248 = FRAME_X_DISPLAY_INFO (f
)->width
- CHAR_TO_PIXEL_WIDTH (f
, 0);
5249 size_hints
.max_height
5250 = FRAME_X_DISPLAY_INFO (f
)->height
- CHAR_TO_PIXEL_HEIGHT (f
, 0);
5252 /* Calculate the base and minimum sizes.
5254 (When we use the X toolkit, we don't do it here.
5255 Instead we copy the values that the widgets are using, below.) */
5256 #ifndef USE_X_TOOLKIT
5258 int base_width
, base_height
;
5259 int min_rows
= 0, min_cols
= 0;
5261 base_width
= CHAR_TO_PIXEL_WIDTH (f
, 0);
5262 base_height
= CHAR_TO_PIXEL_HEIGHT (f
, 0);
5264 check_frame_size (f
, &min_rows
, &min_cols
);
5266 /* The window manager uses the base width hints to calculate the
5267 current number of rows and columns in the frame while
5268 resizing; min_width and min_height aren't useful for this
5269 purpose, since they might not give the dimensions for a
5270 zero-row, zero-column frame.
5272 We use the base_width and base_height members if we have
5273 them; otherwise, we set the min_width and min_height members
5274 to the size for a zero x zero frame. */
5277 size_hints
.flags
|= PBaseSize
;
5278 size_hints
.base_width
= base_width
;
5279 size_hints
.base_height
= base_height
;
5280 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5281 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5283 size_hints
.min_width
= base_width
;
5284 size_hints
.min_height
= base_height
;
5288 /* If we don't need the old flags, we don't need the old hint at all. */
5291 size_hints
.flags
|= flags
;
5294 #endif /* not USE_X_TOOLKIT */
5297 XSizeHints hints
; /* Sometimes I hate X Windows... */
5298 long supplied_return
;
5302 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5305 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5308 #ifdef USE_X_TOOLKIT
5309 size_hints
.base_height
= hints
.base_height
;
5310 size_hints
.base_width
= hints
.base_width
;
5311 size_hints
.min_height
= hints
.min_height
;
5312 size_hints
.min_width
= hints
.min_width
;
5316 size_hints
.flags
|= flags
;
5321 if (hints
.flags
& PSize
)
5322 size_hints
.flags
|= PSize
;
5323 if (hints
.flags
& PPosition
)
5324 size_hints
.flags
|= PPosition
;
5325 if (hints
.flags
& USPosition
)
5326 size_hints
.flags
|= USPosition
;
5327 if (hints
.flags
& USSize
)
5328 size_hints
.flags
|= USSize
;
5332 #ifndef USE_X_TOOLKIT
5337 size_hints
.win_gravity
= f
->output_data
.x
->win_gravity
;
5338 size_hints
.flags
|= PWinGravity
;
5342 size_hints
.flags
&= ~ PPosition
;
5343 size_hints
.flags
|= USPosition
;
5345 #endif /* PWinGravity */
5348 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5350 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5352 #endif /* MAC_TODO */
5355 #if 0 /* MAC_TODO: hide application instead of iconify? */
5356 /* Used for IconicState or NormalState */
5359 x_wm_set_window_state (f
, state
)
5363 #ifdef USE_X_TOOLKIT
5366 XtSetArg (al
[0], XtNinitialState
, state
);
5367 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5368 #else /* not USE_X_TOOLKIT */
5369 Window window
= FRAME_X_WINDOW (f
);
5371 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5372 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5374 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5375 #endif /* not USE_X_TOOLKIT */
5379 x_wm_set_icon_pixmap (f
, pixmap_id
)
5385 #ifndef USE_X_TOOLKIT
5386 Window window
= FRAME_X_WINDOW (f
);
5391 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5392 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5396 /* It seems there is no way to turn off use of an icon pixmap.
5397 The following line does it, only if no icon has yet been created,
5398 for some window managers. But with mwm it crashes.
5399 Some people say it should clear the IconPixmapHint bit in this case,
5400 but that doesn't work, and the X consortium said it isn't the
5401 right thing at all. Since there is no way to win,
5402 best to explicitly give up. */
5404 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5410 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5414 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5415 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5418 #else /* not USE_X_TOOLKIT */
5420 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5421 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5423 #endif /* not USE_X_TOOLKIT */
5426 #endif /* MAC_TODO */
5429 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5433 #if 0 /* MAC_TODO: no icons on Mac */
5434 #ifdef USE_X_TOOLKIT
5435 Window window
= XtWindow (f
->output_data
.x
->widget
);
5437 Window window
= FRAME_X_WINDOW (f
);
5440 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5441 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5442 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5444 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5445 #endif /* MAC_TODO */
5449 /***********************************************************************
5451 ***********************************************************************/
5453 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5456 x_get_font_info (f
, font_idx
)
5460 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5463 /* the global font name table */
5464 char **font_name_table
= NULL
;
5465 int font_name_table_size
= 0;
5466 int font_name_count
= 0;
5468 /* compare two strings ignoring case */
5470 stricmp (const char *s
, const char *t
)
5472 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5475 return tolower (*s
) - tolower (*t
);
5478 /* compare two strings ignoring case and handling wildcard */
5480 wildstrieq (char *s1
, char *s2
)
5482 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5485 return stricmp (s1
, s2
) == 0;
5488 /* Assume parameter 1 is fully qualified, no wildcards. */
5490 mac_font_pattern_match (fontname
, pattern
)
5494 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5495 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5498 /* Copy fontname so we can modify it during comparison. */
5499 strcpy (font_name_copy
, fontname
);
5504 /* Turn pattern into a regexp and do a regexp match. */
5505 for (; *pattern
; pattern
++)
5507 if (*pattern
== '?')
5509 else if (*pattern
== '*')
5520 return (fast_c_string_match_ignore_case (build_string (regex
),
5521 font_name_copy
) >= 0);
5524 /* Two font specs are considered to match if their foundry, family,
5525 weight, slant, and charset match. */
5527 mac_font_match (char *mf
, char *xf
)
5529 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5530 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5532 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5533 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5534 return mac_font_pattern_match (mf
, xf
);
5536 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5537 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5538 return mac_font_pattern_match (mf
, xf
);
5540 return (wildstrieq (m_foundry
, x_foundry
)
5541 && wildstrieq (m_family
, x_family
)
5542 && wildstrieq (m_weight
, x_weight
)
5543 && wildstrieq (m_slant
, x_slant
)
5544 && wildstrieq (m_charset
, x_charset
))
5545 || mac_font_pattern_match (mf
, xf
);
5550 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5552 char foundry
[32], family
[32], cs
[32];
5553 char xf
[255], *result
, *p
;
5555 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5557 strcpy(foundry
, "Apple");
5558 strcpy(family
, name
);
5563 strcpy(cs
, "big5-0");
5566 strcpy(cs
, "gb2312.1980-0");
5569 strcpy(cs
, "jisx0208.1983-sjis");
5572 /* Each Apple Japanese font is entered into the font table
5573 twice: once as a jisx0208.1983-sjis font and once as a
5574 jisx0201.1976-0 font. The latter can be used to display
5575 the ascii charset and katakana-jisx0201 charset. A
5576 negative script code signals that the name of this latter
5577 font is being built. */
5578 strcpy(cs
, "jisx0201.1976-0");
5581 strcpy(cs
, "ksc5601.1989-0");
5584 strcpy(cs
, "mac-roman");
5589 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5590 foundry
, family
, style
& bold
? "bold" : "medium",
5591 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5593 result
= (char *) xmalloc (strlen (xf
) + 1);
5594 strcpy (result
, xf
);
5595 for (p
= result
; *p
; p
++)
5601 /* Convert an X font spec to the corresponding mac font name, which
5602 can then be passed to GetFNum after conversion to a Pascal string.
5603 For ordinary Mac fonts, this should just be their names, like
5604 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5605 collection contain their charset designation in their names, like
5606 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5607 names are handled accordingly. */
5609 x_font_name_to_mac_font_name (char *xf
, char *mf
)
5611 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
5615 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5616 foundry
, family
, weight
, slant
, cs
) != 5 &&
5617 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5618 foundry
, family
, weight
, slant
, cs
) != 5)
5621 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
5622 || strcmp (cs
, "jisx0208.1983-sjis") == 0
5623 || strcmp (cs
, "jisx0201.1976-0") == 0
5624 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
5627 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
5632 add_font_name_table_entry (char *font_name
)
5634 if (font_name_table_size
== 0)
5636 font_name_table_size
= 16;
5637 font_name_table
= (char **)
5638 xmalloc (font_name_table_size
* sizeof (char *));
5640 else if (font_name_count
+ 1 >= font_name_table_size
)
5642 font_name_table_size
+= 16;
5643 font_name_table
= (char **)
5644 xrealloc (font_name_table
,
5645 font_name_table_size
* sizeof (char *));
5648 font_name_table
[font_name_count
++] = font_name
;
5651 /* Sets up the table font_name_table to contain the list of all fonts
5652 in the system the first time the table is used so that the Resource
5653 Manager need not be accessed every time this information is
5657 init_font_name_table ()
5659 #if TARGET_API_MAC_CARBON
5662 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
5664 FMFontFamilyIterator ffi
;
5665 FMFontFamilyInstanceIterator ffii
;
5668 /* Create a dummy instance iterator here to avoid creating and
5669 destroying it in the loop. */
5670 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
5672 /* Create an iterator to enumerate the font families. */
5673 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
5676 FMDisposeFontFamilyInstanceIterator (&ffii
);
5680 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
5688 if (FMGetFontFamilyName (ff
, name
) != noErr
)
5692 sc
= FontToScript (ff
);
5694 /* Point the instance iterator at the current font family. */
5695 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
5698 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
5702 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5704 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5706 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5708 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5714 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5716 if (smJapanese
== sc
)
5717 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5723 /* Dispose of the iterators. */
5724 FMDisposeFontFamilyIterator (&ffi
);
5725 FMDisposeFontFamilyInstanceIterator (&ffii
);
5729 #endif /* TARGET_API_MAC_CARBON */
5731 SInt16 fontnum
, old_fontnum
;
5732 int num_mac_fonts
= CountResources('FOND');
5734 Handle font_handle
, font_handle_2
;
5735 short id
, scriptcode
;
5738 struct FontAssoc
*fat
;
5739 struct AsscEntry
*assc_entry
;
5741 GetPort (&port
); /* save the current font number used */
5742 #if TARGET_API_MAC_CARBON
5743 old_fontnum
= GetPortTextFont (port
);
5745 old_fontnum
= port
->txFont
;
5748 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
5750 font_handle
= GetIndResource ('FOND', i
);
5754 GetResInfo (font_handle
, &id
, &type
, name
);
5755 GetFNum (name
, &fontnum
);
5761 scriptcode
= FontToScript (fontnum
);
5764 HLock (font_handle
);
5766 if (GetResourceSizeOnDisk (font_handle
)
5767 >= sizeof (struct FamRec
))
5769 fat
= (struct FontAssoc
*) (*font_handle
5770 + sizeof (struct FamRec
));
5772 = (struct AsscEntry
*) (*font_handle
5773 + sizeof (struct FamRec
)
5774 + sizeof (struct FontAssoc
));
5776 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
5778 if (font_name_table_size
== 0)
5780 font_name_table_size
= 16;
5781 font_name_table
= (char **)
5782 xmalloc (font_name_table_size
* sizeof (char *));
5784 else if (font_name_count
>= font_name_table_size
)
5786 font_name_table_size
+= 16;
5787 font_name_table
= (char **)
5788 xrealloc (font_name_table
,
5789 font_name_table_size
* sizeof (char *));
5791 font_name_table
[font_name_count
++]
5792 = mac_to_x_fontname (name
,
5793 assc_entry
->fontSize
,
5794 assc_entry
->fontStyle
,
5796 /* Both jisx0208.1983-sjis and
5797 jisx0201.1976-sjis parts are contained in
5798 Apple Japanese (SJIS) font. */
5799 if (smJapanese
== scriptcode
)
5801 font_name_table
[font_name_count
++]
5802 = mac_to_x_fontname (name
,
5803 assc_entry
->fontSize
,
5804 assc_entry
->fontStyle
,
5810 HUnlock (font_handle
);
5811 font_handle_2
= GetNextFOND (font_handle
);
5812 ReleaseResource (font_handle
);
5813 font_handle
= font_handle_2
;
5815 while (ResError () == noErr
&& font_handle
);
5818 TextFont (old_fontnum
);
5819 #if TARGET_API_MAC_CARBON
5821 #endif /* TARGET_API_MAC_CARBON */
5825 /* Return a list of at most MAXNAMES font specs matching the one in
5826 PATTERN. Cache matching fonts for patterns in
5827 dpyinfo->name_list_element to avoid looking them up again by
5828 calling mac_font_pattern_match (slow). */
5831 x_list_fonts (struct frame
*f
,
5832 Lisp_Object pattern
,
5837 Lisp_Object newlist
= Qnil
, tem
, key
;
5840 struct gcpro gcpro1
, gcpro2
;
5841 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
5843 if (font_name_table
== NULL
) /* Initialize when first used. */
5844 init_font_name_table ();
5848 tem
= XCDR (dpyinfo
->name_list_element
);
5849 key
= Fcons (pattern
, make_number (maxnames
));
5851 newlist
= Fassoc (key
, tem
);
5852 if (!NILP (newlist
))
5854 newlist
= Fcdr_safe (newlist
);
5859 ptnstr
= SDATA (pattern
);
5861 GCPRO2 (pattern
, newlist
);
5863 /* Scan and matching bitmap fonts. */
5864 for (i
= 0; i
< font_name_count
; i
++)
5866 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
5868 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
5871 if (n_fonts
>= maxnames
)
5876 /* MAC_TODO: add code for matching outline fonts here */
5882 XSETCDR (dpyinfo
->name_list_element
,
5883 Fcons (Fcons (key
, newlist
),
5884 XCDR (dpyinfo
->name_list_element
)));
5894 /* Check that FONT is valid on frame F. It is if it can be found in F's
5898 x_check_font (f
, font
)
5903 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5905 xassert (font
!= NULL
);
5907 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5908 if (dpyinfo
->font_table
[i
].name
5909 && font
== dpyinfo
->font_table
[i
].font
)
5912 xassert (i
< dpyinfo
->n_fonts
);
5915 #endif /* GLYPH_DEBUG != 0 */
5917 /* Set *W to the minimum width, *H to the minimum font height of FONT.
5918 Note: There are (broken) X fonts out there with invalid XFontStruct
5919 min_bounds contents. For example, handa@etl.go.jp reports that
5920 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
5921 have font->min_bounds.width == 0. */
5924 x_font_min_bounds (font
, w
, h
)
5925 MacFontStruct
*font
;
5929 * TODO: Windows does not appear to offer min bound, only
5930 * average and maximum width, and maximum height.
5932 *h
= FONT_HEIGHT (font
);
5933 *w
= FONT_WIDTH (font
);
5937 /* Compute the smallest character width and smallest font height over
5938 all fonts available on frame F. Set the members smallest_char_width
5939 and smallest_font_height in F's x_display_info structure to
5940 the values computed. Value is non-zero if smallest_font_height or
5941 smallest_char_width become smaller than they were before. */
5944 x_compute_min_glyph_bounds (f
)
5948 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5949 MacFontStruct
*font
;
5950 int old_width
= dpyinfo
->smallest_char_width
;
5951 int old_height
= dpyinfo
->smallest_font_height
;
5953 dpyinfo
->smallest_font_height
= 100000;
5954 dpyinfo
->smallest_char_width
= 100000;
5956 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
5957 if (dpyinfo
->font_table
[i
].name
)
5959 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
5962 font
= (MacFontStruct
*) fontp
->font
;
5963 xassert (font
!= (MacFontStruct
*) ~0);
5964 x_font_min_bounds (font
, &w
, &h
);
5966 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
5967 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
5970 xassert (dpyinfo
->smallest_char_width
> 0
5971 && dpyinfo
->smallest_font_height
> 0);
5973 return (dpyinfo
->n_fonts
== 1
5974 || dpyinfo
->smallest_char_width
< old_width
5975 || dpyinfo
->smallest_font_height
< old_height
);
5979 /* Determine whether given string is a fully-specified XLFD: all 14
5980 fields are present, none is '*'. */
5983 is_fully_specified_xlfd (char *p
)
5991 for (i
= 0; i
< 13; i
++)
5993 q
= strchr (p
+ 1, '-');
5996 if (q
- p
== 2 && *(p
+ 1) == '*')
6001 if (strchr (p
+ 1, '-') != NULL
)
6004 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6011 const int kDefaultFontSize
= 9;
6014 /* XLoadQueryFont creates and returns an internal representation for a
6015 font in a MacFontStruct struct. There is really no concept
6016 corresponding to "loading" a font on the Mac. But we check its
6017 existence and find the font number and all other information for it
6018 and store them in the returned MacFontStruct. */
6020 static MacFontStruct
*
6021 XLoadQueryFont (Display
*dpy
, char *fontname
)
6023 int i
, size
, is_two_byte_font
, char_width
;
6026 SInt16 old_fontnum
, old_fontsize
;
6030 Style fontface
= normal
;
6031 MacFontStruct
*font
;
6032 FontInfo the_fontinfo
;
6033 char s_weight
[7], c_slant
;
6035 if (is_fully_specified_xlfd (fontname
))
6039 for (i
= 0; i
< font_name_count
; i
++)
6040 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
6043 if (i
>= font_name_count
)
6046 name
= font_name_table
[i
];
6049 GetPort (&port
); /* save the current font number used */
6050 #if TARGET_API_MAC_CARBON
6051 old_fontnum
= GetPortTextFont (port
);
6052 old_fontsize
= GetPortTextSize (port
);
6053 old_fontface
= GetPortTextFace (port
);
6055 old_fontnum
= port
->txFont
;
6056 old_fontsize
= port
->txSize
;
6057 old_fontface
= port
->txFace
;
6060 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6061 size
= kDefaultFontSize
;
6063 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6064 if (strcmp (s_weight
, "bold") == 0)
6067 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6071 x_font_name_to_mac_font_name (name
, mfontname
);
6073 GetFNum (mfontname
, &fontnum
);
6077 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6079 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6080 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6082 font
->mac_fontnum
= fontnum
;
6083 font
->mac_fontsize
= size
;
6084 font
->mac_fontface
= fontface
;
6085 font
->mac_scriptcode
= FontToScript (fontnum
);
6087 /* Apple Japanese (SJIS) font is listed as both
6088 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6089 (Roman script) in init_font_name_table (). The latter should be
6090 treated as a one-byte font. */
6095 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6097 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6098 font
->mac_scriptcode
= smRoman
;
6101 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6102 font
->mac_scriptcode
== smTradChinese
||
6103 font
->mac_scriptcode
== smSimpChinese
||
6104 font
->mac_scriptcode
== smKorean
;
6108 TextFace (fontface
);
6110 GetFontInfo (&the_fontinfo
);
6112 font
->ascent
= the_fontinfo
.ascent
;
6113 font
->descent
= the_fontinfo
.descent
;
6115 font
->min_byte1
= 0;
6116 if (is_two_byte_font
)
6117 font
->max_byte1
= 1;
6119 font
->max_byte1
= 0;
6120 font
->min_char_or_byte2
= 0x20;
6121 font
->max_char_or_byte2
= 0xff;
6123 if (is_two_byte_font
)
6125 /* Use the width of an "ideographic space" of that font because
6126 the_fontinfo.widMax returns the wrong width for some fonts. */
6127 switch (font
->mac_scriptcode
)
6130 char_width
= StringWidth("\p\x81\x40");
6133 char_width
= StringWidth("\p\xa1\x40");
6136 char_width
= StringWidth("\p\xa1\xa1");
6139 char_width
= StringWidth("\p\xa1\xa1");
6144 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6145 returns 15 for 12-point Monaco! */
6146 char_width
= CharWidth ('m');
6148 font
->max_bounds
.rbearing
= char_width
;
6149 font
->max_bounds
.lbearing
= 0;
6150 font
->max_bounds
.width
= char_width
;
6151 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6152 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6154 font
->min_bounds
= font
->max_bounds
;
6156 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6157 font
->per_char
= NULL
;
6160 font
->per_char
= (XCharStruct
*)
6161 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6165 for (c
= 0x20; c
<= 0xff; c
++)
6167 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6168 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
6173 TextFont (old_fontnum
); /* restore previous font number, size and face */
6174 TextSize (old_fontsize
);
6175 TextFace (old_fontface
);
6181 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6182 pointer to the structure font_info while allocating it dynamically.
6183 If SIZE is 0, load any size of font.
6184 If loading is failed, return NULL. */
6187 x_load_font (f
, fontname
, size
)
6189 register char *fontname
;
6192 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6193 Lisp_Object font_names
;
6195 /* Get a list of all the fonts that match this name. Once we
6196 have a list of matching fonts, we compare them against the fonts
6197 we already have by comparing names. */
6198 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6200 if (!NILP (font_names
))
6205 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6206 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6207 if (dpyinfo
->font_table
[i
].name
6208 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6209 SDATA (XCAR (tail
)))
6210 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6211 SDATA (XCAR (tail
)))))
6212 return (dpyinfo
->font_table
+ i
);
6215 /* Load the font and add it to the table. */
6218 struct MacFontStruct
*font
;
6219 struct font_info
*fontp
;
6220 unsigned long value
;
6223 /* If we have found fonts by x_list_font, load one of them. If
6224 not, we still try to load a font by the name given as FONTNAME
6225 because XListFonts (called in x_list_font) of some X server has
6226 a bug of not finding a font even if the font surely exists and
6227 is loadable by XLoadQueryFont. */
6228 if (size
> 0 && !NILP (font_names
))
6229 fontname
= (char *) SDATA (XCAR (font_names
));
6231 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6235 /* Find a free slot in the font table. */
6236 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6237 if (dpyinfo
->font_table
[i
].name
== NULL
)
6240 /* If no free slot found, maybe enlarge the font table. */
6241 if (i
== dpyinfo
->n_fonts
6242 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6245 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6246 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6248 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6251 fontp
= dpyinfo
->font_table
+ i
;
6252 if (i
== dpyinfo
->n_fonts
)
6255 /* Now fill in the slots of *FONTP. */
6258 fontp
->font_idx
= i
;
6259 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6260 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6262 fontp
->full_name
= fontp
->name
;
6264 fontp
->size
= font
->max_bounds
.width
;
6265 fontp
->height
= FONT_HEIGHT (font
);
6267 /* For some font, ascent and descent in max_bounds field is
6268 larger than the above value. */
6269 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6270 if (max_height
> fontp
->height
)
6271 fontp
->height
= max_height
;
6274 /* The slot `encoding' specifies how to map a character
6275 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6276 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6277 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6278 2:0xA020..0xFF7F). For the moment, we don't know which charset
6279 uses this font. So, we set information in fontp->encoding[1]
6280 which is never used by any charset. If mapping can't be
6281 decided, set FONT_ENCODING_NOT_DECIDED. */
6282 if (font
->mac_scriptcode
== smJapanese
)
6283 fontp
->encoding
[1] = 4;
6287 = (font
->max_byte1
== 0
6289 ? (font
->min_char_or_byte2
< 0x80
6290 ? (font
->max_char_or_byte2
< 0x80
6291 ? 0 /* 0x20..0x7F */
6292 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6293 : 1) /* 0xA0..0xFF */
6295 : (font
->min_byte1
< 0x80
6296 ? (font
->max_byte1
< 0x80
6297 ? (font
->min_char_or_byte2
< 0x80
6298 ? (font
->max_char_or_byte2
< 0x80
6299 ? 0 /* 0x2020..0x7F7F */
6300 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6301 : 3) /* 0x20A0..0x7FFF */
6302 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6303 : (font
->min_char_or_byte2
< 0x80
6304 ? (font
->max_char_or_byte2
< 0x80
6305 ? 2 /* 0xA020..0xFF7F */
6306 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6307 : 1))); /* 0xA0A0..0xFFFF */
6310 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6311 fontp
->baseline_offset
6312 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6313 ? (long) value
: 0);
6314 fontp
->relative_compose
6315 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6316 ? (long) value
: 0);
6317 fontp
->default_ascent
6318 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6319 ? (long) value
: 0);
6321 fontp
->baseline_offset
= 0;
6322 fontp
->relative_compose
= 0;
6323 fontp
->default_ascent
= 0;
6326 /* Set global flag fonts_changed_p to non-zero if the font loaded
6327 has a character with a smaller width than any other character
6328 before, or if the font loaded has a smalle>r height than any
6329 other font loaded before. If this happens, it will make a
6330 glyph matrix reallocation necessary. */
6331 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6338 /* Return a pointer to struct font_info of a font named FONTNAME for
6339 frame F. If no such font is loaded, return NULL. */
6342 x_query_font (f
, fontname
)
6344 register char *fontname
;
6346 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6349 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6350 if (dpyinfo
->font_table
[i
].name
6351 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6352 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6353 return (dpyinfo
->font_table
+ i
);
6358 /* Find a CCL program for a font specified by FONTP, and set the member
6359 `encoder' of the structure. */
6362 x_find_ccl_program (fontp
)
6363 struct font_info
*fontp
;
6365 Lisp_Object list
, elt
;
6367 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6371 && STRINGP (XCAR (elt
))
6372 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6378 struct ccl_program
*ccl
6379 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6381 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6384 fontp
->font_encoder
= ccl
;
6390 /***********************************************************************
6392 ***********************************************************************/
6394 #ifdef USE_X_TOOLKIT
6395 static XrmOptionDescRec emacs_options
[] = {
6396 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
6397 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
6399 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
6400 XrmoptionSepArg
, NULL
},
6401 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
6403 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6404 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6405 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6406 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
6407 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
6408 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
6409 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
6411 #endif /* USE_X_TOOLKIT */
6413 static int x_initialized
;
6416 /* Test whether two display-name strings agree up to the dot that separates
6417 the screen number from the server number. */
6419 same_x_server (name1
, name2
)
6420 char *name1
, *name2
;
6423 unsigned char *system_name
= SDATA (Vsystem_name
);
6424 int system_name_length
= strlen (system_name
);
6425 int length_until_period
= 0;
6427 while (system_name
[length_until_period
] != 0
6428 && system_name
[length_until_period
] != '.')
6429 length_until_period
++;
6431 /* Treat `unix' like an empty host name. */
6432 if (! strncmp (name1
, "unix:", 5))
6434 if (! strncmp (name2
, "unix:", 5))
6436 /* Treat this host's name like an empty host name. */
6437 if (! strncmp (name1
, system_name
, system_name_length
)
6438 && name1
[system_name_length
] == ':')
6439 name1
+= system_name_length
;
6440 if (! strncmp (name2
, system_name
, system_name_length
)
6441 && name2
[system_name_length
] == ':')
6442 name2
+= system_name_length
;
6443 /* Treat this host's domainless name like an empty host name. */
6444 if (! strncmp (name1
, system_name
, length_until_period
)
6445 && name1
[length_until_period
] == ':')
6446 name1
+= length_until_period
;
6447 if (! strncmp (name2
, system_name
, length_until_period
)
6448 && name2
[length_until_period
] == ':')
6449 name2
+= length_until_period
;
6451 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
6455 if (seen_colon
&& *name1
== '.')
6459 && (*name1
== '.' || *name1
== '\0')
6460 && (*name2
== '.' || *name2
== '\0'));
6465 /* The Mac Event loop code */
6469 #include <Quickdraw.h>
6470 #include <Balloons.h>
6471 #include <Devices.h>
6473 #include <Gestalt.h>
6475 #include <Processes.h>
6477 #include <ToolUtils.h>
6478 #include <TextUtils.h>
6479 #include <Dialogs.h>
6482 #include <TextEncodingConverter.h>
6483 #include <Resources.h>
6488 #endif /* ! MAC_OSX */
6493 #define WINDOW_RESOURCE 128
6494 #define TERM_WINDOW_RESOURCE 129
6496 #define DEFAULT_NUM_COLS 80
6498 #define MIN_DOC_SIZE 64
6499 #define MAX_DOC_SIZE 32767
6501 /* sleep time for WaitNextEvent */
6502 #define WNE_SLEEP_AT_SUSPEND 10
6503 #define WNE_SLEEP_AT_RESUME 1
6505 /* true when cannot handle any Mac OS events */
6506 static int handling_window_update
= 0;
6508 /* the flag appl_is_suspended is used both for determining the sleep
6509 time to be passed to WaitNextEvent and whether the cursor should be
6510 drawn when updating the display. The cursor is turned off when
6511 Emacs is suspended. Redrawing it is unnecessary and what needs to
6512 be done depends on whether the cursor lies inside or outside the
6513 redraw region. So we might as well skip drawing it when Emacs is
6515 static Boolean app_is_suspended
= false;
6516 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6518 #define EXTRA_STACK_ALLOC (256 * 1024)
6520 #define ARGV_STRING_LIST_ID 129
6521 #define ABOUT_ALERT_ID 128
6522 #define RAM_TOO_LARGE_ALERT_ID 129
6524 Boolean terminate_flag
= false;
6526 /* True if using command key as meta key. */
6527 Lisp_Object Vmac_command_key_is_meta
;
6529 /* True if the ctrl and meta keys should be reversed. */
6530 Lisp_Object Vmac_reverse_ctrl_meta
;
6532 #if USE_CARBON_EVENTS
6533 /* True if the mouse wheel button (i.e. button 4) should map to
6534 mouse-2, instead of mouse-3. */
6535 Lisp_Object Vmac_wheel_button_is_mouse_2
;
6537 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
6538 for processing before Emacs sees it. */
6539 Lisp_Object Vmac_pass_command_to_system
;
6541 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
6542 for processing before Emacs sees it. */
6543 Lisp_Object Vmac_pass_control_to_system
;
6546 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
6547 to this text encoding */
6548 int mac_keyboard_text_encoding
;
6549 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
6551 /* Set in term/mac-win.el to indicate that event loop can now generate
6552 drag and drop events. */
6553 Lisp_Object Qmac_ready_for_drag_n_drop
;
6555 Lisp_Object drag_and_drop_file_list
;
6557 Point saved_menu_event_location
;
6560 static void init_required_apple_events (void);
6562 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
6564 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
6565 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
6566 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
6569 static OSErr
init_mac_drag_n_drop ();
6570 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
6572 #if USE_CARBON_EVENTS
6573 /* Preliminary Support for the OSX Services Menu */
6574 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
6575 static void init_service_handler ();
6578 extern void init_emacs_passwd_dir ();
6579 extern int emacs_main (int, char **, char **);
6580 extern void check_alarm ();
6582 extern void initialize_applescript();
6583 extern void terminate_applescript();
6586 #if USE_CARBON_EVENTS
6587 mac_to_emacs_modifiers (UInt32 mods
)
6589 mac_to_emacs_modifiers (EventModifiers mods
)
6592 unsigned int result
= 0;
6593 if (mods
& macShiftKey
)
6594 result
|= shift_modifier
;
6595 if (mods
& macCtrlKey
)
6596 result
|= ctrl_modifier
;
6597 if (mods
& macMetaKey
)
6598 result
|= meta_modifier
;
6599 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
6600 result
|= alt_modifier
;
6604 #if USE_CARBON_EVENTS
6605 /* Obtains the event modifiers from the event ref and then calls
6606 mac_to_emacs_modifiers. */
6608 mac_event_to_emacs_modifiers (EventRef eventRef
)
6611 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
6612 sizeof (UInt32
), NULL
, &mods
);
6613 return mac_to_emacs_modifiers (mods
);
6616 /* Given an event ref, return the code to use for the mouse button
6617 code in the emacs input_event. */
6619 mac_get_mouse_btn (EventRef ref
)
6621 EventMouseButton result
= kEventMouseButtonPrimary
;
6622 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
6623 sizeof (EventMouseButton
), NULL
, &result
);
6626 case kEventMouseButtonPrimary
:
6628 case kEventMouseButtonSecondary
:
6629 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
6630 case kEventMouseButtonTertiary
:
6631 case 4: /* 4 is the number for the mouse wheel button */
6632 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
6638 /* Normally, ConvertEventRefToEventRecord will correctly handle all
6639 events. However the click of the mouse wheel is not converted to a
6640 mouseDown or mouseUp event. This calls ConvertEventRef, but then
6641 checks to see if it is a mouse up or down carbon event that has not
6642 been converted, and if so, converts it by hand (to be picked up in
6643 the XTread_socket loop). */
6644 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
6646 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
6647 /* Do special case for mouse wheel button. */
6648 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
6650 UInt32 kind
= GetEventKind (eventRef
);
6651 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
6653 eventRec
->what
= mouseDown
;
6656 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
6658 eventRec
->what
= mouseUp
;
6663 /* Need where and when. */
6665 GetEventParameter (eventRef
, kEventParamMouseLocation
,
6666 typeQDPoint
, NULL
, sizeof (Point
),
6667 NULL
, &eventRec
->where
);
6668 /* Use two step process because new event modifiers are
6669 32-bit and old are 16-bit. Currently, only loss is
6671 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
6672 typeUInt32
, NULL
, sizeof (UInt32
),
6674 eventRec
->modifiers
= mods
;
6676 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
6687 Handle menubar_handle
;
6688 MenuHandle menu_handle
;
6690 menubar_handle
= GetNewMBar (128);
6691 if(menubar_handle
== NULL
)
6693 SetMenuBar (menubar_handle
);
6696 menu_handle
= GetMenuHandle (M_APPLE
);
6697 if(menu_handle
!= NULL
)
6698 AppendResMenu (menu_handle
,'DRVR');
6705 do_init_managers (void)
6707 #if !TARGET_API_MAC_CARBON
6708 InitGraf (&qd
.thePort
);
6710 FlushEvents (everyEvent
, 0);
6715 #endif /* !TARGET_API_MAC_CARBON */
6718 #if !TARGET_API_MAC_CARBON
6719 /* set up some extra stack space for use by emacs */
6720 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
6722 /* MaxApplZone must be called for AppleScript to execute more
6723 complicated scripts */
6726 #endif /* !TARGET_API_MAC_CARBON */
6730 do_check_ram_size (void)
6732 SInt32 physical_ram_size
, logical_ram_size
;
6734 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
6735 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
6736 || physical_ram_size
> 256 * 1024 * 1024
6737 || logical_ram_size
> 256 * 1024 * 1024)
6739 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
6745 do_window_update (WindowPtr win
)
6747 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
6748 struct frame
*f
= mwp
->mFP
;
6752 if (f
->async_visible
== 0)
6754 f
->async_visible
= 1;
6755 f
->async_iconified
= 0;
6756 SET_FRAME_GARBAGED (f
);
6758 /* An update event is equivalent to MapNotify on X, so report
6759 visibility changes properly. */
6760 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
6761 /* Force a redisplay sooner or later to update the
6762 frame titles in case this is the second frame. */
6763 record_asynch_buffer_change ();
6768 handling_window_update
= 1;
6770 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
6772 expose_frame (f
, 0, 0, 0, 0);
6774 handling_window_update
= 0;
6781 is_emacs_window (WindowPtr win
)
6783 Lisp_Object tail
, frame
;
6788 FOR_EACH_FRAME (tail
, frame
)
6789 if (FRAME_MAC_P (XFRAME (frame
)))
6790 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
6797 do_window_activate (WindowPtr win
)
6802 if (is_emacs_window (win
))
6804 mwp
= (mac_output
*) GetWRefCon (win
);
6809 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6810 activate_scroll_bars (f
);
6816 do_window_deactivate (WindowPtr win
)
6821 if (is_emacs_window (win
))
6823 mwp
= (mac_output
*) GetWRefCon (win
);
6826 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6828 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6829 deactivate_scroll_bars (f
);
6842 if (is_emacs_window (wp
))
6844 mwp
= (mac_output
*) GetWRefCon (wp
);
6849 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6850 activate_scroll_bars (f
);
6854 app_is_suspended
= false;
6855 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6866 if (is_emacs_window (wp
))
6868 mwp
= (mac_output
*) GetWRefCon (wp
);
6871 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6873 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6874 deactivate_scroll_bars (f
);
6878 app_is_suspended
= true;
6879 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
6884 do_mouse_moved (Point mouse_pos
)
6886 WindowPtr wp
= FrontWindow ();
6889 if (is_emacs_window (wp
))
6891 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6893 #if TARGET_API_MAC_CARBON
6894 SetPort (GetWindowPort (wp
));
6899 GlobalToLocal (&mouse_pos
);
6901 note_mouse_movement (f
, &mouse_pos
);
6907 do_os_event (EventRecord
*erp
)
6909 switch((erp
->message
>> 24) & 0x000000FF)
6911 case suspendResumeMessage
:
6912 if((erp
->message
& resumeFlag
) == 1)
6918 case mouseMovedMessage
:
6919 do_mouse_moved (erp
->where
);
6925 do_events (EventRecord
*erp
)
6930 do_window_update ((WindowPtr
) erp
->message
);
6938 if ((erp
->modifiers
& activeFlag
) != 0)
6939 do_window_activate ((WindowPtr
) erp
->message
);
6941 do_window_deactivate ((WindowPtr
) erp
->message
);
6947 do_apple_menu (SInt16 menu_item
)
6949 #if !TARGET_API_MAC_CARBON
6951 SInt16 da_driver_refnum
;
6953 if (menu_item
== I_ABOUT
)
6954 NoteAlert (ABOUT_ALERT_ID
, NULL
);
6957 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
6958 da_driver_refnum
= OpenDeskAcc (item_name
);
6960 #endif /* !TARGET_API_MAC_CARBON */
6964 do_menu_choice (SInt32 menu_choice
)
6966 SInt16 menu_id
, menu_item
;
6968 menu_id
= HiWord (menu_choice
);
6969 menu_item
= LoWord (menu_choice
);
6977 do_apple_menu (menu_item
);
6982 WindowPtr wp
= FrontWindow ();
6983 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6984 MenuHandle menu
= GetMenuHandle (menu_id
);
6989 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
6990 menubar_selection_callback (f
, refcon
);
6999 /* Handle drags in size box. Based on code contributed by Ben
7000 Mesander and IM - Window Manager A. */
7003 do_grow_window (WindowPtr w
, EventRecord
*e
)
7008 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7009 struct frame
*f
= mwp
->mFP
;
7011 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7013 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7015 /* see if it really changed size */
7018 rows
= PIXEL_TO_CHAR_HEIGHT (f
, HiWord (grow_size
));
7019 columns
= PIXEL_TO_CHAR_WIDTH (f
, LoWord (grow_size
));
7021 x_set_window_size (f
, 0, columns
, rows
);
7026 /* Handle clicks in zoom box. Calculation of "standard state" based
7027 on code in IM - Window Manager A and code contributed by Ben
7028 Mesander. The standard state of an Emacs window is 80-characters
7029 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7032 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7035 Rect zoom_rect
, port_rect
;
7037 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
7038 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7039 struct frame
*f
= mwp
->mFP
;
7041 GetPort (&save_port
);
7043 #if TARGET_API_MAC_CARBON
7044 SetPort (GetWindowPort (w
));
7049 /* Clear window to avoid flicker. */
7050 #if TARGET_API_MAC_CARBON
7055 GetWindowPortBounds (w
, &r
);
7058 if (zoom_in_or_out
== inZoomOut
)
7060 /* calculate height of window's title bar (hard card it for now). */
7061 w_title_height
= 20 + GetMBarHeight ();
7063 /* get maximum height of window into zoom_rect.bottom -
7065 GetQDGlobalsScreenBits (&bm
);
7066 zoom_rect
= bm
.bounds
;
7067 zoom_rect
.top
+= w_title_height
;
7068 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7070 zoom_rect
.right
= zoom_rect
.left
7071 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7073 SetWindowStandardState (w
, &zoom_rect
);
7076 #else /* not TARGET_API_MAC_CARBON */
7077 EraseRect (&(w
->portRect
));
7078 if (zoom_in_or_out
== inZoomOut
)
7080 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7081 LocalToGlobal (&top_left
);
7083 /* calculate height of window's title bar */
7084 w_title_height
= top_left
.v
- 1
7085 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7087 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7088 zoom_rect
= qd
.screenBits
.bounds
;
7089 zoom_rect
.top
+= w_title_height
;
7090 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7092 zoom_rect
.right
= zoom_rect
.left
7093 + CHAR_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7095 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7098 #endif /* not TARGET_API_MAC_CARBON */
7100 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
7102 /* retrieve window size and update application values */
7103 #if TARGET_API_MAC_CARBON
7104 GetWindowPortBounds (w
, &port_rect
);
7106 port_rect
= w
->portRect
;
7108 rows
= PIXEL_TO_CHAR_HEIGHT (f
, port_rect
.bottom
- port_rect
.top
);
7109 columns
= PIXEL_TO_CHAR_WIDTH (f
, port_rect
.right
- port_rect
.left
);
7110 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
7112 SetPort (save_port
);
7115 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7117 init_mac_drag_n_drop ()
7119 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7123 /* Intialize AppleEvent dispatcher table for the required events. */
7125 init_required_apple_events ()
7130 /* Make sure we have apple events before starting. */
7131 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7135 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7138 #if TARGET_API_MAC_CARBON
7139 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7140 NewAEEventHandlerUPP
7141 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7144 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7145 NewAEEventHandlerProc
7146 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7152 #if TARGET_API_MAC_CARBON
7153 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7154 NewAEEventHandlerUPP
7155 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7158 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7159 NewAEEventHandlerProc
7160 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7166 #if TARGET_API_MAC_CARBON
7167 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7168 NewAEEventHandlerUPP
7169 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7172 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7173 NewAEEventHandlerProc
7174 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7180 #if TARGET_API_MAC_CARBON
7181 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7182 NewAEEventHandlerUPP
7183 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7186 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7187 NewAEEventHandlerProc
7188 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7195 #if USE_CARBON_EVENTS
7198 init_service_handler ()
7200 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7201 {kEventClassService
, kEventServiceCopy
},
7202 {kEventClassService
, kEventServicePaste
}};
7203 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7204 3, specs
, NULL
, NULL
);
7208 MAC_TODO: Check to see if this is called by AEProcessDesc...
7211 mac_handle_service_event (EventHandlerCallRef callRef
,
7212 EventRef event
, void *data
)
7214 OSStatus err
= noErr
;
7215 switch (GetEventKind (event
))
7217 case kEventServiceGetTypes
:
7219 CFMutableArrayRef copyTypes
, pasteTypes
;
7221 Boolean selection
= true;
7223 GetEventParameter(event, kEventParamServicePasteTypes,
7224 typeCFMutableArrayRef, NULL,
7225 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7227 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7228 typeCFMutableArrayRef
, NULL
,
7229 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7230 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7232 CFArrayAppendValue (copyTypes
, type
);
7233 //CFArrayAppendValue (pasteTypes, type);
7237 case kEventServiceCopy
:
7239 ScrapRef currentScrap
, specificScrap
;
7243 GetCurrentScrap (¤tScrap
);
7245 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7248 void *buffer
= xmalloc (byteCount
);
7251 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7252 sizeof (ScrapRef
), NULL
, &specificScrap
);
7254 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7255 &byteCount
, buffer
);
7257 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7258 kScrapFlavorMaskNone
, byteCount
, buffer
);
7264 case kEventServicePaste
:
7267 // Get the current location
7269 ScrapRef specificScrap;
7270 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7271 sizeof(ScrapRef), NULL, &specificScrap);
7272 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7274 void * buffer = xmalloc(byteCount);
7275 if (buffer != NULL ) {
7276 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7277 &byteCount, buffer);
7279 // Actually place in the buffer
7281 // Get the current "selection" string here
7294 /* Open Application Apple Event */
7296 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7302 /* Defined in mac.c. */
7304 path_from_vol_dir_name (char *, int, short, long, char *);
7307 /* Called when we receive an AppleEvent with an ID of
7308 "kAEOpenDocuments". This routine gets the direct parameter,
7309 extracts the FSSpecs in it, and puts their names on a list. */
7311 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7316 DescType actual_type
;
7319 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7321 goto descriptor_error_exit
;
7323 /* Check to see that we got all of the required parameters from the
7324 event descriptor. For an 'odoc' event this should just be the
7326 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7327 &actual_type
, (Ptr
) &keyword
,
7328 sizeof (keyword
), &actual_size
);
7329 /* No error means that we found some unused parameters.
7330 errAEDescNotFound means that there are no more parameters. If we
7331 get an error code other than that, flag it. */
7332 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7334 err
= errAEEventNotHandled
;
7339 /* Got all the parameters we need. Now, go through the direct
7340 object list and parse it up. */
7342 long num_files_to_open
;
7344 err
= AECountItems (&the_desc
, &num_files_to_open
);
7349 /* AE file list is one based so just use that for indexing here. */
7350 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7353 Str255 path_name
, unix_path_name
;
7358 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7359 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7360 if (err
!= noErr
) break;
7363 err
= FSpMakeFSRef (&fs
, &fref
);
7364 if (err
!= noErr
) break;
7366 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7368 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7370 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7372 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7373 drag_and_drop_file_list
);
7379 /* Nuke the coerced file list in any case */
7380 err2
= AEDisposeDesc(&the_desc
);
7382 descriptor_error_exit
:
7383 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7389 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7390 DragReference theDrag
)
7394 FlavorFlags theFlags
;
7397 ItemReference theItem
;
7400 Size size
= sizeof (HFSFlavor
);
7402 drag_and_drop_file_list
= Qnil
;
7403 GetDragMouse (theDrag
, &mouse
, 0L);
7404 CountDragItems (theDrag
, &items
);
7405 for (index
= 1; index
<= items
; index
++)
7407 /* Only handle file references. */
7408 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7409 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7410 if (result
== noErr
)
7417 Str255 unix_path_name
;
7418 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7420 /* Use Carbon routines, otherwise it converts the file name
7421 to /Macintosh HD/..., which is not correct. */
7422 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7423 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7425 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7426 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7427 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7429 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7430 drag_and_drop_file_list
);
7435 /* If there are items in the list, construct an event and post it to
7436 the queue like an interrupt using kbd_buffer_store_event. */
7437 if (!NILP (drag_and_drop_file_list
))
7439 struct input_event event
;
7441 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
7442 SetPort (GetWindowPort (window
));
7443 GlobalToLocal (&mouse
);
7445 event
.kind
= DRAG_N_DROP_EVENT
;
7447 event
.modifiers
= 0;
7448 event
.timestamp
= TickCount () * (1000 / 60);
7449 XSETINT (event
.x
, mouse
.h
);
7450 XSETINT (event
.y
, mouse
.v
);
7451 XSETFRAME (frame
, f
);
7452 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7454 /* Post to the interrupt queue */
7455 kbd_buffer_store_event (&event
);
7456 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7458 ProcessSerialNumber psn
;
7459 GetCurrentProcess (&psn
);
7460 SetFrontProcess (&psn
);
7466 /* Print Document Apple Event */
7468 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7470 return errAEEventNotHandled
;
7475 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7477 /* FixMe: Do we need an unwind-protect or something here? And what
7478 do we do about unsaved files. Currently just forces quit rather
7479 than doing recursive callback to get user input. */
7481 terminate_flag
= true;
7483 /* Fkill_emacs doesn't return. We have to return. (TI) */
7490 profiler_exit_proc ()
7492 ProfilerDump ("\pEmacs.prof");
7497 /* These few functions implement Emacs as a normal Mac application
7498 (almost): set up the heap and the Toolbox, handle necessary
7499 system events plus a few simple menu events. They also set up
7500 Emacs's access to functions defined in the rest of this file.
7501 Emacs uses function hooks to perform all its terminal I/O. A
7502 complete list of these functions appear in termhooks.h. For what
7503 they do, read the comments there and see also w32term.c and
7504 xterm.c. What's noticeably missing here is the event loop, which
7505 is normally present in most Mac application. After performing the
7506 necessary Mac initializations, main passes off control to
7507 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7508 mac_read_socket (defined further below) to read input. This is
7509 where WaitNextEvent is called to process Mac events. This is also
7510 where check_alarm in sysdep.c is called to simulate alarm signals.
7511 This makes the cursor jump back to its correct position after
7512 briefly jumping to that of the matching parenthesis, print useful
7513 hints and prompts in the minibuffer after the user stops typing for
7516 #if !TARGET_API_MAC_CARBON
7521 #if __profile__ /* is the profiler on? */
7522 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7527 /* set creator and type for files created by MSL */
7532 do_init_managers ();
7536 do_check_ram_size ();
7538 init_emacs_passwd_dir ();
7542 initialize_applescript ();
7544 init_required_apple_events ();
7550 /* set up argv array from STR# resource */
7551 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
7555 /* free up AppleScript resources on exit */
7556 atexit (terminate_applescript
);
7558 #if __profile__ /* is the profiler on? */
7559 atexit (profiler_exit_proc
);
7562 /* 3rd param "envp" never used in emacs_main */
7563 (void) emacs_main (argc
, argv
, 0);
7566 /* Never reached - real exit in Fkill_emacs */
7571 /* Table for translating Mac keycode to X keysym values. Contributed
7572 by Sudhir Shenoy. */
7573 static unsigned char keycode_to_xkeysym_table
[] = {
7574 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7575 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7576 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7578 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
7579 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
7580 /*0x38*/ 0, 0, 0, 0,
7581 /*0x3C*/ 0, 0, 0, 0,
7583 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
7584 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
7585 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
7586 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
7588 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
7589 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
7590 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
7591 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
7593 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
7594 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
7595 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
7596 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
7598 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
7599 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
7600 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
7601 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
7605 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
7607 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
7608 return *xKeySym
!= 0;
7611 /* Emacs calls this whenever it wants to read an input event from the
7614 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
7617 #if USE_CARBON_EVENTS
7620 EventMouseButton mouseBtn
;
7624 EventMask event_mask
;
7627 if (interrupt_input_blocked
)
7629 interrupt_input_pending
= 1;
7634 interrupt_input_pending
= 0;
7637 /* So people can tell when we have read the available input. */
7638 input_signal_count
++;
7643 /* Don't poll for events to process (specifically updateEvt) if
7644 window update currently already in progress. A call to redisplay
7645 (in do_window_update) can be preempted by another call to
7646 redisplay, causing blank regions to be left on the screen and the
7647 cursor to be left at strange places. */
7648 if (handling_window_update
)
7655 Fkill_emacs (make_number (1));
7657 /* It is necessary to set this (additional) argument slot of an
7658 event to nil because keyboard.c protects incompletely processed
7659 event from being garbage collected by placing them in the
7660 kbd_buffer_gcpro vector. */
7663 event_mask
= everyEvent
;
7664 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
7665 event_mask
-= highLevelEventMask
;
7667 #if USE_CARBON_EVENTS
7668 rneResult
= ReceiveNextEvent (0, NULL
,
7670 ? TicksToEventTime (app_sleep_time
)
7672 kEventRemoveFromQueue
, &eventRef
);
7675 /* Handle new events */
7676 if (!mac_convert_event_ref (eventRef
, &er
))
7677 switch (GetEventClass (eventRef
))
7679 case kEventClassMouse
:
7680 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
7684 WindowPtr window_ptr
= FrontNonFloatingWindow ();
7685 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7686 if (!IsValidWindowPtr (window_ptr
))
7693 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
7694 typeSInt32
, NULL
, sizeof (SInt32
),
7696 GetEventParameter(eventRef
, kEventParamMouseLocation
,
7697 typeQDPoint
, NULL
, sizeof (Point
),
7699 bufp
->kind
= MOUSE_WHEEL_EVENT
;
7701 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
7702 SetPort (GetWindowPort (window_ptr
));
7703 GlobalToLocal (&point
);
7704 XSETINT (bufp
->x
, point
.h
);
7705 XSETINT (bufp
->y
, point
.v
);
7706 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7707 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
7711 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7715 /* Send the event to the appropriate receiver. */
7716 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7720 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
7721 #endif /* USE_CARBON_EVENTS */
7727 WindowPtr window_ptr
= FrontWindow ();
7730 #if USE_CARBON_EVENTS
7731 /* This is needed to send mouse events like aqua window buttons
7732 to the correct handler. */
7733 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
7737 if (!is_emacs_window(window_ptr
))
7741 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
7742 && er
.what
== mouseUp
)
7744 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7745 Point mouse_loc
= er
.where
;
7747 /* Convert to local coordinates of new window. */
7748 #if TARGET_API_MAC_CARBON
7749 SetPort (GetWindowPort (window_ptr
));
7751 SetPort (window_ptr
);
7754 GlobalToLocal (&mouse_loc
);
7756 #if USE_CARBON_EVENTS
7757 bufp
->code
= mac_get_mouse_btn (eventRef
);
7759 bufp
->code
= 0; /* only one mouse button */
7761 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
7762 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
7763 bufp
->part
= scroll_bar_handle
;
7764 #if USE_CARBON_EVENTS
7765 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7767 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7769 bufp
->modifiers
|= up_modifier
;
7770 bufp
->timestamp
= er
.when
* (1000 / 60);
7771 /* ticks to milliseconds */
7773 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
7774 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
7775 tracked_scroll_bar
->dragging
= Qnil
;
7776 mouse_tracking_in_progress
= mouse_tracking_none
;
7777 tracked_scroll_bar
= NULL
;
7782 part_code
= FindWindow (er
.where
, &window_ptr
);
7788 struct frame
*f
= ((mac_output
*)
7789 GetWRefCon (FrontWindow ()))->mFP
;
7790 saved_menu_event_location
= er
.where
;
7791 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
7792 XSETFRAME (bufp
->frame_or_window
, f
);
7798 if (window_ptr
!= FrontWindow ())
7799 SelectWindow (window_ptr
);
7802 SInt16 control_part_code
;
7804 struct mac_output
*mwp
= (mac_output
*)
7805 GetWRefCon (window_ptr
);
7806 Point mouse_loc
= er
.where
;
7808 /* convert to local coordinates of new window */
7809 #if TARGET_API_MAC_CARBON
7810 SetPort (GetWindowPort (window_ptr
));
7812 SetPort (window_ptr
);
7815 GlobalToLocal (&mouse_loc
);
7816 #if TARGET_API_MAC_CARBON
7817 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
7818 &control_part_code
);
7820 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
7823 #if USE_CARBON_EVENTS
7824 bufp
->code
= mac_get_mouse_btn (eventRef
);
7826 bufp
->code
= 0; /* only one mouse button */
7828 XSETINT (bufp
->x
, mouse_loc
.h
);
7829 XSETINT (bufp
->y
, mouse_loc
.v
);
7830 bufp
->timestamp
= er
.when
* (1000 / 60);
7831 /* ticks to milliseconds */
7833 #if TARGET_API_MAC_CARBON
7836 if (control_part_code
!= 0)
7839 struct scroll_bar
*bar
= (struct scroll_bar
*)
7840 GetControlReference (ch
);
7841 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
7843 if (er
.what
== mouseDown
7844 && control_part_code
== kControlIndicatorPart
)
7846 mouse_tracking_in_progress
7847 = mouse_tracking_scroll_bar
;
7848 tracked_scroll_bar
= bar
;
7852 mouse_tracking_in_progress
= mouse_tracking_none
;
7853 tracked_scroll_bar
= NULL
;
7858 bufp
->kind
= MOUSE_CLICK_EVENT
;
7859 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7860 if (er
.what
== mouseDown
)
7861 mouse_tracking_in_progress
7862 = mouse_tracking_mouse_movement
;
7864 mouse_tracking_in_progress
= mouse_tracking_none
;
7867 #if USE_CARBON_EVENTS
7868 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7870 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7876 bufp
->modifiers
|= down_modifier
;
7879 bufp
->modifiers
|= up_modifier
;
7888 #if TARGET_API_MAC_CARBON
7892 GetQDGlobalsScreenBits (&bm
);
7893 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
7895 #else /* not TARGET_API_MAC_CARBON */
7896 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
7897 #endif /* not TARGET_API_MAC_CARBON */
7901 if (TrackGoAway (window_ptr
, er
.where
))
7903 bufp
->kind
= DELETE_WINDOW_EVENT
;
7904 XSETFRAME (bufp
->frame_or_window
,
7905 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
7910 /* window resize handling added --ben */
7912 do_grow_window(window_ptr
, &er
);
7915 /* window zoom handling added --ben */
7918 if (TrackBox (window_ptr
, er
.where
, part_code
))
7919 do_zoom_window (window_ptr
, part_code
);
7931 #if USE_CARBON_EVENTS
7932 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
7940 int keycode
= (er
.message
& keyCodeMask
) >> 8;
7943 #if USE_CARBON_EVENTS
7944 /* When using Carbon Events, we need to pass raw keyboard events
7945 to the TSM ourselves. If TSM handles it, it will pass back
7946 noErr, otherwise it will pass back "eventNotHandledErr" and
7947 we can process it normally. */
7948 if ((!NILP (Vmac_pass_command_to_system
)
7949 || !(er
.modifiers
& cmdKey
))
7950 && (!NILP (Vmac_pass_control_to_system
)
7951 || !(er
.modifiers
& controlKey
)))
7954 err
= SendEventToEventTarget (eventRef
,
7955 GetEventDispatcherTarget ());
7956 if (err
!= eventNotHandledErr
)
7961 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
7970 if (keycode_to_xkeysym (keycode
, &xkeysym
))
7972 bufp
->code
= 0xff00 | xkeysym
;
7973 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
7977 if (er
.modifiers
& (controlKey
|
7978 (NILP (Vmac_command_key_is_meta
) ? optionKey
7981 /* This code comes from Keyboard Resource, Appendix
7982 C of IM - Text. This is necessary since shift is
7983 ignored in KCHR table translation when option or
7984 command is pressed. It also does not translate
7985 correctly control-shift chars like C-% so mask off
7987 int new_modifiers
= er
.modifiers
& 0xe600;
7988 /* mask off option and command */
7989 int new_keycode
= keycode
| new_modifiers
;
7990 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
7991 unsigned long some_state
= 0;
7992 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
7993 &some_state
) & 0xff;
7996 bufp
->code
= er
.message
& charCodeMask
;
7997 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
8001 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
8002 convert non-ASCII characters typed at the Mac keyboard
8003 (presumed to be in the Mac Roman encoding) to iso-latin-1
8004 encoding before they are passed to Emacs. This enables the
8005 Mac keyboard to be used to enter non-ASCII iso-latin-1
8006 characters directly. */
8007 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8008 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
8010 static TECObjectRef converter
= NULL
;
8011 OSStatus the_err
= noErr
;
8012 OSStatus convert_status
= noErr
;
8014 if (converter
== NULL
)
8016 the_err
= TECCreateConverter (&converter
,
8017 kTextEncodingMacRoman
,
8018 mac_keyboard_text_encoding
);
8019 current_mac_keyboard_text_encoding
8020 = mac_keyboard_text_encoding
;
8022 else if (mac_keyboard_text_encoding
8023 != current_mac_keyboard_text_encoding
)
8025 /* Free the converter for the current encoding before
8026 creating a new one. */
8027 TECDisposeConverter (converter
);
8028 the_err
= TECCreateConverter (&converter
,
8029 kTextEncodingMacRoman
,
8030 mac_keyboard_text_encoding
);
8031 current_mac_keyboard_text_encoding
8032 = mac_keyboard_text_encoding
;
8035 if (the_err
== noErr
)
8037 unsigned char ch
= bufp
->code
;
8038 ByteCount actual_input_length
, actual_output_length
;
8039 unsigned char outch
;
8041 convert_status
= TECConvertText (converter
, &ch
, 1,
8042 &actual_input_length
,
8044 &actual_output_length
);
8045 if (convert_status
== noErr
8046 && actual_input_length
== 1
8047 && actual_output_length
== 1)
8052 #if USE_CARBON_EVENTS
8053 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8055 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8060 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8061 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
8064 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8069 case kHighLevelEvent
:
8070 drag_and_drop_file_list
= Qnil
;
8072 AEProcessAppleEvent(&er
);
8074 /* Build a DRAG_N_DROP_EVENT type event as is done in
8075 constuct_drag_n_drop in w32term.c. */
8076 if (!NILP (drag_and_drop_file_list
))
8078 struct frame
*f
= NULL
;
8082 wp
= FrontNonFloatingWindow ();
8086 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8087 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8088 wp
= FrontNonFloatingWindow ();
8091 if (wp
&& is_emacs_window(wp
))
8092 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8094 bufp
->kind
= DRAG_N_DROP_EVENT
;
8096 bufp
->timestamp
= er
.when
* (1000 / 60);
8097 /* ticks to milliseconds */
8098 #if USE_CARBON_EVENTS
8099 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8101 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8104 XSETINT (bufp
->x
, 0);
8105 XSETINT (bufp
->y
, 0);
8107 XSETFRAME (frame
, f
);
8108 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8110 /* Regardless of whether Emacs was suspended or in the
8111 foreground, ask it to redraw its entire screen.
8112 Otherwise parts of the screen can be left in an
8113 inconsistent state. */
8115 #if TARGET_API_MAC_CARBON
8119 GetWindowPortBounds (wp
, &r
);
8120 InvalWindowRect (wp
, &r
);
8122 #else /* not TARGET_API_MAC_CARBON */
8123 InvalRect (&(wp
->portRect
));
8124 #endif /* not TARGET_API_MAC_CARBON */
8131 #if USE_CARBON_EVENTS
8132 ReleaseEvent (eventRef
);
8136 /* If the focus was just given to an autoraising frame,
8138 /* ??? This ought to be able to handle more than one such frame. */
8139 if (pending_autoraise_frame
)
8141 x_raise_frame (pending_autoraise_frame
);
8142 pending_autoraise_frame
= 0;
8145 #if !TARGET_API_MAC_CARBON
8146 check_alarm (); /* simulate the handling of a SIGALRM */
8150 static Point old_mouse_pos
= { -1, -1 };
8152 if (app_is_suspended
)
8154 old_mouse_pos
.h
= -1;
8155 old_mouse_pos
.v
= -1;
8163 struct scroll_bar
*sb
;
8165 wp
= FrontWindow ();
8166 if (is_emacs_window (wp
))
8168 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8170 #if TARGET_API_MAC_CARBON
8171 SetPort (GetWindowPort (wp
));
8176 GetMouse (&mouse_pos
);
8178 if (!EqualPt (mouse_pos
, old_mouse_pos
))
8180 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8181 && tracked_scroll_bar
)
8182 x_scroll_bar_note_movement (tracked_scroll_bar
,
8184 - XINT (tracked_scroll_bar
->top
),
8185 TickCount() * (1000 / 60));
8187 note_mouse_movement (f
, &mouse_pos
);
8189 old_mouse_pos
= mouse_pos
;
8201 /* Need to override CodeWarrior's input function so no conversion is
8202 done on newlines Otherwise compiled functions in .elc files will be
8203 read incorrectly. Defined in ...:MSL C:MSL
8204 Common:Source:buffer_io.c. */
8207 __convert_to_newlines (unsigned char * p
, size_t * n
)
8213 __convert_from_newlines (unsigned char * p
, size_t * n
)
8220 /* Initialize the struct pointed to by MW to represent a new COLS x
8221 ROWS Macintosh window, using font with name FONTNAME and size
8224 NewMacWindow (FRAME_PTR fp
)
8227 #if TARGET_API_MAC_CARBON
8228 static int making_terminal_window
= 0;
8230 static int making_terminal_window
= 1;
8233 mwp
= fp
->output_data
.mac
;
8235 if (making_terminal_window
)
8237 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8240 making_terminal_window
= 0;
8243 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8246 SetWRefCon (mwp
->mWP
, (long) mwp
);
8247 /* so that update events can find this mac_output struct */
8248 mwp
->mFP
= fp
; /* point back to emacs frame */
8250 #if TARGET_API_MAC_CARBON
8251 SetPort (GetWindowPort (mwp
->mWP
));
8258 SizeWindow (mwp
->mWP
, mwp
->pixel_width
, mwp
->pixel_height
, false);
8259 ShowWindow (mwp
->mWP
);
8265 make_mac_frame (struct frame
*f
)
8267 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8268 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8270 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8274 f
->output_data
.mac
->cursor_pixel
= 0;
8275 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8276 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8277 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8279 f
->output_data
.mac
->fontset
= -1;
8280 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8281 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8282 f
->output_data
.mac
->left_pos
= 4;
8283 f
->output_data
.mac
->top_pos
= 4;
8284 f
->output_data
.mac
->border_width
= 0;
8285 f
->output_data
.mac
->explicit_parent
= 0;
8287 f
->output_data
.mac
->internal_border_width
= 0;
8289 f
->output_method
= output_mac
;
8299 make_mac_terminal_frame (struct frame
*f
)
8303 XSETFRAME (frame
, f
);
8305 f
->output_method
= output_mac
;
8306 f
->output_data
.mac
= (struct mac_output
*)
8307 xmalloc (sizeof (struct mac_output
));
8308 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8309 f
->output_data
.mac
->fontset
= -1;
8310 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8311 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8313 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8322 /* Need to be initialized for unshow_buffer in window.c. */
8323 selected_window
= f
->selected_window
;
8325 Fmodify_frame_parameters (frame
,
8326 Fcons (Fcons (Qfont
,
8327 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8328 Fmodify_frame_parameters (frame
,
8329 Fcons (Fcons (Qforeground_color
,
8330 build_string ("black")), Qnil
));
8331 Fmodify_frame_parameters (frame
,
8332 Fcons (Fcons (Qbackground_color
,
8333 build_string ("white")), Qnil
));
8337 /***********************************************************************
8339 ***********************************************************************/
8341 #ifdef USE_X_TOOLKIT
8342 static XrmOptionDescRec emacs_options
[] = {
8343 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
8344 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
8346 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
8347 XrmoptionSepArg
, NULL
},
8348 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
8350 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8351 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8352 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8353 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
8354 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
8355 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
8356 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
8358 #endif /* USE_X_TOOLKIT */
8361 /* Test whether two display-name strings agree up to the dot that separates
8362 the screen number from the server number. */
8364 same_x_server (name1
, name2
)
8365 char *name1
, *name2
;
8368 unsigned char *system_name
= SDATA (Vsystem_name
);
8369 int system_name_length
= strlen (system_name
);
8370 int length_until_period
= 0;
8372 while (system_name
[length_until_period
] != 0
8373 && system_name
[length_until_period
] != '.')
8374 length_until_period
++;
8376 /* Treat `unix' like an empty host name. */
8377 if (! strncmp (name1
, "unix:", 5))
8379 if (! strncmp (name2
, "unix:", 5))
8381 /* Treat this host's name like an empty host name. */
8382 if (! strncmp (name1
, system_name
, system_name_length
)
8383 && name1
[system_name_length
] == ':')
8384 name1
+= system_name_length
;
8385 if (! strncmp (name2
, system_name
, system_name_length
)
8386 && name2
[system_name_length
] == ':')
8387 name2
+= system_name_length
;
8388 /* Treat this host's domainless name like an empty host name. */
8389 if (! strncmp (name1
, system_name
, length_until_period
)
8390 && name1
[length_until_period
] == ':')
8391 name1
+= length_until_period
;
8392 if (! strncmp (name2
, system_name
, length_until_period
)
8393 && name2
[length_until_period
] == ':')
8394 name2
+= length_until_period
;
8396 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
8400 if (seen_colon
&& *name1
== '.')
8404 && (*name1
== '.' || *name1
== '\0')
8405 && (*name2
== '.' || *name2
== '\0'));
8409 int mac_initialized
= 0;
8412 mac_initialize_display_info ()
8414 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8415 GDHandle main_device_handle
;
8417 bzero (dpyinfo
, sizeof (*dpyinfo
));
8419 /* Put it on x_display_name_list. */
8420 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8421 x_display_name_list
);
8422 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8425 dpyinfo
->mac_id_name
8426 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8427 + SCHARS (Vsystem_name
)
8429 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8430 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8432 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8433 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8436 main_device_handle
= LMGetMainDevice();
8438 dpyinfo
->reference_count
= 0;
8439 dpyinfo
->resx
= 75.0;
8440 dpyinfo
->resy
= 75.0;
8441 dpyinfo
->n_planes
= 1;
8442 dpyinfo
->n_cbits
= 16;
8443 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8444 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8445 dpyinfo
->grabbed
= 0;
8446 dpyinfo
->root_window
= NULL
;
8448 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8449 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8450 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8451 dpyinfo
->mouse_face_window
= Qnil
;
8454 struct mac_display_info
*
8455 mac_term_init (display_name
, xrm_option
, resource_name
)
8456 Lisp_Object display_name
;
8458 char *resource_name
;
8460 struct mac_display_info
*dpyinfo
;
8461 GDHandle main_device_handle
;
8463 if (!mac_initialized
)
8466 mac_initialized
= 1;
8469 mac_initialize_display_info (display_name
);
8471 dpyinfo
= &one_mac_display_info
;
8473 main_device_handle
= LMGetMainDevice();
8475 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8476 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8485 extern int inhibit_window_system
;
8486 extern int noninteractive
;
8487 CFBundleRef appsBundle
;
8490 /* No need to test if already -nw*/
8491 if (inhibit_window_system
|| noninteractive
)
8494 appsBundle
= CFBundleGetMainBundle();
8495 if (appsBundle
!= NULL
)
8497 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
8498 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
8499 /* We found the bundle identifier, now we know we are valid. */
8506 /* MAC_TODO: Have this start the bundled executable */
8508 /* For now, prevent the fatal error by bringing it up in the terminal */
8509 inhibit_window_system
= 1;
8513 MakeMeTheFrontProcess ()
8515 ProcessSerialNumber psn
;
8518 err
= GetCurrentProcess (&psn
);
8520 (void) SetFrontProcess (&psn
);
8523 /***** Code to handle C-g testing *****/
8525 /* Contains the Mac modifier formed from quit_char */
8526 static mac_quit_char_modifiers
= 0;
8527 static mac_quit_char_keycode
;
8528 extern int quit_char
;
8531 mac_determine_quit_char_modifiers()
8533 /* Todo: Determine modifiers from quit_char. */
8534 UInt32 qc_modifiers
= ctrl_modifier
;
8537 mac_quit_char_modifiers
= 0;
8538 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
8539 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
8540 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
8541 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
8545 init_quit_char_handler ()
8547 /* TODO: Let this support keys other the 'g' */
8548 mac_quit_char_keycode
= 5;
8549 /* Look at <architecture/adb_kb_map.h> for details */
8550 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
8552 mac_determine_quit_char_modifiers();
8556 quit_char_comp (EventRef inEvent
, void *inCompData
)
8558 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
8560 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
8564 UInt32 keyModifiers
;
8565 GetEventParameter(inEvent
, kEventParamKeyCode
,
8566 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
8567 if (keyCode
!= mac_quit_char_keycode
)
8569 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
8570 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
8571 if (keyModifiers
!= mac_quit_char_modifiers
)
8578 mac_check_for_quit_char ()
8581 static EMACS_TIME last_check_time
= { 0, 0 };
8582 static EMACS_TIME one_second
= { 1, 0 };
8585 /* If windows are not initialized, return immediately (keep it bouncin'). */
8586 if (!mac_quit_char_modifiers
)
8589 /* Don't check if last check is less than a second ago. */
8590 EMACS_GET_TIME (now
);
8591 EMACS_SUB_TIME (t
, now
, last_check_time
);
8592 if (EMACS_TIME_LT (t
, one_second
))
8594 last_check_time
= now
;
8596 /* Redetermine modifiers because they are based on lisp variables */
8597 mac_determine_quit_char_modifiers ();
8599 /* Fill the queue with events */
8600 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
8601 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
8605 struct input_event e
;
8606 struct mac_output
*mwp
=
8607 (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8608 /* Use an input_event to emulate what the interrupt handler does. */
8609 e
.kind
= ASCII_KEYSTROKE_EVENT
;
8613 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
8614 XSETFRAME (e
.frame_or_window
, mwp
->mFP
);
8615 /* Remove event from queue to prevent looping. */
8616 RemoveEventFromQueue (GetMainEventQueue (), event
);
8617 ReleaseEvent (event
);
8618 kbd_buffer_store_event (&e
);
8622 #endif /* MAC_OSX */
8624 /* Set up use of X before we make the first connection. */
8626 extern frame_parm_handler mac_frame_parm_handlers
[];
8628 static struct redisplay_interface x_redisplay_interface
=
8630 mac_frame_parm_handlers
,
8634 x_clear_end_of_line
,
8636 x_after_update_window_line
,
8637 x_update_window_begin
,
8638 x_update_window_end
,
8642 x_clear_window_mouse_face
,
8643 x_get_glyph_overhangs
,
8644 x_fix_overlapping_area
,
8645 x_draw_fringe_bitmap
,
8646 mac_per_char_metric
,
8648 NULL
, /* mac_compute_glyph_string_overhangs */
8649 x_draw_glyph_string
,
8650 mac_define_frame_cursor
,
8651 mac_clear_frame_area
,
8652 mac_draw_window_cursor
,
8653 mac_draw_vertical_window_border
,
8654 mac_shift_glyphs_for_insert
8660 rif
= &x_redisplay_interface
;
8662 clear_frame_hook
= x_clear_frame
;
8663 ins_del_lines_hook
= x_ins_del_lines
;
8664 delete_glyphs_hook
= x_delete_glyphs
;
8665 ring_bell_hook
= XTring_bell
;
8666 reset_terminal_modes_hook
= XTreset_terminal_modes
;
8667 set_terminal_modes_hook
= XTset_terminal_modes
;
8668 update_begin_hook
= x_update_begin
;
8669 update_end_hook
= x_update_end
;
8670 set_terminal_window_hook
= XTset_terminal_window
;
8671 read_socket_hook
= XTread_socket
;
8672 frame_up_to_date_hook
= XTframe_up_to_date
;
8673 mouse_position_hook
= XTmouse_position
;
8674 frame_rehighlight_hook
= XTframe_rehighlight
;
8675 frame_raise_lower_hook
= XTframe_raise_lower
;
8677 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
8678 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
8679 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
8680 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
8682 scroll_region_ok
= 1; /* we'll scroll partial frames */
8683 char_ins_del_ok
= 1;
8684 line_ins_del_ok
= 1; /* we'll just blt 'em */
8685 fast_clear_end_of_line
= 1; /* X does this well */
8686 memory_below_frame
= 0; /* we don't remember what scrolls
8691 last_tool_bar_item
= -1;
8692 any_help_event_p
= 0;
8694 /* Try to use interrupt input; if we can't, then start polling. */
8695 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
8697 #ifdef USE_X_TOOLKIT
8698 XtToolkitInitialize ();
8699 Xt_app_con
= XtCreateApplicationContext ();
8700 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
8702 /* Install an asynchronous timer that processes Xt timeout events
8703 every 0.1s. This is necessary because some widget sets use
8704 timeouts internally, for example the LessTif menu bar, or the
8705 Xaw3d scroll bar. When Xt timouts aren't processed, these
8706 widgets don't behave normally. */
8708 EMACS_TIME interval
;
8709 EMACS_SET_SECS_USECS (interval
, 0, 100000);
8710 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
8714 #if USE_TOOLKIT_SCROLL_BARS
8715 xaw3d_arrow_scroll
= False
;
8716 xaw3d_pick_top
= True
;
8720 /* Note that there is no real way portable across R3/R4 to get the
8721 original error handler. */
8722 XSetErrorHandler (x_error_handler
);
8723 XSetIOErrorHandler (x_io_error_quitter
);
8725 /* Disable Window Change signals; they are handled by X events. */
8727 signal (SIGWINCH
, SIG_DFL
);
8728 #endif /* ! defined (SIGWINCH) */
8730 signal (SIGPIPE
, x_connection_signal
);
8733 mac_initialize_display_info ();
8735 #if TARGET_API_MAC_CARBON
8736 init_required_apple_events ();
8738 init_mac_drag_n_drop ();
8740 #if USE_CARBON_EVENTS
8741 init_service_handler ();
8743 init_quit_char_handler ();
8746 DisableMenuCommand (NULL
, kHICommandQuit
);
8748 if (!inhibit_window_system
)
8749 MakeMeTheFrontProcess ();
8758 staticpro (&x_error_message_string
);
8759 x_error_message_string
= Qnil
;
8762 Fprovide (intern ("mac-carbon"), Qnil
);
8764 staticpro (&x_display_name_list
);
8765 x_display_name_list
= Qnil
;
8767 staticpro (&last_mouse_scroll_bar
);
8768 last_mouse_scroll_bar
= Qnil
;
8770 staticpro (&Qvendor_specific_keysyms
);
8771 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
8773 staticpro (&last_mouse_press_frame
);
8774 last_mouse_press_frame
= Qnil
;
8776 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
8777 staticpro (&Qmac_ready_for_drag_n_drop
);
8779 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
8780 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
8781 x_autoselect_window_p
= 0;
8783 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
8784 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
8785 Vx_toolkit_scroll_bars
= Qt
;
8787 DEFVAR_BOOL ("x-use-underline-position-properties",
8788 &x_use_underline_position_properties
,
8789 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
8790 nil means ignore them. If you encounter fonts with bogus
8791 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
8792 to 4.1, set this to nil. */);
8793 x_use_underline_position_properties
= 0;
8795 staticpro (&last_mouse_motion_frame
);
8796 last_mouse_motion_frame
= Qnil
;
8798 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
8799 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
8800 Otherwise the option key is used. */);
8801 Vmac_command_key_is_meta
= Qt
;
8803 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
8804 doc
: /* Non-nil means that the control and meta keys are reversed. This is
8805 useful for non-standard keyboard layouts. */);
8806 Vmac_reverse_ctrl_meta
= Qnil
;
8808 #if USE_CARBON_EVENTS
8809 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
8810 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
8811 the right click will be mouse-3.
8812 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
8813 Vmac_wheel_button_is_mouse_2
= Qt
;
8815 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
8816 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
8817 Toolbox for processing before Emacs sees it. */);
8818 Vmac_pass_command_to_system
= Qt
;
8820 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
8821 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
8822 Toolbox for processing before Emacs sees it. */);
8823 Vmac_pass_control_to_system
= Qt
;
8826 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
8827 doc
: /* One of the Text Encoding Base constant values defined in the
8828 Basic Text Constants section of Inside Macintosh - Text Encoding
8829 Conversion Manager. Its value determines the encoding characters
8830 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
8831 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
8832 its default value, no conversion takes place. If it is set to
8833 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
8834 characters typed on Mac keyboard are first converted into the
8835 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
8836 passed to Emacs. Together with Emacs's set-keyboard-coding-system
8837 command, this enables the Mac keyboard to be used to enter non-ASCII
8838 characters directly. */);
8839 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;