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
*, GC
));
310 static void x_flush
P_ ((struct frame
*f
));
311 static void x_update_begin
P_ ((struct frame
*));
312 static void x_update_window_begin
P_ ((struct window
*));
313 static void x_after_update_window_line
P_ ((struct glyph_row
*));
315 void activate_scroll_bars (FRAME_PTR
);
316 void deactivate_scroll_bars (FRAME_PTR
);
318 static int is_emacs_window (WindowPtr
);
320 extern int image_ascent (struct image
*, struct face
*);
321 int x_bitmap_icon (struct frame
*, Lisp_Object
);
322 void x_make_frame_visible (struct frame
*);
324 extern void window_scroll (Lisp_Object
, int, int, int);
326 /* Defined in macmenu.h. */
327 extern void menubar_selection_callback (FRAME_PTR
, int);
328 extern void set_frame_menubar (FRAME_PTR
, int, int);
330 /* X display function emulation */
333 XFreePixmap (display
, pixmap
)
337 PixMap
*p
= (PixMap
*) pixmap
;
344 /* Set foreground color for subsequent QuickDraw commands. Assume
345 graphic port has already been set. */
348 mac_set_forecolor (unsigned long color
)
352 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
353 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
354 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
356 RGBForeColor (&fg_color
);
360 /* Set background color for subsequent QuickDraw commands. Assume
361 graphic port has already been set. */
364 mac_set_backcolor (unsigned long color
)
368 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
369 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
370 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
372 RGBBackColor (&bg_color
);
375 /* Set foreground and background color for subsequent QuickDraw
376 commands. Assume that the graphic port has already been set. */
379 mac_set_colors (GC gc
)
381 mac_set_forecolor (gc
->foreground
);
382 mac_set_backcolor (gc
->background
);
385 /* Mac version of XDrawLine. */
388 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
394 #if TARGET_API_MAC_CARBON
395 SetPort (GetWindowPort (w
));
406 /* Mac version of XClearArea. */
409 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
413 unsigned int width
, height
;
416 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
420 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
421 xgc
.background
= mwp
->x_compatible
.background_pixel
;
423 #if TARGET_API_MAC_CARBON
424 SetPort (GetWindowPort (w
));
429 mac_set_colors (&xgc
);
430 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
435 /* Mac version of XClearWindow. */
438 XClearWindow (display
, w
)
442 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
445 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
446 xgc
.background
= mwp
->x_compatible
.background_pixel
;
448 #if TARGET_API_MAC_CARBON
449 SetPort (GetWindowPort (w
));
454 mac_set_colors (&xgc
);
456 #if TARGET_API_MAC_CARBON
460 GetWindowPortBounds (w
, &r
);
463 #else /* not TARGET_API_MAC_CARBON */
464 EraseRect (&(w
->portRect
));
465 #endif /* not TARGET_API_MAC_CARBON */
469 /* Mac replacement for XCopyArea. */
472 mac_draw_bitmap (display
, w
, gc
, x
, y
, bitmap
)
481 #if TARGET_API_MAC_CARBON
482 SetPort (GetWindowPort (w
));
488 SetRect (&r
, x
, y
, x
+ bitmap
->bounds
.right
, y
+ bitmap
->bounds
.bottom
);
490 #if TARGET_API_MAC_CARBON
494 LockPortBits (GetWindowPort (w
));
495 pmh
= GetPortPixMap (GetWindowPort (w
));
496 CopyBits (bitmap
, (BitMap
*) *pmh
, &(bitmap
->bounds
), &r
, srcCopy
, 0);
497 UnlockPortBits (GetWindowPort (w
));
499 #else /* not TARGET_API_MAC_CARBON */
500 CopyBits (bitmap
, &(w
->portBits
), &(bitmap
->bounds
), &r
, srcCopy
, 0);
501 #endif /* not TARGET_API_MAC_CARBON */
505 /* Mac replacement for XSetClipRectangles. */
508 mac_set_clip_rectangle (display
, w
, r
)
513 #if TARGET_API_MAC_CARBON
514 SetPort (GetWindowPort (w
));
523 /* Mac replacement for XSetClipMask. */
526 mac_reset_clipping (display
, w
)
532 #if TARGET_API_MAC_CARBON
533 SetPort (GetWindowPort (w
));
538 SetRect (&r
, -32767, -32767, 32767, 32767);
543 /* Mac replacement for XCreateBitmapFromBitmapData. */
546 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
551 int bytes_per_row
, i
, j
;
553 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
554 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
555 if (!bitmap
->baseAddr
)
558 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
559 for (i
= 0; i
< h
; i
++)
560 for (j
= 0; j
< w
; j
++)
561 if (BitTst (bits
, i
* w
+ j
))
562 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
564 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
569 mac_free_bitmap (bitmap
)
572 xfree (bitmap
->baseAddr
);
575 /* Mac replacement for XFillRectangle. */
578 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
583 unsigned int width
, height
;
587 #if TARGET_API_MAC_CARBON
588 SetPort (GetWindowPort (w
));
594 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
596 PaintRect (&r
); /* using foreground color of gc */
600 /* Mac replacement for XDrawRectangle: dest is a window. */
603 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
608 unsigned int width
, height
;
612 #if TARGET_API_MAC_CARBON
613 SetPort (GetWindowPort (w
));
619 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
621 FrameRect (&r
); /* using foreground color of gc */
625 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
628 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
633 unsigned int width
, height
;
635 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
638 #if TARGET_API_MAC_CARBON
639 SetPort (GetWindowPort (w
));
645 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
647 FrameRect (&r
); /* using foreground color of gc */
653 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
660 int nchars
, mode
, bytes_per_char
;
662 #if TARGET_API_MAC_CARBON
663 SetPort (GetWindowPort (w
));
670 TextFont (gc
->font
->mac_fontnum
);
671 TextSize (gc
->font
->mac_fontsize
);
672 TextFace (gc
->font
->mac_fontface
);
676 DrawText (buf
, 0, nchars
* bytes_per_char
);
680 /* Mac replacement for XDrawString. */
683 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
691 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
695 /* Mac replacement for XDrawString16. */
698 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
706 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
711 /* Mac replacement for XDrawImageString. */
714 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
722 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
726 /* Mac replacement for XDrawString16. */
729 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
737 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
742 /* Mac replacement for XCopyArea: dest must be window. */
745 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
752 unsigned int width
, height
;
757 #if TARGET_API_MAC_CARBON
758 SetPort (GetWindowPort (dest
));
765 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
766 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
768 #if TARGET_API_MAC_CARBON
772 LockPortBits (GetWindowPort (dest
));
773 pmh
= GetPortPixMap (GetWindowPort (dest
));
774 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
775 UnlockPortBits (GetWindowPort (dest
));
777 #else /* not TARGET_API_MAC_CARBON */
778 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
779 #endif /* not TARGET_API_MAC_CARBON */
784 /* Convert a pair of local coordinates to global (screen) coordinates.
785 Assume graphic port has been properly set. */
787 local_to_global_coord (short *h
, short *v
)
801 /* Mac replacement for XCopyArea: used only for scrolling. */
804 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
809 unsigned int width
, height
;
812 #if TARGET_API_MAC_CARBON
813 Rect gw_r
, src_r
, dest_r
;
816 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
817 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
819 SetPort (GetWindowPort (w
));
821 ForeColor (blackColor
);
822 BackColor (whiteColor
);
824 LockPortBits (GetWindowPort (w
));
825 pmh
= GetPortPixMap (GetWindowPort (w
));
826 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
827 UnlockPortBits (GetWindowPort (w
));
830 #else /* not TARGET_API_MAC_CARBON */
838 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
839 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
842 /* Need to use global coordinates and screenBits since src and dest
843 areas overlap in general. */
844 local_to_global_coord (&src_r
.left
, &src_r
.top
);
845 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
846 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
847 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
849 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
851 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
852 color mapping in CopyBits. Otherwise, it will be slow. */
853 ForeColor (blackColor
);
854 BackColor (whiteColor
);
855 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
859 #endif /* not TARGET_API_MAC_CARBON */
863 /* Mac replacement for XCopyArea: dest must be Pixmap. */
866 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
873 unsigned int width
, height
;
877 int src_right
= ((PixMap
*) src
)->bounds
.right
;
878 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
879 int w
= src_right
- src_x
;
880 int h
= src_bottom
- src_y
;
884 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
885 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
887 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
891 /* Mac replacement for XChangeGC. */
894 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
897 if (mask
& GCForeground
)
898 gc
->foreground
= xgcv
->foreground
;
899 if (mask
& GCBackground
)
900 gc
->background
= xgcv
->background
;
902 gc
->font
= xgcv
->font
;
906 /* Mac replacement for XCreateGC. */
909 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
912 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
913 bzero (gc
, sizeof (XGCValues
));
915 XChangeGC (ignore
, gc
, mask
, xgcv
);
921 /* Used in xfaces.c. */
924 XFreeGC (display
, gc
)
932 /* Mac replacement for XGetGCValues. */
935 XGetGCValues (void* ignore
, XGCValues
*gc
,
936 unsigned long mask
, XGCValues
*xgcv
)
938 XChangeGC (ignore
, xgcv
, mask
, gc
);
942 /* Mac replacement for XSetForeground. */
945 XSetForeground (display
, gc
, color
)
950 gc
->foreground
= color
;
954 /* Mac replacement for XSetFont. */
957 XSetFont (display
, gc
, font
)
967 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
968 int *direction
,int *font_ascent
,
969 int *font_descent
, XCharStruct
*cs
)
971 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
975 /* x_sync is a no-op on Mac. */
983 /* Remove calls to XFlush by defining XFlush to an empty replacement.
984 Calls to XFlush should be unnecessary because the X output buffer
985 is flushed automatically as needed by calls to XPending,
986 XNextEvent, or XWindowEvent according to the XFlush man page.
987 XTread_socket calls XPending. Removing XFlush improves
990 #if TARGET_API_MAC_CARBON
991 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
993 #define XFlush(DISPLAY) (void) 0
996 /* Flush display of frame F, or of all frames if F is null. */
1002 #if TARGET_API_MAC_CARBON
1006 Lisp_Object rest
, frame
;
1007 FOR_EACH_FRAME (rest
, frame
)
1008 x_flush (XFRAME (frame
));
1010 else if (FRAME_X_P (f
))
1011 XFlush (FRAME_MAC_DISPLAY (f
));
1013 #endif /* TARGET_API_MAC_CARBON */
1018 /* Return the struct mac_display_info corresponding to DPY. There's
1021 struct mac_display_info
*
1022 mac_display_info_for_display (dpy
)
1025 return &one_mac_display_info
;
1030 /***********************************************************************
1031 Starting and ending an update
1032 ***********************************************************************/
1034 /* Start an update of frame F. This function is installed as a hook
1035 for update_begin, i.e. it is called when update_begin is called.
1036 This function is called prior to calls to x_update_window_begin for
1037 each window being updated. */
1043 /* Nothing to do. */
1047 /* Start update of window W. Set the global variable updated_window
1048 to the window being updated and set output_cursor to the cursor
1052 x_update_window_begin (w
)
1055 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1056 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1059 set_output_cursor (&w
->cursor
);
1063 if (f
== display_info
->mouse_face_mouse_frame
)
1065 /* Don't do highlighting for mouse motion during the update. */
1066 display_info
->mouse_face_defer
= 1;
1068 /* If F needs to be redrawn, simply forget about any prior mouse
1070 if (FRAME_GARBAGED_P (f
))
1071 display_info
->mouse_face_window
= Qnil
;
1073 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1074 their mouse_face_p flag set, which means that they are always
1075 unequal to rows in a desired matrix which never have that
1076 flag set. So, rows containing mouse-face glyphs are never
1077 scrolled, and we don't have to switch the mouse highlight off
1078 here to prevent it from being scrolled. */
1080 /* Can we tell that this update does not affect the window
1081 where the mouse highlight is? If so, no need to turn off.
1082 Likewise, don't do anything if the frame is garbaged;
1083 in that case, the frame's current matrix that we would use
1084 is all wrong, and we will redisplay that line anyway. */
1085 if (!NILP (display_info
->mouse_face_window
)
1086 && w
== XWINDOW (display_info
->mouse_face_window
))
1090 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1091 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1094 if (i
< w
->desired_matrix
->nrows
)
1095 clear_mouse_face (display_info
);
1104 /* Draw a vertical window border from (x,y0) to (x,y1) */
1107 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1111 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1113 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1114 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1118 /* End update of window W (which is equal to updated_window).
1120 Draw vertical borders between horizontally adjacent windows, and
1121 display W's cursor if CURSOR_ON_P is non-zero.
1123 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1124 glyphs in mouse-face were overwritten. In that case we have to
1125 make sure that the mouse-highlight is properly redrawn.
1127 W may be a menu bar pseudo-window in case we don't have X toolkit
1128 support. Such windows don't have a cursor, so don't display it
1132 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1134 int cursor_on_p
, mouse_face_overwritten_p
;
1136 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1138 if (!w
->pseudo_window_p
)
1143 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1145 output_cursor
.x
, output_cursor
.y
);
1147 x_draw_vertical_border (w
);
1151 /* If a row with mouse-face was overwritten, arrange for
1152 XTframe_up_to_date to redisplay the mouse highlight. */
1153 if (mouse_face_overwritten_p
)
1155 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1156 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1157 dpyinfo
->mouse_face_window
= Qnil
;
1161 /* Unhide the caret. This won't actually show the cursor, unless it
1162 was visible before the corresponding call to HideCaret in
1163 x_update_window_begin. */
1164 if (w32_use_visible_system_caret
)
1165 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1168 updated_window
= NULL
;
1172 /* End update of frame F. This function is installed as a hook in
1179 /* Reset the background color of Mac OS Window to that of the frame after
1180 update so that it is used by Mac Toolbox to clear the update region before
1181 an update event is generated. */
1182 #if TARGET_API_MAC_CARBON
1183 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1185 SetPort (FRAME_MAC_WINDOW (f
));
1188 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1190 /* Mouse highlight may be displayed again. */
1191 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1194 XFlush (FRAME_MAC_DISPLAY (f
));
1199 /* This function is called from various places in xdisp.c whenever a
1200 complete update has been performed. The global variable
1201 updated_window is not available here. */
1204 XTframe_up_to_date (f
)
1209 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1211 if (dpyinfo
->mouse_face_deferred_gc
1212 || f
== dpyinfo
->mouse_face_mouse_frame
)
1215 if (dpyinfo
->mouse_face_mouse_frame
)
1216 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1217 dpyinfo
->mouse_face_mouse_x
,
1218 dpyinfo
->mouse_face_mouse_y
);
1219 dpyinfo
->mouse_face_deferred_gc
= 0;
1226 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1227 arrow bitmaps, or clear the fringes if no bitmaps are required
1228 before DESIRED_ROW is made current. The window being updated is
1229 found in updated_window. This function is called from
1230 update_window_line only if it is known that there are differences
1231 between bitmaps to be drawn between current row and DESIRED_ROW. */
1234 x_after_update_window_line (desired_row
)
1235 struct glyph_row
*desired_row
;
1237 struct window
*w
= updated_window
;
1243 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1246 draw_row_fringe_bitmaps (w
, desired_row
);
1250 /* When a window has disappeared, make sure that no rest of
1251 full-width rows stays visible in the internal border. Could
1252 check here if updated_window is the leftmost/rightmost window,
1253 but I guess it's not worth doing since vertically split windows
1254 are almost never used, internal border is rarely set, and the
1255 overhead is very small. */
1256 if (windows_or_buffers_changed
1257 && desired_row
->full_width_p
1258 && (f
= XFRAME (w
->frame
),
1259 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1261 && (height
= desired_row
->visible_height
,
1264 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1265 /* Internal border is drawn below the tool bar. */
1266 if (WINDOWP (f
->tool_bar_window
)
1267 && w
== XWINDOW (f
->tool_bar_window
))
1272 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1273 0, y
, width
, height
, 0);
1274 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1275 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1283 /* Draw the bitmap WHICH in one of the left or right fringes of
1284 window W. ROW is the glyph row for which to display the bitmap; it
1285 determines the vertical position at which the bitmap has to be
1289 x_draw_fringe_bitmap (w
, row
, p
)
1291 struct glyph_row
*row
;
1292 struct draw_fringe_bitmap_params
*p
;
1294 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1295 Display
*display
= FRAME_MAC_DISPLAY (f
);
1296 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1298 GC gc
= f
->output_data
.mac
->normal_gc
;
1299 struct face
*face
= p
->face
;
1301 /* Must clip because of partially visible lines. */
1302 x_clip_to_row (w
, row
, gc
);
1307 gcv
.foreground
= face
->background
;
1309 #if 0 /* MAC_TODO: stipple */
1310 /* In case the same realized face is used for fringes and
1311 for something displayed in the text (e.g. face `region' on
1312 mono-displays, the fill style may have been changed to
1313 FillSolid in x_draw_glyph_string_background. */
1315 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1317 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1320 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1322 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1324 #if 0 /* MAC_TODO: stipple */
1326 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1330 if (p
->which
!= NO_FRINGE_BITMAP
)
1332 unsigned char *bits
= fringe_bitmaps
[p
->which
].bits
+ p
->dh
;
1335 mac_create_bitmap_from_bitmap_data (&bitmap
, bits
, p
->wd
, p
->h
);
1336 gcv
.foreground
= face
->foreground
;
1337 gcv
.background
= face
->background
;
1339 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
, &bitmap
);
1341 mac_free_bitmap (&bitmap
);
1344 mac_reset_clipping (display
, window
);
1348 /* This is called when starting Emacs and when restarting after
1349 suspend. When starting Emacs, no window is mapped. And nothing
1350 must be done to Emacs's own window if it is suspended (though that
1354 XTset_terminal_modes ()
1358 /* This is called when exiting or suspending Emacs. Exiting will make
1359 the windows go away, and suspending requires no action. */
1362 XTreset_terminal_modes ()
1367 /***********************************************************************
1369 ***********************************************************************/
1371 /* Function prototypes of this page. */
1373 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1374 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1377 /* Return a pointer to per-char metric information in FONT of a
1378 character pointed by B which is a pointer to an XChar2b. */
1380 #define PER_CHAR_METRIC(font, b) \
1382 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1383 + (((font)->min_byte1 || (font)->max_byte1) \
1384 ? (((b)->byte1 - (font)->min_byte1) \
1385 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1387 : &((font)->max_bounds))
1390 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1391 is not contained in the font. */
1393 static INLINE XCharStruct
*
1394 x_per_char_metric (font
, char2b
)
1398 /* The result metric information. */
1399 XCharStruct
*pcm
= NULL
;
1401 xassert (font
&& char2b
);
1403 if (font
->per_char
!= NULL
)
1405 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1407 /* min_char_or_byte2 specifies the linear character index
1408 corresponding to the first element of the per_char array,
1409 max_char_or_byte2 is the index of the last character. A
1410 character with non-zero CHAR2B->byte1 is not in the font.
1411 A character with byte2 less than min_char_or_byte2 or
1412 greater max_char_or_byte2 is not in the font. */
1413 if (char2b
->byte1
== 0
1414 && char2b
->byte2
>= font
->min_char_or_byte2
1415 && char2b
->byte2
<= font
->max_char_or_byte2
)
1416 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1420 /* If either min_byte1 or max_byte1 are nonzero, both
1421 min_char_or_byte2 and max_char_or_byte2 are less than
1422 256, and the 2-byte character index values corresponding
1423 to the per_char array element N (counting from 0) are:
1425 byte1 = N/D + min_byte1
1426 byte2 = N\D + min_char_or_byte2
1430 D = max_char_or_byte2 - min_char_or_byte2 + 1
1431 / = integer division
1432 \ = integer modulus */
1433 if (char2b
->byte1
>= font
->min_byte1
1434 && char2b
->byte1
<= font
->max_byte1
1435 && char2b
->byte2
>= font
->min_char_or_byte2
1436 && char2b
->byte2
<= font
->max_char_or_byte2
)
1438 pcm
= (font
->per_char
1439 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1440 * (char2b
->byte1
- font
->min_byte1
))
1441 + (char2b
->byte2
- font
->min_char_or_byte2
));
1447 /* If the per_char pointer is null, all glyphs between the first
1448 and last character indexes inclusive have the same
1449 information, as given by both min_bounds and max_bounds. */
1450 if (char2b
->byte2
>= font
->min_char_or_byte2
1451 && char2b
->byte2
<= font
->max_char_or_byte2
)
1452 pcm
= &font
->max_bounds
;
1455 return ((pcm
== NULL
1456 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1463 static XCharStruct
*
1464 mac_per_char_metric (font
, char2b
, font_type
)
1469 return x_per_char_metric (font
, char2b
);
1473 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1474 the two-byte form of C. Encoding is returned in *CHAR2B. */
1477 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1480 struct font_info
*font_info
;
1483 int charset
= CHAR_CHARSET (c
);
1484 XFontStruct
*font
= font_info
->font
;
1486 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1487 This may be either a program in a special encoder language or a
1489 if (font_info
->font_encoder
)
1491 /* It's a program. */
1492 struct ccl_program
*ccl
= font_info
->font_encoder
;
1494 if (CHARSET_DIMENSION (charset
) == 1)
1496 ccl
->reg
[0] = charset
;
1497 ccl
->reg
[1] = char2b
->byte2
;
1501 ccl
->reg
[0] = charset
;
1502 ccl
->reg
[1] = char2b
->byte1
;
1503 ccl
->reg
[2] = char2b
->byte2
;
1506 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1508 /* We assume that MSBs are appropriately set/reset by CCL
1510 if (font
->max_byte1
== 0) /* 1-byte font */
1511 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1513 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1515 else if (font_info
->encoding
[charset
])
1517 /* Fixed encoding scheme. See fontset.h for the meaning of the
1518 encoding numbers. */
1519 int enc
= font_info
->encoding
[charset
];
1521 if ((enc
== 1 || enc
== 2)
1522 && CHARSET_DIMENSION (charset
) == 2)
1523 char2b
->byte1
|= 0x80;
1525 if (enc
== 1 || enc
== 3)
1526 char2b
->byte2
|= 0x80;
1532 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1533 char2b
->byte1
= sjis1
;
1534 char2b
->byte2
= sjis2
;
1539 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1541 return FONT_TYPE_UNKNOWN
;
1546 /***********************************************************************
1548 ***********************************************************************/
1551 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1552 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1553 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1555 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1556 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1557 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1558 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1559 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1560 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1561 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1562 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1563 unsigned long *, double, int));*/
1564 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1565 double, int, unsigned long));
1566 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1567 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1568 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1569 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1570 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1571 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1573 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1574 int, int, int, int, Rect
*));
1575 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1576 int, int, int, Rect
*));
1579 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1583 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1588 struct glyph_string
*s
;
1590 if (s
->font
== FRAME_FONT (s
->f
)
1591 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1592 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1594 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1597 /* Cursor on non-default face: must merge. */
1601 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1602 xgcv
.foreground
= s
->face
->background
;
1604 /* If the glyph would be invisible, try a different foreground. */
1605 if (xgcv
.foreground
== xgcv
.background
)
1606 xgcv
.foreground
= s
->face
->foreground
;
1607 if (xgcv
.foreground
== xgcv
.background
)
1608 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1609 if (xgcv
.foreground
== xgcv
.background
)
1610 xgcv
.foreground
= s
->face
->foreground
;
1612 /* Make sure the cursor is distinct from text in this face. */
1613 if (xgcv
.background
== s
->face
->background
1614 && xgcv
.foreground
== s
->face
->foreground
)
1616 xgcv
.background
= s
->face
->foreground
;
1617 xgcv
.foreground
= s
->face
->background
;
1620 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1621 xgcv
.font
= s
->font
;
1622 mask
= GCForeground
| GCBackground
| GCFont
;
1624 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1625 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1628 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1629 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1631 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1636 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1639 x_set_mouse_face_gc (s
)
1640 struct glyph_string
*s
;
1645 /* What face has to be used last for the mouse face? */
1646 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1647 face
= FACE_FROM_ID (s
->f
, face_id
);
1649 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1651 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1652 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1654 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1655 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1656 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1658 /* If font in this face is same as S->font, use it. */
1659 if (s
->font
== s
->face
->font
)
1660 s
->gc
= s
->face
->gc
;
1663 /* Otherwise construct scratch_cursor_gc with values from FACE
1668 xgcv
.background
= s
->face
->background
;
1669 xgcv
.foreground
= s
->face
->foreground
;
1670 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1671 xgcv
.font
= s
->font
;
1672 mask
= GCForeground
| GCBackground
| GCFont
;
1674 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1675 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1678 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1679 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1681 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1684 xassert (s
->gc
!= 0);
1688 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1689 Faces to use in the mode line have already been computed when the
1690 matrix was built, so there isn't much to do, here. */
1693 x_set_mode_line_face_gc (s
)
1694 struct glyph_string
*s
;
1696 s
->gc
= s
->face
->gc
;
1700 /* Set S->gc of glyph string S for drawing that glyph string. Set
1701 S->stippled_p to a non-zero value if the face of S has a stipple
1705 x_set_glyph_string_gc (s
)
1706 struct glyph_string
*s
;
1708 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1710 if (s
->hl
== DRAW_NORMAL_TEXT
)
1712 s
->gc
= s
->face
->gc
;
1713 s
->stippled_p
= s
->face
->stipple
!= 0;
1715 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1717 x_set_mode_line_face_gc (s
);
1718 s
->stippled_p
= s
->face
->stipple
!= 0;
1720 else if (s
->hl
== DRAW_CURSOR
)
1722 x_set_cursor_gc (s
);
1725 else if (s
->hl
== DRAW_MOUSE_FACE
)
1727 x_set_mouse_face_gc (s
);
1728 s
->stippled_p
= s
->face
->stipple
!= 0;
1730 else if (s
->hl
== DRAW_IMAGE_RAISED
1731 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1733 s
->gc
= s
->face
->gc
;
1734 s
->stippled_p
= s
->face
->stipple
!= 0;
1738 s
->gc
= s
->face
->gc
;
1739 s
->stippled_p
= s
->face
->stipple
!= 0;
1742 /* GC must have been set. */
1743 xassert (s
->gc
!= 0);
1747 /* Set clipping for output of glyph string S. S may be part of a mode
1748 line or menu if we don't have X toolkit support. */
1751 x_set_glyph_string_clipping (s
)
1752 struct glyph_string
*s
;
1755 get_glyph_string_clip_rect (s
, &r
);
1756 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1761 Compute left and right overhang of glyph string S. If S is a glyph
1762 string for a composition, assume overhangs don't exist. */
1765 mac_compute_glyph_string_overhangs (s
)
1766 struct glyph_string
*s
;
1769 /* MAC_TODO: XTextExtents16 does nothing yet... */
1772 && s
->first_glyph
->type
== CHAR_GLYPH
)
1775 int direction
, font_ascent
, font_descent
;
1776 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1777 &font_ascent
, &font_descent
, &cs
);
1778 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1779 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1785 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1788 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1789 struct glyph_string
*s
;
1794 xgcv
.foreground
= s
->gc
->background
;
1795 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1799 /* Draw the background of glyph_string S. If S->background_filled_p
1800 is non-zero don't draw it. FORCE_P non-zero means draw the
1801 background even if it wouldn't be drawn normally. This is used
1802 when a string preceding S draws into the background of S, or S
1803 contains the first component of a composition. */
1806 x_draw_glyph_string_background (s
, force_p
)
1807 struct glyph_string
*s
;
1810 /* Nothing to do if background has already been drawn or if it
1811 shouldn't be drawn in the first place. */
1812 if (!s
->background_filled_p
)
1814 int box_line_width
= max (s
->face
->box_line_width
, 0);
1816 #if 0 /* MAC_TODO: stipple */
1819 /* Fill background with a stipple pattern. */
1820 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1821 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1822 s
->y
+ box_line_width
,
1823 s
->background_width
,
1824 s
->height
- 2 * box_line_width
);
1825 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1826 s
->background_filled_p
= 1;
1830 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1831 || s
->font_not_found_p
1832 || s
->extends_to_end_of_line_p
1835 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1836 s
->background_width
,
1837 s
->height
- 2 * box_line_width
);
1838 s
->background_filled_p
= 1;
1844 /* Draw the foreground of glyph string S. */
1847 x_draw_glyph_string_foreground (s
)
1848 struct glyph_string
*s
;
1852 /* If first glyph of S has a left box line, start drawing the text
1853 of S to the right of that box line. */
1854 if (s
->face
->box
!= FACE_NO_BOX
1855 && s
->first_glyph
->left_box_line_p
)
1856 x
= s
->x
+ abs (s
->face
->box_line_width
);
1860 /* Draw characters of S as rectangles if S's font could not be
1862 if (s
->font_not_found_p
)
1864 for (i
= 0; i
< s
->nchars
; ++i
)
1866 struct glyph
*g
= s
->first_glyph
+ i
;
1867 mac_draw_rectangle (s
->display
, s
->window
,
1868 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
1870 x
+= g
->pixel_width
;
1875 char *char1b
= (char *) s
->char2b
;
1876 int boff
= s
->font_info
->baseline_offset
;
1878 if (s
->font_info
->vertical_centering
)
1879 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
1881 /* If we can use 8-bit functions, condense S->char2b. */
1883 for (i
= 0; i
< s
->nchars
; ++i
)
1884 char1b
[i
] = s
->char2b
[i
].byte2
;
1886 /* Draw text with XDrawString if background has already been
1887 filled. Otherwise, use XDrawImageString. (Note that
1888 XDrawImageString is usually faster than XDrawString.) Always
1889 use XDrawImageString when drawing the cursor so that there is
1890 no chance that characters under a box cursor are invisible. */
1891 if (s
->for_overlaps_p
1892 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
1894 /* Draw characters with 16-bit or 8-bit functions. */
1896 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
1897 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1899 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
1900 s
->ybase
- boff
, char1b
, s
->nchars
);
1905 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
1906 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1908 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
1909 s
->ybase
- boff
, char1b
, s
->nchars
);
1914 /* Draw the foreground of composite glyph string S. */
1917 x_draw_composite_glyph_string_foreground (s
)
1918 struct glyph_string
*s
;
1922 /* If first glyph of S has a left box line, start drawing the text
1923 of S to the right of that box line. */
1924 if (s
->face
->box
!= FACE_NO_BOX
1925 && s
->first_glyph
->left_box_line_p
)
1926 x
= s
->x
+ abs (s
->face
->box_line_width
);
1930 /* S is a glyph string for a composition. S->gidx is the index of
1931 the first character drawn for glyphs of this composition.
1932 S->gidx == 0 means we are drawing the very first character of
1933 this composition. */
1935 /* Draw a rectangle for the composition if the font for the very
1936 first character of the composition could not be loaded. */
1937 if (s
->font_not_found_p
)
1940 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
1941 s
->width
- 1, s
->height
- 1);
1945 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
1946 XDrawString16 (s
->display
, s
->window
, s
->gc
,
1947 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
1948 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
1954 #ifdef USE_X_TOOLKIT
1956 static struct frame
*x_frame_of_widget
P_ ((Widget
));
1959 /* Return the frame on which widget WIDGET is used.. Abort if frame
1960 cannot be determined. */
1962 static struct frame
*
1963 x_frame_of_widget (widget
)
1966 struct x_display_info
*dpyinfo
;
1970 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
1972 /* Find the top-level shell of the widget. Note that this function
1973 can be called when the widget is not yet realized, so XtWindow
1974 (widget) == 0. That's the reason we can't simply use
1975 x_any_window_to_frame. */
1976 while (!XtIsTopLevelShell (widget
))
1977 widget
= XtParent (widget
);
1979 /* Look for a frame with that top-level widget. Allocate the color
1980 on that frame to get the right gamma correction value. */
1981 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
1982 if (GC_FRAMEP (XCAR (tail
))
1983 && (f
= XFRAME (XCAR (tail
)),
1984 (f
->output_data
.nothing
!= 1
1985 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
1986 && f
->output_data
.x
->widget
== widget
)
1993 /* Allocate the color COLOR->pixel on the screen and display of
1994 widget WIDGET in colormap CMAP. If an exact match cannot be
1995 allocated, try the nearest color available. Value is non-zero
1996 if successful. This is called from lwlib. */
1999 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2004 struct frame
*f
= x_frame_of_widget (widget
);
2005 return x_alloc_nearest_color (f
, cmap
, color
);
2009 #endif /* USE_X_TOOLKIT */
2011 #if 0 /* MAC_TODO */
2013 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2014 CMAP. If an exact match can't be allocated, try the nearest color
2015 available. Value is non-zero if successful. Set *COLOR to the
2019 x_alloc_nearest_color (f
, cmap
, color
)
2024 Display
*display
= FRAME_X_DISPLAY (f
);
2025 Screen
*screen
= FRAME_X_SCREEN (f
);
2028 gamma_correct (f
, color
);
2029 rc
= XAllocColor (display
, cmap
, color
);
2032 /* If we got to this point, the colormap is full, so we're going
2033 to try to get the next closest color. The algorithm used is
2034 a least-squares matching, which is what X uses for closest
2035 color matching with StaticColor visuals. */
2037 unsigned long nearest_delta
= ~0;
2038 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2039 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2041 for (i
= 0; i
< ncells
; ++i
)
2043 XQueryColors (display
, cmap
, cells
, ncells
);
2045 for (nearest
= i
= 0; i
< ncells
; ++i
)
2047 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2048 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2049 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2050 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2052 if (delta
< nearest_delta
)
2055 nearest_delta
= delta
;
2059 color
->red
= cells
[nearest
].red
;
2060 color
->green
= cells
[nearest
].green
;
2061 color
->blue
= cells
[nearest
].blue
;
2062 rc
= XAllocColor (display
, cmap
, color
);
2065 #ifdef DEBUG_X_COLORS
2067 register_color (color
->pixel
);
2068 #endif /* DEBUG_X_COLORS */
2074 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2075 It's necessary to do this instead of just using PIXEL directly to
2076 get color reference counts right. */
2079 x_copy_color (f
, pixel
)
2081 unsigned long pixel
;
2085 color
.pixel
= pixel
;
2087 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2088 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2090 #ifdef DEBUG_X_COLORS
2091 register_color (pixel
);
2097 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2098 It's necessary to do this instead of just using PIXEL directly to
2099 get color reference counts right. */
2102 x_copy_dpy_color (dpy
, cmap
, pixel
)
2105 unsigned long pixel
;
2109 color
.pixel
= pixel
;
2111 XQueryColor (dpy
, cmap
, &color
);
2112 XAllocColor (dpy
, cmap
, &color
);
2114 #ifdef DEBUG_X_COLORS
2115 register_color (pixel
);
2120 #endif /* MAC_TODO */
2122 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2123 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2124 If this produces the same color as COLOR, try a color where all RGB
2125 values have DELTA added. Return the allocated color in *COLOR.
2126 DISPLAY is the X display, CMAP is the colormap to operate on.
2127 Value is non-zero if successful. */
2130 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2132 unsigned long *color
;
2138 /* Change RGB values by specified FACTOR. Avoid overflow! */
2139 xassert (factor
>= 0);
2140 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2141 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2142 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2144 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2145 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2146 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2148 /* MAC_TODO: Map to palette and retry with delta if same? */
2149 /* MAC_TODO: Free colors (if using palette)? */
2160 /* Set up the foreground color for drawing relief lines of glyph
2161 string S. RELIEF is a pointer to a struct relief containing the GC
2162 with which lines will be drawn. Use a color that is FACTOR or
2163 DELTA lighter or darker than the relief's background which is found
2164 in S->f->output_data.x->relief_background. If such a color cannot
2165 be allocated, use DEFAULT_PIXEL, instead. */
2168 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2170 struct relief
*relief
;
2173 unsigned long default_pixel
;
2176 struct mac_output
*di
= f
->output_data
.mac
;
2177 unsigned long mask
= GCForeground
;
2178 unsigned long pixel
;
2179 unsigned long background
= di
->relief_background
;
2180 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2182 /* MAC_TODO: Free colors (if using palette)? */
2184 /* Allocate new color. */
2185 xgcv
.foreground
= default_pixel
;
2187 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2189 relief
->allocated_p
= 1;
2190 xgcv
.foreground
= relief
->pixel
= pixel
;
2193 if (relief
->gc
== 0)
2195 #if 0 /* MAC_TODO: stipple */
2196 xgcv
.stipple
= dpyinfo
->gray
;
2199 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2202 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2206 /* Set up colors for the relief lines around glyph string S. */
2209 x_setup_relief_colors (s
)
2210 struct glyph_string
*s
;
2212 struct mac_output
*di
= s
->f
->output_data
.mac
;
2213 unsigned long color
;
2215 if (s
->face
->use_box_color_for_shadows_p
)
2216 color
= s
->face
->box_color
;
2221 /* Get the background color of the face. */
2222 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2223 color
= xgcv
.background
;
2226 if (di
->white_relief
.gc
== 0
2227 || color
!= di
->relief_background
)
2229 di
->relief_background
= color
;
2230 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2231 WHITE_PIX_DEFAULT (s
->f
));
2232 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2233 BLACK_PIX_DEFAULT (s
->f
));
2238 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2239 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2240 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2241 relief. LEFT_P non-zero means draw a relief on the left side of
2242 the rectangle. RIGHT_P non-zero means draw a relief on the right
2243 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2247 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2248 raised_p
, left_p
, right_p
, clip_rect
)
2250 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
2257 gc
= f
->output_data
.mac
->white_relief
.gc
;
2259 gc
= f
->output_data
.mac
->black_relief
.gc
;
2260 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
2263 for (i
= 0; i
< width
; ++i
)
2264 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2265 left_x
+ i
* left_p
, top_y
+ i
,
2266 right_x
+ 1 - i
* right_p
, top_y
+ i
);
2270 for (i
= 0; i
< width
; ++i
)
2271 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2272 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2274 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2276 gc
= f
->output_data
.mac
->black_relief
.gc
;
2278 gc
= f
->output_data
.mac
->white_relief
.gc
;
2279 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2283 for (i
= 0; i
< width
; ++i
)
2284 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2285 left_x
+ i
* left_p
, bottom_y
- i
,
2286 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
2290 for (i
= 0; i
< width
; ++i
)
2291 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2292 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
2294 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2298 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2299 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2300 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2301 left side of the rectangle. RIGHT_P non-zero means draw a line
2302 on the right side of the rectangle. CLIP_RECT is the clipping
2303 rectangle to use when drawing. */
2306 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2307 left_p
, right_p
, clip_rect
)
2308 struct glyph_string
*s
;
2309 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
2314 xgcv
.foreground
= s
->face
->box_color
;
2315 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2318 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2319 left_x
, top_y
, right_x
- left_x
, width
);
2323 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2324 left_x
, top_y
, width
, bottom_y
- top_y
);
2327 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2328 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
2332 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2333 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
2335 mac_reset_clipping (s
->display
, s
->window
);
2339 /* Draw a box around glyph string S. */
2342 x_draw_glyph_string_box (s
)
2343 struct glyph_string
*s
;
2345 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2346 int left_p
, right_p
;
2347 struct glyph
*last_glyph
;
2350 last_x
= window_box_right (s
->w
, s
->area
);
2351 if (s
->row
->full_width_p
2352 && !s
->w
->pseudo_window_p
)
2354 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2355 if (s
->area
!= RIGHT_MARGIN_AREA
2356 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2357 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
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 (FRAME_COLUMN_WIDTH (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
);
3151 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3152 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3153 bottom_y
= y
+ height
;
3157 /* Scrolling up. Make sure we don't copy part of the mode
3158 line at the bottom. */
3159 if (from_y
+ run
->height
> bottom_y
)
3160 height
= bottom_y
- from_y
;
3162 height
= run
->height
;
3166 /* Scolling down. Make sure we don't copy over the mode line.
3168 if (to_y
+ run
->height
> bottom_y
)
3169 height
= bottom_y
- to_y
;
3171 height
= run
->height
;
3176 /* Cursor off. Will be switched on again in x_update_window_end. */
3180 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3181 f
->output_data
.mac
->normal_gc
,
3191 /***********************************************************************
3193 ***********************************************************************/
3200 x_update_cursor (f
, 1);
3204 frame_unhighlight (f
)
3207 x_update_cursor (f
, 1);
3210 /* The focus has changed. Update the frames as necessary to reflect
3211 the new situation. Note that we can't change the selected frame
3212 here, because the Lisp code we are interrupting might become confused.
3213 Each event gets marked with the frame in which it occurred, so the
3214 Lisp code can tell when the switch took place by examining the events. */
3217 x_new_focus_frame (dpyinfo
, frame
)
3218 struct x_display_info
*dpyinfo
;
3219 struct frame
*frame
;
3221 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3223 if (frame
!= dpyinfo
->x_focus_frame
)
3225 /* Set this before calling other routines, so that they see
3226 the correct value of x_focus_frame. */
3227 dpyinfo
->x_focus_frame
= frame
;
3229 if (old_focus
&& old_focus
->auto_lower
)
3230 x_lower_frame (old_focus
);
3233 selected_frame
= frame
;
3234 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3236 Fselect_window (selected_frame
->selected_window
, Qnil
);
3237 choose_minibuf_frame ();
3240 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3241 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3243 pending_autoraise_frame
= 0;
3246 x_frame_rehighlight (dpyinfo
);
3249 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3252 x_mouse_leave (dpyinfo
)
3253 struct x_display_info
*dpyinfo
;
3255 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3258 /* The focus has changed, or we have redirected a frame's focus to
3259 another frame (this happens when a frame uses a surrogate
3260 mini-buffer frame). Shift the highlight as appropriate.
3262 The FRAME argument doesn't necessarily have anything to do with which
3263 frame is being highlighted or un-highlighted; we only use it to find
3264 the appropriate X display info. */
3267 XTframe_rehighlight (frame
)
3268 struct frame
*frame
;
3272 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3276 x_frame_rehighlight (dpyinfo
)
3277 struct x_display_info
*dpyinfo
;
3279 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3281 if (dpyinfo
->x_focus_frame
)
3283 dpyinfo
->x_highlight_frame
3284 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3285 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3286 : dpyinfo
->x_focus_frame
);
3287 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3289 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3290 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3294 dpyinfo
->x_highlight_frame
= 0;
3296 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3299 frame_unhighlight (old_highlight
);
3300 if (dpyinfo
->x_highlight_frame
)
3301 frame_highlight (dpyinfo
->x_highlight_frame
);
3307 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3309 #if 0 /* MAC_TODO */
3310 /* Initialize mode_switch_bit and modifier_meaning. */
3312 x_find_modifier_meanings (dpyinfo
)
3313 struct x_display_info
*dpyinfo
;
3315 int min_code
, max_code
;
3318 XModifierKeymap
*mods
;
3320 dpyinfo
->meta_mod_mask
= 0;
3321 dpyinfo
->shift_lock_mask
= 0;
3322 dpyinfo
->alt_mod_mask
= 0;
3323 dpyinfo
->super_mod_mask
= 0;
3324 dpyinfo
->hyper_mod_mask
= 0;
3327 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3329 min_code
= dpyinfo
->display
->min_keycode
;
3330 max_code
= dpyinfo
->display
->max_keycode
;
3333 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3334 min_code
, max_code
- min_code
+ 1,
3336 mods
= XGetModifierMapping (dpyinfo
->display
);
3338 /* Scan the modifier table to see which modifier bits the Meta and
3339 Alt keysyms are on. */
3341 int row
, col
; /* The row and column in the modifier table. */
3343 for (row
= 3; row
< 8; row
++)
3344 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3347 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3349 /* Zeroes are used for filler. Skip them. */
3353 /* Are any of this keycode's keysyms a meta key? */
3357 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3359 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3365 dpyinfo
->meta_mod_mask
|= (1 << row
);
3370 dpyinfo
->alt_mod_mask
|= (1 << row
);
3375 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3380 dpyinfo
->super_mod_mask
|= (1 << row
);
3384 /* Ignore this if it's not on the lock modifier. */
3385 if ((1 << row
) == LockMask
)
3386 dpyinfo
->shift_lock_mask
= LockMask
;
3394 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3395 if (! dpyinfo
->meta_mod_mask
)
3397 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3398 dpyinfo
->alt_mod_mask
= 0;
3401 /* If some keys are both alt and meta,
3402 make them just meta, not alt. */
3403 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3405 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3408 XFree ((char *) syms
);
3409 XFreeModifiermap (mods
);
3412 #endif /* MAC_TODO */
3414 /* Convert between the modifier bits X uses and the modifier bits
3418 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3419 struct x_display_info
*dpyinfo
;
3420 unsigned short state
;
3422 return (((state
& shiftKey
) ? shift_modifier
: 0)
3423 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3424 | ((state
& cmdKey
) ? meta_modifier
: 0)
3425 | ((state
& optionKey
) ? alt_modifier
: 0));
3428 #if 0 /* MAC_TODO */
3429 static unsigned short
3430 x_emacs_to_x_modifiers (dpyinfo
, state
)
3431 struct x_display_info
*dpyinfo
;
3434 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3435 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3436 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3437 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3438 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3439 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3441 #endif /* MAC_TODO */
3443 /* Convert a keysym to its name. */
3446 x_get_keysym_name (keysym
)
3453 value
= XKeysymToString (keysym
);
3464 /* Mouse clicks and mouse movement. Rah. */
3466 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3468 If the event is a button press, then note that we have grabbed
3472 construct_mouse_click (result
, event
, f
)
3473 struct input_event
*result
;
3479 result
->kind
= MOUSE_CLICK_EVENT
;
3480 result
->code
= 0; /* only one mouse button */
3481 result
->timestamp
= event
->when
;
3482 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3484 mouseLoc
= event
->where
;
3486 #if TARGET_API_MAC_CARBON
3487 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
3489 SetPort (FRAME_MAC_WINDOW (f
));
3492 GlobalToLocal (&mouseLoc
);
3493 XSETINT (result
->x
, mouseLoc
.h
);
3494 XSETINT (result
->y
, mouseLoc
.v
);
3496 XSETFRAME (result
->frame_or_window
, f
);
3503 /* Function to report a mouse movement to the mainstream Emacs code.
3504 The input handler calls this.
3506 We have received a mouse movement event, which is given in *event.
3507 If the mouse is over a different glyph than it was last time, tell
3508 the mainstream emacs code by setting mouse_moved. If not, ask for
3509 another motion event, so we can check again the next time it moves. */
3511 static Point last_mouse_motion_position
;
3512 static Lisp_Object last_mouse_motion_frame
;
3515 note_mouse_movement (frame
, pos
)
3519 #if TARGET_API_MAC_CARBON
3523 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3524 last_mouse_motion_position
= *pos
;
3525 XSETFRAME (last_mouse_motion_frame
, frame
);
3527 #if TARGET_API_MAC_CARBON
3528 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3530 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3533 frame
->mouse_moved
= 1;
3534 last_mouse_scroll_bar
= Qnil
;
3535 note_mouse_highlight (frame
, -1, -1);
3537 /* Has the mouse moved off the glyph it was on at the last sighting? */
3538 else if (pos
->h
< last_mouse_glyph
.left
3539 || pos
->h
>= last_mouse_glyph
.right
3540 || pos
->v
< last_mouse_glyph
.top
3541 || pos
->v
>= last_mouse_glyph
.bottom
)
3543 frame
->mouse_moved
= 1;
3544 last_mouse_scroll_bar
= Qnil
;
3545 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3549 /* This is used for debugging, to turn off note_mouse_highlight. */
3551 int disable_mouse_highlight
;
3555 /************************************************************************
3557 ************************************************************************/
3559 static struct scroll_bar
*x_window_to_scroll_bar ();
3560 static void x_scroll_bar_report_motion ();
3561 static void x_check_fullscreen
P_ ((struct frame
*));
3562 static void x_check_fullscreen_move
P_ ((struct frame
*));
3563 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3566 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3569 redo_mouse_highlight ()
3571 if (!NILP (last_mouse_motion_frame
)
3572 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3573 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3574 last_mouse_motion_position
.h
,
3575 last_mouse_motion_position
.v
);
3579 /* Try to determine frame pixel position and size of the glyph under
3580 frame pixel coordinates X/Y on frame F . Return the position and
3581 size in *RECT. Value is non-zero if we could compute these
3585 glyph_rect (f
, x
, y
, rect
)
3592 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3596 struct window
*w
= XWINDOW (window
);
3597 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3598 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3600 for (; r
< end
&& r
->enabled_p
; ++r
)
3601 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3603 /* Found the row at y. */
3604 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3605 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3608 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3609 rect
->bottom
= rect
->top
+ r
->height
;
3613 /* x is to the left of the first glyph in the row. */
3614 /* Shouldn't this be a pixel value?
3615 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3617 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
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 /* Shouldn't this be a pixel value?
3634 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3636 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3641 /* The y is not on any row. */
3645 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3647 /* Record the position of the mouse in last_mouse_glyph. */
3649 remember_mouse_glyph (f1
, gx
, gy
)
3653 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3655 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3656 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3658 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3659 round down even for negative values. */
3665 /* This was the original code from XTmouse_position, but it seems
3666 to give the position of the glyph diagonally next to the one
3667 the mouse is over. */
3668 gx
= (gx
+ width
- 1) / width
* width
;
3669 gy
= (gy
+ height
- 1) / height
* height
;
3671 gx
= gx
/ width
* width
;
3672 gy
= gy
/ height
* height
;
3675 last_mouse_glyph
.left
= gx
;
3676 last_mouse_glyph
.top
= gy
;
3677 last_mouse_glyph
.right
= gx
+ width
;
3678 last_mouse_glyph
.bottom
= gy
+ height
;
3683 /* Return the current position of the mouse.
3684 *fp should be a frame which indicates which display to ask about.
3686 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3687 and *part to the frame, window, and scroll bar part that the mouse
3688 is over. Set *x and *y to the portion and whole of the mouse's
3689 position on the scroll bar.
3691 If the mouse movement started elsewhere, set *fp to the frame the
3692 mouse is on, *bar_window to nil, and *x and *y to the character cell
3695 Set *time to the server time-stamp for the time at which the mouse
3696 was at this position.
3698 Don't store anything if we don't have a valid set of values to report.
3700 This clears the mouse_moved flag, so we can wait for the next mouse
3704 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3707 Lisp_Object
*bar_window
;
3708 enum scroll_bar_part
*part
;
3710 unsigned long *time
;
3713 int ignore1
, ignore2
;
3714 WindowPtr wp
= FrontWindow ();
3716 Lisp_Object frame
, tail
;
3718 if (is_emacs_window(wp
))
3719 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
3723 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3724 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3727 /* Clear the mouse-moved flag for every frame on this display. */
3728 FOR_EACH_FRAME (tail
, frame
)
3729 XFRAME (frame
)->mouse_moved
= 0;
3731 last_mouse_scroll_bar
= Qnil
;
3733 #if TARGET_API_MAC_CARBON
3734 SetPort (GetWindowPort (wp
));
3739 GetMouse (&mouse_pos
);
3741 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3742 &last_mouse_glyph
, insist
);
3745 *part
= scroll_bar_handle
;
3747 XSETINT (*x
, mouse_pos
.h
);
3748 XSETINT (*y
, mouse_pos
.v
);
3749 *time
= last_mouse_movement_time
;
3756 /***********************************************************************
3758 ***********************************************************************/
3760 /* Handle mouse button event on the tool-bar of frame F, at
3761 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3765 mac_handle_tool_bar_click (f
, button_event
)
3767 EventRecord
*button_event
;
3769 int x
= button_event
->where
.h
;
3770 int y
= button_event
->where
.v
;
3772 if (button_event
->what
== mouseDown
)
3773 handle_tool_bar_click (f
, x
, y
, 1, 0);
3775 handle_tool_bar_click (f
, x
, y
, 0,
3776 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3777 button_event
->modifiers
));
3781 /************************************************************************
3782 Scroll bars, general
3783 ************************************************************************/
3785 /* Create a scroll bar and return the scroll bar vector for it. W is
3786 the Emacs window on which to create the scroll bar. TOP, LEFT,
3787 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
3790 static struct scroll_bar
*
3791 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
3793 int top
, left
, width
, height
, disp_top
, disp_height
;
3795 struct frame
*f
= XFRAME (w
->frame
);
3796 struct scroll_bar
*bar
3797 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
3805 r
.right
= left
+ width
;
3806 r
.bottom
= disp_top
+ disp_height
;
3808 #ifdef TARGET_API_MAC_CARBON
3809 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
3810 kControlScrollBarProc
, 0L);
3812 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
3815 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
3816 SetControlReference (ch
, (long) bar
);
3818 XSETWINDOW (bar
->window
, w
);
3819 XSETINT (bar
->top
, top
);
3820 XSETINT (bar
->left
, left
);
3821 XSETINT (bar
->width
, width
);
3822 XSETINT (bar
->height
, height
);
3823 XSETINT (bar
->start
, 0);
3824 XSETINT (bar
->end
, 0);
3825 bar
->dragging
= Qnil
;
3827 /* Add bar to its frame's list of scroll bars. */
3828 bar
->next
= FRAME_SCROLL_BARS (f
);
3830 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
3831 if (!NILP (bar
->next
))
3832 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
3839 /* Draw BAR's handle in the proper position.
3841 If the handle is already drawn from START to END, don't bother
3842 redrawing it, unless REBUILD is non-zero; in that case, always
3843 redraw it. (REBUILD is handy for drawing the handle after expose
3846 Normally, we want to constrain the start and end of the handle to
3847 fit inside its rectangle, but if the user is dragging the scroll
3848 bar handle, we want to let them drag it down all the way, so that
3849 the bar's top is as far down as it goes; otherwise, there's no way
3850 to move to the very end of the buffer. */
3853 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
3854 struct scroll_bar
*bar
;
3858 int dragging
= ! NILP (bar
->dragging
);
3859 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
3860 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3861 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
3862 int length
= end
- start
;
3864 /* If the display is already accurate, do nothing. */
3866 && start
== XINT (bar
->start
)
3867 && end
== XINT (bar
->end
))
3872 /* Make sure the values are reasonable, and try to preserve the
3873 distance between start and end. */
3876 else if (start
> top_range
)
3878 end
= start
+ length
;
3882 else if (end
> top_range
&& ! dragging
)
3885 /* Store the adjusted setting in the scroll bar. */
3886 XSETINT (bar
->start
, start
);
3887 XSETINT (bar
->end
, end
);
3889 /* Clip the end position, just for display. */
3890 if (end
> top_range
)
3893 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
3894 top positions, to make sure the handle is always at least that
3895 many pixels tall. */
3896 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
3898 SetControlMinimum (ch
, 0);
3899 /* Don't inadvertently activate deactivated scroll bars */
3900 if (GetControlMaximum (ch
) != -1)
3901 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
3903 SetControlValue (ch
, start
);
3904 #if TARGET_API_MAC_CARBON
3905 SetControlViewSize (ch
, end
- start
);
3912 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
3916 x_scroll_bar_remove (bar
)
3917 struct scroll_bar
*bar
;
3919 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3923 /* Destroy the Mac scroll bar control */
3924 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
3926 /* Disassociate this scroll bar from its window. */
3927 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
3932 /* Set the handle of the vertical scroll bar for WINDOW to indicate
3933 that we are displaying PORTION characters out of a total of WHOLE
3934 characters, starting at POSITION. If WINDOW has no scroll bar,
3937 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
3939 int portion
, whole
, position
;
3941 struct frame
*f
= XFRAME (w
->frame
);
3942 struct scroll_bar
*bar
;
3943 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
3944 int window_y
, window_height
;
3946 /* Get window dimensions. */
3947 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
3952 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
3954 height
= window_height
;
3956 /* Compute the left edge of the scroll bar area. */
3957 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
3959 /* Compute the width of the scroll bar which might be less than
3960 the width of the area reserved for the scroll bar. */
3961 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
3962 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
3966 /* Compute the left edge of the scroll bar. */
3967 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
3968 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
3970 sb_left
= left
+ (width
- sb_width
) / 2;
3972 /* Adjustments according to Inside Macintosh to make it look nice */
3974 disp_height
= height
;
3980 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
3986 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
3989 /* Does the scroll bar exist yet? */
3990 if (NILP (w
->vertical_scroll_bar
))
3993 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3994 left
, top
, width
, height
, 0);
3996 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
3998 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4002 /* It may just need to be moved and resized. */
4005 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4006 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4010 /* If already correctly positioned, do nothing. */
4011 if (XINT (bar
->left
) == sb_left
4012 && XINT (bar
->top
) == top
4013 && XINT (bar
->width
) == sb_width
4014 && XINT (bar
->height
) == height
)
4018 /* Clear areas not covered by the scroll bar because it's not as
4019 wide as the area reserved for it . This makes sure a
4020 previous mode line display is cleared after C-x 2 C-x 1, for
4022 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4023 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4024 left
, top
, area_width
, height
, 0);
4027 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4028 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4029 sb_left
- 1, top
, 1, height
, 0);
4033 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4034 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4038 /* Remember new settings. */
4039 XSETINT (bar
->left
, sb_left
);
4040 XSETINT (bar
->top
, top
);
4041 XSETINT (bar
->width
, sb_width
);
4042 XSETINT (bar
->height
, height
);
4048 /* Set the scroll bar's current state, unless we're currently being
4050 if (NILP (bar
->dragging
))
4052 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4055 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4058 int start
= ((double) position
* top_range
) / whole
;
4059 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4060 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4066 /* The following three hooks are used when we're doing a thorough
4067 redisplay of the frame. We don't explicitly know which scroll bars
4068 are going to be deleted, because keeping track of when windows go
4069 away is a real pain - "Can you say set-window-configuration, boys
4070 and girls?" Instead, we just assert at the beginning of redisplay
4071 that *all* scroll bars are to be removed, and then save a scroll bar
4072 from the fiery pit when we actually redisplay its window. */
4074 /* Arrange for all scroll bars on FRAME to be removed at the next call
4075 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4076 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4079 XTcondemn_scroll_bars (frame
)
4082 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4083 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4086 bar
= FRAME_SCROLL_BARS (frame
);
4087 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4088 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4089 XSCROLL_BAR (bar
)->prev
= Qnil
;
4090 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4091 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4092 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4097 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4098 Note that WINDOW isn't necessarily condemned at all. */
4101 XTredeem_scroll_bar (window
)
4102 struct window
*window
;
4104 struct scroll_bar
*bar
;
4106 /* We can't redeem this window's scroll bar if it doesn't have one. */
4107 if (NILP (window
->vertical_scroll_bar
))
4110 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4112 /* Unlink it from the condemned list. */
4114 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4116 if (NILP (bar
->prev
))
4118 /* If the prev pointer is nil, it must be the first in one of
4120 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4121 /* It's not condemned. Everything's fine. */
4123 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4124 window
->vertical_scroll_bar
))
4125 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4127 /* If its prev pointer is nil, it must be at the front of
4128 one or the other! */
4132 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4134 if (! NILP (bar
->next
))
4135 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4137 bar
->next
= FRAME_SCROLL_BARS (f
);
4139 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4140 if (! NILP (bar
->next
))
4141 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4145 /* Remove all scroll bars on FRAME that haven't been saved since the
4146 last call to `*condemn_scroll_bars_hook'. */
4149 XTjudge_scroll_bars (f
)
4152 Lisp_Object bar
, next
;
4154 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4156 /* Clear out the condemned list now so we won't try to process any
4157 more events on the hapless scroll bars. */
4158 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4160 for (; ! NILP (bar
); bar
= next
)
4162 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4164 x_scroll_bar_remove (b
);
4167 b
->next
= b
->prev
= Qnil
;
4170 /* Now there should be no references to the condemned scroll bars,
4171 and they should get garbage-collected. */
4176 activate_scroll_bars (frame
)
4182 bar
= FRAME_SCROLL_BARS (frame
);
4183 while (! NILP (bar
))
4185 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4186 #ifdef TARGET_API_MAC_CARBON
4187 ActivateControl (ch
);
4189 SetControlMaximum (ch
,
4190 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4191 XINT (XSCROLL_BAR (bar
)
4194 bar
= XSCROLL_BAR (bar
)->next
;
4200 deactivate_scroll_bars (frame
)
4206 bar
= FRAME_SCROLL_BARS (frame
);
4207 while (! NILP (bar
))
4209 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4210 #ifdef TARGET_API_MAC_CARBON
4211 DeactivateControl (ch
);
4213 SetControlMaximum (ch
, XINT (-1));
4215 bar
= XSCROLL_BAR (bar
)->next
;
4219 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4220 is set to something other than NO_EVENT, it is enqueued.
4222 This may be called from a signal handler, so we have to ignore GC
4226 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4227 struct scroll_bar
*bar
;
4230 struct input_event
*bufp
;
4232 if (! GC_WINDOWP (bar
->window
))
4235 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4236 bufp
->frame_or_window
= bar
->window
;
4239 bar
->dragging
= Qnil
;
4243 case kControlUpButtonPart
:
4244 bufp
->part
= scroll_bar_up_arrow
;
4246 case kControlDownButtonPart
:
4247 bufp
->part
= scroll_bar_down_arrow
;
4249 case kControlPageUpPart
:
4250 bufp
->part
= scroll_bar_above_handle
;
4252 case kControlPageDownPart
:
4253 bufp
->part
= scroll_bar_below_handle
;
4255 #ifdef TARGET_API_MAC_CARBON
4258 case kControlIndicatorPart
:
4260 if (er
->what
== mouseDown
)
4261 bar
->dragging
= make_number (0);
4262 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4263 bufp
->part
= scroll_bar_handle
;
4269 /* Handle some mouse motion while someone is dragging the scroll bar.
4271 This may be called from a signal handler, so we have to ignore GC
4275 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4276 struct scroll_bar
*bar
;
4280 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4282 last_mouse_movement_time
= t
;
4285 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4287 /* If we're dragging the bar, display it. */
4288 if (! GC_NILP (bar
->dragging
))
4290 /* Where should the handle be now? */
4291 int new_start
= y_pos
- 24;
4293 if (new_start
!= XINT (bar
->start
))
4295 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4297 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4303 /* Return information to the user about the current position of the
4304 mouse on the scroll bar. */
4307 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4309 Lisp_Object
*bar_window
;
4310 enum scroll_bar_part
*part
;
4312 unsigned long *time
;
4314 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4315 WindowPtr wp
= FrontWindow ();
4317 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
4318 int win_y
, top_range
;
4320 #if TARGET_API_MAC_CARBON
4321 SetPort (GetWindowPort (wp
));
4326 GetMouse (&mouse_pos
);
4328 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4329 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4331 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4335 if (! NILP (bar
->dragging
))
4336 win_y
-= XINT (bar
->dragging
);
4340 if (win_y
> top_range
)
4344 *bar_window
= bar
->window
;
4346 if (! NILP (bar
->dragging
))
4347 *part
= scroll_bar_handle
;
4348 else if (win_y
< XINT (bar
->start
))
4349 *part
= scroll_bar_above_handle
;
4350 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4351 *part
= scroll_bar_handle
;
4353 *part
= scroll_bar_below_handle
;
4355 XSETINT (*x
, win_y
);
4356 XSETINT (*y
, top_range
);
4359 last_mouse_scroll_bar
= Qnil
;
4361 *time
= last_mouse_movement_time
;
4364 /***********************************************************************
4366 ***********************************************************************/
4368 /* Set clipping for output in glyph row ROW. W is the window in which
4369 we operate. GC is the graphics context to set clipping in.
4371 ROW may be a text row or, e.g., a mode line. Text rows must be
4372 clipped to the interior of the window dedicated to text display,
4373 mode lines must be clipped to the whole window. */
4376 x_clip_to_row (w
, row
, gc
)
4378 struct glyph_row
*row
;
4381 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4383 int window_y
, window_width
;
4385 window_box (w
, -1, 0, &window_y
, &window_width
, 0);
4387 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4388 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4389 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4390 clip_rect
.right
= clip_rect
.left
+ window_width
;
4391 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4393 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4397 /* Draw a hollow box cursor on window W in glyph row ROW. */
4400 x_draw_hollow_cursor (w
, row
)
4402 struct glyph_row
*row
;
4404 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4405 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4406 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4409 struct glyph
*cursor_glyph
;
4412 /* Compute frame-relative coordinates from window-relative
4414 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4415 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
4416 + row
->ascent
- w
->phys_cursor_ascent
);
4417 h
= row
->height
- 1;
4419 /* Get the glyph the cursor is on. If we can't tell because
4420 the current matrix is invalid or such, give up. */
4421 cursor_glyph
= get_phys_cursor_glyph (w
);
4422 if (cursor_glyph
== NULL
)
4425 /* Compute the width of the rectangle to draw. If on a stretch
4426 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4427 rectangle as wide as the glyph, but use a canonical character
4429 wd
= cursor_glyph
->pixel_width
- 1;
4430 if (cursor_glyph
->type
== STRETCH_GLYPH
4431 && !x_stretch_cursor_p
)
4432 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4434 /* The foreground of cursor_gc is typically the same as the normal
4435 background color, which can cause the cursor box to be invisible. */
4436 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4437 if (dpyinfo
->scratch_cursor_gc
)
4438 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4440 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4441 GCForeground
, &xgcv
);
4442 gc
= dpyinfo
->scratch_cursor_gc
;
4444 /* Set clipping, draw the rectangle, and reset clipping again. */
4445 x_clip_to_row (w
, row
, gc
);
4446 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4447 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4451 /* Draw a bar cursor on window W in glyph row ROW.
4453 Implementation note: One would like to draw a bar cursor with an
4454 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4455 Unfortunately, I didn't find a font yet that has this property set.
4459 x_draw_bar_cursor (w
, row
, width
)
4461 struct glyph_row
*row
;
4464 /* If cursor hpos is out of bounds, don't draw garbage. This can
4465 happen in mini-buffer windows when switching between echo area
4466 glyphs and mini-buffer. */
4467 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
4469 struct frame
*f
= XFRAME (w
->frame
);
4470 struct glyph
*cursor_glyph
;
4478 cursor_glyph
= get_phys_cursor_glyph (w
);
4479 if (cursor_glyph
== NULL
)
4482 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
4483 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4484 mask
= GCForeground
| GCBackground
;
4485 dpy
= FRAME_MAC_DISPLAY (f
);
4486 window
= FRAME_MAC_WINDOW (f
);
4487 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4490 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4493 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4494 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4498 width
= FRAME_CURSOR_WIDTH (f
);
4500 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4501 x_clip_to_row (w
, row
, gc
);
4502 XFillRectangle (dpy
, window
, gc
,
4504 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4505 min (cursor_glyph
->pixel_width
, width
),
4507 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4512 /* RIF: Define cursor CURSOR on frame F. */
4515 mac_define_frame_cursor (f
, cursor
)
4523 /* RIF: Clear area on frame F. */
4526 mac_clear_frame_area (f
, x
, y
, width
, height
)
4528 int x
, y
, width
, height
;
4530 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4531 x
, y
, width
, height
, 0);
4535 /* RIF: Draw cursor on window W. */
4538 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4540 struct glyph_row
*glyph_row
;
4542 int cursor_type
, cursor_width
;
4547 w
->phys_cursor_type
= cursor_type
;
4548 w
->phys_cursor_width
= cursor_width
;
4549 w
->phys_cursor_on_p
= 1;
4551 switch (cursor_type
)
4553 case HOLLOW_BOX_CURSOR
:
4554 x_draw_hollow_cursor (w
, glyph_row
);
4557 case FILLED_BOX_CURSOR
:
4558 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4562 /* TODO. For now, just draw bar cursor. */
4564 x_draw_bar_cursor (w
, glyph_row
, cursor_width
);
4579 #if 0 /* MAC_TODO: no icon support yet. */
4581 x_bitmap_icon (f
, icon
)
4587 if (FRAME_W32_WINDOW (f
) == 0)
4591 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4592 else if (STRINGP (icon
))
4593 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4594 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4595 else if (SYMBOLP (icon
))
4599 if (EQ (icon
, intern ("application")))
4600 name
= (LPCTSTR
) IDI_APPLICATION
;
4601 else if (EQ (icon
, intern ("hand")))
4602 name
= (LPCTSTR
) IDI_HAND
;
4603 else if (EQ (icon
, intern ("question")))
4604 name
= (LPCTSTR
) IDI_QUESTION
;
4605 else if (EQ (icon
, intern ("exclamation")))
4606 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4607 else if (EQ (icon
, intern ("asterisk")))
4608 name
= (LPCTSTR
) IDI_ASTERISK
;
4609 else if (EQ (icon
, intern ("winlogo")))
4610 name
= (LPCTSTR
) IDI_WINLOGO
;
4614 hicon
= LoadIcon (NULL
, name
);
4622 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4627 #endif /* MAC_TODO */
4629 /************************************************************************
4631 ************************************************************************/
4633 /* Display Error Handling functions not used on W32. Listing them here
4634 helps diff stay in step when comparing w32term.c with xterm.c.
4636 x_error_catcher (display, error)
4637 x_catch_errors (dpy)
4638 x_catch_errors_unwind (old_val)
4639 x_check_errors (dpy, format)
4640 x_had_errors_p (dpy)
4641 x_clear_errors (dpy)
4642 x_uncatch_errors (dpy, count)
4644 x_connection_signal (signalnum)
4645 x_connection_closed (dpy, error_message)
4646 x_error_quitter (display, error)
4647 x_error_handler (display, error)
4648 x_io_error_quitter (display)
4653 /* Changing the font of the frame. */
4655 /* Give frame F the font named FONTNAME as its default font, and
4656 return the full name of that font. FONTNAME may be a wildcard
4657 pattern; in that case, we choose some font that fits the pattern.
4658 The return value shows which font we chose. */
4661 x_new_font (f
, fontname
)
4663 register char *fontname
;
4665 struct font_info
*fontp
4666 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4671 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4672 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4673 FRAME_FONTSET (f
) = -1;
4675 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4676 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4678 compute_fringe_widths (f
, 1);
4680 /* Compute the scroll bar width in character columns. */
4681 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4683 int wid
= FRAME_COLUMN_WIDTH (f
);
4684 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4685 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4689 int wid
= FRAME_COLUMN_WIDTH (f
);
4690 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4693 /* Now make the frame display the given font. */
4694 if (FRAME_MAC_WINDOW (f
) != 0)
4696 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4698 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4700 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4703 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4704 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4707 return build_string (fontp
->full_name
);
4710 /* Give frame F the fontset named FONTSETNAME as its default font, and
4711 return the full name of that fontset. FONTSETNAME may be a wildcard
4712 pattern; in that case, we choose some fontset that fits the pattern.
4713 The return value shows which fontset we chose. */
4716 x_new_fontset (f
, fontsetname
)
4720 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
4726 if (FRAME_FONTSET (f
) == fontset
)
4727 /* This fontset is already set in frame F. There's nothing more
4729 return fontset_name (fontset
);
4731 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
4733 if (!STRINGP (result
))
4734 /* Can't load ASCII font. */
4737 /* Since x_new_font doesn't update any fontset information, do it now. */
4738 FRAME_FONTSET(f
) = fontset
;
4740 return build_string (fontsetname
);
4744 /***********************************************************************
4745 TODO: W32 Input Methods
4746 ***********************************************************************/
4747 /* Listing missing functions from xterm.c helps diff stay in step.
4749 xim_destroy_callback (xim, client_data, call_data)
4750 xim_open_dpy (dpyinfo, resource_name)
4752 xim_instantiate_callback (display, client_data, call_data)
4753 xim_initialize (dpyinfo, resource_name)
4754 xim_close_dpy (dpyinfo)
4759 /* Calculate the absolute position in frame F
4760 from its current recorded position values and gravity. */
4763 x_calc_absolute_position (f
)
4767 int flags
= f
->size_hint_flags
;
4771 /* Find the position of the outside upper-left corner of
4772 the inner window, with respect to the outer window. */
4773 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
4776 GetPort (&savePort
);
4778 #if TARGET_API_MAC_CARBON
4779 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
4781 SetPort (FRAME_MAC_WINDOW (f
));
4784 #if TARGET_API_MAC_CARBON
4788 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
4789 SetPt(&pt
, r
.left
, r
.top
);
4791 #else /* not TARGET_API_MAC_CARBON */
4792 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
4793 #endif /* not TARGET_API_MAC_CARBON */
4794 LocalToGlobal (&pt
);
4798 /* Treat negative positions as relative to the leftmost bottommost
4799 position that fits on the screen. */
4800 if (flags
& XNegative
)
4801 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
4802 - 2 * f
->border_width
- pt
.h
4803 - FRAME_PIXEL_WIDTH (f
)
4805 /* NTEMACS_TODO: Subtract menubar height? */
4806 if (flags
& YNegative
)
4807 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
4808 - 2 * f
->border_width
- pt
.v
4809 - FRAME_PIXEL_HEIGHT (f
)
4811 /* The left_pos and top_pos
4812 are now relative to the top and left screen edges,
4813 so the flags should correspond. */
4814 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4817 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
4818 to really change the position, and 0 when calling from
4819 x_make_frame_visible (in that case, XOFF and YOFF are the current
4820 position values). It is -1 when calling from x_set_frame_parameters,
4821 which means, do adjust for borders but don't change the gravity. */
4824 x_set_offset (f
, xoff
, yoff
, change_gravity
)
4826 register int xoff
, yoff
;
4829 int modified_top
, modified_left
;
4831 if (change_gravity
> 0)
4835 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4837 f
->size_hint_flags
|= XNegative
;
4839 f
->size_hint_flags
|= YNegative
;
4840 f
->win_gravity
= NorthWestGravity
;
4842 x_calc_absolute_position (f
);
4845 x_wm_set_size_hint (f
, (long) 0, 0);
4847 modified_left
= f
->left_pos
;
4848 modified_top
= f
->top_pos
;
4850 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
4851 modified_top
+ 42, false);
4856 /* Call this to change the size of frame F's x-window.
4857 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
4858 for this size change and subsequent size changes.
4859 Otherwise we leave the window gravity unchanged. */
4862 x_set_window_size (f
, change_gravity
, cols
, rows
)
4867 int pixelwidth
, pixelheight
;
4871 check_frame_size (f
, &rows
, &cols
);
4872 f
->scroll_bar_actual_width
4873 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
4875 compute_fringe_widths (f
, 0);
4877 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
4878 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
4880 f
->win_gravity
= NorthWestGravity
;
4881 x_wm_set_size_hint (f
, (long) 0, 0);
4883 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
4885 /* Now, strictly speaking, we can't be sure that this is accurate,
4886 but the window manager will get around to dealing with the size
4887 change request eventually, and we'll hear how it went when the
4888 ConfigureNotify event gets here.
4890 We could just not bother storing any of this information here,
4891 and let the ConfigureNotify event set everything up, but that
4892 might be kind of confusing to the Lisp code, since size changes
4893 wouldn't be reported in the frame parameters until some random
4894 point in the future when the ConfigureNotify event arrives.
4896 We pass 1 for DELAY since we can't run Lisp code inside of
4898 change_frame_size (f
, rows
, cols
, 0, 1, 0);
4899 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
4900 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
4902 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
4903 receive in the ConfigureNotify event; if we get what we asked
4904 for, then the event won't cause the screen to become garbaged, so
4905 we have to make sure to do it here. */
4906 SET_FRAME_GARBAGED (f
);
4908 XFlush (FRAME_X_DISPLAY (f
));
4910 /* If cursor was outside the new size, mark it as off. */
4911 mark_window_cursors_off (XWINDOW (f
->root_window
));
4913 /* Clear out any recollection of where the mouse highlighting was,
4914 since it might be in a place that's outside the new frame size.
4915 Actually checking whether it is outside is a pain in the neck,
4916 so don't try--just let the highlighting be done afresh with new size. */
4917 cancel_mouse_face (f
);
4922 /* Mouse warping. */
4924 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
4927 x_set_mouse_position (f
, x
, y
)
4933 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
4934 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
4936 if (pix_x
< 0) pix_x
= 0;
4937 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
4939 if (pix_y
< 0) pix_y
= 0;
4940 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
4942 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
4946 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
4950 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
4953 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
4954 0, 0, 0, 0, pix_x
, pix_y
);
4960 /* focus shifting, raising and lowering. */
4963 x_focus_on_frame (f
)
4966 #if 0 /* This proves to be unpleasant. */
4970 /* I don't think that the ICCCM allows programs to do things like this
4971 without the interaction of the window manager. Whatever you end up
4972 doing with this code, do it to x_unfocus_frame too. */
4973 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
4974 RevertToPointerRoot
, CurrentTime
);
4984 /* Raise frame F. */
4989 if (f
->async_visible
)
4990 SelectWindow (FRAME_MAC_WINDOW (f
));
4993 /* Lower frame F. */
4998 if (f
->async_visible
)
4999 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5003 XTframe_raise_lower (f
, raise_flag
)
5013 /* Change of visibility. */
5015 /* This tries to wait until the frame is really visible.
5016 However, if the window manager asks the user where to position
5017 the frame, this will return before the user finishes doing that.
5018 The frame will not actually be visible at that time,
5019 but it will become visible later when the window manager
5020 finishes with it. */
5023 x_make_frame_visible (f
)
5027 int original_top
, original_left
;
5031 if (! FRAME_VISIBLE_P (f
))
5033 /* We test FRAME_GARBAGED_P here to make sure we don't
5034 call x_set_offset a second time
5035 if we get to x_make_frame_visible a second time
5036 before the window gets really visible. */
5037 if (! FRAME_ICONIFIED_P (f
)
5038 && ! f
->output_data
.mac
->asked_for_visible
)
5039 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5041 f
->output_data
.mac
->asked_for_visible
= 1;
5043 ShowWindow (FRAME_MAC_WINDOW (f
));
5046 XFlush (FRAME_MAC_DISPLAY (f
));
5048 #if 0 /* MAC_TODO */
5049 /* Synchronize to ensure Emacs knows the frame is visible
5050 before we do anything else. We do this loop with input not blocked
5051 so that incoming events are handled. */
5056 /* This must come after we set COUNT. */
5059 XSETFRAME (frame
, f
);
5061 /* Wait until the frame is visible. Process X events until a
5062 MapNotify event has been seen, or until we think we won't get a
5063 MapNotify at all.. */
5064 for (count
= input_signal_count
+ 10;
5065 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5067 /* Force processing of queued events. */
5070 /* Machines that do polling rather than SIGIO have been
5071 observed to go into a busy-wait here. So we'll fake an
5072 alarm signal to let the handler know that there's something
5073 to be read. We used to raise a real alarm, but it seems
5074 that the handler isn't always enabled here. This is
5076 if (input_polling_used ())
5078 /* It could be confusing if a real alarm arrives while
5079 processing the fake one. Turn it off and let the
5080 handler reset it. */
5081 extern void poll_for_input_1
P_ ((void));
5082 int old_poll_suppress_count
= poll_suppress_count
;
5083 poll_suppress_count
= 1;
5084 poll_for_input_1 ();
5085 poll_suppress_count
= old_poll_suppress_count
;
5088 /* See if a MapNotify event has been processed. */
5089 FRAME_SAMPLE_VISIBILITY (f
);
5092 #endif /* MAC_TODO */
5095 /* Change from mapped state to withdrawn state. */
5097 /* Make the frame visible (mapped and not iconified). */
5100 x_make_frame_invisible (f
)
5103 /* Don't keep the highlight on an invisible frame. */
5104 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5105 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5109 HideWindow (FRAME_MAC_WINDOW (f
));
5111 /* We can't distinguish this from iconification
5112 just by the event that we get from the server.
5113 So we can't win using the usual strategy of letting
5114 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5115 and synchronize with the server to make sure we agree. */
5117 FRAME_ICONIFIED_P (f
) = 0;
5118 f
->async_visible
= 0;
5119 f
->async_iconified
= 0;
5124 /* Change window state from mapped to iconified. */
5130 /* Don't keep the highlight on an invisible frame. */
5131 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5132 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5135 /* Review: Since window is still visible in dock, still allow updates? */
5136 if (f
->async_iconified
)
5142 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5148 /* Destroy the X window of frame F. */
5151 x_destroy_window (f
)
5154 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5158 DisposeWindow (FRAME_MAC_WINDOW (f
));
5160 free_frame_menubar (f
);
5161 free_frame_faces (f
);
5163 xfree (f
->output_data
.mac
);
5164 f
->output_data
.mac
= 0;
5165 if (f
== dpyinfo
->x_focus_frame
)
5166 dpyinfo
->x_focus_frame
= 0;
5167 if (f
== dpyinfo
->x_focus_event_frame
)
5168 dpyinfo
->x_focus_event_frame
= 0;
5169 if (f
== dpyinfo
->x_highlight_frame
)
5170 dpyinfo
->x_highlight_frame
= 0;
5172 dpyinfo
->reference_count
--;
5174 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5176 dpyinfo
->mouse_face_beg_row
5177 = dpyinfo
->mouse_face_beg_col
= -1;
5178 dpyinfo
->mouse_face_end_row
5179 = dpyinfo
->mouse_face_end_col
= -1;
5180 dpyinfo
->mouse_face_window
= Qnil
;
5181 dpyinfo
->mouse_face_deferred_gc
= 0;
5182 dpyinfo
->mouse_face_mouse_frame
= 0;
5188 /* Setting window manager hints. */
5190 /* Set the normal size hints for the window manager, for frame F.
5191 FLAGS is the flags word to use--or 0 meaning preserve the flags
5192 that the window now has.
5193 If USER_POSITION is nonzero, we set the USPosition
5194 flag (this is useful when FLAGS is 0). */
5196 x_wm_set_size_hint (f
, flags
, user_position
)
5201 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5202 XSizeHints size_hints
;
5204 #ifdef USE_X_TOOLKIT
5207 Dimension widget_width
, widget_height
;
5208 Window window
= XtWindow (f
->output_data
.x
->widget
);
5209 #else /* not USE_X_TOOLKIT */
5210 Window window
= FRAME_X_WINDOW (f
);
5211 #endif /* not USE_X_TOOLKIT */
5213 /* Setting PMaxSize caused various problems. */
5214 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5216 size_hints
.x
= f
->left_pos
;
5217 size_hints
.y
= f
->top_pos
;
5219 #ifdef USE_X_TOOLKIT
5220 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5221 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5222 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5223 size_hints
.height
= widget_height
;
5224 size_hints
.width
= widget_width
;
5225 #else /* not USE_X_TOOLKIT */
5226 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5227 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5228 #endif /* not USE_X_TOOLKIT */
5230 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5231 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5232 size_hints
.max_width
5233 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5234 size_hints
.max_height
5235 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5237 /* Calculate the base and minimum sizes.
5239 (When we use the X toolkit, we don't do it here.
5240 Instead we copy the values that the widgets are using, below.) */
5241 #ifndef USE_X_TOOLKIT
5243 int base_width
, base_height
;
5244 int min_rows
= 0, min_cols
= 0;
5246 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5247 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5249 check_frame_size (f
, &min_rows
, &min_cols
);
5251 /* The window manager uses the base width hints to calculate the
5252 current number of rows and columns in the frame while
5253 resizing; min_width and min_height aren't useful for this
5254 purpose, since they might not give the dimensions for a
5255 zero-row, zero-column frame.
5257 We use the base_width and base_height members if we have
5258 them; otherwise, we set the min_width and min_height members
5259 to the size for a zero x zero frame. */
5262 size_hints
.flags
|= PBaseSize
;
5263 size_hints
.base_width
= base_width
;
5264 size_hints
.base_height
= base_height
;
5265 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5266 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5268 size_hints
.min_width
= base_width
;
5269 size_hints
.min_height
= base_height
;
5273 /* If we don't need the old flags, we don't need the old hint at all. */
5276 size_hints
.flags
|= flags
;
5279 #endif /* not USE_X_TOOLKIT */
5282 XSizeHints hints
; /* Sometimes I hate X Windows... */
5283 long supplied_return
;
5287 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5290 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5293 #ifdef USE_X_TOOLKIT
5294 size_hints
.base_height
= hints
.base_height
;
5295 size_hints
.base_width
= hints
.base_width
;
5296 size_hints
.min_height
= hints
.min_height
;
5297 size_hints
.min_width
= hints
.min_width
;
5301 size_hints
.flags
|= flags
;
5306 if (hints
.flags
& PSize
)
5307 size_hints
.flags
|= PSize
;
5308 if (hints
.flags
& PPosition
)
5309 size_hints
.flags
|= PPosition
;
5310 if (hints
.flags
& USPosition
)
5311 size_hints
.flags
|= USPosition
;
5312 if (hints
.flags
& USSize
)
5313 size_hints
.flags
|= USSize
;
5317 #ifndef USE_X_TOOLKIT
5322 size_hints
.win_gravity
= f
->win_gravity
;
5323 size_hints
.flags
|= PWinGravity
;
5327 size_hints
.flags
&= ~ PPosition
;
5328 size_hints
.flags
|= USPosition
;
5330 #endif /* PWinGravity */
5333 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5335 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5337 #endif /* MAC_TODO */
5340 #if 0 /* MAC_TODO: hide application instead of iconify? */
5341 /* Used for IconicState or NormalState */
5344 x_wm_set_window_state (f
, state
)
5348 #ifdef USE_X_TOOLKIT
5351 XtSetArg (al
[0], XtNinitialState
, state
);
5352 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5353 #else /* not USE_X_TOOLKIT */
5354 Window window
= FRAME_X_WINDOW (f
);
5356 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5357 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5359 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5360 #endif /* not USE_X_TOOLKIT */
5364 x_wm_set_icon_pixmap (f
, pixmap_id
)
5370 #ifndef USE_X_TOOLKIT
5371 Window window
= FRAME_X_WINDOW (f
);
5376 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5377 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5381 /* It seems there is no way to turn off use of an icon pixmap.
5382 The following line does it, only if no icon has yet been created,
5383 for some window managers. But with mwm it crashes.
5384 Some people say it should clear the IconPixmapHint bit in this case,
5385 but that doesn't work, and the X consortium said it isn't the
5386 right thing at all. Since there is no way to win,
5387 best to explicitly give up. */
5389 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5395 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5399 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5400 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5403 #else /* not USE_X_TOOLKIT */
5405 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5406 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5408 #endif /* not USE_X_TOOLKIT */
5411 #endif /* MAC_TODO */
5414 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5418 #if 0 /* MAC_TODO: no icons on Mac */
5419 #ifdef USE_X_TOOLKIT
5420 Window window
= XtWindow (f
->output_data
.x
->widget
);
5422 Window window
= FRAME_X_WINDOW (f
);
5425 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5426 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5427 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5429 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5430 #endif /* MAC_TODO */
5434 /***********************************************************************
5436 ***********************************************************************/
5438 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5441 x_get_font_info (f
, font_idx
)
5445 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5448 /* the global font name table */
5449 char **font_name_table
= NULL
;
5450 int font_name_table_size
= 0;
5451 int font_name_count
= 0;
5453 /* compare two strings ignoring case */
5455 stricmp (const char *s
, const char *t
)
5457 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5460 return tolower (*s
) - tolower (*t
);
5463 /* compare two strings ignoring case and handling wildcard */
5465 wildstrieq (char *s1
, char *s2
)
5467 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5470 return stricmp (s1
, s2
) == 0;
5473 /* Assume parameter 1 is fully qualified, no wildcards. */
5475 mac_font_pattern_match (fontname
, pattern
)
5479 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5480 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5483 /* Copy fontname so we can modify it during comparison. */
5484 strcpy (font_name_copy
, fontname
);
5489 /* Turn pattern into a regexp and do a regexp match. */
5490 for (; *pattern
; pattern
++)
5492 if (*pattern
== '?')
5494 else if (*pattern
== '*')
5505 return (fast_c_string_match_ignore_case (build_string (regex
),
5506 font_name_copy
) >= 0);
5509 /* Two font specs are considered to match if their foundry, family,
5510 weight, slant, and charset match. */
5512 mac_font_match (char *mf
, char *xf
)
5514 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5515 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5517 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5518 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5519 return mac_font_pattern_match (mf
, xf
);
5521 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5522 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5523 return mac_font_pattern_match (mf
, xf
);
5525 return (wildstrieq (m_foundry
, x_foundry
)
5526 && wildstrieq (m_family
, x_family
)
5527 && wildstrieq (m_weight
, x_weight
)
5528 && wildstrieq (m_slant
, x_slant
)
5529 && wildstrieq (m_charset
, x_charset
))
5530 || mac_font_pattern_match (mf
, xf
);
5535 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5537 char foundry
[32], family
[32], cs
[32];
5538 char xf
[255], *result
, *p
;
5540 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5542 strcpy(foundry
, "Apple");
5543 strcpy(family
, name
);
5548 strcpy(cs
, "big5-0");
5551 strcpy(cs
, "gb2312.1980-0");
5554 strcpy(cs
, "jisx0208.1983-sjis");
5557 /* Each Apple Japanese font is entered into the font table
5558 twice: once as a jisx0208.1983-sjis font and once as a
5559 jisx0201.1976-0 font. The latter can be used to display
5560 the ascii charset and katakana-jisx0201 charset. A
5561 negative script code signals that the name of this latter
5562 font is being built. */
5563 strcpy(cs
, "jisx0201.1976-0");
5566 strcpy(cs
, "ksc5601.1989-0");
5569 strcpy(cs
, "mac-roman");
5574 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5575 foundry
, family
, style
& bold
? "bold" : "medium",
5576 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5578 result
= (char *) xmalloc (strlen (xf
) + 1);
5579 strcpy (result
, xf
);
5580 for (p
= result
; *p
; p
++)
5586 /* Convert an X font spec to the corresponding mac font name, which
5587 can then be passed to GetFNum after conversion to a Pascal string.
5588 For ordinary Mac fonts, this should just be their names, like
5589 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5590 collection contain their charset designation in their names, like
5591 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5592 names are handled accordingly. */
5594 x_font_name_to_mac_font_name (char *xf
, char *mf
)
5596 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
5600 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5601 foundry
, family
, weight
, slant
, cs
) != 5 &&
5602 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5603 foundry
, family
, weight
, slant
, cs
) != 5)
5606 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
5607 || strcmp (cs
, "jisx0208.1983-sjis") == 0
5608 || strcmp (cs
, "jisx0201.1976-0") == 0
5609 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
5612 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
5617 add_font_name_table_entry (char *font_name
)
5619 if (font_name_table_size
== 0)
5621 font_name_table_size
= 16;
5622 font_name_table
= (char **)
5623 xmalloc (font_name_table_size
* sizeof (char *));
5625 else if (font_name_count
+ 1 >= font_name_table_size
)
5627 font_name_table_size
+= 16;
5628 font_name_table
= (char **)
5629 xrealloc (font_name_table
,
5630 font_name_table_size
* sizeof (char *));
5633 font_name_table
[font_name_count
++] = font_name
;
5636 /* Sets up the table font_name_table to contain the list of all fonts
5637 in the system the first time the table is used so that the Resource
5638 Manager need not be accessed every time this information is
5642 init_font_name_table ()
5644 #if TARGET_API_MAC_CARBON
5647 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
5649 FMFontFamilyIterator ffi
;
5650 FMFontFamilyInstanceIterator ffii
;
5653 /* Create a dummy instance iterator here to avoid creating and
5654 destroying it in the loop. */
5655 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
5657 /* Create an iterator to enumerate the font families. */
5658 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
5661 FMDisposeFontFamilyInstanceIterator (&ffii
);
5665 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
5673 if (FMGetFontFamilyName (ff
, name
) != noErr
)
5677 sc
= FontToScript (ff
);
5679 /* Point the instance iterator at the current font family. */
5680 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
5683 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
5687 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5689 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5691 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5693 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5699 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5701 if (smJapanese
== sc
)
5702 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5708 /* Dispose of the iterators. */
5709 FMDisposeFontFamilyIterator (&ffi
);
5710 FMDisposeFontFamilyInstanceIterator (&ffii
);
5714 #endif /* TARGET_API_MAC_CARBON */
5716 SInt16 fontnum
, old_fontnum
;
5717 int num_mac_fonts
= CountResources('FOND');
5719 Handle font_handle
, font_handle_2
;
5720 short id
, scriptcode
;
5723 struct FontAssoc
*fat
;
5724 struct AsscEntry
*assc_entry
;
5726 GetPort (&port
); /* save the current font number used */
5727 #if TARGET_API_MAC_CARBON
5728 old_fontnum
= GetPortTextFont (port
);
5730 old_fontnum
= port
->txFont
;
5733 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
5735 font_handle
= GetIndResource ('FOND', i
);
5739 GetResInfo (font_handle
, &id
, &type
, name
);
5740 GetFNum (name
, &fontnum
);
5746 scriptcode
= FontToScript (fontnum
);
5749 HLock (font_handle
);
5751 if (GetResourceSizeOnDisk (font_handle
)
5752 >= sizeof (struct FamRec
))
5754 fat
= (struct FontAssoc
*) (*font_handle
5755 + sizeof (struct FamRec
));
5757 = (struct AsscEntry
*) (*font_handle
5758 + sizeof (struct FamRec
)
5759 + sizeof (struct FontAssoc
));
5761 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
5763 if (font_name_table_size
== 0)
5765 font_name_table_size
= 16;
5766 font_name_table
= (char **)
5767 xmalloc (font_name_table_size
* sizeof (char *));
5769 else if (font_name_count
>= font_name_table_size
)
5771 font_name_table_size
+= 16;
5772 font_name_table
= (char **)
5773 xrealloc (font_name_table
,
5774 font_name_table_size
* sizeof (char *));
5776 font_name_table
[font_name_count
++]
5777 = mac_to_x_fontname (name
,
5778 assc_entry
->fontSize
,
5779 assc_entry
->fontStyle
,
5781 /* Both jisx0208.1983-sjis and
5782 jisx0201.1976-sjis parts are contained in
5783 Apple Japanese (SJIS) font. */
5784 if (smJapanese
== scriptcode
)
5786 font_name_table
[font_name_count
++]
5787 = mac_to_x_fontname (name
,
5788 assc_entry
->fontSize
,
5789 assc_entry
->fontStyle
,
5795 HUnlock (font_handle
);
5796 font_handle_2
= GetNextFOND (font_handle
);
5797 ReleaseResource (font_handle
);
5798 font_handle
= font_handle_2
;
5800 while (ResError () == noErr
&& font_handle
);
5803 TextFont (old_fontnum
);
5804 #if TARGET_API_MAC_CARBON
5806 #endif /* TARGET_API_MAC_CARBON */
5810 /* Return a list of at most MAXNAMES font specs matching the one in
5811 PATTERN. Cache matching fonts for patterns in
5812 dpyinfo->name_list_element to avoid looking them up again by
5813 calling mac_font_pattern_match (slow). Return as many matching
5814 fonts as possible if MAXNAMES = -1. */
5817 x_list_fonts (struct frame
*f
,
5818 Lisp_Object pattern
,
5823 Lisp_Object newlist
= Qnil
, tem
, key
;
5826 struct gcpro gcpro1
, gcpro2
;
5827 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
5829 if (font_name_table
== NULL
) /* Initialize when first used. */
5830 init_font_name_table ();
5834 tem
= XCDR (dpyinfo
->name_list_element
);
5835 key
= Fcons (pattern
, make_number (maxnames
));
5837 newlist
= Fassoc (key
, tem
);
5838 if (!NILP (newlist
))
5840 newlist
= Fcdr_safe (newlist
);
5845 ptnstr
= SDATA (pattern
);
5847 GCPRO2 (pattern
, newlist
);
5849 /* Scan and matching bitmap fonts. */
5850 for (i
= 0; i
< font_name_count
; i
++)
5852 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
5854 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
5857 if (maxnames
> 0 && n_fonts
>= maxnames
)
5862 /* MAC_TODO: add code for matching outline fonts here */
5868 XSETCDR (dpyinfo
->name_list_element
,
5869 Fcons (Fcons (key
, newlist
),
5870 XCDR (dpyinfo
->name_list_element
)));
5880 /* Check that FONT is valid on frame F. It is if it can be found in F's
5884 x_check_font (f
, font
)
5889 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5891 xassert (font
!= NULL
);
5893 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5894 if (dpyinfo
->font_table
[i
].name
5895 && font
== dpyinfo
->font_table
[i
].font
)
5898 xassert (i
< dpyinfo
->n_fonts
);
5901 #endif /* GLYPH_DEBUG != 0 */
5903 /* Set *W to the minimum width, *H to the minimum font height of FONT.
5904 Note: There are (broken) X fonts out there with invalid XFontStruct
5905 min_bounds contents. For example, handa@etl.go.jp reports that
5906 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
5907 have font->min_bounds.width == 0. */
5910 x_font_min_bounds (font
, w
, h
)
5911 MacFontStruct
*font
;
5915 * TODO: Windows does not appear to offer min bound, only
5916 * average and maximum width, and maximum height.
5918 *h
= FONT_HEIGHT (font
);
5919 *w
= FONT_WIDTH (font
);
5923 /* Compute the smallest character width and smallest font height over
5924 all fonts available on frame F. Set the members smallest_char_width
5925 and smallest_font_height in F's x_display_info structure to
5926 the values computed. Value is non-zero if smallest_font_height or
5927 smallest_char_width become smaller than they were before. */
5930 x_compute_min_glyph_bounds (f
)
5934 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5935 MacFontStruct
*font
;
5936 int old_width
= dpyinfo
->smallest_char_width
;
5937 int old_height
= dpyinfo
->smallest_font_height
;
5939 dpyinfo
->smallest_font_height
= 100000;
5940 dpyinfo
->smallest_char_width
= 100000;
5942 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
5943 if (dpyinfo
->font_table
[i
].name
)
5945 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
5948 font
= (MacFontStruct
*) fontp
->font
;
5949 xassert (font
!= (MacFontStruct
*) ~0);
5950 x_font_min_bounds (font
, &w
, &h
);
5952 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
5953 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
5956 xassert (dpyinfo
->smallest_char_width
> 0
5957 && dpyinfo
->smallest_font_height
> 0);
5959 return (dpyinfo
->n_fonts
== 1
5960 || dpyinfo
->smallest_char_width
< old_width
5961 || dpyinfo
->smallest_font_height
< old_height
);
5965 /* Determine whether given string is a fully-specified XLFD: all 14
5966 fields are present, none is '*'. */
5969 is_fully_specified_xlfd (char *p
)
5977 for (i
= 0; i
< 13; i
++)
5979 q
= strchr (p
+ 1, '-');
5982 if (q
- p
== 2 && *(p
+ 1) == '*')
5987 if (strchr (p
+ 1, '-') != NULL
)
5990 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
5997 const int kDefaultFontSize
= 9;
6000 /* XLoadQueryFont creates and returns an internal representation for a
6001 font in a MacFontStruct struct. There is really no concept
6002 corresponding to "loading" a font on the Mac. But we check its
6003 existence and find the font number and all other information for it
6004 and store them in the returned MacFontStruct. */
6006 static MacFontStruct
*
6007 XLoadQueryFont (Display
*dpy
, char *fontname
)
6009 int i
, size
, is_two_byte_font
, char_width
;
6012 SInt16 old_fontnum
, old_fontsize
;
6016 Style fontface
= normal
;
6017 MacFontStruct
*font
;
6018 FontInfo the_fontinfo
;
6019 char s_weight
[7], c_slant
;
6021 if (is_fully_specified_xlfd (fontname
))
6025 for (i
= 0; i
< font_name_count
; i
++)
6026 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
6029 if (i
>= font_name_count
)
6032 name
= font_name_table
[i
];
6035 GetPort (&port
); /* save the current font number used */
6036 #if TARGET_API_MAC_CARBON
6037 old_fontnum
= GetPortTextFont (port
);
6038 old_fontsize
= GetPortTextSize (port
);
6039 old_fontface
= GetPortTextFace (port
);
6041 old_fontnum
= port
->txFont
;
6042 old_fontsize
= port
->txSize
;
6043 old_fontface
= port
->txFace
;
6046 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6047 size
= kDefaultFontSize
;
6049 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6050 if (strcmp (s_weight
, "bold") == 0)
6053 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6057 x_font_name_to_mac_font_name (name
, mfontname
);
6059 GetFNum (mfontname
, &fontnum
);
6063 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6065 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6066 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6068 font
->mac_fontnum
= fontnum
;
6069 font
->mac_fontsize
= size
;
6070 font
->mac_fontface
= fontface
;
6071 font
->mac_scriptcode
= FontToScript (fontnum
);
6073 /* Apple Japanese (SJIS) font is listed as both
6074 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6075 (Roman script) in init_font_name_table (). The latter should be
6076 treated as a one-byte font. */
6081 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6083 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6084 font
->mac_scriptcode
= smRoman
;
6087 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6088 font
->mac_scriptcode
== smTradChinese
||
6089 font
->mac_scriptcode
== smSimpChinese
||
6090 font
->mac_scriptcode
== smKorean
;
6094 TextFace (fontface
);
6096 GetFontInfo (&the_fontinfo
);
6098 font
->ascent
= the_fontinfo
.ascent
;
6099 font
->descent
= the_fontinfo
.descent
;
6101 font
->min_byte1
= 0;
6102 if (is_two_byte_font
)
6103 font
->max_byte1
= 1;
6105 font
->max_byte1
= 0;
6106 font
->min_char_or_byte2
= 0x20;
6107 font
->max_char_or_byte2
= 0xff;
6109 if (is_two_byte_font
)
6111 /* Use the width of an "ideographic space" of that font because
6112 the_fontinfo.widMax returns the wrong width for some fonts. */
6113 switch (font
->mac_scriptcode
)
6116 char_width
= StringWidth("\p\x81\x40");
6119 char_width
= StringWidth("\p\xa1\x40");
6122 char_width
= StringWidth("\p\xa1\xa1");
6125 char_width
= StringWidth("\p\xa1\xa1");
6130 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6131 returns 15 for 12-point Monaco! */
6132 char_width
= CharWidth ('m');
6134 font
->max_bounds
.rbearing
= char_width
;
6135 font
->max_bounds
.lbearing
= 0;
6136 font
->max_bounds
.width
= char_width
;
6137 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6138 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6140 font
->min_bounds
= font
->max_bounds
;
6142 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6143 font
->per_char
= NULL
;
6146 font
->per_char
= (XCharStruct
*)
6147 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6151 for (c
= 0x20; c
<= 0xff; c
++)
6153 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6154 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
6159 TextFont (old_fontnum
); /* restore previous font number, size and face */
6160 TextSize (old_fontsize
);
6161 TextFace (old_fontface
);
6167 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6168 pointer to the structure font_info while allocating it dynamically.
6169 If SIZE is 0, load any size of font.
6170 If loading is failed, return NULL. */
6173 x_load_font (f
, fontname
, size
)
6175 register char *fontname
;
6178 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6179 Lisp_Object font_names
;
6181 /* Get a list of all the fonts that match this name. Once we
6182 have a list of matching fonts, we compare them against the fonts
6183 we already have by comparing names. */
6184 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6186 if (!NILP (font_names
))
6191 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6192 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6193 if (dpyinfo
->font_table
[i
].name
6194 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6195 SDATA (XCAR (tail
)))
6196 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6197 SDATA (XCAR (tail
)))))
6198 return (dpyinfo
->font_table
+ i
);
6201 /* Load the font and add it to the table. */
6204 struct MacFontStruct
*font
;
6205 struct font_info
*fontp
;
6206 unsigned long value
;
6209 /* If we have found fonts by x_list_font, load one of them. If
6210 not, we still try to load a font by the name given as FONTNAME
6211 because XListFonts (called in x_list_font) of some X server has
6212 a bug of not finding a font even if the font surely exists and
6213 is loadable by XLoadQueryFont. */
6214 if (size
> 0 && !NILP (font_names
))
6215 fontname
= (char *) SDATA (XCAR (font_names
));
6217 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6221 /* Find a free slot in the font table. */
6222 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6223 if (dpyinfo
->font_table
[i
].name
== NULL
)
6226 /* If no free slot found, maybe enlarge the font table. */
6227 if (i
== dpyinfo
->n_fonts
6228 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6231 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6232 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6234 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6237 fontp
= dpyinfo
->font_table
+ i
;
6238 if (i
== dpyinfo
->n_fonts
)
6241 /* Now fill in the slots of *FONTP. */
6244 fontp
->font_idx
= i
;
6245 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6246 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6248 fontp
->full_name
= fontp
->name
;
6250 fontp
->size
= font
->max_bounds
.width
;
6251 fontp
->height
= FONT_HEIGHT (font
);
6253 /* For some font, ascent and descent in max_bounds field is
6254 larger than the above value. */
6255 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6256 if (max_height
> fontp
->height
)
6257 fontp
->height
= max_height
;
6260 /* The slot `encoding' specifies how to map a character
6261 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6262 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6263 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6264 2:0xA020..0xFF7F). For the moment, we don't know which charset
6265 uses this font. So, we set information in fontp->encoding[1]
6266 which is never used by any charset. If mapping can't be
6267 decided, set FONT_ENCODING_NOT_DECIDED. */
6268 if (font
->mac_scriptcode
== smJapanese
)
6269 fontp
->encoding
[1] = 4;
6273 = (font
->max_byte1
== 0
6275 ? (font
->min_char_or_byte2
< 0x80
6276 ? (font
->max_char_or_byte2
< 0x80
6277 ? 0 /* 0x20..0x7F */
6278 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6279 : 1) /* 0xA0..0xFF */
6281 : (font
->min_byte1
< 0x80
6282 ? (font
->max_byte1
< 0x80
6283 ? (font
->min_char_or_byte2
< 0x80
6284 ? (font
->max_char_or_byte2
< 0x80
6285 ? 0 /* 0x2020..0x7F7F */
6286 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6287 : 3) /* 0x20A0..0x7FFF */
6288 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6289 : (font
->min_char_or_byte2
< 0x80
6290 ? (font
->max_char_or_byte2
< 0x80
6291 ? 2 /* 0xA020..0xFF7F */
6292 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6293 : 1))); /* 0xA0A0..0xFFFF */
6296 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6297 fontp
->baseline_offset
6298 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6299 ? (long) value
: 0);
6300 fontp
->relative_compose
6301 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6302 ? (long) value
: 0);
6303 fontp
->default_ascent
6304 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6305 ? (long) value
: 0);
6307 fontp
->baseline_offset
= 0;
6308 fontp
->relative_compose
= 0;
6309 fontp
->default_ascent
= 0;
6312 /* Set global flag fonts_changed_p to non-zero if the font loaded
6313 has a character with a smaller width than any other character
6314 before, or if the font loaded has a smalle>r height than any
6315 other font loaded before. If this happens, it will make a
6316 glyph matrix reallocation necessary. */
6317 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6324 /* Return a pointer to struct font_info of a font named FONTNAME for
6325 frame F. If no such font is loaded, return NULL. */
6328 x_query_font (f
, fontname
)
6330 register char *fontname
;
6332 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6335 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6336 if (dpyinfo
->font_table
[i
].name
6337 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6338 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6339 return (dpyinfo
->font_table
+ i
);
6344 /* Find a CCL program for a font specified by FONTP, and set the member
6345 `encoder' of the structure. */
6348 x_find_ccl_program (fontp
)
6349 struct font_info
*fontp
;
6351 Lisp_Object list
, elt
;
6353 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6357 && STRINGP (XCAR (elt
))
6358 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6364 struct ccl_program
*ccl
6365 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6367 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6370 fontp
->font_encoder
= ccl
;
6376 /***********************************************************************
6378 ***********************************************************************/
6380 #ifdef USE_X_TOOLKIT
6381 static XrmOptionDescRec emacs_options
[] = {
6382 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
6383 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
6385 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
6386 XrmoptionSepArg
, NULL
},
6387 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
6389 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6390 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6391 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
6392 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
6393 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
6394 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
6395 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
6397 #endif /* USE_X_TOOLKIT */
6399 static int x_initialized
;
6402 /* Test whether two display-name strings agree up to the dot that separates
6403 the screen number from the server number. */
6405 same_x_server (name1
, name2
)
6406 char *name1
, *name2
;
6409 unsigned char *system_name
= SDATA (Vsystem_name
);
6410 int system_name_length
= strlen (system_name
);
6411 int length_until_period
= 0;
6413 while (system_name
[length_until_period
] != 0
6414 && system_name
[length_until_period
] != '.')
6415 length_until_period
++;
6417 /* Treat `unix' like an empty host name. */
6418 if (! strncmp (name1
, "unix:", 5))
6420 if (! strncmp (name2
, "unix:", 5))
6422 /* Treat this host's name like an empty host name. */
6423 if (! strncmp (name1
, system_name
, system_name_length
)
6424 && name1
[system_name_length
] == ':')
6425 name1
+= system_name_length
;
6426 if (! strncmp (name2
, system_name
, system_name_length
)
6427 && name2
[system_name_length
] == ':')
6428 name2
+= system_name_length
;
6429 /* Treat this host's domainless name like an empty host name. */
6430 if (! strncmp (name1
, system_name
, length_until_period
)
6431 && name1
[length_until_period
] == ':')
6432 name1
+= length_until_period
;
6433 if (! strncmp (name2
, system_name
, length_until_period
)
6434 && name2
[length_until_period
] == ':')
6435 name2
+= length_until_period
;
6437 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
6441 if (seen_colon
&& *name1
== '.')
6445 && (*name1
== '.' || *name1
== '\0')
6446 && (*name2
== '.' || *name2
== '\0'));
6451 /* The Mac Event loop code */
6455 #include <Quickdraw.h>
6456 #include <Balloons.h>
6457 #include <Devices.h>
6459 #include <Gestalt.h>
6461 #include <Processes.h>
6463 #include <ToolUtils.h>
6464 #include <TextUtils.h>
6465 #include <Dialogs.h>
6468 #include <TextEncodingConverter.h>
6469 #include <Resources.h>
6474 #endif /* ! MAC_OSX */
6479 #define WINDOW_RESOURCE 128
6480 #define TERM_WINDOW_RESOURCE 129
6482 #define DEFAULT_NUM_COLS 80
6484 #define MIN_DOC_SIZE 64
6485 #define MAX_DOC_SIZE 32767
6487 /* sleep time for WaitNextEvent */
6488 #define WNE_SLEEP_AT_SUSPEND 10
6489 #define WNE_SLEEP_AT_RESUME 1
6491 /* true when cannot handle any Mac OS events */
6492 static int handling_window_update
= 0;
6494 /* the flag appl_is_suspended is used both for determining the sleep
6495 time to be passed to WaitNextEvent and whether the cursor should be
6496 drawn when updating the display. The cursor is turned off when
6497 Emacs is suspended. Redrawing it is unnecessary and what needs to
6498 be done depends on whether the cursor lies inside or outside the
6499 redraw region. So we might as well skip drawing it when Emacs is
6501 static Boolean app_is_suspended
= false;
6502 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6504 #define EXTRA_STACK_ALLOC (256 * 1024)
6506 #define ARGV_STRING_LIST_ID 129
6507 #define ABOUT_ALERT_ID 128
6508 #define RAM_TOO_LARGE_ALERT_ID 129
6510 Boolean terminate_flag
= false;
6512 /* True if using command key as meta key. */
6513 Lisp_Object Vmac_command_key_is_meta
;
6515 /* True if the ctrl and meta keys should be reversed. */
6516 Lisp_Object Vmac_reverse_ctrl_meta
;
6518 #if USE_CARBON_EVENTS
6519 /* True if the mouse wheel button (i.e. button 4) should map to
6520 mouse-2, instead of mouse-3. */
6521 Lisp_Object Vmac_wheel_button_is_mouse_2
;
6523 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
6524 for processing before Emacs sees it. */
6525 Lisp_Object Vmac_pass_command_to_system
;
6527 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
6528 for processing before Emacs sees it. */
6529 Lisp_Object Vmac_pass_control_to_system
;
6532 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
6533 to this text encoding */
6534 int mac_keyboard_text_encoding
;
6535 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
6537 /* Set in term/mac-win.el to indicate that event loop can now generate
6538 drag and drop events. */
6539 Lisp_Object Qmac_ready_for_drag_n_drop
;
6541 Lisp_Object drag_and_drop_file_list
;
6543 Point saved_menu_event_location
;
6546 static void init_required_apple_events (void);
6548 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
6550 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
6551 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
6552 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
6555 static OSErr
init_mac_drag_n_drop ();
6556 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
6558 #if USE_CARBON_EVENTS
6559 /* Preliminary Support for the OSX Services Menu */
6560 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
6561 static void init_service_handler ();
6564 extern void init_emacs_passwd_dir ();
6565 extern int emacs_main (int, char **, char **);
6566 extern void check_alarm ();
6568 extern void initialize_applescript();
6569 extern void terminate_applescript();
6572 #if USE_CARBON_EVENTS
6573 mac_to_emacs_modifiers (UInt32 mods
)
6575 mac_to_emacs_modifiers (EventModifiers mods
)
6578 unsigned int result
= 0;
6579 if (mods
& macShiftKey
)
6580 result
|= shift_modifier
;
6581 if (mods
& macCtrlKey
)
6582 result
|= ctrl_modifier
;
6583 if (mods
& macMetaKey
)
6584 result
|= meta_modifier
;
6585 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
6586 result
|= alt_modifier
;
6590 #if USE_CARBON_EVENTS
6591 /* Obtains the event modifiers from the event ref and then calls
6592 mac_to_emacs_modifiers. */
6594 mac_event_to_emacs_modifiers (EventRef eventRef
)
6597 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
6598 sizeof (UInt32
), NULL
, &mods
);
6599 return mac_to_emacs_modifiers (mods
);
6602 /* Given an event ref, return the code to use for the mouse button
6603 code in the emacs input_event. */
6605 mac_get_mouse_btn (EventRef ref
)
6607 EventMouseButton result
= kEventMouseButtonPrimary
;
6608 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
6609 sizeof (EventMouseButton
), NULL
, &result
);
6612 case kEventMouseButtonPrimary
:
6614 case kEventMouseButtonSecondary
:
6615 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
6616 case kEventMouseButtonTertiary
:
6617 case 4: /* 4 is the number for the mouse wheel button */
6618 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
6624 /* Normally, ConvertEventRefToEventRecord will correctly handle all
6625 events. However the click of the mouse wheel is not converted to a
6626 mouseDown or mouseUp event. This calls ConvertEventRef, but then
6627 checks to see if it is a mouse up or down carbon event that has not
6628 been converted, and if so, converts it by hand (to be picked up in
6629 the XTread_socket loop). */
6630 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
6632 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
6633 /* Do special case for mouse wheel button. */
6634 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
6636 UInt32 kind
= GetEventKind (eventRef
);
6637 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
6639 eventRec
->what
= mouseDown
;
6642 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
6644 eventRec
->what
= mouseUp
;
6649 /* Need where and when. */
6651 GetEventParameter (eventRef
, kEventParamMouseLocation
,
6652 typeQDPoint
, NULL
, sizeof (Point
),
6653 NULL
, &eventRec
->where
);
6654 /* Use two step process because new event modifiers are
6655 32-bit and old are 16-bit. Currently, only loss is
6657 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
6658 typeUInt32
, NULL
, sizeof (UInt32
),
6660 eventRec
->modifiers
= mods
;
6662 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
6673 Handle menubar_handle
;
6674 MenuHandle menu_handle
;
6676 menubar_handle
= GetNewMBar (128);
6677 if(menubar_handle
== NULL
)
6679 SetMenuBar (menubar_handle
);
6682 menu_handle
= GetMenuHandle (M_APPLE
);
6683 if(menu_handle
!= NULL
)
6684 AppendResMenu (menu_handle
,'DRVR');
6691 do_init_managers (void)
6693 #if !TARGET_API_MAC_CARBON
6694 InitGraf (&qd
.thePort
);
6696 FlushEvents (everyEvent
, 0);
6701 #endif /* !TARGET_API_MAC_CARBON */
6704 #if !TARGET_API_MAC_CARBON
6705 /* set up some extra stack space for use by emacs */
6706 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
6708 /* MaxApplZone must be called for AppleScript to execute more
6709 complicated scripts */
6712 #endif /* !TARGET_API_MAC_CARBON */
6716 do_check_ram_size (void)
6718 SInt32 physical_ram_size
, logical_ram_size
;
6720 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
6721 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
6722 || physical_ram_size
> 256 * 1024 * 1024
6723 || logical_ram_size
> 256 * 1024 * 1024)
6725 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
6731 do_window_update (WindowPtr win
)
6733 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
6734 struct frame
*f
= mwp
->mFP
;
6738 if (f
->async_visible
== 0)
6740 f
->async_visible
= 1;
6741 f
->async_iconified
= 0;
6742 SET_FRAME_GARBAGED (f
);
6744 /* An update event is equivalent to MapNotify on X, so report
6745 visibility changes properly. */
6746 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
6747 /* Force a redisplay sooner or later to update the
6748 frame titles in case this is the second frame. */
6749 record_asynch_buffer_change ();
6754 handling_window_update
= 1;
6756 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
6758 expose_frame (f
, 0, 0, 0, 0);
6760 handling_window_update
= 0;
6767 is_emacs_window (WindowPtr win
)
6769 Lisp_Object tail
, frame
;
6774 FOR_EACH_FRAME (tail
, frame
)
6775 if (FRAME_MAC_P (XFRAME (frame
)))
6776 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
6783 do_window_activate (WindowPtr win
)
6788 if (is_emacs_window (win
))
6790 mwp
= (mac_output
*) GetWRefCon (win
);
6795 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6796 activate_scroll_bars (f
);
6802 do_window_deactivate (WindowPtr win
)
6807 if (is_emacs_window (win
))
6809 mwp
= (mac_output
*) GetWRefCon (win
);
6812 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6814 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6815 deactivate_scroll_bars (f
);
6828 if (is_emacs_window (wp
))
6830 mwp
= (mac_output
*) GetWRefCon (wp
);
6835 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6836 activate_scroll_bars (f
);
6840 app_is_suspended
= false;
6841 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6852 if (is_emacs_window (wp
))
6854 mwp
= (mac_output
*) GetWRefCon (wp
);
6857 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6859 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6860 deactivate_scroll_bars (f
);
6864 app_is_suspended
= true;
6865 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
6870 do_mouse_moved (Point mouse_pos
)
6872 WindowPtr wp
= FrontWindow ();
6875 if (is_emacs_window (wp
))
6877 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6879 #if TARGET_API_MAC_CARBON
6880 SetPort (GetWindowPort (wp
));
6885 GlobalToLocal (&mouse_pos
);
6887 note_mouse_movement (f
, &mouse_pos
);
6893 do_os_event (EventRecord
*erp
)
6895 switch((erp
->message
>> 24) & 0x000000FF)
6897 case suspendResumeMessage
:
6898 if((erp
->message
& resumeFlag
) == 1)
6904 case mouseMovedMessage
:
6905 do_mouse_moved (erp
->where
);
6911 do_events (EventRecord
*erp
)
6916 do_window_update ((WindowPtr
) erp
->message
);
6924 if ((erp
->modifiers
& activeFlag
) != 0)
6925 do_window_activate ((WindowPtr
) erp
->message
);
6927 do_window_deactivate ((WindowPtr
) erp
->message
);
6933 do_apple_menu (SInt16 menu_item
)
6935 #if !TARGET_API_MAC_CARBON
6937 SInt16 da_driver_refnum
;
6939 if (menu_item
== I_ABOUT
)
6940 NoteAlert (ABOUT_ALERT_ID
, NULL
);
6943 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
6944 da_driver_refnum
= OpenDeskAcc (item_name
);
6946 #endif /* !TARGET_API_MAC_CARBON */
6950 do_menu_choice (SInt32 menu_choice
)
6952 SInt16 menu_id
, menu_item
;
6954 menu_id
= HiWord (menu_choice
);
6955 menu_item
= LoWord (menu_choice
);
6963 do_apple_menu (menu_item
);
6968 WindowPtr wp
= FrontWindow ();
6969 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6970 MenuHandle menu
= GetMenuHandle (menu_id
);
6975 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
6976 menubar_selection_callback (f
, refcon
);
6985 /* Handle drags in size box. Based on code contributed by Ben
6986 Mesander and IM - Window Manager A. */
6989 do_grow_window (WindowPtr w
, EventRecord
*e
)
6994 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
6995 struct frame
*f
= mwp
->mFP
;
6997 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
6999 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7001 /* see if it really changed size */
7004 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7005 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7007 x_set_window_size (f
, 0, columns
, rows
);
7012 /* Handle clicks in zoom box. Calculation of "standard state" based
7013 on code in IM - Window Manager A and code contributed by Ben
7014 Mesander. The standard state of an Emacs window is 80-characters
7015 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7018 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7021 Rect zoom_rect
, port_rect
;
7023 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
7024 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7025 struct frame
*f
= mwp
->mFP
;
7027 GetPort (&save_port
);
7029 #if TARGET_API_MAC_CARBON
7030 SetPort (GetWindowPort (w
));
7035 /* Clear window to avoid flicker. */
7036 #if TARGET_API_MAC_CARBON
7041 GetWindowPortBounds (w
, &r
);
7044 if (zoom_in_or_out
== inZoomOut
)
7046 /* calculate height of window's title bar (hard card it for now). */
7047 w_title_height
= 20 + GetMBarHeight ();
7049 /* get maximum height of window into zoom_rect.bottom -
7051 GetQDGlobalsScreenBits (&bm
);
7052 zoom_rect
= bm
.bounds
;
7053 zoom_rect
.top
+= w_title_height
;
7054 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7056 zoom_rect
.right
= zoom_rect
.left
7057 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7059 SetWindowStandardState (w
, &zoom_rect
);
7062 #else /* not TARGET_API_MAC_CARBON */
7063 EraseRect (&(w
->portRect
));
7064 if (zoom_in_or_out
== inZoomOut
)
7066 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7067 LocalToGlobal (&top_left
);
7069 /* calculate height of window's title bar */
7070 w_title_height
= top_left
.v
- 1
7071 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7073 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7074 zoom_rect
= qd
.screenBits
.bounds
;
7075 zoom_rect
.top
+= w_title_height
;
7076 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7078 zoom_rect
.right
= zoom_rect
.left
7079 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7081 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7084 #endif /* not TARGET_API_MAC_CARBON */
7086 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
7088 /* retrieve window size and update application values */
7089 #if TARGET_API_MAC_CARBON
7090 GetWindowPortBounds (w
, &port_rect
);
7092 port_rect
= w
->portRect
;
7094 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7095 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7096 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
7098 SetPort (save_port
);
7101 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7103 init_mac_drag_n_drop ()
7105 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7109 /* Intialize AppleEvent dispatcher table for the required events. */
7111 init_required_apple_events ()
7116 /* Make sure we have apple events before starting. */
7117 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7121 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7124 #if TARGET_API_MAC_CARBON
7125 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7126 NewAEEventHandlerUPP
7127 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7130 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7131 NewAEEventHandlerProc
7132 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7138 #if TARGET_API_MAC_CARBON
7139 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7140 NewAEEventHandlerUPP
7141 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7144 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7145 NewAEEventHandlerProc
7146 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7152 #if TARGET_API_MAC_CARBON
7153 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7154 NewAEEventHandlerUPP
7155 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7158 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7159 NewAEEventHandlerProc
7160 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7166 #if TARGET_API_MAC_CARBON
7167 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7168 NewAEEventHandlerUPP
7169 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7172 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7173 NewAEEventHandlerProc
7174 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7181 #if USE_CARBON_EVENTS
7184 init_service_handler ()
7186 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7187 {kEventClassService
, kEventServiceCopy
},
7188 {kEventClassService
, kEventServicePaste
}};
7189 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7190 3, specs
, NULL
, NULL
);
7194 MAC_TODO: Check to see if this is called by AEProcessDesc...
7197 mac_handle_service_event (EventHandlerCallRef callRef
,
7198 EventRef event
, void *data
)
7200 OSStatus err
= noErr
;
7201 switch (GetEventKind (event
))
7203 case kEventServiceGetTypes
:
7205 CFMutableArrayRef copyTypes
, pasteTypes
;
7207 Boolean selection
= true;
7209 GetEventParameter(event, kEventParamServicePasteTypes,
7210 typeCFMutableArrayRef, NULL,
7211 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7213 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7214 typeCFMutableArrayRef
, NULL
,
7215 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7216 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7218 CFArrayAppendValue (copyTypes
, type
);
7219 //CFArrayAppendValue (pasteTypes, type);
7223 case kEventServiceCopy
:
7225 ScrapRef currentScrap
, specificScrap
;
7229 GetCurrentScrap (¤tScrap
);
7231 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7234 void *buffer
= xmalloc (byteCount
);
7237 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7238 sizeof (ScrapRef
), NULL
, &specificScrap
);
7240 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7241 &byteCount
, buffer
);
7243 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7244 kScrapFlavorMaskNone
, byteCount
, buffer
);
7250 case kEventServicePaste
:
7253 // Get the current location
7255 ScrapRef specificScrap;
7256 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7257 sizeof(ScrapRef), NULL, &specificScrap);
7258 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7260 void * buffer = xmalloc(byteCount);
7261 if (buffer != NULL ) {
7262 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7263 &byteCount, buffer);
7265 // Actually place in the buffer
7267 // Get the current "selection" string here
7280 /* Open Application Apple Event */
7282 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7288 /* Defined in mac.c. */
7290 path_from_vol_dir_name (char *, int, short, long, char *);
7293 /* Called when we receive an AppleEvent with an ID of
7294 "kAEOpenDocuments". This routine gets the direct parameter,
7295 extracts the FSSpecs in it, and puts their names on a list. */
7297 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7302 DescType actual_type
;
7305 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7307 goto descriptor_error_exit
;
7309 /* Check to see that we got all of the required parameters from the
7310 event descriptor. For an 'odoc' event this should just be the
7312 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7313 &actual_type
, (Ptr
) &keyword
,
7314 sizeof (keyword
), &actual_size
);
7315 /* No error means that we found some unused parameters.
7316 errAEDescNotFound means that there are no more parameters. If we
7317 get an error code other than that, flag it. */
7318 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7320 err
= errAEEventNotHandled
;
7325 /* Got all the parameters we need. Now, go through the direct
7326 object list and parse it up. */
7328 long num_files_to_open
;
7330 err
= AECountItems (&the_desc
, &num_files_to_open
);
7335 /* AE file list is one based so just use that for indexing here. */
7336 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7339 Str255 path_name
, unix_path_name
;
7344 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7345 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7346 if (err
!= noErr
) break;
7349 err
= FSpMakeFSRef (&fs
, &fref
);
7350 if (err
!= noErr
) break;
7352 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7354 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7356 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7358 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7359 drag_and_drop_file_list
);
7365 /* Nuke the coerced file list in any case */
7366 err2
= AEDisposeDesc(&the_desc
);
7368 descriptor_error_exit
:
7369 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7375 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7376 DragReference theDrag
)
7380 FlavorFlags theFlags
;
7383 ItemReference theItem
;
7386 Size size
= sizeof (HFSFlavor
);
7388 drag_and_drop_file_list
= Qnil
;
7389 GetDragMouse (theDrag
, &mouse
, 0L);
7390 CountDragItems (theDrag
, &items
);
7391 for (index
= 1; index
<= items
; index
++)
7393 /* Only handle file references. */
7394 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7395 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7396 if (result
== noErr
)
7403 Str255 unix_path_name
;
7404 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7406 /* Use Carbon routines, otherwise it converts the file name
7407 to /Macintosh HD/..., which is not correct. */
7408 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7409 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7411 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7412 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7413 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7415 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7416 drag_and_drop_file_list
);
7421 /* If there are items in the list, construct an event and post it to
7422 the queue like an interrupt using kbd_buffer_store_event. */
7423 if (!NILP (drag_and_drop_file_list
))
7425 struct input_event event
;
7427 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
7428 SetPort (GetWindowPort (window
));
7429 GlobalToLocal (&mouse
);
7431 event
.kind
= DRAG_N_DROP_EVENT
;
7433 event
.modifiers
= 0;
7434 event
.timestamp
= TickCount () * (1000 / 60);
7435 XSETINT (event
.x
, mouse
.h
);
7436 XSETINT (event
.y
, mouse
.v
);
7437 XSETFRAME (frame
, f
);
7438 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7440 /* Post to the interrupt queue */
7441 kbd_buffer_store_event (&event
);
7442 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7444 ProcessSerialNumber psn
;
7445 GetCurrentProcess (&psn
);
7446 SetFrontProcess (&psn
);
7452 /* Print Document Apple Event */
7454 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7456 return errAEEventNotHandled
;
7461 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7463 /* FixMe: Do we need an unwind-protect or something here? And what
7464 do we do about unsaved files. Currently just forces quit rather
7465 than doing recursive callback to get user input. */
7467 terminate_flag
= true;
7469 /* Fkill_emacs doesn't return. We have to return. (TI) */
7476 profiler_exit_proc ()
7478 ProfilerDump ("\pEmacs.prof");
7483 /* These few functions implement Emacs as a normal Mac application
7484 (almost): set up the heap and the Toolbox, handle necessary
7485 system events plus a few simple menu events. They also set up
7486 Emacs's access to functions defined in the rest of this file.
7487 Emacs uses function hooks to perform all its terminal I/O. A
7488 complete list of these functions appear in termhooks.h. For what
7489 they do, read the comments there and see also w32term.c and
7490 xterm.c. What's noticeably missing here is the event loop, which
7491 is normally present in most Mac application. After performing the
7492 necessary Mac initializations, main passes off control to
7493 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7494 mac_read_socket (defined further below) to read input. This is
7495 where WaitNextEvent is called to process Mac events. This is also
7496 where check_alarm in sysdep.c is called to simulate alarm signals.
7497 This makes the cursor jump back to its correct position after
7498 briefly jumping to that of the matching parenthesis, print useful
7499 hints and prompts in the minibuffer after the user stops typing for
7502 #if !TARGET_API_MAC_CARBON
7507 #if __profile__ /* is the profiler on? */
7508 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7513 /* set creator and type for files created by MSL */
7518 do_init_managers ();
7522 do_check_ram_size ();
7524 init_emacs_passwd_dir ();
7528 initialize_applescript ();
7530 init_required_apple_events ();
7536 /* set up argv array from STR# resource */
7537 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
7541 /* free up AppleScript resources on exit */
7542 atexit (terminate_applescript
);
7544 #if __profile__ /* is the profiler on? */
7545 atexit (profiler_exit_proc
);
7548 /* 3rd param "envp" never used in emacs_main */
7549 (void) emacs_main (argc
, argv
, 0);
7552 /* Never reached - real exit in Fkill_emacs */
7557 /* Table for translating Mac keycode to X keysym values. Contributed
7558 by Sudhir Shenoy. */
7559 static unsigned char keycode_to_xkeysym_table
[] = {
7560 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7561 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7562 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7564 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
7565 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
7566 /*0x38*/ 0, 0, 0, 0,
7567 /*0x3C*/ 0, 0, 0, 0,
7569 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
7570 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
7571 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
7572 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
7574 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
7575 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
7576 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
7577 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
7579 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
7580 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
7581 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
7582 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
7584 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
7585 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
7586 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
7587 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
7591 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
7593 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
7594 return *xKeySym
!= 0;
7597 /* Emacs calls this whenever it wants to read an input event from the
7600 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
7603 #if USE_CARBON_EVENTS
7606 EventMouseButton mouseBtn
;
7610 EventMask event_mask
;
7613 if (interrupt_input_blocked
)
7615 interrupt_input_pending
= 1;
7620 interrupt_input_pending
= 0;
7623 /* So people can tell when we have read the available input. */
7624 input_signal_count
++;
7629 /* Don't poll for events to process (specifically updateEvt) if
7630 window update currently already in progress. A call to redisplay
7631 (in do_window_update) can be preempted by another call to
7632 redisplay, causing blank regions to be left on the screen and the
7633 cursor to be left at strange places. */
7634 if (handling_window_update
)
7641 Fkill_emacs (make_number (1));
7643 /* It is necessary to set this (additional) argument slot of an
7644 event to nil because keyboard.c protects incompletely processed
7645 event from being garbage collected by placing them in the
7646 kbd_buffer_gcpro vector. */
7649 event_mask
= everyEvent
;
7650 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
7651 event_mask
-= highLevelEventMask
;
7653 #if USE_CARBON_EVENTS
7654 rneResult
= ReceiveNextEvent (0, NULL
,
7656 ? TicksToEventTime (app_sleep_time
)
7658 kEventRemoveFromQueue
, &eventRef
);
7661 /* Handle new events */
7662 if (!mac_convert_event_ref (eventRef
, &er
))
7663 switch (GetEventClass (eventRef
))
7665 case kEventClassMouse
:
7666 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
7670 WindowPtr window_ptr
= FrontNonFloatingWindow ();
7671 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7672 if (!IsValidWindowPtr (window_ptr
))
7679 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
7680 typeSInt32
, NULL
, sizeof (SInt32
),
7682 GetEventParameter(eventRef
, kEventParamMouseLocation
,
7683 typeQDPoint
, NULL
, sizeof (Point
),
7685 bufp
->kind
= MOUSE_WHEEL_EVENT
;
7687 bufp
->modifiers
= mac_event_to_emacs_modifiers(eventRef
);
7688 SetPort (GetWindowPort (window_ptr
));
7689 GlobalToLocal (&point
);
7690 XSETINT (bufp
->x
, point
.h
);
7691 XSETINT (bufp
->y
, point
.v
);
7692 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7693 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
7697 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7701 /* Send the event to the appropriate receiver. */
7702 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7706 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
7707 #endif /* USE_CARBON_EVENTS */
7713 WindowPtr window_ptr
= FrontWindow ();
7716 #if USE_CARBON_EVENTS
7717 /* This is needed to send mouse events like aqua window buttons
7718 to the correct handler. */
7719 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
7723 if (!is_emacs_window(window_ptr
))
7727 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
7728 && er
.what
== mouseUp
)
7730 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7731 Point mouse_loc
= er
.where
;
7733 /* Convert to local coordinates of new window. */
7734 #if TARGET_API_MAC_CARBON
7735 SetPort (GetWindowPort (window_ptr
));
7737 SetPort (window_ptr
);
7740 GlobalToLocal (&mouse_loc
);
7742 #if USE_CARBON_EVENTS
7743 bufp
->code
= mac_get_mouse_btn (eventRef
);
7745 bufp
->code
= 0; /* only one mouse button */
7747 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
7748 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
7749 bufp
->part
= scroll_bar_handle
;
7750 #if USE_CARBON_EVENTS
7751 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7753 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7755 bufp
->modifiers
|= up_modifier
;
7756 bufp
->timestamp
= er
.when
* (1000 / 60);
7757 /* ticks to milliseconds */
7759 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
7760 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
7761 tracked_scroll_bar
->dragging
= Qnil
;
7762 mouse_tracking_in_progress
= mouse_tracking_none
;
7763 tracked_scroll_bar
= NULL
;
7768 part_code
= FindWindow (er
.where
, &window_ptr
);
7774 struct frame
*f
= ((mac_output
*)
7775 GetWRefCon (FrontWindow ()))->mFP
;
7776 saved_menu_event_location
= er
.where
;
7777 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
7778 XSETFRAME (bufp
->frame_or_window
, f
);
7784 if (window_ptr
!= FrontWindow ())
7785 SelectWindow (window_ptr
);
7788 SInt16 control_part_code
;
7790 struct mac_output
*mwp
= (mac_output
*)
7791 GetWRefCon (window_ptr
);
7792 Point mouse_loc
= er
.where
;
7794 /* convert to local coordinates of new window */
7795 #if TARGET_API_MAC_CARBON
7796 SetPort (GetWindowPort (window_ptr
));
7798 SetPort (window_ptr
);
7801 GlobalToLocal (&mouse_loc
);
7802 #if TARGET_API_MAC_CARBON
7803 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
7804 &control_part_code
);
7806 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
7809 #if USE_CARBON_EVENTS
7810 bufp
->code
= mac_get_mouse_btn (eventRef
);
7812 bufp
->code
= 0; /* only one mouse button */
7814 XSETINT (bufp
->x
, mouse_loc
.h
);
7815 XSETINT (bufp
->y
, mouse_loc
.v
);
7816 bufp
->timestamp
= er
.when
* (1000 / 60);
7817 /* ticks to milliseconds */
7819 #if TARGET_API_MAC_CARBON
7822 if (control_part_code
!= 0)
7825 struct scroll_bar
*bar
= (struct scroll_bar
*)
7826 GetControlReference (ch
);
7827 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
7829 if (er
.what
== mouseDown
7830 && control_part_code
== kControlIndicatorPart
)
7832 mouse_tracking_in_progress
7833 = mouse_tracking_scroll_bar
;
7834 tracked_scroll_bar
= bar
;
7838 mouse_tracking_in_progress
= mouse_tracking_none
;
7839 tracked_scroll_bar
= NULL
;
7844 bufp
->kind
= MOUSE_CLICK_EVENT
;
7845 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7846 if (er
.what
== mouseDown
)
7847 mouse_tracking_in_progress
7848 = mouse_tracking_mouse_movement
;
7850 mouse_tracking_in_progress
= mouse_tracking_none
;
7853 #if USE_CARBON_EVENTS
7854 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7856 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7862 bufp
->modifiers
|= down_modifier
;
7865 bufp
->modifiers
|= up_modifier
;
7874 #if TARGET_API_MAC_CARBON
7878 GetQDGlobalsScreenBits (&bm
);
7879 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
7881 #else /* not TARGET_API_MAC_CARBON */
7882 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
7883 #endif /* not TARGET_API_MAC_CARBON */
7887 if (TrackGoAway (window_ptr
, er
.where
))
7889 bufp
->kind
= DELETE_WINDOW_EVENT
;
7890 XSETFRAME (bufp
->frame_or_window
,
7891 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
7896 /* window resize handling added --ben */
7898 do_grow_window(window_ptr
, &er
);
7901 /* window zoom handling added --ben */
7904 if (TrackBox (window_ptr
, er
.where
, part_code
))
7905 do_zoom_window (window_ptr
, part_code
);
7917 #if USE_CARBON_EVENTS
7918 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
7926 int keycode
= (er
.message
& keyCodeMask
) >> 8;
7929 #if USE_CARBON_EVENTS
7930 /* When using Carbon Events, we need to pass raw keyboard events
7931 to the TSM ourselves. If TSM handles it, it will pass back
7932 noErr, otherwise it will pass back "eventNotHandledErr" and
7933 we can process it normally. */
7934 if ((!NILP (Vmac_pass_command_to_system
)
7935 || !(er
.modifiers
& cmdKey
))
7936 && (!NILP (Vmac_pass_control_to_system
)
7937 || !(er
.modifiers
& controlKey
)))
7940 err
= SendEventToEventTarget (eventRef
,
7941 GetEventDispatcherTarget ());
7942 if (err
!= eventNotHandledErr
)
7947 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
7956 if (keycode_to_xkeysym (keycode
, &xkeysym
))
7958 bufp
->code
= 0xff00 | xkeysym
;
7959 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
7963 if (er
.modifiers
& (controlKey
|
7964 (NILP (Vmac_command_key_is_meta
) ? optionKey
7967 /* This code comes from Keyboard Resource, Appendix
7968 C of IM - Text. This is necessary since shift is
7969 ignored in KCHR table translation when option or
7970 command is pressed. It also does not translate
7971 correctly control-shift chars like C-% so mask off
7973 int new_modifiers
= er
.modifiers
& 0xe600;
7974 /* mask off option and command */
7975 int new_keycode
= keycode
| new_modifiers
;
7976 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
7977 unsigned long some_state
= 0;
7978 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
7979 &some_state
) & 0xff;
7982 bufp
->code
= er
.message
& charCodeMask
;
7983 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
7987 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
7988 convert non-ASCII characters typed at the Mac keyboard
7989 (presumed to be in the Mac Roman encoding) to iso-latin-1
7990 encoding before they are passed to Emacs. This enables the
7991 Mac keyboard to be used to enter non-ASCII iso-latin-1
7992 characters directly. */
7993 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
7994 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
7996 static TECObjectRef converter
= NULL
;
7997 OSStatus the_err
= noErr
;
7998 OSStatus convert_status
= noErr
;
8000 if (converter
== NULL
)
8002 the_err
= TECCreateConverter (&converter
,
8003 kTextEncodingMacRoman
,
8004 mac_keyboard_text_encoding
);
8005 current_mac_keyboard_text_encoding
8006 = mac_keyboard_text_encoding
;
8008 else if (mac_keyboard_text_encoding
8009 != current_mac_keyboard_text_encoding
)
8011 /* Free the converter for the current encoding before
8012 creating a new one. */
8013 TECDisposeConverter (converter
);
8014 the_err
= TECCreateConverter (&converter
,
8015 kTextEncodingMacRoman
,
8016 mac_keyboard_text_encoding
);
8017 current_mac_keyboard_text_encoding
8018 = mac_keyboard_text_encoding
;
8021 if (the_err
== noErr
)
8023 unsigned char ch
= bufp
->code
;
8024 ByteCount actual_input_length
, actual_output_length
;
8025 unsigned char outch
;
8027 convert_status
= TECConvertText (converter
, &ch
, 1,
8028 &actual_input_length
,
8030 &actual_output_length
);
8031 if (convert_status
== noErr
8032 && actual_input_length
== 1
8033 && actual_output_length
== 1)
8038 #if USE_CARBON_EVENTS
8039 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8041 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8046 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8047 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
8050 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8055 case kHighLevelEvent
:
8056 drag_and_drop_file_list
= Qnil
;
8058 AEProcessAppleEvent(&er
);
8060 /* Build a DRAG_N_DROP_EVENT type event as is done in
8061 constuct_drag_n_drop in w32term.c. */
8062 if (!NILP (drag_and_drop_file_list
))
8064 struct frame
*f
= NULL
;
8068 wp
= FrontNonFloatingWindow ();
8072 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8073 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8074 wp
= FrontNonFloatingWindow ();
8077 if (wp
&& is_emacs_window(wp
))
8078 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8080 bufp
->kind
= DRAG_N_DROP_EVENT
;
8082 bufp
->timestamp
= er
.when
* (1000 / 60);
8083 /* ticks to milliseconds */
8084 #if USE_CARBON_EVENTS
8085 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8087 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8090 XSETINT (bufp
->x
, 0);
8091 XSETINT (bufp
->y
, 0);
8093 XSETFRAME (frame
, f
);
8094 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8096 /* Regardless of whether Emacs was suspended or in the
8097 foreground, ask it to redraw its entire screen.
8098 Otherwise parts of the screen can be left in an
8099 inconsistent state. */
8101 #if TARGET_API_MAC_CARBON
8105 GetWindowPortBounds (wp
, &r
);
8106 InvalWindowRect (wp
, &r
);
8108 #else /* not TARGET_API_MAC_CARBON */
8109 InvalRect (&(wp
->portRect
));
8110 #endif /* not TARGET_API_MAC_CARBON */
8117 #if USE_CARBON_EVENTS
8118 ReleaseEvent (eventRef
);
8122 /* If the focus was just given to an autoraising frame,
8124 /* ??? This ought to be able to handle more than one such frame. */
8125 if (pending_autoraise_frame
)
8127 x_raise_frame (pending_autoraise_frame
);
8128 pending_autoraise_frame
= 0;
8131 #if !TARGET_API_MAC_CARBON
8132 check_alarm (); /* simulate the handling of a SIGALRM */
8136 static Point old_mouse_pos
= { -1, -1 };
8138 if (app_is_suspended
)
8140 old_mouse_pos
.h
= -1;
8141 old_mouse_pos
.v
= -1;
8149 struct scroll_bar
*sb
;
8151 wp
= FrontWindow ();
8152 if (is_emacs_window (wp
))
8154 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8156 #if TARGET_API_MAC_CARBON
8157 SetPort (GetWindowPort (wp
));
8162 GetMouse (&mouse_pos
);
8164 if (!EqualPt (mouse_pos
, old_mouse_pos
))
8166 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8167 && tracked_scroll_bar
)
8168 x_scroll_bar_note_movement (tracked_scroll_bar
,
8170 - XINT (tracked_scroll_bar
->top
),
8171 TickCount() * (1000 / 60));
8173 note_mouse_movement (f
, &mouse_pos
);
8175 old_mouse_pos
= mouse_pos
;
8187 /* Need to override CodeWarrior's input function so no conversion is
8188 done on newlines Otherwise compiled functions in .elc files will be
8189 read incorrectly. Defined in ...:MSL C:MSL
8190 Common:Source:buffer_io.c. */
8193 __convert_to_newlines (unsigned char * p
, size_t * n
)
8199 __convert_from_newlines (unsigned char * p
, size_t * n
)
8206 /* Initialize the struct pointed to by MW to represent a new COLS x
8207 ROWS Macintosh window, using font with name FONTNAME and size
8210 NewMacWindow (FRAME_PTR fp
)
8213 #if TARGET_API_MAC_CARBON
8214 static int making_terminal_window
= 0;
8216 static int making_terminal_window
= 1;
8219 mwp
= fp
->output_data
.mac
;
8221 if (making_terminal_window
)
8223 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8226 making_terminal_window
= 0;
8229 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8232 SetWRefCon (mwp
->mWP
, (long) mwp
);
8233 /* so that update events can find this mac_output struct */
8234 mwp
->mFP
= fp
; /* point back to emacs frame */
8236 #if TARGET_API_MAC_CARBON
8237 SetPort (GetWindowPort (mwp
->mWP
));
8244 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8245 ShowWindow (mwp
->mWP
);
8251 make_mac_frame (struct frame
*f
)
8253 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8254 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8256 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8260 f
->output_data
.mac
->cursor_pixel
= 0;
8261 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8262 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8263 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8265 FRAME_FONTSET (f
) = -1;
8266 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8267 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8268 f
->output_data
.mac
->explicit_parent
= 0;
8271 f
->border_width
= 0;
8273 f
->internal_border_width
= 0;
8275 f
->output_method
= output_mac
;
8280 f
->new_text_cols
= 0;
8281 f
->new_text_lines
= 0;
8285 make_mac_terminal_frame (struct frame
*f
)
8289 XSETFRAME (frame
, f
);
8291 f
->output_method
= output_mac
;
8292 f
->output_data
.mac
= (struct mac_output
*)
8293 xmalloc (sizeof (struct mac_output
));
8294 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8295 FRAME_FONTSET (f
) = -1;
8296 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8297 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8299 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8301 FRAME_COLS (f
) = 96;
8302 FRAME_LINES (f
) = 4;
8308 /* Need to be initialized for unshow_buffer in window.c. */
8309 selected_window
= f
->selected_window
;
8311 Fmodify_frame_parameters (frame
,
8312 Fcons (Fcons (Qfont
,
8313 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8314 Fmodify_frame_parameters (frame
,
8315 Fcons (Fcons (Qforeground_color
,
8316 build_string ("black")), Qnil
));
8317 Fmodify_frame_parameters (frame
,
8318 Fcons (Fcons (Qbackground_color
,
8319 build_string ("white")), Qnil
));
8323 /***********************************************************************
8325 ***********************************************************************/
8327 #ifdef USE_X_TOOLKIT
8328 static XrmOptionDescRec emacs_options
[] = {
8329 {"-geometry", ".geometry", XrmoptionSepArg
, NULL
},
8330 {"-iconic", ".iconic", XrmoptionNoArg
, (XtPointer
) "yes"},
8332 {"-internal-border-width", "*EmacsScreen.internalBorderWidth",
8333 XrmoptionSepArg
, NULL
},
8334 {"-ib", "*EmacsScreen.internalBorderWidth", XrmoptionSepArg
, NULL
},
8336 {"-T", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8337 {"-wn", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8338 {"-title", "*EmacsShell.title", XrmoptionSepArg
, (XtPointer
) NULL
},
8339 {"-iconname", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
8340 {"-in", "*EmacsShell.iconName", XrmoptionSepArg
, (XtPointer
) NULL
},
8341 {"-mc", "*pointerColor", XrmoptionSepArg
, (XtPointer
) NULL
},
8342 {"-cr", "*cursorColor", XrmoptionSepArg
, (XtPointer
) NULL
}
8344 #endif /* USE_X_TOOLKIT */
8347 /* Test whether two display-name strings agree up to the dot that separates
8348 the screen number from the server number. */
8350 same_x_server (name1
, name2
)
8351 char *name1
, *name2
;
8354 unsigned char *system_name
= SDATA (Vsystem_name
);
8355 int system_name_length
= strlen (system_name
);
8356 int length_until_period
= 0;
8358 while (system_name
[length_until_period
] != 0
8359 && system_name
[length_until_period
] != '.')
8360 length_until_period
++;
8362 /* Treat `unix' like an empty host name. */
8363 if (! strncmp (name1
, "unix:", 5))
8365 if (! strncmp (name2
, "unix:", 5))
8367 /* Treat this host's name like an empty host name. */
8368 if (! strncmp (name1
, system_name
, system_name_length
)
8369 && name1
[system_name_length
] == ':')
8370 name1
+= system_name_length
;
8371 if (! strncmp (name2
, system_name
, system_name_length
)
8372 && name2
[system_name_length
] == ':')
8373 name2
+= system_name_length
;
8374 /* Treat this host's domainless name like an empty host name. */
8375 if (! strncmp (name1
, system_name
, length_until_period
)
8376 && name1
[length_until_period
] == ':')
8377 name1
+= length_until_period
;
8378 if (! strncmp (name2
, system_name
, length_until_period
)
8379 && name2
[length_until_period
] == ':')
8380 name2
+= length_until_period
;
8382 for (; *name1
!= '\0' && *name1
== *name2
; name1
++, name2
++)
8386 if (seen_colon
&& *name1
== '.')
8390 && (*name1
== '.' || *name1
== '\0')
8391 && (*name2
== '.' || *name2
== '\0'));
8395 int mac_initialized
= 0;
8398 mac_initialize_display_info ()
8400 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8401 GDHandle main_device_handle
;
8403 bzero (dpyinfo
, sizeof (*dpyinfo
));
8405 /* Put it on x_display_name_list. */
8406 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8407 x_display_name_list
);
8408 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8411 dpyinfo
->mac_id_name
8412 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8413 + SCHARS (Vsystem_name
)
8415 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8416 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8418 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8419 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8422 main_device_handle
= LMGetMainDevice();
8424 dpyinfo
->reference_count
= 0;
8425 dpyinfo
->resx
= 75.0;
8426 dpyinfo
->resy
= 75.0;
8427 dpyinfo
->n_planes
= 1;
8428 dpyinfo
->n_cbits
= 16;
8429 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8430 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8431 dpyinfo
->grabbed
= 0;
8432 dpyinfo
->root_window
= NULL
;
8434 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8435 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8436 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8437 dpyinfo
->mouse_face_window
= Qnil
;
8440 struct mac_display_info
*
8441 mac_term_init (display_name
, xrm_option
, resource_name
)
8442 Lisp_Object display_name
;
8444 char *resource_name
;
8446 struct mac_display_info
*dpyinfo
;
8447 GDHandle main_device_handle
;
8449 if (!mac_initialized
)
8452 mac_initialized
= 1;
8455 mac_initialize_display_info (display_name
);
8457 dpyinfo
= &one_mac_display_info
;
8459 main_device_handle
= LMGetMainDevice();
8461 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8462 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8471 extern int inhibit_window_system
;
8472 extern int noninteractive
;
8473 CFBundleRef appsBundle
;
8476 /* No need to test if already -nw*/
8477 if (inhibit_window_system
|| noninteractive
)
8480 appsBundle
= CFBundleGetMainBundle();
8481 if (appsBundle
!= NULL
)
8483 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
8484 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
8485 /* We found the bundle identifier, now we know we are valid. */
8492 /* MAC_TODO: Have this start the bundled executable */
8494 /* For now, prevent the fatal error by bringing it up in the terminal */
8495 inhibit_window_system
= 1;
8499 MakeMeTheFrontProcess ()
8501 ProcessSerialNumber psn
;
8504 err
= GetCurrentProcess (&psn
);
8506 (void) SetFrontProcess (&psn
);
8509 /***** Code to handle C-g testing *****/
8511 /* Contains the Mac modifier formed from quit_char */
8512 static mac_quit_char_modifiers
= 0;
8513 static mac_quit_char_keycode
;
8514 extern int quit_char
;
8517 mac_determine_quit_char_modifiers()
8519 /* Todo: Determine modifiers from quit_char. */
8520 UInt32 qc_modifiers
= ctrl_modifier
;
8523 mac_quit_char_modifiers
= 0;
8524 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
8525 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
8526 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
8527 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
8531 init_quit_char_handler ()
8533 /* TODO: Let this support keys other the 'g' */
8534 mac_quit_char_keycode
= 5;
8535 /* Look at <architecture/adb_kb_map.h> for details */
8536 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
8538 mac_determine_quit_char_modifiers();
8542 quit_char_comp (EventRef inEvent
, void *inCompData
)
8544 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
8546 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
8550 UInt32 keyModifiers
;
8551 GetEventParameter(inEvent
, kEventParamKeyCode
,
8552 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
8553 if (keyCode
!= mac_quit_char_keycode
)
8555 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
8556 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
8557 if (keyModifiers
!= mac_quit_char_modifiers
)
8564 mac_check_for_quit_char ()
8567 static EMACS_TIME last_check_time
= { 0, 0 };
8568 static EMACS_TIME one_second
= { 1, 0 };
8571 /* If windows are not initialized, return immediately (keep it bouncin'). */
8572 if (!mac_quit_char_modifiers
)
8575 /* Don't check if last check is less than a second ago. */
8576 EMACS_GET_TIME (now
);
8577 EMACS_SUB_TIME (t
, now
, last_check_time
);
8578 if (EMACS_TIME_LT (t
, one_second
))
8580 last_check_time
= now
;
8582 /* Redetermine modifiers because they are based on lisp variables */
8583 mac_determine_quit_char_modifiers ();
8585 /* Fill the queue with events */
8586 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
8587 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
8591 struct input_event e
;
8592 struct mac_output
*mwp
=
8593 (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8594 /* Use an input_event to emulate what the interrupt handler does. */
8595 e
.kind
= ASCII_KEYSTROKE_EVENT
;
8599 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
8600 XSETFRAME (e
.frame_or_window
, mwp
->mFP
);
8601 /* Remove event from queue to prevent looping. */
8602 RemoveEventFromQueue (GetMainEventQueue (), event
);
8603 ReleaseEvent (event
);
8604 kbd_buffer_store_event (&e
);
8608 #endif /* MAC_OSX */
8610 /* Set up use of X before we make the first connection. */
8612 extern frame_parm_handler mac_frame_parm_handlers
[];
8614 static struct redisplay_interface x_redisplay_interface
=
8616 mac_frame_parm_handlers
,
8620 x_clear_end_of_line
,
8622 x_after_update_window_line
,
8623 x_update_window_begin
,
8624 x_update_window_end
,
8628 x_clear_window_mouse_face
,
8629 x_get_glyph_overhangs
,
8630 x_fix_overlapping_area
,
8631 x_draw_fringe_bitmap
,
8632 mac_per_char_metric
,
8634 NULL
, /* mac_compute_glyph_string_overhangs */
8635 x_draw_glyph_string
,
8636 mac_define_frame_cursor
,
8637 mac_clear_frame_area
,
8638 mac_draw_window_cursor
,
8639 mac_draw_vertical_window_border
,
8640 mac_shift_glyphs_for_insert
8646 rif
= &x_redisplay_interface
;
8648 clear_frame_hook
= x_clear_frame
;
8649 ins_del_lines_hook
= x_ins_del_lines
;
8650 delete_glyphs_hook
= x_delete_glyphs
;
8651 ring_bell_hook
= XTring_bell
;
8652 reset_terminal_modes_hook
= XTreset_terminal_modes
;
8653 set_terminal_modes_hook
= XTset_terminal_modes
;
8654 update_begin_hook
= x_update_begin
;
8655 update_end_hook
= x_update_end
;
8656 set_terminal_window_hook
= XTset_terminal_window
;
8657 read_socket_hook
= XTread_socket
;
8658 frame_up_to_date_hook
= XTframe_up_to_date
;
8659 mouse_position_hook
= XTmouse_position
;
8660 frame_rehighlight_hook
= XTframe_rehighlight
;
8661 frame_raise_lower_hook
= XTframe_raise_lower
;
8663 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
8664 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
8665 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
8666 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
8668 scroll_region_ok
= 1; /* we'll scroll partial frames */
8669 char_ins_del_ok
= 1;
8670 line_ins_del_ok
= 1; /* we'll just blt 'em */
8671 fast_clear_end_of_line
= 1; /* X does this well */
8672 memory_below_frame
= 0; /* we don't remember what scrolls
8677 last_tool_bar_item
= -1;
8678 any_help_event_p
= 0;
8680 /* Try to use interrupt input; if we can't, then start polling. */
8681 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
8683 #ifdef USE_X_TOOLKIT
8684 XtToolkitInitialize ();
8685 Xt_app_con
= XtCreateApplicationContext ();
8686 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
8688 /* Install an asynchronous timer that processes Xt timeout events
8689 every 0.1s. This is necessary because some widget sets use
8690 timeouts internally, for example the LessTif menu bar, or the
8691 Xaw3d scroll bar. When Xt timouts aren't processed, these
8692 widgets don't behave normally. */
8694 EMACS_TIME interval
;
8695 EMACS_SET_SECS_USECS (interval
, 0, 100000);
8696 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
8700 #if USE_TOOLKIT_SCROLL_BARS
8701 xaw3d_arrow_scroll
= False
;
8702 xaw3d_pick_top
= True
;
8706 /* Note that there is no real way portable across R3/R4 to get the
8707 original error handler. */
8708 XSetErrorHandler (x_error_handler
);
8709 XSetIOErrorHandler (x_io_error_quitter
);
8711 /* Disable Window Change signals; they are handled by X events. */
8713 signal (SIGWINCH
, SIG_DFL
);
8714 #endif /* ! defined (SIGWINCH) */
8716 signal (SIGPIPE
, x_connection_signal
);
8719 mac_initialize_display_info ();
8721 #if TARGET_API_MAC_CARBON
8722 init_required_apple_events ();
8724 init_mac_drag_n_drop ();
8726 #if USE_CARBON_EVENTS
8727 init_service_handler ();
8729 init_quit_char_handler ();
8732 DisableMenuCommand (NULL
, kHICommandQuit
);
8734 if (!inhibit_window_system
)
8735 MakeMeTheFrontProcess ();
8744 staticpro (&x_error_message_string
);
8745 x_error_message_string
= Qnil
;
8748 Fprovide (intern ("mac-carbon"), Qnil
);
8750 staticpro (&x_display_name_list
);
8751 x_display_name_list
= Qnil
;
8753 staticpro (&last_mouse_scroll_bar
);
8754 last_mouse_scroll_bar
= Qnil
;
8756 staticpro (&Qvendor_specific_keysyms
);
8757 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
8759 staticpro (&last_mouse_press_frame
);
8760 last_mouse_press_frame
= Qnil
;
8762 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
8763 staticpro (&Qmac_ready_for_drag_n_drop
);
8765 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
8766 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
8767 x_autoselect_window_p
= 0;
8769 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
8770 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
8771 Vx_toolkit_scroll_bars
= Qt
;
8773 DEFVAR_BOOL ("x-use-underline-position-properties",
8774 &x_use_underline_position_properties
,
8775 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
8776 nil means ignore them. If you encounter fonts with bogus
8777 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
8778 to 4.1, set this to nil. */);
8779 x_use_underline_position_properties
= 0;
8781 staticpro (&last_mouse_motion_frame
);
8782 last_mouse_motion_frame
= Qnil
;
8784 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
8785 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
8786 Otherwise the option key is used. */);
8787 Vmac_command_key_is_meta
= Qt
;
8789 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
8790 doc
: /* Non-nil means that the control and meta keys are reversed. This is
8791 useful for non-standard keyboard layouts. */);
8792 Vmac_reverse_ctrl_meta
= Qnil
;
8794 #if USE_CARBON_EVENTS
8795 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
8796 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
8797 the right click will be mouse-3.
8798 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
8799 Vmac_wheel_button_is_mouse_2
= Qt
;
8801 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
8802 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
8803 Toolbox for processing before Emacs sees it. */);
8804 Vmac_pass_command_to_system
= Qt
;
8806 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
8807 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
8808 Toolbox for processing before Emacs sees it. */);
8809 Vmac_pass_control_to_system
= Qt
;
8812 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
8813 doc
: /* One of the Text Encoding Base constant values defined in the
8814 Basic Text Constants section of Inside Macintosh - Text Encoding
8815 Conversion Manager. Its value determines the encoding characters
8816 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
8817 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
8818 its default value, no conversion takes place. If it is set to
8819 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
8820 characters typed on Mac keyboard are first converted into the
8821 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
8822 passed to Emacs. Together with Emacs's set-keyboard-coding-system
8823 command, this enables the Mac keyboard to be used to enter non-ASCII
8824 characters directly. */);
8825 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;