1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 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"
38 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
39 obtain events from the event queue. If set to 0, WaitNextEvent is
41 #define USE_CARBON_EVENTS 1
42 #else /* not MAC_OSX */
43 #include <Quickdraw.h>
44 #include <ToolUtils.h>
48 #include <Resources.h>
50 #include <TextUtils.h>
54 #if defined (__MRC__) || (__MSL__ >= 0x6000)
55 #include <ControlDefinitions.h>
61 #endif /* not MAC_OSX */
75 #include "dispextern.h"
77 #include "termhooks.h"
84 #include "intervals.h"
85 #include "composite.h"
88 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
89 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
90 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
91 #define macShiftKey (shiftKey)
92 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
93 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
95 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
99 /* Non-nil means Emacs uses toolkit scroll bars. */
101 Lisp_Object Vx_toolkit_scroll_bars
;
103 /* Non-zero means that a HELP_EVENT has been generated since Emacs
106 static int any_help_event_p
;
108 /* Non-zero means autoselect window with the mouse cursor. */
110 int x_autoselect_window_p
;
112 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
114 int x_use_underline_position_properties
;
116 /* Non-zero means draw block and hollow cursor as wide as the glyph
117 under it. For example, if a block cursor is over a tab, it will be
118 drawn as wide as that tab on the display. */
121 /* This is a chain of structures for all the X displays currently in
124 struct x_display_info
*x_display_list
;
126 /* This is a list of cons cells, each of the form (NAME
127 . FONT-LIST-CACHE), one for each element of x_display_list and in
128 the same order. NAME is the name of the frame. FONT-LIST-CACHE
129 records previous values returned by x-list-fonts. */
131 Lisp_Object x_display_name_list
;
133 /* This is display since Mac does not support multiple ones. */
134 struct mac_display_info one_mac_display_info
;
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the XT functions.
138 It is zero while not inside an update. In that case, the XT
139 functions assume that `selected_frame' is the frame to apply to. */
141 extern struct frame
*updating_frame
;
143 extern int waiting_for_input
;
145 /* This is a frame waiting to be auto-raised, within XTread_socket. */
147 struct frame
*pending_autoraise_frame
;
149 /* Non-zero means user is interacting with a toolkit scroll bar. */
151 static int toolkit_scroll_bar_interaction
;
155 Formerly, we used PointerMotionHintMask (in standard_event_mask)
156 so that we would have to call XQueryPointer after each MotionNotify
157 event to ask for another such event. However, this made mouse tracking
158 slow, and there was a bug that made it eventually stop.
160 Simply asking for MotionNotify all the time seems to work better.
162 In order to avoid asking for motion events and then throwing most
163 of them away or busy-polling the server for mouse positions, we ask
164 the server for pointer motion hints. This means that we get only
165 one event per group of mouse movements. "Groups" are delimited by
166 other kinds of events (focus changes and button clicks, for
167 example), or by XQueryPointer calls; when one of these happens, we
168 get another MotionNotify event the next time the mouse moves. This
169 is at least as efficient as getting motion events when mouse
170 tracking is on, and I suspect only negligibly worse when tracking
173 /* Where the mouse was last time we reported a mouse event. */
175 static Rect last_mouse_glyph
;
176 static Lisp_Object last_mouse_press_frame
;
178 /* The scroll bar in which the last X motion event occurred.
180 If the last X motion event occurred in a scroll bar, we set this so
181 XTmouse_position can know whether to report a scroll bar motion or
184 If the last X motion event didn't occur in a scroll bar, we set
185 this to Qnil, to tell XTmouse_position to return an ordinary motion
188 static Lisp_Object last_mouse_scroll_bar
;
190 /* This is a hack. We would really prefer that XTmouse_position would
191 return the time associated with the position it returns, but there
192 doesn't seem to be any way to wrest the time-stamp from the server
193 along with the position query. So, we just keep track of the time
194 of the last movement we received, and return that in hopes that
195 it's somewhat accurate. */
197 static Time last_mouse_movement_time
;
199 struct scroll_bar
*tracked_scroll_bar
= NULL
;
201 /* Incremented by XTread_socket whenever it really tries to read
205 static int volatile input_signal_count
;
207 static int input_signal_count
;
210 /* Used locally within XTread_socket. */
212 static int x_noop_count
;
214 /* Initial values of argv and argc. */
216 extern char **initial_argv
;
217 extern int initial_argc
;
219 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
221 /* Tells if a window manager is present or not. */
223 extern Lisp_Object Vx_no_window_manager
;
227 /* A mask of extra modifier bits to put into every keyboard char. */
229 extern int extra_keyboard_modifiers
;
231 /* The keysyms to use for the various modifiers. */
233 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
235 static Lisp_Object Qvendor_specific_keysyms
;
238 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
241 extern int inhibit_window_system
;
244 QDGlobals qd
; /* QuickDraw global information structure. */
248 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
249 struct mac_display_info
*mac_display_info_for_display (Display
*);
250 static void x_update_window_end
P_ ((struct window
*, int, int));
251 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
252 static int x_io_error_quitter
P_ ((Display
*));
253 int x_catch_errors
P_ ((Display
*));
254 void x_uncatch_errors
P_ ((Display
*, int));
255 void x_lower_frame
P_ ((struct frame
*));
256 void x_scroll_bar_clear
P_ ((struct frame
*));
257 int x_had_errors_p
P_ ((Display
*));
258 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
259 void x_raise_frame
P_ ((struct frame
*));
260 void x_set_window_size
P_ ((struct frame
*, int, int, int));
261 void x_wm_set_window_state
P_ ((struct frame
*, int));
262 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
263 void mac_initialize
P_ ((void));
264 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
265 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
266 static void x_update_end
P_ ((struct frame
*));
267 static void XTframe_up_to_date
P_ ((struct frame
*));
268 static void XTreassert_line_highlight
P_ ((int, int));
269 static void x_change_line_highlight
P_ ((int, int, int, int));
270 static void XTset_terminal_modes
P_ ((void));
271 static void XTreset_terminal_modes
P_ ((void));
272 static void x_clear_frame
P_ ((void));
273 static void frame_highlight
P_ ((struct frame
*));
274 static void frame_unhighlight
P_ ((struct frame
*));
275 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
276 static void XTframe_rehighlight
P_ ((struct frame
*));
277 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
278 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
279 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
280 enum text_cursor_kinds
));
282 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
283 static void x_flush
P_ ((struct frame
*f
));
284 static void x_update_begin
P_ ((struct frame
*));
285 static void x_update_window_begin
P_ ((struct window
*));
286 static void x_after_update_window_line
P_ ((struct glyph_row
*));
288 void activate_scroll_bars (FRAME_PTR
);
289 void deactivate_scroll_bars (FRAME_PTR
);
291 static int is_emacs_window (WindowPtr
);
293 int x_bitmap_icon (struct frame
*, Lisp_Object
);
294 void x_make_frame_visible (struct frame
*);
296 extern void window_scroll (Lisp_Object
, int, int, int);
298 /* Defined in macmenu.h. */
299 extern void menubar_selection_callback (FRAME_PTR
, int);
300 extern void set_frame_menubar (FRAME_PTR
, int, int);
302 /* X display function emulation */
305 XFreePixmap (display
, pixmap
)
306 Display
*display
; /* not used */
309 DisposeGWorld (pixmap
);
313 /* Set foreground color for subsequent QuickDraw commands. Assume
314 graphic port has already been set. */
317 mac_set_forecolor (unsigned long color
)
321 fg_color
.red
= RED16_FROM_ULONG (color
);
322 fg_color
.green
= GREEN16_FROM_ULONG (color
);
323 fg_color
.blue
= BLUE16_FROM_ULONG (color
);
325 RGBForeColor (&fg_color
);
329 /* Set background color for subsequent QuickDraw commands. Assume
330 graphic port has already been set. */
333 mac_set_backcolor (unsigned long color
)
337 bg_color
.red
= RED16_FROM_ULONG (color
);
338 bg_color
.green
= GREEN16_FROM_ULONG (color
);
339 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
341 RGBBackColor (&bg_color
);
344 /* Set foreground and background color for subsequent QuickDraw
345 commands. Assume that the graphic port has already been set. */
348 mac_set_colors (GC gc
)
350 mac_set_forecolor (gc
->foreground
);
351 mac_set_backcolor (gc
->background
);
354 /* Mac version of XDrawLine. */
357 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
363 SetPortWindowPort (w
);
372 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
381 GetGWorld (&old_port
, &old_gdh
);
386 LockPixels (GetGWorldPixMap (p
));
389 UnlockPixels (GetGWorldPixMap (p
));
391 SetGWorld (old_port
, old_gdh
);
394 /* Mac version of XClearArea. */
397 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
401 unsigned int width
, height
;
404 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
408 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
409 xgc
.background
= mwp
->x_compatible
.background_pixel
;
411 SetPortWindowPort (w
);
413 mac_set_colors (&xgc
);
414 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
419 /* Mac version of XClearWindow. */
422 XClearWindow (display
, w
)
426 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
429 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
430 xgc
.background
= mwp
->x_compatible
.background_pixel
;
432 SetPortWindowPort (w
);
434 mac_set_colors (&xgc
);
436 #if TARGET_API_MAC_CARBON
440 GetWindowPortBounds (w
, &r
);
443 #else /* not TARGET_API_MAC_CARBON */
444 EraseRect (&(w
->portRect
));
445 #endif /* not TARGET_API_MAC_CARBON */
449 /* Mac replacement for XCopyArea. */
452 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
456 int x
, y
, width
, height
;
457 unsigned short *bits
;
463 bitmap
.rowBytes
= sizeof(unsigned short);
464 bitmap
.baseAddr
= (char *)bits
;
465 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
467 SetPortWindowPort (w
);
470 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
472 #if TARGET_API_MAC_CARBON
473 LockPortBits (GetWindowPort (w
));
474 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
475 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
476 UnlockPortBits (GetWindowPort (w
));
477 #else /* not TARGET_API_MAC_CARBON */
478 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
479 overlay_p
? srcOr
: srcCopy
, 0);
480 #endif /* not TARGET_API_MAC_CARBON */
484 /* Mac replacement for XSetClipRectangles. */
487 mac_set_clip_rectangle (display
, w
, r
)
492 SetPortWindowPort (w
);
498 /* Mac replacement for XSetClipMask. */
501 mac_reset_clipping (display
, w
)
507 SetPortWindowPort (w
);
509 SetRect (&r
, -32767, -32767, 32767, 32767);
514 /* XBM bits seem to be backward within bytes compared with how
521 unsigned char reflected
= 0x00;
522 for (i
= 0; i
< 8; i
++)
524 if (orig
& (0x01 << i
))
525 reflected
|= 0x80 >> i
;
531 /* Mac replacement for XCreateBitmapFromBitmapData. */
534 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
542 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
543 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
544 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
545 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
546 for (i
= 0; i
< h
; i
++)
548 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
549 for (j
= 0; j
< w1
; j
++)
550 *p
++ = reflect_byte (*bits
++);
553 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
558 mac_free_bitmap (bitmap
)
561 xfree (bitmap
->baseAddr
);
566 XCreatePixmap (display
, w
, width
, height
, depth
)
567 Display
*display
; /* not used */
569 unsigned int width
, height
;
570 unsigned int depth
; /* not used */
576 SetPortWindowPort (w
);
578 SetRect (&r
, 0, 0, width
, height
);
579 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
587 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
588 Display
*display
; /* not used */
591 unsigned int width
, height
;
592 unsigned long fg
, bg
;
593 unsigned int depth
; /* not used */
600 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
604 GetGWorld (&old_port
, &old_gdh
);
605 SetGWorld (pixmap
, NULL
);
606 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
607 mac_set_forecolor (fg
);
608 mac_set_backcolor (bg
);
609 LockPixels (GetGWorldPixMap (pixmap
));
610 #if TARGET_API_MAC_CARBON
611 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
612 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
613 #else /* not TARGET_API_MAC_CARBON */
614 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
615 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
616 #endif /* not TARGET_API_MAC_CARBON */
617 UnlockPixels (GetGWorldPixMap (pixmap
));
618 SetGWorld (old_port
, old_gdh
);
619 mac_free_bitmap (&bitmap
);
625 /* Mac replacement for XFillRectangle. */
628 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
633 unsigned int width
, height
;
637 SetPortWindowPort (w
);
640 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
642 PaintRect (&r
); /* using foreground color of gc */
647 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
652 unsigned int width
, height
;
658 GetGWorld (&old_port
, &old_gdh
);
661 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
663 LockPixels (GetGWorldPixMap (p
));
664 PaintRect (&r
); /* using foreground color of gc */
665 UnlockPixels (GetGWorldPixMap (p
));
667 SetGWorld (old_port
, old_gdh
);
671 /* Mac replacement for XDrawRectangle: dest is a window. */
674 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
679 unsigned int width
, height
;
683 SetPortWindowPort (w
);
686 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
688 FrameRect (&r
); /* using foreground color of gc */
692 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
695 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
700 unsigned int width
, height
;
706 GetGWorld (&old_port
, &old_gdh
);
709 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
711 LockPixels (GetGWorldPixMap (p
));
712 FrameRect (&r
); /* using foreground color of gc */
713 UnlockPixels (GetGWorldPixMap (p
));
715 SetGWorld (old_port
, old_gdh
);
720 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
727 int nchars
, mode
, bytes_per_char
;
729 SetPortWindowPort (w
);
733 TextFont (gc
->font
->mac_fontnum
);
734 TextSize (gc
->font
->mac_fontsize
);
735 TextFace (gc
->font
->mac_fontface
);
739 DrawText (buf
, 0, nchars
* bytes_per_char
);
743 /* Mac replacement for XDrawString. */
746 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
754 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
758 /* Mac replacement for XDrawString16. */
761 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
769 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
774 /* Mac replacement for XDrawImageString. */
777 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
785 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
789 /* Mac replacement for XDrawString16. */
792 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
800 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
805 /* Mac replacement for XCopyArea: dest must be window. */
808 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
815 unsigned int width
, height
;
820 SetPortWindowPort (dest
);
822 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
823 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
825 ForeColor (blackColor
);
826 BackColor (whiteColor
);
828 LockPixels (GetGWorldPixMap (src
));
829 #if TARGET_API_MAC_CARBON
830 LockPortBits (GetWindowPort (dest
));
831 CopyBits (GetPortBitMapForCopyBits (src
),
832 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
833 &src_r
, &dest_r
, srcCopy
, 0);
834 UnlockPortBits (GetWindowPort (dest
));
835 #else /* not TARGET_API_MAC_CARBON */
836 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
837 &src_r
, &dest_r
, srcCopy
, 0);
838 #endif /* not TARGET_API_MAC_CARBON */
839 UnlockPixels (GetGWorldPixMap (src
));
844 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
845 width
, height
, dest_x
, dest_y
)
851 unsigned int width
, height
;
856 SetPortWindowPort (dest
);
858 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
859 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
861 ForeColor (blackColor
);
862 BackColor (whiteColor
);
864 LockPixels (GetGWorldPixMap (src
));
865 LockPixels (GetGWorldPixMap (mask
));
866 #if TARGET_API_MAC_CARBON
867 LockPortBits (GetWindowPort (dest
));
868 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
869 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
870 &src_r
, &src_r
, &dest_r
);
871 UnlockPortBits (GetWindowPort (dest
));
872 #else /* not TARGET_API_MAC_CARBON */
873 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
874 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
875 #endif /* not TARGET_API_MAC_CARBON */
876 UnlockPixels (GetGWorldPixMap (mask
));
877 UnlockPixels (GetGWorldPixMap (src
));
882 /* Convert a pair of local coordinates to global (screen) coordinates.
883 Assume graphic port has been properly set. */
885 local_to_global_coord (short *h
, short *v
)
899 /* Mac replacement for XCopyArea: used only for scrolling. */
902 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
907 unsigned int width
, height
;
910 #if TARGET_API_MAC_CARBON
911 Rect gw_r
, src_r
, dest_r
;
913 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
914 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
916 SetPortWindowPort (w
);
918 ForeColor (blackColor
);
919 BackColor (whiteColor
);
921 LockPortBits (GetWindowPort (w
));
923 const BitMap
*bitmap
= GetPortBitMapForCopyBits (GetWindowPort (w
));
924 CopyBits (bitmap
, bitmap
, &src_r
, &dest_r
, srcCopy
, 0);
926 UnlockPortBits (GetWindowPort (w
));
929 #else /* not TARGET_API_MAC_CARBON */
937 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
938 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
941 /* Need to use global coordinates and screenBits since src and dest
942 areas overlap in general. */
943 local_to_global_coord (&src_r
.left
, &src_r
.top
);
944 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
945 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
946 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
948 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
950 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
951 color mapping in CopyBits. Otherwise, it will be slow. */
952 ForeColor (blackColor
);
953 BackColor (whiteColor
);
954 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
958 #endif /* not TARGET_API_MAC_CARBON */
962 /* Mac replacement for XCopyArea: dest must be Pixmap. */
965 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
971 unsigned int width
, height
;
978 GetGWorld (&old_port
, &old_gdh
);
979 SetGWorld (dest
, NULL
);
980 ForeColor (blackColor
);
981 BackColor (whiteColor
);
983 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
984 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
986 LockPixels (GetGWorldPixMap (src
));
987 LockPixels (GetGWorldPixMap (dest
));
988 #if TARGET_API_MAC_CARBON
989 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
990 &src_r
, &dest_r
, srcCopy
, 0);
991 #else /* not TARGET_API_MAC_CARBON */
992 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
993 &src_r
, &dest_r
, srcCopy
, 0);
994 #endif /* not TARGET_API_MAC_CARBON */
995 UnlockPixels (GetGWorldPixMap (dest
));
996 UnlockPixels (GetGWorldPixMap (src
));
998 SetGWorld (old_port
, old_gdh
);
1003 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
1004 width
, height
, dest_x
, dest_y
)
1006 Pixmap src
, mask
, dest
;
1009 unsigned int width
, height
;
1016 GetGWorld (&old_port
, &old_gdh
);
1017 SetGWorld (dest
, NULL
);
1018 ForeColor (blackColor
);
1019 BackColor (whiteColor
);
1021 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1022 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1024 LockPixels (GetGWorldPixMap (src
));
1025 LockPixels (GetGWorldPixMap (mask
));
1026 LockPixels (GetGWorldPixMap (dest
));
1027 #if TARGET_API_MAC_CARBON
1028 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1029 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1030 #else /* not TARGET_API_MAC_CARBON */
1031 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1032 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1033 #endif /* not TARGET_API_MAC_CARBON */
1034 UnlockPixels (GetGWorldPixMap (dest
));
1035 UnlockPixels (GetGWorldPixMap (mask
));
1036 UnlockPixels (GetGWorldPixMap (src
));
1038 SetGWorld (old_port
, old_gdh
);
1042 /* Mac replacement for XChangeGC. */
1045 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1048 if (mask
& GCForeground
)
1049 gc
->foreground
= xgcv
->foreground
;
1050 if (mask
& GCBackground
)
1051 gc
->background
= xgcv
->background
;
1053 gc
->font
= xgcv
->font
;
1057 /* Mac replacement for XCreateGC. */
1060 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1063 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1064 bzero (gc
, sizeof (XGCValues
));
1066 XChangeGC (ignore
, gc
, mask
, xgcv
);
1072 /* Used in xfaces.c. */
1075 XFreeGC (display
, gc
)
1083 /* Mac replacement for XGetGCValues. */
1086 XGetGCValues (void* ignore
, XGCValues
*gc
,
1087 unsigned long mask
, XGCValues
*xgcv
)
1089 XChangeGC (ignore
, xgcv
, mask
, gc
);
1093 /* Mac replacement for XSetForeground. */
1096 XSetForeground (display
, gc
, color
)
1099 unsigned long color
;
1101 gc
->foreground
= color
;
1105 /* Mac replacement for XSetFont. */
1108 XSetFont (display
, gc
, font
)
1118 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1119 int *direction
,int *font_ascent
,
1120 int *font_descent
, XCharStruct
*cs
)
1122 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1126 /* x_sync is a no-op on Mac. */
1134 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1135 Calls to XFlush should be unnecessary because the X output buffer
1136 is flushed automatically as needed by calls to XPending,
1137 XNextEvent, or XWindowEvent according to the XFlush man page.
1138 XTread_socket calls XPending. Removing XFlush improves
1141 #if TARGET_API_MAC_CARBON
1142 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1144 #define XFlush(DISPLAY) (void) 0
1147 /* Flush display of frame F, or of all frames if F is null. */
1153 #if TARGET_API_MAC_CARBON
1157 Lisp_Object rest
, frame
;
1158 FOR_EACH_FRAME (rest
, frame
)
1159 x_flush (XFRAME (frame
));
1161 else if (FRAME_MAC_P (f
))
1162 XFlush (FRAME_MAC_DISPLAY (f
));
1164 #endif /* TARGET_API_MAC_CARBON */
1169 /* Return the struct mac_display_info corresponding to DPY. There's
1172 struct mac_display_info
*
1173 mac_display_info_for_display (dpy
)
1176 return &one_mac_display_info
;
1181 /***********************************************************************
1182 Starting and ending an update
1183 ***********************************************************************/
1185 /* Start an update of frame F. This function is installed as a hook
1186 for update_begin, i.e. it is called when update_begin is called.
1187 This function is called prior to calls to x_update_window_begin for
1188 each window being updated. */
1194 /* Nothing to do. */
1198 /* Start update of window W. Set the global variable updated_window
1199 to the window being updated and set output_cursor to the cursor
1203 x_update_window_begin (w
)
1206 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1207 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1210 set_output_cursor (&w
->cursor
);
1214 if (f
== display_info
->mouse_face_mouse_frame
)
1216 /* Don't do highlighting for mouse motion during the update. */
1217 display_info
->mouse_face_defer
= 1;
1219 /* If F needs to be redrawn, simply forget about any prior mouse
1221 if (FRAME_GARBAGED_P (f
))
1222 display_info
->mouse_face_window
= Qnil
;
1224 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1225 their mouse_face_p flag set, which means that they are always
1226 unequal to rows in a desired matrix which never have that
1227 flag set. So, rows containing mouse-face glyphs are never
1228 scrolled, and we don't have to switch the mouse highlight off
1229 here to prevent it from being scrolled. */
1231 /* Can we tell that this update does not affect the window
1232 where the mouse highlight is? If so, no need to turn off.
1233 Likewise, don't do anything if the frame is garbaged;
1234 in that case, the frame's current matrix that we would use
1235 is all wrong, and we will redisplay that line anyway. */
1236 if (!NILP (display_info
->mouse_face_window
)
1237 && w
== XWINDOW (display_info
->mouse_face_window
))
1241 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1242 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1245 if (i
< w
->desired_matrix
->nrows
)
1246 clear_mouse_face (display_info
);
1255 /* Draw a vertical window border from (x,y0) to (x,y1) */
1258 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1262 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1264 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1265 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1269 /* End update of window W (which is equal to updated_window).
1271 Draw vertical borders between horizontally adjacent windows, and
1272 display W's cursor if CURSOR_ON_P is non-zero.
1274 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1275 glyphs in mouse-face were overwritten. In that case we have to
1276 make sure that the mouse-highlight is properly redrawn.
1278 W may be a menu bar pseudo-window in case we don't have X toolkit
1279 support. Such windows don't have a cursor, so don't display it
1283 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1285 int cursor_on_p
, mouse_face_overwritten_p
;
1287 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1289 if (!w
->pseudo_window_p
)
1294 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1296 output_cursor
.x
, output_cursor
.y
);
1298 if (draw_window_fringes (w
, 1))
1299 x_draw_vertical_border (w
);
1304 /* If a row with mouse-face was overwritten, arrange for
1305 XTframe_up_to_date to redisplay the mouse highlight. */
1306 if (mouse_face_overwritten_p
)
1308 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1309 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1310 dpyinfo
->mouse_face_window
= Qnil
;
1314 /* Unhide the caret. This won't actually show the cursor, unless it
1315 was visible before the corresponding call to HideCaret in
1316 x_update_window_begin. */
1317 if (w32_use_visible_system_caret
)
1318 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1321 updated_window
= NULL
;
1325 /* End update of frame F. This function is installed as a hook in
1332 /* Mouse highlight may be displayed again. */
1333 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1336 /* Reset the background color of Mac OS Window to that of the frame after
1337 update so that it is used by Mac Toolbox to clear the update region before
1338 an update event is generated. */
1339 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1341 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1343 XFlush (FRAME_MAC_DISPLAY (f
));
1348 /* This function is called from various places in xdisp.c whenever a
1349 complete update has been performed. The global variable
1350 updated_window is not available here. */
1353 XTframe_up_to_date (f
)
1356 if (FRAME_MAC_P (f
))
1358 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1360 if (dpyinfo
->mouse_face_deferred_gc
1361 || f
== dpyinfo
->mouse_face_mouse_frame
)
1364 if (dpyinfo
->mouse_face_mouse_frame
)
1365 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1366 dpyinfo
->mouse_face_mouse_x
,
1367 dpyinfo
->mouse_face_mouse_y
);
1368 dpyinfo
->mouse_face_deferred_gc
= 0;
1375 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1376 arrow bitmaps, or clear the fringes if no bitmaps are required
1377 before DESIRED_ROW is made current. The window being updated is
1378 found in updated_window. This function is called from
1379 update_window_line only if it is known that there are differences
1380 between bitmaps to be drawn between current row and DESIRED_ROW. */
1383 x_after_update_window_line (desired_row
)
1384 struct glyph_row
*desired_row
;
1386 struct window
*w
= updated_window
;
1392 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1393 desired_row
->redraw_fringe_bitmaps_p
= 1;
1395 /* When a window has disappeared, make sure that no rest of
1396 full-width rows stays visible in the internal border. Could
1397 check here if updated_window is the leftmost/rightmost window,
1398 but I guess it's not worth doing since vertically split windows
1399 are almost never used, internal border is rarely set, and the
1400 overhead is very small. */
1401 if (windows_or_buffers_changed
1402 && desired_row
->full_width_p
1403 && (f
= XFRAME (w
->frame
),
1404 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1406 && (height
= desired_row
->visible_height
,
1409 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1410 /* Internal border is drawn below the tool bar. */
1411 if (WINDOWP (f
->tool_bar_window
)
1412 && w
== XWINDOW (f
->tool_bar_window
))
1417 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1418 0, y
, width
, height
, 0);
1419 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1420 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1428 /* Draw the bitmap WHICH in one of the left or right fringes of
1429 window W. ROW is the glyph row for which to display the bitmap; it
1430 determines the vertical position at which the bitmap has to be
1434 x_draw_fringe_bitmap (w
, row
, p
)
1436 struct glyph_row
*row
;
1437 struct draw_fringe_bitmap_params
*p
;
1439 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1440 Display
*display
= FRAME_MAC_DISPLAY (f
);
1441 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1443 GC gc
= f
->output_data
.mac
->normal_gc
;
1444 struct face
*face
= p
->face
;
1447 /* Must clip because of partially visible lines. */
1448 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1451 /* Adjust position of "bottom aligned" bitmap on partially
1452 visible last row. */
1454 int oldVH
= row
->visible_height
;
1455 row
->visible_height
= p
->h
;
1456 row
->y
-= rowY
- p
->y
;
1457 x_clip_to_row (w
, row
, -1, gc
);
1459 row
->visible_height
= oldVH
;
1462 x_clip_to_row (w
, row
, -1, gc
);
1464 if (p
->bx
>= 0 && !p
->overlay_p
)
1467 gcv
.foreground
= face
->background
;
1469 #if 0 /* MAC_TODO: stipple */
1470 /* In case the same realized face is used for fringes and
1471 for something displayed in the text (e.g. face `region' on
1472 mono-displays, the fill style may have been changed to
1473 FillSolid in x_draw_glyph_string_background. */
1475 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1477 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1480 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1482 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1484 #if 0 /* MAC_TODO: stipple */
1486 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1492 unsigned short *bits
= p
->bits
+ p
->dh
;
1494 gcv
.foreground
= (p
->cursor_p
1495 ? (p
->overlay_p
? face
->background
1496 : f
->output_data
.mac
->cursor_pixel
)
1497 : face
->foreground
);
1498 gcv
.background
= face
->background
;
1500 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1501 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1504 mac_reset_clipping (display
, window
);
1508 /* This is called when starting Emacs and when restarting after
1509 suspend. When starting Emacs, no window is mapped. And nothing
1510 must be done to Emacs's own window if it is suspended (though that
1514 XTset_terminal_modes ()
1518 /* This is called when exiting or suspending Emacs. Exiting will make
1519 the windows go away, and suspending requires no action. */
1522 XTreset_terminal_modes ()
1527 /***********************************************************************
1529 ***********************************************************************/
1531 /* Function prototypes of this page. */
1533 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1534 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1537 /* Return a pointer to per-char metric information in FONT of a
1538 character pointed by B which is a pointer to an XChar2b. */
1540 #define PER_CHAR_METRIC(font, b) \
1542 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1543 + (((font)->min_byte1 || (font)->max_byte1) \
1544 ? (((b)->byte1 - (font)->min_byte1) \
1545 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1547 : &((font)->max_bounds))
1550 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1551 is not contained in the font. */
1553 static INLINE XCharStruct
*
1554 x_per_char_metric (font
, char2b
)
1558 /* The result metric information. */
1559 XCharStruct
*pcm
= NULL
;
1561 xassert (font
&& char2b
);
1563 if (font
->per_char
!= NULL
)
1565 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1567 /* min_char_or_byte2 specifies the linear character index
1568 corresponding to the first element of the per_char array,
1569 max_char_or_byte2 is the index of the last character. A
1570 character with non-zero CHAR2B->byte1 is not in the font.
1571 A character with byte2 less than min_char_or_byte2 or
1572 greater max_char_or_byte2 is not in the font. */
1573 if (char2b
->byte1
== 0
1574 && char2b
->byte2
>= font
->min_char_or_byte2
1575 && char2b
->byte2
<= font
->max_char_or_byte2
)
1576 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1580 /* If either min_byte1 or max_byte1 are nonzero, both
1581 min_char_or_byte2 and max_char_or_byte2 are less than
1582 256, and the 2-byte character index values corresponding
1583 to the per_char array element N (counting from 0) are:
1585 byte1 = N/D + min_byte1
1586 byte2 = N\D + min_char_or_byte2
1590 D = max_char_or_byte2 - min_char_or_byte2 + 1
1591 / = integer division
1592 \ = integer modulus */
1593 if (char2b
->byte1
>= font
->min_byte1
1594 && char2b
->byte1
<= font
->max_byte1
1595 && char2b
->byte2
>= font
->min_char_or_byte2
1596 && char2b
->byte2
<= font
->max_char_or_byte2
)
1598 pcm
= (font
->per_char
1599 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1600 * (char2b
->byte1
- font
->min_byte1
))
1601 + (char2b
->byte2
- font
->min_char_or_byte2
));
1607 /* If the per_char pointer is null, all glyphs between the first
1608 and last character indexes inclusive have the same
1609 information, as given by both min_bounds and max_bounds. */
1610 if (char2b
->byte2
>= font
->min_char_or_byte2
1611 && char2b
->byte2
<= font
->max_char_or_byte2
)
1612 pcm
= &font
->max_bounds
;
1615 return ((pcm
== NULL
1616 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1623 static XCharStruct
*
1624 mac_per_char_metric (font
, char2b
, font_type
)
1629 return x_per_char_metric (font
, char2b
);
1633 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1634 the two-byte form of C. Encoding is returned in *CHAR2B. */
1637 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1640 struct font_info
*font_info
;
1643 int charset
= CHAR_CHARSET (c
);
1644 XFontStruct
*font
= font_info
->font
;
1646 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1647 This may be either a program in a special encoder language or a
1649 if (font_info
->font_encoder
)
1651 /* It's a program. */
1652 struct ccl_program
*ccl
= font_info
->font_encoder
;
1654 if (CHARSET_DIMENSION (charset
) == 1)
1656 ccl
->reg
[0] = charset
;
1657 ccl
->reg
[1] = char2b
->byte2
;
1661 ccl
->reg
[0] = charset
;
1662 ccl
->reg
[1] = char2b
->byte1
;
1663 ccl
->reg
[2] = char2b
->byte2
;
1666 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1668 /* We assume that MSBs are appropriately set/reset by CCL
1670 if (font
->max_byte1
== 0) /* 1-byte font */
1671 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1673 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1675 else if (font_info
->encoding
[charset
])
1677 /* Fixed encoding scheme. See fontset.h for the meaning of the
1678 encoding numbers. */
1679 int enc
= font_info
->encoding
[charset
];
1681 if ((enc
== 1 || enc
== 2)
1682 && CHARSET_DIMENSION (charset
) == 2)
1683 char2b
->byte1
|= 0x80;
1685 if (enc
== 1 || enc
== 3)
1686 char2b
->byte2
|= 0x80;
1692 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1693 char2b
->byte1
= sjis1
;
1694 char2b
->byte2
= sjis2
;
1699 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1701 return FONT_TYPE_UNKNOWN
;
1706 /***********************************************************************
1708 ***********************************************************************/
1711 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1712 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1713 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1715 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1716 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1717 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1718 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1719 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1720 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1721 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1722 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1723 unsigned long *, double, int));*/
1724 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1725 double, int, unsigned long));
1726 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1727 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1728 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1729 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1730 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1731 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1733 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1734 int, int, int, int, int, int,
1736 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1737 int, int, int, Rect
*));
1740 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1744 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1749 struct glyph_string
*s
;
1751 if (s
->font
== FRAME_FONT (s
->f
)
1752 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1753 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1755 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1758 /* Cursor on non-default face: must merge. */
1762 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1763 xgcv
.foreground
= s
->face
->background
;
1765 /* If the glyph would be invisible, try a different foreground. */
1766 if (xgcv
.foreground
== xgcv
.background
)
1767 xgcv
.foreground
= s
->face
->foreground
;
1768 if (xgcv
.foreground
== xgcv
.background
)
1769 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1770 if (xgcv
.foreground
== xgcv
.background
)
1771 xgcv
.foreground
= s
->face
->foreground
;
1773 /* Make sure the cursor is distinct from text in this face. */
1774 if (xgcv
.background
== s
->face
->background
1775 && xgcv
.foreground
== s
->face
->foreground
)
1777 xgcv
.background
= s
->face
->foreground
;
1778 xgcv
.foreground
= s
->face
->background
;
1781 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1782 xgcv
.font
= s
->font
;
1783 mask
= GCForeground
| GCBackground
| GCFont
;
1785 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1786 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1789 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1790 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1792 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1797 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1800 x_set_mouse_face_gc (s
)
1801 struct glyph_string
*s
;
1806 /* What face has to be used last for the mouse face? */
1807 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1808 face
= FACE_FROM_ID (s
->f
, face_id
);
1810 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1812 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1813 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1815 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1816 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1817 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1819 /* If font in this face is same as S->font, use it. */
1820 if (s
->font
== s
->face
->font
)
1821 s
->gc
= s
->face
->gc
;
1824 /* Otherwise construct scratch_cursor_gc with values from FACE
1829 xgcv
.background
= s
->face
->background
;
1830 xgcv
.foreground
= s
->face
->foreground
;
1831 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1832 xgcv
.font
= s
->font
;
1833 mask
= GCForeground
| GCBackground
| GCFont
;
1835 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1836 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1839 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1840 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1842 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1845 xassert (s
->gc
!= 0);
1849 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1850 Faces to use in the mode line have already been computed when the
1851 matrix was built, so there isn't much to do, here. */
1854 x_set_mode_line_face_gc (s
)
1855 struct glyph_string
*s
;
1857 s
->gc
= s
->face
->gc
;
1861 /* Set S->gc of glyph string S for drawing that glyph string. Set
1862 S->stippled_p to a non-zero value if the face of S has a stipple
1866 x_set_glyph_string_gc (s
)
1867 struct glyph_string
*s
;
1869 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1871 if (s
->hl
== DRAW_NORMAL_TEXT
)
1873 s
->gc
= s
->face
->gc
;
1874 s
->stippled_p
= s
->face
->stipple
!= 0;
1876 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1878 x_set_mode_line_face_gc (s
);
1879 s
->stippled_p
= s
->face
->stipple
!= 0;
1881 else if (s
->hl
== DRAW_CURSOR
)
1883 x_set_cursor_gc (s
);
1886 else if (s
->hl
== DRAW_MOUSE_FACE
)
1888 x_set_mouse_face_gc (s
);
1889 s
->stippled_p
= s
->face
->stipple
!= 0;
1891 else if (s
->hl
== DRAW_IMAGE_RAISED
1892 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1894 s
->gc
= s
->face
->gc
;
1895 s
->stippled_p
= s
->face
->stipple
!= 0;
1899 s
->gc
= s
->face
->gc
;
1900 s
->stippled_p
= s
->face
->stipple
!= 0;
1903 /* GC must have been set. */
1904 xassert (s
->gc
!= 0);
1908 /* Set clipping for output of glyph string S. S may be part of a mode
1909 line or menu if we don't have X toolkit support. */
1912 x_set_glyph_string_clipping (s
)
1913 struct glyph_string
*s
;
1916 get_glyph_string_clip_rect (s
, &r
);
1917 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1922 Compute left and right overhang of glyph string S. If S is a glyph
1923 string for a composition, assume overhangs don't exist. */
1926 mac_compute_glyph_string_overhangs (s
)
1927 struct glyph_string
*s
;
1930 /* MAC_TODO: XTextExtents16 does nothing yet... */
1933 && s
->first_glyph
->type
== CHAR_GLYPH
)
1936 int direction
, font_ascent
, font_descent
;
1937 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1938 &font_ascent
, &font_descent
, &cs
);
1939 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1940 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1946 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1949 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1950 struct glyph_string
*s
;
1955 xgcv
.foreground
= s
->gc
->background
;
1956 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1960 /* Draw the background of glyph_string S. If S->background_filled_p
1961 is non-zero don't draw it. FORCE_P non-zero means draw the
1962 background even if it wouldn't be drawn normally. This is used
1963 when a string preceding S draws into the background of S, or S
1964 contains the first component of a composition. */
1967 x_draw_glyph_string_background (s
, force_p
)
1968 struct glyph_string
*s
;
1971 /* Nothing to do if background has already been drawn or if it
1972 shouldn't be drawn in the first place. */
1973 if (!s
->background_filled_p
)
1975 int box_line_width
= max (s
->face
->box_line_width
, 0);
1977 #if 0 /* MAC_TODO: stipple */
1980 /* Fill background with a stipple pattern. */
1981 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1982 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1983 s
->y
+ box_line_width
,
1984 s
->background_width
,
1985 s
->height
- 2 * box_line_width
);
1986 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1987 s
->background_filled_p
= 1;
1991 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1992 || s
->font_not_found_p
1993 || s
->extends_to_end_of_line_p
1996 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1997 s
->background_width
,
1998 s
->height
- 2 * box_line_width
);
1999 s
->background_filled_p
= 1;
2005 /* Draw the foreground of glyph string S. */
2008 x_draw_glyph_string_foreground (s
)
2009 struct glyph_string
*s
;
2013 /* If first glyph of S has a left box line, start drawing the text
2014 of S to the right of that box line. */
2015 if (s
->face
->box
!= FACE_NO_BOX
2016 && s
->first_glyph
->left_box_line_p
)
2017 x
= s
->x
+ abs (s
->face
->box_line_width
);
2021 /* Draw characters of S as rectangles if S's font could not be
2023 if (s
->font_not_found_p
)
2025 for (i
= 0; i
< s
->nchars
; ++i
)
2027 struct glyph
*g
= s
->first_glyph
+ i
;
2028 mac_draw_rectangle (s
->display
, s
->window
,
2029 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2031 x
+= g
->pixel_width
;
2036 char *char1b
= (char *) s
->char2b
;
2037 int boff
= s
->font_info
->baseline_offset
;
2039 if (s
->font_info
->vertical_centering
)
2040 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2042 /* If we can use 8-bit functions, condense S->char2b. */
2044 for (i
= 0; i
< s
->nchars
; ++i
)
2045 char1b
[i
] = s
->char2b
[i
].byte2
;
2047 /* Draw text with XDrawString if background has already been
2048 filled. Otherwise, use XDrawImageString. (Note that
2049 XDrawImageString is usually faster than XDrawString.) Always
2050 use XDrawImageString when drawing the cursor so that there is
2051 no chance that characters under a box cursor are invisible. */
2052 if (s
->for_overlaps_p
2053 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2055 /* Draw characters with 16-bit or 8-bit functions. */
2057 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2058 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2060 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2061 s
->ybase
- boff
, char1b
, s
->nchars
);
2066 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2067 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2069 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2070 s
->ybase
- boff
, char1b
, s
->nchars
);
2075 /* Draw the foreground of composite glyph string S. */
2078 x_draw_composite_glyph_string_foreground (s
)
2079 struct glyph_string
*s
;
2083 /* If first glyph of S has a left box line, start drawing the text
2084 of S to the right of that box line. */
2085 if (s
->face
->box
!= FACE_NO_BOX
2086 && s
->first_glyph
->left_box_line_p
)
2087 x
= s
->x
+ abs (s
->face
->box_line_width
);
2091 /* S is a glyph string for a composition. S->gidx is the index of
2092 the first character drawn for glyphs of this composition.
2093 S->gidx == 0 means we are drawing the very first character of
2094 this composition. */
2096 /* Draw a rectangle for the composition if the font for the very
2097 first character of the composition could not be loaded. */
2098 if (s
->font_not_found_p
)
2101 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2102 s
->width
- 1, s
->height
- 1);
2106 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2107 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2108 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2109 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2115 #ifdef USE_X_TOOLKIT
2117 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2120 /* Return the frame on which widget WIDGET is used.. Abort if frame
2121 cannot be determined. */
2123 static struct frame
*
2124 x_frame_of_widget (widget
)
2127 struct x_display_info
*dpyinfo
;
2131 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2133 /* Find the top-level shell of the widget. Note that this function
2134 can be called when the widget is not yet realized, so XtWindow
2135 (widget) == 0. That's the reason we can't simply use
2136 x_any_window_to_frame. */
2137 while (!XtIsTopLevelShell (widget
))
2138 widget
= XtParent (widget
);
2140 /* Look for a frame with that top-level widget. Allocate the color
2141 on that frame to get the right gamma correction value. */
2142 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2143 if (GC_FRAMEP (XCAR (tail
))
2144 && (f
= XFRAME (XCAR (tail
)),
2145 (f
->output_data
.nothing
!= 1
2146 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2147 && f
->output_data
.x
->widget
== widget
)
2154 /* Allocate the color COLOR->pixel on the screen and display of
2155 widget WIDGET in colormap CMAP. If an exact match cannot be
2156 allocated, try the nearest color available. Value is non-zero
2157 if successful. This is called from lwlib. */
2160 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2165 struct frame
*f
= x_frame_of_widget (widget
);
2166 return x_alloc_nearest_color (f
, cmap
, color
);
2170 #endif /* USE_X_TOOLKIT */
2172 #if 0 /* MAC_TODO */
2174 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2175 CMAP. If an exact match can't be allocated, try the nearest color
2176 available. Value is non-zero if successful. Set *COLOR to the
2180 x_alloc_nearest_color (f
, cmap
, color
)
2185 Display
*display
= FRAME_X_DISPLAY (f
);
2186 Screen
*screen
= FRAME_X_SCREEN (f
);
2189 gamma_correct (f
, color
);
2190 rc
= XAllocColor (display
, cmap
, color
);
2193 /* If we got to this point, the colormap is full, so we're going
2194 to try to get the next closest color. The algorithm used is
2195 a least-squares matching, which is what X uses for closest
2196 color matching with StaticColor visuals. */
2198 unsigned long nearest_delta
= ~0;
2199 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2200 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2202 for (i
= 0; i
< ncells
; ++i
)
2204 XQueryColors (display
, cmap
, cells
, ncells
);
2206 for (nearest
= i
= 0; i
< ncells
; ++i
)
2208 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2209 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2210 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2211 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2213 if (delta
< nearest_delta
)
2216 nearest_delta
= delta
;
2220 color
->red
= cells
[nearest
].red
;
2221 color
->green
= cells
[nearest
].green
;
2222 color
->blue
= cells
[nearest
].blue
;
2223 rc
= XAllocColor (display
, cmap
, color
);
2226 #ifdef DEBUG_X_COLORS
2228 register_color (color
->pixel
);
2229 #endif /* DEBUG_X_COLORS */
2235 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2236 It's necessary to do this instead of just using PIXEL directly to
2237 get color reference counts right. */
2240 x_copy_color (f
, pixel
)
2242 unsigned long pixel
;
2246 color
.pixel
= pixel
;
2248 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2249 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2251 #ifdef DEBUG_X_COLORS
2252 register_color (pixel
);
2258 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2259 It's necessary to do this instead of just using PIXEL directly to
2260 get color reference counts right. */
2263 x_copy_dpy_color (dpy
, cmap
, pixel
)
2266 unsigned long pixel
;
2270 color
.pixel
= pixel
;
2272 XQueryColor (dpy
, cmap
, &color
);
2273 XAllocColor (dpy
, cmap
, &color
);
2275 #ifdef DEBUG_X_COLORS
2276 register_color (pixel
);
2281 #endif /* MAC_TODO */
2284 /* Brightness beyond which a color won't have its highlight brightness
2287 Nominally, highlight colors for `3d' faces are calculated by
2288 brightening an object's color by a constant scale factor, but this
2289 doesn't yield good results for dark colors, so for colors who's
2290 brightness is less than this value (on a scale of 0-255) have to
2291 use an additional additive factor.
2293 The value here is set so that the default menu-bar/mode-line color
2294 (grey75) will not have its highlights changed at all. */
2295 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2298 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2299 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2300 If this produces the same color as COLOR, try a color where all RGB
2301 values have DELTA added. Return the allocated color in *COLOR.
2302 DISPLAY is the X display, CMAP is the colormap to operate on.
2303 Value is non-zero if successful. */
2306 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2308 unsigned long *color
;
2315 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2318 /* Change RGB values by specified FACTOR. Avoid overflow! */
2319 xassert (factor
>= 0);
2320 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2321 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2322 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2324 /* Calculate brightness of COLOR. */
2325 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2326 + BLUE_FROM_ULONG (*color
)) / 6;
2328 /* We only boost colors that are darker than
2329 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2330 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2331 /* Make an additive adjustment to NEW, because it's dark enough so
2332 that scaling by FACTOR alone isn't enough. */
2334 /* How far below the limit this color is (0 - 1, 1 being darker). */
2335 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2336 /* The additive adjustment. */
2337 int min_delta
= delta
* dimness
* factor
/ 2;
2340 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2341 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2342 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2344 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2345 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2346 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2350 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2351 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2352 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2354 /* MAC_TODO: Map to palette and retry with delta if same? */
2355 /* MAC_TODO: Free colors (if using palette)? */
2366 /* Set up the foreground color for drawing relief lines of glyph
2367 string S. RELIEF is a pointer to a struct relief containing the GC
2368 with which lines will be drawn. Use a color that is FACTOR or
2369 DELTA lighter or darker than the relief's background which is found
2370 in S->f->output_data.x->relief_background. If such a color cannot
2371 be allocated, use DEFAULT_PIXEL, instead. */
2374 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2376 struct relief
*relief
;
2379 unsigned long default_pixel
;
2382 struct mac_output
*di
= f
->output_data
.mac
;
2383 unsigned long mask
= GCForeground
;
2384 unsigned long pixel
;
2385 unsigned long background
= di
->relief_background
;
2386 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2388 /* MAC_TODO: Free colors (if using palette)? */
2390 /* Allocate new color. */
2391 xgcv
.foreground
= default_pixel
;
2393 if (dpyinfo
->n_planes
!= 1
2394 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2396 relief
->allocated_p
= 1;
2397 xgcv
.foreground
= relief
->pixel
= pixel
;
2400 if (relief
->gc
== 0)
2402 #if 0 /* MAC_TODO: stipple */
2403 xgcv
.stipple
= dpyinfo
->gray
;
2406 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2409 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2413 /* Set up colors for the relief lines around glyph string S. */
2416 x_setup_relief_colors (s
)
2417 struct glyph_string
*s
;
2419 struct mac_output
*di
= s
->f
->output_data
.mac
;
2420 unsigned long color
;
2422 if (s
->face
->use_box_color_for_shadows_p
)
2423 color
= s
->face
->box_color
;
2424 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2426 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2427 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2432 /* Get the background color of the face. */
2433 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2434 color
= xgcv
.background
;
2437 if (di
->white_relief
.gc
== 0
2438 || color
!= di
->relief_background
)
2440 di
->relief_background
= color
;
2441 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2442 WHITE_PIX_DEFAULT (s
->f
));
2443 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2444 BLACK_PIX_DEFAULT (s
->f
));
2449 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2450 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2451 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2452 relief. LEFT_P non-zero means draw a relief on the left side of
2453 the rectangle. RIGHT_P non-zero means draw a relief on the right
2454 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2458 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2459 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2461 int left_x
, top_y
, right_x
, bottom_y
, width
;
2462 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2465 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2466 Window window
= FRAME_MAC_WINDOW (f
);
2471 gc
= f
->output_data
.mac
->white_relief
.gc
;
2473 gc
= f
->output_data
.mac
->black_relief
.gc
;
2474 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2478 for (i
= 0; i
< width
; ++i
)
2479 XDrawLine (dpy
, window
, gc
,
2480 left_x
+ i
* left_p
, top_y
+ i
,
2481 right_x
- i
* right_p
, top_y
+ i
);
2485 for (i
= 0; i
< width
; ++i
)
2486 XDrawLine (dpy
, window
, gc
,
2487 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2489 mac_reset_clipping (dpy
, window
);
2491 gc
= f
->output_data
.mac
->black_relief
.gc
;
2493 gc
= f
->output_data
.mac
->white_relief
.gc
;
2494 mac_set_clip_rectangle (dpy
, window
,
2499 for (i
= 0; i
< width
; ++i
)
2500 XDrawLine (dpy
, window
, gc
,
2501 left_x
+ i
* left_p
, bottom_y
- i
,
2502 right_x
- i
* right_p
, bottom_y
- i
);
2506 for (i
= 0; i
< width
; ++i
)
2507 XDrawLine (dpy
, window
, gc
,
2508 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2510 mac_reset_clipping (dpy
, window
);
2514 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2515 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2516 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2517 left side of the rectangle. RIGHT_P non-zero means draw a line
2518 on the right side of the rectangle. CLIP_RECT is the clipping
2519 rectangle to use when drawing. */
2522 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2523 left_p
, right_p
, clip_rect
)
2524 struct glyph_string
*s
;
2525 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2530 xgcv
.foreground
= s
->face
->box_color
;
2531 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2534 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2535 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2539 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2540 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2543 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2544 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2548 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2549 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2551 mac_reset_clipping (s
->display
, s
->window
);
2555 /* Draw a box around glyph string S. */
2558 x_draw_glyph_string_box (s
)
2559 struct glyph_string
*s
;
2561 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2562 int left_p
, right_p
;
2563 struct glyph
*last_glyph
;
2566 last_x
= window_box_right (s
->w
, s
->area
);
2567 if (s
->row
->full_width_p
2568 && !s
->w
->pseudo_window_p
)
2570 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2571 if (s
->area
!= RIGHT_MARGIN_AREA
2572 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2573 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2576 /* The glyph that may have a right box line. */
2577 last_glyph
= (s
->cmp
|| s
->img
2579 : s
->first_glyph
+ s
->nchars
- 1);
2581 width
= abs (s
->face
->box_line_width
);
2582 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2584 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2586 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2588 bottom_y
= top_y
+ s
->height
- 1;
2590 left_p
= (s
->first_glyph
->left_box_line_p
2591 || (s
->hl
== DRAW_MOUSE_FACE
2593 || s
->prev
->hl
!= s
->hl
)));
2594 right_p
= (last_glyph
->right_box_line_p
2595 || (s
->hl
== DRAW_MOUSE_FACE
2597 || s
->next
->hl
!= s
->hl
)));
2599 get_glyph_string_clip_rect (s
, &clip_rect
);
2601 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2602 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2603 left_p
, right_p
, &clip_rect
);
2606 x_setup_relief_colors (s
);
2607 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2608 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2613 /* Draw foreground of image glyph string S. */
2616 x_draw_image_foreground (s
)
2617 struct glyph_string
*s
;
2620 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2622 /* If first glyph of S has a left box line, start drawing it to the
2623 right of that line. */
2624 if (s
->face
->box
!= FACE_NO_BOX
2625 && s
->first_glyph
->left_box_line_p
2627 x
+= abs (s
->face
->box_line_width
);
2629 /* If there is a margin around the image, adjust x- and y-position
2631 if (s
->slice
.x
== 0)
2632 x
+= s
->img
->hmargin
;
2633 if (s
->slice
.y
== 0)
2634 y
+= s
->img
->vmargin
;
2641 XRectangle clip_rect
, image_rect
, r
;
2643 get_glyph_string_clip_rect (s
, &nr
);
2644 CONVERT_TO_XRECT (clip_rect
, nr
);
2647 image_rect
.width
= s
->slice
.width
;
2648 image_rect
.height
= s
->slice
.height
;
2649 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2650 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2652 s
->slice
.x
+ r
.x
- x
, s
->slice
.y
+ r
.y
- y
,
2653 r
.width
, r
.height
, r
.x
, r
.y
);
2658 XRectangle clip_rect
, image_rect
, r
;
2660 get_glyph_string_clip_rect (s
, &nr
);
2661 CONVERT_TO_XRECT (clip_rect
, nr
);
2664 image_rect
.width
= s
->slice
.width
;
2665 image_rect
.height
= s
->slice
.height
;
2666 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2667 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2668 s
->slice
.x
+ r
.x
- x
, s
->slice
.y
+ r
.y
- y
,
2669 r
.width
, r
.height
, r
.x
, r
.y
);
2671 /* When the image has a mask, we can expect that at
2672 least part of a mouse highlight or a block cursor will
2673 be visible. If the image doesn't have a mask, make
2674 a block cursor visible by drawing a rectangle around
2675 the image. I believe it's looking better if we do
2676 nothing here for mouse-face. */
2677 if (s
->hl
== DRAW_CURSOR
)
2679 int r
= s
->img
->relief
;
2681 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2683 s
->slice
.width
+ r
*2 - 1,
2684 s
->slice
.height
+ r
*2 - 1);
2689 /* Draw a rectangle if image could not be loaded. */
2690 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2691 s
->slice
.width
- 1, s
->slice
.height
- 1);
2695 /* Draw a relief around the image glyph string S. */
2698 x_draw_image_relief (s
)
2699 struct glyph_string
*s
;
2701 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2704 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2706 /* If first glyph of S has a left box line, start drawing it to the
2707 right of that line. */
2708 if (s
->face
->box
!= FACE_NO_BOX
2709 && s
->first_glyph
->left_box_line_p
2711 x
+= abs (s
->face
->box_line_width
);
2713 /* If there is a margin around the image, adjust x- and y-position
2715 if (s
->slice
.x
== 0)
2716 x
+= s
->img
->hmargin
;
2717 if (s
->slice
.y
== 0)
2718 y
+= s
->img
->vmargin
;
2720 if (s
->hl
== DRAW_IMAGE_SUNKEN
2721 || s
->hl
== DRAW_IMAGE_RAISED
)
2723 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2724 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2728 thick
= abs (s
->img
->relief
);
2729 raised_p
= s
->img
->relief
> 0;
2734 x1
= x
+ s
->slice
.width
+ thick
- 1;
2735 y1
= y
+ s
->slice
.height
+ thick
- 1;
2737 x_setup_relief_colors (s
);
2738 get_glyph_string_clip_rect (s
, &r
);
2739 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2741 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2743 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2748 /* Draw the foreground of image glyph string S to PIXMAP. */
2751 x_draw_image_foreground_1 (s
, pixmap
)
2752 struct glyph_string
*s
;
2756 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2758 /* If first glyph of S has a left box line, start drawing it to the
2759 right of that line. */
2760 if (s
->face
->box
!= FACE_NO_BOX
2761 && s
->first_glyph
->left_box_line_p
2763 x
+= abs (s
->face
->box_line_width
);
2765 /* If there is a margin around the image, adjust x- and y-position
2767 if (s
->slice
.x
== 0)
2768 x
+= s
->img
->hmargin
;
2769 if (s
->slice
.y
== 0)
2770 y
+= s
->img
->vmargin
;
2775 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2776 s
->img
->mask
, pixmap
, s
->gc
,
2777 s
->slice
.x
, s
->slice
.y
,
2778 s
->slice
.width
, s
->slice
.height
,
2782 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2783 s
->slice
.x
, s
->slice
.y
,
2784 s
->slice
.width
, s
->slice
.height
,
2787 /* When the image has a mask, we can expect that at
2788 least part of a mouse highlight or a block cursor will
2789 be visible. If the image doesn't have a mask, make
2790 a block cursor visible by drawing a rectangle around
2791 the image. I believe it's looking better if we do
2792 nothing here for mouse-face. */
2793 if (s
->hl
== DRAW_CURSOR
)
2795 int r
= s
->img
->relief
;
2797 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2798 s
->slice
.width
+ r
*2 - 1,
2799 s
->slice
.height
+ r
*2 - 1);
2804 /* Draw a rectangle if image could not be loaded. */
2805 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2806 s
->slice
.width
- 1, s
->slice
.height
- 1);
2810 /* Draw part of the background of glyph string S. X, Y, W, and H
2811 give the rectangle to draw. */
2814 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2815 struct glyph_string
*s
;
2818 #if 0 /* MAC_TODO: stipple */
2821 /* Fill background with a stipple pattern. */
2822 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2823 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2824 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2827 #endif /* MAC_TODO */
2828 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2832 /* Draw image glyph string S.
2835 s->x +-------------------------
2838 | +-------------------------
2841 | | +-------------------
2847 x_draw_image_glyph_string (s
)
2848 struct glyph_string
*s
;
2851 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2852 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2856 height
= s
->height
- 2 * box_line_vwidth
;
2859 /* Fill background with face under the image. Do it only if row is
2860 taller than image or if image has a clip mask to reduce
2862 s
->stippled_p
= s
->face
->stipple
!= 0;
2863 if (height
> s
->slice
.height
2867 || s
->img
->pixmap
== 0
2868 || s
->width
!= s
->background_width
)
2871 if (s
->first_glyph
->left_box_line_p
2873 x
+= box_line_hwidth
;
2876 if (s
->slice
.y
== 0)
2877 y
+= box_line_vwidth
;
2881 /* Create a pixmap as large as the glyph string. Fill it
2882 with the background color. Copy the image to it, using
2883 its mask. Copy the temporary pixmap to the display. */
2884 int depth
= one_mac_display_info
.n_planes
;
2886 /* Create a pixmap as large as the glyph string. */
2887 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2888 s
->background_width
,
2891 /* Fill the pixmap with the background color/stipple. */
2892 #if 0 /* TODO: stipple */
2895 /* Fill background with a stipple pattern. */
2896 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2897 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2898 0, 0, s
->background_width
, s
->height
);
2899 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2905 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2907 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2908 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2909 0, 0, s
->background_width
,
2911 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2915 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2917 s
->background_filled_p
= 1;
2920 /* Draw the foreground. */
2923 x_draw_image_foreground_1 (s
, pixmap
);
2924 x_set_glyph_string_clipping (s
);
2925 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2926 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2927 mac_reset_clipping (s
->display
, s
->window
);
2928 XFreePixmap (s
->display
, pixmap
);
2931 x_draw_image_foreground (s
);
2933 /* If we must draw a relief around the image, do it. */
2935 || s
->hl
== DRAW_IMAGE_RAISED
2936 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2937 x_draw_image_relief (s
);
2941 /* Draw stretch glyph string S. */
2944 x_draw_stretch_glyph_string (s
)
2945 struct glyph_string
*s
;
2947 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2948 s
->stippled_p
= s
->face
->stipple
!= 0;
2950 if (s
->hl
== DRAW_CURSOR
2951 && !x_stretch_cursor_p
)
2953 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2954 as wide as the stretch glyph. */
2955 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2958 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2960 /* Clear rest using the GC of the original non-cursor face. */
2961 if (width
< s
->background_width
)
2963 int x
= s
->x
+ width
, y
= s
->y
;
2964 int w
= s
->background_width
- width
, h
= s
->height
;
2968 if (s
->row
->mouse_face_p
2969 && cursor_in_mouse_face_p (s
->w
))
2971 x_set_mouse_face_gc (s
);
2977 get_glyph_string_clip_rect (s
, &r
);
2978 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2980 #if 0 /* MAC_TODO: stipple */
2981 if (s
->face
->stipple
)
2983 /* Fill background with a stipple pattern. */
2984 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2985 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2986 XSetFillStyle (s
->display
, gc
, FillSolid
);
2989 #endif /* MAC_TODO */
2992 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
2993 XSetForeground (s
->display
, gc
, xgcv
.background
);
2994 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2995 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
2998 mac_reset_clipping (s
->display
, s
->window
);
3001 else if (!s
->background_filled_p
)
3002 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3005 s
->background_filled_p
= 1;
3009 /* Draw glyph string S. */
3012 x_draw_glyph_string (s
)
3013 struct glyph_string
*s
;
3015 int relief_drawn_p
= 0;
3017 /* If S draws into the background of its successor, draw the
3018 background of the successor first so that S can draw into it.
3019 This makes S->next use XDrawString instead of XDrawImageString. */
3020 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3022 xassert (s
->next
->img
== NULL
);
3023 x_set_glyph_string_gc (s
->next
);
3024 x_set_glyph_string_clipping (s
->next
);
3025 x_draw_glyph_string_background (s
->next
, 1);
3028 /* Set up S->gc, set clipping and draw S. */
3029 x_set_glyph_string_gc (s
);
3031 /* Draw relief (if any) in advance for char/composition so that the
3032 glyph string can be drawn over it. */
3033 if (!s
->for_overlaps_p
3034 && s
->face
->box
!= FACE_NO_BOX
3035 && (s
->first_glyph
->type
== CHAR_GLYPH
3036 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3039 x_set_glyph_string_clipping (s
);
3040 x_draw_glyph_string_background (s
, 1);
3041 x_draw_glyph_string_box (s
);
3042 x_set_glyph_string_clipping (s
);
3046 x_set_glyph_string_clipping (s
);
3048 switch (s
->first_glyph
->type
)
3051 x_draw_image_glyph_string (s
);
3055 x_draw_stretch_glyph_string (s
);
3059 if (s
->for_overlaps_p
)
3060 s
->background_filled_p
= 1;
3062 x_draw_glyph_string_background (s
, 0);
3063 x_draw_glyph_string_foreground (s
);
3066 case COMPOSITE_GLYPH
:
3067 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3068 s
->background_filled_p
= 1;
3070 x_draw_glyph_string_background (s
, 1);
3071 x_draw_composite_glyph_string_foreground (s
);
3078 if (!s
->for_overlaps_p
)
3080 /* Draw underline. */
3081 if (s
->face
->underline_p
)
3083 unsigned long h
= 1;
3084 unsigned long dy
= s
->height
- h
;
3086 if (s
->face
->underline_defaulted_p
)
3087 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3092 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3093 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3094 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3096 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3100 /* Draw overline. */
3101 if (s
->face
->overline_p
)
3103 unsigned long dy
= 0, h
= 1;
3105 if (s
->face
->overline_color_defaulted_p
)
3106 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3111 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3112 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3113 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3115 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3119 /* Draw strike-through. */
3120 if (s
->face
->strike_through_p
)
3122 unsigned long h
= 1;
3123 unsigned long dy
= (s
->height
- h
) / 2;
3125 if (s
->face
->strike_through_color_defaulted_p
)
3126 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3131 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3132 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3133 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3135 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3139 /* Draw relief if not yet drawn. */
3140 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3141 x_draw_glyph_string_box (s
);
3144 /* Reset clipping. */
3145 mac_reset_clipping (s
->display
, s
->window
);
3148 /* Shift display to make room for inserted glyphs. */
3151 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3153 int x
, y
, width
, height
, shift_by
;
3155 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3156 f
->output_data
.mac
->normal_gc
,
3157 x
, y
, width
, height
,
3161 /* Delete N glyphs at the nominal cursor position. Not implemented
3172 /* Clear entire frame. If updating_frame is non-null, clear that
3173 frame. Otherwise clear the selected frame. */
3183 f
= SELECTED_FRAME ();
3185 /* Clearing the frame will erase any cursor, so mark them all as no
3187 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3188 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3189 output_cursor
.x
= -1;
3191 /* We don't set the output cursor here because there will always
3192 follow an explicit cursor_to. */
3194 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3196 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3197 /* We have to clear the scroll bars, too. If we have changed
3198 colors or something like that, then they should be notified. */
3199 x_scroll_bar_clear (f
);
3202 XFlush (FRAME_MAC_DISPLAY (f
));
3208 /* Invert the middle quarter of the frame for .15 sec. */
3210 /* We use the select system call to do the waiting, so we have to make
3211 sure it's available. If it isn't, we just won't do visual bells. */
3213 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3216 /* Subtract the `struct timeval' values X and Y, storing the result in
3217 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3220 timeval_subtract (result
, x
, y
)
3221 struct timeval
*result
, x
, y
;
3223 /* Perform the carry for the later subtraction by updating y. This
3224 is safer because on some systems the tv_sec member is unsigned. */
3225 if (x
.tv_usec
< y
.tv_usec
)
3227 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3228 y
.tv_usec
-= 1000000 * nsec
;
3232 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3234 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3235 y
.tv_usec
+= 1000000 * nsec
;
3239 /* Compute the time remaining to wait. tv_usec is certainly
3241 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3242 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3244 /* Return indication of whether the result should be considered
3246 return x
.tv_sec
< y
.tv_sec
;
3258 struct timeval wakeup
;
3260 EMACS_GET_TIME (wakeup
);
3262 /* Compute time to wait until, propagating carry from usecs. */
3263 wakeup
.tv_usec
+= 150000;
3264 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3265 wakeup
.tv_usec
%= 1000000;
3267 /* Keep waiting until past the time wakeup. */
3270 struct timeval timeout
;
3272 EMACS_GET_TIME (timeout
);
3274 /* In effect, timeout = wakeup - timeout.
3275 Break if result would be negative. */
3276 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3279 /* Try to wait that long--but we might wake up sooner. */
3280 select (0, NULL
, NULL
, NULL
, &timeout
);
3289 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3292 /* Make audible bell. */
3297 struct frame
*f
= SELECTED_FRAME ();
3299 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3307 XFlush (FRAME_MAC_DISPLAY (f
));
3314 /* Specify how many text lines, from the top of the window,
3315 should be affected by insert-lines and delete-lines operations.
3316 This, and those operations, are used only within an update
3317 that is bounded by calls to x_update_begin and x_update_end. */
3320 XTset_terminal_window (n
)
3323 /* This function intentionally left blank. */
3328 /***********************************************************************
3330 ***********************************************************************/
3332 /* Perform an insert-lines or delete-lines operation, inserting N
3333 lines or deleting -N lines at vertical position VPOS. */
3336 x_ins_del_lines (vpos
, n
)
3343 /* Scroll part of the display as described by RUN. */
3346 x_scroll_run (w
, run
)
3350 struct frame
*f
= XFRAME (w
->frame
);
3351 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3353 /* Get frame-relative bounding box of the text display area of W,
3354 without mode lines. Include in this box the left and right
3356 window_box (w
, -1, &x
, &y
, &width
, &height
);
3358 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3359 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3360 bottom_y
= y
+ height
;
3364 /* Scrolling up. Make sure we don't copy part of the mode
3365 line at the bottom. */
3366 if (from_y
+ run
->height
> bottom_y
)
3367 height
= bottom_y
- from_y
;
3369 height
= run
->height
;
3373 /* Scolling down. Make sure we don't copy over the mode line.
3375 if (to_y
+ run
->height
> bottom_y
)
3376 height
= bottom_y
- to_y
;
3378 height
= run
->height
;
3383 /* Cursor off. Will be switched on again in x_update_window_end. */
3387 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3388 f
->output_data
.mac
->normal_gc
,
3398 /***********************************************************************
3400 ***********************************************************************/
3407 x_update_cursor (f
, 1);
3411 frame_unhighlight (f
)
3414 x_update_cursor (f
, 1);
3417 /* The focus has changed. Update the frames as necessary to reflect
3418 the new situation. Note that we can't change the selected frame
3419 here, because the Lisp code we are interrupting might become confused.
3420 Each event gets marked with the frame in which it occurred, so the
3421 Lisp code can tell when the switch took place by examining the events. */
3424 x_new_focus_frame (dpyinfo
, frame
)
3425 struct x_display_info
*dpyinfo
;
3426 struct frame
*frame
;
3428 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3430 if (frame
!= dpyinfo
->x_focus_frame
)
3432 /* Set this before calling other routines, so that they see
3433 the correct value of x_focus_frame. */
3434 dpyinfo
->x_focus_frame
= frame
;
3436 if (old_focus
&& old_focus
->auto_lower
)
3437 x_lower_frame (old_focus
);
3440 selected_frame
= frame
;
3441 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3443 Fselect_window (selected_frame
->selected_window
, Qnil
);
3444 choose_minibuf_frame ();
3447 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3448 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3450 pending_autoraise_frame
= 0;
3453 x_frame_rehighlight (dpyinfo
);
3456 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3459 x_mouse_leave (dpyinfo
)
3460 struct x_display_info
*dpyinfo
;
3462 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3465 /* The focus has changed, or we have redirected a frame's focus to
3466 another frame (this happens when a frame uses a surrogate
3467 mini-buffer frame). Shift the highlight as appropriate.
3469 The FRAME argument doesn't necessarily have anything to do with which
3470 frame is being highlighted or un-highlighted; we only use it to find
3471 the appropriate X display info. */
3474 XTframe_rehighlight (frame
)
3475 struct frame
*frame
;
3477 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3481 x_frame_rehighlight (dpyinfo
)
3482 struct x_display_info
*dpyinfo
;
3484 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3486 if (dpyinfo
->x_focus_frame
)
3488 dpyinfo
->x_highlight_frame
3489 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3490 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3491 : dpyinfo
->x_focus_frame
);
3492 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3494 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3495 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3499 dpyinfo
->x_highlight_frame
= 0;
3501 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3504 frame_unhighlight (old_highlight
);
3505 if (dpyinfo
->x_highlight_frame
)
3506 frame_highlight (dpyinfo
->x_highlight_frame
);
3512 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3514 #if 0 /* MAC_TODO */
3515 /* Initialize mode_switch_bit and modifier_meaning. */
3517 x_find_modifier_meanings (dpyinfo
)
3518 struct x_display_info
*dpyinfo
;
3520 int min_code
, max_code
;
3523 XModifierKeymap
*mods
;
3525 dpyinfo
->meta_mod_mask
= 0;
3526 dpyinfo
->shift_lock_mask
= 0;
3527 dpyinfo
->alt_mod_mask
= 0;
3528 dpyinfo
->super_mod_mask
= 0;
3529 dpyinfo
->hyper_mod_mask
= 0;
3532 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3534 min_code
= dpyinfo
->display
->min_keycode
;
3535 max_code
= dpyinfo
->display
->max_keycode
;
3538 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3539 min_code
, max_code
- min_code
+ 1,
3541 mods
= XGetModifierMapping (dpyinfo
->display
);
3543 /* Scan the modifier table to see which modifier bits the Meta and
3544 Alt keysyms are on. */
3546 int row
, col
; /* The row and column in the modifier table. */
3548 for (row
= 3; row
< 8; row
++)
3549 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3552 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3554 /* Zeroes are used for filler. Skip them. */
3558 /* Are any of this keycode's keysyms a meta key? */
3562 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3564 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3570 dpyinfo
->meta_mod_mask
|= (1 << row
);
3575 dpyinfo
->alt_mod_mask
|= (1 << row
);
3580 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3585 dpyinfo
->super_mod_mask
|= (1 << row
);
3589 /* Ignore this if it's not on the lock modifier. */
3590 if ((1 << row
) == LockMask
)
3591 dpyinfo
->shift_lock_mask
= LockMask
;
3599 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3600 if (! dpyinfo
->meta_mod_mask
)
3602 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3603 dpyinfo
->alt_mod_mask
= 0;
3606 /* If some keys are both alt and meta,
3607 make them just meta, not alt. */
3608 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3610 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3613 XFree ((char *) syms
);
3614 XFreeModifiermap (mods
);
3617 #endif /* MAC_TODO */
3619 /* Convert between the modifier bits X uses and the modifier bits
3623 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3624 struct x_display_info
*dpyinfo
;
3625 unsigned short state
;
3627 return (((state
& shiftKey
) ? shift_modifier
: 0)
3628 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3629 | ((state
& cmdKey
) ? meta_modifier
: 0)
3630 | ((state
& optionKey
) ? alt_modifier
: 0));
3633 #if 0 /* MAC_TODO */
3634 static unsigned short
3635 x_emacs_to_x_modifiers (dpyinfo
, state
)
3636 struct x_display_info
*dpyinfo
;
3639 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3640 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3641 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3642 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3643 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3644 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3646 #endif /* MAC_TODO */
3648 /* Convert a keysym to its name. */
3651 x_get_keysym_name (keysym
)
3658 value
= XKeysymToString (keysym
);
3669 /* Mouse clicks and mouse movement. Rah. */
3671 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3673 If the event is a button press, then note that we have grabbed
3677 construct_mouse_click (result
, event
, f
)
3678 struct input_event
*result
;
3684 result
->kind
= MOUSE_CLICK_EVENT
;
3685 result
->code
= 0; /* only one mouse button */
3686 result
->timestamp
= event
->when
;
3687 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3689 mouseLoc
= event
->where
;
3691 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
3693 GlobalToLocal (&mouseLoc
);
3694 XSETINT (result
->x
, mouseLoc
.h
);
3695 XSETINT (result
->y
, mouseLoc
.v
);
3697 XSETFRAME (result
->frame_or_window
, f
);
3704 /* Function to report a mouse movement to the mainstream Emacs code.
3705 The input handler calls this.
3707 We have received a mouse movement event, which is given in *event.
3708 If the mouse is over a different glyph than it was last time, tell
3709 the mainstream emacs code by setting mouse_moved. If not, ask for
3710 another motion event, so we can check again the next time it moves. */
3712 static Point last_mouse_motion_position
;
3713 static Lisp_Object last_mouse_motion_frame
;
3716 note_mouse_movement (frame
, pos
)
3720 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
3721 #if TARGET_API_MAC_CARBON
3725 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3726 last_mouse_motion_position
= *pos
;
3727 XSETFRAME (last_mouse_motion_frame
, frame
);
3729 #if TARGET_API_MAC_CARBON
3730 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3732 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3735 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
3736 /* This case corresponds to LeaveNotify in X11. */
3738 /* If we move outside the frame, then we're certainly no
3739 longer on any text in the frame. */
3740 clear_mouse_face (dpyinfo
);
3741 dpyinfo
->mouse_face_mouse_frame
= 0;
3742 if (!dpyinfo
->grabbed
)
3743 rif
->define_frame_cursor (frame
,
3744 frame
->output_data
.mac
->nontext_cursor
);
3747 /* Has the mouse moved off the glyph it was on at the last sighting? */
3748 else if (pos
->h
< last_mouse_glyph
.left
3749 || pos
->h
>= last_mouse_glyph
.right
3750 || pos
->v
< last_mouse_glyph
.top
3751 || pos
->v
>= last_mouse_glyph
.bottom
)
3753 frame
->mouse_moved
= 1;
3754 last_mouse_scroll_bar
= Qnil
;
3755 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3759 /* This is used for debugging, to turn off note_mouse_highlight. */
3761 int disable_mouse_highlight
;
3765 /************************************************************************
3767 ************************************************************************/
3769 static struct scroll_bar
*x_window_to_scroll_bar ();
3770 static void x_scroll_bar_report_motion ();
3771 static void x_check_fullscreen
P_ ((struct frame
*));
3772 static void x_check_fullscreen_move
P_ ((struct frame
*));
3773 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3776 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3779 redo_mouse_highlight ()
3781 if (!NILP (last_mouse_motion_frame
)
3782 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3783 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3784 last_mouse_motion_position
.h
,
3785 last_mouse_motion_position
.v
);
3789 /* Try to determine frame pixel position and size of the glyph under
3790 frame pixel coordinates X/Y on frame F . Return the position and
3791 size in *RECT. Value is non-zero if we could compute these
3795 glyph_rect (f
, x
, y
, rect
)
3802 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3806 struct window
*w
= XWINDOW (window
);
3807 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3808 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3810 for (; r
< end
&& r
->enabled_p
; ++r
)
3811 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3813 /* Found the row at y. */
3814 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3815 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3818 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3819 rect
->bottom
= rect
->top
+ r
->height
;
3823 /* x is to the left of the first glyph in the row. */
3824 /* Shouldn't this be a pixel value?
3825 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3827 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3828 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3832 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3833 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3835 /* x is on a glyph. */
3836 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3837 rect
->right
= rect
->left
+ g
->pixel_width
;
3841 /* x is to the right of the last glyph in the row. */
3842 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3843 /* Shouldn't this be a pixel value?
3844 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3846 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3851 /* The y is not on any row. */
3855 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3857 /* Record the position of the mouse in last_mouse_glyph. */
3859 remember_mouse_glyph (f1
, gx
, gy
)
3863 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3865 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3866 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3868 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3869 round down even for negative values. */
3875 /* This was the original code from XTmouse_position, but it seems
3876 to give the position of the glyph diagonally next to the one
3877 the mouse is over. */
3878 gx
= (gx
+ width
- 1) / width
* width
;
3879 gy
= (gy
+ height
- 1) / height
* height
;
3881 gx
= gx
/ width
* width
;
3882 gy
= gy
/ height
* height
;
3885 last_mouse_glyph
.left
= gx
;
3886 last_mouse_glyph
.top
= gy
;
3887 last_mouse_glyph
.right
= gx
+ width
;
3888 last_mouse_glyph
.bottom
= gy
+ height
;
3894 front_emacs_window ()
3896 #if TARGET_API_MAC_CARBON
3897 WindowPtr wp
= GetFrontWindowOfClass (kDocumentWindowClass
, true);
3899 while (wp
&& !is_emacs_window (wp
))
3900 wp
= GetNextWindowOfClass (wp
, kDocumentWindowClass
, true);
3902 WindowPtr wp
= FrontWindow ();
3904 while (wp
&& (wp
== tip_window
|| !is_emacs_window (wp
)))
3905 wp
= GetNextWindow (wp
);
3911 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
3913 /* Return the current position of the mouse.
3914 *fp should be a frame which indicates which display to ask about.
3916 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3917 and *part to the frame, window, and scroll bar part that the mouse
3918 is over. Set *x and *y to the portion and whole of the mouse's
3919 position on the scroll bar.
3921 If the mouse movement started elsewhere, set *fp to the frame the
3922 mouse is on, *bar_window to nil, and *x and *y to the character cell
3925 Set *time to the server time-stamp for the time at which the mouse
3926 was at this position.
3928 Don't store anything if we don't have a valid set of values to report.
3930 This clears the mouse_moved flag, so we can wait for the next mouse
3934 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3937 Lisp_Object
*bar_window
;
3938 enum scroll_bar_part
*part
;
3940 unsigned long *time
;
3943 int ignore1
, ignore2
;
3944 WindowPtr wp
= front_emacs_window ();
3946 Lisp_Object frame
, tail
;
3948 if (is_emacs_window(wp
))
3949 f
= mac_window_to_frame (wp
);
3953 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3954 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3957 /* Clear the mouse-moved flag for every frame on this display. */
3958 FOR_EACH_FRAME (tail
, frame
)
3959 XFRAME (frame
)->mouse_moved
= 0;
3961 last_mouse_scroll_bar
= Qnil
;
3963 SetPortWindowPort (wp
);
3965 GetMouse (&mouse_pos
);
3967 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3968 &last_mouse_glyph
, insist
);
3971 *part
= scroll_bar_handle
;
3973 XSETINT (*x
, mouse_pos
.h
);
3974 XSETINT (*y
, mouse_pos
.v
);
3975 *time
= last_mouse_movement_time
;
3982 /***********************************************************************
3984 ***********************************************************************/
3986 /* Handle mouse button event on the tool-bar of frame F, at
3987 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3991 mac_handle_tool_bar_click (f
, button_event
)
3993 EventRecord
*button_event
;
3995 int x
= button_event
->where
.h
;
3996 int y
= button_event
->where
.v
;
3998 if (button_event
->what
== mouseDown
)
3999 handle_tool_bar_click (f
, x
, y
, 1, 0);
4001 handle_tool_bar_click (f
, x
, y
, 0,
4002 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
4003 button_event
->modifiers
));
4007 /************************************************************************
4008 Scroll bars, general
4009 ************************************************************************/
4011 /* Create a scroll bar and return the scroll bar vector for it. W is
4012 the Emacs window on which to create the scroll bar. TOP, LEFT,
4013 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4016 static struct scroll_bar
*
4017 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4019 int top
, left
, width
, height
, disp_top
, disp_height
;
4021 struct frame
*f
= XFRAME (w
->frame
);
4022 struct scroll_bar
*bar
4023 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4031 r
.right
= left
+ width
;
4032 r
.bottom
= disp_top
+ disp_height
;
4034 #ifdef TARGET_API_MAC_CARBON
4035 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
4036 kControlScrollBarProc
, 0L);
4038 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
4041 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4042 SetControlReference (ch
, (long) bar
);
4044 XSETWINDOW (bar
->window
, w
);
4045 XSETINT (bar
->top
, top
);
4046 XSETINT (bar
->left
, left
);
4047 XSETINT (bar
->width
, width
);
4048 XSETINT (bar
->height
, height
);
4049 XSETINT (bar
->start
, 0);
4050 XSETINT (bar
->end
, 0);
4051 bar
->dragging
= Qnil
;
4053 /* Add bar to its frame's list of scroll bars. */
4054 bar
->next
= FRAME_SCROLL_BARS (f
);
4056 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4057 if (!NILP (bar
->next
))
4058 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4065 /* Draw BAR's handle in the proper position.
4067 If the handle is already drawn from START to END, don't bother
4068 redrawing it, unless REBUILD is non-zero; in that case, always
4069 redraw it. (REBUILD is handy for drawing the handle after expose
4072 Normally, we want to constrain the start and end of the handle to
4073 fit inside its rectangle, but if the user is dragging the scroll
4074 bar handle, we want to let them drag it down all the way, so that
4075 the bar's top is as far down as it goes; otherwise, there's no way
4076 to move to the very end of the buffer. */
4079 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4080 struct scroll_bar
*bar
;
4084 int dragging
= ! NILP (bar
->dragging
);
4085 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4086 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4087 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4088 int length
= end
- start
;
4090 /* If the display is already accurate, do nothing. */
4092 && start
== XINT (bar
->start
)
4093 && end
== XINT (bar
->end
))
4098 /* Make sure the values are reasonable, and try to preserve the
4099 distance between start and end. */
4102 else if (start
> top_range
)
4104 end
= start
+ length
;
4108 else if (end
> top_range
&& ! dragging
)
4111 /* Store the adjusted setting in the scroll bar. */
4112 XSETINT (bar
->start
, start
);
4113 XSETINT (bar
->end
, end
);
4115 /* Clip the end position, just for display. */
4116 if (end
> top_range
)
4119 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4120 top positions, to make sure the handle is always at least that
4121 many pixels tall. */
4122 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4124 SetControlMinimum (ch
, 0);
4125 /* Don't inadvertently activate deactivated scroll bars */
4126 if (GetControlMaximum (ch
) != -1)
4127 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4129 SetControlValue (ch
, start
);
4130 #if TARGET_API_MAC_CARBON
4131 SetControlViewSize (ch
, end
- start
);
4138 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4142 x_scroll_bar_remove (bar
)
4143 struct scroll_bar
*bar
;
4145 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4149 /* Destroy the Mac scroll bar control */
4150 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4152 /* Disassociate this scroll bar from its window. */
4153 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4158 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4159 that we are displaying PORTION characters out of a total of WHOLE
4160 characters, starting at POSITION. If WINDOW has no scroll bar,
4163 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4165 int portion
, whole
, position
;
4167 struct frame
*f
= XFRAME (w
->frame
);
4168 struct scroll_bar
*bar
;
4169 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4170 int window_y
, window_height
;
4172 /* Get window dimensions. */
4173 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4178 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4180 height
= window_height
;
4182 /* Compute the left edge of the scroll bar area. */
4183 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4185 /* Compute the width of the scroll bar which might be less than
4186 the width of the area reserved for the scroll bar. */
4187 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4188 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4192 /* Compute the left edge of the scroll bar. */
4193 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4194 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
4196 sb_left
= left
+ (width
- sb_width
) / 2;
4198 /* Adjustments according to Inside Macintosh to make it look nice */
4200 disp_height
= height
;
4206 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4212 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4215 /* Does the scroll bar exist yet? */
4216 if (NILP (w
->vertical_scroll_bar
))
4219 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4220 left
, top
, width
, height
, 0);
4222 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4224 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4228 /* It may just need to be moved and resized. */
4231 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4232 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4236 /* If already correctly positioned, do nothing. */
4237 if (XINT (bar
->left
) == sb_left
4238 && XINT (bar
->top
) == top
4239 && XINT (bar
->width
) == sb_width
4240 && XINT (bar
->height
) == height
)
4244 /* Clear areas not covered by the scroll bar because it's not as
4245 wide as the area reserved for it . This makes sure a
4246 previous mode line display is cleared after C-x 2 C-x 1, for
4248 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4249 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4250 left
, top
, area_width
, height
, 0);
4253 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4254 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4255 sb_left
- 1, top
, 1, height
, 0);
4259 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4260 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4264 /* Remember new settings. */
4265 XSETINT (bar
->left
, sb_left
);
4266 XSETINT (bar
->top
, top
);
4267 XSETINT (bar
->width
, sb_width
);
4268 XSETINT (bar
->height
, height
);
4274 /* Set the scroll bar's current state, unless we're currently being
4276 if (NILP (bar
->dragging
))
4278 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4281 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4284 int start
= ((double) position
* top_range
) / whole
;
4285 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4286 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4292 /* The following three hooks are used when we're doing a thorough
4293 redisplay of the frame. We don't explicitly know which scroll bars
4294 are going to be deleted, because keeping track of when windows go
4295 away is a real pain - "Can you say set-window-configuration, boys
4296 and girls?" Instead, we just assert at the beginning of redisplay
4297 that *all* scroll bars are to be removed, and then save a scroll bar
4298 from the fiery pit when we actually redisplay its window. */
4300 /* Arrange for all scroll bars on FRAME to be removed at the next call
4301 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4302 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4305 XTcondemn_scroll_bars (frame
)
4308 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4309 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4312 bar
= FRAME_SCROLL_BARS (frame
);
4313 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4314 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4315 XSCROLL_BAR (bar
)->prev
= Qnil
;
4316 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4317 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4318 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4323 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4324 Note that WINDOW isn't necessarily condemned at all. */
4327 XTredeem_scroll_bar (window
)
4328 struct window
*window
;
4330 struct scroll_bar
*bar
;
4332 /* We can't redeem this window's scroll bar if it doesn't have one. */
4333 if (NILP (window
->vertical_scroll_bar
))
4336 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4338 /* Unlink it from the condemned list. */
4340 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4342 if (NILP (bar
->prev
))
4344 /* If the prev pointer is nil, it must be the first in one of
4346 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4347 /* It's not condemned. Everything's fine. */
4349 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4350 window
->vertical_scroll_bar
))
4351 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4353 /* If its prev pointer is nil, it must be at the front of
4354 one or the other! */
4358 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4360 if (! NILP (bar
->next
))
4361 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4363 bar
->next
= FRAME_SCROLL_BARS (f
);
4365 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4366 if (! NILP (bar
->next
))
4367 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4371 /* Remove all scroll bars on FRAME that haven't been saved since the
4372 last call to `*condemn_scroll_bars_hook'. */
4375 XTjudge_scroll_bars (f
)
4378 Lisp_Object bar
, next
;
4380 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4382 /* Clear out the condemned list now so we won't try to process any
4383 more events on the hapless scroll bars. */
4384 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4386 for (; ! NILP (bar
); bar
= next
)
4388 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4390 x_scroll_bar_remove (b
);
4393 b
->next
= b
->prev
= Qnil
;
4396 /* Now there should be no references to the condemned scroll bars,
4397 and they should get garbage-collected. */
4402 activate_scroll_bars (frame
)
4408 bar
= FRAME_SCROLL_BARS (frame
);
4409 while (! NILP (bar
))
4411 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4412 #ifdef TARGET_API_MAC_CARBON
4413 ActivateControl (ch
);
4415 SetControlMaximum (ch
,
4416 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4417 XINT (XSCROLL_BAR (bar
)
4420 bar
= XSCROLL_BAR (bar
)->next
;
4426 deactivate_scroll_bars (frame
)
4432 bar
= FRAME_SCROLL_BARS (frame
);
4433 while (! NILP (bar
))
4435 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4436 #ifdef TARGET_API_MAC_CARBON
4437 DeactivateControl (ch
);
4439 SetControlMaximum (ch
, XINT (-1));
4441 bar
= XSCROLL_BAR (bar
)->next
;
4445 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4446 is set to something other than NO_EVENT, it is enqueued.
4448 This may be called from a signal handler, so we have to ignore GC
4452 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4453 struct scroll_bar
*bar
;
4456 struct input_event
*bufp
;
4458 int win_y
, top_range
;
4460 if (! GC_WINDOWP (bar
->window
))
4463 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4464 bufp
->frame_or_window
= bar
->window
;
4467 bar
->dragging
= Qnil
;
4471 case kControlUpButtonPart
:
4472 bufp
->part
= scroll_bar_up_arrow
;
4474 case kControlDownButtonPart
:
4475 bufp
->part
= scroll_bar_down_arrow
;
4477 case kControlPageUpPart
:
4478 bufp
->part
= scroll_bar_above_handle
;
4480 case kControlPageDownPart
:
4481 bufp
->part
= scroll_bar_below_handle
;
4483 #ifdef TARGET_API_MAC_CARBON
4486 case kControlIndicatorPart
:
4488 if (er
->what
== mouseDown
)
4489 bar
->dragging
= make_number (0);
4490 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4491 bufp
->part
= scroll_bar_handle
;
4495 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
4496 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
4498 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4502 if (! NILP (bar
->dragging
))
4503 win_y
-= XINT (bar
->dragging
);
4507 if (win_y
> top_range
)
4510 XSETINT (bufp
->x
, win_y
);
4511 XSETINT (bufp
->y
, top_range
);
4515 /* Handle some mouse motion while someone is dragging the scroll bar.
4517 This may be called from a signal handler, so we have to ignore GC
4521 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4522 struct scroll_bar
*bar
;
4526 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4528 last_mouse_movement_time
= t
;
4531 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4533 /* If we're dragging the bar, display it. */
4534 if (! GC_NILP (bar
->dragging
))
4536 /* Where should the handle be now? */
4537 int new_start
= y_pos
- 24;
4539 if (new_start
!= XINT (bar
->start
))
4541 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4543 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4549 /* Return information to the user about the current position of the
4550 mouse on the scroll bar. */
4553 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4555 Lisp_Object
*bar_window
;
4556 enum scroll_bar_part
*part
;
4558 unsigned long *time
;
4560 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4561 WindowPtr wp
= front_emacs_window ();
4563 struct frame
*f
= mac_window_to_frame (wp
);
4564 int win_y
, top_range
;
4566 SetPortWindowPort (wp
);
4568 GetMouse (&mouse_pos
);
4570 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4571 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4573 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4577 if (! NILP (bar
->dragging
))
4578 win_y
-= XINT (bar
->dragging
);
4582 if (win_y
> top_range
)
4586 *bar_window
= bar
->window
;
4588 if (! NILP (bar
->dragging
))
4589 *part
= scroll_bar_handle
;
4590 else if (win_y
< XINT (bar
->start
))
4591 *part
= scroll_bar_above_handle
;
4592 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4593 *part
= scroll_bar_handle
;
4595 *part
= scroll_bar_below_handle
;
4597 XSETINT (*x
, win_y
);
4598 XSETINT (*y
, top_range
);
4601 last_mouse_scroll_bar
= Qnil
;
4603 *time
= last_mouse_movement_time
;
4606 /***********************************************************************
4608 ***********************************************************************/
4610 /* Set clipping for output in glyph row ROW. W is the window in which
4611 we operate. GC is the graphics context to set clipping in.
4613 ROW may be a text row or, e.g., a mode line. Text rows must be
4614 clipped to the interior of the window dedicated to text display,
4615 mode lines must be clipped to the whole window. */
4618 x_clip_to_row (w
, row
, area
, gc
)
4620 struct glyph_row
*row
;
4624 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4626 int window_x
, window_y
, window_width
;
4628 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
4630 clip_rect
.left
= window_x
;
4631 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4632 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4633 clip_rect
.right
= clip_rect
.left
+ window_width
;
4634 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4636 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4640 /* Draw a hollow box cursor on window W in glyph row ROW. */
4643 x_draw_hollow_cursor (w
, row
)
4645 struct glyph_row
*row
;
4647 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4648 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4649 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4652 struct glyph
*cursor_glyph
;
4655 /* Get the glyph the cursor is on. If we can't tell because
4656 the current matrix is invalid or such, give up. */
4657 cursor_glyph
= get_phys_cursor_glyph (w
);
4658 if (cursor_glyph
== NULL
)
4661 /* Compute the width of the rectangle to draw. If on a stretch
4662 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4663 rectangle as wide as the glyph, but use a canonical character
4665 wd
= cursor_glyph
->pixel_width
- 1;
4666 if (cursor_glyph
->type
== STRETCH_GLYPH
4667 && !x_stretch_cursor_p
)
4668 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4669 w
->phys_cursor_width
= wd
;
4671 /* Compute frame-relative coordinates from window-relative
4673 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4674 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4676 /* Compute the proper height and ascent of the rectangle, based
4677 on the actual glyph. Using the full height of the row looks
4678 bad when there are tall images on that row. */
4679 h
= max (min (FRAME_LINE_HEIGHT (f
), row
->height
),
4680 cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4681 if (h
< row
->height
)
4682 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4685 /* The foreground of cursor_gc is typically the same as the normal
4686 background color, which can cause the cursor box to be invisible. */
4687 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4688 if (dpyinfo
->scratch_cursor_gc
)
4689 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4691 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4692 GCForeground
, &xgcv
);
4693 gc
= dpyinfo
->scratch_cursor_gc
;
4695 /* Set clipping, draw the rectangle, and reset clipping again. */
4696 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4697 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4698 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4702 /* Draw a bar cursor on window W in glyph row ROW.
4704 Implementation note: One would like to draw a bar cursor with an
4705 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4706 Unfortunately, I didn't find a font yet that has this property set.
4710 x_draw_bar_cursor (w
, row
, width
, kind
)
4712 struct glyph_row
*row
;
4714 enum text_cursor_kinds kind
;
4716 struct frame
*f
= XFRAME (w
->frame
);
4717 struct glyph
*cursor_glyph
;
4719 /* If cursor is out of bounds, don't draw garbage. This can happen
4720 in mini-buffer windows when switching between echo area glyphs
4722 cursor_glyph
= get_phys_cursor_glyph (w
);
4723 if (cursor_glyph
== NULL
)
4726 /* If on an image, draw like a normal cursor. That's usually better
4727 visible than drawing a bar, esp. if the image is large so that
4728 the bar might not be in the window. */
4729 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4731 struct glyph_row
*row
;
4732 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4733 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4737 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4738 Window window
= FRAME_MAC_WINDOW (f
);
4739 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4740 unsigned long mask
= GCForeground
| GCBackground
;
4741 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4744 /* If the glyph's background equals the color we normally draw
4745 the bar cursor in, the bar cursor in its normal color is
4746 invisible. Use the glyph's foreground color instead in this
4747 case, on the assumption that the glyph's colors are chosen so
4748 that the glyph is legible. */
4749 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4750 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4752 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4755 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4758 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4759 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4763 width
= FRAME_CURSOR_WIDTH (f
);
4764 width
= min (cursor_glyph
->pixel_width
, width
);
4766 w
->phys_cursor_width
= width
;
4767 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4769 if (kind
== BAR_CURSOR
)
4770 XFillRectangle (dpy
, window
, gc
,
4771 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4772 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4773 width
, row
->height
);
4775 XFillRectangle (dpy
, window
, gc
,
4776 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4777 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4778 row
->height
- width
),
4779 cursor_glyph
->pixel_width
,
4782 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4787 /* RIF: Define cursor CURSOR on frame F. */
4790 mac_define_frame_cursor (f
, cursor
)
4794 #if TARGET_API_MAC_CARBON
4795 SetThemeCursor (cursor
);
4797 SetCursor (*cursor
);
4802 /* RIF: Clear area on frame F. */
4805 mac_clear_frame_area (f
, x
, y
, width
, height
)
4807 int x
, y
, width
, height
;
4809 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4810 x
, y
, width
, height
, 0);
4814 /* RIF: Draw cursor on window W. */
4817 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4819 struct glyph_row
*glyph_row
;
4821 int cursor_type
, cursor_width
;
4826 w
->phys_cursor_type
= cursor_type
;
4827 w
->phys_cursor_on_p
= 1;
4829 if (glyph_row
->exact_window_width_line_p
4830 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4832 glyph_row
->cursor_in_fringe_p
= 1;
4833 draw_fringe_bitmap (w
, glyph_row
, 0);
4836 switch (cursor_type
)
4838 case HOLLOW_BOX_CURSOR
:
4839 x_draw_hollow_cursor (w
, glyph_row
);
4842 case FILLED_BOX_CURSOR
:
4843 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4847 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4851 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4855 w
->phys_cursor_width
= 0;
4867 #if 0 /* MAC_TODO: no icon support yet. */
4869 x_bitmap_icon (f
, icon
)
4875 if (FRAME_W32_WINDOW (f
) == 0)
4879 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4880 else if (STRINGP (icon
))
4881 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4882 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4883 else if (SYMBOLP (icon
))
4887 if (EQ (icon
, intern ("application")))
4888 name
= (LPCTSTR
) IDI_APPLICATION
;
4889 else if (EQ (icon
, intern ("hand")))
4890 name
= (LPCTSTR
) IDI_HAND
;
4891 else if (EQ (icon
, intern ("question")))
4892 name
= (LPCTSTR
) IDI_QUESTION
;
4893 else if (EQ (icon
, intern ("exclamation")))
4894 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4895 else if (EQ (icon
, intern ("asterisk")))
4896 name
= (LPCTSTR
) IDI_ASTERISK
;
4897 else if (EQ (icon
, intern ("winlogo")))
4898 name
= (LPCTSTR
) IDI_WINLOGO
;
4902 hicon
= LoadIcon (NULL
, name
);
4910 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4915 #endif /* MAC_TODO */
4917 /************************************************************************
4919 ************************************************************************/
4921 /* Display Error Handling functions not used on W32. Listing them here
4922 helps diff stay in step when comparing w32term.c with xterm.c.
4924 x_error_catcher (display, error)
4925 x_catch_errors (dpy)
4926 x_catch_errors_unwind (old_val)
4927 x_check_errors (dpy, format)
4928 x_had_errors_p (dpy)
4929 x_clear_errors (dpy)
4930 x_uncatch_errors (dpy, count)
4932 x_connection_signal (signalnum)
4933 x_connection_closed (dpy, error_message)
4934 x_error_quitter (display, error)
4935 x_error_handler (display, error)
4936 x_io_error_quitter (display)
4941 /* Changing the font of the frame. */
4943 /* Give frame F the font named FONTNAME as its default font, and
4944 return the full name of that font. FONTNAME may be a wildcard
4945 pattern; in that case, we choose some font that fits the pattern.
4946 The return value shows which font we chose. */
4949 x_new_font (f
, fontname
)
4951 register char *fontname
;
4953 struct font_info
*fontp
4954 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4959 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4960 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4961 FRAME_FONTSET (f
) = -1;
4963 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4964 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4966 compute_fringe_widths (f
, 1);
4968 /* Compute the scroll bar width in character columns. */
4969 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4971 int wid
= FRAME_COLUMN_WIDTH (f
);
4972 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4973 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4977 int wid
= FRAME_COLUMN_WIDTH (f
);
4978 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4981 /* Now make the frame display the given font. */
4982 if (FRAME_MAC_WINDOW (f
) != 0)
4984 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4986 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4988 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4991 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4992 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4995 return build_string (fontp
->full_name
);
4998 /* Give frame F the fontset named FONTSETNAME as its default font, and
4999 return the full name of that fontset. FONTSETNAME may be a wildcard
5000 pattern; in that case, we choose some fontset that fits the pattern.
5001 The return value shows which fontset we chose. */
5004 x_new_fontset (f
, fontsetname
)
5008 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5014 if (FRAME_FONTSET (f
) == fontset
)
5015 /* This fontset is already set in frame F. There's nothing more
5017 return fontset_name (fontset
);
5019 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5021 if (!STRINGP (result
))
5022 /* Can't load ASCII font. */
5025 /* Since x_new_font doesn't update any fontset information, do it now. */
5026 FRAME_FONTSET(f
) = fontset
;
5028 return build_string (fontsetname
);
5032 /***********************************************************************
5033 TODO: W32 Input Methods
5034 ***********************************************************************/
5035 /* Listing missing functions from xterm.c helps diff stay in step.
5037 xim_destroy_callback (xim, client_data, call_data)
5038 xim_open_dpy (dpyinfo, resource_name)
5040 xim_instantiate_callback (display, client_data, call_data)
5041 xim_initialize (dpyinfo, resource_name)
5042 xim_close_dpy (dpyinfo)
5048 mac_get_window_bounds (f
, inner
, outer
)
5050 Rect
*inner
, *outer
;
5052 #if TARGET_API_MAC_CARBON
5053 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5054 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5055 #else /* not TARGET_API_MAC_CARBON */
5056 RgnHandle region
= NewRgn ();
5058 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5059 *inner
= (*region
)->rgnBBox
;
5060 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5061 *outer
= (*region
)->rgnBBox
;
5062 DisposeRgn (region
);
5063 #endif /* not TARGET_API_MAC_CARBON */
5067 /* Calculate the absolute position in frame F
5068 from its current recorded position values and gravity. */
5071 x_calc_absolute_position (f
)
5074 int width_diff
= 0, height_diff
= 0;
5075 int flags
= f
->size_hint_flags
;
5078 /* We have nothing to do if the current position
5079 is already for the top-left corner. */
5080 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5083 /* Find the offsets of the outside upper-left corner of
5084 the inner window, with respect to the outer window. */
5085 mac_get_window_bounds (f
, &inner
, &outer
);
5087 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5088 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5090 /* Treat negative positions as relative to the leftmost bottommost
5091 position that fits on the screen. */
5092 if (flags
& XNegative
)
5093 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5095 - FRAME_PIXEL_WIDTH (f
)
5098 if (flags
& YNegative
)
5099 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5101 - FRAME_PIXEL_HEIGHT (f
)
5104 /* The left_pos and top_pos
5105 are now relative to the top and left screen edges,
5106 so the flags should correspond. */
5107 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5110 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5111 to really change the position, and 0 when calling from
5112 x_make_frame_visible (in that case, XOFF and YOFF are the current
5113 position values). It is -1 when calling from x_set_frame_parameters,
5114 which means, do adjust for borders but don't change the gravity. */
5117 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5119 register int xoff
, yoff
;
5122 if (change_gravity
> 0)
5126 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5128 f
->size_hint_flags
|= XNegative
;
5130 f
->size_hint_flags
|= YNegative
;
5131 f
->win_gravity
= NorthWestGravity
;
5133 x_calc_absolute_position (f
);
5136 x_wm_set_size_hint (f
, (long) 0, 0);
5138 #if TARGET_API_MAC_CARBON
5139 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5140 /* If the title bar is completely outside the screen, adjust the
5142 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5143 kWindowConstrainMoveRegardlessOfFit
5144 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5145 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5148 Rect inner
, outer
, screen_rect
, dummy
;
5149 RgnHandle region
= NewRgn ();
5151 mac_get_window_bounds (f
, &inner
, &outer
);
5152 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5153 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5154 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5155 f
->top_pos
+ f
->y_pixels_diff
, false);
5157 /* If the title bar is completely outside the screen, adjust the
5158 position. The variable `outer' holds the title bar rectangle.
5159 The variable `inner' holds slightly smaller one than `outer',
5160 so that the calculation of overlapping may not become too
5162 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5163 outer
= (*region
)->rgnBBox
;
5164 DisposeRgn (region
);
5166 InsetRect (&inner
, 8, 8);
5167 screen_rect
= qd
.screenBits
.bounds
;
5168 screen_rect
.top
+= GetMBarHeight ();
5170 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5172 if (inner
.right
<= screen_rect
.left
)
5173 f
->left_pos
= screen_rect
.left
;
5174 else if (inner
.left
>= screen_rect
.right
)
5175 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5177 if (inner
.bottom
<= screen_rect
.top
)
5178 f
->top_pos
= screen_rect
.top
;
5179 else if (inner
.top
>= screen_rect
.bottom
)
5180 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5182 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5183 f
->top_pos
+ f
->y_pixels_diff
, false);
5191 /* Call this to change the size of frame F's x-window.
5192 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5193 for this size change and subsequent size changes.
5194 Otherwise we leave the window gravity unchanged. */
5197 x_set_window_size (f
, change_gravity
, cols
, rows
)
5202 int pixelwidth
, pixelheight
;
5206 check_frame_size (f
, &rows
, &cols
);
5207 f
->scroll_bar_actual_width
5208 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5210 compute_fringe_widths (f
, 0);
5212 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5213 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5215 f
->win_gravity
= NorthWestGravity
;
5216 x_wm_set_size_hint (f
, (long) 0, 0);
5218 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5220 /* Now, strictly speaking, we can't be sure that this is accurate,
5221 but the window manager will get around to dealing with the size
5222 change request eventually, and we'll hear how it went when the
5223 ConfigureNotify event gets here.
5225 We could just not bother storing any of this information here,
5226 and let the ConfigureNotify event set everything up, but that
5227 might be kind of confusing to the Lisp code, since size changes
5228 wouldn't be reported in the frame parameters until some random
5229 point in the future when the ConfigureNotify event arrives.
5231 We pass 1 for DELAY since we can't run Lisp code inside of
5233 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5234 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5235 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5237 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5238 receive in the ConfigureNotify event; if we get what we asked
5239 for, then the event won't cause the screen to become garbaged, so
5240 we have to make sure to do it here. */
5241 SET_FRAME_GARBAGED (f
);
5243 XFlush (FRAME_X_DISPLAY (f
));
5245 /* If cursor was outside the new size, mark it as off. */
5246 mark_window_cursors_off (XWINDOW (f
->root_window
));
5248 /* Clear out any recollection of where the mouse highlighting was,
5249 since it might be in a place that's outside the new frame size.
5250 Actually checking whether it is outside is a pain in the neck,
5251 so don't try--just let the highlighting be done afresh with new size. */
5252 cancel_mouse_face (f
);
5257 /* Mouse warping. */
5259 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5262 x_set_mouse_position (f
, x
, y
)
5268 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5269 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5271 if (pix_x
< 0) pix_x
= 0;
5272 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5274 if (pix_y
< 0) pix_y
= 0;
5275 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5277 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5281 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5285 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5288 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5289 0, 0, 0, 0, pix_x
, pix_y
);
5295 /* focus shifting, raising and lowering. */
5298 x_focus_on_frame (f
)
5301 #if 0 /* This proves to be unpleasant. */
5305 /* I don't think that the ICCCM allows programs to do things like this
5306 without the interaction of the window manager. Whatever you end up
5307 doing with this code, do it to x_unfocus_frame too. */
5308 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5309 RevertToPointerRoot
, CurrentTime
);
5319 /* Raise frame F. */
5324 if (f
->async_visible
)
5327 SelectWindow (FRAME_MAC_WINDOW (f
));
5332 /* Lower frame F. */
5337 if (f
->async_visible
)
5340 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5346 XTframe_raise_lower (f
, raise_flag
)
5356 /* Change of visibility. */
5358 /* This tries to wait until the frame is really visible.
5359 However, if the window manager asks the user where to position
5360 the frame, this will return before the user finishes doing that.
5361 The frame will not actually be visible at that time,
5362 but it will become visible later when the window manager
5363 finishes with it. */
5366 x_make_frame_visible (f
)
5370 int original_top
, original_left
;
5374 if (! FRAME_VISIBLE_P (f
))
5376 /* We test FRAME_GARBAGED_P here to make sure we don't
5377 call x_set_offset a second time
5378 if we get to x_make_frame_visible a second time
5379 before the window gets really visible. */
5380 if (! FRAME_ICONIFIED_P (f
)
5381 && ! f
->output_data
.mac
->asked_for_visible
)
5382 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5384 f
->output_data
.mac
->asked_for_visible
= 1;
5386 ShowWindow (FRAME_MAC_WINDOW (f
));
5389 XFlush (FRAME_MAC_DISPLAY (f
));
5391 /* Synchronize to ensure Emacs knows the frame is visible
5392 before we do anything else. We do this loop with input not blocked
5393 so that incoming events are handled. */
5398 /* This must come after we set COUNT. */
5401 XSETFRAME (frame
, f
);
5403 /* Wait until the frame is visible. Process X events until a
5404 MapNotify event has been seen, or until we think we won't get a
5405 MapNotify at all.. */
5406 for (count
= input_signal_count
+ 10;
5407 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5409 /* Force processing of queued events. */
5412 /* Machines that do polling rather than SIGIO have been
5413 observed to go into a busy-wait here. So we'll fake an
5414 alarm signal to let the handler know that there's something
5415 to be read. We used to raise a real alarm, but it seems
5416 that the handler isn't always enabled here. This is
5418 if (input_polling_used ())
5420 /* It could be confusing if a real alarm arrives while
5421 processing the fake one. Turn it off and let the
5422 handler reset it. */
5423 extern void poll_for_input_1
P_ ((void));
5424 int old_poll_suppress_count
= poll_suppress_count
;
5425 poll_suppress_count
= 1;
5426 poll_for_input_1 ();
5427 poll_suppress_count
= old_poll_suppress_count
;
5430 /* See if a MapNotify event has been processed. */
5431 FRAME_SAMPLE_VISIBILITY (f
);
5436 /* Change from mapped state to withdrawn state. */
5438 /* Make the frame visible (mapped and not iconified). */
5441 x_make_frame_invisible (f
)
5444 /* Don't keep the highlight on an invisible frame. */
5445 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5446 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5450 HideWindow (FRAME_MAC_WINDOW (f
));
5452 /* We can't distinguish this from iconification
5453 just by the event that we get from the server.
5454 So we can't win using the usual strategy of letting
5455 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5456 and synchronize with the server to make sure we agree. */
5458 FRAME_ICONIFIED_P (f
) = 0;
5459 f
->async_visible
= 0;
5460 f
->async_iconified
= 0;
5465 /* Change window state from mapped to iconified. */
5471 /* Don't keep the highlight on an invisible frame. */
5472 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5473 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5476 /* Review: Since window is still visible in dock, still allow updates? */
5477 if (f
->async_iconified
)
5483 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5489 /* Free X resources of frame F. */
5492 x_free_frame_resources (f
)
5495 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5496 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5501 if (wp
== tip_window
)
5502 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5503 closed' event. So we reset tip_window here. */
5506 free_frame_menubar (f
);
5508 if (FRAME_FACE_CACHE (f
))
5509 free_frame_faces (f
);
5513 xfree (f
->output_data
.mac
);
5514 f
->output_data
.mac
= NULL
;
5516 if (f
== dpyinfo
->x_focus_frame
)
5517 dpyinfo
->x_focus_frame
= 0;
5518 if (f
== dpyinfo
->x_focus_event_frame
)
5519 dpyinfo
->x_focus_event_frame
= 0;
5520 if (f
== dpyinfo
->x_highlight_frame
)
5521 dpyinfo
->x_highlight_frame
= 0;
5523 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5525 dpyinfo
->mouse_face_beg_row
5526 = dpyinfo
->mouse_face_beg_col
= -1;
5527 dpyinfo
->mouse_face_end_row
5528 = dpyinfo
->mouse_face_end_col
= -1;
5529 dpyinfo
->mouse_face_window
= Qnil
;
5530 dpyinfo
->mouse_face_deferred_gc
= 0;
5531 dpyinfo
->mouse_face_mouse_frame
= 0;
5538 /* Destroy the X window of frame F. */
5541 x_destroy_window (f
)
5544 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5546 x_free_frame_resources (f
);
5548 dpyinfo
->reference_count
--;
5552 /* Setting window manager hints. */
5554 /* Set the normal size hints for the window manager, for frame F.
5555 FLAGS is the flags word to use--or 0 meaning preserve the flags
5556 that the window now has.
5557 If USER_POSITION is nonzero, we set the USPosition
5558 flag (this is useful when FLAGS is 0). */
5560 x_wm_set_size_hint (f
, flags
, user_position
)
5565 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5566 XSizeHints size_hints
;
5568 #ifdef USE_X_TOOLKIT
5571 Dimension widget_width
, widget_height
;
5572 Window window
= XtWindow (f
->output_data
.x
->widget
);
5573 #else /* not USE_X_TOOLKIT */
5574 Window window
= FRAME_X_WINDOW (f
);
5575 #endif /* not USE_X_TOOLKIT */
5577 /* Setting PMaxSize caused various problems. */
5578 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5580 size_hints
.x
= f
->left_pos
;
5581 size_hints
.y
= f
->top_pos
;
5583 #ifdef USE_X_TOOLKIT
5584 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5585 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5586 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5587 size_hints
.height
= widget_height
;
5588 size_hints
.width
= widget_width
;
5589 #else /* not USE_X_TOOLKIT */
5590 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5591 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5592 #endif /* not USE_X_TOOLKIT */
5594 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5595 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5596 size_hints
.max_width
5597 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5598 size_hints
.max_height
5599 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5601 /* Calculate the base and minimum sizes.
5603 (When we use the X toolkit, we don't do it here.
5604 Instead we copy the values that the widgets are using, below.) */
5605 #ifndef USE_X_TOOLKIT
5607 int base_width
, base_height
;
5608 int min_rows
= 0, min_cols
= 0;
5610 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5611 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5613 check_frame_size (f
, &min_rows
, &min_cols
);
5615 /* The window manager uses the base width hints to calculate the
5616 current number of rows and columns in the frame while
5617 resizing; min_width and min_height aren't useful for this
5618 purpose, since they might not give the dimensions for a
5619 zero-row, zero-column frame.
5621 We use the base_width and base_height members if we have
5622 them; otherwise, we set the min_width and min_height members
5623 to the size for a zero x zero frame. */
5626 size_hints
.flags
|= PBaseSize
;
5627 size_hints
.base_width
= base_width
;
5628 size_hints
.base_height
= base_height
;
5629 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5630 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5632 size_hints
.min_width
= base_width
;
5633 size_hints
.min_height
= base_height
;
5637 /* If we don't need the old flags, we don't need the old hint at all. */
5640 size_hints
.flags
|= flags
;
5643 #endif /* not USE_X_TOOLKIT */
5646 XSizeHints hints
; /* Sometimes I hate X Windows... */
5647 long supplied_return
;
5651 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5654 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5657 #ifdef USE_X_TOOLKIT
5658 size_hints
.base_height
= hints
.base_height
;
5659 size_hints
.base_width
= hints
.base_width
;
5660 size_hints
.min_height
= hints
.min_height
;
5661 size_hints
.min_width
= hints
.min_width
;
5665 size_hints
.flags
|= flags
;
5670 if (hints
.flags
& PSize
)
5671 size_hints
.flags
|= PSize
;
5672 if (hints
.flags
& PPosition
)
5673 size_hints
.flags
|= PPosition
;
5674 if (hints
.flags
& USPosition
)
5675 size_hints
.flags
|= USPosition
;
5676 if (hints
.flags
& USSize
)
5677 size_hints
.flags
|= USSize
;
5681 #ifndef USE_X_TOOLKIT
5686 size_hints
.win_gravity
= f
->win_gravity
;
5687 size_hints
.flags
|= PWinGravity
;
5691 size_hints
.flags
&= ~ PPosition
;
5692 size_hints
.flags
|= USPosition
;
5694 #endif /* PWinGravity */
5697 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5699 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5701 #endif /* MAC_TODO */
5704 #if 0 /* MAC_TODO: hide application instead of iconify? */
5705 /* Used for IconicState or NormalState */
5708 x_wm_set_window_state (f
, state
)
5712 #ifdef USE_X_TOOLKIT
5715 XtSetArg (al
[0], XtNinitialState
, state
);
5716 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5717 #else /* not USE_X_TOOLKIT */
5718 Window window
= FRAME_X_WINDOW (f
);
5720 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5721 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5723 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5724 #endif /* not USE_X_TOOLKIT */
5728 x_wm_set_icon_pixmap (f
, pixmap_id
)
5734 #ifndef USE_X_TOOLKIT
5735 Window window
= FRAME_X_WINDOW (f
);
5740 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5741 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5745 /* It seems there is no way to turn off use of an icon pixmap.
5746 The following line does it, only if no icon has yet been created,
5747 for some window managers. But with mwm it crashes.
5748 Some people say it should clear the IconPixmapHint bit in this case,
5749 but that doesn't work, and the X consortium said it isn't the
5750 right thing at all. Since there is no way to win,
5751 best to explicitly give up. */
5753 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5759 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5763 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5764 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5767 #else /* not USE_X_TOOLKIT */
5769 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5770 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5772 #endif /* not USE_X_TOOLKIT */
5775 #endif /* MAC_TODO */
5778 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5782 #if 0 /* MAC_TODO: no icons on Mac */
5783 #ifdef USE_X_TOOLKIT
5784 Window window
= XtWindow (f
->output_data
.x
->widget
);
5786 Window window
= FRAME_X_WINDOW (f
);
5789 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5790 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5791 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5793 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5794 #endif /* MAC_TODO */
5798 /***********************************************************************
5800 ***********************************************************************/
5802 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5805 x_get_font_info (f
, font_idx
)
5809 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5812 /* the global font name table */
5813 char **font_name_table
= NULL
;
5814 int font_name_table_size
= 0;
5815 int font_name_count
= 0;
5818 /* compare two strings ignoring case */
5820 stricmp (const char *s
, const char *t
)
5822 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5825 return tolower (*s
) - tolower (*t
);
5828 /* compare two strings ignoring case and handling wildcard */
5830 wildstrieq (char *s1
, char *s2
)
5832 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5835 return stricmp (s1
, s2
) == 0;
5838 /* Assume parameter 1 is fully qualified, no wildcards. */
5840 mac_font_pattern_match (fontname
, pattern
)
5844 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5845 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5848 /* Copy fontname so we can modify it during comparison. */
5849 strcpy (font_name_copy
, fontname
);
5854 /* Turn pattern into a regexp and do a regexp match. */
5855 for (; *pattern
; pattern
++)
5857 if (*pattern
== '?')
5859 else if (*pattern
== '*')
5870 return (fast_c_string_match_ignore_case (build_string (regex
),
5871 font_name_copy
) >= 0);
5874 /* Two font specs are considered to match if their foundry, family,
5875 weight, slant, and charset match. */
5877 mac_font_match (char *mf
, char *xf
)
5879 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5880 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5882 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5883 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5884 return mac_font_pattern_match (mf
, xf
);
5886 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5887 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5888 return mac_font_pattern_match (mf
, xf
);
5890 return (wildstrieq (m_foundry
, x_foundry
)
5891 && wildstrieq (m_family
, x_family
)
5892 && wildstrieq (m_weight
, x_weight
)
5893 && wildstrieq (m_slant
, x_slant
)
5894 && wildstrieq (m_charset
, x_charset
))
5895 || mac_font_pattern_match (mf
, xf
);
5899 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5902 decode_mac_font_name (char *name
, int size
, short scriptcode
)
5904 Lisp_Object coding_system
;
5905 struct coding_system coding
;
5911 coding_system
= Qbig5
;
5914 coding_system
= Qcn_gb
;
5917 coding_system
= Qsjis
;
5920 coding_system
= Qeuc_kr
;
5926 setup_coding_system (coding_system
, &coding
);
5927 coding
.src_multibyte
= 0;
5928 coding
.dst_multibyte
= 1;
5929 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5930 coding
.composing
= COMPOSITION_DISABLED
;
5931 buf
= (char *) alloca (size
);
5933 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5934 bcopy (buf
, name
, coding
.produced
);
5935 name
[coding
.produced
] = '\0';
5940 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5942 char foundry
[32], family
[32], cs
[32];
5943 char xf
[256], *result
, *p
;
5945 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5947 strcpy(foundry
, "Apple");
5948 strcpy(family
, name
);
5953 strcpy(cs
, "big5-0");
5956 strcpy(cs
, "gb2312.1980-0");
5959 strcpy(cs
, "jisx0208.1983-sjis");
5962 /* Each Apple Japanese font is entered into the font table
5963 twice: once as a jisx0208.1983-sjis font and once as a
5964 jisx0201.1976-0 font. The latter can be used to display
5965 the ascii charset and katakana-jisx0201 charset. A
5966 negative script code signals that the name of this latter
5967 font is being built. */
5968 strcpy(cs
, "jisx0201.1976-0");
5971 strcpy(cs
, "ksc5601.1989-0");
5974 strcpy(cs
, "mac-roman");
5979 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5980 foundry
, family
, style
& bold
? "bold" : "medium",
5981 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5983 result
= (char *) xmalloc (strlen (xf
) + 1);
5984 strcpy (result
, xf
);
5985 for (p
= result
; *p
; p
++)
5991 /* Convert an X font spec to the corresponding mac font name, which
5992 can then be passed to GetFNum after conversion to a Pascal string.
5993 For ordinary Mac fonts, this should just be their names, like
5994 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5995 collection contain their charset designation in their names, like
5996 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5997 names are handled accordingly. */
5999 x_font_name_to_mac_font_name (char *xf
, char *mf
)
6001 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
6002 Lisp_Object coding_system
= Qnil
;
6003 struct coding_system coding
;
6007 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6008 foundry
, family
, weight
, slant
, cs
) != 5 &&
6009 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6010 foundry
, family
, weight
, slant
, cs
) != 5)
6013 if (strcmp (cs
, "big5-0") == 0)
6014 coding_system
= Qbig5
;
6015 else if (strcmp (cs
, "gb2312.1980-0") == 0)
6016 coding_system
= Qcn_gb
;
6017 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
6018 || strcmp (cs
, "jisx0201.1976-0") == 0)
6019 coding_system
= Qsjis
;
6020 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
6021 coding_system
= Qeuc_kr
;
6022 else if (strcmp (cs
, "mac-roman") == 0)
6023 strcpy (mf
, family
);
6025 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
6027 if (!NILP (coding_system
))
6029 setup_coding_system (coding_system
, &coding
);
6030 coding
.src_multibyte
= 1;
6031 coding
.dst_multibyte
= 1;
6032 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6033 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
6034 mf
[coding
.produced
] = '\0';
6040 add_font_name_table_entry (char *font_name
)
6042 if (font_name_table_size
== 0)
6044 font_name_table_size
= 16;
6045 font_name_table
= (char **)
6046 xmalloc (font_name_table_size
* sizeof (char *));
6048 else if (font_name_count
+ 1 >= font_name_table_size
)
6050 font_name_table_size
+= 16;
6051 font_name_table
= (char **)
6052 xrealloc (font_name_table
,
6053 font_name_table_size
* sizeof (char *));
6056 font_name_table
[font_name_count
++] = font_name
;
6059 /* Sets up the table font_name_table to contain the list of all fonts
6060 in the system the first time the table is used so that the Resource
6061 Manager need not be accessed every time this information is
6065 init_font_name_table ()
6067 #if TARGET_API_MAC_CARBON
6070 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
6072 FMFontFamilyIterator ffi
;
6073 FMFontFamilyInstanceIterator ffii
;
6076 /* Create a dummy instance iterator here to avoid creating and
6077 destroying it in the loop. */
6078 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6080 /* Create an iterator to enumerate the font families. */
6081 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6084 FMDisposeFontFamilyInstanceIterator (&ffii
);
6088 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6096 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6102 sc
= FontToScript (ff
);
6103 decode_mac_font_name (name
, sizeof (name
), sc
);
6105 /* Point the instance iterator at the current font family. */
6106 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6109 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6112 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6113 contained in Apple Japanese (SJIS) font. */
6117 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6119 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6121 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6123 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6128 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6130 if (sc
== smJapanese
)
6135 else if (sc
== -smJapanese
)
6140 /* Dispose of the iterators. */
6141 FMDisposeFontFamilyIterator (&ffi
);
6142 FMDisposeFontFamilyInstanceIterator (&ffii
);
6146 #endif /* TARGET_API_MAC_CARBON */
6148 SInt16 fontnum
, old_fontnum
;
6149 int num_mac_fonts
= CountResources('FOND');
6151 Handle font_handle
, font_handle_2
;
6152 short id
, scriptcode
;
6155 struct FontAssoc
*fat
;
6156 struct AsscEntry
*assc_entry
;
6158 GetPort (&port
); /* save the current font number used */
6159 #if TARGET_API_MAC_CARBON
6160 old_fontnum
= GetPortTextFont (port
);
6162 old_fontnum
= port
->txFont
;
6165 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6167 font_handle
= GetIndResource ('FOND', i
);
6171 GetResInfo (font_handle
, &id
, &type
, name
);
6172 GetFNum (name
, &fontnum
);
6178 scriptcode
= FontToScript (fontnum
);
6179 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6182 HLock (font_handle
);
6184 if (GetResourceSizeOnDisk (font_handle
)
6185 >= sizeof (struct FamRec
))
6187 fat
= (struct FontAssoc
*) (*font_handle
6188 + sizeof (struct FamRec
));
6190 = (struct AsscEntry
*) (*font_handle
6191 + sizeof (struct FamRec
)
6192 + sizeof (struct FontAssoc
));
6194 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6196 if (font_name_table_size
== 0)
6198 font_name_table_size
= 16;
6199 font_name_table
= (char **)
6200 xmalloc (font_name_table_size
* sizeof (char *));
6202 else if (font_name_count
>= font_name_table_size
)
6204 font_name_table_size
+= 16;
6205 font_name_table
= (char **)
6206 xrealloc (font_name_table
,
6207 font_name_table_size
* sizeof (char *));
6209 font_name_table
[font_name_count
++]
6210 = mac_to_x_fontname (name
,
6211 assc_entry
->fontSize
,
6212 assc_entry
->fontStyle
,
6214 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6215 parts are contained in Apple Japanese (SJIS)
6217 if (smJapanese
== scriptcode
)
6219 font_name_table
[font_name_count
++]
6220 = mac_to_x_fontname (name
,
6221 assc_entry
->fontSize
,
6222 assc_entry
->fontStyle
,
6228 HUnlock (font_handle
);
6229 font_handle_2
= GetNextFOND (font_handle
);
6230 ReleaseResource (font_handle
);
6231 font_handle
= font_handle_2
;
6233 while (ResError () == noErr
&& font_handle
);
6236 TextFont (old_fontnum
);
6237 #if TARGET_API_MAC_CARBON
6239 #endif /* TARGET_API_MAC_CARBON */
6243 enum xlfd_scalable_field_index
6245 XLFD_SCL_PIXEL_SIZE
,
6246 XLFD_SCL_POINT_SIZE
,
6251 static int xlfd_scalable_fields
[] =
6260 mac_do_list_fonts (pattern
, maxnames
)
6265 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6266 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6269 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6271 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6274 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6275 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6276 fonts are scaled according to the specified size. */
6279 field
= xlfd_scalable_fields
;
6287 if ('1' <= *ptr
&& *ptr
<= '9')
6289 *val
= *ptr
++ - '0';
6290 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6291 *val
= *val
* 10 + *ptr
++ - '0';
6298 ptr
= strchr (ptr
, '-');
6301 while (ptr
&& i
< 14);
6303 if (i
== 14 && ptr
== NULL
)
6305 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6307 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6308 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6310 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6312 scl_val
[XLFD_SCL_POINT_SIZE
] =
6313 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6315 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6317 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6318 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6322 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6327 /* Turn pattern into a regexp and do a regexp match. */
6328 for (; *pattern
; pattern
++)
6330 if (*pattern
== '?')
6332 else if (*pattern
== '*')
6338 *ptr
++ = tolower (*pattern
);
6343 pattern_regex
= build_string (regex
);
6345 for (i
= 0; i
< font_name_count
; i
++)
6347 fontname
= build_string (font_name_table
[i
]);
6348 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6350 font_list
= Fcons (fontname
, font_list
);
6353 if (maxnames
> 0 && n_fonts
>= maxnames
)
6356 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6357 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6359 int former_len
= ptr
- font_name_table
[i
];
6361 memcpy (scaled
, font_name_table
[i
], former_len
);
6362 sprintf (scaled
+ former_len
,
6363 "-%d-%d-75-75-m-%d-%s",
6364 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6365 scl_val
[XLFD_SCL_POINT_SIZE
],
6366 scl_val
[XLFD_SCL_AVGWIDTH
],
6367 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6368 fontname
= build_string (scaled
);
6369 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6371 font_list
= Fcons (fontname
, font_list
);
6374 if (maxnames
> 0 && n_fonts
>= maxnames
)
6382 /* Return a list of at most MAXNAMES font specs matching the one in
6383 PATTERN. Cache matching fonts for patterns in
6384 dpyinfo->name_list_element to avoid looking them up again by
6385 calling mac_font_pattern_match (slow). Return as many matching
6386 fonts as possible if MAXNAMES = -1. */
6389 x_list_fonts (struct frame
*f
,
6390 Lisp_Object pattern
,
6394 Lisp_Object newlist
= Qnil
, tem
, key
;
6395 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6397 if (font_name_table
== NULL
) /* Initialize when first used. */
6398 init_font_name_table ();
6402 tem
= XCDR (dpyinfo
->name_list_element
);
6403 key
= Fcons (pattern
, make_number (maxnames
));
6405 newlist
= Fassoc (key
, tem
);
6406 if (!NILP (newlist
))
6408 newlist
= Fcdr_safe (newlist
);
6413 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6415 /* MAC_TODO: add code for matching outline fonts here */
6419 XSETCDR (dpyinfo
->name_list_element
,
6420 Fcons (Fcons (key
, newlist
),
6421 XCDR (dpyinfo
->name_list_element
)));
6431 /* Check that FONT is valid on frame F. It is if it can be found in F's
6435 x_check_font (f
, font
)
6440 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6442 xassert (font
!= NULL
);
6444 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6445 if (dpyinfo
->font_table
[i
].name
6446 && font
== dpyinfo
->font_table
[i
].font
)
6449 xassert (i
< dpyinfo
->n_fonts
);
6452 #endif /* GLYPH_DEBUG != 0 */
6454 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6455 Note: There are (broken) X fonts out there with invalid XFontStruct
6456 min_bounds contents. For example, handa@etl.go.jp reports that
6457 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6458 have font->min_bounds.width == 0. */
6461 x_font_min_bounds (font
, w
, h
)
6462 MacFontStruct
*font
;
6466 * TODO: Windows does not appear to offer min bound, only
6467 * average and maximum width, and maximum height.
6469 *h
= FONT_HEIGHT (font
);
6470 *w
= FONT_WIDTH (font
);
6474 /* Compute the smallest character width and smallest font height over
6475 all fonts available on frame F. Set the members smallest_char_width
6476 and smallest_font_height in F's x_display_info structure to
6477 the values computed. Value is non-zero if smallest_font_height or
6478 smallest_char_width become smaller than they were before. */
6481 x_compute_min_glyph_bounds (f
)
6485 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6486 MacFontStruct
*font
;
6487 int old_width
= dpyinfo
->smallest_char_width
;
6488 int old_height
= dpyinfo
->smallest_font_height
;
6490 dpyinfo
->smallest_font_height
= 100000;
6491 dpyinfo
->smallest_char_width
= 100000;
6493 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6494 if (dpyinfo
->font_table
[i
].name
)
6496 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6499 font
= (MacFontStruct
*) fontp
->font
;
6500 xassert (font
!= (MacFontStruct
*) ~0);
6501 x_font_min_bounds (font
, &w
, &h
);
6503 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6504 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6507 xassert (dpyinfo
->smallest_char_width
> 0
6508 && dpyinfo
->smallest_font_height
> 0);
6510 return (dpyinfo
->n_fonts
== 1
6511 || dpyinfo
->smallest_char_width
< old_width
6512 || dpyinfo
->smallest_font_height
< old_height
);
6516 /* Determine whether given string is a fully-specified XLFD: all 14
6517 fields are present, none is '*'. */
6520 is_fully_specified_xlfd (char *p
)
6528 for (i
= 0; i
< 13; i
++)
6530 q
= strchr (p
+ 1, '-');
6533 if (q
- p
== 2 && *(p
+ 1) == '*')
6538 if (strchr (p
+ 1, '-') != NULL
)
6541 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6548 const int kDefaultFontSize
= 9;
6551 /* XLoadQueryFont creates and returns an internal representation for a
6552 font in a MacFontStruct struct. There is really no concept
6553 corresponding to "loading" a font on the Mac. But we check its
6554 existence and find the font number and all other information for it
6555 and store them in the returned MacFontStruct. */
6557 static MacFontStruct
*
6558 XLoadQueryFont (Display
*dpy
, char *fontname
)
6560 int i
, size
, is_two_byte_font
, char_width
;
6563 SInt16 old_fontnum
, old_fontsize
;
6567 Style fontface
= normal
;
6568 MacFontStruct
*font
;
6569 FontInfo the_fontinfo
;
6570 char s_weight
[7], c_slant
;
6572 if (is_fully_specified_xlfd (fontname
))
6576 Lisp_Object matched_fonts
;
6578 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6579 if (NILP (matched_fonts
))
6581 name
= SDATA (XCAR (matched_fonts
));
6584 GetPort (&port
); /* save the current font number used */
6585 #if TARGET_API_MAC_CARBON
6586 old_fontnum
= GetPortTextFont (port
);
6587 old_fontsize
= GetPortTextSize (port
);
6588 old_fontface
= GetPortTextFace (port
);
6590 old_fontnum
= port
->txFont
;
6591 old_fontsize
= port
->txSize
;
6592 old_fontface
= port
->txFace
;
6595 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6596 size
= kDefaultFontSize
;
6598 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6599 if (strcmp (s_weight
, "bold") == 0)
6602 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6606 x_font_name_to_mac_font_name (name
, mfontname
);
6608 GetFNum (mfontname
, &fontnum
);
6612 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6614 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6615 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6617 font
->mac_fontnum
= fontnum
;
6618 font
->mac_fontsize
= size
;
6619 font
->mac_fontface
= fontface
;
6620 font
->mac_scriptcode
= FontToScript (fontnum
);
6622 /* Apple Japanese (SJIS) font is listed as both
6623 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6624 (Roman script) in init_font_name_table (). The latter should be
6625 treated as a one-byte font. */
6630 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6632 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6633 font
->mac_scriptcode
= smRoman
;
6636 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6637 font
->mac_scriptcode
== smTradChinese
||
6638 font
->mac_scriptcode
== smSimpChinese
||
6639 font
->mac_scriptcode
== smKorean
;
6643 TextFace (fontface
);
6645 GetFontInfo (&the_fontinfo
);
6647 font
->ascent
= the_fontinfo
.ascent
;
6648 font
->descent
= the_fontinfo
.descent
;
6650 font
->min_byte1
= 0;
6651 if (is_two_byte_font
)
6652 font
->max_byte1
= 1;
6654 font
->max_byte1
= 0;
6655 font
->min_char_or_byte2
= 0x20;
6656 font
->max_char_or_byte2
= 0xff;
6658 if (is_two_byte_font
)
6660 /* Use the width of an "ideographic space" of that font because
6661 the_fontinfo.widMax returns the wrong width for some fonts. */
6662 switch (font
->mac_scriptcode
)
6665 char_width
= StringWidth("\p\x81\x40");
6668 char_width
= StringWidth("\p\xa1\x40");
6671 char_width
= StringWidth("\p\xa1\xa1");
6674 char_width
= StringWidth("\p\xa1\xa1");
6679 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6680 returns 15 for 12-point Monaco! */
6681 char_width
= CharWidth ('m');
6683 font
->max_bounds
.rbearing
= char_width
;
6684 font
->max_bounds
.lbearing
= 0;
6685 font
->max_bounds
.width
= char_width
;
6686 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6687 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6689 font
->min_bounds
= font
->max_bounds
;
6691 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6692 font
->per_char
= NULL
;
6695 font
->per_char
= (XCharStruct
*)
6696 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6700 for (c
= 0x20; c
<= 0xff; c
++)
6702 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6703 font
->per_char
[c
- 0x20].width
=
6704 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6709 TextFont (old_fontnum
); /* restore previous font number, size and face */
6710 TextSize (old_fontsize
);
6711 TextFace (old_fontface
);
6717 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6718 pointer to the structure font_info while allocating it dynamically.
6719 If SIZE is 0, load any size of font.
6720 If loading is failed, return NULL. */
6723 x_load_font (f
, fontname
, size
)
6725 register char *fontname
;
6728 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6729 Lisp_Object font_names
;
6731 /* Get a list of all the fonts that match this name. Once we
6732 have a list of matching fonts, we compare them against the fonts
6733 we already have by comparing names. */
6734 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6736 if (!NILP (font_names
))
6741 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6742 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6743 if (dpyinfo
->font_table
[i
].name
6744 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6745 SDATA (XCAR (tail
)))
6746 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6747 SDATA (XCAR (tail
)))))
6748 return (dpyinfo
->font_table
+ i
);
6751 /* Load the font and add it to the table. */
6754 struct MacFontStruct
*font
;
6755 struct font_info
*fontp
;
6756 unsigned long value
;
6759 /* If we have found fonts by x_list_font, load one of them. If
6760 not, we still try to load a font by the name given as FONTNAME
6761 because XListFonts (called in x_list_font) of some X server has
6762 a bug of not finding a font even if the font surely exists and
6763 is loadable by XLoadQueryFont. */
6764 if (size
> 0 && !NILP (font_names
))
6765 fontname
= (char *) SDATA (XCAR (font_names
));
6767 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6771 /* Find a free slot in the font table. */
6772 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6773 if (dpyinfo
->font_table
[i
].name
== NULL
)
6776 /* If no free slot found, maybe enlarge the font table. */
6777 if (i
== dpyinfo
->n_fonts
6778 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6781 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6782 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6784 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6787 fontp
= dpyinfo
->font_table
+ i
;
6788 if (i
== dpyinfo
->n_fonts
)
6791 /* Now fill in the slots of *FONTP. */
6793 bzero (fontp
, sizeof (*fontp
));
6795 fontp
->font_idx
= i
;
6796 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6797 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6799 fontp
->full_name
= fontp
->name
;
6801 fontp
->size
= font
->max_bounds
.width
;
6802 fontp
->height
= FONT_HEIGHT (font
);
6804 /* For some font, ascent and descent in max_bounds field is
6805 larger than the above value. */
6806 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6807 if (max_height
> fontp
->height
)
6808 fontp
->height
= max_height
;
6811 /* The slot `encoding' specifies how to map a character
6812 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6813 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6814 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6815 2:0xA020..0xFF7F). For the moment, we don't know which charset
6816 uses this font. So, we set information in fontp->encoding[1]
6817 which is never used by any charset. If mapping can't be
6818 decided, set FONT_ENCODING_NOT_DECIDED. */
6819 if (font
->mac_scriptcode
== smJapanese
)
6820 fontp
->encoding
[1] = 4;
6824 = (font
->max_byte1
== 0
6826 ? (font
->min_char_or_byte2
< 0x80
6827 ? (font
->max_char_or_byte2
< 0x80
6828 ? 0 /* 0x20..0x7F */
6829 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6830 : 1) /* 0xA0..0xFF */
6832 : (font
->min_byte1
< 0x80
6833 ? (font
->max_byte1
< 0x80
6834 ? (font
->min_char_or_byte2
< 0x80
6835 ? (font
->max_char_or_byte2
< 0x80
6836 ? 0 /* 0x2020..0x7F7F */
6837 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6838 : 3) /* 0x20A0..0x7FFF */
6839 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6840 : (font
->min_char_or_byte2
< 0x80
6841 ? (font
->max_char_or_byte2
< 0x80
6842 ? 2 /* 0xA020..0xFF7F */
6843 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6844 : 1))); /* 0xA0A0..0xFFFF */
6847 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6848 fontp
->baseline_offset
6849 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6850 ? (long) value
: 0);
6851 fontp
->relative_compose
6852 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6853 ? (long) value
: 0);
6854 fontp
->default_ascent
6855 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6856 ? (long) value
: 0);
6858 fontp
->baseline_offset
= 0;
6859 fontp
->relative_compose
= 0;
6860 fontp
->default_ascent
= 0;
6863 /* Set global flag fonts_changed_p to non-zero if the font loaded
6864 has a character with a smaller width than any other character
6865 before, or if the font loaded has a smalle>r height than any
6866 other font loaded before. If this happens, it will make a
6867 glyph matrix reallocation necessary. */
6868 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6875 /* Return a pointer to struct font_info of a font named FONTNAME for
6876 frame F. If no such font is loaded, return NULL. */
6879 x_query_font (f
, fontname
)
6881 register char *fontname
;
6883 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6886 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6887 if (dpyinfo
->font_table
[i
].name
6888 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6889 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6890 return (dpyinfo
->font_table
+ i
);
6895 /* Find a CCL program for a font specified by FONTP, and set the member
6896 `encoder' of the structure. */
6899 x_find_ccl_program (fontp
)
6900 struct font_info
*fontp
;
6902 Lisp_Object list
, elt
;
6904 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6908 && STRINGP (XCAR (elt
))
6909 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6915 struct ccl_program
*ccl
6916 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6918 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6921 fontp
->font_encoder
= ccl
;
6927 /* The Mac Event loop code */
6931 #include <Quickdraw.h>
6932 #include <Balloons.h>
6933 #include <Devices.h>
6935 #include <Gestalt.h>
6937 #include <Processes.h>
6939 #include <ToolUtils.h>
6940 #include <TextUtils.h>
6941 #include <Dialogs.h>
6944 #include <TextEncodingConverter.h>
6945 #include <Resources.h>
6950 #endif /* ! MAC_OSX */
6955 #define WINDOW_RESOURCE 128
6956 #define TERM_WINDOW_RESOURCE 129
6958 #define DEFAULT_NUM_COLS 80
6960 #define MIN_DOC_SIZE 64
6961 #define MAX_DOC_SIZE 32767
6963 /* sleep time for WaitNextEvent */
6964 #define WNE_SLEEP_AT_SUSPEND 10
6965 #define WNE_SLEEP_AT_RESUME 1
6967 /* true when cannot handle any Mac OS events */
6968 static int handling_window_update
= 0;
6971 /* the flag appl_is_suspended is used both for determining the sleep
6972 time to be passed to WaitNextEvent and whether the cursor should be
6973 drawn when updating the display. The cursor is turned off when
6974 Emacs is suspended. Redrawing it is unnecessary and what needs to
6975 be done depends on whether the cursor lies inside or outside the
6976 redraw region. So we might as well skip drawing it when Emacs is
6978 static Boolean app_is_suspended
= false;
6979 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6982 #define EXTRA_STACK_ALLOC (256 * 1024)
6984 #define ARGV_STRING_LIST_ID 129
6985 #define ABOUT_ALERT_ID 128
6986 #define RAM_TOO_LARGE_ALERT_ID 129
6988 Boolean terminate_flag
= false;
6990 /* Contains the string "reverse", which is a constant for mouse button emu.*/
6991 Lisp_Object Qreverse
;
6993 /* True if using command key as meta key. */
6994 Lisp_Object Vmac_command_key_is_meta
;
6996 /* Modifier associated with the option key, or nil for normal behavior. */
6997 Lisp_Object Vmac_option_modifier
;
6999 /* True if the ctrl and meta keys should be reversed. */
7000 Lisp_Object Vmac_reverse_ctrl_meta
;
7002 /* True if the option and command modifiers should be used to emulate
7003 a three button mouse */
7004 Lisp_Object Vmac_emulate_three_button_mouse
;
7006 #if USE_CARBON_EVENTS
7007 /* True if the mouse wheel button (i.e. button 4) should map to
7008 mouse-2, instead of mouse-3. */
7009 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7011 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7012 for processing before Emacs sees it. */
7013 Lisp_Object Vmac_pass_command_to_system
;
7015 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7016 for processing before Emacs sees it. */
7017 Lisp_Object Vmac_pass_control_to_system
;
7020 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
7021 to this text encoding */
7022 int mac_keyboard_text_encoding
;
7023 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
7025 /* Set in term/mac-win.el to indicate that event loop can now generate
7026 drag and drop events. */
7027 Lisp_Object Qmac_ready_for_drag_n_drop
;
7029 Lisp_Object drag_and_drop_file_list
;
7031 Point saved_menu_event_location
;
7033 #if !TARGET_API_MAC_CARBON
7034 /* Place holder for the default arrow cursor. */
7035 CursPtr arrow_cursor
;
7039 static void init_required_apple_events (void);
7041 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7043 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7044 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7045 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7048 static OSErr
init_mac_drag_n_drop ();
7049 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7051 #if USE_CARBON_EVENTS
7052 /* Preliminary Support for the OSX Services Menu */
7053 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
7054 static void init_service_handler ();
7057 extern void init_emacs_passwd_dir ();
7058 extern int emacs_main (int, char **, char **);
7059 extern void check_alarm ();
7061 extern void initialize_applescript();
7062 extern void terminate_applescript();
7065 #if USE_CARBON_EVENTS
7066 mac_to_emacs_modifiers (UInt32 mods
)
7068 mac_to_emacs_modifiers (EventModifiers mods
)
7071 unsigned int result
= 0;
7072 if (mods
& macShiftKey
)
7073 result
|= shift_modifier
;
7074 if (mods
& macCtrlKey
)
7075 result
|= ctrl_modifier
;
7076 if (mods
& macMetaKey
)
7077 result
|= meta_modifier
;
7078 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7079 result
|= alt_modifier
;
7080 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7081 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7083 result
|= XUINT(val
);
7090 mac_get_emulated_btn ( UInt32 modifiers
)
7093 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7094 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7095 if (modifiers
& cmdKey
)
7096 result
= cmdIs3
? 2 : 1;
7097 else if (modifiers
& optionKey
)
7098 result
= cmdIs3
? 1 : 2;
7103 #if USE_CARBON_EVENTS
7104 /* Obtains the event modifiers from the event ref and then calls
7105 mac_to_emacs_modifiers. */
7107 mac_event_to_emacs_modifiers (EventRef eventRef
)
7110 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7111 sizeof (UInt32
), NULL
, &mods
);
7112 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7113 GetEventClass(eventRef
) == kEventClassMouse
)
7115 mods
&= ~(optionKey
| cmdKey
);
7117 return mac_to_emacs_modifiers (mods
);
7120 /* Given an event ref, return the code to use for the mouse button
7121 code in the emacs input_event. */
7123 mac_get_mouse_btn (EventRef ref
)
7125 EventMouseButton result
= kEventMouseButtonPrimary
;
7126 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7127 sizeof (EventMouseButton
), NULL
, &result
);
7130 case kEventMouseButtonPrimary
:
7131 if (NILP (Vmac_emulate_three_button_mouse
))
7135 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7136 sizeof (UInt32
), NULL
, &mods
);
7137 return mac_get_emulated_btn(mods
);
7139 case kEventMouseButtonSecondary
:
7140 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7141 case kEventMouseButtonTertiary
:
7142 case 4: /* 4 is the number for the mouse wheel button */
7143 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7149 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7150 events. However the click of the mouse wheel is not converted to a
7151 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7152 checks to see if it is a mouse up or down carbon event that has not
7153 been converted, and if so, converts it by hand (to be picked up in
7154 the XTread_socket loop). */
7155 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7157 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7158 /* Do special case for mouse wheel button. */
7159 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7161 UInt32 kind
= GetEventKind (eventRef
);
7162 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7164 eventRec
->what
= mouseDown
;
7167 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7169 eventRec
->what
= mouseUp
;
7174 /* Need where and when. */
7176 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7177 typeQDPoint
, NULL
, sizeof (Point
),
7178 NULL
, &eventRec
->where
);
7179 /* Use two step process because new event modifiers are
7180 32-bit and old are 16-bit. Currently, only loss is
7182 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7183 typeUInt32
, NULL
, sizeof (UInt32
),
7185 eventRec
->modifiers
= mods
;
7187 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7198 Handle menubar_handle
;
7199 MenuHandle menu_handle
;
7201 menubar_handle
= GetNewMBar (128);
7202 if(menubar_handle
== NULL
)
7204 SetMenuBar (menubar_handle
);
7207 menu_handle
= GetMenuHandle (M_APPLE
);
7208 if(menu_handle
!= NULL
)
7209 AppendResMenu (menu_handle
,'DRVR');
7216 do_init_managers (void)
7218 #if !TARGET_API_MAC_CARBON
7219 InitGraf (&qd
.thePort
);
7221 FlushEvents (everyEvent
, 0);
7226 #endif /* !TARGET_API_MAC_CARBON */
7229 #if !TARGET_API_MAC_CARBON
7230 arrow_cursor
= &qd
.arrow
;
7232 /* set up some extra stack space for use by emacs */
7233 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7235 /* MaxApplZone must be called for AppleScript to execute more
7236 complicated scripts */
7239 #endif /* !TARGET_API_MAC_CARBON */
7243 do_check_ram_size (void)
7245 SInt32 physical_ram_size
, logical_ram_size
;
7247 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7248 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7249 || physical_ram_size
> (1 << VALBITS
)
7250 || logical_ram_size
> (1 << VALBITS
))
7252 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7258 do_window_update (WindowPtr win
)
7260 struct frame
*f
= mac_window_to_frame (win
);
7262 if (win
== tip_window
)
7263 /* The tooltip has been drawn already. Avoid the
7264 SET_FRAME_GARBAGED below. */
7269 if (f
->async_visible
== 0)
7271 f
->async_visible
= 1;
7272 f
->async_iconified
= 0;
7273 SET_FRAME_GARBAGED (f
);
7275 /* An update event is equivalent to MapNotify on X, so report
7276 visibility changes properly. */
7277 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7278 /* Force a redisplay sooner or later to update the
7279 frame titles in case this is the second frame. */
7280 record_asynch_buffer_change ();
7285 handling_window_update
= 1;
7287 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7289 expose_frame (f
, 0, 0, 0, 0);
7291 handling_window_update
= 0;
7298 is_emacs_window (WindowPtr win
)
7300 Lisp_Object tail
, frame
;
7305 FOR_EACH_FRAME (tail
, frame
)
7306 if (FRAME_MAC_P (XFRAME (frame
)))
7307 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7316 /* Window-activate events will do the job. */
7321 wp
= front_emacs_window ();
7324 f
= mac_window_to_frame (wp
);
7328 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7329 activate_scroll_bars (f
);
7333 app_is_suspended
= false;
7334 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7341 /* Window-deactivate events will do the job. */
7346 wp
= front_emacs_window ();
7349 f
= mac_window_to_frame (wp
);
7351 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7353 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7354 deactivate_scroll_bars (f
);
7358 app_is_suspended
= true;
7359 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7365 do_mouse_moved (mouse_pos
, f
)
7369 WindowPtr wp
= front_emacs_window ();
7370 struct x_display_info
*dpyinfo
;
7374 *f
= mac_window_to_frame (wp
);
7375 dpyinfo
= FRAME_MAC_DISPLAY_INFO (*f
);
7377 if (dpyinfo
->mouse_face_hidden
)
7379 dpyinfo
->mouse_face_hidden
= 0;
7380 clear_mouse_face (dpyinfo
);
7383 SetPortWindowPort (wp
);
7385 GlobalToLocal (&mouse_pos
);
7387 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
7388 x_scroll_bar_note_movement (tracked_scroll_bar
,
7390 - XINT (tracked_scroll_bar
->top
),
7391 TickCount() * (1000 / 60));
7393 note_mouse_movement (*f
, &mouse_pos
);
7399 do_apple_menu (SInt16 menu_item
)
7401 #if !TARGET_API_MAC_CARBON
7403 SInt16 da_driver_refnum
;
7405 if (menu_item
== I_ABOUT
)
7406 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7409 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7410 da_driver_refnum
= OpenDeskAcc (item_name
);
7412 #endif /* !TARGET_API_MAC_CARBON */
7416 do_menu_choice (SInt32 menu_choice
)
7418 SInt16 menu_id
, menu_item
;
7420 menu_id
= HiWord (menu_choice
);
7421 menu_item
= LoWord (menu_choice
);
7429 do_apple_menu (menu_item
);
7434 struct frame
*f
= mac_window_to_frame (front_emacs_window ());
7435 MenuHandle menu
= GetMenuHandle (menu_id
);
7440 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7441 menubar_selection_callback (f
, refcon
);
7450 /* Handle drags in size box. Based on code contributed by Ben
7451 Mesander and IM - Window Manager A. */
7454 do_grow_window (WindowPtr w
, EventRecord
*e
)
7459 struct frame
*f
= mac_window_to_frame (w
);
7461 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7463 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7465 /* see if it really changed size */
7468 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7469 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7471 x_set_window_size (f
, 0, columns
, rows
);
7476 /* Handle clicks in zoom box. Calculation of "standard state" based
7477 on code in IM - Window Manager A and code contributed by Ben
7478 Mesander. The standard state of an Emacs window is 80-characters
7479 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7482 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7485 Rect zoom_rect
, port_rect
;
7487 int w_title_height
, columns
, rows
;
7488 struct frame
*f
= mac_window_to_frame (w
);
7490 #if TARGET_API_MAC_CARBON
7492 Point standard_size
;
7494 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7495 standard_size
.v
= FRAME_MAC_DISPLAY_INFO (f
)->height
;
7497 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7498 zoom_in_or_out
= inZoomIn
;
7501 /* Adjust the standard size according to character boundaries. */
7503 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7504 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7505 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7506 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7507 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7508 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7509 && port_rect
.left
== zoom_rect
.left
7510 && port_rect
.top
== zoom_rect
.top
)
7511 zoom_in_or_out
= inZoomIn
;
7513 zoom_in_or_out
= inZoomOut
;
7516 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7518 #else /* not TARGET_API_MAC_CARBON */
7519 GetPort (&save_port
);
7521 SetPortWindowPort (w
);
7523 /* Clear window to avoid flicker. */
7524 EraseRect (&(w
->portRect
));
7525 if (zoom_in_or_out
== inZoomOut
)
7527 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7528 LocalToGlobal (&top_left
);
7530 /* calculate height of window's title bar */
7531 w_title_height
= top_left
.v
- 1
7532 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7534 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7535 zoom_rect
= qd
.screenBits
.bounds
;
7536 zoom_rect
.top
+= w_title_height
;
7537 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7539 zoom_rect
.right
= zoom_rect
.left
7540 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7542 /* Adjust the standard size according to character boundaries. */
7543 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7545 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7547 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7551 ZoomWindow (w
, zoom_in_or_out
, w
== front_emacs_window ());
7553 SetPort (save_port
);
7554 #endif /* not TARGET_API_MAC_CARBON */
7556 /* retrieve window size and update application values */
7557 #if TARGET_API_MAC_CARBON
7558 GetWindowPortBounds (w
, &port_rect
);
7560 port_rect
= w
->portRect
;
7562 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7563 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7564 x_set_window_size (f
, 0, columns
, rows
);
7565 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7568 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7570 init_mac_drag_n_drop ()
7572 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7576 /* Intialize AppleEvent dispatcher table for the required events. */
7578 init_required_apple_events ()
7583 /* Make sure we have apple events before starting. */
7584 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7588 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7591 #if TARGET_API_MAC_CARBON
7592 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7593 NewAEEventHandlerUPP
7594 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7597 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7598 NewAEEventHandlerProc
7599 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7605 #if TARGET_API_MAC_CARBON
7606 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7607 NewAEEventHandlerUPP
7608 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7611 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7612 NewAEEventHandlerProc
7613 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7619 #if TARGET_API_MAC_CARBON
7620 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7621 NewAEEventHandlerUPP
7622 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7625 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7626 NewAEEventHandlerProc
7627 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7633 #if TARGET_API_MAC_CARBON
7634 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7635 NewAEEventHandlerUPP
7636 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7639 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7640 NewAEEventHandlerProc
7641 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7648 #if USE_CARBON_EVENTS
7651 init_service_handler ()
7653 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7654 {kEventClassService
, kEventServiceCopy
},
7655 {kEventClassService
, kEventServicePaste
}};
7656 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7657 3, specs
, NULL
, NULL
);
7661 MAC_TODO: Check to see if this is called by AEProcessDesc...
7664 mac_handle_service_event (EventHandlerCallRef callRef
,
7665 EventRef event
, void *data
)
7667 OSStatus err
= noErr
;
7668 switch (GetEventKind (event
))
7670 case kEventServiceGetTypes
:
7672 CFMutableArrayRef copyTypes
, pasteTypes
;
7674 Boolean selection
= true;
7676 GetEventParameter(event, kEventParamServicePasteTypes,
7677 typeCFMutableArrayRef, NULL,
7678 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7680 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7681 typeCFMutableArrayRef
, NULL
,
7682 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7683 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7685 CFArrayAppendValue (copyTypes
, type
);
7686 //CFArrayAppendValue (pasteTypes, type);
7690 case kEventServiceCopy
:
7692 ScrapRef currentScrap
, specificScrap
;
7696 GetCurrentScrap (¤tScrap
);
7698 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7701 void *buffer
= xmalloc (byteCount
);
7704 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7705 sizeof (ScrapRef
), NULL
, &specificScrap
);
7707 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7708 &byteCount
, buffer
);
7710 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7711 kScrapFlavorMaskNone
, byteCount
, buffer
);
7717 case kEventServicePaste
:
7720 // Get the current location
7722 ScrapRef specificScrap;
7723 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7724 sizeof(ScrapRef), NULL, &specificScrap);
7725 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7727 void * buffer = xmalloc(byteCount);
7728 if (buffer != NULL ) {
7729 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7730 &byteCount, buffer);
7732 // Actually place in the buffer
7734 // Get the current "selection" string here
7747 /* Open Application Apple Event */
7749 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7755 /* Defined in mac.c. */
7757 path_from_vol_dir_name (char *, int, short, long, char *);
7760 /* Called when we receive an AppleEvent with an ID of
7761 "kAEOpenDocuments". This routine gets the direct parameter,
7762 extracts the FSSpecs in it, and puts their names on a list. */
7764 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7769 DescType actual_type
;
7772 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7774 goto descriptor_error_exit
;
7776 /* Check to see that we got all of the required parameters from the
7777 event descriptor. For an 'odoc' event this should just be the
7779 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7780 &actual_type
, (Ptr
) &keyword
,
7781 sizeof (keyword
), &actual_size
);
7782 /* No error means that we found some unused parameters.
7783 errAEDescNotFound means that there are no more parameters. If we
7784 get an error code other than that, flag it. */
7785 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7787 err
= errAEEventNotHandled
;
7792 /* Got all the parameters we need. Now, go through the direct
7793 object list and parse it up. */
7795 long num_files_to_open
;
7797 err
= AECountItems (&the_desc
, &num_files_to_open
);
7802 /* AE file list is one based so just use that for indexing here. */
7803 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7806 Str255 path_name
, unix_path_name
;
7811 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7812 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7813 if (err
!= noErr
) break;
7816 err
= FSpMakeFSRef (&fs
, &fref
);
7817 if (err
!= noErr
) break;
7819 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7821 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7823 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7825 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7826 drag_and_drop_file_list
);
7832 /* Nuke the coerced file list in any case */
7833 err2
= AEDisposeDesc(&the_desc
);
7835 descriptor_error_exit
:
7836 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7842 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7843 DragReference theDrag
)
7847 FlavorFlags theFlags
;
7850 ItemReference theItem
;
7853 Size size
= sizeof (HFSFlavor
);
7855 drag_and_drop_file_list
= Qnil
;
7856 GetDragMouse (theDrag
, &mouse
, 0L);
7857 CountDragItems (theDrag
, &items
);
7858 for (index
= 1; index
<= items
; index
++)
7860 /* Only handle file references. */
7861 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7862 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7863 if (result
== noErr
)
7870 Str255 unix_path_name
;
7871 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7873 /* Use Carbon routines, otherwise it converts the file name
7874 to /Macintosh HD/..., which is not correct. */
7875 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7876 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7878 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7879 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7880 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7882 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7883 drag_and_drop_file_list
);
7888 /* If there are items in the list, construct an event and post it to
7889 the queue like an interrupt using kbd_buffer_store_event. */
7890 if (!NILP (drag_and_drop_file_list
))
7892 struct input_event event
;
7894 struct frame
*f
= mac_window_to_frame (window
);
7895 SetPortWindowPort (window
);
7896 GlobalToLocal (&mouse
);
7898 event
.kind
= DRAG_N_DROP_EVENT
;
7900 event
.modifiers
= 0;
7901 event
.timestamp
= TickCount () * (1000 / 60);
7902 XSETINT (event
.x
, mouse
.h
);
7903 XSETINT (event
.y
, mouse
.v
);
7904 XSETFRAME (frame
, f
);
7905 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7907 /* Post to the interrupt queue */
7908 kbd_buffer_store_event (&event
);
7909 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7911 ProcessSerialNumber psn
;
7912 GetCurrentProcess (&psn
);
7913 SetFrontProcess (&psn
);
7919 /* Print Document Apple Event */
7921 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7923 return errAEEventNotHandled
;
7928 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7930 /* FixMe: Do we need an unwind-protect or something here? And what
7931 do we do about unsaved files. Currently just forces quit rather
7932 than doing recursive callback to get user input. */
7934 terminate_flag
= true;
7936 /* Fkill_emacs doesn't return. We have to return. (TI) */
7943 profiler_exit_proc ()
7945 ProfilerDump ("\pEmacs.prof");
7950 /* These few functions implement Emacs as a normal Mac application
7951 (almost): set up the heap and the Toolbox, handle necessary
7952 system events plus a few simple menu events. They also set up
7953 Emacs's access to functions defined in the rest of this file.
7954 Emacs uses function hooks to perform all its terminal I/O. A
7955 complete list of these functions appear in termhooks.h. For what
7956 they do, read the comments there and see also w32term.c and
7957 xterm.c. What's noticeably missing here is the event loop, which
7958 is normally present in most Mac application. After performing the
7959 necessary Mac initializations, main passes off control to
7960 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7961 mac_read_socket (defined further below) to read input. This is
7962 where WaitNextEvent is called to process Mac events. This is also
7963 where check_alarm in sysdep.c is called to simulate alarm signals.
7964 This makes the cursor jump back to its correct position after
7965 briefly jumping to that of the matching parenthesis, print useful
7966 hints and prompts in the minibuffer after the user stops typing for
7969 #if !TARGET_API_MAC_CARBON
7974 #if __profile__ /* is the profiler on? */
7975 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7980 /* set creator and type for files created by MSL */
7985 do_init_managers ();
7990 do_check_ram_size ();
7993 init_emacs_passwd_dir ();
7997 initialize_applescript ();
7999 init_required_apple_events ();
8005 /* set up argv array from STR# resource */
8006 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8010 /* free up AppleScript resources on exit */
8011 atexit (terminate_applescript
);
8013 #if __profile__ /* is the profiler on? */
8014 atexit (profiler_exit_proc
);
8017 /* 3rd param "envp" never used in emacs_main */
8018 (void) emacs_main (argc
, argv
, 0);
8021 /* Never reached - real exit in Fkill_emacs */
8026 /* Table for translating Mac keycode to X keysym values. Contributed
8027 by Sudhir Shenoy. */
8028 static unsigned char keycode_to_xkeysym_table
[] = {
8029 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8030 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8031 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8033 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8034 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
8035 /*0x38*/ 0, 0, 0, 0,
8036 /*0x3C*/ 0, 0, 0, 0,
8038 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8039 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
8040 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8041 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8043 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8044 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8045 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8046 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8048 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8049 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8050 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8051 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8053 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8054 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8055 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8056 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8060 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8062 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8063 return *xKeySym
!= 0;
8066 /* Emacs calls this whenever it wants to read an input event from the
8069 XTread_socket (sd
, expected
, hold_quit
)
8071 struct input_event
*hold_quit
;
8073 struct input_event inev
;
8075 #if USE_CARBON_EVENTS
8077 EventTargetRef toolbox_dispatcher
= GetEventDispatcherTarget ();
8079 EventMask event_mask
;
8082 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8084 if (interrupt_input_blocked
)
8086 interrupt_input_pending
= 1;
8090 interrupt_input_pending
= 0;
8093 /* So people can tell when we have read the available input. */
8094 input_signal_count
++;
8096 /* Don't poll for events to process (specifically updateEvt) if
8097 window update currently already in progress. A call to redisplay
8098 (in do_window_update) can be preempted by another call to
8099 redisplay, causing blank regions to be left on the screen and the
8100 cursor to be left at strange places. */
8101 if (handling_window_update
)
8108 Fkill_emacs (make_number (1));
8110 #if !USE_CARBON_EVENTS
8111 event_mask
= everyEvent
;
8112 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8113 event_mask
-= highLevelEventMask
;
8115 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
))
8116 #else /* USE_CARBON_EVENTS */
8117 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8118 kEventRemoveFromQueue
, &eventRef
))
8119 #endif /* USE_CARBON_EVENTS */
8124 /* It is necessary to set this (additional) argument slot of an
8125 event to nil because keyboard.c protects incompletely
8126 processed event from being garbage collected by placing them
8127 in the kbd_buffer_gcpro vector. */
8129 inev
.kind
= NO_EVENT
;
8132 #if USE_CARBON_EVENTS
8133 /* Handle new events */
8134 if (!mac_convert_event_ref (eventRef
, &er
))
8135 switch (GetEventClass (eventRef
))
8137 case kEventClassWindow
:
8138 if (GetEventKind (eventRef
) == kEventWindowBoundsChanged
)
8140 WindowPtr window_ptr
;
8141 GetEventParameter(eventRef
, kEventParamDirectObject
,
8142 typeWindowRef
, NULL
, sizeof(WindowPtr
),
8144 f
= mac_window_to_frame (window_ptr
);
8145 if (f
&& !f
->async_iconified
)
8146 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8147 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8150 case kEventClassMouse
:
8151 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8155 WindowPtr window_ptr
= front_emacs_window ();
8157 if (!IsValidWindowPtr (window_ptr
))
8163 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8164 typeSInt32
, NULL
, sizeof (SInt32
),
8166 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8167 typeQDPoint
, NULL
, sizeof (Point
),
8169 inev
.kind
= WHEEL_EVENT
;
8171 inev
.modifiers
= (mac_event_to_emacs_modifiers (eventRef
)
8172 | ((delta
< 0) ? down_modifier
8174 SetPortWindowPort (window_ptr
);
8175 GlobalToLocal (&point
);
8176 XSETINT (inev
.x
, point
.h
);
8177 XSETINT (inev
.y
, point
.v
);
8178 XSETFRAME (inev
.frame_or_window
,
8179 mac_window_to_frame (window_ptr
));
8180 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8183 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8187 /* Send the event to the appropriate receiver. */
8188 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8191 #endif /* USE_CARBON_EVENTS */
8197 WindowPtr window_ptr
;
8201 #if USE_CARBON_EVENTS
8202 /* This is needed to send mouse events like aqua window
8203 buttons to the correct handler. */
8204 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8205 != eventNotHandledErr
)
8209 if (dpyinfo
->grabbed
&& last_mouse_frame
8210 && FRAME_LIVE_P (last_mouse_frame
))
8212 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8213 part_code
= inContent
;
8217 part_code
= FindWindow (er
.where
, &window_ptr
);
8218 if (tip_window
&& window_ptr
== tip_window
)
8220 HideWindow (tip_window
);
8221 part_code
= FindWindow (er
.where
, &window_ptr
);
8225 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8231 f
= mac_window_to_frame (front_emacs_window ());
8232 saved_menu_event_location
= er
.where
;
8233 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8234 XSETFRAME (inev
.frame_or_window
, f
);
8238 if (window_ptr
!= front_emacs_window ())
8239 SelectWindow (window_ptr
);
8242 SInt16 control_part_code
;
8244 Point mouse_loc
= er
.where
;
8246 f
= mac_window_to_frame (window_ptr
);
8247 /* convert to local coordinates of new window */
8248 SetPortWindowPort (window_ptr
);
8250 GlobalToLocal (&mouse_loc
);
8251 #if TARGET_API_MAC_CARBON
8252 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8253 &control_part_code
);
8255 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8259 #if USE_CARBON_EVENTS
8260 inev
.code
= mac_get_mouse_btn (eventRef
);
8261 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8263 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8264 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8266 XSETINT (inev
.x
, mouse_loc
.h
);
8267 XSETINT (inev
.y
, mouse_loc
.v
);
8268 inev
.timestamp
= er
.when
* (1000 / 60);
8269 /* ticks to milliseconds */
8271 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8272 #if TARGET_API_MAC_CARBON
8275 || control_part_code
!= 0
8279 struct scroll_bar
*bar
;
8281 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8283 bar
= tracked_scroll_bar
;
8284 control_part_code
= kControlIndicatorPart
;
8287 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8288 x_scroll_bar_handle_click (bar
, control_part_code
,
8290 if (er
.what
== mouseDown
8291 && control_part_code
== kControlIndicatorPart
)
8292 tracked_scroll_bar
= bar
;
8294 tracked_scroll_bar
= NULL
;
8299 int x
= mouse_loc
.h
;
8300 int y
= mouse_loc
.v
;
8302 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
8303 if (EQ (window
, f
->tool_bar_window
))
8305 if (er
.what
== mouseDown
)
8306 handle_tool_bar_click (f
, x
, y
, 1, 0);
8308 handle_tool_bar_click (f
, x
, y
, 0,
8314 XSETFRAME (inev
.frame_or_window
, f
);
8315 inev
.kind
= MOUSE_CLICK_EVENT
;
8319 if (er
.what
== mouseDown
)
8321 dpyinfo
->grabbed
|= (1 << inev
.code
);
8322 last_mouse_frame
= f
;
8323 /* Ignore any mouse motion that happened
8324 before this event; any subsequent
8325 mouse-movement Emacs events should reflect
8326 only motion after the ButtonPress. */
8331 last_tool_bar_item
= -1;
8335 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
8336 /* If a button is released though it was not
8337 previously pressed, that would be because
8338 of multi-button emulation. */
8339 dpyinfo
->grabbed
= 0;
8341 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
8347 inev
.modifiers
|= down_modifier
;
8350 inev
.modifiers
|= up_modifier
;
8357 #if TARGET_API_MAC_CARBON
8358 DragWindow (window_ptr
, er
.where
, NULL
);
8359 #else /* not TARGET_API_MAC_CARBON */
8360 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8361 #endif /* not TARGET_API_MAC_CARBON */
8362 /* Update the frame parameters. */
8364 struct frame
*f
= mac_window_to_frame (window_ptr
);
8366 if (f
&& !f
->async_iconified
)
8367 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8372 if (TrackGoAway (window_ptr
, er
.where
))
8374 inev
.kind
= DELETE_WINDOW_EVENT
;
8375 XSETFRAME (inev
.frame_or_window
,
8376 mac_window_to_frame (window_ptr
));
8380 /* window resize handling added --ben */
8382 do_grow_window (window_ptr
, &er
);
8385 /* window zoom handling added --ben */
8388 if (TrackBox (window_ptr
, er
.where
, part_code
))
8389 do_zoom_window (window_ptr
, part_code
);
8399 #if USE_CARBON_EVENTS
8400 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8401 != eventNotHandledErr
)
8404 do_window_update ((WindowPtr
) er
.message
);
8408 #if USE_CARBON_EVENTS
8409 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8410 != eventNotHandledErr
)
8413 switch ((er
.message
>> 24) & 0x000000FF)
8415 case suspendResumeMessage
:
8416 if ((er
.message
& resumeFlag
) == 1)
8422 case mouseMovedMessage
:
8423 previous_help_echo_string
= help_echo_string
;
8424 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
8427 do_mouse_moved (er
.where
, &f
);
8429 /* If the contents of the global variable
8430 help_echo_string has changed, generate a
8432 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
8440 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
8442 #if USE_CARBON_EVENTS
8443 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8444 != eventNotHandledErr
)
8447 if (window_ptr
== tip_window
)
8449 HideWindow (tip_window
);
8453 if (!is_emacs_window (window_ptr
))
8456 f
= mac_window_to_frame (window_ptr
);
8458 if ((er
.modifiers
& activeFlag
) != 0)
8460 /* A window has been activated */
8461 Point mouse_loc
= er
.where
;
8463 x_new_focus_frame (dpyinfo
, f
);
8464 activate_scroll_bars (f
);
8466 SetPortWindowPort (window_ptr
);
8467 GlobalToLocal (&mouse_loc
);
8468 /* Window-activated event counts as mouse movement,
8469 so update things that depend on mouse position. */
8470 note_mouse_movement (mac_window_to_frame (window_ptr
),
8475 /* A window has been deactivated */
8476 dpyinfo
->grabbed
= 0;
8478 if (f
== dpyinfo
->x_focus_frame
)
8480 x_new_focus_frame (dpyinfo
, 0);
8481 deactivate_scroll_bars (f
);
8485 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8487 /* If we move outside the frame, then we're
8488 certainly no longer on any text in the
8490 clear_mouse_face (dpyinfo
);
8491 dpyinfo
->mouse_face_mouse_frame
= 0;
8494 /* Generate a nil HELP_EVENT to cancel a help-echo.
8495 Do it only if there's something to cancel.
8496 Otherwise, the startup message is cleared when the
8497 mouse leaves the frame. */
8498 if (any_help_event_p
)
8507 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8510 #if USE_CARBON_EVENTS
8511 /* When using Carbon Events, we need to pass raw keyboard
8512 events to the TSM ourselves. If TSM handles it, it
8513 will pass back noErr, otherwise it will pass back
8514 "eventNotHandledErr" and we can process it
8516 if ((!NILP (Vmac_pass_command_to_system
)
8517 || !(er
.modifiers
& cmdKey
))
8518 && (!NILP (Vmac_pass_control_to_system
)
8519 || !(er
.modifiers
& controlKey
)))
8520 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8521 != eventNotHandledErr
)
8525 #if TARGET_API_MAC_CARBON
8526 if (!IsValidWindowPtr (front_emacs_window ()))
8535 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8537 clear_mouse_face (dpyinfo
);
8538 dpyinfo
->mouse_face_hidden
= 1;
8541 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8543 inev
.code
= 0xff00 | xkeysym
;
8544 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8548 if (er
.modifiers
& (controlKey
|
8549 (NILP (Vmac_command_key_is_meta
) ? optionKey
8552 /* This code comes from Keyboard Resource,
8553 Appendix C of IM - Text. This is necessary
8554 since shift is ignored in KCHR table
8555 translation when option or command is pressed.
8556 It also does not translate correctly
8557 control-shift chars like C-% so mask off shift
8559 int new_modifiers
= er
.modifiers
& 0xe600;
8560 /* mask off option and command */
8561 int new_keycode
= keycode
| new_modifiers
;
8562 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8563 unsigned long some_state
= 0;
8564 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8565 &some_state
) & 0xff;
8566 } else if (!NILP(Vmac_option_modifier
) && (er
.modifiers
& optionKey
))
8568 /* When using the option key as an emacs modifier, convert
8569 the pressed key code back to one without the Mac option
8570 modifier applied. */
8571 int new_modifiers
= er
.modifiers
& ~optionKey
;
8572 int new_keycode
= keycode
| new_modifiers
;
8573 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8574 unsigned long some_state
= 0;
8575 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8576 &some_state
) & 0xff;
8579 inev
.code
= er
.message
& charCodeMask
;
8580 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8584 /* If variable mac-convert-keyboard-input-to-latin-1 is
8585 non-nil, convert non-ASCII characters typed at the Mac
8586 keyboard (presumed to be in the Mac Roman encoding) to
8587 iso-latin-1 encoding before they are passed to Emacs.
8588 This enables the Mac keyboard to be used to enter
8589 non-ASCII iso-latin-1 characters directly. */
8590 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8591 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8593 static TECObjectRef converter
= NULL
;
8594 OSStatus the_err
= noErr
;
8595 OSStatus convert_status
= noErr
;
8597 if (converter
== NULL
)
8599 the_err
= TECCreateConverter (&converter
,
8600 kTextEncodingMacRoman
,
8601 mac_keyboard_text_encoding
);
8602 current_mac_keyboard_text_encoding
8603 = mac_keyboard_text_encoding
;
8605 else if (mac_keyboard_text_encoding
8606 != current_mac_keyboard_text_encoding
)
8608 /* Free the converter for the current encoding
8609 before creating a new one. */
8610 TECDisposeConverter (converter
);
8611 the_err
= TECCreateConverter (&converter
,
8612 kTextEncodingMacRoman
,
8613 mac_keyboard_text_encoding
);
8614 current_mac_keyboard_text_encoding
8615 = mac_keyboard_text_encoding
;
8618 if (the_err
== noErr
)
8620 unsigned char ch
= inev
.code
;
8621 ByteCount actual_input_length
, actual_output_length
;
8622 unsigned char outch
;
8624 convert_status
= TECConvertText (converter
, &ch
, 1,
8625 &actual_input_length
,
8627 &actual_output_length
);
8628 if (convert_status
== noErr
8629 && actual_input_length
== 1
8630 && actual_output_length
== 1)
8635 #if USE_CARBON_EVENTS
8636 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8638 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8640 XSETFRAME (inev
.frame_or_window
,
8641 mac_window_to_frame (front_emacs_window ()));
8642 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8645 case kHighLevelEvent
:
8646 drag_and_drop_file_list
= Qnil
;
8648 AEProcessAppleEvent(&er
);
8650 /* Build a DRAG_N_DROP_EVENT type event as is done in
8651 constuct_drag_n_drop in w32term.c. */
8652 if (!NILP (drag_and_drop_file_list
))
8654 struct frame
*f
= NULL
;
8658 wp
= front_emacs_window ();
8662 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8663 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8664 wp
= front_emacs_window ();
8668 f
= mac_window_to_frame (wp
);
8670 inev
.kind
= DRAG_N_DROP_EVENT
;
8672 inev
.timestamp
= er
.when
* (1000 / 60);
8673 /* ticks to milliseconds */
8674 #if USE_CARBON_EVENTS
8675 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8677 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8680 XSETINT (inev
.x
, 0);
8681 XSETINT (inev
.y
, 0);
8683 XSETFRAME (frame
, f
);
8684 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8686 /* Regardless of whether Emacs was suspended or in the
8687 foreground, ask it to redraw its entire screen.
8688 Otherwise parts of the screen can be left in an
8689 inconsistent state. */
8691 #if TARGET_API_MAC_CARBON
8695 GetWindowPortBounds (wp
, &r
);
8696 InvalWindowRect (wp
, &r
);
8698 #else /* not TARGET_API_MAC_CARBON */
8699 InvalRect (&(wp
->portRect
));
8700 #endif /* not TARGET_API_MAC_CARBON */
8705 #if USE_CARBON_EVENTS
8706 ReleaseEvent (eventRef
);
8709 if (inev
.kind
!= NO_EVENT
)
8711 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8716 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
8721 XSETFRAME (frame
, f
);
8727 any_help_event_p
= 1;
8728 gen_help_event (help_echo_string
, frame
, help_echo_window
,
8729 help_echo_object
, help_echo_pos
);
8733 help_echo_string
= Qnil
;
8734 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
8741 /* If the focus was just given to an autoraising frame,
8743 /* ??? This ought to be able to handle more than one such frame. */
8744 if (pending_autoraise_frame
)
8746 x_raise_frame (pending_autoraise_frame
);
8747 pending_autoraise_frame
= 0;
8750 #if !TARGET_API_MAC_CARBON
8751 check_alarm (); /* simulate the handling of a SIGALRM */
8759 /* Need to override CodeWarrior's input function so no conversion is
8760 done on newlines Otherwise compiled functions in .elc files will be
8761 read incorrectly. Defined in ...:MSL C:MSL
8762 Common:Source:buffer_io.c. */
8765 __convert_to_newlines (unsigned char * p
, size_t * n
)
8771 __convert_from_newlines (unsigned char * p
, size_t * n
)
8778 /* Initialize the struct pointed to by MW to represent a new COLS x
8779 ROWS Macintosh window, using font with name FONTNAME and size
8782 make_mac_frame (FRAME_PTR fp
)
8785 #if TARGET_API_MAC_CARBON
8786 static int making_terminal_window
= 0;
8788 static int making_terminal_window
= 1;
8791 mwp
= fp
->output_data
.mac
;
8794 if (making_terminal_window
)
8796 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8799 making_terminal_window
= 0;
8803 #if TARGET_API_MAC_CARBON
8806 SetRect (&r
, 0, 0, 1, 1);
8807 if (CreateNewWindow (kDocumentWindowClass
,
8808 kWindowStandardDocumentAttributes
8809 /* | kWindowToolbarButtonAttribute */,
8810 &r
, &mwp
->mWP
) != noErr
)
8812 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8817 SetWRefCon (mwp
->mWP
, (long) mwp
);
8818 /* so that update events can find this mac_output struct */
8819 mwp
->mFP
= fp
; /* point back to emacs frame */
8821 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8827 make_mac_terminal_frame (struct frame
*f
)
8831 XSETFRAME (frame
, f
);
8833 f
->output_method
= output_mac
;
8834 f
->output_data
.mac
= (struct mac_output
*)
8835 xmalloc (sizeof (struct mac_output
));
8836 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8838 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8840 FRAME_COLS (f
) = 96;
8841 FRAME_LINES (f
) = 4;
8843 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8844 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8846 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8848 f
->output_data
.mac
->cursor_pixel
= 0;
8849 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8850 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8851 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8853 FRAME_FONTSET (f
) = -1;
8854 f
->output_data
.mac
->explicit_parent
= 0;
8857 f
->border_width
= 0;
8859 f
->internal_border_width
= 0;
8864 f
->new_text_cols
= 0;
8865 f
->new_text_lines
= 0;
8871 /* Need to be initialized for unshow_buffer in window.c. */
8872 selected_window
= f
->selected_window
;
8874 Fmodify_frame_parameters (frame
,
8875 Fcons (Fcons (Qfont
,
8876 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8877 Fmodify_frame_parameters (frame
,
8878 Fcons (Fcons (Qforeground_color
,
8879 build_string ("black")), Qnil
));
8880 Fmodify_frame_parameters (frame
,
8881 Fcons (Fcons (Qbackground_color
,
8882 build_string ("white")), Qnil
));
8884 ShowWindow (f
->output_data
.mac
->mWP
);
8888 /***********************************************************************
8890 ***********************************************************************/
8892 int mac_initialized
= 0;
8895 mac_initialize_display_info ()
8897 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8898 GDHandle main_device_handle
;
8900 bzero (dpyinfo
, sizeof (*dpyinfo
));
8902 /* Put it on x_display_name_list. */
8903 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8904 x_display_name_list
);
8905 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8908 dpyinfo
->mac_id_name
8909 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8910 + SCHARS (Vsystem_name
)
8912 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8913 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8915 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8916 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8919 main_device_handle
= LMGetMainDevice();
8921 dpyinfo
->reference_count
= 0;
8922 dpyinfo
->resx
= 75.0;
8923 dpyinfo
->resy
= 75.0;
8924 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
8926 /* HasDepth returns true if it is possible to have a 32 bit display,
8927 but this may not be what is actually used. Mac OSX can do better.
8928 CGMainDisplayID is only available on OSX 10.2 and higher, but the
8929 header for CGGetActiveDisplayList says that the first display returned
8930 is the active one, so we use that. */
8932 CGDirectDisplayID disp_id
[1];
8933 CGDisplayCount disp_count
;
8934 CGDisplayErr error_code
;
8936 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
8937 if (error_code
!= 0)
8938 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
8940 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
8943 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8944 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
8945 gdDevType
, dpyinfo
->color_p
))
8948 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8949 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8950 dpyinfo
->grabbed
= 0;
8951 dpyinfo
->root_window
= NULL
;
8952 dpyinfo
->image_cache
= make_image_cache ();
8954 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8955 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8956 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8957 dpyinfo
->mouse_face_window
= Qnil
;
8958 dpyinfo
->mouse_face_overlay
= Qnil
;
8959 dpyinfo
->mouse_face_hidden
= 0;
8962 struct mac_display_info
*
8963 mac_term_init (display_name
, xrm_option
, resource_name
)
8964 Lisp_Object display_name
;
8966 char *resource_name
;
8968 struct mac_display_info
*dpyinfo
;
8969 GDHandle main_device_handle
;
8971 if (!mac_initialized
)
8974 mac_initialized
= 1;
8977 mac_initialize_display_info (display_name
);
8979 dpyinfo
= &one_mac_display_info
;
8981 main_device_handle
= LMGetMainDevice();
8983 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8984 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8993 extern int inhibit_window_system
;
8994 extern int noninteractive
;
8995 CFBundleRef appsBundle
;
8998 /* No need to test if already -nw*/
8999 if (inhibit_window_system
|| noninteractive
)
9002 appsBundle
= CFBundleGetMainBundle();
9003 if (appsBundle
!= NULL
)
9005 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9006 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9007 /* We found the bundle identifier, now we know we are valid. */
9014 /* MAC_TODO: Have this start the bundled executable */
9016 /* For now, prevent the fatal error by bringing it up in the terminal */
9017 inhibit_window_system
= 1;
9021 MakeMeTheFrontProcess ()
9023 ProcessSerialNumber psn
;
9026 err
= GetCurrentProcess (&psn
);
9028 (void) SetFrontProcess (&psn
);
9031 /***** Code to handle C-g testing *****/
9033 /* Contains the Mac modifier formed from quit_char */
9034 static mac_quit_char_modifiers
= 0;
9035 static mac_quit_char_keycode
;
9036 extern int quit_char
;
9039 mac_determine_quit_char_modifiers()
9041 /* Todo: Determine modifiers from quit_char. */
9042 UInt32 qc_modifiers
= ctrl_modifier
;
9045 mac_quit_char_modifiers
= 0;
9046 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9047 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9048 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9049 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9053 init_quit_char_handler ()
9055 /* TODO: Let this support keys other the 'g' */
9056 mac_quit_char_keycode
= 5;
9057 /* Look at <architecture/adb_kb_map.h> for details */
9058 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9060 mac_determine_quit_char_modifiers();
9064 quit_char_comp (EventRef inEvent
, void *inCompData
)
9066 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9068 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9072 UInt32 keyModifiers
;
9073 GetEventParameter(inEvent
, kEventParamKeyCode
,
9074 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9075 if (keyCode
!= mac_quit_char_keycode
)
9077 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9078 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9079 if (keyModifiers
!= mac_quit_char_modifiers
)
9086 mac_check_for_quit_char ()
9089 static EMACS_TIME last_check_time
= { 0, 0 };
9090 static EMACS_TIME one_second
= { 1, 0 };
9093 /* If windows are not initialized, return immediately (keep it bouncin'). */
9094 if (!mac_quit_char_modifiers
)
9097 /* Don't check if last check is less than a second ago. */
9098 EMACS_GET_TIME (now
);
9099 EMACS_SUB_TIME (t
, now
, last_check_time
);
9100 if (EMACS_TIME_LT (t
, one_second
))
9102 last_check_time
= now
;
9104 /* Redetermine modifiers because they are based on lisp variables */
9105 mac_determine_quit_char_modifiers ();
9107 /* Fill the queue with events */
9109 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9110 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9115 struct input_event e
;
9117 /* Use an input_event to emulate what the interrupt handler does. */
9119 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9123 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9124 XSETFRAME (e
.frame_or_window
, mac_window_to_frame (front_emacs_window ()));
9125 /* Remove event from queue to prevent looping. */
9126 RemoveEventFromQueue (GetMainEventQueue (), event
);
9127 ReleaseEvent (event
);
9128 kbd_buffer_store_event (&e
);
9132 #endif /* MAC_OSX */
9134 /* Set up use of X before we make the first connection. */
9136 extern frame_parm_handler mac_frame_parm_handlers
[];
9138 static struct redisplay_interface x_redisplay_interface
=
9140 mac_frame_parm_handlers
,
9144 x_clear_end_of_line
,
9146 x_after_update_window_line
,
9147 x_update_window_begin
,
9148 x_update_window_end
,
9152 x_clear_window_mouse_face
,
9153 x_get_glyph_overhangs
,
9154 x_fix_overlapping_area
,
9155 x_draw_fringe_bitmap
,
9156 0, /* define_fringe_bitmap */
9157 0, /* destroy_fringe_bitmap */
9158 mac_per_char_metric
,
9160 NULL
, /* mac_compute_glyph_string_overhangs */
9161 x_draw_glyph_string
,
9162 mac_define_frame_cursor
,
9163 mac_clear_frame_area
,
9164 mac_draw_window_cursor
,
9165 mac_draw_vertical_window_border
,
9166 mac_shift_glyphs_for_insert
9172 rif
= &x_redisplay_interface
;
9174 clear_frame_hook
= x_clear_frame
;
9175 ins_del_lines_hook
= x_ins_del_lines
;
9176 delete_glyphs_hook
= x_delete_glyphs
;
9177 ring_bell_hook
= XTring_bell
;
9178 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9179 set_terminal_modes_hook
= XTset_terminal_modes
;
9180 update_begin_hook
= x_update_begin
;
9181 update_end_hook
= x_update_end
;
9182 set_terminal_window_hook
= XTset_terminal_window
;
9183 read_socket_hook
= XTread_socket
;
9184 frame_up_to_date_hook
= XTframe_up_to_date
;
9185 mouse_position_hook
= XTmouse_position
;
9186 frame_rehighlight_hook
= XTframe_rehighlight
;
9187 frame_raise_lower_hook
= XTframe_raise_lower
;
9189 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9190 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9191 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9192 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9194 scroll_region_ok
= 1; /* we'll scroll partial frames */
9195 char_ins_del_ok
= 1;
9196 line_ins_del_ok
= 1; /* we'll just blt 'em */
9197 fast_clear_end_of_line
= 1; /* X does this well */
9198 memory_below_frame
= 0; /* we don't remember what scrolls
9203 last_tool_bar_item
= -1;
9204 any_help_event_p
= 0;
9206 /* Try to use interrupt input; if we can't, then start polling. */
9207 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9209 #ifdef USE_X_TOOLKIT
9210 XtToolkitInitialize ();
9211 Xt_app_con
= XtCreateApplicationContext ();
9212 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9214 /* Install an asynchronous timer that processes Xt timeout events
9215 every 0.1s. This is necessary because some widget sets use
9216 timeouts internally, for example the LessTif menu bar, or the
9217 Xaw3d scroll bar. When Xt timouts aren't processed, these
9218 widgets don't behave normally. */
9220 EMACS_TIME interval
;
9221 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9222 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9226 #if USE_TOOLKIT_SCROLL_BARS
9227 xaw3d_arrow_scroll
= False
;
9228 xaw3d_pick_top
= True
;
9232 /* Note that there is no real way portable across R3/R4 to get the
9233 original error handler. */
9234 XSetErrorHandler (x_error_handler
);
9235 XSetIOErrorHandler (x_io_error_quitter
);
9237 /* Disable Window Change signals; they are handled by X events. */
9239 signal (SIGWINCH
, SIG_DFL
);
9240 #endif /* ! defined (SIGWINCH) */
9242 signal (SIGPIPE
, x_connection_signal
);
9246 mac_initialize_display_info ();
9248 #if TARGET_API_MAC_CARBON
9249 init_required_apple_events ();
9251 init_mac_drag_n_drop ();
9253 #if USE_CARBON_EVENTS
9254 init_service_handler ();
9256 init_quit_char_handler ();
9259 DisableMenuCommand (NULL
, kHICommandQuit
);
9261 if (!inhibit_window_system
)
9262 MakeMeTheFrontProcess ();
9272 staticpro (&x_error_message_string
);
9273 x_error_message_string
= Qnil
;
9276 Qmodifier_value
= intern ("modifier-value");
9277 Qalt
= intern ("alt");
9278 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
9279 Qhyper
= intern ("hyper");
9280 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
9281 Qsuper
= intern ("super");
9282 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
9284 Fprovide (intern ("mac-carbon"), Qnil
);
9286 staticpro (&Qreverse
);
9287 Qreverse
= intern ("reverse");
9289 staticpro (&x_display_name_list
);
9290 x_display_name_list
= Qnil
;
9292 staticpro (&last_mouse_scroll_bar
);
9293 last_mouse_scroll_bar
= Qnil
;
9295 staticpro (&Qvendor_specific_keysyms
);
9296 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9298 staticpro (&last_mouse_press_frame
);
9299 last_mouse_press_frame
= Qnil
;
9301 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9302 staticpro (&Qmac_ready_for_drag_n_drop
);
9304 Qbig5
= intern ("big5");
9307 Qcn_gb
= intern ("cn-gb");
9308 staticpro (&Qcn_gb
);
9310 Qsjis
= intern ("sjis");
9313 Qeuc_kr
= intern ("euc-kr");
9314 staticpro (&Qeuc_kr
);
9316 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9317 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9318 x_autoselect_window_p
= 0;
9320 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9321 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9322 Vx_toolkit_scroll_bars
= Qt
;
9324 DEFVAR_BOOL ("x-use-underline-position-properties",
9325 &x_use_underline_position_properties
,
9326 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9327 nil means ignore them. If you encounter fonts with bogus
9328 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9329 to 4.1, set this to nil. */);
9330 x_use_underline_position_properties
= 0;
9332 staticpro (&last_mouse_motion_frame
);
9333 last_mouse_motion_frame
= Qnil
;
9335 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9336 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9337 Otherwise the option key is used. */);
9338 Vmac_command_key_is_meta
= Qt
;
9340 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
9341 doc
: /* Modifier to use for the Mac alt/option key. The value can
9342 be alt, hyper, or super for the respective modifier. If the value is
9343 nil then the key will act as the normal Mac option modifier. */);
9344 Vmac_option_modifier
= Qnil
;
9346 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9347 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9348 useful for non-standard keyboard layouts. */);
9349 Vmac_reverse_ctrl_meta
= Qnil
;
9351 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9352 &Vmac_emulate_three_button_mouse
,
9353 doc
: /* t means that when the option-key is held down while pressing the
9354 mouse button, the click will register as mouse-2 and while the
9355 command-key is held down, the click will register as mouse-3.
9356 'reverse means that the the option-key will register for mouse-3
9357 and the command-key will register for mouse-2. nil means that
9358 not emulation should be done and the modifiers should be placed
9359 on the mouse-1 event. */);
9360 Vmac_emulate_three_button_mouse
= Qnil
;
9362 #if USE_CARBON_EVENTS
9363 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9364 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9365 the right click will be mouse-3.
9366 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9367 Vmac_wheel_button_is_mouse_2
= Qt
;
9369 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9370 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9371 Toolbox for processing before Emacs sees it. */);
9372 Vmac_pass_command_to_system
= Qt
;
9374 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9375 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9376 Toolbox for processing before Emacs sees it. */);
9377 Vmac_pass_control_to_system
= Qt
;
9380 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9381 doc
: /* One of the Text Encoding Base constant values defined in the
9382 Basic Text Constants section of Inside Macintosh - Text Encoding
9383 Conversion Manager. Its value determines the encoding characters
9384 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9385 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9386 its default value, no conversion takes place. If it is set to
9387 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9388 characters typed on Mac keyboard are first converted into the
9389 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9390 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9391 command, this enables the Mac keyboard to be used to enter non-ASCII
9392 characters directly. */);
9393 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9396 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9397 (do not change this comment) */