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
*, 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
, gc
);
1459 row
->visible_height
= oldVH
;
1462 x_clip_to_row (w
, row
, 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
, gc
)
4620 struct glyph_row
*row
;
4623 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4625 int window_y
, window_width
;
4627 window_box (w
, -1, 0, &window_y
, &window_width
, 0);
4629 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4630 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4631 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4632 clip_rect
.right
= clip_rect
.left
+ window_width
;
4633 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4635 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4639 /* Draw a hollow box cursor on window W in glyph row ROW. */
4642 x_draw_hollow_cursor (w
, row
)
4644 struct glyph_row
*row
;
4646 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4647 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4648 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4651 struct glyph
*cursor_glyph
;
4654 /* Get the glyph the cursor is on. If we can't tell because
4655 the current matrix is invalid or such, give up. */
4656 cursor_glyph
= get_phys_cursor_glyph (w
);
4657 if (cursor_glyph
== NULL
)
4660 /* Compute the width of the rectangle to draw. If on a stretch
4661 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4662 rectangle as wide as the glyph, but use a canonical character
4664 wd
= cursor_glyph
->pixel_width
- 1;
4665 if (cursor_glyph
->type
== STRETCH_GLYPH
4666 && !x_stretch_cursor_p
)
4667 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4668 w
->phys_cursor_width
= wd
;
4670 /* Compute frame-relative coordinates from window-relative
4672 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4673 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4675 /* Compute the proper height and ascent of the rectangle, based
4676 on the actual glyph. Using the full height of the row looks
4677 bad when there are tall images on that row. */
4678 h
= max (min (FRAME_LINE_HEIGHT (f
), row
->height
),
4679 cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4680 if (h
< row
->height
)
4681 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4684 /* The foreground of cursor_gc is typically the same as the normal
4685 background color, which can cause the cursor box to be invisible. */
4686 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4687 if (dpyinfo
->scratch_cursor_gc
)
4688 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4690 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4691 GCForeground
, &xgcv
);
4692 gc
= dpyinfo
->scratch_cursor_gc
;
4694 /* Set clipping, draw the rectangle, and reset clipping again. */
4695 x_clip_to_row (w
, row
, gc
);
4696 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4697 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4701 /* Draw a bar cursor on window W in glyph row ROW.
4703 Implementation note: One would like to draw a bar cursor with an
4704 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4705 Unfortunately, I didn't find a font yet that has this property set.
4709 x_draw_bar_cursor (w
, row
, width
, kind
)
4711 struct glyph_row
*row
;
4713 enum text_cursor_kinds kind
;
4715 struct frame
*f
= XFRAME (w
->frame
);
4716 struct glyph
*cursor_glyph
;
4718 /* If cursor is out of bounds, don't draw garbage. This can happen
4719 in mini-buffer windows when switching between echo area glyphs
4721 cursor_glyph
= get_phys_cursor_glyph (w
);
4722 if (cursor_glyph
== NULL
)
4725 /* If on an image, draw like a normal cursor. That's usually better
4726 visible than drawing a bar, esp. if the image is large so that
4727 the bar might not be in the window. */
4728 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4730 struct glyph_row
*row
;
4731 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4732 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4736 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4737 Window window
= FRAME_MAC_WINDOW (f
);
4738 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4739 unsigned long mask
= GCForeground
| GCBackground
;
4740 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4743 /* If the glyph's background equals the color we normally draw
4744 the bar cursor in, the bar cursor in its normal color is
4745 invisible. Use the glyph's foreground color instead in this
4746 case, on the assumption that the glyph's colors are chosen so
4747 that the glyph is legible. */
4748 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4749 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4751 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4754 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4757 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4758 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4762 width
= FRAME_CURSOR_WIDTH (f
);
4763 width
= min (cursor_glyph
->pixel_width
, width
);
4765 w
->phys_cursor_width
= width
;
4766 x_clip_to_row (w
, row
, gc
);
4768 if (kind
== BAR_CURSOR
)
4769 XFillRectangle (dpy
, window
, gc
,
4770 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4771 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4772 width
, row
->height
);
4774 XFillRectangle (dpy
, window
, gc
,
4775 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4776 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4777 row
->height
- width
),
4778 cursor_glyph
->pixel_width
,
4781 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4786 /* RIF: Define cursor CURSOR on frame F. */
4789 mac_define_frame_cursor (f
, cursor
)
4793 #if TARGET_API_MAC_CARBON
4794 SetThemeCursor (cursor
);
4796 SetCursor (*cursor
);
4801 /* RIF: Clear area on frame F. */
4804 mac_clear_frame_area (f
, x
, y
, width
, height
)
4806 int x
, y
, width
, height
;
4808 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4809 x
, y
, width
, height
, 0);
4813 /* RIF: Draw cursor on window W. */
4816 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4818 struct glyph_row
*glyph_row
;
4820 int cursor_type
, cursor_width
;
4825 w
->phys_cursor_type
= cursor_type
;
4826 w
->phys_cursor_on_p
= 1;
4828 if (glyph_row
->exact_window_width_line_p
4829 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4831 glyph_row
->cursor_in_fringe_p
= 1;
4832 draw_fringe_bitmap (w
, glyph_row
, 0);
4835 switch (cursor_type
)
4837 case HOLLOW_BOX_CURSOR
:
4838 x_draw_hollow_cursor (w
, glyph_row
);
4841 case FILLED_BOX_CURSOR
:
4842 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4846 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4850 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4854 w
->phys_cursor_width
= 0;
4866 #if 0 /* MAC_TODO: no icon support yet. */
4868 x_bitmap_icon (f
, icon
)
4874 if (FRAME_W32_WINDOW (f
) == 0)
4878 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4879 else if (STRINGP (icon
))
4880 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4881 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4882 else if (SYMBOLP (icon
))
4886 if (EQ (icon
, intern ("application")))
4887 name
= (LPCTSTR
) IDI_APPLICATION
;
4888 else if (EQ (icon
, intern ("hand")))
4889 name
= (LPCTSTR
) IDI_HAND
;
4890 else if (EQ (icon
, intern ("question")))
4891 name
= (LPCTSTR
) IDI_QUESTION
;
4892 else if (EQ (icon
, intern ("exclamation")))
4893 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4894 else if (EQ (icon
, intern ("asterisk")))
4895 name
= (LPCTSTR
) IDI_ASTERISK
;
4896 else if (EQ (icon
, intern ("winlogo")))
4897 name
= (LPCTSTR
) IDI_WINLOGO
;
4901 hicon
= LoadIcon (NULL
, name
);
4909 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4914 #endif /* MAC_TODO */
4916 /************************************************************************
4918 ************************************************************************/
4920 /* Display Error Handling functions not used on W32. Listing them here
4921 helps diff stay in step when comparing w32term.c with xterm.c.
4923 x_error_catcher (display, error)
4924 x_catch_errors (dpy)
4925 x_catch_errors_unwind (old_val)
4926 x_check_errors (dpy, format)
4927 x_had_errors_p (dpy)
4928 x_clear_errors (dpy)
4929 x_uncatch_errors (dpy, count)
4931 x_connection_signal (signalnum)
4932 x_connection_closed (dpy, error_message)
4933 x_error_quitter (display, error)
4934 x_error_handler (display, error)
4935 x_io_error_quitter (display)
4940 /* Changing the font of the frame. */
4942 /* Give frame F the font named FONTNAME as its default font, and
4943 return the full name of that font. FONTNAME may be a wildcard
4944 pattern; in that case, we choose some font that fits the pattern.
4945 The return value shows which font we chose. */
4948 x_new_font (f
, fontname
)
4950 register char *fontname
;
4952 struct font_info
*fontp
4953 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4958 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4959 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4960 FRAME_FONTSET (f
) = -1;
4962 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4963 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4965 compute_fringe_widths (f
, 1);
4967 /* Compute the scroll bar width in character columns. */
4968 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4970 int wid
= FRAME_COLUMN_WIDTH (f
);
4971 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4972 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4976 int wid
= FRAME_COLUMN_WIDTH (f
);
4977 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4980 /* Now make the frame display the given font. */
4981 if (FRAME_MAC_WINDOW (f
) != 0)
4983 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4985 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4987 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4990 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4991 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4994 return build_string (fontp
->full_name
);
4997 /* Give frame F the fontset named FONTSETNAME as its default font, and
4998 return the full name of that fontset. FONTSETNAME may be a wildcard
4999 pattern; in that case, we choose some fontset that fits the pattern.
5000 The return value shows which fontset we chose. */
5003 x_new_fontset (f
, fontsetname
)
5007 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5013 if (FRAME_FONTSET (f
) == fontset
)
5014 /* This fontset is already set in frame F. There's nothing more
5016 return fontset_name (fontset
);
5018 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5020 if (!STRINGP (result
))
5021 /* Can't load ASCII font. */
5024 /* Since x_new_font doesn't update any fontset information, do it now. */
5025 FRAME_FONTSET(f
) = fontset
;
5027 return build_string (fontsetname
);
5031 /***********************************************************************
5032 TODO: W32 Input Methods
5033 ***********************************************************************/
5034 /* Listing missing functions from xterm.c helps diff stay in step.
5036 xim_destroy_callback (xim, client_data, call_data)
5037 xim_open_dpy (dpyinfo, resource_name)
5039 xim_instantiate_callback (display, client_data, call_data)
5040 xim_initialize (dpyinfo, resource_name)
5041 xim_close_dpy (dpyinfo)
5047 mac_get_window_bounds (f
, inner
, outer
)
5049 Rect
*inner
, *outer
;
5051 #if TARGET_API_MAC_CARBON
5052 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5053 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5054 #else /* not TARGET_API_MAC_CARBON */
5055 RgnHandle region
= NewRgn ();
5057 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5058 *inner
= (*region
)->rgnBBox
;
5059 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5060 *outer
= (*region
)->rgnBBox
;
5061 DisposeRgn (region
);
5062 #endif /* not TARGET_API_MAC_CARBON */
5066 /* Calculate the absolute position in frame F
5067 from its current recorded position values and gravity. */
5070 x_calc_absolute_position (f
)
5073 int width_diff
= 0, height_diff
= 0;
5074 int flags
= f
->size_hint_flags
;
5077 /* We have nothing to do if the current position
5078 is already for the top-left corner. */
5079 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5082 /* Find the offsets of the outside upper-left corner of
5083 the inner window, with respect to the outer window. */
5084 mac_get_window_bounds (f
, &inner
, &outer
);
5086 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5087 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5089 /* Treat negative positions as relative to the leftmost bottommost
5090 position that fits on the screen. */
5091 if (flags
& XNegative
)
5092 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5094 - FRAME_PIXEL_WIDTH (f
)
5097 if (flags
& YNegative
)
5098 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5100 - FRAME_PIXEL_HEIGHT (f
)
5103 /* The left_pos and top_pos
5104 are now relative to the top and left screen edges,
5105 so the flags should correspond. */
5106 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5109 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5110 to really change the position, and 0 when calling from
5111 x_make_frame_visible (in that case, XOFF and YOFF are the current
5112 position values). It is -1 when calling from x_set_frame_parameters,
5113 which means, do adjust for borders but don't change the gravity. */
5116 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5118 register int xoff
, yoff
;
5121 if (change_gravity
> 0)
5125 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5127 f
->size_hint_flags
|= XNegative
;
5129 f
->size_hint_flags
|= YNegative
;
5130 f
->win_gravity
= NorthWestGravity
;
5132 x_calc_absolute_position (f
);
5135 x_wm_set_size_hint (f
, (long) 0, 0);
5137 #if TARGET_API_MAC_CARBON
5138 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5139 /* If the title bar is completely outside the screen, adjust the
5141 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5142 kWindowConstrainMoveRegardlessOfFit
5143 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5144 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5147 Rect inner
, outer
, screen_rect
, dummy
;
5148 RgnHandle region
= NewRgn ();
5150 mac_get_window_bounds (f
, &inner
, &outer
);
5151 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5152 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5153 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5154 f
->top_pos
+ f
->y_pixels_diff
, false);
5156 /* If the title bar is completely outside the screen, adjust the
5157 position. The variable `outer' holds the title bar rectangle.
5158 The variable `inner' holds slightly smaller one than `outer',
5159 so that the calculation of overlapping may not become too
5161 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5162 outer
= (*region
)->rgnBBox
;
5163 DisposeRgn (region
);
5165 InsetRect (&inner
, 8, 8);
5166 screen_rect
= qd
.screenBits
.bounds
;
5167 screen_rect
.top
+= GetMBarHeight ();
5169 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5171 if (inner
.right
<= screen_rect
.left
)
5172 f
->left_pos
= screen_rect
.left
;
5173 else if (inner
.left
>= screen_rect
.right
)
5174 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5176 if (inner
.bottom
<= screen_rect
.top
)
5177 f
->top_pos
= screen_rect
.top
;
5178 else if (inner
.top
>= screen_rect
.bottom
)
5179 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5181 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5182 f
->top_pos
+ f
->y_pixels_diff
, false);
5190 /* Call this to change the size of frame F's x-window.
5191 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5192 for this size change and subsequent size changes.
5193 Otherwise we leave the window gravity unchanged. */
5196 x_set_window_size (f
, change_gravity
, cols
, rows
)
5201 int pixelwidth
, pixelheight
;
5205 check_frame_size (f
, &rows
, &cols
);
5206 f
->scroll_bar_actual_width
5207 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5209 compute_fringe_widths (f
, 0);
5211 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5212 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5214 f
->win_gravity
= NorthWestGravity
;
5215 x_wm_set_size_hint (f
, (long) 0, 0);
5217 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5219 /* Now, strictly speaking, we can't be sure that this is accurate,
5220 but the window manager will get around to dealing with the size
5221 change request eventually, and we'll hear how it went when the
5222 ConfigureNotify event gets here.
5224 We could just not bother storing any of this information here,
5225 and let the ConfigureNotify event set everything up, but that
5226 might be kind of confusing to the Lisp code, since size changes
5227 wouldn't be reported in the frame parameters until some random
5228 point in the future when the ConfigureNotify event arrives.
5230 We pass 1 for DELAY since we can't run Lisp code inside of
5232 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5233 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5234 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5236 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5237 receive in the ConfigureNotify event; if we get what we asked
5238 for, then the event won't cause the screen to become garbaged, so
5239 we have to make sure to do it here. */
5240 SET_FRAME_GARBAGED (f
);
5242 XFlush (FRAME_X_DISPLAY (f
));
5244 /* If cursor was outside the new size, mark it as off. */
5245 mark_window_cursors_off (XWINDOW (f
->root_window
));
5247 /* Clear out any recollection of where the mouse highlighting was,
5248 since it might be in a place that's outside the new frame size.
5249 Actually checking whether it is outside is a pain in the neck,
5250 so don't try--just let the highlighting be done afresh with new size. */
5251 cancel_mouse_face (f
);
5256 /* Mouse warping. */
5258 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5261 x_set_mouse_position (f
, x
, y
)
5267 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5268 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5270 if (pix_x
< 0) pix_x
= 0;
5271 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5273 if (pix_y
< 0) pix_y
= 0;
5274 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5276 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5280 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5284 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5287 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5288 0, 0, 0, 0, pix_x
, pix_y
);
5294 /* focus shifting, raising and lowering. */
5297 x_focus_on_frame (f
)
5300 #if 0 /* This proves to be unpleasant. */
5304 /* I don't think that the ICCCM allows programs to do things like this
5305 without the interaction of the window manager. Whatever you end up
5306 doing with this code, do it to x_unfocus_frame too. */
5307 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5308 RevertToPointerRoot
, CurrentTime
);
5318 /* Raise frame F. */
5323 if (f
->async_visible
)
5326 SelectWindow (FRAME_MAC_WINDOW (f
));
5331 /* Lower frame F. */
5336 if (f
->async_visible
)
5339 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5345 XTframe_raise_lower (f
, raise_flag
)
5355 /* Change of visibility. */
5357 /* This tries to wait until the frame is really visible.
5358 However, if the window manager asks the user where to position
5359 the frame, this will return before the user finishes doing that.
5360 The frame will not actually be visible at that time,
5361 but it will become visible later when the window manager
5362 finishes with it. */
5365 x_make_frame_visible (f
)
5369 int original_top
, original_left
;
5373 if (! FRAME_VISIBLE_P (f
))
5375 /* We test FRAME_GARBAGED_P here to make sure we don't
5376 call x_set_offset a second time
5377 if we get to x_make_frame_visible a second time
5378 before the window gets really visible. */
5379 if (! FRAME_ICONIFIED_P (f
)
5380 && ! f
->output_data
.mac
->asked_for_visible
)
5381 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5383 f
->output_data
.mac
->asked_for_visible
= 1;
5385 ShowWindow (FRAME_MAC_WINDOW (f
));
5388 XFlush (FRAME_MAC_DISPLAY (f
));
5390 /* Synchronize to ensure Emacs knows the frame is visible
5391 before we do anything else. We do this loop with input not blocked
5392 so that incoming events are handled. */
5397 /* This must come after we set COUNT. */
5400 XSETFRAME (frame
, f
);
5402 /* Wait until the frame is visible. Process X events until a
5403 MapNotify event has been seen, or until we think we won't get a
5404 MapNotify at all.. */
5405 for (count
= input_signal_count
+ 10;
5406 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5408 /* Force processing of queued events. */
5411 /* Machines that do polling rather than SIGIO have been
5412 observed to go into a busy-wait here. So we'll fake an
5413 alarm signal to let the handler know that there's something
5414 to be read. We used to raise a real alarm, but it seems
5415 that the handler isn't always enabled here. This is
5417 if (input_polling_used ())
5419 /* It could be confusing if a real alarm arrives while
5420 processing the fake one. Turn it off and let the
5421 handler reset it. */
5422 extern void poll_for_input_1
P_ ((void));
5423 int old_poll_suppress_count
= poll_suppress_count
;
5424 poll_suppress_count
= 1;
5425 poll_for_input_1 ();
5426 poll_suppress_count
= old_poll_suppress_count
;
5429 /* See if a MapNotify event has been processed. */
5430 FRAME_SAMPLE_VISIBILITY (f
);
5435 /* Change from mapped state to withdrawn state. */
5437 /* Make the frame visible (mapped and not iconified). */
5440 x_make_frame_invisible (f
)
5443 /* Don't keep the highlight on an invisible frame. */
5444 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5445 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5449 HideWindow (FRAME_MAC_WINDOW (f
));
5451 /* We can't distinguish this from iconification
5452 just by the event that we get from the server.
5453 So we can't win using the usual strategy of letting
5454 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5455 and synchronize with the server to make sure we agree. */
5457 FRAME_ICONIFIED_P (f
) = 0;
5458 f
->async_visible
= 0;
5459 f
->async_iconified
= 0;
5464 /* Change window state from mapped to iconified. */
5470 /* Don't keep the highlight on an invisible frame. */
5471 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5472 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5475 /* Review: Since window is still visible in dock, still allow updates? */
5476 if (f
->async_iconified
)
5482 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5488 /* Free X resources of frame F. */
5491 x_free_frame_resources (f
)
5494 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5495 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5500 if (wp
== tip_window
)
5501 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5502 closed' event. So we reset tip_window here. */
5505 free_frame_menubar (f
);
5507 if (FRAME_FACE_CACHE (f
))
5508 free_frame_faces (f
);
5512 xfree (f
->output_data
.mac
);
5513 f
->output_data
.mac
= NULL
;
5515 if (f
== dpyinfo
->x_focus_frame
)
5516 dpyinfo
->x_focus_frame
= 0;
5517 if (f
== dpyinfo
->x_focus_event_frame
)
5518 dpyinfo
->x_focus_event_frame
= 0;
5519 if (f
== dpyinfo
->x_highlight_frame
)
5520 dpyinfo
->x_highlight_frame
= 0;
5522 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5524 dpyinfo
->mouse_face_beg_row
5525 = dpyinfo
->mouse_face_beg_col
= -1;
5526 dpyinfo
->mouse_face_end_row
5527 = dpyinfo
->mouse_face_end_col
= -1;
5528 dpyinfo
->mouse_face_window
= Qnil
;
5529 dpyinfo
->mouse_face_deferred_gc
= 0;
5530 dpyinfo
->mouse_face_mouse_frame
= 0;
5537 /* Destroy the X window of frame F. */
5540 x_destroy_window (f
)
5543 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5545 x_free_frame_resources (f
);
5547 dpyinfo
->reference_count
--;
5551 /* Setting window manager hints. */
5553 /* Set the normal size hints for the window manager, for frame F.
5554 FLAGS is the flags word to use--or 0 meaning preserve the flags
5555 that the window now has.
5556 If USER_POSITION is nonzero, we set the USPosition
5557 flag (this is useful when FLAGS is 0). */
5559 x_wm_set_size_hint (f
, flags
, user_position
)
5564 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5565 XSizeHints size_hints
;
5567 #ifdef USE_X_TOOLKIT
5570 Dimension widget_width
, widget_height
;
5571 Window window
= XtWindow (f
->output_data
.x
->widget
);
5572 #else /* not USE_X_TOOLKIT */
5573 Window window
= FRAME_X_WINDOW (f
);
5574 #endif /* not USE_X_TOOLKIT */
5576 /* Setting PMaxSize caused various problems. */
5577 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5579 size_hints
.x
= f
->left_pos
;
5580 size_hints
.y
= f
->top_pos
;
5582 #ifdef USE_X_TOOLKIT
5583 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5584 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5585 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5586 size_hints
.height
= widget_height
;
5587 size_hints
.width
= widget_width
;
5588 #else /* not USE_X_TOOLKIT */
5589 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5590 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5591 #endif /* not USE_X_TOOLKIT */
5593 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5594 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5595 size_hints
.max_width
5596 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5597 size_hints
.max_height
5598 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5600 /* Calculate the base and minimum sizes.
5602 (When we use the X toolkit, we don't do it here.
5603 Instead we copy the values that the widgets are using, below.) */
5604 #ifndef USE_X_TOOLKIT
5606 int base_width
, base_height
;
5607 int min_rows
= 0, min_cols
= 0;
5609 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5610 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5612 check_frame_size (f
, &min_rows
, &min_cols
);
5614 /* The window manager uses the base width hints to calculate the
5615 current number of rows and columns in the frame while
5616 resizing; min_width and min_height aren't useful for this
5617 purpose, since they might not give the dimensions for a
5618 zero-row, zero-column frame.
5620 We use the base_width and base_height members if we have
5621 them; otherwise, we set the min_width and min_height members
5622 to the size for a zero x zero frame. */
5625 size_hints
.flags
|= PBaseSize
;
5626 size_hints
.base_width
= base_width
;
5627 size_hints
.base_height
= base_height
;
5628 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5629 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5631 size_hints
.min_width
= base_width
;
5632 size_hints
.min_height
= base_height
;
5636 /* If we don't need the old flags, we don't need the old hint at all. */
5639 size_hints
.flags
|= flags
;
5642 #endif /* not USE_X_TOOLKIT */
5645 XSizeHints hints
; /* Sometimes I hate X Windows... */
5646 long supplied_return
;
5650 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5653 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5656 #ifdef USE_X_TOOLKIT
5657 size_hints
.base_height
= hints
.base_height
;
5658 size_hints
.base_width
= hints
.base_width
;
5659 size_hints
.min_height
= hints
.min_height
;
5660 size_hints
.min_width
= hints
.min_width
;
5664 size_hints
.flags
|= flags
;
5669 if (hints
.flags
& PSize
)
5670 size_hints
.flags
|= PSize
;
5671 if (hints
.flags
& PPosition
)
5672 size_hints
.flags
|= PPosition
;
5673 if (hints
.flags
& USPosition
)
5674 size_hints
.flags
|= USPosition
;
5675 if (hints
.flags
& USSize
)
5676 size_hints
.flags
|= USSize
;
5680 #ifndef USE_X_TOOLKIT
5685 size_hints
.win_gravity
= f
->win_gravity
;
5686 size_hints
.flags
|= PWinGravity
;
5690 size_hints
.flags
&= ~ PPosition
;
5691 size_hints
.flags
|= USPosition
;
5693 #endif /* PWinGravity */
5696 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5698 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5700 #endif /* MAC_TODO */
5703 #if 0 /* MAC_TODO: hide application instead of iconify? */
5704 /* Used for IconicState or NormalState */
5707 x_wm_set_window_state (f
, state
)
5711 #ifdef USE_X_TOOLKIT
5714 XtSetArg (al
[0], XtNinitialState
, state
);
5715 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5716 #else /* not USE_X_TOOLKIT */
5717 Window window
= FRAME_X_WINDOW (f
);
5719 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5720 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5722 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5723 #endif /* not USE_X_TOOLKIT */
5727 x_wm_set_icon_pixmap (f
, pixmap_id
)
5733 #ifndef USE_X_TOOLKIT
5734 Window window
= FRAME_X_WINDOW (f
);
5739 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5740 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5744 /* It seems there is no way to turn off use of an icon pixmap.
5745 The following line does it, only if no icon has yet been created,
5746 for some window managers. But with mwm it crashes.
5747 Some people say it should clear the IconPixmapHint bit in this case,
5748 but that doesn't work, and the X consortium said it isn't the
5749 right thing at all. Since there is no way to win,
5750 best to explicitly give up. */
5752 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5758 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5762 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5763 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5766 #else /* not USE_X_TOOLKIT */
5768 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5769 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5771 #endif /* not USE_X_TOOLKIT */
5774 #endif /* MAC_TODO */
5777 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5781 #if 0 /* MAC_TODO: no icons on Mac */
5782 #ifdef USE_X_TOOLKIT
5783 Window window
= XtWindow (f
->output_data
.x
->widget
);
5785 Window window
= FRAME_X_WINDOW (f
);
5788 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5789 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5790 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5792 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5793 #endif /* MAC_TODO */
5797 /***********************************************************************
5799 ***********************************************************************/
5801 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5804 x_get_font_info (f
, font_idx
)
5808 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5811 /* the global font name table */
5812 char **font_name_table
= NULL
;
5813 int font_name_table_size
= 0;
5814 int font_name_count
= 0;
5817 /* compare two strings ignoring case */
5819 stricmp (const char *s
, const char *t
)
5821 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5824 return tolower (*s
) - tolower (*t
);
5827 /* compare two strings ignoring case and handling wildcard */
5829 wildstrieq (char *s1
, char *s2
)
5831 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5834 return stricmp (s1
, s2
) == 0;
5837 /* Assume parameter 1 is fully qualified, no wildcards. */
5839 mac_font_pattern_match (fontname
, pattern
)
5843 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5844 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5847 /* Copy fontname so we can modify it during comparison. */
5848 strcpy (font_name_copy
, fontname
);
5853 /* Turn pattern into a regexp and do a regexp match. */
5854 for (; *pattern
; pattern
++)
5856 if (*pattern
== '?')
5858 else if (*pattern
== '*')
5869 return (fast_c_string_match_ignore_case (build_string (regex
),
5870 font_name_copy
) >= 0);
5873 /* Two font specs are considered to match if their foundry, family,
5874 weight, slant, and charset match. */
5876 mac_font_match (char *mf
, char *xf
)
5878 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5879 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5881 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5882 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5883 return mac_font_pattern_match (mf
, xf
);
5885 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5886 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5887 return mac_font_pattern_match (mf
, xf
);
5889 return (wildstrieq (m_foundry
, x_foundry
)
5890 && wildstrieq (m_family
, x_family
)
5891 && wildstrieq (m_weight
, x_weight
)
5892 && wildstrieq (m_slant
, x_slant
)
5893 && wildstrieq (m_charset
, x_charset
))
5894 || mac_font_pattern_match (mf
, xf
);
5898 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5901 decode_mac_font_name (char *name
, int size
, short scriptcode
)
5903 Lisp_Object coding_system
;
5904 struct coding_system coding
;
5910 coding_system
= Qbig5
;
5913 coding_system
= Qcn_gb
;
5916 coding_system
= Qsjis
;
5919 coding_system
= Qeuc_kr
;
5925 setup_coding_system (coding_system
, &coding
);
5926 coding
.src_multibyte
= 0;
5927 coding
.dst_multibyte
= 1;
5928 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5929 coding
.composing
= COMPOSITION_DISABLED
;
5930 buf
= (char *) alloca (size
);
5932 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5933 bcopy (buf
, name
, coding
.produced
);
5934 name
[coding
.produced
] = '\0';
5939 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5941 char foundry
[32], family
[32], cs
[32];
5942 char xf
[256], *result
, *p
;
5944 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5946 strcpy(foundry
, "Apple");
5947 strcpy(family
, name
);
5952 strcpy(cs
, "big5-0");
5955 strcpy(cs
, "gb2312.1980-0");
5958 strcpy(cs
, "jisx0208.1983-sjis");
5961 /* Each Apple Japanese font is entered into the font table
5962 twice: once as a jisx0208.1983-sjis font and once as a
5963 jisx0201.1976-0 font. The latter can be used to display
5964 the ascii charset and katakana-jisx0201 charset. A
5965 negative script code signals that the name of this latter
5966 font is being built. */
5967 strcpy(cs
, "jisx0201.1976-0");
5970 strcpy(cs
, "ksc5601.1989-0");
5973 strcpy(cs
, "mac-roman");
5978 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5979 foundry
, family
, style
& bold
? "bold" : "medium",
5980 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5982 result
= (char *) xmalloc (strlen (xf
) + 1);
5983 strcpy (result
, xf
);
5984 for (p
= result
; *p
; p
++)
5990 /* Convert an X font spec to the corresponding mac font name, which
5991 can then be passed to GetFNum after conversion to a Pascal string.
5992 For ordinary Mac fonts, this should just be their names, like
5993 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5994 collection contain their charset designation in their names, like
5995 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5996 names are handled accordingly. */
5998 x_font_name_to_mac_font_name (char *xf
, char *mf
)
6000 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
6001 Lisp_Object coding_system
= Qnil
;
6002 struct coding_system coding
;
6006 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6007 foundry
, family
, weight
, slant
, cs
) != 5 &&
6008 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6009 foundry
, family
, weight
, slant
, cs
) != 5)
6012 if (strcmp (cs
, "big5-0") == 0)
6013 coding_system
= Qbig5
;
6014 else if (strcmp (cs
, "gb2312.1980-0") == 0)
6015 coding_system
= Qcn_gb
;
6016 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
6017 || strcmp (cs
, "jisx0201.1976-0") == 0)
6018 coding_system
= Qsjis
;
6019 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
6020 coding_system
= Qeuc_kr
;
6021 else if (strcmp (cs
, "mac-roman") == 0)
6022 strcpy (mf
, family
);
6024 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
6026 if (!NILP (coding_system
))
6028 setup_coding_system (coding_system
, &coding
);
6029 coding
.src_multibyte
= 1;
6030 coding
.dst_multibyte
= 1;
6031 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6032 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
6033 mf
[coding
.produced
] = '\0';
6039 add_font_name_table_entry (char *font_name
)
6041 if (font_name_table_size
== 0)
6043 font_name_table_size
= 16;
6044 font_name_table
= (char **)
6045 xmalloc (font_name_table_size
* sizeof (char *));
6047 else if (font_name_count
+ 1 >= font_name_table_size
)
6049 font_name_table_size
+= 16;
6050 font_name_table
= (char **)
6051 xrealloc (font_name_table
,
6052 font_name_table_size
* sizeof (char *));
6055 font_name_table
[font_name_count
++] = font_name
;
6058 /* Sets up the table font_name_table to contain the list of all fonts
6059 in the system the first time the table is used so that the Resource
6060 Manager need not be accessed every time this information is
6064 init_font_name_table ()
6066 #if TARGET_API_MAC_CARBON
6069 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
6071 FMFontFamilyIterator ffi
;
6072 FMFontFamilyInstanceIterator ffii
;
6075 /* Create a dummy instance iterator here to avoid creating and
6076 destroying it in the loop. */
6077 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6079 /* Create an iterator to enumerate the font families. */
6080 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6083 FMDisposeFontFamilyInstanceIterator (&ffii
);
6087 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6095 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6101 sc
= FontToScript (ff
);
6102 decode_mac_font_name (name
, sizeof (name
), sc
);
6104 /* Point the instance iterator at the current font family. */
6105 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6108 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6111 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6112 contained in Apple Japanese (SJIS) font. */
6116 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6118 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6120 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6122 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6127 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6129 if (sc
== smJapanese
)
6134 else if (sc
== -smJapanese
)
6139 /* Dispose of the iterators. */
6140 FMDisposeFontFamilyIterator (&ffi
);
6141 FMDisposeFontFamilyInstanceIterator (&ffii
);
6145 #endif /* TARGET_API_MAC_CARBON */
6147 SInt16 fontnum
, old_fontnum
;
6148 int num_mac_fonts
= CountResources('FOND');
6150 Handle font_handle
, font_handle_2
;
6151 short id
, scriptcode
;
6154 struct FontAssoc
*fat
;
6155 struct AsscEntry
*assc_entry
;
6157 GetPort (&port
); /* save the current font number used */
6158 #if TARGET_API_MAC_CARBON
6159 old_fontnum
= GetPortTextFont (port
);
6161 old_fontnum
= port
->txFont
;
6164 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6166 font_handle
= GetIndResource ('FOND', i
);
6170 GetResInfo (font_handle
, &id
, &type
, name
);
6171 GetFNum (name
, &fontnum
);
6177 scriptcode
= FontToScript (fontnum
);
6178 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6181 HLock (font_handle
);
6183 if (GetResourceSizeOnDisk (font_handle
)
6184 >= sizeof (struct FamRec
))
6186 fat
= (struct FontAssoc
*) (*font_handle
6187 + sizeof (struct FamRec
));
6189 = (struct AsscEntry
*) (*font_handle
6190 + sizeof (struct FamRec
)
6191 + sizeof (struct FontAssoc
));
6193 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6195 if (font_name_table_size
== 0)
6197 font_name_table_size
= 16;
6198 font_name_table
= (char **)
6199 xmalloc (font_name_table_size
* sizeof (char *));
6201 else if (font_name_count
>= font_name_table_size
)
6203 font_name_table_size
+= 16;
6204 font_name_table
= (char **)
6205 xrealloc (font_name_table
,
6206 font_name_table_size
* sizeof (char *));
6208 font_name_table
[font_name_count
++]
6209 = mac_to_x_fontname (name
,
6210 assc_entry
->fontSize
,
6211 assc_entry
->fontStyle
,
6213 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6214 parts are contained in Apple Japanese (SJIS)
6216 if (smJapanese
== scriptcode
)
6218 font_name_table
[font_name_count
++]
6219 = mac_to_x_fontname (name
,
6220 assc_entry
->fontSize
,
6221 assc_entry
->fontStyle
,
6227 HUnlock (font_handle
);
6228 font_handle_2
= GetNextFOND (font_handle
);
6229 ReleaseResource (font_handle
);
6230 font_handle
= font_handle_2
;
6232 while (ResError () == noErr
&& font_handle
);
6235 TextFont (old_fontnum
);
6236 #if TARGET_API_MAC_CARBON
6238 #endif /* TARGET_API_MAC_CARBON */
6242 enum xlfd_scalable_field_index
6244 XLFD_SCL_PIXEL_SIZE
,
6245 XLFD_SCL_POINT_SIZE
,
6250 static int xlfd_scalable_fields
[] =
6259 mac_do_list_fonts (pattern
, maxnames
)
6264 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6265 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6268 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6270 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6273 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6274 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6275 fonts are scaled according to the specified size. */
6278 field
= xlfd_scalable_fields
;
6286 if ('1' <= *ptr
&& *ptr
<= '9')
6288 *val
= *ptr
++ - '0';
6289 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6290 *val
= *val
* 10 + *ptr
++ - '0';
6297 ptr
= strchr (ptr
, '-');
6300 while (ptr
&& i
< 14);
6302 if (i
== 14 && ptr
== NULL
)
6304 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6306 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6307 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6309 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6311 scl_val
[XLFD_SCL_POINT_SIZE
] =
6312 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6314 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6316 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6317 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6321 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6326 /* Turn pattern into a regexp and do a regexp match. */
6327 for (; *pattern
; pattern
++)
6329 if (*pattern
== '?')
6331 else if (*pattern
== '*')
6337 *ptr
++ = tolower (*pattern
);
6342 pattern_regex
= build_string (regex
);
6344 for (i
= 0; i
< font_name_count
; i
++)
6346 fontname
= build_string (font_name_table
[i
]);
6347 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6349 font_list
= Fcons (fontname
, font_list
);
6352 if (maxnames
> 0 && n_fonts
>= maxnames
)
6355 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6356 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6358 int former_len
= ptr
- font_name_table
[i
];
6360 memcpy (scaled
, font_name_table
[i
], former_len
);
6361 sprintf (scaled
+ former_len
,
6362 "-%d-%d-75-75-m-%d-%s",
6363 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6364 scl_val
[XLFD_SCL_POINT_SIZE
],
6365 scl_val
[XLFD_SCL_AVGWIDTH
],
6366 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6367 fontname
= build_string (scaled
);
6368 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6370 font_list
= Fcons (fontname
, font_list
);
6373 if (maxnames
> 0 && n_fonts
>= maxnames
)
6381 /* Return a list of at most MAXNAMES font specs matching the one in
6382 PATTERN. Cache matching fonts for patterns in
6383 dpyinfo->name_list_element to avoid looking them up again by
6384 calling mac_font_pattern_match (slow). Return as many matching
6385 fonts as possible if MAXNAMES = -1. */
6388 x_list_fonts (struct frame
*f
,
6389 Lisp_Object pattern
,
6393 Lisp_Object newlist
= Qnil
, tem
, key
;
6394 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6396 if (font_name_table
== NULL
) /* Initialize when first used. */
6397 init_font_name_table ();
6401 tem
= XCDR (dpyinfo
->name_list_element
);
6402 key
= Fcons (pattern
, make_number (maxnames
));
6404 newlist
= Fassoc (key
, tem
);
6405 if (!NILP (newlist
))
6407 newlist
= Fcdr_safe (newlist
);
6412 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6414 /* MAC_TODO: add code for matching outline fonts here */
6418 XSETCDR (dpyinfo
->name_list_element
,
6419 Fcons (Fcons (key
, newlist
),
6420 XCDR (dpyinfo
->name_list_element
)));
6430 /* Check that FONT is valid on frame F. It is if it can be found in F's
6434 x_check_font (f
, font
)
6439 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6441 xassert (font
!= NULL
);
6443 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6444 if (dpyinfo
->font_table
[i
].name
6445 && font
== dpyinfo
->font_table
[i
].font
)
6448 xassert (i
< dpyinfo
->n_fonts
);
6451 #endif /* GLYPH_DEBUG != 0 */
6453 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6454 Note: There are (broken) X fonts out there with invalid XFontStruct
6455 min_bounds contents. For example, handa@etl.go.jp reports that
6456 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6457 have font->min_bounds.width == 0. */
6460 x_font_min_bounds (font
, w
, h
)
6461 MacFontStruct
*font
;
6465 * TODO: Windows does not appear to offer min bound, only
6466 * average and maximum width, and maximum height.
6468 *h
= FONT_HEIGHT (font
);
6469 *w
= FONT_WIDTH (font
);
6473 /* Compute the smallest character width and smallest font height over
6474 all fonts available on frame F. Set the members smallest_char_width
6475 and smallest_font_height in F's x_display_info structure to
6476 the values computed. Value is non-zero if smallest_font_height or
6477 smallest_char_width become smaller than they were before. */
6480 x_compute_min_glyph_bounds (f
)
6484 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6485 MacFontStruct
*font
;
6486 int old_width
= dpyinfo
->smallest_char_width
;
6487 int old_height
= dpyinfo
->smallest_font_height
;
6489 dpyinfo
->smallest_font_height
= 100000;
6490 dpyinfo
->smallest_char_width
= 100000;
6492 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6493 if (dpyinfo
->font_table
[i
].name
)
6495 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6498 font
= (MacFontStruct
*) fontp
->font
;
6499 xassert (font
!= (MacFontStruct
*) ~0);
6500 x_font_min_bounds (font
, &w
, &h
);
6502 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6503 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6506 xassert (dpyinfo
->smallest_char_width
> 0
6507 && dpyinfo
->smallest_font_height
> 0);
6509 return (dpyinfo
->n_fonts
== 1
6510 || dpyinfo
->smallest_char_width
< old_width
6511 || dpyinfo
->smallest_font_height
< old_height
);
6515 /* Determine whether given string is a fully-specified XLFD: all 14
6516 fields are present, none is '*'. */
6519 is_fully_specified_xlfd (char *p
)
6527 for (i
= 0; i
< 13; i
++)
6529 q
= strchr (p
+ 1, '-');
6532 if (q
- p
== 2 && *(p
+ 1) == '*')
6537 if (strchr (p
+ 1, '-') != NULL
)
6540 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6547 const int kDefaultFontSize
= 9;
6550 /* XLoadQueryFont creates and returns an internal representation for a
6551 font in a MacFontStruct struct. There is really no concept
6552 corresponding to "loading" a font on the Mac. But we check its
6553 existence and find the font number and all other information for it
6554 and store them in the returned MacFontStruct. */
6556 static MacFontStruct
*
6557 XLoadQueryFont (Display
*dpy
, char *fontname
)
6559 int i
, size
, is_two_byte_font
, char_width
;
6562 SInt16 old_fontnum
, old_fontsize
;
6566 Style fontface
= normal
;
6567 MacFontStruct
*font
;
6568 FontInfo the_fontinfo
;
6569 char s_weight
[7], c_slant
;
6571 if (is_fully_specified_xlfd (fontname
))
6575 Lisp_Object matched_fonts
;
6577 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6578 if (NILP (matched_fonts
))
6580 name
= SDATA (XCAR (matched_fonts
));
6583 GetPort (&port
); /* save the current font number used */
6584 #if TARGET_API_MAC_CARBON
6585 old_fontnum
= GetPortTextFont (port
);
6586 old_fontsize
= GetPortTextSize (port
);
6587 old_fontface
= GetPortTextFace (port
);
6589 old_fontnum
= port
->txFont
;
6590 old_fontsize
= port
->txSize
;
6591 old_fontface
= port
->txFace
;
6594 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6595 size
= kDefaultFontSize
;
6597 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6598 if (strcmp (s_weight
, "bold") == 0)
6601 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6605 x_font_name_to_mac_font_name (name
, mfontname
);
6607 GetFNum (mfontname
, &fontnum
);
6611 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6613 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6614 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6616 font
->mac_fontnum
= fontnum
;
6617 font
->mac_fontsize
= size
;
6618 font
->mac_fontface
= fontface
;
6619 font
->mac_scriptcode
= FontToScript (fontnum
);
6621 /* Apple Japanese (SJIS) font is listed as both
6622 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6623 (Roman script) in init_font_name_table (). The latter should be
6624 treated as a one-byte font. */
6629 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6631 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6632 font
->mac_scriptcode
= smRoman
;
6635 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6636 font
->mac_scriptcode
== smTradChinese
||
6637 font
->mac_scriptcode
== smSimpChinese
||
6638 font
->mac_scriptcode
== smKorean
;
6642 TextFace (fontface
);
6644 GetFontInfo (&the_fontinfo
);
6646 font
->ascent
= the_fontinfo
.ascent
;
6647 font
->descent
= the_fontinfo
.descent
;
6649 font
->min_byte1
= 0;
6650 if (is_two_byte_font
)
6651 font
->max_byte1
= 1;
6653 font
->max_byte1
= 0;
6654 font
->min_char_or_byte2
= 0x20;
6655 font
->max_char_or_byte2
= 0xff;
6657 if (is_two_byte_font
)
6659 /* Use the width of an "ideographic space" of that font because
6660 the_fontinfo.widMax returns the wrong width for some fonts. */
6661 switch (font
->mac_scriptcode
)
6664 char_width
= StringWidth("\p\x81\x40");
6667 char_width
= StringWidth("\p\xa1\x40");
6670 char_width
= StringWidth("\p\xa1\xa1");
6673 char_width
= StringWidth("\p\xa1\xa1");
6678 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6679 returns 15 for 12-point Monaco! */
6680 char_width
= CharWidth ('m');
6682 font
->max_bounds
.rbearing
= char_width
;
6683 font
->max_bounds
.lbearing
= 0;
6684 font
->max_bounds
.width
= char_width
;
6685 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6686 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6688 font
->min_bounds
= font
->max_bounds
;
6690 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6691 font
->per_char
= NULL
;
6694 font
->per_char
= (XCharStruct
*)
6695 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6699 for (c
= 0x20; c
<= 0xff; c
++)
6701 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6702 font
->per_char
[c
- 0x20].width
=
6703 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6708 TextFont (old_fontnum
); /* restore previous font number, size and face */
6709 TextSize (old_fontsize
);
6710 TextFace (old_fontface
);
6716 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6717 pointer to the structure font_info while allocating it dynamically.
6718 If SIZE is 0, load any size of font.
6719 If loading is failed, return NULL. */
6722 x_load_font (f
, fontname
, size
)
6724 register char *fontname
;
6727 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6728 Lisp_Object font_names
;
6730 /* Get a list of all the fonts that match this name. Once we
6731 have a list of matching fonts, we compare them against the fonts
6732 we already have by comparing names. */
6733 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6735 if (!NILP (font_names
))
6740 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6741 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6742 if (dpyinfo
->font_table
[i
].name
6743 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6744 SDATA (XCAR (tail
)))
6745 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6746 SDATA (XCAR (tail
)))))
6747 return (dpyinfo
->font_table
+ i
);
6750 /* Load the font and add it to the table. */
6753 struct MacFontStruct
*font
;
6754 struct font_info
*fontp
;
6755 unsigned long value
;
6758 /* If we have found fonts by x_list_font, load one of them. If
6759 not, we still try to load a font by the name given as FONTNAME
6760 because XListFonts (called in x_list_font) of some X server has
6761 a bug of not finding a font even if the font surely exists and
6762 is loadable by XLoadQueryFont. */
6763 if (size
> 0 && !NILP (font_names
))
6764 fontname
= (char *) SDATA (XCAR (font_names
));
6766 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6770 /* Find a free slot in the font table. */
6771 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6772 if (dpyinfo
->font_table
[i
].name
== NULL
)
6775 /* If no free slot found, maybe enlarge the font table. */
6776 if (i
== dpyinfo
->n_fonts
6777 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6780 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6781 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6783 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6786 fontp
= dpyinfo
->font_table
+ i
;
6787 if (i
== dpyinfo
->n_fonts
)
6790 /* Now fill in the slots of *FONTP. */
6792 bzero (fontp
, sizeof (*fontp
));
6794 fontp
->font_idx
= i
;
6795 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6796 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6798 fontp
->full_name
= fontp
->name
;
6800 fontp
->size
= font
->max_bounds
.width
;
6801 fontp
->height
= FONT_HEIGHT (font
);
6803 /* For some font, ascent and descent in max_bounds field is
6804 larger than the above value. */
6805 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6806 if (max_height
> fontp
->height
)
6807 fontp
->height
= max_height
;
6810 /* The slot `encoding' specifies how to map a character
6811 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6812 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6813 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6814 2:0xA020..0xFF7F). For the moment, we don't know which charset
6815 uses this font. So, we set information in fontp->encoding[1]
6816 which is never used by any charset. If mapping can't be
6817 decided, set FONT_ENCODING_NOT_DECIDED. */
6818 if (font
->mac_scriptcode
== smJapanese
)
6819 fontp
->encoding
[1] = 4;
6823 = (font
->max_byte1
== 0
6825 ? (font
->min_char_or_byte2
< 0x80
6826 ? (font
->max_char_or_byte2
< 0x80
6827 ? 0 /* 0x20..0x7F */
6828 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6829 : 1) /* 0xA0..0xFF */
6831 : (font
->min_byte1
< 0x80
6832 ? (font
->max_byte1
< 0x80
6833 ? (font
->min_char_or_byte2
< 0x80
6834 ? (font
->max_char_or_byte2
< 0x80
6835 ? 0 /* 0x2020..0x7F7F */
6836 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6837 : 3) /* 0x20A0..0x7FFF */
6838 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6839 : (font
->min_char_or_byte2
< 0x80
6840 ? (font
->max_char_or_byte2
< 0x80
6841 ? 2 /* 0xA020..0xFF7F */
6842 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6843 : 1))); /* 0xA0A0..0xFFFF */
6846 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6847 fontp
->baseline_offset
6848 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6849 ? (long) value
: 0);
6850 fontp
->relative_compose
6851 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6852 ? (long) value
: 0);
6853 fontp
->default_ascent
6854 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6855 ? (long) value
: 0);
6857 fontp
->baseline_offset
= 0;
6858 fontp
->relative_compose
= 0;
6859 fontp
->default_ascent
= 0;
6862 /* Set global flag fonts_changed_p to non-zero if the font loaded
6863 has a character with a smaller width than any other character
6864 before, or if the font loaded has a smalle>r height than any
6865 other font loaded before. If this happens, it will make a
6866 glyph matrix reallocation necessary. */
6867 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6874 /* Return a pointer to struct font_info of a font named FONTNAME for
6875 frame F. If no such font is loaded, return NULL. */
6878 x_query_font (f
, fontname
)
6880 register char *fontname
;
6882 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6885 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6886 if (dpyinfo
->font_table
[i
].name
6887 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6888 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6889 return (dpyinfo
->font_table
+ i
);
6894 /* Find a CCL program for a font specified by FONTP, and set the member
6895 `encoder' of the structure. */
6898 x_find_ccl_program (fontp
)
6899 struct font_info
*fontp
;
6901 Lisp_Object list
, elt
;
6903 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6907 && STRINGP (XCAR (elt
))
6908 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6914 struct ccl_program
*ccl
6915 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6917 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6920 fontp
->font_encoder
= ccl
;
6926 /* The Mac Event loop code */
6930 #include <Quickdraw.h>
6931 #include <Balloons.h>
6932 #include <Devices.h>
6934 #include <Gestalt.h>
6936 #include <Processes.h>
6938 #include <ToolUtils.h>
6939 #include <TextUtils.h>
6940 #include <Dialogs.h>
6943 #include <TextEncodingConverter.h>
6944 #include <Resources.h>
6949 #endif /* ! MAC_OSX */
6954 #define WINDOW_RESOURCE 128
6955 #define TERM_WINDOW_RESOURCE 129
6957 #define DEFAULT_NUM_COLS 80
6959 #define MIN_DOC_SIZE 64
6960 #define MAX_DOC_SIZE 32767
6962 /* sleep time for WaitNextEvent */
6963 #define WNE_SLEEP_AT_SUSPEND 10
6964 #define WNE_SLEEP_AT_RESUME 1
6966 /* true when cannot handle any Mac OS events */
6967 static int handling_window_update
= 0;
6970 /* the flag appl_is_suspended is used both for determining the sleep
6971 time to be passed to WaitNextEvent and whether the cursor should be
6972 drawn when updating the display. The cursor is turned off when
6973 Emacs is suspended. Redrawing it is unnecessary and what needs to
6974 be done depends on whether the cursor lies inside or outside the
6975 redraw region. So we might as well skip drawing it when Emacs is
6977 static Boolean app_is_suspended
= false;
6978 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6981 #define EXTRA_STACK_ALLOC (256 * 1024)
6983 #define ARGV_STRING_LIST_ID 129
6984 #define ABOUT_ALERT_ID 128
6985 #define RAM_TOO_LARGE_ALERT_ID 129
6987 Boolean terminate_flag
= false;
6989 /* Contains the string "reverse", which is a constant for mouse button emu.*/
6990 Lisp_Object Qreverse
;
6992 /* True if using command key as meta key. */
6993 Lisp_Object Vmac_command_key_is_meta
;
6995 /* Modifier associated with the option key, or nil for normal behavior. */
6996 Lisp_Object Vmac_option_modifier
;
6998 /* True if the ctrl and meta keys should be reversed. */
6999 Lisp_Object Vmac_reverse_ctrl_meta
;
7001 /* True if the option and command modifiers should be used to emulate
7002 a three button mouse */
7003 Lisp_Object Vmac_emulate_three_button_mouse
;
7005 #if USE_CARBON_EVENTS
7006 /* True if the mouse wheel button (i.e. button 4) should map to
7007 mouse-2, instead of mouse-3. */
7008 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7010 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7011 for processing before Emacs sees it. */
7012 Lisp_Object Vmac_pass_command_to_system
;
7014 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7015 for processing before Emacs sees it. */
7016 Lisp_Object Vmac_pass_control_to_system
;
7019 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
7020 to this text encoding */
7021 int mac_keyboard_text_encoding
;
7022 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
7024 /* Set in term/mac-win.el to indicate that event loop can now generate
7025 drag and drop events. */
7026 Lisp_Object Qmac_ready_for_drag_n_drop
;
7028 Lisp_Object drag_and_drop_file_list
;
7030 Point saved_menu_event_location
;
7032 #if !TARGET_API_MAC_CARBON
7033 /* Place holder for the default arrow cursor. */
7034 CursPtr arrow_cursor
;
7038 static void init_required_apple_events (void);
7040 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7042 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7043 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7044 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7047 static OSErr
init_mac_drag_n_drop ();
7048 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7050 #if USE_CARBON_EVENTS
7051 /* Preliminary Support for the OSX Services Menu */
7052 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
7053 static void init_service_handler ();
7056 extern void init_emacs_passwd_dir ();
7057 extern int emacs_main (int, char **, char **);
7058 extern void check_alarm ();
7060 extern void initialize_applescript();
7061 extern void terminate_applescript();
7064 #if USE_CARBON_EVENTS
7065 mac_to_emacs_modifiers (UInt32 mods
)
7067 mac_to_emacs_modifiers (EventModifiers mods
)
7070 unsigned int result
= 0;
7071 if (mods
& macShiftKey
)
7072 result
|= shift_modifier
;
7073 if (mods
& macCtrlKey
)
7074 result
|= ctrl_modifier
;
7075 if (mods
& macMetaKey
)
7076 result
|= meta_modifier
;
7077 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7078 result
|= alt_modifier
;
7079 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7080 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7082 result
|= XUINT(val
);
7089 mac_get_emulated_btn ( UInt32 modifiers
)
7092 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7093 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7094 if (modifiers
& cmdKey
)
7095 result
= cmdIs3
? 2 : 1;
7096 else if (modifiers
& optionKey
)
7097 result
= cmdIs3
? 1 : 2;
7102 #if USE_CARBON_EVENTS
7103 /* Obtains the event modifiers from the event ref and then calls
7104 mac_to_emacs_modifiers. */
7106 mac_event_to_emacs_modifiers (EventRef eventRef
)
7109 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7110 sizeof (UInt32
), NULL
, &mods
);
7111 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7112 GetEventClass(eventRef
) == kEventClassMouse
)
7114 mods
&= ~(optionKey
| cmdKey
);
7116 return mac_to_emacs_modifiers (mods
);
7119 /* Given an event ref, return the code to use for the mouse button
7120 code in the emacs input_event. */
7122 mac_get_mouse_btn (EventRef ref
)
7124 EventMouseButton result
= kEventMouseButtonPrimary
;
7125 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7126 sizeof (EventMouseButton
), NULL
, &result
);
7129 case kEventMouseButtonPrimary
:
7130 if (NILP (Vmac_emulate_three_button_mouse
))
7134 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7135 sizeof (UInt32
), NULL
, &mods
);
7136 return mac_get_emulated_btn(mods
);
7138 case kEventMouseButtonSecondary
:
7139 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7140 case kEventMouseButtonTertiary
:
7141 case 4: /* 4 is the number for the mouse wheel button */
7142 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7148 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7149 events. However the click of the mouse wheel is not converted to a
7150 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7151 checks to see if it is a mouse up or down carbon event that has not
7152 been converted, and if so, converts it by hand (to be picked up in
7153 the XTread_socket loop). */
7154 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7156 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7157 /* Do special case for mouse wheel button. */
7158 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7160 UInt32 kind
= GetEventKind (eventRef
);
7161 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7163 eventRec
->what
= mouseDown
;
7166 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7168 eventRec
->what
= mouseUp
;
7173 /* Need where and when. */
7175 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7176 typeQDPoint
, NULL
, sizeof (Point
),
7177 NULL
, &eventRec
->where
);
7178 /* Use two step process because new event modifiers are
7179 32-bit and old are 16-bit. Currently, only loss is
7181 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7182 typeUInt32
, NULL
, sizeof (UInt32
),
7184 eventRec
->modifiers
= mods
;
7186 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7197 Handle menubar_handle
;
7198 MenuHandle menu_handle
;
7200 menubar_handle
= GetNewMBar (128);
7201 if(menubar_handle
== NULL
)
7203 SetMenuBar (menubar_handle
);
7206 menu_handle
= GetMenuHandle (M_APPLE
);
7207 if(menu_handle
!= NULL
)
7208 AppendResMenu (menu_handle
,'DRVR');
7215 do_init_managers (void)
7217 #if !TARGET_API_MAC_CARBON
7218 InitGraf (&qd
.thePort
);
7220 FlushEvents (everyEvent
, 0);
7225 #endif /* !TARGET_API_MAC_CARBON */
7228 #if !TARGET_API_MAC_CARBON
7229 arrow_cursor
= &qd
.arrow
;
7231 /* set up some extra stack space for use by emacs */
7232 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7234 /* MaxApplZone must be called for AppleScript to execute more
7235 complicated scripts */
7238 #endif /* !TARGET_API_MAC_CARBON */
7242 do_check_ram_size (void)
7244 SInt32 physical_ram_size
, logical_ram_size
;
7246 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7247 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7248 || physical_ram_size
> (1 << VALBITS
)
7249 || logical_ram_size
> (1 << VALBITS
))
7251 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7257 do_window_update (WindowPtr win
)
7259 struct frame
*f
= mac_window_to_frame (win
);
7261 if (win
== tip_window
)
7262 /* The tooltip has been drawn already. Avoid the
7263 SET_FRAME_GARBAGED below. */
7268 if (f
->async_visible
== 0)
7270 f
->async_visible
= 1;
7271 f
->async_iconified
= 0;
7272 SET_FRAME_GARBAGED (f
);
7274 /* An update event is equivalent to MapNotify on X, so report
7275 visibility changes properly. */
7276 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7277 /* Force a redisplay sooner or later to update the
7278 frame titles in case this is the second frame. */
7279 record_asynch_buffer_change ();
7284 handling_window_update
= 1;
7286 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7288 expose_frame (f
, 0, 0, 0, 0);
7290 handling_window_update
= 0;
7297 is_emacs_window (WindowPtr win
)
7299 Lisp_Object tail
, frame
;
7304 FOR_EACH_FRAME (tail
, frame
)
7305 if (FRAME_MAC_P (XFRAME (frame
)))
7306 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7315 /* Window-activate events will do the job. */
7320 wp
= front_emacs_window ();
7323 f
= mac_window_to_frame (wp
);
7327 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7328 activate_scroll_bars (f
);
7332 app_is_suspended
= false;
7333 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7340 /* Window-deactivate events will do the job. */
7345 wp
= front_emacs_window ();
7348 f
= mac_window_to_frame (wp
);
7350 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7352 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7353 deactivate_scroll_bars (f
);
7357 app_is_suspended
= true;
7358 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7364 do_mouse_moved (mouse_pos
, f
)
7368 WindowPtr wp
= front_emacs_window ();
7369 struct x_display_info
*dpyinfo
;
7373 *f
= mac_window_to_frame (wp
);
7374 dpyinfo
= FRAME_MAC_DISPLAY_INFO (*f
);
7376 if (dpyinfo
->mouse_face_hidden
)
7378 dpyinfo
->mouse_face_hidden
= 0;
7379 clear_mouse_face (dpyinfo
);
7382 SetPortWindowPort (wp
);
7384 GlobalToLocal (&mouse_pos
);
7386 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
7387 x_scroll_bar_note_movement (tracked_scroll_bar
,
7389 - XINT (tracked_scroll_bar
->top
),
7390 TickCount() * (1000 / 60));
7392 note_mouse_movement (*f
, &mouse_pos
);
7398 do_apple_menu (SInt16 menu_item
)
7400 #if !TARGET_API_MAC_CARBON
7402 SInt16 da_driver_refnum
;
7404 if (menu_item
== I_ABOUT
)
7405 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7408 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7409 da_driver_refnum
= OpenDeskAcc (item_name
);
7411 #endif /* !TARGET_API_MAC_CARBON */
7415 do_menu_choice (SInt32 menu_choice
)
7417 SInt16 menu_id
, menu_item
;
7419 menu_id
= HiWord (menu_choice
);
7420 menu_item
= LoWord (menu_choice
);
7428 do_apple_menu (menu_item
);
7433 struct frame
*f
= mac_window_to_frame (front_emacs_window ());
7434 MenuHandle menu
= GetMenuHandle (menu_id
);
7439 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7440 menubar_selection_callback (f
, refcon
);
7449 /* Handle drags in size box. Based on code contributed by Ben
7450 Mesander and IM - Window Manager A. */
7453 do_grow_window (WindowPtr w
, EventRecord
*e
)
7458 struct frame
*f
= mac_window_to_frame (w
);
7460 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7462 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7464 /* see if it really changed size */
7467 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7468 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7470 x_set_window_size (f
, 0, columns
, rows
);
7475 /* Handle clicks in zoom box. Calculation of "standard state" based
7476 on code in IM - Window Manager A and code contributed by Ben
7477 Mesander. The standard state of an Emacs window is 80-characters
7478 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7481 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7484 Rect zoom_rect
, port_rect
;
7486 int w_title_height
, columns
, rows
;
7487 struct frame
*f
= mac_window_to_frame (w
);
7489 #if TARGET_API_MAC_CARBON
7491 Point standard_size
;
7493 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7494 standard_size
.v
= FRAME_MAC_DISPLAY_INFO (f
)->height
;
7496 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7497 zoom_in_or_out
= inZoomIn
;
7500 /* Adjust the standard size according to character boundaries. */
7502 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7503 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7504 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7505 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7506 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7507 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7508 && port_rect
.left
== zoom_rect
.left
7509 && port_rect
.top
== zoom_rect
.top
)
7510 zoom_in_or_out
= inZoomIn
;
7512 zoom_in_or_out
= inZoomOut
;
7515 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7517 #else /* not TARGET_API_MAC_CARBON */
7518 GetPort (&save_port
);
7520 SetPortWindowPort (w
);
7522 /* Clear window to avoid flicker. */
7523 EraseRect (&(w
->portRect
));
7524 if (zoom_in_or_out
== inZoomOut
)
7526 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7527 LocalToGlobal (&top_left
);
7529 /* calculate height of window's title bar */
7530 w_title_height
= top_left
.v
- 1
7531 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7533 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7534 zoom_rect
= qd
.screenBits
.bounds
;
7535 zoom_rect
.top
+= w_title_height
;
7536 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7538 zoom_rect
.right
= zoom_rect
.left
7539 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7541 /* Adjust the standard size according to character boundaries. */
7542 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7544 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7546 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7550 ZoomWindow (w
, zoom_in_or_out
, w
== front_emacs_window ());
7552 SetPort (save_port
);
7553 #endif /* not TARGET_API_MAC_CARBON */
7555 /* retrieve window size and update application values */
7556 #if TARGET_API_MAC_CARBON
7557 GetWindowPortBounds (w
, &port_rect
);
7559 port_rect
= w
->portRect
;
7561 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7562 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7563 x_set_window_size (f
, 0, columns
, rows
);
7564 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7567 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7569 init_mac_drag_n_drop ()
7571 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7575 /* Intialize AppleEvent dispatcher table for the required events. */
7577 init_required_apple_events ()
7582 /* Make sure we have apple events before starting. */
7583 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7587 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7590 #if TARGET_API_MAC_CARBON
7591 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7592 NewAEEventHandlerUPP
7593 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7596 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7597 NewAEEventHandlerProc
7598 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7604 #if TARGET_API_MAC_CARBON
7605 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7606 NewAEEventHandlerUPP
7607 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7610 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7611 NewAEEventHandlerProc
7612 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7618 #if TARGET_API_MAC_CARBON
7619 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7620 NewAEEventHandlerUPP
7621 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7624 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7625 NewAEEventHandlerProc
7626 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7632 #if TARGET_API_MAC_CARBON
7633 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7634 NewAEEventHandlerUPP
7635 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7638 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7639 NewAEEventHandlerProc
7640 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7647 #if USE_CARBON_EVENTS
7650 init_service_handler ()
7652 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7653 {kEventClassService
, kEventServiceCopy
},
7654 {kEventClassService
, kEventServicePaste
}};
7655 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7656 3, specs
, NULL
, NULL
);
7660 MAC_TODO: Check to see if this is called by AEProcessDesc...
7663 mac_handle_service_event (EventHandlerCallRef callRef
,
7664 EventRef event
, void *data
)
7666 OSStatus err
= noErr
;
7667 switch (GetEventKind (event
))
7669 case kEventServiceGetTypes
:
7671 CFMutableArrayRef copyTypes
, pasteTypes
;
7673 Boolean selection
= true;
7675 GetEventParameter(event, kEventParamServicePasteTypes,
7676 typeCFMutableArrayRef, NULL,
7677 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7679 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7680 typeCFMutableArrayRef
, NULL
,
7681 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7682 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7684 CFArrayAppendValue (copyTypes
, type
);
7685 //CFArrayAppendValue (pasteTypes, type);
7689 case kEventServiceCopy
:
7691 ScrapRef currentScrap
, specificScrap
;
7695 GetCurrentScrap (¤tScrap
);
7697 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7700 void *buffer
= xmalloc (byteCount
);
7703 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7704 sizeof (ScrapRef
), NULL
, &specificScrap
);
7706 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7707 &byteCount
, buffer
);
7709 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7710 kScrapFlavorMaskNone
, byteCount
, buffer
);
7716 case kEventServicePaste
:
7719 // Get the current location
7721 ScrapRef specificScrap;
7722 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7723 sizeof(ScrapRef), NULL, &specificScrap);
7724 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7726 void * buffer = xmalloc(byteCount);
7727 if (buffer != NULL ) {
7728 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7729 &byteCount, buffer);
7731 // Actually place in the buffer
7733 // Get the current "selection" string here
7746 /* Open Application Apple Event */
7748 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7754 /* Defined in mac.c. */
7756 path_from_vol_dir_name (char *, int, short, long, char *);
7759 /* Called when we receive an AppleEvent with an ID of
7760 "kAEOpenDocuments". This routine gets the direct parameter,
7761 extracts the FSSpecs in it, and puts their names on a list. */
7763 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7768 DescType actual_type
;
7771 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7773 goto descriptor_error_exit
;
7775 /* Check to see that we got all of the required parameters from the
7776 event descriptor. For an 'odoc' event this should just be the
7778 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7779 &actual_type
, (Ptr
) &keyword
,
7780 sizeof (keyword
), &actual_size
);
7781 /* No error means that we found some unused parameters.
7782 errAEDescNotFound means that there are no more parameters. If we
7783 get an error code other than that, flag it. */
7784 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7786 err
= errAEEventNotHandled
;
7791 /* Got all the parameters we need. Now, go through the direct
7792 object list and parse it up. */
7794 long num_files_to_open
;
7796 err
= AECountItems (&the_desc
, &num_files_to_open
);
7801 /* AE file list is one based so just use that for indexing here. */
7802 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7805 Str255 path_name
, unix_path_name
;
7810 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7811 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7812 if (err
!= noErr
) break;
7815 err
= FSpMakeFSRef (&fs
, &fref
);
7816 if (err
!= noErr
) break;
7818 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7820 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7822 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7824 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7825 drag_and_drop_file_list
);
7831 /* Nuke the coerced file list in any case */
7832 err2
= AEDisposeDesc(&the_desc
);
7834 descriptor_error_exit
:
7835 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7841 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7842 DragReference theDrag
)
7846 FlavorFlags theFlags
;
7849 ItemReference theItem
;
7852 Size size
= sizeof (HFSFlavor
);
7854 drag_and_drop_file_list
= Qnil
;
7855 GetDragMouse (theDrag
, &mouse
, 0L);
7856 CountDragItems (theDrag
, &items
);
7857 for (index
= 1; index
<= items
; index
++)
7859 /* Only handle file references. */
7860 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7861 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7862 if (result
== noErr
)
7869 Str255 unix_path_name
;
7870 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7872 /* Use Carbon routines, otherwise it converts the file name
7873 to /Macintosh HD/..., which is not correct. */
7874 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7875 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7877 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7878 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7879 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7881 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7882 drag_and_drop_file_list
);
7887 /* If there are items in the list, construct an event and post it to
7888 the queue like an interrupt using kbd_buffer_store_event. */
7889 if (!NILP (drag_and_drop_file_list
))
7891 struct input_event event
;
7893 struct frame
*f
= mac_window_to_frame (window
);
7894 SetPortWindowPort (window
);
7895 GlobalToLocal (&mouse
);
7897 event
.kind
= DRAG_N_DROP_EVENT
;
7899 event
.modifiers
= 0;
7900 event
.timestamp
= TickCount () * (1000 / 60);
7901 XSETINT (event
.x
, mouse
.h
);
7902 XSETINT (event
.y
, mouse
.v
);
7903 XSETFRAME (frame
, f
);
7904 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7906 /* Post to the interrupt queue */
7907 kbd_buffer_store_event (&event
);
7908 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7910 ProcessSerialNumber psn
;
7911 GetCurrentProcess (&psn
);
7912 SetFrontProcess (&psn
);
7918 /* Print Document Apple Event */
7920 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7922 return errAEEventNotHandled
;
7927 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7929 /* FixMe: Do we need an unwind-protect or something here? And what
7930 do we do about unsaved files. Currently just forces quit rather
7931 than doing recursive callback to get user input. */
7933 terminate_flag
= true;
7935 /* Fkill_emacs doesn't return. We have to return. (TI) */
7942 profiler_exit_proc ()
7944 ProfilerDump ("\pEmacs.prof");
7949 /* These few functions implement Emacs as a normal Mac application
7950 (almost): set up the heap and the Toolbox, handle necessary
7951 system events plus a few simple menu events. They also set up
7952 Emacs's access to functions defined in the rest of this file.
7953 Emacs uses function hooks to perform all its terminal I/O. A
7954 complete list of these functions appear in termhooks.h. For what
7955 they do, read the comments there and see also w32term.c and
7956 xterm.c. What's noticeably missing here is the event loop, which
7957 is normally present in most Mac application. After performing the
7958 necessary Mac initializations, main passes off control to
7959 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7960 mac_read_socket (defined further below) to read input. This is
7961 where WaitNextEvent is called to process Mac events. This is also
7962 where check_alarm in sysdep.c is called to simulate alarm signals.
7963 This makes the cursor jump back to its correct position after
7964 briefly jumping to that of the matching parenthesis, print useful
7965 hints and prompts in the minibuffer after the user stops typing for
7968 #if !TARGET_API_MAC_CARBON
7973 #if __profile__ /* is the profiler on? */
7974 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7979 /* set creator and type for files created by MSL */
7984 do_init_managers ();
7989 do_check_ram_size ();
7992 init_emacs_passwd_dir ();
7996 initialize_applescript ();
7998 init_required_apple_events ();
8004 /* set up argv array from STR# resource */
8005 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8009 /* free up AppleScript resources on exit */
8010 atexit (terminate_applescript
);
8012 #if __profile__ /* is the profiler on? */
8013 atexit (profiler_exit_proc
);
8016 /* 3rd param "envp" never used in emacs_main */
8017 (void) emacs_main (argc
, argv
, 0);
8020 /* Never reached - real exit in Fkill_emacs */
8025 /* Table for translating Mac keycode to X keysym values. Contributed
8026 by Sudhir Shenoy. */
8027 static unsigned char keycode_to_xkeysym_table
[] = {
8028 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8029 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8030 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8032 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8033 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
8034 /*0x38*/ 0, 0, 0, 0,
8035 /*0x3C*/ 0, 0, 0, 0,
8037 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8038 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
8039 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8040 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8042 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8043 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8044 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8045 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8047 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8048 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8049 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8050 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8052 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8053 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8054 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8055 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8059 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8061 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8062 return *xKeySym
!= 0;
8065 /* Emacs calls this whenever it wants to read an input event from the
8068 XTread_socket (sd
, expected
, hold_quit
)
8070 struct input_event
*hold_quit
;
8072 struct input_event inev
;
8074 #if USE_CARBON_EVENTS
8076 EventTargetRef toolbox_dispatcher
= GetEventDispatcherTarget ();
8078 EventMask event_mask
;
8081 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8083 if (interrupt_input_blocked
)
8085 interrupt_input_pending
= 1;
8089 interrupt_input_pending
= 0;
8092 /* So people can tell when we have read the available input. */
8093 input_signal_count
++;
8095 /* Don't poll for events to process (specifically updateEvt) if
8096 window update currently already in progress. A call to redisplay
8097 (in do_window_update) can be preempted by another call to
8098 redisplay, causing blank regions to be left on the screen and the
8099 cursor to be left at strange places. */
8100 if (handling_window_update
)
8107 Fkill_emacs (make_number (1));
8109 #if !USE_CARBON_EVENTS
8110 event_mask
= everyEvent
;
8111 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8112 event_mask
-= highLevelEventMask
;
8114 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
))
8115 #else /* USE_CARBON_EVENTS */
8116 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8117 kEventRemoveFromQueue
, &eventRef
))
8118 #endif /* USE_CARBON_EVENTS */
8123 /* It is necessary to set this (additional) argument slot of an
8124 event to nil because keyboard.c protects incompletely
8125 processed event from being garbage collected by placing them
8126 in the kbd_buffer_gcpro vector. */
8128 inev
.kind
= NO_EVENT
;
8131 #if USE_CARBON_EVENTS
8132 /* Handle new events */
8133 if (!mac_convert_event_ref (eventRef
, &er
))
8134 switch (GetEventClass (eventRef
))
8136 case kEventClassWindow
:
8137 if (GetEventKind (eventRef
) == kEventWindowBoundsChanged
)
8139 WindowPtr window_ptr
;
8140 GetEventParameter(eventRef
, kEventParamDirectObject
,
8141 typeWindowRef
, NULL
, sizeof(WindowPtr
),
8143 f
= mac_window_to_frame (window_ptr
);
8144 if (f
&& !f
->async_iconified
)
8145 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8146 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8149 case kEventClassMouse
:
8150 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8154 WindowPtr window_ptr
= front_emacs_window ();
8156 if (!IsValidWindowPtr (window_ptr
))
8162 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8163 typeSInt32
, NULL
, sizeof (SInt32
),
8165 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8166 typeQDPoint
, NULL
, sizeof (Point
),
8168 inev
.kind
= WHEEL_EVENT
;
8170 inev
.modifiers
= (mac_event_to_emacs_modifiers (eventRef
)
8171 | ((delta
< 0) ? down_modifier
8173 SetPortWindowPort (window_ptr
);
8174 GlobalToLocal (&point
);
8175 XSETINT (inev
.x
, point
.h
);
8176 XSETINT (inev
.y
, point
.v
);
8177 XSETFRAME (inev
.frame_or_window
,
8178 mac_window_to_frame (window_ptr
));
8179 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8182 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8186 /* Send the event to the appropriate receiver. */
8187 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8190 #endif /* USE_CARBON_EVENTS */
8196 WindowPtr window_ptr
;
8200 #if USE_CARBON_EVENTS
8201 /* This is needed to send mouse events like aqua window
8202 buttons to the correct handler. */
8203 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8204 != eventNotHandledErr
)
8208 if (dpyinfo
->grabbed
&& last_mouse_frame
8209 && FRAME_LIVE_P (last_mouse_frame
))
8211 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8212 part_code
= inContent
;
8216 part_code
= FindWindow (er
.where
, &window_ptr
);
8217 if (tip_window
&& window_ptr
== tip_window
)
8219 HideWindow (tip_window
);
8220 part_code
= FindWindow (er
.where
, &window_ptr
);
8224 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8230 f
= mac_window_to_frame (front_emacs_window ());
8231 saved_menu_event_location
= er
.where
;
8232 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8233 XSETFRAME (inev
.frame_or_window
, f
);
8237 if (window_ptr
!= front_emacs_window ())
8238 SelectWindow (window_ptr
);
8241 SInt16 control_part_code
;
8243 Point mouse_loc
= er
.where
;
8245 f
= mac_window_to_frame (window_ptr
);
8246 /* convert to local coordinates of new window */
8247 SetPortWindowPort (window_ptr
);
8249 GlobalToLocal (&mouse_loc
);
8250 #if TARGET_API_MAC_CARBON
8251 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8252 &control_part_code
);
8254 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8258 #if USE_CARBON_EVENTS
8259 inev
.code
= mac_get_mouse_btn (eventRef
);
8260 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8262 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8263 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8265 XSETINT (inev
.x
, mouse_loc
.h
);
8266 XSETINT (inev
.y
, mouse_loc
.v
);
8267 inev
.timestamp
= er
.when
* (1000 / 60);
8268 /* ticks to milliseconds */
8270 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8271 #if TARGET_API_MAC_CARBON
8274 || control_part_code
!= 0
8278 struct scroll_bar
*bar
;
8280 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8282 bar
= tracked_scroll_bar
;
8283 control_part_code
= kControlIndicatorPart
;
8286 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8287 x_scroll_bar_handle_click (bar
, control_part_code
,
8289 if (er
.what
== mouseDown
8290 && control_part_code
== kControlIndicatorPart
)
8291 tracked_scroll_bar
= bar
;
8293 tracked_scroll_bar
= NULL
;
8298 int x
= mouse_loc
.h
;
8299 int y
= mouse_loc
.v
;
8301 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
8302 if (EQ (window
, f
->tool_bar_window
))
8304 if (er
.what
== mouseDown
)
8305 handle_tool_bar_click (f
, x
, y
, 1, 0);
8307 handle_tool_bar_click (f
, x
, y
, 0,
8313 XSETFRAME (inev
.frame_or_window
, f
);
8314 inev
.kind
= MOUSE_CLICK_EVENT
;
8318 if (er
.what
== mouseDown
)
8320 dpyinfo
->grabbed
|= (1 << inev
.code
);
8321 last_mouse_frame
= f
;
8322 /* Ignore any mouse motion that happened
8323 before this event; any subsequent
8324 mouse-movement Emacs events should reflect
8325 only motion after the ButtonPress. */
8330 last_tool_bar_item
= -1;
8334 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
8335 /* If a button is released though it was not
8336 previously pressed, that would be because
8337 of multi-button emulation. */
8338 dpyinfo
->grabbed
= 0;
8340 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
8346 inev
.modifiers
|= down_modifier
;
8349 inev
.modifiers
|= up_modifier
;
8356 #if TARGET_API_MAC_CARBON
8357 DragWindow (window_ptr
, er
.where
, NULL
);
8358 #else /* not TARGET_API_MAC_CARBON */
8359 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8360 #endif /* not TARGET_API_MAC_CARBON */
8361 /* Update the frame parameters. */
8363 struct frame
*f
= mac_window_to_frame (window_ptr
);
8365 if (f
&& !f
->async_iconified
)
8366 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8371 if (TrackGoAway (window_ptr
, er
.where
))
8373 inev
.kind
= DELETE_WINDOW_EVENT
;
8374 XSETFRAME (inev
.frame_or_window
,
8375 mac_window_to_frame (window_ptr
));
8379 /* window resize handling added --ben */
8381 do_grow_window (window_ptr
, &er
);
8384 /* window zoom handling added --ben */
8387 if (TrackBox (window_ptr
, er
.where
, part_code
))
8388 do_zoom_window (window_ptr
, part_code
);
8398 #if USE_CARBON_EVENTS
8399 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8400 != eventNotHandledErr
)
8403 do_window_update ((WindowPtr
) er
.message
);
8407 #if USE_CARBON_EVENTS
8408 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8409 != eventNotHandledErr
)
8412 switch ((er
.message
>> 24) & 0x000000FF)
8414 case suspendResumeMessage
:
8415 if ((er
.message
& resumeFlag
) == 1)
8421 case mouseMovedMessage
:
8422 previous_help_echo_string
= help_echo_string
;
8423 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
8426 do_mouse_moved (er
.where
, &f
);
8428 /* If the contents of the global variable
8429 help_echo_string has changed, generate a
8431 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
8439 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
8441 #if USE_CARBON_EVENTS
8442 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8443 != eventNotHandledErr
)
8446 if (window_ptr
== tip_window
)
8448 HideWindow (tip_window
);
8452 if (!is_emacs_window (window_ptr
))
8455 f
= mac_window_to_frame (window_ptr
);
8457 if ((er
.modifiers
& activeFlag
) != 0)
8459 /* A window has been activated */
8460 Point mouse_loc
= er
.where
;
8462 x_new_focus_frame (dpyinfo
, f
);
8463 activate_scroll_bars (f
);
8465 SetPortWindowPort (window_ptr
);
8466 GlobalToLocal (&mouse_loc
);
8467 /* Window-activated event counts as mouse movement,
8468 so update things that depend on mouse position. */
8469 note_mouse_movement (mac_window_to_frame (window_ptr
),
8474 /* A window has been deactivated */
8475 dpyinfo
->grabbed
= 0;
8477 if (f
== dpyinfo
->x_focus_frame
)
8479 x_new_focus_frame (dpyinfo
, 0);
8480 deactivate_scroll_bars (f
);
8484 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8486 /* If we move outside the frame, then we're
8487 certainly no longer on any text in the
8489 clear_mouse_face (dpyinfo
);
8490 dpyinfo
->mouse_face_mouse_frame
= 0;
8493 /* Generate a nil HELP_EVENT to cancel a help-echo.
8494 Do it only if there's something to cancel.
8495 Otherwise, the startup message is cleared when the
8496 mouse leaves the frame. */
8497 if (any_help_event_p
)
8506 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8509 #if USE_CARBON_EVENTS
8510 /* When using Carbon Events, we need to pass raw keyboard
8511 events to the TSM ourselves. If TSM handles it, it
8512 will pass back noErr, otherwise it will pass back
8513 "eventNotHandledErr" and we can process it
8515 if ((!NILP (Vmac_pass_command_to_system
)
8516 || !(er
.modifiers
& cmdKey
))
8517 && (!NILP (Vmac_pass_control_to_system
)
8518 || !(er
.modifiers
& controlKey
)))
8519 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8520 != eventNotHandledErr
)
8524 #if TARGET_API_MAC_CARBON
8525 if (!IsValidWindowPtr (front_emacs_window ()))
8534 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8536 clear_mouse_face (dpyinfo
);
8537 dpyinfo
->mouse_face_hidden
= 1;
8540 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8542 inev
.code
= 0xff00 | xkeysym
;
8543 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8547 if (er
.modifiers
& (controlKey
|
8548 (NILP (Vmac_command_key_is_meta
) ? optionKey
8551 /* This code comes from Keyboard Resource,
8552 Appendix C of IM - Text. This is necessary
8553 since shift is ignored in KCHR table
8554 translation when option or command is pressed.
8555 It also does not translate correctly
8556 control-shift chars like C-% so mask off shift
8558 int new_modifiers
= er
.modifiers
& 0xe600;
8559 /* mask off option and command */
8560 int new_keycode
= keycode
| new_modifiers
;
8561 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8562 unsigned long some_state
= 0;
8563 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8564 &some_state
) & 0xff;
8565 } else if (!NILP(Vmac_option_modifier
) && (er
.modifiers
& optionKey
))
8567 /* When using the option key as an emacs modifier, convert
8568 the pressed key code back to one without the Mac option
8569 modifier applied. */
8570 int new_modifiers
= er
.modifiers
& ~optionKey
;
8571 int new_keycode
= keycode
| new_modifiers
;
8572 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8573 unsigned long some_state
= 0;
8574 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8575 &some_state
) & 0xff;
8578 inev
.code
= er
.message
& charCodeMask
;
8579 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8583 /* If variable mac-convert-keyboard-input-to-latin-1 is
8584 non-nil, convert non-ASCII characters typed at the Mac
8585 keyboard (presumed to be in the Mac Roman encoding) to
8586 iso-latin-1 encoding before they are passed to Emacs.
8587 This enables the Mac keyboard to be used to enter
8588 non-ASCII iso-latin-1 characters directly. */
8589 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8590 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8592 static TECObjectRef converter
= NULL
;
8593 OSStatus the_err
= noErr
;
8594 OSStatus convert_status
= noErr
;
8596 if (converter
== NULL
)
8598 the_err
= TECCreateConverter (&converter
,
8599 kTextEncodingMacRoman
,
8600 mac_keyboard_text_encoding
);
8601 current_mac_keyboard_text_encoding
8602 = mac_keyboard_text_encoding
;
8604 else if (mac_keyboard_text_encoding
8605 != current_mac_keyboard_text_encoding
)
8607 /* Free the converter for the current encoding
8608 before creating a new one. */
8609 TECDisposeConverter (converter
);
8610 the_err
= TECCreateConverter (&converter
,
8611 kTextEncodingMacRoman
,
8612 mac_keyboard_text_encoding
);
8613 current_mac_keyboard_text_encoding
8614 = mac_keyboard_text_encoding
;
8617 if (the_err
== noErr
)
8619 unsigned char ch
= inev
.code
;
8620 ByteCount actual_input_length
, actual_output_length
;
8621 unsigned char outch
;
8623 convert_status
= TECConvertText (converter
, &ch
, 1,
8624 &actual_input_length
,
8626 &actual_output_length
);
8627 if (convert_status
== noErr
8628 && actual_input_length
== 1
8629 && actual_output_length
== 1)
8634 #if USE_CARBON_EVENTS
8635 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8637 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8639 XSETFRAME (inev
.frame_or_window
,
8640 mac_window_to_frame (front_emacs_window ()));
8641 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8644 case kHighLevelEvent
:
8645 drag_and_drop_file_list
= Qnil
;
8647 AEProcessAppleEvent(&er
);
8649 /* Build a DRAG_N_DROP_EVENT type event as is done in
8650 constuct_drag_n_drop in w32term.c. */
8651 if (!NILP (drag_and_drop_file_list
))
8653 struct frame
*f
= NULL
;
8657 wp
= front_emacs_window ();
8661 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8662 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8663 wp
= front_emacs_window ();
8667 f
= mac_window_to_frame (wp
);
8669 inev
.kind
= DRAG_N_DROP_EVENT
;
8671 inev
.timestamp
= er
.when
* (1000 / 60);
8672 /* ticks to milliseconds */
8673 #if USE_CARBON_EVENTS
8674 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8676 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8679 XSETINT (inev
.x
, 0);
8680 XSETINT (inev
.y
, 0);
8682 XSETFRAME (frame
, f
);
8683 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8685 /* Regardless of whether Emacs was suspended or in the
8686 foreground, ask it to redraw its entire screen.
8687 Otherwise parts of the screen can be left in an
8688 inconsistent state. */
8690 #if TARGET_API_MAC_CARBON
8694 GetWindowPortBounds (wp
, &r
);
8695 InvalWindowRect (wp
, &r
);
8697 #else /* not TARGET_API_MAC_CARBON */
8698 InvalRect (&(wp
->portRect
));
8699 #endif /* not TARGET_API_MAC_CARBON */
8704 #if USE_CARBON_EVENTS
8705 ReleaseEvent (eventRef
);
8708 if (inev
.kind
!= NO_EVENT
)
8710 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8715 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
8720 XSETFRAME (frame
, f
);
8726 any_help_event_p
= 1;
8727 gen_help_event (help_echo_string
, frame
, help_echo_window
,
8728 help_echo_object
, help_echo_pos
);
8732 help_echo_string
= Qnil
;
8733 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
8740 /* If the focus was just given to an autoraising frame,
8742 /* ??? This ought to be able to handle more than one such frame. */
8743 if (pending_autoraise_frame
)
8745 x_raise_frame (pending_autoraise_frame
);
8746 pending_autoraise_frame
= 0;
8749 #if !TARGET_API_MAC_CARBON
8750 check_alarm (); /* simulate the handling of a SIGALRM */
8758 /* Need to override CodeWarrior's input function so no conversion is
8759 done on newlines Otherwise compiled functions in .elc files will be
8760 read incorrectly. Defined in ...:MSL C:MSL
8761 Common:Source:buffer_io.c. */
8764 __convert_to_newlines (unsigned char * p
, size_t * n
)
8770 __convert_from_newlines (unsigned char * p
, size_t * n
)
8777 /* Initialize the struct pointed to by MW to represent a new COLS x
8778 ROWS Macintosh window, using font with name FONTNAME and size
8781 make_mac_frame (FRAME_PTR fp
)
8784 #if TARGET_API_MAC_CARBON
8785 static int making_terminal_window
= 0;
8787 static int making_terminal_window
= 1;
8790 mwp
= fp
->output_data
.mac
;
8793 if (making_terminal_window
)
8795 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8798 making_terminal_window
= 0;
8802 #if TARGET_API_MAC_CARBON
8805 SetRect (&r
, 0, 0, 1, 1);
8806 if (CreateNewWindow (kDocumentWindowClass
,
8807 kWindowStandardDocumentAttributes
8808 /* | kWindowToolbarButtonAttribute */,
8809 &r
, &mwp
->mWP
) != noErr
)
8811 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8816 SetWRefCon (mwp
->mWP
, (long) mwp
);
8817 /* so that update events can find this mac_output struct */
8818 mwp
->mFP
= fp
; /* point back to emacs frame */
8820 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8826 make_mac_terminal_frame (struct frame
*f
)
8830 XSETFRAME (frame
, f
);
8832 f
->output_method
= output_mac
;
8833 f
->output_data
.mac
= (struct mac_output
*)
8834 xmalloc (sizeof (struct mac_output
));
8835 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8837 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8839 FRAME_COLS (f
) = 96;
8840 FRAME_LINES (f
) = 4;
8842 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8843 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8845 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8847 f
->output_data
.mac
->cursor_pixel
= 0;
8848 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8849 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8850 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8852 FRAME_FONTSET (f
) = -1;
8853 f
->output_data
.mac
->explicit_parent
= 0;
8856 f
->border_width
= 0;
8858 f
->internal_border_width
= 0;
8863 f
->new_text_cols
= 0;
8864 f
->new_text_lines
= 0;
8870 /* Need to be initialized for unshow_buffer in window.c. */
8871 selected_window
= f
->selected_window
;
8873 Fmodify_frame_parameters (frame
,
8874 Fcons (Fcons (Qfont
,
8875 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8876 Fmodify_frame_parameters (frame
,
8877 Fcons (Fcons (Qforeground_color
,
8878 build_string ("black")), Qnil
));
8879 Fmodify_frame_parameters (frame
,
8880 Fcons (Fcons (Qbackground_color
,
8881 build_string ("white")), Qnil
));
8883 ShowWindow (f
->output_data
.mac
->mWP
);
8887 /***********************************************************************
8889 ***********************************************************************/
8891 int mac_initialized
= 0;
8894 mac_initialize_display_info ()
8896 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8897 GDHandle main_device_handle
;
8899 bzero (dpyinfo
, sizeof (*dpyinfo
));
8901 /* Put it on x_display_name_list. */
8902 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8903 x_display_name_list
);
8904 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8907 dpyinfo
->mac_id_name
8908 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8909 + SCHARS (Vsystem_name
)
8911 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8912 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8914 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8915 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8918 main_device_handle
= LMGetMainDevice();
8920 dpyinfo
->reference_count
= 0;
8921 dpyinfo
->resx
= 75.0;
8922 dpyinfo
->resy
= 75.0;
8923 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
8925 /* HasDepth returns true if it is possible to have a 32 bit display,
8926 but this may not be what is actually used. Mac OSX can do better.
8927 CGMainDisplayID is only available on OSX 10.2 and higher, but the
8928 header for CGGetActiveDisplayList says that the first display returned
8929 is the active one, so we use that. */
8931 CGDirectDisplayID disp_id
[1];
8932 CGDisplayCount disp_count
;
8933 CGDisplayErr error_code
;
8935 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
8936 if (error_code
!= 0)
8937 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
8939 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
8942 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8943 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
8944 gdDevType
, dpyinfo
->color_p
))
8947 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8948 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8949 dpyinfo
->grabbed
= 0;
8950 dpyinfo
->root_window
= NULL
;
8951 dpyinfo
->image_cache
= make_image_cache ();
8953 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8954 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8955 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8956 dpyinfo
->mouse_face_window
= Qnil
;
8957 dpyinfo
->mouse_face_overlay
= Qnil
;
8958 dpyinfo
->mouse_face_hidden
= 0;
8961 struct mac_display_info
*
8962 mac_term_init (display_name
, xrm_option
, resource_name
)
8963 Lisp_Object display_name
;
8965 char *resource_name
;
8967 struct mac_display_info
*dpyinfo
;
8968 GDHandle main_device_handle
;
8970 if (!mac_initialized
)
8973 mac_initialized
= 1;
8976 mac_initialize_display_info (display_name
);
8978 dpyinfo
= &one_mac_display_info
;
8980 main_device_handle
= LMGetMainDevice();
8982 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8983 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8992 extern int inhibit_window_system
;
8993 extern int noninteractive
;
8994 CFBundleRef appsBundle
;
8997 /* No need to test if already -nw*/
8998 if (inhibit_window_system
|| noninteractive
)
9001 appsBundle
= CFBundleGetMainBundle();
9002 if (appsBundle
!= NULL
)
9004 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9005 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9006 /* We found the bundle identifier, now we know we are valid. */
9013 /* MAC_TODO: Have this start the bundled executable */
9015 /* For now, prevent the fatal error by bringing it up in the terminal */
9016 inhibit_window_system
= 1;
9020 MakeMeTheFrontProcess ()
9022 ProcessSerialNumber psn
;
9025 err
= GetCurrentProcess (&psn
);
9027 (void) SetFrontProcess (&psn
);
9030 /***** Code to handle C-g testing *****/
9032 /* Contains the Mac modifier formed from quit_char */
9033 static mac_quit_char_modifiers
= 0;
9034 static mac_quit_char_keycode
;
9035 extern int quit_char
;
9038 mac_determine_quit_char_modifiers()
9040 /* Todo: Determine modifiers from quit_char. */
9041 UInt32 qc_modifiers
= ctrl_modifier
;
9044 mac_quit_char_modifiers
= 0;
9045 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9046 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9047 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9048 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9052 init_quit_char_handler ()
9054 /* TODO: Let this support keys other the 'g' */
9055 mac_quit_char_keycode
= 5;
9056 /* Look at <architecture/adb_kb_map.h> for details */
9057 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9059 mac_determine_quit_char_modifiers();
9063 quit_char_comp (EventRef inEvent
, void *inCompData
)
9065 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9067 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9071 UInt32 keyModifiers
;
9072 GetEventParameter(inEvent
, kEventParamKeyCode
,
9073 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9074 if (keyCode
!= mac_quit_char_keycode
)
9076 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9077 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9078 if (keyModifiers
!= mac_quit_char_modifiers
)
9085 mac_check_for_quit_char ()
9088 static EMACS_TIME last_check_time
= { 0, 0 };
9089 static EMACS_TIME one_second
= { 1, 0 };
9092 /* If windows are not initialized, return immediately (keep it bouncin'). */
9093 if (!mac_quit_char_modifiers
)
9096 /* Don't check if last check is less than a second ago. */
9097 EMACS_GET_TIME (now
);
9098 EMACS_SUB_TIME (t
, now
, last_check_time
);
9099 if (EMACS_TIME_LT (t
, one_second
))
9101 last_check_time
= now
;
9103 /* Redetermine modifiers because they are based on lisp variables */
9104 mac_determine_quit_char_modifiers ();
9106 /* Fill the queue with events */
9108 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9109 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9114 struct input_event e
;
9116 /* Use an input_event to emulate what the interrupt handler does. */
9118 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9122 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9123 XSETFRAME (e
.frame_or_window
, mac_window_to_frame (front_emacs_window ()));
9124 /* Remove event from queue to prevent looping. */
9125 RemoveEventFromQueue (GetMainEventQueue (), event
);
9126 ReleaseEvent (event
);
9127 kbd_buffer_store_event (&e
);
9131 #endif /* MAC_OSX */
9133 /* Set up use of X before we make the first connection. */
9135 extern frame_parm_handler mac_frame_parm_handlers
[];
9137 static struct redisplay_interface x_redisplay_interface
=
9139 mac_frame_parm_handlers
,
9143 x_clear_end_of_line
,
9145 x_after_update_window_line
,
9146 x_update_window_begin
,
9147 x_update_window_end
,
9151 x_clear_window_mouse_face
,
9152 x_get_glyph_overhangs
,
9153 x_fix_overlapping_area
,
9154 x_draw_fringe_bitmap
,
9155 0, /* define_fringe_bitmap */
9156 0, /* destroy_fringe_bitmap */
9157 mac_per_char_metric
,
9159 NULL
, /* mac_compute_glyph_string_overhangs */
9160 x_draw_glyph_string
,
9161 mac_define_frame_cursor
,
9162 mac_clear_frame_area
,
9163 mac_draw_window_cursor
,
9164 mac_draw_vertical_window_border
,
9165 mac_shift_glyphs_for_insert
9171 rif
= &x_redisplay_interface
;
9173 clear_frame_hook
= x_clear_frame
;
9174 ins_del_lines_hook
= x_ins_del_lines
;
9175 delete_glyphs_hook
= x_delete_glyphs
;
9176 ring_bell_hook
= XTring_bell
;
9177 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9178 set_terminal_modes_hook
= XTset_terminal_modes
;
9179 update_begin_hook
= x_update_begin
;
9180 update_end_hook
= x_update_end
;
9181 set_terminal_window_hook
= XTset_terminal_window
;
9182 read_socket_hook
= XTread_socket
;
9183 frame_up_to_date_hook
= XTframe_up_to_date
;
9184 mouse_position_hook
= XTmouse_position
;
9185 frame_rehighlight_hook
= XTframe_rehighlight
;
9186 frame_raise_lower_hook
= XTframe_raise_lower
;
9188 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9189 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9190 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9191 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9193 scroll_region_ok
= 1; /* we'll scroll partial frames */
9194 char_ins_del_ok
= 1;
9195 line_ins_del_ok
= 1; /* we'll just blt 'em */
9196 fast_clear_end_of_line
= 1; /* X does this well */
9197 memory_below_frame
= 0; /* we don't remember what scrolls
9202 last_tool_bar_item
= -1;
9203 any_help_event_p
= 0;
9205 /* Try to use interrupt input; if we can't, then start polling. */
9206 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9208 #ifdef USE_X_TOOLKIT
9209 XtToolkitInitialize ();
9210 Xt_app_con
= XtCreateApplicationContext ();
9211 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9213 /* Install an asynchronous timer that processes Xt timeout events
9214 every 0.1s. This is necessary because some widget sets use
9215 timeouts internally, for example the LessTif menu bar, or the
9216 Xaw3d scroll bar. When Xt timouts aren't processed, these
9217 widgets don't behave normally. */
9219 EMACS_TIME interval
;
9220 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9221 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9225 #if USE_TOOLKIT_SCROLL_BARS
9226 xaw3d_arrow_scroll
= False
;
9227 xaw3d_pick_top
= True
;
9231 /* Note that there is no real way portable across R3/R4 to get the
9232 original error handler. */
9233 XSetErrorHandler (x_error_handler
);
9234 XSetIOErrorHandler (x_io_error_quitter
);
9236 /* Disable Window Change signals; they are handled by X events. */
9238 signal (SIGWINCH
, SIG_DFL
);
9239 #endif /* ! defined (SIGWINCH) */
9241 signal (SIGPIPE
, x_connection_signal
);
9245 mac_initialize_display_info ();
9247 #if TARGET_API_MAC_CARBON
9248 init_required_apple_events ();
9250 init_mac_drag_n_drop ();
9252 #if USE_CARBON_EVENTS
9253 init_service_handler ();
9255 init_quit_char_handler ();
9258 DisableMenuCommand (NULL
, kHICommandQuit
);
9260 if (!inhibit_window_system
)
9261 MakeMeTheFrontProcess ();
9271 staticpro (&x_error_message_string
);
9272 x_error_message_string
= Qnil
;
9275 Qmodifier_value
= intern ("modifier-value");
9276 Qalt
= intern ("alt");
9277 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
9278 Qhyper
= intern ("hyper");
9279 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
9280 Qsuper
= intern ("super");
9281 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
9283 Fprovide (intern ("mac-carbon"), Qnil
);
9285 staticpro (&Qreverse
);
9286 Qreverse
= intern ("reverse");
9288 staticpro (&x_display_name_list
);
9289 x_display_name_list
= Qnil
;
9291 staticpro (&last_mouse_scroll_bar
);
9292 last_mouse_scroll_bar
= Qnil
;
9294 staticpro (&Qvendor_specific_keysyms
);
9295 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9297 staticpro (&last_mouse_press_frame
);
9298 last_mouse_press_frame
= Qnil
;
9300 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9301 staticpro (&Qmac_ready_for_drag_n_drop
);
9303 Qbig5
= intern ("big5");
9306 Qcn_gb
= intern ("cn-gb");
9307 staticpro (&Qcn_gb
);
9309 Qsjis
= intern ("sjis");
9312 Qeuc_kr
= intern ("euc-kr");
9313 staticpro (&Qeuc_kr
);
9315 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9316 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9317 x_autoselect_window_p
= 0;
9319 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9320 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9321 Vx_toolkit_scroll_bars
= Qt
;
9323 DEFVAR_BOOL ("x-use-underline-position-properties",
9324 &x_use_underline_position_properties
,
9325 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9326 nil means ignore them. If you encounter fonts with bogus
9327 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9328 to 4.1, set this to nil. */);
9329 x_use_underline_position_properties
= 0;
9331 staticpro (&last_mouse_motion_frame
);
9332 last_mouse_motion_frame
= Qnil
;
9334 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9335 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9336 Otherwise the option key is used. */);
9337 Vmac_command_key_is_meta
= Qt
;
9339 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
9340 doc
: /* Modifier to use for the Mac alt/option key. The value can
9341 be alt, hyper, or super for the respective modifier. If the value is
9342 nil then the key will act as the normal Mac option modifier. */);
9343 Vmac_option_modifier
= Qnil
;
9345 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9346 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9347 useful for non-standard keyboard layouts. */);
9348 Vmac_reverse_ctrl_meta
= Qnil
;
9350 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9351 &Vmac_emulate_three_button_mouse
,
9352 doc
: /* t means that when the option-key is held down while pressing the
9353 mouse button, the click will register as mouse-2 and while the
9354 command-key is held down, the click will register as mouse-3.
9355 'reverse means that the the option-key will register for mouse-3
9356 and the command-key will register for mouse-2. nil means that
9357 not emulation should be done and the modifiers should be placed
9358 on the mouse-1 event. */);
9359 Vmac_emulate_three_button_mouse
= Qnil
;
9361 #if USE_CARBON_EVENTS
9362 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9363 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9364 the right click will be mouse-3.
9365 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9366 Vmac_wheel_button_is_mouse_2
= Qt
;
9368 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9369 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9370 Toolbox for processing before Emacs sees it. */);
9371 Vmac_pass_command_to_system
= Qt
;
9373 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9374 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9375 Toolbox for processing before Emacs sees it. */);
9376 Vmac_pass_control_to_system
= Qt
;
9379 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9380 doc
: /* One of the Text Encoding Base constant values defined in the
9381 Basic Text Constants section of Inside Macintosh - Text Encoding
9382 Conversion Manager. Its value determines the encoding characters
9383 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9384 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9385 its default value, no conversion takes place. If it is set to
9386 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9387 characters typed on Mac keyboard are first converted into the
9388 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9389 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9390 command, this enables the Mac keyboard to be used to enter non-ASCII
9391 characters directly. */);
9392 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9395 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9396 (do not change this comment) */