1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
38 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
39 obtain events from the event queue. If set to 0, WaitNextEvent is
41 #define USE_CARBON_EVENTS 1
42 #else /* not MAC_OSX */
43 #include <Quickdraw.h>
44 #include <ToolUtils.h>
48 #include <Resources.h>
50 #include <TextUtils.h>
54 #if defined (__MRC__) || (__MSL__ >= 0x6000)
55 #include <ControlDefinitions.h>
61 #endif /* not MAC_OSX */
75 #include "dispextern.h"
77 #include "termhooks.h"
84 #include "intervals.h"
85 #include "composite.h"
88 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
89 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
90 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
91 #define macShiftKey (shiftKey)
92 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
93 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
95 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
99 /* Non-nil means Emacs uses toolkit scroll bars. */
101 Lisp_Object Vx_toolkit_scroll_bars
;
103 /* Non-zero means that a HELP_EVENT has been generated since Emacs
106 static int any_help_event_p
;
108 /* Non-zero means autoselect window with the mouse cursor. */
110 int x_autoselect_window_p
;
112 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
114 int x_use_underline_position_properties
;
116 /* Non-zero means draw block and hollow cursor as wide as the glyph
117 under it. For example, if a block cursor is over a tab, it will be
118 drawn as wide as that tab on the display. */
121 /* This is a chain of structures for all the X displays currently in
124 struct x_display_info
*x_display_list
;
126 /* This is a list of cons cells, each of the form (NAME
127 . FONT-LIST-CACHE), one for each element of x_display_list and in
128 the same order. NAME is the name of the frame. FONT-LIST-CACHE
129 records previous values returned by x-list-fonts. */
131 Lisp_Object x_display_name_list
;
133 /* This is display since Mac does not support multiple ones. */
134 struct mac_display_info one_mac_display_info
;
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the XT functions.
138 It is zero while not inside an update. In that case, the XT
139 functions assume that `selected_frame' is the frame to apply to. */
141 extern struct frame
*updating_frame
;
143 extern int waiting_for_input
;
145 /* This is a frame waiting to be auto-raised, within XTread_socket. */
147 struct frame
*pending_autoraise_frame
;
149 /* Non-zero means user is interacting with a toolkit scroll bar. */
151 static int toolkit_scroll_bar_interaction
;
155 Formerly, we used PointerMotionHintMask (in standard_event_mask)
156 so that we would have to call XQueryPointer after each MotionNotify
157 event to ask for another such event. However, this made mouse tracking
158 slow, and there was a bug that made it eventually stop.
160 Simply asking for MotionNotify all the time seems to work better.
162 In order to avoid asking for motion events and then throwing most
163 of them away or busy-polling the server for mouse positions, we ask
164 the server for pointer motion hints. This means that we get only
165 one event per group of mouse movements. "Groups" are delimited by
166 other kinds of events (focus changes and button clicks, for
167 example), or by XQueryPointer calls; when one of these happens, we
168 get another MotionNotify event the next time the mouse moves. This
169 is at least as efficient as getting motion events when mouse
170 tracking is on, and I suspect only negligibly worse when tracking
173 /* Where the mouse was last time we reported a mouse event. */
175 static Rect last_mouse_glyph
;
176 static Lisp_Object last_mouse_press_frame
;
178 /* The scroll bar in which the last X motion event occurred.
180 If the last X motion event occurred in a scroll bar, we set this so
181 XTmouse_position can know whether to report a scroll bar motion or
184 If the last X motion event didn't occur in a scroll bar, we set
185 this to Qnil, to tell XTmouse_position to return an ordinary motion
188 static Lisp_Object last_mouse_scroll_bar
;
190 /* This is a hack. We would really prefer that XTmouse_position would
191 return the time associated with the position it returns, but there
192 doesn't seem to be any way to wrest the time-stamp from the server
193 along with the position query. So, we just keep track of the time
194 of the last movement we received, and return that in hopes that
195 it's somewhat accurate. */
197 static Time last_mouse_movement_time
;
199 struct scroll_bar
*tracked_scroll_bar
= NULL
;
201 /* Incremented by XTread_socket whenever it really tries to read
205 static int volatile input_signal_count
;
207 static int input_signal_count
;
210 /* Used locally within XTread_socket. */
212 static int x_noop_count
;
214 /* Initial values of argv and argc. */
216 extern char **initial_argv
;
217 extern int initial_argc
;
219 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
221 /* Tells if a window manager is present or not. */
223 extern Lisp_Object Vx_no_window_manager
;
227 /* A mask of extra modifier bits to put into every keyboard char. */
229 extern int extra_keyboard_modifiers
;
231 /* The keysyms to use for the various modifiers. */
233 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
235 static Lisp_Object Qvendor_specific_keysyms
;
238 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
241 extern int inhibit_window_system
;
244 QDGlobals qd
; /* QuickDraw global information structure. */
248 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
249 struct mac_display_info
*mac_display_info_for_display (Display
*);
250 static void x_update_window_end
P_ ((struct window
*, int, int));
251 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
252 static int x_io_error_quitter
P_ ((Display
*));
253 int x_catch_errors
P_ ((Display
*));
254 void x_uncatch_errors
P_ ((Display
*, int));
255 void x_lower_frame
P_ ((struct frame
*));
256 void x_scroll_bar_clear
P_ ((struct frame
*));
257 int x_had_errors_p
P_ ((Display
*));
258 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
259 void x_raise_frame
P_ ((struct frame
*));
260 void x_set_window_size
P_ ((struct frame
*, int, int, int));
261 void x_wm_set_window_state
P_ ((struct frame
*, int));
262 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
263 void mac_initialize
P_ ((void));
264 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
265 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
266 static void x_update_end
P_ ((struct frame
*));
267 static void XTframe_up_to_date
P_ ((struct frame
*));
268 static void XTreassert_line_highlight
P_ ((int, int));
269 static void x_change_line_highlight
P_ ((int, int, int, int));
270 static void XTset_terminal_modes
P_ ((void));
271 static void XTreset_terminal_modes
P_ ((void));
272 static void x_clear_frame
P_ ((void));
273 static void frame_highlight
P_ ((struct frame
*));
274 static void frame_unhighlight
P_ ((struct frame
*));
275 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
276 static void XTframe_rehighlight
P_ ((struct frame
*));
277 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
278 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
279 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
280 enum text_cursor_kinds
));
282 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
283 static void x_flush
P_ ((struct frame
*f
));
284 static void x_update_begin
P_ ((struct frame
*));
285 static void x_update_window_begin
P_ ((struct window
*));
286 static void x_after_update_window_line
P_ ((struct glyph_row
*));
288 void activate_scroll_bars (FRAME_PTR
);
289 void deactivate_scroll_bars (FRAME_PTR
);
291 static int is_emacs_window (WindowPtr
);
293 int x_bitmap_icon (struct frame
*, Lisp_Object
);
294 void x_make_frame_visible (struct frame
*);
296 extern void window_scroll (Lisp_Object
, int, int, int);
298 /* Defined in macmenu.h. */
299 extern void menubar_selection_callback (FRAME_PTR
, int);
300 extern void set_frame_menubar (FRAME_PTR
, int, int);
302 /* X display function emulation */
305 XFreePixmap (display
, pixmap
)
306 Display
*display
; /* not used */
309 DisposeGWorld (pixmap
);
313 /* Set foreground color for subsequent QuickDraw commands. Assume
314 graphic port has already been set. */
317 mac_set_forecolor (unsigned long color
)
321 fg_color
.red
= RED16_FROM_ULONG (color
);
322 fg_color
.green
= GREEN16_FROM_ULONG (color
);
323 fg_color
.blue
= BLUE16_FROM_ULONG (color
);
325 RGBForeColor (&fg_color
);
329 /* Set background color for subsequent QuickDraw commands. Assume
330 graphic port has already been set. */
333 mac_set_backcolor (unsigned long color
)
337 bg_color
.red
= RED16_FROM_ULONG (color
);
338 bg_color
.green
= GREEN16_FROM_ULONG (color
);
339 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
341 RGBBackColor (&bg_color
);
344 /* Set foreground and background color for subsequent QuickDraw
345 commands. Assume that the graphic port has already been set. */
348 mac_set_colors (GC gc
)
350 mac_set_forecolor (gc
->foreground
);
351 mac_set_backcolor (gc
->background
);
354 /* Mac version of XDrawLine. */
357 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
363 SetPortWindowPort (w
);
372 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
381 GetGWorld (&old_port
, &old_gdh
);
386 LockPixels (GetGWorldPixMap (p
));
389 UnlockPixels (GetGWorldPixMap (p
));
391 SetGWorld (old_port
, old_gdh
);
394 /* Mac version of XClearArea. */
397 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
401 unsigned int width
, height
;
404 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
408 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
409 xgc
.background
= mwp
->x_compatible
.background_pixel
;
411 SetPortWindowPort (w
);
413 mac_set_colors (&xgc
);
414 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
419 /* Mac version of XClearWindow. */
422 XClearWindow (display
, w
)
426 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
429 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
430 xgc
.background
= mwp
->x_compatible
.background_pixel
;
432 SetPortWindowPort (w
);
434 mac_set_colors (&xgc
);
436 #if TARGET_API_MAC_CARBON
440 GetWindowPortBounds (w
, &r
);
443 #else /* not TARGET_API_MAC_CARBON */
444 EraseRect (&(w
->portRect
));
445 #endif /* not TARGET_API_MAC_CARBON */
449 /* Mac replacement for XCopyArea. */
452 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
456 int x
, y
, width
, height
;
457 unsigned short *bits
;
463 bitmap
.rowBytes
= sizeof(unsigned short);
464 bitmap
.baseAddr
= (char *)bits
;
465 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
467 SetPortWindowPort (w
);
470 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
472 #if TARGET_API_MAC_CARBON
473 LockPortBits (GetWindowPort (w
));
474 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
475 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
476 UnlockPortBits (GetWindowPort (w
));
477 #else /* not TARGET_API_MAC_CARBON */
478 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
479 overlay_p
? srcOr
: srcCopy
, 0);
480 #endif /* not TARGET_API_MAC_CARBON */
484 /* Mac replacement for XSetClipRectangles. */
487 mac_set_clip_rectangle (display
, w
, r
)
492 SetPortWindowPort (w
);
498 /* Mac replacement for XSetClipMask. */
501 mac_reset_clipping (display
, w
)
507 SetPortWindowPort (w
);
509 SetRect (&r
, -32767, -32767, 32767, 32767);
514 /* XBM bits seem to be backward within bytes compared with how
521 unsigned char reflected
= 0x00;
522 for (i
= 0; i
< 8; i
++)
524 if (orig
& (0x01 << i
))
525 reflected
|= 0x80 >> i
;
531 /* Mac replacement for XCreateBitmapFromBitmapData. */
534 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
542 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
543 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
544 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
545 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
546 for (i
= 0; i
< h
; i
++)
548 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
549 for (j
= 0; j
< w1
; j
++)
550 *p
++ = reflect_byte (*bits
++);
553 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
558 mac_free_bitmap (bitmap
)
561 xfree (bitmap
->baseAddr
);
566 XCreatePixmap (display
, w
, width
, height
, depth
)
567 Display
*display
; /* not used */
569 unsigned int width
, height
;
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 */
646 #if 0 /* TODO: figure out if we need to do this on Mac. */
648 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
653 unsigned int width
, height
;
659 GetGWorld (&old_port
, &old_gdh
);
662 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
664 LockPixels (GetGWorldPixMap (p
));
665 PaintRect (&r
); /* using foreground color of gc */
666 UnlockPixels (GetGWorldPixMap (p
));
668 SetGWorld (old_port
, old_gdh
);
673 /* Mac replacement for XDrawRectangle: dest is a window. */
676 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
681 unsigned int width
, height
;
685 SetPortWindowPort (w
);
688 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
690 FrameRect (&r
); /* using foreground color of gc */
694 #if 0 /* TODO: figure out if we need to do this on Mac. */
695 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
698 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
703 unsigned int width
, height
;
709 GetGWorld (&old_port
, &old_gdh
);
712 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
714 LockPixels (GetGWorldPixMap (p
));
715 FrameRect (&r
); /* using foreground color of gc */
716 UnlockPixels (GetGWorldPixMap (p
));
718 SetGWorld (old_port
, old_gdh
);
724 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
731 int nchars
, mode
, bytes_per_char
;
733 SetPortWindowPort (w
);
737 TextFont (gc
->font
->mac_fontnum
);
738 TextSize (gc
->font
->mac_fontsize
);
739 TextFace (gc
->font
->mac_fontface
);
743 DrawText (buf
, 0, nchars
* bytes_per_char
);
747 /* Mac replacement for XDrawString. */
750 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
758 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
762 /* Mac replacement for XDrawString16. */
765 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
773 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
778 /* Mac replacement for XDrawImageString. */
781 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
789 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
793 /* Mac replacement for XDrawString16. */
796 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
804 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
809 /* Mac replacement for XCopyArea: dest must be window. */
812 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
819 unsigned int width
, height
;
824 SetPortWindowPort (dest
);
826 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
827 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
829 ForeColor (blackColor
);
830 BackColor (whiteColor
);
832 LockPixels (GetGWorldPixMap (src
));
833 #if TARGET_API_MAC_CARBON
834 LockPortBits (GetWindowPort (dest
));
835 CopyBits (GetPortBitMapForCopyBits (src
),
836 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
837 &src_r
, &dest_r
, srcCopy
, 0);
838 UnlockPortBits (GetWindowPort (dest
));
839 #else /* not TARGET_API_MAC_CARBON */
840 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
841 &src_r
, &dest_r
, srcCopy
, 0);
842 #endif /* not TARGET_API_MAC_CARBON */
843 UnlockPixels (GetGWorldPixMap (src
));
848 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
849 width
, height
, dest_x
, dest_y
)
855 unsigned int width
, height
;
860 SetPortWindowPort (dest
);
862 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
863 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
865 ForeColor (blackColor
);
866 BackColor (whiteColor
);
868 LockPixels (GetGWorldPixMap (src
));
869 LockPixels (GetGWorldPixMap (mask
));
870 #if TARGET_API_MAC_CARBON
871 LockPortBits (GetWindowPort (dest
));
872 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
873 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
874 &src_r
, &src_r
, &dest_r
);
875 UnlockPortBits (GetWindowPort (dest
));
876 #else /* not TARGET_API_MAC_CARBON */
877 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
878 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
879 #endif /* not TARGET_API_MAC_CARBON */
880 UnlockPixels (GetGWorldPixMap (mask
));
881 UnlockPixels (GetGWorldPixMap (src
));
886 /* Convert a pair of local coordinates to global (screen) coordinates.
887 Assume graphic port has been properly set. */
889 local_to_global_coord (short *h
, short *v
)
903 /* Mac replacement for XCopyArea: used only for scrolling. */
906 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
911 unsigned int width
, height
;
914 #if TARGET_API_MAC_CARBON
916 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
918 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
919 ScrollWindowRect (w
, &src_r
, dest_x
- src_x
, dest_y
- src_y
,
920 kScrollWindowNoOptions
, dummy
);
922 #else /* not TARGET_API_MAC_CARBON */
930 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
931 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
934 /* Need to use global coordinates and screenBits since src and dest
935 areas overlap in general. */
936 local_to_global_coord (&src_r
.left
, &src_r
.top
);
937 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
938 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
939 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
941 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
943 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
944 color mapping in CopyBits. Otherwise, it will be slow. */
945 ForeColor (blackColor
);
946 BackColor (whiteColor
);
947 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
951 #endif /* not TARGET_API_MAC_CARBON */
955 #if 0 /* TODO: figure out if we need to do this on Mac. */
956 /* Mac replacement for XCopyArea: dest must be Pixmap. */
959 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
965 unsigned int width
, height
;
972 GetGWorld (&old_port
, &old_gdh
);
973 SetGWorld (dest
, NULL
);
974 ForeColor (blackColor
);
975 BackColor (whiteColor
);
977 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
978 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
980 LockPixels (GetGWorldPixMap (src
));
981 LockPixels (GetGWorldPixMap (dest
));
982 #if TARGET_API_MAC_CARBON
983 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
984 &src_r
, &dest_r
, srcCopy
, 0);
985 #else /* not TARGET_API_MAC_CARBON */
986 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
987 &src_r
, &dest_r
, srcCopy
, 0);
988 #endif /* not TARGET_API_MAC_CARBON */
989 UnlockPixels (GetGWorldPixMap (dest
));
990 UnlockPixels (GetGWorldPixMap (src
));
992 SetGWorld (old_port
, old_gdh
);
997 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
998 width
, height
, dest_x
, dest_y
)
1000 Pixmap src
, mask
, dest
;
1003 unsigned int width
, height
;
1010 GetGWorld (&old_port
, &old_gdh
);
1011 SetGWorld (dest
, NULL
);
1012 ForeColor (blackColor
);
1013 BackColor (whiteColor
);
1015 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1016 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1018 LockPixels (GetGWorldPixMap (src
));
1019 LockPixels (GetGWorldPixMap (mask
));
1020 LockPixels (GetGWorldPixMap (dest
));
1021 #if TARGET_API_MAC_CARBON
1022 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1023 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1024 #else /* not TARGET_API_MAC_CARBON */
1025 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1026 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1027 #endif /* not TARGET_API_MAC_CARBON */
1028 UnlockPixels (GetGWorldPixMap (dest
));
1029 UnlockPixels (GetGWorldPixMap (mask
));
1030 UnlockPixels (GetGWorldPixMap (src
));
1032 SetGWorld (old_port
, old_gdh
);
1037 /* Mac replacement for XChangeGC. */
1040 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1043 if (mask
& GCForeground
)
1044 gc
->foreground
= xgcv
->foreground
;
1045 if (mask
& GCBackground
)
1046 gc
->background
= xgcv
->background
;
1048 gc
->font
= xgcv
->font
;
1052 /* Mac replacement for XCreateGC. */
1055 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1058 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1059 bzero (gc
, sizeof (XGCValues
));
1061 XChangeGC (ignore
, gc
, mask
, xgcv
);
1067 /* Used in xfaces.c. */
1070 XFreeGC (display
, gc
)
1078 /* Mac replacement for XGetGCValues. */
1081 XGetGCValues (void* ignore
, XGCValues
*gc
,
1082 unsigned long mask
, XGCValues
*xgcv
)
1084 XChangeGC (ignore
, xgcv
, mask
, gc
);
1088 /* Mac replacement for XSetForeground. */
1091 XSetForeground (display
, gc
, color
)
1094 unsigned long color
;
1096 gc
->foreground
= color
;
1100 /* Mac replacement for XSetFont. */
1103 XSetFont (display
, gc
, font
)
1113 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1114 int *direction
,int *font_ascent
,
1115 int *font_descent
, XCharStruct
*cs
)
1117 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1121 /* x_sync is a no-op on Mac. */
1129 /* Flush display of frame F, or of all frames if F is null. */
1135 #if TARGET_API_MAC_CARBON
1138 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1140 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1146 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1147 Calls to XFlush should be unnecessary because the X output buffer
1148 is flushed automatically as needed by calls to XPending,
1149 XNextEvent, or XWindowEvent according to the XFlush man page.
1150 XTread_socket calls XPending. Removing XFlush improves
1153 #define XFlush(DISPLAY) (void) 0
1156 /* Return the struct mac_display_info corresponding to DPY. There's
1159 struct mac_display_info
*
1160 mac_display_info_for_display (dpy
)
1163 return &one_mac_display_info
;
1168 /***********************************************************************
1169 Starting and ending an update
1170 ***********************************************************************/
1172 /* Start an update of frame F. This function is installed as a hook
1173 for update_begin, i.e. it is called when update_begin is called.
1174 This function is called prior to calls to x_update_window_begin for
1175 each window being updated. */
1181 /* Nothing to do. */
1185 /* Start update of window W. Set the global variable updated_window
1186 to the window being updated and set output_cursor to the cursor
1190 x_update_window_begin (w
)
1193 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1194 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1197 set_output_cursor (&w
->cursor
);
1201 if (f
== display_info
->mouse_face_mouse_frame
)
1203 /* Don't do highlighting for mouse motion during the update. */
1204 display_info
->mouse_face_defer
= 1;
1206 /* If F needs to be redrawn, simply forget about any prior mouse
1208 if (FRAME_GARBAGED_P (f
))
1209 display_info
->mouse_face_window
= Qnil
;
1211 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1212 their mouse_face_p flag set, which means that they are always
1213 unequal to rows in a desired matrix which never have that
1214 flag set. So, rows containing mouse-face glyphs are never
1215 scrolled, and we don't have to switch the mouse highlight off
1216 here to prevent it from being scrolled. */
1218 /* Can we tell that this update does not affect the window
1219 where the mouse highlight is? If so, no need to turn off.
1220 Likewise, don't do anything if the frame is garbaged;
1221 in that case, the frame's current matrix that we would use
1222 is all wrong, and we will redisplay that line anyway. */
1223 if (!NILP (display_info
->mouse_face_window
)
1224 && w
== XWINDOW (display_info
->mouse_face_window
))
1228 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1229 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1232 if (i
< w
->desired_matrix
->nrows
)
1233 clear_mouse_face (display_info
);
1242 /* Draw a vertical window border from (x,y0) to (x,y1) */
1245 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1249 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1251 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1252 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1256 /* End update of window W (which is equal to updated_window).
1258 Draw vertical borders between horizontally adjacent windows, and
1259 display W's cursor if CURSOR_ON_P is non-zero.
1261 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1262 glyphs in mouse-face were overwritten. In that case we have to
1263 make sure that the mouse-highlight is properly redrawn.
1265 W may be a menu bar pseudo-window in case we don't have X toolkit
1266 support. Such windows don't have a cursor, so don't display it
1270 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1272 int cursor_on_p
, mouse_face_overwritten_p
;
1274 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1276 if (!w
->pseudo_window_p
)
1281 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1283 output_cursor
.x
, output_cursor
.y
);
1285 if (draw_window_fringes (w
, 1))
1286 x_draw_vertical_border (w
);
1291 /* If a row with mouse-face was overwritten, arrange for
1292 XTframe_up_to_date to redisplay the mouse highlight. */
1293 if (mouse_face_overwritten_p
)
1295 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1296 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1297 dpyinfo
->mouse_face_window
= Qnil
;
1301 /* Unhide the caret. This won't actually show the cursor, unless it
1302 was visible before the corresponding call to HideCaret in
1303 x_update_window_begin. */
1304 if (w32_use_visible_system_caret
)
1305 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1308 updated_window
= NULL
;
1312 /* End update of frame F. This function is installed as a hook in
1319 /* Mouse highlight may be displayed again. */
1320 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1323 /* Reset the background color of Mac OS Window to that of the frame after
1324 update so that it is used by Mac Toolbox to clear the update region before
1325 an update event is generated. */
1326 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
1328 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1330 XFlush (FRAME_MAC_DISPLAY (f
));
1335 /* This function is called from various places in xdisp.c whenever a
1336 complete update has been performed. The global variable
1337 updated_window is not available here. */
1340 XTframe_up_to_date (f
)
1343 if (FRAME_MAC_P (f
))
1345 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1347 if (dpyinfo
->mouse_face_deferred_gc
1348 || f
== dpyinfo
->mouse_face_mouse_frame
)
1351 if (dpyinfo
->mouse_face_mouse_frame
)
1352 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1353 dpyinfo
->mouse_face_mouse_x
,
1354 dpyinfo
->mouse_face_mouse_y
);
1355 dpyinfo
->mouse_face_deferred_gc
= 0;
1362 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1363 arrow bitmaps, or clear the fringes if no bitmaps are required
1364 before DESIRED_ROW is made current. The window being updated is
1365 found in updated_window. This function is called from
1366 update_window_line only if it is known that there are differences
1367 between bitmaps to be drawn between current row and DESIRED_ROW. */
1370 x_after_update_window_line (desired_row
)
1371 struct glyph_row
*desired_row
;
1373 struct window
*w
= updated_window
;
1379 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1380 desired_row
->redraw_fringe_bitmaps_p
= 1;
1382 /* When a window has disappeared, make sure that no rest of
1383 full-width rows stays visible in the internal border. Could
1384 check here if updated_window is the leftmost/rightmost window,
1385 but I guess it's not worth doing since vertically split windows
1386 are almost never used, internal border is rarely set, and the
1387 overhead is very small. */
1388 if (windows_or_buffers_changed
1389 && desired_row
->full_width_p
1390 && (f
= XFRAME (w
->frame
),
1391 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1393 && (height
= desired_row
->visible_height
,
1396 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1397 /* Internal border is drawn below the tool bar. */
1398 if (WINDOWP (f
->tool_bar_window
)
1399 && w
== XWINDOW (f
->tool_bar_window
))
1404 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1405 0, y
, width
, height
, 0);
1406 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1407 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1415 /* Draw the bitmap WHICH in one of the left or right fringes of
1416 window W. ROW is the glyph row for which to display the bitmap; it
1417 determines the vertical position at which the bitmap has to be
1421 x_draw_fringe_bitmap (w
, row
, p
)
1423 struct glyph_row
*row
;
1424 struct draw_fringe_bitmap_params
*p
;
1426 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1427 Display
*display
= FRAME_MAC_DISPLAY (f
);
1428 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1430 GC gc
= f
->output_data
.mac
->normal_gc
;
1431 struct face
*face
= p
->face
;
1434 /* Must clip because of partially visible lines. */
1435 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1438 /* Adjust position of "bottom aligned" bitmap on partially
1439 visible last row. */
1441 int oldVH
= row
->visible_height
;
1442 row
->visible_height
= p
->h
;
1443 row
->y
-= rowY
- p
->y
;
1444 x_clip_to_row (w
, row
, -1, gc
);
1446 row
->visible_height
= oldVH
;
1449 x_clip_to_row (w
, row
, -1, gc
);
1451 if (p
->bx
>= 0 && !p
->overlay_p
)
1454 gcv
.foreground
= face
->background
;
1456 #if 0 /* MAC_TODO: stipple */
1457 /* In case the same realized face is used for fringes and
1458 for something displayed in the text (e.g. face `region' on
1459 mono-displays, the fill style may have been changed to
1460 FillSolid in x_draw_glyph_string_background. */
1462 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1464 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1467 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1469 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1471 #if 0 /* MAC_TODO: stipple */
1473 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1479 unsigned short *bits
= p
->bits
+ p
->dh
;
1481 gcv
.foreground
= (p
->cursor_p
1482 ? (p
->overlay_p
? face
->background
1483 : f
->output_data
.mac
->cursor_pixel
)
1484 : face
->foreground
);
1485 gcv
.background
= face
->background
;
1487 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1488 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1491 mac_reset_clipping (display
, window
);
1495 /* This is called when starting Emacs and when restarting after
1496 suspend. When starting Emacs, no window is mapped. And nothing
1497 must be done to Emacs's own window if it is suspended (though that
1501 XTset_terminal_modes ()
1505 /* This is called when exiting or suspending Emacs. Exiting will make
1506 the windows go away, and suspending requires no action. */
1509 XTreset_terminal_modes ()
1514 /***********************************************************************
1516 ***********************************************************************/
1518 /* Function prototypes of this page. */
1520 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1521 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1524 /* Return a pointer to per-char metric information in FONT of a
1525 character pointed by B which is a pointer to an XChar2b. */
1527 #define PER_CHAR_METRIC(font, b) \
1529 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1530 + (((font)->min_byte1 || (font)->max_byte1) \
1531 ? (((b)->byte1 - (font)->min_byte1) \
1532 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1534 : &((font)->max_bounds))
1537 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1538 is not contained in the font. */
1540 static INLINE XCharStruct
*
1541 x_per_char_metric (font
, char2b
)
1545 /* The result metric information. */
1546 XCharStruct
*pcm
= NULL
;
1548 xassert (font
&& char2b
);
1550 if (font
->per_char
!= NULL
)
1552 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1554 /* min_char_or_byte2 specifies the linear character index
1555 corresponding to the first element of the per_char array,
1556 max_char_or_byte2 is the index of the last character. A
1557 character with non-zero CHAR2B->byte1 is not in the font.
1558 A character with byte2 less than min_char_or_byte2 or
1559 greater max_char_or_byte2 is not in the font. */
1560 if (char2b
->byte1
== 0
1561 && char2b
->byte2
>= font
->min_char_or_byte2
1562 && char2b
->byte2
<= font
->max_char_or_byte2
)
1563 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1567 /* If either min_byte1 or max_byte1 are nonzero, both
1568 min_char_or_byte2 and max_char_or_byte2 are less than
1569 256, and the 2-byte character index values corresponding
1570 to the per_char array element N (counting from 0) are:
1572 byte1 = N/D + min_byte1
1573 byte2 = N\D + min_char_or_byte2
1577 D = max_char_or_byte2 - min_char_or_byte2 + 1
1578 / = integer division
1579 \ = integer modulus */
1580 if (char2b
->byte1
>= font
->min_byte1
1581 && char2b
->byte1
<= font
->max_byte1
1582 && char2b
->byte2
>= font
->min_char_or_byte2
1583 && char2b
->byte2
<= font
->max_char_or_byte2
)
1585 pcm
= (font
->per_char
1586 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1587 * (char2b
->byte1
- font
->min_byte1
))
1588 + (char2b
->byte2
- font
->min_char_or_byte2
));
1594 /* If the per_char pointer is null, all glyphs between the first
1595 and last character indexes inclusive have the same
1596 information, as given by both min_bounds and max_bounds. */
1597 if (char2b
->byte2
>= font
->min_char_or_byte2
1598 && char2b
->byte2
<= font
->max_char_or_byte2
)
1599 pcm
= &font
->max_bounds
;
1602 return ((pcm
== NULL
1603 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1610 static XCharStruct
*
1611 mac_per_char_metric (font
, char2b
, font_type
)
1616 return x_per_char_metric (font
, char2b
);
1620 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1621 the two-byte form of C. Encoding is returned in *CHAR2B. */
1624 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1627 struct font_info
*font_info
;
1630 int charset
= CHAR_CHARSET (c
);
1631 XFontStruct
*font
= font_info
->font
;
1633 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1634 This may be either a program in a special encoder language or a
1636 if (font_info
->font_encoder
)
1638 /* It's a program. */
1639 struct ccl_program
*ccl
= font_info
->font_encoder
;
1641 if (CHARSET_DIMENSION (charset
) == 1)
1643 ccl
->reg
[0] = charset
;
1644 ccl
->reg
[1] = char2b
->byte2
;
1648 ccl
->reg
[0] = charset
;
1649 ccl
->reg
[1] = char2b
->byte1
;
1650 ccl
->reg
[2] = char2b
->byte2
;
1653 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1655 /* We assume that MSBs are appropriately set/reset by CCL
1657 if (font
->max_byte1
== 0) /* 1-byte font */
1658 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1660 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1662 else if (font_info
->encoding
[charset
])
1664 /* Fixed encoding scheme. See fontset.h for the meaning of the
1665 encoding numbers. */
1666 int enc
= font_info
->encoding
[charset
];
1668 if ((enc
== 1 || enc
== 2)
1669 && CHARSET_DIMENSION (charset
) == 2)
1670 char2b
->byte1
|= 0x80;
1672 if (enc
== 1 || enc
== 3)
1673 char2b
->byte2
|= 0x80;
1679 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1680 char2b
->byte1
= sjis1
;
1681 char2b
->byte2
= sjis2
;
1686 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1688 return FONT_TYPE_UNKNOWN
;
1693 /***********************************************************************
1695 ***********************************************************************/
1698 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1699 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1700 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1702 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1703 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1704 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1705 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1706 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1707 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1708 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1709 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1710 unsigned long *, double, int));*/
1711 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1712 double, int, unsigned long));
1713 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1714 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1715 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1716 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1717 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1718 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1720 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1721 int, int, int, int, int, int,
1723 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1724 int, int, int, Rect
*));
1727 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1731 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1736 struct glyph_string
*s
;
1738 if (s
->font
== FRAME_FONT (s
->f
)
1739 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1740 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1742 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1745 /* Cursor on non-default face: must merge. */
1749 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1750 xgcv
.foreground
= s
->face
->background
;
1752 /* If the glyph would be invisible, try a different foreground. */
1753 if (xgcv
.foreground
== xgcv
.background
)
1754 xgcv
.foreground
= s
->face
->foreground
;
1755 if (xgcv
.foreground
== xgcv
.background
)
1756 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1757 if (xgcv
.foreground
== xgcv
.background
)
1758 xgcv
.foreground
= s
->face
->foreground
;
1760 /* Make sure the cursor is distinct from text in this face. */
1761 if (xgcv
.background
== s
->face
->background
1762 && xgcv
.foreground
== s
->face
->foreground
)
1764 xgcv
.background
= s
->face
->foreground
;
1765 xgcv
.foreground
= s
->face
->background
;
1768 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1769 xgcv
.font
= s
->font
;
1770 mask
= GCForeground
| GCBackground
| GCFont
;
1772 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1773 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1776 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1777 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1779 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1784 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1787 x_set_mouse_face_gc (s
)
1788 struct glyph_string
*s
;
1793 /* What face has to be used last for the mouse face? */
1794 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1795 face
= FACE_FROM_ID (s
->f
, face_id
);
1797 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1799 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1800 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1802 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1803 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1804 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1806 /* If font in this face is same as S->font, use it. */
1807 if (s
->font
== s
->face
->font
)
1808 s
->gc
= s
->face
->gc
;
1811 /* Otherwise construct scratch_cursor_gc with values from FACE
1816 xgcv
.background
= s
->face
->background
;
1817 xgcv
.foreground
= s
->face
->foreground
;
1818 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1819 xgcv
.font
= s
->font
;
1820 mask
= GCForeground
| GCBackground
| GCFont
;
1822 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1823 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1826 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1827 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1829 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1832 xassert (s
->gc
!= 0);
1836 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1837 Faces to use in the mode line have already been computed when the
1838 matrix was built, so there isn't much to do, here. */
1841 x_set_mode_line_face_gc (s
)
1842 struct glyph_string
*s
;
1844 s
->gc
= s
->face
->gc
;
1848 /* Set S->gc of glyph string S for drawing that glyph string. Set
1849 S->stippled_p to a non-zero value if the face of S has a stipple
1853 x_set_glyph_string_gc (s
)
1854 struct glyph_string
*s
;
1856 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1858 if (s
->hl
== DRAW_NORMAL_TEXT
)
1860 s
->gc
= s
->face
->gc
;
1861 s
->stippled_p
= s
->face
->stipple
!= 0;
1863 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1865 x_set_mode_line_face_gc (s
);
1866 s
->stippled_p
= s
->face
->stipple
!= 0;
1868 else if (s
->hl
== DRAW_CURSOR
)
1870 x_set_cursor_gc (s
);
1873 else if (s
->hl
== DRAW_MOUSE_FACE
)
1875 x_set_mouse_face_gc (s
);
1876 s
->stippled_p
= s
->face
->stipple
!= 0;
1878 else if (s
->hl
== DRAW_IMAGE_RAISED
1879 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1881 s
->gc
= s
->face
->gc
;
1882 s
->stippled_p
= s
->face
->stipple
!= 0;
1886 s
->gc
= s
->face
->gc
;
1887 s
->stippled_p
= s
->face
->stipple
!= 0;
1890 /* GC must have been set. */
1891 xassert (s
->gc
!= 0);
1895 /* Set clipping for output of glyph string S. S may be part of a mode
1896 line or menu if we don't have X toolkit support. */
1899 x_set_glyph_string_clipping (s
)
1900 struct glyph_string
*s
;
1903 get_glyph_string_clip_rect (s
, &r
);
1904 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1909 Compute left and right overhang of glyph string S. If S is a glyph
1910 string for a composition, assume overhangs don't exist. */
1913 mac_compute_glyph_string_overhangs (s
)
1914 struct glyph_string
*s
;
1917 /* MAC_TODO: XTextExtents16 does nothing yet... */
1920 && s
->first_glyph
->type
== CHAR_GLYPH
)
1923 int direction
, font_ascent
, font_descent
;
1924 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1925 &font_ascent
, &font_descent
, &cs
);
1926 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1927 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1933 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1936 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1937 struct glyph_string
*s
;
1942 xgcv
.foreground
= s
->gc
->background
;
1943 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1947 /* We prefer not to use XDrawImageString (srcCopy text transfer mode)
1948 on Mac OS X because:
1949 - Screen is double-buffered. (In srcCopy mode, a text is drawn
1950 into an offscreen graphics world first. So performance gain
1951 cannot be expected.)
1952 - It lowers rendering quality.
1953 - Some fonts leave garbage on cursor movement. */
1955 /* Draw the background of glyph_string S. If S->background_filled_p
1956 is non-zero don't draw it. FORCE_P non-zero means draw the
1957 background even if it wouldn't be drawn normally. This is used
1958 when a string preceding S draws into the background of S, or S
1959 contains the first component of a composition. */
1962 x_draw_glyph_string_background (s
, force_p
)
1963 struct glyph_string
*s
;
1966 /* Nothing to do if background has already been drawn or if it
1967 shouldn't be drawn in the first place. */
1968 if (!s
->background_filled_p
)
1970 int box_line_width
= max (s
->face
->box_line_width
, 0);
1972 #if 0 /* MAC_TODO: stipple */
1975 /* Fill background with a stipple pattern. */
1976 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1977 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1978 s
->y
+ box_line_width
,
1979 s
->background_width
,
1980 s
->height
- 2 * box_line_width
);
1981 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1982 s
->background_filled_p
= 1;
1986 #if 0 /* defined(MAC_OS8)*/
1987 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1988 || s
->font_not_found_p
1989 || s
->extends_to_end_of_line_p
1993 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1994 s
->background_width
,
1995 s
->height
- 2 * box_line_width
);
1996 s
->background_filled_p
= 1;
2002 /* Draw the foreground of glyph string S. */
2005 x_draw_glyph_string_foreground (s
)
2006 struct glyph_string
*s
;
2010 /* If first glyph of S has a left box line, start drawing the text
2011 of S to the right of that box line. */
2012 if (s
->face
->box
!= FACE_NO_BOX
2013 && s
->first_glyph
->left_box_line_p
)
2014 x
= s
->x
+ abs (s
->face
->box_line_width
);
2018 /* Draw characters of S as rectangles if S's font could not be
2020 if (s
->font_not_found_p
)
2022 for (i
= 0; i
< s
->nchars
; ++i
)
2024 struct glyph
*g
= s
->first_glyph
+ i
;
2025 mac_draw_rectangle (s
->display
, s
->window
,
2026 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2028 x
+= g
->pixel_width
;
2033 char *char1b
= (char *) s
->char2b
;
2034 int boff
= s
->font_info
->baseline_offset
;
2036 if (s
->font_info
->vertical_centering
)
2037 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2039 /* If we can use 8-bit functions, condense S->char2b. */
2041 for (i
= 0; i
< s
->nchars
; ++i
)
2042 char1b
[i
] = s
->char2b
[i
].byte2
;
2044 #if 0 /* defined(MAC_OS8) */
2045 /* Draw text with XDrawString if background has already been
2046 filled. Otherwise, use XDrawImageString. (Note that
2047 XDrawImageString is usually faster than XDrawString.) Always
2048 use XDrawImageString when drawing the cursor so that there is
2049 no chance that characters under a box cursor are invisible. */
2050 if (s
->for_overlaps_p
2051 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2054 /* Draw characters with 16-bit or 8-bit functions. */
2056 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2057 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2059 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2060 s
->ybase
- boff
, char1b
, s
->nchars
);
2062 #if 0 /* defined(MAC_OS8)*/
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
);
2076 /* Draw the foreground of composite glyph string S. */
2079 x_draw_composite_glyph_string_foreground (s
)
2080 struct glyph_string
*s
;
2084 /* If first glyph of S has a left box line, start drawing the text
2085 of S to the right of that box line. */
2086 if (s
->face
->box
!= FACE_NO_BOX
2087 && s
->first_glyph
->left_box_line_p
)
2088 x
= s
->x
+ abs (s
->face
->box_line_width
);
2092 /* S is a glyph string for a composition. S->gidx is the index of
2093 the first character drawn for glyphs of this composition.
2094 S->gidx == 0 means we are drawing the very first character of
2095 this composition. */
2097 /* Draw a rectangle for the composition if the font for the very
2098 first character of the composition could not be loaded. */
2099 if (s
->font_not_found_p
)
2102 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2103 s
->width
- 1, s
->height
- 1);
2107 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2108 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2109 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2110 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2116 #ifdef USE_X_TOOLKIT
2118 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2121 /* Return the frame on which widget WIDGET is used.. Abort if frame
2122 cannot be determined. */
2124 static struct frame
*
2125 x_frame_of_widget (widget
)
2128 struct x_display_info
*dpyinfo
;
2132 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2134 /* Find the top-level shell of the widget. Note that this function
2135 can be called when the widget is not yet realized, so XtWindow
2136 (widget) == 0. That's the reason we can't simply use
2137 x_any_window_to_frame. */
2138 while (!XtIsTopLevelShell (widget
))
2139 widget
= XtParent (widget
);
2141 /* Look for a frame with that top-level widget. Allocate the color
2142 on that frame to get the right gamma correction value. */
2143 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2144 if (GC_FRAMEP (XCAR (tail
))
2145 && (f
= XFRAME (XCAR (tail
)),
2146 (f
->output_data
.nothing
!= 1
2147 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2148 && f
->output_data
.x
->widget
== widget
)
2155 /* Allocate the color COLOR->pixel on the screen and display of
2156 widget WIDGET in colormap CMAP. If an exact match cannot be
2157 allocated, try the nearest color available. Value is non-zero
2158 if successful. This is called from lwlib. */
2161 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2166 struct frame
*f
= x_frame_of_widget (widget
);
2167 return x_alloc_nearest_color (f
, cmap
, color
);
2171 #endif /* USE_X_TOOLKIT */
2173 #if 0 /* MAC_TODO */
2175 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2176 CMAP. If an exact match can't be allocated, try the nearest color
2177 available. Value is non-zero if successful. Set *COLOR to the
2181 x_alloc_nearest_color (f
, cmap
, color
)
2186 Display
*display
= FRAME_X_DISPLAY (f
);
2187 Screen
*screen
= FRAME_X_SCREEN (f
);
2190 gamma_correct (f
, color
);
2191 rc
= XAllocColor (display
, cmap
, color
);
2194 /* If we got to this point, the colormap is full, so we're going
2195 to try to get the next closest color. The algorithm used is
2196 a least-squares matching, which is what X uses for closest
2197 color matching with StaticColor visuals. */
2199 unsigned long nearest_delta
= ~0;
2200 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2201 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2203 for (i
= 0; i
< ncells
; ++i
)
2205 XQueryColors (display
, cmap
, cells
, ncells
);
2207 for (nearest
= i
= 0; i
< ncells
; ++i
)
2209 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2210 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2211 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2212 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2214 if (delta
< nearest_delta
)
2217 nearest_delta
= delta
;
2221 color
->red
= cells
[nearest
].red
;
2222 color
->green
= cells
[nearest
].green
;
2223 color
->blue
= cells
[nearest
].blue
;
2224 rc
= XAllocColor (display
, cmap
, color
);
2227 #ifdef DEBUG_X_COLORS
2229 register_color (color
->pixel
);
2230 #endif /* DEBUG_X_COLORS */
2236 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2237 It's necessary to do this instead of just using PIXEL directly to
2238 get color reference counts right. */
2241 x_copy_color (f
, pixel
)
2243 unsigned long pixel
;
2247 color
.pixel
= pixel
;
2249 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2250 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2252 #ifdef DEBUG_X_COLORS
2253 register_color (pixel
);
2259 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2260 It's necessary to do this instead of just using PIXEL directly to
2261 get color reference counts right. */
2264 x_copy_dpy_color (dpy
, cmap
, pixel
)
2267 unsigned long pixel
;
2271 color
.pixel
= pixel
;
2273 XQueryColor (dpy
, cmap
, &color
);
2274 XAllocColor (dpy
, cmap
, &color
);
2276 #ifdef DEBUG_X_COLORS
2277 register_color (pixel
);
2282 #endif /* MAC_TODO */
2285 /* Brightness beyond which a color won't have its highlight brightness
2288 Nominally, highlight colors for `3d' faces are calculated by
2289 brightening an object's color by a constant scale factor, but this
2290 doesn't yield good results for dark colors, so for colors who's
2291 brightness is less than this value (on a scale of 0-255) have to
2292 use an additional additive factor.
2294 The value here is set so that the default menu-bar/mode-line color
2295 (grey75) will not have its highlights changed at all. */
2296 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2299 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2300 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2301 If this produces the same color as COLOR, try a color where all RGB
2302 values have DELTA added. Return the allocated color in *COLOR.
2303 DISPLAY is the X display, CMAP is the colormap to operate on.
2304 Value is non-zero if successful. */
2307 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2309 unsigned long *color
;
2316 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2319 /* Change RGB values by specified FACTOR. Avoid overflow! */
2320 xassert (factor
>= 0);
2321 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2322 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2323 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2325 /* Calculate brightness of COLOR. */
2326 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2327 + BLUE_FROM_ULONG (*color
)) / 6;
2329 /* We only boost colors that are darker than
2330 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2331 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2332 /* Make an additive adjustment to NEW, because it's dark enough so
2333 that scaling by FACTOR alone isn't enough. */
2335 /* How far below the limit this color is (0 - 1, 1 being darker). */
2336 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2337 /* The additive adjustment. */
2338 int min_delta
= delta
* dimness
* factor
/ 2;
2341 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2342 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2343 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2345 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2346 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2347 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2351 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2352 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2353 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2355 /* MAC_TODO: Map to palette and retry with delta if same? */
2356 /* MAC_TODO: Free colors (if using palette)? */
2367 /* Set up the foreground color for drawing relief lines of glyph
2368 string S. RELIEF is a pointer to a struct relief containing the GC
2369 with which lines will be drawn. Use a color that is FACTOR or
2370 DELTA lighter or darker than the relief's background which is found
2371 in S->f->output_data.x->relief_background. If such a color cannot
2372 be allocated, use DEFAULT_PIXEL, instead. */
2375 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2377 struct relief
*relief
;
2380 unsigned long default_pixel
;
2383 struct mac_output
*di
= f
->output_data
.mac
;
2384 unsigned long mask
= GCForeground
;
2385 unsigned long pixel
;
2386 unsigned long background
= di
->relief_background
;
2387 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2389 /* MAC_TODO: Free colors (if using palette)? */
2391 /* Allocate new color. */
2392 xgcv
.foreground
= default_pixel
;
2394 if (dpyinfo
->n_planes
!= 1
2395 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2397 relief
->allocated_p
= 1;
2398 xgcv
.foreground
= relief
->pixel
= pixel
;
2401 if (relief
->gc
== 0)
2403 #if 0 /* MAC_TODO: stipple */
2404 xgcv
.stipple
= dpyinfo
->gray
;
2407 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2410 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2414 /* Set up colors for the relief lines around glyph string S. */
2417 x_setup_relief_colors (s
)
2418 struct glyph_string
*s
;
2420 struct mac_output
*di
= s
->f
->output_data
.mac
;
2421 unsigned long color
;
2423 if (s
->face
->use_box_color_for_shadows_p
)
2424 color
= s
->face
->box_color
;
2425 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2427 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2428 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2433 /* Get the background color of the face. */
2434 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2435 color
= xgcv
.background
;
2438 if (di
->white_relief
.gc
== 0
2439 || color
!= di
->relief_background
)
2441 di
->relief_background
= color
;
2442 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2443 WHITE_PIX_DEFAULT (s
->f
));
2444 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2445 BLACK_PIX_DEFAULT (s
->f
));
2450 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2451 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2452 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2453 relief. LEFT_P non-zero means draw a relief on the left side of
2454 the rectangle. RIGHT_P non-zero means draw a relief on the right
2455 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2459 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2460 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2462 int left_x
, top_y
, right_x
, bottom_y
, width
;
2463 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2466 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2467 Window window
= FRAME_MAC_WINDOW (f
);
2472 gc
= f
->output_data
.mac
->white_relief
.gc
;
2474 gc
= f
->output_data
.mac
->black_relief
.gc
;
2475 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2479 for (i
= 0; i
< width
; ++i
)
2480 XDrawLine (dpy
, window
, gc
,
2481 left_x
+ i
* left_p
, top_y
+ i
,
2482 right_x
- i
* right_p
, top_y
+ i
);
2486 for (i
= 0; i
< width
; ++i
)
2487 XDrawLine (dpy
, window
, gc
,
2488 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2490 mac_reset_clipping (dpy
, window
);
2492 gc
= f
->output_data
.mac
->black_relief
.gc
;
2494 gc
= f
->output_data
.mac
->white_relief
.gc
;
2495 mac_set_clip_rectangle (dpy
, window
,
2500 for (i
= 0; i
< width
; ++i
)
2501 XDrawLine (dpy
, window
, gc
,
2502 left_x
+ i
* left_p
, bottom_y
- i
,
2503 right_x
- i
* right_p
, bottom_y
- i
);
2507 for (i
= 0; i
< width
; ++i
)
2508 XDrawLine (dpy
, window
, gc
,
2509 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2511 mac_reset_clipping (dpy
, window
);
2515 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2516 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2517 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2518 left side of the rectangle. RIGHT_P non-zero means draw a line
2519 on the right side of the rectangle. CLIP_RECT is the clipping
2520 rectangle to use when drawing. */
2523 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2524 left_p
, right_p
, clip_rect
)
2525 struct glyph_string
*s
;
2526 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2531 xgcv
.foreground
= s
->face
->box_color
;
2532 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2535 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2536 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2540 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2541 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2544 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2545 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2549 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2550 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2552 mac_reset_clipping (s
->display
, s
->window
);
2556 /* Draw a box around glyph string S. */
2559 x_draw_glyph_string_box (s
)
2560 struct glyph_string
*s
;
2562 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2563 int left_p
, right_p
;
2564 struct glyph
*last_glyph
;
2567 last_x
= window_box_right (s
->w
, s
->area
);
2568 if (s
->row
->full_width_p
2569 && !s
->w
->pseudo_window_p
)
2571 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2572 if (s
->area
!= RIGHT_MARGIN_AREA
2573 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2574 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2577 /* The glyph that may have a right box line. */
2578 last_glyph
= (s
->cmp
|| s
->img
2580 : s
->first_glyph
+ s
->nchars
- 1);
2582 width
= abs (s
->face
->box_line_width
);
2583 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2585 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2587 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2589 bottom_y
= top_y
+ s
->height
- 1;
2591 left_p
= (s
->first_glyph
->left_box_line_p
2592 || (s
->hl
== DRAW_MOUSE_FACE
2594 || s
->prev
->hl
!= s
->hl
)));
2595 right_p
= (last_glyph
->right_box_line_p
2596 || (s
->hl
== DRAW_MOUSE_FACE
2598 || s
->next
->hl
!= s
->hl
)));
2600 get_glyph_string_clip_rect (s
, &clip_rect
);
2602 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2603 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2604 left_p
, right_p
, &clip_rect
);
2607 x_setup_relief_colors (s
);
2608 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2609 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2614 /* Draw foreground of image glyph string S. */
2617 x_draw_image_foreground (s
)
2618 struct glyph_string
*s
;
2621 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2623 /* If first glyph of S has a left box line, start drawing it to the
2624 right of that line. */
2625 if (s
->face
->box
!= FACE_NO_BOX
2626 && s
->first_glyph
->left_box_line_p
2628 x
+= abs (s
->face
->box_line_width
);
2630 /* If there is a margin around the image, adjust x- and y-position
2632 if (s
->slice
.x
== 0)
2633 x
+= s
->img
->hmargin
;
2634 if (s
->slice
.y
== 0)
2635 y
+= s
->img
->vmargin
;
2639 x_set_glyph_string_clipping (s
);
2642 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2643 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2644 s
->slice
.width
, s
->slice
.height
, x
, y
);
2647 mac_copy_area (s
->display
, s
->img
->pixmap
,
2648 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2649 s
->slice
.width
, s
->slice
.height
, x
, y
);
2651 /* When the image has a mask, we can expect that at
2652 least part of a mouse highlight or a block cursor will
2653 be visible. If the image doesn't have a mask, make
2654 a block cursor visible by drawing a rectangle around
2655 the image. I believe it's looking better if we do
2656 nothing here for mouse-face. */
2657 if (s
->hl
== DRAW_CURSOR
)
2659 int r
= s
->img
->relief
;
2661 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2663 s
->slice
.width
+ r
*2 - 1,
2664 s
->slice
.height
+ r
*2 - 1);
2669 /* Draw a rectangle if image could not be loaded. */
2670 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2671 s
->slice
.width
- 1, s
->slice
.height
- 1);
2675 /* Draw a relief around the image glyph string S. */
2678 x_draw_image_relief (s
)
2679 struct glyph_string
*s
;
2681 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2684 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2686 /* If first glyph of S has a left box line, start drawing it to the
2687 right of that line. */
2688 if (s
->face
->box
!= FACE_NO_BOX
2689 && s
->first_glyph
->left_box_line_p
2691 x
+= abs (s
->face
->box_line_width
);
2693 /* If there is a margin around the image, adjust x- and y-position
2695 if (s
->slice
.x
== 0)
2696 x
+= s
->img
->hmargin
;
2697 if (s
->slice
.y
== 0)
2698 y
+= s
->img
->vmargin
;
2700 if (s
->hl
== DRAW_IMAGE_SUNKEN
2701 || s
->hl
== DRAW_IMAGE_RAISED
)
2703 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2704 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2708 thick
= abs (s
->img
->relief
);
2709 raised_p
= s
->img
->relief
> 0;
2714 x1
= x
+ s
->slice
.width
+ thick
- 1;
2715 y1
= y
+ s
->slice
.height
+ thick
- 1;
2717 x_setup_relief_colors (s
);
2718 get_glyph_string_clip_rect (s
, &r
);
2719 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2721 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2723 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2728 #if 0 /* TODO: figure out if we need to do this on Mac. */
2729 /* Draw the foreground of image glyph string S to PIXMAP. */
2732 x_draw_image_foreground_1 (s
, pixmap
)
2733 struct glyph_string
*s
;
2737 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2739 /* If first glyph of S has a left box line, start drawing it to the
2740 right of that line. */
2741 if (s
->face
->box
!= FACE_NO_BOX
2742 && s
->first_glyph
->left_box_line_p
2744 x
+= abs (s
->face
->box_line_width
);
2746 /* If there is a margin around the image, adjust x- and y-position
2748 if (s
->slice
.x
== 0)
2749 x
+= s
->img
->hmargin
;
2750 if (s
->slice
.y
== 0)
2751 y
+= s
->img
->vmargin
;
2756 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2757 s
->img
->mask
, pixmap
, s
->gc
,
2758 s
->slice
.x
, s
->slice
.y
,
2759 s
->slice
.width
, s
->slice
.height
,
2763 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2764 s
->slice
.x
, s
->slice
.y
,
2765 s
->slice
.width
, s
->slice
.height
,
2768 /* When the image has a mask, we can expect that at
2769 least part of a mouse highlight or a block cursor will
2770 be visible. If the image doesn't have a mask, make
2771 a block cursor visible by drawing a rectangle around
2772 the image. I believe it's looking better if we do
2773 nothing here for mouse-face. */
2774 if (s
->hl
== DRAW_CURSOR
)
2776 int r
= s
->img
->relief
;
2778 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2779 s
->slice
.width
+ r
*2 - 1,
2780 s
->slice
.height
+ r
*2 - 1);
2785 /* Draw a rectangle if image could not be loaded. */
2786 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2787 s
->slice
.width
- 1, s
->slice
.height
- 1);
2792 /* Draw part of the background of glyph string S. X, Y, W, and H
2793 give the rectangle to draw. */
2796 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2797 struct glyph_string
*s
;
2800 #if 0 /* MAC_TODO: stipple */
2803 /* Fill background with a stipple pattern. */
2804 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2805 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2806 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2809 #endif /* MAC_TODO */
2810 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2814 /* Draw image glyph string S.
2817 s->x +-------------------------
2820 | +-------------------------
2823 | | +-------------------
2829 x_draw_image_glyph_string (s
)
2830 struct glyph_string
*s
;
2833 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2834 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2838 height
= s
->height
- 2 * box_line_vwidth
;
2841 /* Fill background with face under the image. Do it only if row is
2842 taller than image or if image has a clip mask to reduce
2844 s
->stippled_p
= s
->face
->stipple
!= 0;
2845 if (height
> s
->slice
.height
2849 || s
->img
->pixmap
== 0
2850 || s
->width
!= s
->background_width
)
2853 if (s
->first_glyph
->left_box_line_p
2855 x
+= box_line_hwidth
;
2858 if (s
->slice
.y
== 0)
2859 y
+= box_line_vwidth
;
2861 #if 0 /* TODO: figure out if we need to do this on Mac. */
2864 /* Create a pixmap as large as the glyph string. Fill it
2865 with the background color. Copy the image to it, using
2866 its mask. Copy the temporary pixmap to the display. */
2867 int depth
= one_mac_display_info
.n_planes
;
2869 /* Create a pixmap as large as the glyph string. */
2870 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2871 s
->background_width
,
2874 /* Fill the pixmap with the background color/stipple. */
2875 #if 0 /* TODO: stipple */
2878 /* Fill background with a stipple pattern. */
2879 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2880 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2881 0, 0, s
->background_width
, s
->height
);
2882 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2888 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2890 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2891 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2892 0, 0, s
->background_width
,
2894 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2899 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2901 s
->background_filled_p
= 1;
2904 /* Draw the foreground. */
2905 #if 0 /* TODO: figure out if we need to do this on Mac. */
2908 x_draw_image_foreground_1 (s
, pixmap
);
2909 x_set_glyph_string_clipping (s
);
2910 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2911 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2912 mac_reset_clipping (s
->display
, s
->window
);
2913 XFreePixmap (s
->display
, pixmap
);
2917 x_draw_image_foreground (s
);
2919 /* If we must draw a relief around the image, do it. */
2921 || s
->hl
== DRAW_IMAGE_RAISED
2922 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2923 x_draw_image_relief (s
);
2927 /* Draw stretch glyph string S. */
2930 x_draw_stretch_glyph_string (s
)
2931 struct glyph_string
*s
;
2933 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2934 s
->stippled_p
= s
->face
->stipple
!= 0;
2936 if (s
->hl
== DRAW_CURSOR
2937 && !x_stretch_cursor_p
)
2939 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2940 as wide as the stretch glyph. */
2941 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2944 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2946 /* Clear rest using the GC of the original non-cursor face. */
2947 if (width
< s
->background_width
)
2949 int x
= s
->x
+ width
, y
= s
->y
;
2950 int w
= s
->background_width
- width
, h
= s
->height
;
2954 if (s
->row
->mouse_face_p
2955 && cursor_in_mouse_face_p (s
->w
))
2957 x_set_mouse_face_gc (s
);
2963 get_glyph_string_clip_rect (s
, &r
);
2964 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2966 #if 0 /* MAC_TODO: stipple */
2967 if (s
->face
->stipple
)
2969 /* Fill background with a stipple pattern. */
2970 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2971 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2972 XSetFillStyle (s
->display
, gc
, FillSolid
);
2975 #endif /* MAC_TODO */
2978 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
2979 XSetForeground (s
->display
, gc
, xgcv
.background
);
2980 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2981 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
2984 mac_reset_clipping (s
->display
, s
->window
);
2987 else if (!s
->background_filled_p
)
2988 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2991 s
->background_filled_p
= 1;
2995 /* Draw glyph string S. */
2998 x_draw_glyph_string (s
)
2999 struct glyph_string
*s
;
3001 int relief_drawn_p
= 0;
3003 /* If S draws into the background of its successor, draw the
3004 background of the successor first so that S can draw into it.
3005 This makes S->next use XDrawString instead of XDrawImageString. */
3006 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3008 xassert (s
->next
->img
== NULL
);
3009 x_set_glyph_string_gc (s
->next
);
3010 x_set_glyph_string_clipping (s
->next
);
3011 x_draw_glyph_string_background (s
->next
, 1);
3014 /* Set up S->gc, set clipping and draw S. */
3015 x_set_glyph_string_gc (s
);
3017 /* Draw relief (if any) in advance for char/composition so that the
3018 glyph string can be drawn over it. */
3019 if (!s
->for_overlaps_p
3020 && s
->face
->box
!= FACE_NO_BOX
3021 && (s
->first_glyph
->type
== CHAR_GLYPH
3022 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3025 x_set_glyph_string_clipping (s
);
3026 x_draw_glyph_string_background (s
, 1);
3027 x_draw_glyph_string_box (s
);
3028 x_set_glyph_string_clipping (s
);
3032 x_set_glyph_string_clipping (s
);
3034 switch (s
->first_glyph
->type
)
3037 x_draw_image_glyph_string (s
);
3041 x_draw_stretch_glyph_string (s
);
3045 if (s
->for_overlaps_p
)
3046 s
->background_filled_p
= 1;
3048 x_draw_glyph_string_background (s
, 0);
3049 x_draw_glyph_string_foreground (s
);
3052 case COMPOSITE_GLYPH
:
3053 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3054 s
->background_filled_p
= 1;
3056 x_draw_glyph_string_background (s
, 1);
3057 x_draw_composite_glyph_string_foreground (s
);
3064 if (!s
->for_overlaps_p
)
3066 /* Draw underline. */
3067 if (s
->face
->underline_p
)
3069 unsigned long h
= 1;
3070 unsigned long dy
= s
->height
- h
;
3072 if (s
->face
->underline_defaulted_p
)
3073 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3078 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3079 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3080 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3082 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3086 /* Draw overline. */
3087 if (s
->face
->overline_p
)
3089 unsigned long dy
= 0, h
= 1;
3091 if (s
->face
->overline_color_defaulted_p
)
3092 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3097 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3098 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3099 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3101 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3105 /* Draw strike-through. */
3106 if (s
->face
->strike_through_p
)
3108 unsigned long h
= 1;
3109 unsigned long dy
= (s
->height
- h
) / 2;
3111 if (s
->face
->strike_through_color_defaulted_p
)
3112 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3117 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3118 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3119 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3121 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3125 /* Draw relief if not yet drawn. */
3126 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3127 x_draw_glyph_string_box (s
);
3130 /* Reset clipping. */
3131 mac_reset_clipping (s
->display
, s
->window
);
3134 /* Shift display to make room for inserted glyphs. */
3137 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3139 int x
, y
, width
, height
, shift_by
;
3141 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3142 f
->output_data
.mac
->normal_gc
,
3143 x
, y
, width
, height
,
3147 /* Delete N glyphs at the nominal cursor position. Not implemented
3158 /* Clear entire frame. If updating_frame is non-null, clear that
3159 frame. Otherwise clear the selected frame. */
3169 f
= SELECTED_FRAME ();
3171 /* Clearing the frame will erase any cursor, so mark them all as no
3173 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3174 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3175 output_cursor
.x
= -1;
3177 /* We don't set the output cursor here because there will always
3178 follow an explicit cursor_to. */
3180 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3182 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3183 /* We have to clear the scroll bars, too. If we have changed
3184 colors or something like that, then they should be notified. */
3185 x_scroll_bar_clear (f
);
3188 XFlush (FRAME_MAC_DISPLAY (f
));
3194 /* Invert the middle quarter of the frame for .15 sec. */
3196 /* We use the select system call to do the waiting, so we have to make
3197 sure it's available. If it isn't, we just won't do visual bells. */
3199 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3202 /* Subtract the `struct timeval' values X and Y, storing the result in
3203 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3206 timeval_subtract (result
, x
, y
)
3207 struct timeval
*result
, x
, y
;
3209 /* Perform the carry for the later subtraction by updating y. This
3210 is safer because on some systems the tv_sec member is unsigned. */
3211 if (x
.tv_usec
< y
.tv_usec
)
3213 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3214 y
.tv_usec
-= 1000000 * nsec
;
3218 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3220 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3221 y
.tv_usec
+= 1000000 * nsec
;
3225 /* Compute the time remaining to wait. tv_usec is certainly
3227 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3228 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3230 /* Return indication of whether the result should be considered
3232 return x
.tv_sec
< y
.tv_sec
;
3244 struct timeval wakeup
;
3246 EMACS_GET_TIME (wakeup
);
3248 /* Compute time to wait until, propagating carry from usecs. */
3249 wakeup
.tv_usec
+= 150000;
3250 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3251 wakeup
.tv_usec
%= 1000000;
3253 /* Keep waiting until past the time wakeup. */
3256 struct timeval timeout
;
3258 EMACS_GET_TIME (timeout
);
3260 /* In effect, timeout = wakeup - timeout.
3261 Break if result would be negative. */
3262 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3265 /* Try to wait that long--but we might wake up sooner. */
3266 select (0, NULL
, NULL
, NULL
, &timeout
);
3275 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3278 /* Make audible bell. */
3283 struct frame
*f
= SELECTED_FRAME ();
3285 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3293 XFlush (FRAME_MAC_DISPLAY (f
));
3300 /* Specify how many text lines, from the top of the window,
3301 should be affected by insert-lines and delete-lines operations.
3302 This, and those operations, are used only within an update
3303 that is bounded by calls to x_update_begin and x_update_end. */
3306 XTset_terminal_window (n
)
3309 /* This function intentionally left blank. */
3314 /***********************************************************************
3316 ***********************************************************************/
3318 /* Perform an insert-lines or delete-lines operation, inserting N
3319 lines or deleting -N lines at vertical position VPOS. */
3322 x_ins_del_lines (vpos
, n
)
3329 /* Scroll part of the display as described by RUN. */
3332 x_scroll_run (w
, run
)
3336 struct frame
*f
= XFRAME (w
->frame
);
3337 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3339 /* Get frame-relative bounding box of the text display area of W,
3340 without mode lines. Include in this box the left and right
3342 window_box (w
, -1, &x
, &y
, &width
, &height
);
3344 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3345 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3346 bottom_y
= y
+ height
;
3350 /* Scrolling up. Make sure we don't copy part of the mode
3351 line at the bottom. */
3352 if (from_y
+ run
->height
> bottom_y
)
3353 height
= bottom_y
- from_y
;
3355 height
= run
->height
;
3359 /* Scolling down. Make sure we don't copy over the mode line.
3361 if (to_y
+ run
->height
> bottom_y
)
3362 height
= bottom_y
- to_y
;
3364 height
= run
->height
;
3369 /* Cursor off. Will be switched on again in x_update_window_end. */
3373 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3374 f
->output_data
.mac
->normal_gc
,
3384 /***********************************************************************
3386 ***********************************************************************/
3393 x_update_cursor (f
, 1);
3397 frame_unhighlight (f
)
3400 x_update_cursor (f
, 1);
3403 /* The focus has changed. Update the frames as necessary to reflect
3404 the new situation. Note that we can't change the selected frame
3405 here, because the Lisp code we are interrupting might become confused.
3406 Each event gets marked with the frame in which it occurred, so the
3407 Lisp code can tell when the switch took place by examining the events. */
3410 x_new_focus_frame (dpyinfo
, frame
)
3411 struct x_display_info
*dpyinfo
;
3412 struct frame
*frame
;
3414 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3416 if (frame
!= dpyinfo
->x_focus_frame
)
3418 /* Set this before calling other routines, so that they see
3419 the correct value of x_focus_frame. */
3420 dpyinfo
->x_focus_frame
= frame
;
3422 if (old_focus
&& old_focus
->auto_lower
)
3423 x_lower_frame (old_focus
);
3426 selected_frame
= frame
;
3427 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3429 Fselect_window (selected_frame
->selected_window
, Qnil
);
3430 choose_minibuf_frame ();
3433 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3434 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3436 pending_autoraise_frame
= 0;
3439 x_frame_rehighlight (dpyinfo
);
3442 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3445 x_mouse_leave (dpyinfo
)
3446 struct x_display_info
*dpyinfo
;
3448 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3451 /* The focus has changed, or we have redirected a frame's focus to
3452 another frame (this happens when a frame uses a surrogate
3453 mini-buffer frame). Shift the highlight as appropriate.
3455 The FRAME argument doesn't necessarily have anything to do with which
3456 frame is being highlighted or un-highlighted; we only use it to find
3457 the appropriate X display info. */
3460 XTframe_rehighlight (frame
)
3461 struct frame
*frame
;
3463 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3467 x_frame_rehighlight (dpyinfo
)
3468 struct x_display_info
*dpyinfo
;
3470 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3472 if (dpyinfo
->x_focus_frame
)
3474 dpyinfo
->x_highlight_frame
3475 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3476 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3477 : dpyinfo
->x_focus_frame
);
3478 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3480 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3481 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3485 dpyinfo
->x_highlight_frame
= 0;
3487 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3490 frame_unhighlight (old_highlight
);
3491 if (dpyinfo
->x_highlight_frame
)
3492 frame_highlight (dpyinfo
->x_highlight_frame
);
3498 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3500 #if 0 /* MAC_TODO */
3501 /* Initialize mode_switch_bit and modifier_meaning. */
3503 x_find_modifier_meanings (dpyinfo
)
3504 struct x_display_info
*dpyinfo
;
3506 int min_code
, max_code
;
3509 XModifierKeymap
*mods
;
3511 dpyinfo
->meta_mod_mask
= 0;
3512 dpyinfo
->shift_lock_mask
= 0;
3513 dpyinfo
->alt_mod_mask
= 0;
3514 dpyinfo
->super_mod_mask
= 0;
3515 dpyinfo
->hyper_mod_mask
= 0;
3518 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3520 min_code
= dpyinfo
->display
->min_keycode
;
3521 max_code
= dpyinfo
->display
->max_keycode
;
3524 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3525 min_code
, max_code
- min_code
+ 1,
3527 mods
= XGetModifierMapping (dpyinfo
->display
);
3529 /* Scan the modifier table to see which modifier bits the Meta and
3530 Alt keysyms are on. */
3532 int row
, col
; /* The row and column in the modifier table. */
3534 for (row
= 3; row
< 8; row
++)
3535 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3538 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3540 /* Zeroes are used for filler. Skip them. */
3544 /* Are any of this keycode's keysyms a meta key? */
3548 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3550 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3556 dpyinfo
->meta_mod_mask
|= (1 << row
);
3561 dpyinfo
->alt_mod_mask
|= (1 << row
);
3566 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3571 dpyinfo
->super_mod_mask
|= (1 << row
);
3575 /* Ignore this if it's not on the lock modifier. */
3576 if ((1 << row
) == LockMask
)
3577 dpyinfo
->shift_lock_mask
= LockMask
;
3585 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3586 if (! dpyinfo
->meta_mod_mask
)
3588 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3589 dpyinfo
->alt_mod_mask
= 0;
3592 /* If some keys are both alt and meta,
3593 make them just meta, not alt. */
3594 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3596 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3599 XFree ((char *) syms
);
3600 XFreeModifiermap (mods
);
3603 #endif /* MAC_TODO */
3605 /* Convert between the modifier bits X uses and the modifier bits
3609 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3610 struct x_display_info
*dpyinfo
;
3611 unsigned short state
;
3613 return (((state
& shiftKey
) ? shift_modifier
: 0)
3614 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3615 | ((state
& cmdKey
) ? meta_modifier
: 0)
3616 | ((state
& optionKey
) ? alt_modifier
: 0));
3619 #if 0 /* MAC_TODO */
3620 static unsigned short
3621 x_emacs_to_x_modifiers (dpyinfo
, state
)
3622 struct x_display_info
*dpyinfo
;
3625 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3626 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3627 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3628 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3629 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3630 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3632 #endif /* MAC_TODO */
3634 /* Convert a keysym to its name. */
3637 x_get_keysym_name (keysym
)
3644 value
= XKeysymToString (keysym
);
3655 /* Mouse clicks and mouse movement. Rah. */
3657 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3659 If the event is a button press, then note that we have grabbed
3663 construct_mouse_click (result
, event
, f
)
3664 struct input_event
*result
;
3670 result
->kind
= MOUSE_CLICK_EVENT
;
3671 result
->code
= 0; /* only one mouse button */
3672 result
->timestamp
= event
->when
;
3673 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3675 mouseLoc
= event
->where
;
3677 SetPortWindowPort (FRAME_MAC_WINDOW (f
));
3679 GlobalToLocal (&mouseLoc
);
3680 XSETINT (result
->x
, mouseLoc
.h
);
3681 XSETINT (result
->y
, mouseLoc
.v
);
3683 XSETFRAME (result
->frame_or_window
, f
);
3690 /* Function to report a mouse movement to the mainstream Emacs code.
3691 The input handler calls this.
3693 We have received a mouse movement event, which is given in *event.
3694 If the mouse is over a different glyph than it was last time, tell
3695 the mainstream emacs code by setting mouse_moved. If not, ask for
3696 another motion event, so we can check again the next time it moves. */
3698 static Point last_mouse_motion_position
;
3699 static Lisp_Object last_mouse_motion_frame
;
3702 note_mouse_movement (frame
, pos
)
3706 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
3707 #if TARGET_API_MAC_CARBON
3711 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3712 last_mouse_motion_position
= *pos
;
3713 XSETFRAME (last_mouse_motion_frame
, frame
);
3715 #if TARGET_API_MAC_CARBON
3716 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3718 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3721 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
3722 /* This case corresponds to LeaveNotify in X11. */
3724 /* If we move outside the frame, then we're certainly no
3725 longer on any text in the frame. */
3726 clear_mouse_face (dpyinfo
);
3727 dpyinfo
->mouse_face_mouse_frame
= 0;
3728 if (!dpyinfo
->grabbed
)
3729 rif
->define_frame_cursor (frame
,
3730 frame
->output_data
.mac
->nontext_cursor
);
3733 /* Has the mouse moved off the glyph it was on at the last sighting? */
3734 else if (pos
->h
< last_mouse_glyph
.left
3735 || pos
->h
>= last_mouse_glyph
.right
3736 || pos
->v
< last_mouse_glyph
.top
3737 || pos
->v
>= last_mouse_glyph
.bottom
)
3739 frame
->mouse_moved
= 1;
3740 last_mouse_scroll_bar
= Qnil
;
3741 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3745 /* This is used for debugging, to turn off note_mouse_highlight. */
3747 int disable_mouse_highlight
;
3751 /************************************************************************
3753 ************************************************************************/
3755 static struct scroll_bar
*x_window_to_scroll_bar ();
3756 static void x_scroll_bar_report_motion ();
3757 static void x_check_fullscreen
P_ ((struct frame
*));
3758 static void x_check_fullscreen_move
P_ ((struct frame
*));
3759 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3762 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3765 redo_mouse_highlight ()
3767 if (!NILP (last_mouse_motion_frame
)
3768 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3769 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3770 last_mouse_motion_position
.h
,
3771 last_mouse_motion_position
.v
);
3775 /* Try to determine frame pixel position and size of the glyph under
3776 frame pixel coordinates X/Y on frame F . Return the position and
3777 size in *RECT. Value is non-zero if we could compute these
3781 glyph_rect (f
, x
, y
, rect
)
3788 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3792 struct window
*w
= XWINDOW (window
);
3793 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3794 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3796 for (; r
< end
&& r
->enabled_p
; ++r
)
3797 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3799 /* Found the row at y. */
3800 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3801 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3804 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3805 rect
->bottom
= rect
->top
+ r
->height
;
3809 /* x is to the left of the first glyph in the row. */
3810 /* Shouldn't this be a pixel value?
3811 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3813 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3814 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3818 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3819 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3821 /* x is on a glyph. */
3822 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3823 rect
->right
= rect
->left
+ g
->pixel_width
;
3827 /* x is to the right of the last glyph in the row. */
3828 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3829 /* Shouldn't this be a pixel value?
3830 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3832 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3837 /* The y is not on any row. */
3841 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3843 /* Record the position of the mouse in last_mouse_glyph. */
3845 remember_mouse_glyph (f1
, gx
, gy
)
3849 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3851 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3852 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3854 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3855 round down even for negative values. */
3861 /* This was the original code from XTmouse_position, but it seems
3862 to give the position of the glyph diagonally next to the one
3863 the mouse is over. */
3864 gx
= (gx
+ width
- 1) / width
* width
;
3865 gy
= (gy
+ height
- 1) / height
* height
;
3867 gx
= gx
/ width
* width
;
3868 gy
= gy
/ height
* height
;
3871 last_mouse_glyph
.left
= gx
;
3872 last_mouse_glyph
.top
= gy
;
3873 last_mouse_glyph
.right
= gx
+ width
;
3874 last_mouse_glyph
.bottom
= gy
+ height
;
3880 front_emacs_window ()
3882 #if TARGET_API_MAC_CARBON
3883 WindowPtr wp
= GetFrontWindowOfClass (kDocumentWindowClass
, true);
3885 while (wp
&& !is_emacs_window (wp
))
3886 wp
= GetNextWindowOfClass (wp
, kDocumentWindowClass
, true);
3888 WindowPtr wp
= FrontWindow ();
3890 while (wp
&& (wp
== tip_window
|| !is_emacs_window (wp
)))
3891 wp
= GetNextWindow (wp
);
3897 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
3899 /* Return the current position of the mouse.
3900 *fp should be a frame which indicates which display to ask about.
3902 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3903 and *part to the frame, window, and scroll bar part that the mouse
3904 is over. Set *x and *y to the portion and whole of the mouse's
3905 position on the scroll bar.
3907 If the mouse movement started elsewhere, set *fp to the frame the
3908 mouse is on, *bar_window to nil, and *x and *y to the character cell
3911 Set *time to the server time-stamp for the time at which the mouse
3912 was at this position.
3914 Don't store anything if we don't have a valid set of values to report.
3916 This clears the mouse_moved flag, so we can wait for the next mouse
3920 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3923 Lisp_Object
*bar_window
;
3924 enum scroll_bar_part
*part
;
3926 unsigned long *time
;
3929 int ignore1
, ignore2
;
3930 WindowPtr wp
= front_emacs_window ();
3932 Lisp_Object frame
, tail
;
3934 if (is_emacs_window(wp
))
3935 f
= mac_window_to_frame (wp
);
3939 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3940 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3943 /* Clear the mouse-moved flag for every frame on this display. */
3944 FOR_EACH_FRAME (tail
, frame
)
3945 XFRAME (frame
)->mouse_moved
= 0;
3947 last_mouse_scroll_bar
= Qnil
;
3949 SetPortWindowPort (wp
);
3951 GetMouse (&mouse_pos
);
3953 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3954 &last_mouse_glyph
, insist
);
3957 *part
= scroll_bar_handle
;
3959 XSETINT (*x
, mouse_pos
.h
);
3960 XSETINT (*y
, mouse_pos
.v
);
3961 *time
= last_mouse_movement_time
;
3968 /***********************************************************************
3970 ***********************************************************************/
3972 /* Handle mouse button event on the tool-bar of frame F, at
3973 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3977 mac_handle_tool_bar_click (f
, button_event
)
3979 EventRecord
*button_event
;
3981 int x
= button_event
->where
.h
;
3982 int y
= button_event
->where
.v
;
3984 if (button_event
->what
== mouseDown
)
3985 handle_tool_bar_click (f
, x
, y
, 1, 0);
3987 handle_tool_bar_click (f
, x
, y
, 0,
3988 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3989 button_event
->modifiers
));
3993 /************************************************************************
3994 Scroll bars, general
3995 ************************************************************************/
3997 /* Create a scroll bar and return the scroll bar vector for it. W is
3998 the Emacs window on which to create the scroll bar. TOP, LEFT,
3999 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4002 static struct scroll_bar
*
4003 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4005 int top
, left
, width
, height
, disp_top
, disp_height
;
4007 struct frame
*f
= XFRAME (w
->frame
);
4008 struct scroll_bar
*bar
4009 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4017 r
.right
= left
+ width
;
4018 r
.bottom
= disp_top
+ disp_height
;
4020 #ifdef TARGET_API_MAC_CARBON
4021 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
4022 kControlScrollBarProc
, 0L);
4024 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
4027 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4028 SetControlReference (ch
, (long) bar
);
4030 XSETWINDOW (bar
->window
, w
);
4031 XSETINT (bar
->top
, top
);
4032 XSETINT (bar
->left
, left
);
4033 XSETINT (bar
->width
, width
);
4034 XSETINT (bar
->height
, height
);
4035 XSETINT (bar
->start
, 0);
4036 XSETINT (bar
->end
, 0);
4037 bar
->dragging
= Qnil
;
4039 /* Add bar to its frame's list of scroll bars. */
4040 bar
->next
= FRAME_SCROLL_BARS (f
);
4042 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4043 if (!NILP (bar
->next
))
4044 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4051 /* Draw BAR's handle in the proper position.
4053 If the handle is already drawn from START to END, don't bother
4054 redrawing it, unless REBUILD is non-zero; in that case, always
4055 redraw it. (REBUILD is handy for drawing the handle after expose
4058 Normally, we want to constrain the start and end of the handle to
4059 fit inside its rectangle, but if the user is dragging the scroll
4060 bar handle, we want to let them drag it down all the way, so that
4061 the bar's top is as far down as it goes; otherwise, there's no way
4062 to move to the very end of the buffer. */
4065 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4066 struct scroll_bar
*bar
;
4070 int dragging
= ! NILP (bar
->dragging
);
4071 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4072 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4073 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4074 int length
= end
- start
;
4076 /* If the display is already accurate, do nothing. */
4078 && start
== XINT (bar
->start
)
4079 && end
== XINT (bar
->end
))
4084 /* Make sure the values are reasonable, and try to preserve the
4085 distance between start and end. */
4088 else if (start
> top_range
)
4090 end
= start
+ length
;
4094 else if (end
> top_range
&& ! dragging
)
4097 /* Store the adjusted setting in the scroll bar. */
4098 XSETINT (bar
->start
, start
);
4099 XSETINT (bar
->end
, end
);
4101 /* Clip the end position, just for display. */
4102 if (end
> top_range
)
4105 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4106 top positions, to make sure the handle is always at least that
4107 many pixels tall. */
4108 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4110 SetControlMinimum (ch
, 0);
4111 /* Don't inadvertently activate deactivated scroll bars */
4112 if (GetControlMaximum (ch
) != -1)
4113 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4115 SetControlValue (ch
, start
);
4116 #if TARGET_API_MAC_CARBON
4117 SetControlViewSize (ch
, end
- start
);
4124 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4128 x_scroll_bar_remove (bar
)
4129 struct scroll_bar
*bar
;
4131 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4135 /* Destroy the Mac scroll bar control */
4136 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4138 /* Disassociate this scroll bar from its window. */
4139 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4144 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4145 that we are displaying PORTION characters out of a total of WHOLE
4146 characters, starting at POSITION. If WINDOW has no scroll bar,
4149 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4151 int portion
, whole
, position
;
4153 struct frame
*f
= XFRAME (w
->frame
);
4154 struct scroll_bar
*bar
;
4155 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4156 int window_y
, window_height
;
4158 /* Get window dimensions. */
4159 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4164 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4166 height
= window_height
;
4168 /* Compute the left edge of the scroll bar area. */
4169 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4171 /* Compute the width of the scroll bar which might be less than
4172 the width of the area reserved for the scroll bar. */
4173 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4174 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4178 /* Compute the left edge of the scroll bar. */
4179 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4180 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
4182 sb_left
= left
+ (width
- sb_width
) / 2;
4184 /* Adjustments according to Inside Macintosh to make it look nice */
4186 disp_height
= height
;
4192 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4198 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4201 /* Does the scroll bar exist yet? */
4202 if (NILP (w
->vertical_scroll_bar
))
4205 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4206 left
, top
, width
, height
, 0);
4208 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4210 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4214 /* It may just need to be moved and resized. */
4217 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4218 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4222 /* If already correctly positioned, do nothing. */
4223 if (XINT (bar
->left
) == sb_left
4224 && XINT (bar
->top
) == top
4225 && XINT (bar
->width
) == sb_width
4226 && XINT (bar
->height
) == height
)
4230 /* Clear areas not covered by the scroll bar because it's not as
4231 wide as the area reserved for it . This makes sure a
4232 previous mode line display is cleared after C-x 2 C-x 1, for
4234 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4235 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4236 left
, top
, area_width
, height
, 0);
4239 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4240 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4241 sb_left
- 1, top
, 1, height
, 0);
4245 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4246 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4250 /* Remember new settings. */
4251 XSETINT (bar
->left
, sb_left
);
4252 XSETINT (bar
->top
, top
);
4253 XSETINT (bar
->width
, sb_width
);
4254 XSETINT (bar
->height
, height
);
4260 /* Set the scroll bar's current state, unless we're currently being
4262 if (NILP (bar
->dragging
))
4264 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4267 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4270 int start
= ((double) position
* top_range
) / whole
;
4271 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4272 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4278 /* The following three hooks are used when we're doing a thorough
4279 redisplay of the frame. We don't explicitly know which scroll bars
4280 are going to be deleted, because keeping track of when windows go
4281 away is a real pain - "Can you say set-window-configuration, boys
4282 and girls?" Instead, we just assert at the beginning of redisplay
4283 that *all* scroll bars are to be removed, and then save a scroll bar
4284 from the fiery pit when we actually redisplay its window. */
4286 /* Arrange for all scroll bars on FRAME to be removed at the next call
4287 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4288 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4291 XTcondemn_scroll_bars (frame
)
4294 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4295 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4298 bar
= FRAME_SCROLL_BARS (frame
);
4299 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4300 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4301 XSCROLL_BAR (bar
)->prev
= Qnil
;
4302 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4303 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4304 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4309 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4310 Note that WINDOW isn't necessarily condemned at all. */
4313 XTredeem_scroll_bar (window
)
4314 struct window
*window
;
4316 struct scroll_bar
*bar
;
4318 /* We can't redeem this window's scroll bar if it doesn't have one. */
4319 if (NILP (window
->vertical_scroll_bar
))
4322 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4324 /* Unlink it from the condemned list. */
4326 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4328 if (NILP (bar
->prev
))
4330 /* If the prev pointer is nil, it must be the first in one of
4332 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4333 /* It's not condemned. Everything's fine. */
4335 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4336 window
->vertical_scroll_bar
))
4337 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4339 /* If its prev pointer is nil, it must be at the front of
4340 one or the other! */
4344 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4346 if (! NILP (bar
->next
))
4347 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4349 bar
->next
= FRAME_SCROLL_BARS (f
);
4351 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4352 if (! NILP (bar
->next
))
4353 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4357 /* Remove all scroll bars on FRAME that haven't been saved since the
4358 last call to `*condemn_scroll_bars_hook'. */
4361 XTjudge_scroll_bars (f
)
4364 Lisp_Object bar
, next
;
4366 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4368 /* Clear out the condemned list now so we won't try to process any
4369 more events on the hapless scroll bars. */
4370 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4372 for (; ! NILP (bar
); bar
= next
)
4374 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4376 x_scroll_bar_remove (b
);
4379 b
->next
= b
->prev
= Qnil
;
4382 /* Now there should be no references to the condemned scroll bars,
4383 and they should get garbage-collected. */
4388 activate_scroll_bars (frame
)
4394 bar
= FRAME_SCROLL_BARS (frame
);
4395 while (! NILP (bar
))
4397 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4398 #ifdef TARGET_API_MAC_CARBON
4399 ActivateControl (ch
);
4401 SetControlMaximum (ch
,
4402 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4403 XINT (XSCROLL_BAR (bar
)
4406 bar
= XSCROLL_BAR (bar
)->next
;
4412 deactivate_scroll_bars (frame
)
4418 bar
= FRAME_SCROLL_BARS (frame
);
4419 while (! NILP (bar
))
4421 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4422 #ifdef TARGET_API_MAC_CARBON
4423 DeactivateControl (ch
);
4425 SetControlMaximum (ch
, XINT (-1));
4427 bar
= XSCROLL_BAR (bar
)->next
;
4431 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4432 is set to something other than NO_EVENT, it is enqueued.
4434 This may be called from a signal handler, so we have to ignore GC
4438 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4439 struct scroll_bar
*bar
;
4442 struct input_event
*bufp
;
4444 int win_y
, top_range
;
4446 if (! GC_WINDOWP (bar
->window
))
4449 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4450 bufp
->frame_or_window
= bar
->window
;
4453 bar
->dragging
= Qnil
;
4457 case kControlUpButtonPart
:
4458 bufp
->part
= scroll_bar_up_arrow
;
4460 case kControlDownButtonPart
:
4461 bufp
->part
= scroll_bar_down_arrow
;
4463 case kControlPageUpPart
:
4464 bufp
->part
= scroll_bar_above_handle
;
4466 case kControlPageDownPart
:
4467 bufp
->part
= scroll_bar_below_handle
;
4469 #ifdef TARGET_API_MAC_CARBON
4472 case kControlIndicatorPart
:
4474 if (er
->what
== mouseDown
)
4475 bar
->dragging
= make_number (0);
4476 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4477 bufp
->part
= scroll_bar_handle
;
4481 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
4482 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
4484 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4488 if (! NILP (bar
->dragging
))
4489 win_y
-= XINT (bar
->dragging
);
4493 if (win_y
> top_range
)
4496 XSETINT (bufp
->x
, win_y
);
4497 XSETINT (bufp
->y
, top_range
);
4501 /* Handle some mouse motion while someone is dragging the scroll bar.
4503 This may be called from a signal handler, so we have to ignore GC
4507 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4508 struct scroll_bar
*bar
;
4512 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4514 last_mouse_movement_time
= t
;
4517 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4519 /* If we're dragging the bar, display it. */
4520 if (! GC_NILP (bar
->dragging
))
4522 /* Where should the handle be now? */
4523 int new_start
= y_pos
- 24;
4525 if (new_start
!= XINT (bar
->start
))
4527 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4529 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4535 /* Return information to the user about the current position of the
4536 mouse on the scroll bar. */
4539 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4541 Lisp_Object
*bar_window
;
4542 enum scroll_bar_part
*part
;
4544 unsigned long *time
;
4546 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4547 WindowPtr wp
= front_emacs_window ();
4549 struct frame
*f
= mac_window_to_frame (wp
);
4550 int win_y
, top_range
;
4552 SetPortWindowPort (wp
);
4554 GetMouse (&mouse_pos
);
4556 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4557 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4559 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4563 if (! NILP (bar
->dragging
))
4564 win_y
-= XINT (bar
->dragging
);
4568 if (win_y
> top_range
)
4572 *bar_window
= bar
->window
;
4574 if (! NILP (bar
->dragging
))
4575 *part
= scroll_bar_handle
;
4576 else if (win_y
< XINT (bar
->start
))
4577 *part
= scroll_bar_above_handle
;
4578 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4579 *part
= scroll_bar_handle
;
4581 *part
= scroll_bar_below_handle
;
4583 XSETINT (*x
, win_y
);
4584 XSETINT (*y
, top_range
);
4587 last_mouse_scroll_bar
= Qnil
;
4589 *time
= last_mouse_movement_time
;
4592 /***********************************************************************
4594 ***********************************************************************/
4596 /* Set clipping for output in glyph row ROW. W is the window in which
4597 we operate. GC is the graphics context to set clipping in.
4599 ROW may be a text row or, e.g., a mode line. Text rows must be
4600 clipped to the interior of the window dedicated to text display,
4601 mode lines must be clipped to the whole window. */
4604 x_clip_to_row (w
, row
, area
, gc
)
4606 struct glyph_row
*row
;
4610 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4612 int window_x
, window_y
, window_width
;
4614 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
4616 clip_rect
.left
= window_x
;
4617 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4618 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4619 clip_rect
.right
= clip_rect
.left
+ window_width
;
4620 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4622 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4626 /* Draw a hollow box cursor on window W in glyph row ROW. */
4629 x_draw_hollow_cursor (w
, row
)
4631 struct glyph_row
*row
;
4633 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4634 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4635 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4638 struct glyph
*cursor_glyph
;
4641 /* Get the glyph the cursor is on. If we can't tell because
4642 the current matrix is invalid or such, give up. */
4643 cursor_glyph
= get_phys_cursor_glyph (w
);
4644 if (cursor_glyph
== NULL
)
4647 /* Compute the width of the rectangle to draw. If on a stretch
4648 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4649 rectangle as wide as the glyph, but use a canonical character
4651 wd
= cursor_glyph
->pixel_width
- 1;
4652 if (cursor_glyph
->type
== STRETCH_GLYPH
4653 && !x_stretch_cursor_p
)
4654 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4655 w
->phys_cursor_width
= wd
;
4657 /* Compute frame-relative coordinates from window-relative
4659 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4660 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4662 /* Compute the proper height and ascent of the rectangle, based
4663 on the actual glyph. Using the full height of the row looks
4664 bad when there are tall images on that row. */
4665 h
= max (min (FRAME_LINE_HEIGHT (f
), row
->height
),
4666 cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4667 if (h
< row
->height
)
4668 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4671 /* The foreground of cursor_gc is typically the same as the normal
4672 background color, which can cause the cursor box to be invisible. */
4673 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4674 if (dpyinfo
->scratch_cursor_gc
)
4675 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4677 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4678 GCForeground
, &xgcv
);
4679 gc
= dpyinfo
->scratch_cursor_gc
;
4681 /* Set clipping, draw the rectangle, and reset clipping again. */
4682 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4683 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4684 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4688 /* Draw a bar cursor on window W in glyph row ROW.
4690 Implementation note: One would like to draw a bar cursor with an
4691 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4692 Unfortunately, I didn't find a font yet that has this property set.
4696 x_draw_bar_cursor (w
, row
, width
, kind
)
4698 struct glyph_row
*row
;
4700 enum text_cursor_kinds kind
;
4702 struct frame
*f
= XFRAME (w
->frame
);
4703 struct glyph
*cursor_glyph
;
4705 /* If cursor is out of bounds, don't draw garbage. This can happen
4706 in mini-buffer windows when switching between echo area glyphs
4708 cursor_glyph
= get_phys_cursor_glyph (w
);
4709 if (cursor_glyph
== NULL
)
4712 /* If on an image, draw like a normal cursor. That's usually better
4713 visible than drawing a bar, esp. if the image is large so that
4714 the bar might not be in the window. */
4715 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4717 struct glyph_row
*row
;
4718 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4719 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4723 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4724 Window window
= FRAME_MAC_WINDOW (f
);
4725 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4726 unsigned long mask
= GCForeground
| GCBackground
;
4727 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4730 /* If the glyph's background equals the color we normally draw
4731 the bar cursor in, the bar cursor in its normal color is
4732 invisible. Use the glyph's foreground color instead in this
4733 case, on the assumption that the glyph's colors are chosen so
4734 that the glyph is legible. */
4735 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4736 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4738 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4741 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4744 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4745 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4749 width
= FRAME_CURSOR_WIDTH (f
);
4750 width
= min (cursor_glyph
->pixel_width
, width
);
4752 w
->phys_cursor_width
= width
;
4753 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
4755 if (kind
== BAR_CURSOR
)
4756 XFillRectangle (dpy
, window
, gc
,
4757 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4758 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4759 width
, row
->height
);
4761 XFillRectangle (dpy
, window
, gc
,
4762 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4763 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4764 row
->height
- width
),
4765 cursor_glyph
->pixel_width
,
4768 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4773 /* RIF: Define cursor CURSOR on frame F. */
4776 mac_define_frame_cursor (f
, cursor
)
4780 #if TARGET_API_MAC_CARBON
4781 SetThemeCursor (cursor
);
4783 SetCursor (*cursor
);
4788 /* RIF: Clear area on frame F. */
4791 mac_clear_frame_area (f
, x
, y
, width
, height
)
4793 int x
, y
, width
, height
;
4795 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4796 x
, y
, width
, height
, 0);
4800 /* RIF: Draw cursor on window W. */
4803 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4805 struct glyph_row
*glyph_row
;
4807 int cursor_type
, cursor_width
;
4812 w
->phys_cursor_type
= cursor_type
;
4813 w
->phys_cursor_on_p
= 1;
4815 if (glyph_row
->exact_window_width_line_p
4816 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4818 glyph_row
->cursor_in_fringe_p
= 1;
4819 draw_fringe_bitmap (w
, glyph_row
, 0);
4822 switch (cursor_type
)
4824 case HOLLOW_BOX_CURSOR
:
4825 x_draw_hollow_cursor (w
, glyph_row
);
4828 case FILLED_BOX_CURSOR
:
4829 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4833 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4837 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4841 w
->phys_cursor_width
= 0;
4853 #if 0 /* MAC_TODO: no icon support yet. */
4855 x_bitmap_icon (f
, icon
)
4861 if (FRAME_W32_WINDOW (f
) == 0)
4865 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4866 else if (STRINGP (icon
))
4867 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4868 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4869 else if (SYMBOLP (icon
))
4873 if (EQ (icon
, intern ("application")))
4874 name
= (LPCTSTR
) IDI_APPLICATION
;
4875 else if (EQ (icon
, intern ("hand")))
4876 name
= (LPCTSTR
) IDI_HAND
;
4877 else if (EQ (icon
, intern ("question")))
4878 name
= (LPCTSTR
) IDI_QUESTION
;
4879 else if (EQ (icon
, intern ("exclamation")))
4880 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4881 else if (EQ (icon
, intern ("asterisk")))
4882 name
= (LPCTSTR
) IDI_ASTERISK
;
4883 else if (EQ (icon
, intern ("winlogo")))
4884 name
= (LPCTSTR
) IDI_WINLOGO
;
4888 hicon
= LoadIcon (NULL
, name
);
4896 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4901 #endif /* MAC_TODO */
4903 /************************************************************************
4905 ************************************************************************/
4907 /* Display Error Handling functions not used on W32. Listing them here
4908 helps diff stay in step when comparing w32term.c with xterm.c.
4910 x_error_catcher (display, error)
4911 x_catch_errors (dpy)
4912 x_catch_errors_unwind (old_val)
4913 x_check_errors (dpy, format)
4914 x_had_errors_p (dpy)
4915 x_clear_errors (dpy)
4916 x_uncatch_errors (dpy, count)
4918 x_connection_signal (signalnum)
4919 x_connection_closed (dpy, error_message)
4920 x_error_quitter (display, error)
4921 x_error_handler (display, error)
4922 x_io_error_quitter (display)
4927 /* Changing the font of the frame. */
4929 /* Give frame F the font named FONTNAME as its default font, and
4930 return the full name of that font. FONTNAME may be a wildcard
4931 pattern; in that case, we choose some font that fits the pattern.
4932 The return value shows which font we chose. */
4935 x_new_font (f
, fontname
)
4937 register char *fontname
;
4939 struct font_info
*fontp
4940 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4945 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4946 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4947 FRAME_FONTSET (f
) = -1;
4949 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4950 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4952 compute_fringe_widths (f
, 1);
4954 /* Compute the scroll bar width in character columns. */
4955 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4957 int wid
= FRAME_COLUMN_WIDTH (f
);
4958 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4959 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4963 int wid
= FRAME_COLUMN_WIDTH (f
);
4964 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4967 /* Now make the frame display the given font. */
4968 if (FRAME_MAC_WINDOW (f
) != 0)
4970 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4972 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4974 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4977 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4978 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4981 return build_string (fontp
->full_name
);
4984 /* Give frame F the fontset named FONTSETNAME as its default font, and
4985 return the full name of that fontset. FONTSETNAME may be a wildcard
4986 pattern; in that case, we choose some fontset that fits the pattern.
4987 The return value shows which fontset we chose. */
4990 x_new_fontset (f
, fontsetname
)
4994 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5000 if (FRAME_FONTSET (f
) == fontset
)
5001 /* This fontset is already set in frame F. There's nothing more
5003 return fontset_name (fontset
);
5005 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5007 if (!STRINGP (result
))
5008 /* Can't load ASCII font. */
5011 /* Since x_new_font doesn't update any fontset information, do it now. */
5012 FRAME_FONTSET(f
) = fontset
;
5014 return build_string (fontsetname
);
5018 /***********************************************************************
5019 TODO: W32 Input Methods
5020 ***********************************************************************/
5021 /* Listing missing functions from xterm.c helps diff stay in step.
5023 xim_destroy_callback (xim, client_data, call_data)
5024 xim_open_dpy (dpyinfo, resource_name)
5026 xim_instantiate_callback (display, client_data, call_data)
5027 xim_initialize (dpyinfo, resource_name)
5028 xim_close_dpy (dpyinfo)
5034 mac_get_window_bounds (f
, inner
, outer
)
5036 Rect
*inner
, *outer
;
5038 #if TARGET_API_MAC_CARBON
5039 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5040 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5041 #else /* not TARGET_API_MAC_CARBON */
5042 RgnHandle region
= NewRgn ();
5044 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5045 *inner
= (*region
)->rgnBBox
;
5046 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5047 *outer
= (*region
)->rgnBBox
;
5048 DisposeRgn (region
);
5049 #endif /* not TARGET_API_MAC_CARBON */
5053 /* Calculate the absolute position in frame F
5054 from its current recorded position values and gravity. */
5057 x_calc_absolute_position (f
)
5060 int width_diff
= 0, height_diff
= 0;
5061 int flags
= f
->size_hint_flags
;
5064 /* We have nothing to do if the current position
5065 is already for the top-left corner. */
5066 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5069 /* Find the offsets of the outside upper-left corner of
5070 the inner window, with respect to the outer window. */
5071 mac_get_window_bounds (f
, &inner
, &outer
);
5073 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5074 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5076 /* Treat negative positions as relative to the leftmost bottommost
5077 position that fits on the screen. */
5078 if (flags
& XNegative
)
5079 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5081 - FRAME_PIXEL_WIDTH (f
)
5084 if (flags
& YNegative
)
5085 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5087 - FRAME_PIXEL_HEIGHT (f
)
5090 /* The left_pos and top_pos
5091 are now relative to the top and left screen edges,
5092 so the flags should correspond. */
5093 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5096 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5097 to really change the position, and 0 when calling from
5098 x_make_frame_visible (in that case, XOFF and YOFF are the current
5099 position values). It is -1 when calling from x_set_frame_parameters,
5100 which means, do adjust for borders but don't change the gravity. */
5103 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5105 register int xoff
, yoff
;
5108 if (change_gravity
> 0)
5112 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5114 f
->size_hint_flags
|= XNegative
;
5116 f
->size_hint_flags
|= YNegative
;
5117 f
->win_gravity
= NorthWestGravity
;
5119 x_calc_absolute_position (f
);
5122 x_wm_set_size_hint (f
, (long) 0, 0);
5124 #if TARGET_API_MAC_CARBON
5125 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5126 /* If the title bar is completely outside the screen, adjust the
5128 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5129 kWindowConstrainMoveRegardlessOfFit
5130 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5131 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5134 Rect inner
, outer
, screen_rect
, dummy
;
5135 RgnHandle region
= NewRgn ();
5137 mac_get_window_bounds (f
, &inner
, &outer
);
5138 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5139 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5140 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5141 f
->top_pos
+ f
->y_pixels_diff
, false);
5143 /* If the title bar is completely outside the screen, adjust the
5144 position. The variable `outer' holds the title bar rectangle.
5145 The variable `inner' holds slightly smaller one than `outer',
5146 so that the calculation of overlapping may not become too
5148 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5149 outer
= (*region
)->rgnBBox
;
5150 DisposeRgn (region
);
5152 InsetRect (&inner
, 8, 8);
5153 screen_rect
= qd
.screenBits
.bounds
;
5154 screen_rect
.top
+= GetMBarHeight ();
5156 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5158 if (inner
.right
<= screen_rect
.left
)
5159 f
->left_pos
= screen_rect
.left
;
5160 else if (inner
.left
>= screen_rect
.right
)
5161 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5163 if (inner
.bottom
<= screen_rect
.top
)
5164 f
->top_pos
= screen_rect
.top
;
5165 else if (inner
.top
>= screen_rect
.bottom
)
5166 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5168 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5169 f
->top_pos
+ f
->y_pixels_diff
, false);
5177 /* Call this to change the size of frame F's x-window.
5178 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5179 for this size change and subsequent size changes.
5180 Otherwise we leave the window gravity unchanged. */
5183 x_set_window_size (f
, change_gravity
, cols
, rows
)
5188 int pixelwidth
, pixelheight
;
5192 check_frame_size (f
, &rows
, &cols
);
5193 f
->scroll_bar_actual_width
5194 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5196 compute_fringe_widths (f
, 0);
5198 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5199 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5201 f
->win_gravity
= NorthWestGravity
;
5202 x_wm_set_size_hint (f
, (long) 0, 0);
5204 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5206 /* Now, strictly speaking, we can't be sure that this is accurate,
5207 but the window manager will get around to dealing with the size
5208 change request eventually, and we'll hear how it went when the
5209 ConfigureNotify event gets here.
5211 We could just not bother storing any of this information here,
5212 and let the ConfigureNotify event set everything up, but that
5213 might be kind of confusing to the Lisp code, since size changes
5214 wouldn't be reported in the frame parameters until some random
5215 point in the future when the ConfigureNotify event arrives.
5217 We pass 1 for DELAY since we can't run Lisp code inside of
5219 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5220 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5221 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5223 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5224 receive in the ConfigureNotify event; if we get what we asked
5225 for, then the event won't cause the screen to become garbaged, so
5226 we have to make sure to do it here. */
5227 SET_FRAME_GARBAGED (f
);
5229 XFlush (FRAME_X_DISPLAY (f
));
5231 /* If cursor was outside the new size, mark it as off. */
5232 mark_window_cursors_off (XWINDOW (f
->root_window
));
5234 /* Clear out any recollection of where the mouse highlighting was,
5235 since it might be in a place that's outside the new frame size.
5236 Actually checking whether it is outside is a pain in the neck,
5237 so don't try--just let the highlighting be done afresh with new size. */
5238 cancel_mouse_face (f
);
5243 /* Mouse warping. */
5245 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5248 x_set_mouse_position (f
, x
, y
)
5254 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5255 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5257 if (pix_x
< 0) pix_x
= 0;
5258 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5260 if (pix_y
< 0) pix_y
= 0;
5261 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5263 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5267 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5271 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5274 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5275 0, 0, 0, 0, pix_x
, pix_y
);
5281 /* focus shifting, raising and lowering. */
5284 x_focus_on_frame (f
)
5287 #if 0 /* This proves to be unpleasant. */
5291 /* I don't think that the ICCCM allows programs to do things like this
5292 without the interaction of the window manager. Whatever you end up
5293 doing with this code, do it to x_unfocus_frame too. */
5294 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5295 RevertToPointerRoot
, CurrentTime
);
5305 /* Raise frame F. */
5310 if (f
->async_visible
)
5313 SelectWindow (FRAME_MAC_WINDOW (f
));
5318 /* Lower frame F. */
5323 if (f
->async_visible
)
5326 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5332 XTframe_raise_lower (f
, raise_flag
)
5342 /* Change of visibility. */
5344 /* This tries to wait until the frame is really visible.
5345 However, if the window manager asks the user where to position
5346 the frame, this will return before the user finishes doing that.
5347 The frame will not actually be visible at that time,
5348 but it will become visible later when the window manager
5349 finishes with it. */
5352 x_make_frame_visible (f
)
5356 int original_top
, original_left
;
5360 if (! FRAME_VISIBLE_P (f
))
5362 /* We test FRAME_GARBAGED_P here to make sure we don't
5363 call x_set_offset a second time
5364 if we get to x_make_frame_visible a second time
5365 before the window gets really visible. */
5366 if (! FRAME_ICONIFIED_P (f
)
5367 && ! f
->output_data
.mac
->asked_for_visible
)
5368 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5370 f
->output_data
.mac
->asked_for_visible
= 1;
5372 ShowWindow (FRAME_MAC_WINDOW (f
));
5375 XFlush (FRAME_MAC_DISPLAY (f
));
5377 /* Synchronize to ensure Emacs knows the frame is visible
5378 before we do anything else. We do this loop with input not blocked
5379 so that incoming events are handled. */
5384 /* This must come after we set COUNT. */
5387 XSETFRAME (frame
, f
);
5389 /* Wait until the frame is visible. Process X events until a
5390 MapNotify event has been seen, or until we think we won't get a
5391 MapNotify at all.. */
5392 for (count
= input_signal_count
+ 10;
5393 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5395 /* Force processing of queued events. */
5398 /* Machines that do polling rather than SIGIO have been
5399 observed to go into a busy-wait here. So we'll fake an
5400 alarm signal to let the handler know that there's something
5401 to be read. We used to raise a real alarm, but it seems
5402 that the handler isn't always enabled here. This is
5404 if (input_polling_used ())
5406 /* It could be confusing if a real alarm arrives while
5407 processing the fake one. Turn it off and let the
5408 handler reset it. */
5409 extern void poll_for_input_1
P_ ((void));
5410 int old_poll_suppress_count
= poll_suppress_count
;
5411 poll_suppress_count
= 1;
5412 poll_for_input_1 ();
5413 poll_suppress_count
= old_poll_suppress_count
;
5416 /* See if a MapNotify event has been processed. */
5417 FRAME_SAMPLE_VISIBILITY (f
);
5422 /* Change from mapped state to withdrawn state. */
5424 /* Make the frame visible (mapped and not iconified). */
5427 x_make_frame_invisible (f
)
5430 /* Don't keep the highlight on an invisible frame. */
5431 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5432 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5436 HideWindow (FRAME_MAC_WINDOW (f
));
5438 /* We can't distinguish this from iconification
5439 just by the event that we get from the server.
5440 So we can't win using the usual strategy of letting
5441 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5442 and synchronize with the server to make sure we agree. */
5444 FRAME_ICONIFIED_P (f
) = 0;
5445 f
->async_visible
= 0;
5446 f
->async_iconified
= 0;
5451 /* Change window state from mapped to iconified. */
5457 /* Don't keep the highlight on an invisible frame. */
5458 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5459 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5462 /* Review: Since window is still visible in dock, still allow updates? */
5463 if (f
->async_iconified
)
5469 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5475 /* Free X resources of frame F. */
5478 x_free_frame_resources (f
)
5481 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5482 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5487 if (wp
== tip_window
)
5488 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5489 closed' event. So we reset tip_window here. */
5492 free_frame_menubar (f
);
5494 if (FRAME_FACE_CACHE (f
))
5495 free_frame_faces (f
);
5499 xfree (f
->output_data
.mac
);
5500 f
->output_data
.mac
= NULL
;
5502 if (f
== dpyinfo
->x_focus_frame
)
5503 dpyinfo
->x_focus_frame
= 0;
5504 if (f
== dpyinfo
->x_focus_event_frame
)
5505 dpyinfo
->x_focus_event_frame
= 0;
5506 if (f
== dpyinfo
->x_highlight_frame
)
5507 dpyinfo
->x_highlight_frame
= 0;
5509 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5511 dpyinfo
->mouse_face_beg_row
5512 = dpyinfo
->mouse_face_beg_col
= -1;
5513 dpyinfo
->mouse_face_end_row
5514 = dpyinfo
->mouse_face_end_col
= -1;
5515 dpyinfo
->mouse_face_window
= Qnil
;
5516 dpyinfo
->mouse_face_deferred_gc
= 0;
5517 dpyinfo
->mouse_face_mouse_frame
= 0;
5524 /* Destroy the X window of frame F. */
5527 x_destroy_window (f
)
5530 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5532 x_free_frame_resources (f
);
5534 dpyinfo
->reference_count
--;
5538 /* Setting window manager hints. */
5540 /* Set the normal size hints for the window manager, for frame F.
5541 FLAGS is the flags word to use--or 0 meaning preserve the flags
5542 that the window now has.
5543 If USER_POSITION is nonzero, we set the USPosition
5544 flag (this is useful when FLAGS is 0). */
5546 x_wm_set_size_hint (f
, flags
, user_position
)
5551 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5552 XSizeHints size_hints
;
5554 #ifdef USE_X_TOOLKIT
5557 Dimension widget_width
, widget_height
;
5558 Window window
= XtWindow (f
->output_data
.x
->widget
);
5559 #else /* not USE_X_TOOLKIT */
5560 Window window
= FRAME_X_WINDOW (f
);
5561 #endif /* not USE_X_TOOLKIT */
5563 /* Setting PMaxSize caused various problems. */
5564 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5566 size_hints
.x
= f
->left_pos
;
5567 size_hints
.y
= f
->top_pos
;
5569 #ifdef USE_X_TOOLKIT
5570 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5571 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5572 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5573 size_hints
.height
= widget_height
;
5574 size_hints
.width
= widget_width
;
5575 #else /* not USE_X_TOOLKIT */
5576 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5577 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5578 #endif /* not USE_X_TOOLKIT */
5580 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5581 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5582 size_hints
.max_width
5583 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5584 size_hints
.max_height
5585 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5587 /* Calculate the base and minimum sizes.
5589 (When we use the X toolkit, we don't do it here.
5590 Instead we copy the values that the widgets are using, below.) */
5591 #ifndef USE_X_TOOLKIT
5593 int base_width
, base_height
;
5594 int min_rows
= 0, min_cols
= 0;
5596 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5597 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5599 check_frame_size (f
, &min_rows
, &min_cols
);
5601 /* The window manager uses the base width hints to calculate the
5602 current number of rows and columns in the frame while
5603 resizing; min_width and min_height aren't useful for this
5604 purpose, since they might not give the dimensions for a
5605 zero-row, zero-column frame.
5607 We use the base_width and base_height members if we have
5608 them; otherwise, we set the min_width and min_height members
5609 to the size for a zero x zero frame. */
5612 size_hints
.flags
|= PBaseSize
;
5613 size_hints
.base_width
= base_width
;
5614 size_hints
.base_height
= base_height
;
5615 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5616 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5618 size_hints
.min_width
= base_width
;
5619 size_hints
.min_height
= base_height
;
5623 /* If we don't need the old flags, we don't need the old hint at all. */
5626 size_hints
.flags
|= flags
;
5629 #endif /* not USE_X_TOOLKIT */
5632 XSizeHints hints
; /* Sometimes I hate X Windows... */
5633 long supplied_return
;
5637 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5640 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5643 #ifdef USE_X_TOOLKIT
5644 size_hints
.base_height
= hints
.base_height
;
5645 size_hints
.base_width
= hints
.base_width
;
5646 size_hints
.min_height
= hints
.min_height
;
5647 size_hints
.min_width
= hints
.min_width
;
5651 size_hints
.flags
|= flags
;
5656 if (hints
.flags
& PSize
)
5657 size_hints
.flags
|= PSize
;
5658 if (hints
.flags
& PPosition
)
5659 size_hints
.flags
|= PPosition
;
5660 if (hints
.flags
& USPosition
)
5661 size_hints
.flags
|= USPosition
;
5662 if (hints
.flags
& USSize
)
5663 size_hints
.flags
|= USSize
;
5667 #ifndef USE_X_TOOLKIT
5672 size_hints
.win_gravity
= f
->win_gravity
;
5673 size_hints
.flags
|= PWinGravity
;
5677 size_hints
.flags
&= ~ PPosition
;
5678 size_hints
.flags
|= USPosition
;
5680 #endif /* PWinGravity */
5683 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5685 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5687 #endif /* MAC_TODO */
5690 #if 0 /* MAC_TODO: hide application instead of iconify? */
5691 /* Used for IconicState or NormalState */
5694 x_wm_set_window_state (f
, state
)
5698 #ifdef USE_X_TOOLKIT
5701 XtSetArg (al
[0], XtNinitialState
, state
);
5702 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5703 #else /* not USE_X_TOOLKIT */
5704 Window window
= FRAME_X_WINDOW (f
);
5706 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5707 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5709 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5710 #endif /* not USE_X_TOOLKIT */
5714 x_wm_set_icon_pixmap (f
, pixmap_id
)
5720 #ifndef USE_X_TOOLKIT
5721 Window window
= FRAME_X_WINDOW (f
);
5726 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5727 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5731 /* It seems there is no way to turn off use of an icon pixmap.
5732 The following line does it, only if no icon has yet been created,
5733 for some window managers. But with mwm it crashes.
5734 Some people say it should clear the IconPixmapHint bit in this case,
5735 but that doesn't work, and the X consortium said it isn't the
5736 right thing at all. Since there is no way to win,
5737 best to explicitly give up. */
5739 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5745 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5749 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5750 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5753 #else /* not USE_X_TOOLKIT */
5755 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5756 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5758 #endif /* not USE_X_TOOLKIT */
5761 #endif /* MAC_TODO */
5764 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5768 #if 0 /* MAC_TODO: no icons on Mac */
5769 #ifdef USE_X_TOOLKIT
5770 Window window
= XtWindow (f
->output_data
.x
->widget
);
5772 Window window
= FRAME_X_WINDOW (f
);
5775 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5776 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5777 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5779 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5780 #endif /* MAC_TODO */
5784 /***********************************************************************
5786 ***********************************************************************/
5788 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5791 x_get_font_info (f
, font_idx
)
5795 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5798 /* the global font name table */
5799 char **font_name_table
= NULL
;
5800 int font_name_table_size
= 0;
5801 int font_name_count
= 0;
5804 /* compare two strings ignoring case */
5806 stricmp (const char *s
, const char *t
)
5808 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5811 return tolower (*s
) - tolower (*t
);
5814 /* compare two strings ignoring case and handling wildcard */
5816 wildstrieq (char *s1
, char *s2
)
5818 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5821 return stricmp (s1
, s2
) == 0;
5824 /* Assume parameter 1 is fully qualified, no wildcards. */
5826 mac_font_pattern_match (fontname
, pattern
)
5830 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5831 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5834 /* Copy fontname so we can modify it during comparison. */
5835 strcpy (font_name_copy
, fontname
);
5840 /* Turn pattern into a regexp and do a regexp match. */
5841 for (; *pattern
; pattern
++)
5843 if (*pattern
== '?')
5845 else if (*pattern
== '*')
5856 return (fast_c_string_match_ignore_case (build_string (regex
),
5857 font_name_copy
) >= 0);
5860 /* Two font specs are considered to match if their foundry, family,
5861 weight, slant, and charset match. */
5863 mac_font_match (char *mf
, char *xf
)
5865 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5866 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5868 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5869 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5870 return mac_font_pattern_match (mf
, xf
);
5872 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5873 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5874 return mac_font_pattern_match (mf
, xf
);
5876 return (wildstrieq (m_foundry
, x_foundry
)
5877 && wildstrieq (m_family
, x_family
)
5878 && wildstrieq (m_weight
, x_weight
)
5879 && wildstrieq (m_slant
, x_slant
)
5880 && wildstrieq (m_charset
, x_charset
))
5881 || mac_font_pattern_match (mf
, xf
);
5885 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5888 decode_mac_font_name (name
, size
, scriptcode
)
5891 #if TARGET_API_MAC_CARBON
5897 Lisp_Object coding_system
;
5898 struct coding_system coding
;
5904 coding_system
= Qbig5
;
5907 coding_system
= Qcn_gb
;
5910 coding_system
= Qsjis
;
5913 coding_system
= Qeuc_kr
;
5919 setup_coding_system (coding_system
, &coding
);
5920 coding
.src_multibyte
= 0;
5921 coding
.dst_multibyte
= 1;
5922 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5923 coding
.composing
= COMPOSITION_DISABLED
;
5924 buf
= (char *) alloca (size
);
5926 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5927 bcopy (buf
, name
, coding
.produced
);
5928 name
[coding
.produced
] = '\0';
5933 mac_to_x_fontname (name
, size
, style
, scriptcode
, encoding_base
)
5937 #if TARGET_API_MAC_CARBON
5943 char foundry
[32], family
[32], cs
[32];
5944 char xf
[256], *result
, *p
;
5946 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5948 strcpy(foundry
, "Apple");
5949 strcpy(family
, name
);
5953 case smTradChinese
: /* == kTextEncodingMacChineseTrad */
5954 strcpy(cs
, "big5-0");
5956 case smSimpChinese
: /* == kTextEncodingMacChineseSimp */
5957 strcpy(cs
, "gb2312.1980-0");
5959 case smJapanese
: /* == kTextEncodingMacJapanese */
5960 strcpy(cs
, "jisx0208.1983-sjis");
5963 /* Each Apple Japanese font is entered into the font table
5964 twice: once as a jisx0208.1983-sjis font and once as a
5965 jisx0201.1976-0 font. The latter can be used to display
5966 the ascii charset and katakana-jisx0201 charset. A
5967 negative script code signals that the name of this latter
5968 font is being built. */
5969 strcpy(cs
, "jisx0201.1976-0");
5971 case smKorean
: /* == kTextEncodingMacKorean */
5972 strcpy(cs
, "ksc5601.1989-0");
5974 #if TARGET_API_MAC_CARBON
5975 case kTextEncodingMacCyrillic
:
5976 strcpy(cs
, "mac-cyrillic");
5978 case kTextEncodingMacCentralEurRoman
:
5979 strcpy(cs
, "mac-centraleuropean");
5981 case kTextEncodingMacSymbol
:
5982 case kTextEncodingMacDingbats
:
5983 strcpy(cs
, "adobe-fontspecific");
5987 strcpy(cs
, "mac-roman");
5992 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5993 foundry
, family
, style
& bold
? "bold" : "medium",
5994 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5996 result
= (char *) xmalloc (strlen (xf
) + 1);
5997 strcpy (result
, xf
);
5998 for (p
= result
; *p
; p
++)
6004 /* Convert an X font spec to the corresponding mac font name, which
6005 can then be passed to GetFNum after conversion to a Pascal string.
6006 For ordinary Mac fonts, this should just be their names, like
6007 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
6008 collection contain their charset designation in their names, like
6009 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
6010 names are handled accordingly. */
6012 x_font_name_to_mac_font_name (char *xf
, char *mf
)
6014 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
6015 Lisp_Object coding_system
= Qnil
;
6016 struct coding_system coding
;
6020 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6021 foundry
, family
, weight
, slant
, cs
) != 5 &&
6022 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6023 foundry
, family
, weight
, slant
, cs
) != 5)
6026 if (strcmp (cs
, "big5-0") == 0)
6027 coding_system
= Qbig5
;
6028 else if (strcmp (cs
, "gb2312.1980-0") == 0)
6029 coding_system
= Qcn_gb
;
6030 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
6031 || strcmp (cs
, "jisx0201.1976-0") == 0)
6032 coding_system
= Qsjis
;
6033 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
6034 coding_system
= Qeuc_kr
;
6035 else if (strcmp (cs
, "mac-roman") == 0
6036 || strcmp (cs
, "mac-cyrillic") == 0
6037 || strcmp (cs
, "mac-centraleuropean") == 0
6038 || strcmp (cs
, "adobe-fontspecific") == 0)
6039 strcpy (mf
, family
);
6041 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
6043 if (!NILP (coding_system
))
6045 setup_coding_system (coding_system
, &coding
);
6046 coding
.src_multibyte
= 1;
6047 coding
.dst_multibyte
= 1;
6048 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6049 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
6050 mf
[coding
.produced
] = '\0';
6056 add_font_name_table_entry (char *font_name
)
6058 if (font_name_table_size
== 0)
6060 font_name_table_size
= 16;
6061 font_name_table
= (char **)
6062 xmalloc (font_name_table_size
* sizeof (char *));
6064 else if (font_name_count
+ 1 >= font_name_table_size
)
6066 font_name_table_size
+= 16;
6067 font_name_table
= (char **)
6068 xrealloc (font_name_table
,
6069 font_name_table_size
* sizeof (char *));
6072 font_name_table
[font_name_count
++] = font_name
;
6075 /* Sets up the table font_name_table to contain the list of all fonts
6076 in the system the first time the table is used so that the Resource
6077 Manager need not be accessed every time this information is
6081 init_font_name_table ()
6083 #if TARGET_API_MAC_CARBON
6086 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
6088 FMFontFamilyIterator ffi
;
6089 FMFontFamilyInstanceIterator ffii
;
6092 /* Create a dummy instance iterator here to avoid creating and
6093 destroying it in the loop. */
6094 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6096 /* Create an iterator to enumerate the font families. */
6097 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6100 FMDisposeFontFamilyInstanceIterator (&ffii
);
6104 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6110 TextEncoding encoding
;
6111 TextEncodingBase sc
;
6113 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6119 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
6121 sc
= GetTextEncodingBase (encoding
);
6122 decode_mac_font_name (name
, sizeof (name
), sc
);
6124 /* Point the instance iterator at the current font family. */
6125 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6128 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6131 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6132 contained in Apple Japanese (SJIS) font. */
6136 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6138 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6140 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6142 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6147 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6149 if (sc
== smJapanese
)
6154 else if (sc
== -smJapanese
)
6159 /* Dispose of the iterators. */
6160 FMDisposeFontFamilyIterator (&ffi
);
6161 FMDisposeFontFamilyInstanceIterator (&ffii
);
6165 #endif /* TARGET_API_MAC_CARBON */
6167 SInt16 fontnum
, old_fontnum
;
6168 int num_mac_fonts
= CountResources('FOND');
6170 Handle font_handle
, font_handle_2
;
6171 short id
, scriptcode
;
6174 struct FontAssoc
*fat
;
6175 struct AsscEntry
*assc_entry
;
6177 GetPort (&port
); /* save the current font number used */
6178 #if TARGET_API_MAC_CARBON
6179 old_fontnum
= GetPortTextFont (port
);
6181 old_fontnum
= port
->txFont
;
6184 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6186 font_handle
= GetIndResource ('FOND', i
);
6190 GetResInfo (font_handle
, &id
, &type
, name
);
6191 GetFNum (name
, &fontnum
);
6197 scriptcode
= FontToScript (fontnum
);
6198 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6201 HLock (font_handle
);
6203 if (GetResourceSizeOnDisk (font_handle
)
6204 >= sizeof (struct FamRec
))
6206 fat
= (struct FontAssoc
*) (*font_handle
6207 + sizeof (struct FamRec
));
6209 = (struct AsscEntry
*) (*font_handle
6210 + sizeof (struct FamRec
)
6211 + sizeof (struct FontAssoc
));
6213 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6215 if (font_name_table_size
== 0)
6217 font_name_table_size
= 16;
6218 font_name_table
= (char **)
6219 xmalloc (font_name_table_size
* sizeof (char *));
6221 else if (font_name_count
>= font_name_table_size
)
6223 font_name_table_size
+= 16;
6224 font_name_table
= (char **)
6225 xrealloc (font_name_table
,
6226 font_name_table_size
* sizeof (char *));
6228 font_name_table
[font_name_count
++]
6229 = mac_to_x_fontname (name
,
6230 assc_entry
->fontSize
,
6231 assc_entry
->fontStyle
,
6233 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6234 parts are contained in Apple Japanese (SJIS)
6236 if (smJapanese
== scriptcode
)
6238 font_name_table
[font_name_count
++]
6239 = mac_to_x_fontname (name
,
6240 assc_entry
->fontSize
,
6241 assc_entry
->fontStyle
,
6247 HUnlock (font_handle
);
6248 font_handle_2
= GetNextFOND (font_handle
);
6249 ReleaseResource (font_handle
);
6250 font_handle
= font_handle_2
;
6252 while (ResError () == noErr
&& font_handle
);
6255 TextFont (old_fontnum
);
6256 #if TARGET_API_MAC_CARBON
6258 #endif /* TARGET_API_MAC_CARBON */
6262 enum xlfd_scalable_field_index
6264 XLFD_SCL_PIXEL_SIZE
,
6265 XLFD_SCL_POINT_SIZE
,
6270 static int xlfd_scalable_fields
[] =
6279 mac_do_list_fonts (pattern
, maxnames
)
6284 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6285 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6288 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6290 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6293 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6294 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6295 fonts are scaled according to the specified size. */
6298 field
= xlfd_scalable_fields
;
6306 if ('1' <= *ptr
&& *ptr
<= '9')
6308 *val
= *ptr
++ - '0';
6309 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6310 *val
= *val
* 10 + *ptr
++ - '0';
6317 ptr
= strchr (ptr
, '-');
6320 while (ptr
&& i
< 14);
6322 if (i
== 14 && ptr
== NULL
)
6324 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6326 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6327 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6329 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6331 scl_val
[XLFD_SCL_POINT_SIZE
] =
6332 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6334 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6336 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6337 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6341 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6346 /* Turn pattern into a regexp and do a regexp match. */
6347 for (; *pattern
; pattern
++)
6349 if (*pattern
== '?')
6351 else if (*pattern
== '*')
6357 *ptr
++ = tolower (*pattern
);
6362 pattern_regex
= build_string (regex
);
6364 for (i
= 0; i
< font_name_count
; i
++)
6366 fontname
= build_string (font_name_table
[i
]);
6367 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6369 font_list
= Fcons (fontname
, font_list
);
6372 if (maxnames
> 0 && n_fonts
>= maxnames
)
6375 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6376 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6378 int former_len
= ptr
- font_name_table
[i
];
6380 memcpy (scaled
, font_name_table
[i
], former_len
);
6381 sprintf (scaled
+ former_len
,
6382 "-%d-%d-75-75-m-%d-%s",
6383 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6384 scl_val
[XLFD_SCL_POINT_SIZE
],
6385 scl_val
[XLFD_SCL_AVGWIDTH
],
6386 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6387 fontname
= build_string (scaled
);
6388 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6390 font_list
= Fcons (fontname
, font_list
);
6393 if (maxnames
> 0 && n_fonts
>= maxnames
)
6401 /* Return a list of at most MAXNAMES font specs matching the one in
6402 PATTERN. Cache matching fonts for patterns in
6403 dpyinfo->name_list_element to avoid looking them up again by
6404 calling mac_font_pattern_match (slow). Return as many matching
6405 fonts as possible if MAXNAMES = -1. */
6408 x_list_fonts (struct frame
*f
,
6409 Lisp_Object pattern
,
6413 Lisp_Object newlist
= Qnil
, tem
, key
;
6414 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6416 if (font_name_table
== NULL
) /* Initialize when first used. */
6417 init_font_name_table ();
6421 tem
= XCDR (dpyinfo
->name_list_element
);
6422 key
= Fcons (pattern
, make_number (maxnames
));
6424 newlist
= Fassoc (key
, tem
);
6425 if (!NILP (newlist
))
6427 newlist
= Fcdr_safe (newlist
);
6432 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6434 /* MAC_TODO: add code for matching outline fonts here */
6438 XSETCDR (dpyinfo
->name_list_element
,
6439 Fcons (Fcons (key
, newlist
),
6440 XCDR (dpyinfo
->name_list_element
)));
6450 /* Check that FONT is valid on frame F. It is if it can be found in F's
6454 x_check_font (f
, font
)
6459 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6461 xassert (font
!= NULL
);
6463 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6464 if (dpyinfo
->font_table
[i
].name
6465 && font
== dpyinfo
->font_table
[i
].font
)
6468 xassert (i
< dpyinfo
->n_fonts
);
6471 #endif /* GLYPH_DEBUG != 0 */
6473 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6474 Note: There are (broken) X fonts out there with invalid XFontStruct
6475 min_bounds contents. For example, handa@etl.go.jp reports that
6476 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6477 have font->min_bounds.width == 0. */
6480 x_font_min_bounds (font
, w
, h
)
6481 MacFontStruct
*font
;
6485 * TODO: Windows does not appear to offer min bound, only
6486 * average and maximum width, and maximum height.
6488 *h
= FONT_HEIGHT (font
);
6489 *w
= FONT_WIDTH (font
);
6493 /* Compute the smallest character width and smallest font height over
6494 all fonts available on frame F. Set the members smallest_char_width
6495 and smallest_font_height in F's x_display_info structure to
6496 the values computed. Value is non-zero if smallest_font_height or
6497 smallest_char_width become smaller than they were before. */
6500 x_compute_min_glyph_bounds (f
)
6504 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6505 MacFontStruct
*font
;
6506 int old_width
= dpyinfo
->smallest_char_width
;
6507 int old_height
= dpyinfo
->smallest_font_height
;
6509 dpyinfo
->smallest_font_height
= 100000;
6510 dpyinfo
->smallest_char_width
= 100000;
6512 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6513 if (dpyinfo
->font_table
[i
].name
)
6515 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6518 font
= (MacFontStruct
*) fontp
->font
;
6519 xassert (font
!= (MacFontStruct
*) ~0);
6520 x_font_min_bounds (font
, &w
, &h
);
6522 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6523 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6526 xassert (dpyinfo
->smallest_char_width
> 0
6527 && dpyinfo
->smallest_font_height
> 0);
6529 return (dpyinfo
->n_fonts
== 1
6530 || dpyinfo
->smallest_char_width
< old_width
6531 || dpyinfo
->smallest_font_height
< old_height
);
6535 /* Determine whether given string is a fully-specified XLFD: all 14
6536 fields are present, none is '*'. */
6539 is_fully_specified_xlfd (char *p
)
6547 for (i
= 0; i
< 13; i
++)
6549 q
= strchr (p
+ 1, '-');
6552 if (q
- p
== 2 && *(p
+ 1) == '*')
6557 if (strchr (p
+ 1, '-') != NULL
)
6560 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6567 const int kDefaultFontSize
= 9;
6570 /* XLoadQueryFont creates and returns an internal representation for a
6571 font in a MacFontStruct struct. There is really no concept
6572 corresponding to "loading" a font on the Mac. But we check its
6573 existence and find the font number and all other information for it
6574 and store them in the returned MacFontStruct. */
6576 static MacFontStruct
*
6577 XLoadQueryFont (Display
*dpy
, char *fontname
)
6579 int i
, size
, is_two_byte_font
, char_width
;
6582 SInt16 old_fontnum
, old_fontsize
;
6586 Style fontface
= normal
;
6587 MacFontStruct
*font
;
6588 FontInfo the_fontinfo
;
6589 char s_weight
[7], c_slant
;
6591 if (is_fully_specified_xlfd (fontname
))
6595 Lisp_Object matched_fonts
;
6597 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6598 if (NILP (matched_fonts
))
6600 name
= SDATA (XCAR (matched_fonts
));
6603 GetPort (&port
); /* save the current font number used */
6604 #if TARGET_API_MAC_CARBON
6605 old_fontnum
= GetPortTextFont (port
);
6606 old_fontsize
= GetPortTextSize (port
);
6607 old_fontface
= GetPortTextFace (port
);
6609 old_fontnum
= port
->txFont
;
6610 old_fontsize
= port
->txSize
;
6611 old_fontface
= port
->txFace
;
6614 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6615 size
= kDefaultFontSize
;
6617 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6618 if (strcmp (s_weight
, "bold") == 0)
6621 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6625 x_font_name_to_mac_font_name (name
, mfontname
);
6627 GetFNum (mfontname
, &fontnum
);
6631 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6633 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6634 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6636 font
->mac_fontnum
= fontnum
;
6637 font
->mac_fontsize
= size
;
6638 font
->mac_fontface
= fontface
;
6639 font
->mac_scriptcode
= FontToScript (fontnum
);
6641 /* Apple Japanese (SJIS) font is listed as both
6642 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6643 (Roman script) in init_font_name_table (). The latter should be
6644 treated as a one-byte font. */
6649 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6651 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6652 font
->mac_scriptcode
= smRoman
;
6655 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6656 font
->mac_scriptcode
== smTradChinese
||
6657 font
->mac_scriptcode
== smSimpChinese
||
6658 font
->mac_scriptcode
== smKorean
;
6662 TextFace (fontface
);
6664 GetFontInfo (&the_fontinfo
);
6666 font
->ascent
= the_fontinfo
.ascent
;
6667 font
->descent
= the_fontinfo
.descent
;
6669 font
->min_byte1
= 0;
6670 if (is_two_byte_font
)
6671 font
->max_byte1
= 1;
6673 font
->max_byte1
= 0;
6674 font
->min_char_or_byte2
= 0x20;
6675 font
->max_char_or_byte2
= 0xff;
6677 if (is_two_byte_font
)
6679 /* Use the width of an "ideographic space" of that font because
6680 the_fontinfo.widMax returns the wrong width for some fonts. */
6681 switch (font
->mac_scriptcode
)
6684 char_width
= StringWidth("\p\x81\x40");
6687 char_width
= StringWidth("\p\xa1\x40");
6690 char_width
= StringWidth("\p\xa1\xa1");
6693 char_width
= StringWidth("\p\xa1\xa1");
6698 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6699 returns 15 for 12-point Monaco! */
6700 char_width
= CharWidth ('m');
6702 font
->max_bounds
.rbearing
= char_width
;
6703 font
->max_bounds
.lbearing
= 0;
6704 font
->max_bounds
.width
= char_width
;
6705 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6706 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6708 font
->min_bounds
= font
->max_bounds
;
6710 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6711 font
->per_char
= NULL
;
6714 font
->per_char
= (XCharStruct
*)
6715 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6719 for (c
= 0x20; c
<= 0xff; c
++)
6721 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6722 font
->per_char
[c
- 0x20].width
=
6723 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6728 TextFont (old_fontnum
); /* restore previous font number, size and face */
6729 TextSize (old_fontsize
);
6730 TextFace (old_fontface
);
6736 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6737 pointer to the structure font_info while allocating it dynamically.
6738 If SIZE is 0, load any size of font.
6739 If loading is failed, return NULL. */
6742 x_load_font (f
, fontname
, size
)
6744 register char *fontname
;
6747 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6748 Lisp_Object font_names
;
6750 /* Get a list of all the fonts that match this name. Once we
6751 have a list of matching fonts, we compare them against the fonts
6752 we already have by comparing names. */
6753 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6755 if (!NILP (font_names
))
6760 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6761 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6762 if (dpyinfo
->font_table
[i
].name
6763 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6764 SDATA (XCAR (tail
)))
6765 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6766 SDATA (XCAR (tail
)))))
6767 return (dpyinfo
->font_table
+ i
);
6770 /* Load the font and add it to the table. */
6773 struct MacFontStruct
*font
;
6774 struct font_info
*fontp
;
6775 unsigned long value
;
6778 /* If we have found fonts by x_list_font, load one of them. If
6779 not, we still try to load a font by the name given as FONTNAME
6780 because XListFonts (called in x_list_font) of some X server has
6781 a bug of not finding a font even if the font surely exists and
6782 is loadable by XLoadQueryFont. */
6783 if (size
> 0 && !NILP (font_names
))
6784 fontname
= (char *) SDATA (XCAR (font_names
));
6786 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6790 /* Find a free slot in the font table. */
6791 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6792 if (dpyinfo
->font_table
[i
].name
== NULL
)
6795 /* If no free slot found, maybe enlarge the font table. */
6796 if (i
== dpyinfo
->n_fonts
6797 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6800 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6801 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6803 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6806 fontp
= dpyinfo
->font_table
+ i
;
6807 if (i
== dpyinfo
->n_fonts
)
6810 /* Now fill in the slots of *FONTP. */
6812 bzero (fontp
, sizeof (*fontp
));
6814 fontp
->font_idx
= i
;
6815 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6816 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6818 fontp
->full_name
= fontp
->name
;
6820 fontp
->size
= font
->max_bounds
.width
;
6821 fontp
->height
= FONT_HEIGHT (font
);
6823 /* For some font, ascent and descent in max_bounds field is
6824 larger than the above value. */
6825 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6826 if (max_height
> fontp
->height
)
6827 fontp
->height
= max_height
;
6830 /* The slot `encoding' specifies how to map a character
6831 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6832 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6833 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6834 2:0xA020..0xFF7F). For the moment, we don't know which charset
6835 uses this font. So, we set information in fontp->encoding[1]
6836 which is never used by any charset. If mapping can't be
6837 decided, set FONT_ENCODING_NOT_DECIDED. */
6838 if (font
->mac_scriptcode
== smJapanese
)
6839 fontp
->encoding
[1] = 4;
6843 = (font
->max_byte1
== 0
6845 ? (font
->min_char_or_byte2
< 0x80
6846 ? (font
->max_char_or_byte2
< 0x80
6847 ? 0 /* 0x20..0x7F */
6848 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6849 : 1) /* 0xA0..0xFF */
6851 : (font
->min_byte1
< 0x80
6852 ? (font
->max_byte1
< 0x80
6853 ? (font
->min_char_or_byte2
< 0x80
6854 ? (font
->max_char_or_byte2
< 0x80
6855 ? 0 /* 0x2020..0x7F7F */
6856 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6857 : 3) /* 0x20A0..0x7FFF */
6858 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6859 : (font
->min_char_or_byte2
< 0x80
6860 ? (font
->max_char_or_byte2
< 0x80
6861 ? 2 /* 0xA020..0xFF7F */
6862 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6863 : 1))); /* 0xA0A0..0xFFFF */
6866 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6867 fontp
->baseline_offset
6868 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6869 ? (long) value
: 0);
6870 fontp
->relative_compose
6871 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6872 ? (long) value
: 0);
6873 fontp
->default_ascent
6874 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6875 ? (long) value
: 0);
6877 fontp
->baseline_offset
= 0;
6878 fontp
->relative_compose
= 0;
6879 fontp
->default_ascent
= 0;
6882 /* Set global flag fonts_changed_p to non-zero if the font loaded
6883 has a character with a smaller width than any other character
6884 before, or if the font loaded has a smalle>r height than any
6885 other font loaded before. If this happens, it will make a
6886 glyph matrix reallocation necessary. */
6887 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6894 /* Return a pointer to struct font_info of a font named FONTNAME for
6895 frame F. If no such font is loaded, return NULL. */
6898 x_query_font (f
, fontname
)
6900 register char *fontname
;
6902 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6905 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6906 if (dpyinfo
->font_table
[i
].name
6907 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6908 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6909 return (dpyinfo
->font_table
+ i
);
6914 /* Find a CCL program for a font specified by FONTP, and set the member
6915 `encoder' of the structure. */
6918 x_find_ccl_program (fontp
)
6919 struct font_info
*fontp
;
6921 Lisp_Object list
, elt
;
6923 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6927 && STRINGP (XCAR (elt
))
6928 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6934 struct ccl_program
*ccl
6935 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6937 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6940 fontp
->font_encoder
= ccl
;
6946 /* The Mac Event loop code */
6950 #include <Quickdraw.h>
6951 #include <Balloons.h>
6952 #include <Devices.h>
6954 #include <Gestalt.h>
6956 #include <Processes.h>
6958 #include <ToolUtils.h>
6959 #include <TextUtils.h>
6960 #include <Dialogs.h>
6963 #include <TextEncodingConverter.h>
6964 #include <Resources.h>
6969 #endif /* ! MAC_OSX */
6974 #define WINDOW_RESOURCE 128
6975 #define TERM_WINDOW_RESOURCE 129
6977 #define DEFAULT_NUM_COLS 80
6979 #define MIN_DOC_SIZE 64
6980 #define MAX_DOC_SIZE 32767
6982 /* sleep time for WaitNextEvent */
6983 #define WNE_SLEEP_AT_SUSPEND 10
6984 #define WNE_SLEEP_AT_RESUME 1
6986 /* true when cannot handle any Mac OS events */
6987 static int handling_window_update
= 0;
6990 /* the flag appl_is_suspended is used both for determining the sleep
6991 time to be passed to WaitNextEvent and whether the cursor should be
6992 drawn when updating the display. The cursor is turned off when
6993 Emacs is suspended. Redrawing it is unnecessary and what needs to
6994 be done depends on whether the cursor lies inside or outside the
6995 redraw region. So we might as well skip drawing it when Emacs is
6997 static Boolean app_is_suspended
= false;
6998 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7001 #define EXTRA_STACK_ALLOC (256 * 1024)
7003 #define ARGV_STRING_LIST_ID 129
7004 #define ABOUT_ALERT_ID 128
7005 #define RAM_TOO_LARGE_ALERT_ID 129
7007 Boolean terminate_flag
= false;
7009 /* Contains the string "reverse", which is a constant for mouse button emu.*/
7010 Lisp_Object Qreverse
;
7012 /* True if using command key as meta key. */
7013 Lisp_Object Vmac_command_key_is_meta
;
7015 /* Modifier associated with the option key, or nil for normal behavior. */
7016 Lisp_Object Vmac_option_modifier
;
7018 /* True if the ctrl and meta keys should be reversed. */
7019 Lisp_Object Vmac_reverse_ctrl_meta
;
7021 /* True if the option and command modifiers should be used to emulate
7022 a three button mouse */
7023 Lisp_Object Vmac_emulate_three_button_mouse
;
7025 #if USE_CARBON_EVENTS
7026 /* True if the mouse wheel button (i.e. button 4) should map to
7027 mouse-2, instead of mouse-3. */
7028 Lisp_Object Vmac_wheel_button_is_mouse_2
;
7030 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
7031 for processing before Emacs sees it. */
7032 Lisp_Object Vmac_pass_command_to_system
;
7034 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
7035 for processing before Emacs sees it. */
7036 Lisp_Object Vmac_pass_control_to_system
;
7039 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
7040 to this text encoding */
7041 int mac_keyboard_text_encoding
;
7042 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
7044 /* Set in term/mac-win.el to indicate that event loop can now generate
7045 drag and drop events. */
7046 Lisp_Object Qmac_ready_for_drag_n_drop
;
7048 Lisp_Object drag_and_drop_file_list
;
7050 Point saved_menu_event_location
;
7052 #if !TARGET_API_MAC_CARBON
7053 /* Place holder for the default arrow cursor. */
7054 CursPtr arrow_cursor
;
7058 static void init_required_apple_events (void);
7060 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
7062 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
7063 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
7064 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
7067 static OSErr
init_mac_drag_n_drop ();
7068 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
7070 #if USE_CARBON_EVENTS
7071 /* Preliminary Support for the OSX Services Menu */
7072 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
7073 static void init_service_handler ();
7076 extern void init_emacs_passwd_dir ();
7077 extern int emacs_main (int, char **, char **);
7078 extern void check_alarm ();
7080 extern void initialize_applescript();
7081 extern void terminate_applescript();
7084 #if USE_CARBON_EVENTS
7085 mac_to_emacs_modifiers (UInt32 mods
)
7087 mac_to_emacs_modifiers (EventModifiers mods
)
7090 unsigned int result
= 0;
7091 if (mods
& macShiftKey
)
7092 result
|= shift_modifier
;
7093 if (mods
& macCtrlKey
)
7094 result
|= ctrl_modifier
;
7095 if (mods
& macMetaKey
)
7096 result
|= meta_modifier
;
7097 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
7098 result
|= alt_modifier
;
7099 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
7100 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
7102 result
|= XUINT(val
);
7109 mac_get_emulated_btn ( UInt32 modifiers
)
7112 if (!NILP (Vmac_emulate_three_button_mouse
)) {
7113 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
7114 if (modifiers
& cmdKey
)
7115 result
= cmdIs3
? 2 : 1;
7116 else if (modifiers
& optionKey
)
7117 result
= cmdIs3
? 1 : 2;
7122 #if USE_CARBON_EVENTS
7123 /* Obtains the event modifiers from the event ref and then calls
7124 mac_to_emacs_modifiers. */
7126 mac_event_to_emacs_modifiers (EventRef eventRef
)
7129 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7130 sizeof (UInt32
), NULL
, &mods
);
7131 if (!NILP (Vmac_emulate_three_button_mouse
) &&
7132 GetEventClass(eventRef
) == kEventClassMouse
)
7134 mods
&= ~(optionKey
| cmdKey
);
7136 return mac_to_emacs_modifiers (mods
);
7139 /* Given an event ref, return the code to use for the mouse button
7140 code in the emacs input_event. */
7142 mac_get_mouse_btn (EventRef ref
)
7144 EventMouseButton result
= kEventMouseButtonPrimary
;
7145 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7146 sizeof (EventMouseButton
), NULL
, &result
);
7149 case kEventMouseButtonPrimary
:
7150 if (NILP (Vmac_emulate_three_button_mouse
))
7154 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7155 sizeof (UInt32
), NULL
, &mods
);
7156 return mac_get_emulated_btn(mods
);
7158 case kEventMouseButtonSecondary
:
7159 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7160 case kEventMouseButtonTertiary
:
7161 case 4: /* 4 is the number for the mouse wheel button */
7162 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7168 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7169 events. However the click of the mouse wheel is not converted to a
7170 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7171 checks to see if it is a mouse up or down carbon event that has not
7172 been converted, and if so, converts it by hand (to be picked up in
7173 the XTread_socket loop). */
7174 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7176 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7177 /* Do special case for mouse wheel button. */
7178 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7180 UInt32 kind
= GetEventKind (eventRef
);
7181 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7183 eventRec
->what
= mouseDown
;
7186 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7188 eventRec
->what
= mouseUp
;
7193 /* Need where and when. */
7195 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7196 typeQDPoint
, NULL
, sizeof (Point
),
7197 NULL
, &eventRec
->where
);
7198 /* Use two step process because new event modifiers are
7199 32-bit and old are 16-bit. Currently, only loss is
7201 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7202 typeUInt32
, NULL
, sizeof (UInt32
),
7204 eventRec
->modifiers
= mods
;
7206 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7217 Handle menubar_handle
;
7218 MenuHandle menu_handle
;
7220 menubar_handle
= GetNewMBar (128);
7221 if(menubar_handle
== NULL
)
7223 SetMenuBar (menubar_handle
);
7226 menu_handle
= GetMenuHandle (M_APPLE
);
7227 if(menu_handle
!= NULL
)
7228 AppendResMenu (menu_handle
,'DRVR');
7235 do_init_managers (void)
7237 #if !TARGET_API_MAC_CARBON
7238 InitGraf (&qd
.thePort
);
7240 FlushEvents (everyEvent
, 0);
7245 #endif /* !TARGET_API_MAC_CARBON */
7248 #if !TARGET_API_MAC_CARBON
7249 arrow_cursor
= &qd
.arrow
;
7251 /* set up some extra stack space for use by emacs */
7252 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7254 /* MaxApplZone must be called for AppleScript to execute more
7255 complicated scripts */
7258 #endif /* !TARGET_API_MAC_CARBON */
7262 do_check_ram_size (void)
7264 SInt32 physical_ram_size
, logical_ram_size
;
7266 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7267 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7268 || physical_ram_size
> (1 << VALBITS
)
7269 || logical_ram_size
> (1 << VALBITS
))
7271 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7277 do_window_update (WindowPtr win
)
7279 struct frame
*f
= mac_window_to_frame (win
);
7281 if (win
== tip_window
)
7282 /* The tooltip has been drawn already. Avoid the
7283 SET_FRAME_GARBAGED below. */
7288 if (f
->async_visible
== 0)
7290 f
->async_visible
= 1;
7291 f
->async_iconified
= 0;
7292 SET_FRAME_GARBAGED (f
);
7294 /* An update event is equivalent to MapNotify on X, so report
7295 visibility changes properly. */
7296 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7297 /* Force a redisplay sooner or later to update the
7298 frame titles in case this is the second frame. */
7299 record_asynch_buffer_change ();
7304 handling_window_update
= 1;
7306 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7308 expose_frame (f
, 0, 0, 0, 0);
7310 handling_window_update
= 0;
7317 is_emacs_window (WindowPtr win
)
7319 Lisp_Object tail
, frame
;
7324 FOR_EACH_FRAME (tail
, frame
)
7325 if (FRAME_MAC_P (XFRAME (frame
)))
7326 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7335 /* Window-activate events will do the job. */
7340 wp
= front_emacs_window ();
7343 f
= mac_window_to_frame (wp
);
7347 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7348 activate_scroll_bars (f
);
7352 app_is_suspended
= false;
7353 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7360 /* Window-deactivate events will do the job. */
7365 wp
= front_emacs_window ();
7368 f
= mac_window_to_frame (wp
);
7370 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7372 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7373 deactivate_scroll_bars (f
);
7377 app_is_suspended
= true;
7378 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7384 do_mouse_moved (mouse_pos
, f
)
7388 WindowPtr wp
= front_emacs_window ();
7389 struct x_display_info
*dpyinfo
;
7393 *f
= mac_window_to_frame (wp
);
7394 dpyinfo
= FRAME_MAC_DISPLAY_INFO (*f
);
7396 if (dpyinfo
->mouse_face_hidden
)
7398 dpyinfo
->mouse_face_hidden
= 0;
7399 clear_mouse_face (dpyinfo
);
7402 SetPortWindowPort (wp
);
7404 GlobalToLocal (&mouse_pos
);
7406 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
7407 x_scroll_bar_note_movement (tracked_scroll_bar
,
7409 - XINT (tracked_scroll_bar
->top
),
7410 TickCount() * (1000 / 60));
7412 note_mouse_movement (*f
, &mouse_pos
);
7418 do_apple_menu (SInt16 menu_item
)
7420 #if !TARGET_API_MAC_CARBON
7422 SInt16 da_driver_refnum
;
7424 if (menu_item
== I_ABOUT
)
7425 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7428 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7429 da_driver_refnum
= OpenDeskAcc (item_name
);
7431 #endif /* !TARGET_API_MAC_CARBON */
7435 do_menu_choice (SInt32 menu_choice
)
7437 SInt16 menu_id
, menu_item
;
7439 menu_id
= HiWord (menu_choice
);
7440 menu_item
= LoWord (menu_choice
);
7448 do_apple_menu (menu_item
);
7453 struct frame
*f
= mac_window_to_frame (front_emacs_window ());
7454 MenuHandle menu
= GetMenuHandle (menu_id
);
7459 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7460 menubar_selection_callback (f
, refcon
);
7469 /* Handle drags in size box. Based on code contributed by Ben
7470 Mesander and IM - Window Manager A. */
7473 do_grow_window (WindowPtr w
, EventRecord
*e
)
7478 struct frame
*f
= mac_window_to_frame (w
);
7480 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7482 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7484 /* see if it really changed size */
7487 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7488 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7490 x_set_window_size (f
, 0, columns
, rows
);
7495 /* Handle clicks in zoom box. Calculation of "standard state" based
7496 on code in IM - Window Manager A and code contributed by Ben
7497 Mesander. The standard state of an Emacs window is 80-characters
7498 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7501 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7504 Rect zoom_rect
, port_rect
;
7506 int w_title_height
, columns
, rows
;
7507 struct frame
*f
= mac_window_to_frame (w
);
7509 #if TARGET_API_MAC_CARBON
7511 Point standard_size
;
7513 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7514 standard_size
.v
= FRAME_MAC_DISPLAY_INFO (f
)->height
;
7516 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
7517 zoom_in_or_out
= inZoomIn
;
7520 /* Adjust the standard size according to character boundaries. */
7522 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
7523 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7524 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
7525 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7526 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
7527 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
7528 && port_rect
.left
== zoom_rect
.left
7529 && port_rect
.top
== zoom_rect
.top
)
7530 zoom_in_or_out
= inZoomIn
;
7532 zoom_in_or_out
= inZoomOut
;
7535 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
7537 #else /* not TARGET_API_MAC_CARBON */
7538 GetPort (&save_port
);
7540 SetPortWindowPort (w
);
7542 /* Clear window to avoid flicker. */
7543 EraseRect (&(w
->portRect
));
7544 if (zoom_in_or_out
== inZoomOut
)
7546 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7547 LocalToGlobal (&top_left
);
7549 /* calculate height of window's title bar */
7550 w_title_height
= top_left
.v
- 1
7551 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7553 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7554 zoom_rect
= qd
.screenBits
.bounds
;
7555 zoom_rect
.top
+= w_title_height
;
7556 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7558 zoom_rect
.right
= zoom_rect
.left
7559 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7561 /* Adjust the standard size according to character boundaries. */
7562 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
7564 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
7566 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7570 ZoomWindow (w
, zoom_in_or_out
, w
== front_emacs_window ());
7572 SetPort (save_port
);
7573 #endif /* not TARGET_API_MAC_CARBON */
7575 /* retrieve window size and update application values */
7576 #if TARGET_API_MAC_CARBON
7577 GetWindowPortBounds (w
, &port_rect
);
7579 port_rect
= w
->portRect
;
7581 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7582 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7583 x_set_window_size (f
, 0, columns
, rows
);
7584 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
7587 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7589 init_mac_drag_n_drop ()
7591 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7595 /* Intialize AppleEvent dispatcher table for the required events. */
7597 init_required_apple_events ()
7602 /* Make sure we have apple events before starting. */
7603 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7607 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7610 #if TARGET_API_MAC_CARBON
7611 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7612 NewAEEventHandlerUPP
7613 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7616 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7617 NewAEEventHandlerProc
7618 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7624 #if TARGET_API_MAC_CARBON
7625 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7626 NewAEEventHandlerUPP
7627 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7630 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7631 NewAEEventHandlerProc
7632 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7638 #if TARGET_API_MAC_CARBON
7639 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7640 NewAEEventHandlerUPP
7641 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7644 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7645 NewAEEventHandlerProc
7646 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7652 #if TARGET_API_MAC_CARBON
7653 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7654 NewAEEventHandlerUPP
7655 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7658 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7659 NewAEEventHandlerProc
7660 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7667 #if USE_CARBON_EVENTS
7670 init_service_handler ()
7672 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7673 {kEventClassService
, kEventServiceCopy
},
7674 {kEventClassService
, kEventServicePaste
}};
7675 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7676 3, specs
, NULL
, NULL
);
7680 MAC_TODO: Check to see if this is called by AEProcessDesc...
7683 mac_handle_service_event (EventHandlerCallRef callRef
,
7684 EventRef event
, void *data
)
7686 OSStatus err
= noErr
;
7687 switch (GetEventKind (event
))
7689 case kEventServiceGetTypes
:
7691 CFMutableArrayRef copyTypes
, pasteTypes
;
7693 Boolean selection
= true;
7695 GetEventParameter(event, kEventParamServicePasteTypes,
7696 typeCFMutableArrayRef, NULL,
7697 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7699 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7700 typeCFMutableArrayRef
, NULL
,
7701 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7702 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7704 CFArrayAppendValue (copyTypes
, type
);
7705 //CFArrayAppendValue (pasteTypes, type);
7709 case kEventServiceCopy
:
7711 ScrapRef currentScrap
, specificScrap
;
7715 GetCurrentScrap (¤tScrap
);
7717 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7720 void *buffer
= xmalloc (byteCount
);
7723 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7724 sizeof (ScrapRef
), NULL
, &specificScrap
);
7726 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7727 &byteCount
, buffer
);
7729 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7730 kScrapFlavorMaskNone
, byteCount
, buffer
);
7736 case kEventServicePaste
:
7739 // Get the current location
7741 ScrapRef specificScrap;
7742 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7743 sizeof(ScrapRef), NULL, &specificScrap);
7744 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7746 void * buffer = xmalloc(byteCount);
7747 if (buffer != NULL ) {
7748 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7749 &byteCount, buffer);
7751 // Actually place in the buffer
7753 // Get the current "selection" string here
7766 /* Open Application Apple Event */
7768 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7774 /* Defined in mac.c. */
7776 path_from_vol_dir_name (char *, int, short, long, char *);
7779 /* Called when we receive an AppleEvent with an ID of
7780 "kAEOpenDocuments". This routine gets the direct parameter,
7781 extracts the FSSpecs in it, and puts their names on a list. */
7783 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7788 DescType actual_type
;
7791 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7793 goto descriptor_error_exit
;
7795 /* Check to see that we got all of the required parameters from the
7796 event descriptor. For an 'odoc' event this should just be the
7798 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7799 &actual_type
, (Ptr
) &keyword
,
7800 sizeof (keyword
), &actual_size
);
7801 /* No error means that we found some unused parameters.
7802 errAEDescNotFound means that there are no more parameters. If we
7803 get an error code other than that, flag it. */
7804 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7806 err
= errAEEventNotHandled
;
7811 /* Got all the parameters we need. Now, go through the direct
7812 object list and parse it up. */
7814 long num_files_to_open
;
7816 err
= AECountItems (&the_desc
, &num_files_to_open
);
7821 /* AE file list is one based so just use that for indexing here. */
7822 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7825 Str255 path_name
, unix_path_name
;
7830 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7831 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7832 if (err
!= noErr
) break;
7835 err
= FSpMakeFSRef (&fs
, &fref
);
7836 if (err
!= noErr
) break;
7838 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7840 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7842 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7844 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7845 drag_and_drop_file_list
);
7851 /* Nuke the coerced file list in any case */
7852 err2
= AEDisposeDesc(&the_desc
);
7854 descriptor_error_exit
:
7855 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7861 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7862 DragReference theDrag
)
7866 FlavorFlags theFlags
;
7869 ItemReference theItem
;
7872 Size size
= sizeof (HFSFlavor
);
7874 drag_and_drop_file_list
= Qnil
;
7875 GetDragMouse (theDrag
, &mouse
, 0L);
7876 CountDragItems (theDrag
, &items
);
7877 for (index
= 1; index
<= items
; index
++)
7879 /* Only handle file references. */
7880 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7881 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7882 if (result
== noErr
)
7889 Str255 unix_path_name
;
7890 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7892 /* Use Carbon routines, otherwise it converts the file name
7893 to /Macintosh HD/..., which is not correct. */
7894 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7895 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7897 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7898 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7899 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7901 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7902 drag_and_drop_file_list
);
7907 /* If there are items in the list, construct an event and post it to
7908 the queue like an interrupt using kbd_buffer_store_event. */
7909 if (!NILP (drag_and_drop_file_list
))
7911 struct input_event event
;
7913 struct frame
*f
= mac_window_to_frame (window
);
7914 SetPortWindowPort (window
);
7915 GlobalToLocal (&mouse
);
7917 event
.kind
= DRAG_N_DROP_EVENT
;
7919 event
.modifiers
= 0;
7920 event
.timestamp
= TickCount () * (1000 / 60);
7921 XSETINT (event
.x
, mouse
.h
);
7922 XSETINT (event
.y
, mouse
.v
);
7923 XSETFRAME (frame
, f
);
7924 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7926 /* Post to the interrupt queue */
7927 kbd_buffer_store_event (&event
);
7928 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7930 ProcessSerialNumber psn
;
7931 GetCurrentProcess (&psn
);
7932 SetFrontProcess (&psn
);
7938 /* Print Document Apple Event */
7940 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7942 return errAEEventNotHandled
;
7947 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7949 /* FixMe: Do we need an unwind-protect or something here? And what
7950 do we do about unsaved files. Currently just forces quit rather
7951 than doing recursive callback to get user input. */
7953 terminate_flag
= true;
7955 /* Fkill_emacs doesn't return. We have to return. (TI) */
7962 profiler_exit_proc ()
7964 ProfilerDump ("\pEmacs.prof");
7969 /* These few functions implement Emacs as a normal Mac application
7970 (almost): set up the heap and the Toolbox, handle necessary
7971 system events plus a few simple menu events. They also set up
7972 Emacs's access to functions defined in the rest of this file.
7973 Emacs uses function hooks to perform all its terminal I/O. A
7974 complete list of these functions appear in termhooks.h. For what
7975 they do, read the comments there and see also w32term.c and
7976 xterm.c. What's noticeably missing here is the event loop, which
7977 is normally present in most Mac application. After performing the
7978 necessary Mac initializations, main passes off control to
7979 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7980 mac_read_socket (defined further below) to read input. This is
7981 where WaitNextEvent is called to process Mac events. This is also
7982 where check_alarm in sysdep.c is called to simulate alarm signals.
7983 This makes the cursor jump back to its correct position after
7984 briefly jumping to that of the matching parenthesis, print useful
7985 hints and prompts in the minibuffer after the user stops typing for
7988 #if !TARGET_API_MAC_CARBON
7993 #if __profile__ /* is the profiler on? */
7994 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7999 /* set creator and type for files created by MSL */
8004 do_init_managers ();
8009 do_check_ram_size ();
8012 init_emacs_passwd_dir ();
8016 initialize_applescript ();
8018 init_required_apple_events ();
8024 /* set up argv array from STR# resource */
8025 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8029 /* free up AppleScript resources on exit */
8030 atexit (terminate_applescript
);
8032 #if __profile__ /* is the profiler on? */
8033 atexit (profiler_exit_proc
);
8036 /* 3rd param "envp" never used in emacs_main */
8037 (void) emacs_main (argc
, argv
, 0);
8040 /* Never reached - real exit in Fkill_emacs */
8045 /* Table for translating Mac keycode to X keysym values. Contributed
8046 by Sudhir Shenoy. */
8047 static unsigned char keycode_to_xkeysym_table
[] = {
8048 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8049 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8050 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8052 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8053 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
8054 /*0x38*/ 0, 0, 0, 0,
8055 /*0x3C*/ 0, 0, 0, 0,
8057 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8058 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
8059 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8060 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8062 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8063 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8064 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8065 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8067 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8068 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8069 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8070 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8072 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8073 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8074 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8075 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8079 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8081 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8082 return *xKeySym
!= 0;
8085 /* Emacs calls this whenever it wants to read an input event from the
8088 XTread_socket (sd
, expected
, hold_quit
)
8090 struct input_event
*hold_quit
;
8092 struct input_event inev
;
8094 #if USE_CARBON_EVENTS
8096 EventTargetRef toolbox_dispatcher
= GetEventDispatcherTarget ();
8098 EventMask event_mask
;
8101 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8103 if (interrupt_input_blocked
)
8105 interrupt_input_pending
= 1;
8109 interrupt_input_pending
= 0;
8112 /* So people can tell when we have read the available input. */
8113 input_signal_count
++;
8115 /* Don't poll for events to process (specifically updateEvt) if
8116 window update currently already in progress. A call to redisplay
8117 (in do_window_update) can be preempted by another call to
8118 redisplay, causing blank regions to be left on the screen and the
8119 cursor to be left at strange places. */
8120 if (handling_window_update
)
8127 Fkill_emacs (make_number (1));
8129 #if !USE_CARBON_EVENTS
8130 event_mask
= everyEvent
;
8131 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8132 event_mask
-= highLevelEventMask
;
8134 while (WaitNextEvent (event_mask
, &er
, 0L, NULL
))
8135 #else /* USE_CARBON_EVENTS */
8136 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
8137 kEventRemoveFromQueue
, &eventRef
))
8138 #endif /* USE_CARBON_EVENTS */
8143 /* It is necessary to set this (additional) argument slot of an
8144 event to nil because keyboard.c protects incompletely
8145 processed event from being garbage collected by placing them
8146 in the kbd_buffer_gcpro vector. */
8148 inev
.kind
= NO_EVENT
;
8151 #if USE_CARBON_EVENTS
8152 /* Handle new events */
8153 if (!mac_convert_event_ref (eventRef
, &er
))
8154 switch (GetEventClass (eventRef
))
8156 case kEventClassWindow
:
8157 if (GetEventKind (eventRef
) == kEventWindowBoundsChanged
)
8159 WindowPtr window_ptr
;
8160 GetEventParameter(eventRef
, kEventParamDirectObject
,
8161 typeWindowRef
, NULL
, sizeof(WindowPtr
),
8163 f
= mac_window_to_frame (window_ptr
);
8164 if (f
&& !f
->async_iconified
)
8165 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8166 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8169 case kEventClassMouse
:
8170 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8174 WindowPtr window_ptr
= front_emacs_window ();
8176 if (!IsValidWindowPtr (window_ptr
))
8182 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8183 typeSInt32
, NULL
, sizeof (SInt32
),
8185 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8186 typeQDPoint
, NULL
, sizeof (Point
),
8188 inev
.kind
= WHEEL_EVENT
;
8190 inev
.modifiers
= (mac_event_to_emacs_modifiers (eventRef
)
8191 | ((delta
< 0) ? down_modifier
8193 SetPortWindowPort (window_ptr
);
8194 GlobalToLocal (&point
);
8195 XSETINT (inev
.x
, point
.h
);
8196 XSETINT (inev
.y
, point
.v
);
8197 XSETFRAME (inev
.frame_or_window
,
8198 mac_window_to_frame (window_ptr
));
8199 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8202 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8206 /* Send the event to the appropriate receiver. */
8207 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
8210 #endif /* USE_CARBON_EVENTS */
8216 WindowPtr window_ptr
;
8220 #if USE_CARBON_EVENTS
8221 /* This is needed to send mouse events like aqua window
8222 buttons to the correct handler. */
8223 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8224 != eventNotHandledErr
)
8228 if (dpyinfo
->grabbed
&& last_mouse_frame
8229 && FRAME_LIVE_P (last_mouse_frame
))
8231 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
8232 part_code
= inContent
;
8236 part_code
= FindWindow (er
.where
, &window_ptr
);
8237 if (tip_window
&& window_ptr
== tip_window
)
8239 HideWindow (tip_window
);
8240 part_code
= FindWindow (er
.where
, &window_ptr
);
8244 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
8250 f
= mac_window_to_frame (front_emacs_window ());
8251 saved_menu_event_location
= er
.where
;
8252 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8253 XSETFRAME (inev
.frame_or_window
, f
);
8257 if (window_ptr
!= front_emacs_window ())
8258 SelectWindow (window_ptr
);
8261 SInt16 control_part_code
;
8263 Point mouse_loc
= er
.where
;
8265 f
= mac_window_to_frame (window_ptr
);
8266 /* convert to local coordinates of new window */
8267 SetPortWindowPort (window_ptr
);
8269 GlobalToLocal (&mouse_loc
);
8270 #if TARGET_API_MAC_CARBON
8271 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8272 &control_part_code
);
8274 control_part_code
= FindControl (mouse_loc
, window_ptr
,
8278 #if USE_CARBON_EVENTS
8279 inev
.code
= mac_get_mouse_btn (eventRef
);
8280 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8282 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
8283 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8285 XSETINT (inev
.x
, mouse_loc
.h
);
8286 XSETINT (inev
.y
, mouse_loc
.v
);
8287 inev
.timestamp
= er
.when
* (1000 / 60);
8288 /* ticks to milliseconds */
8290 if (dpyinfo
->grabbed
&& tracked_scroll_bar
8291 #if TARGET_API_MAC_CARBON
8294 || control_part_code
!= 0
8298 struct scroll_bar
*bar
;
8300 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
8302 bar
= tracked_scroll_bar
;
8303 control_part_code
= kControlIndicatorPart
;
8306 bar
= (struct scroll_bar
*) GetControlReference (ch
);
8307 x_scroll_bar_handle_click (bar
, control_part_code
,
8309 if (er
.what
== mouseDown
8310 && control_part_code
== kControlIndicatorPart
)
8311 tracked_scroll_bar
= bar
;
8313 tracked_scroll_bar
= NULL
;
8318 int x
= mouse_loc
.h
;
8319 int y
= mouse_loc
.v
;
8321 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
8322 if (EQ (window
, f
->tool_bar_window
))
8324 if (er
.what
== mouseDown
)
8325 handle_tool_bar_click (f
, x
, y
, 1, 0);
8327 handle_tool_bar_click (f
, x
, y
, 0,
8333 XSETFRAME (inev
.frame_or_window
, f
);
8334 inev
.kind
= MOUSE_CLICK_EVENT
;
8338 if (er
.what
== mouseDown
)
8340 dpyinfo
->grabbed
|= (1 << inev
.code
);
8341 last_mouse_frame
= f
;
8342 /* Ignore any mouse motion that happened
8343 before this event; any subsequent
8344 mouse-movement Emacs events should reflect
8345 only motion after the ButtonPress. */
8350 last_tool_bar_item
= -1;
8354 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
8355 /* If a button is released though it was not
8356 previously pressed, that would be because
8357 of multi-button emulation. */
8358 dpyinfo
->grabbed
= 0;
8360 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
8366 inev
.modifiers
|= down_modifier
;
8369 inev
.modifiers
|= up_modifier
;
8376 #if TARGET_API_MAC_CARBON
8377 DragWindow (window_ptr
, er
.where
, NULL
);
8378 #else /* not TARGET_API_MAC_CARBON */
8379 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8380 #endif /* not TARGET_API_MAC_CARBON */
8381 /* Update the frame parameters. */
8383 struct frame
*f
= mac_window_to_frame (window_ptr
);
8385 if (f
&& !f
->async_iconified
)
8386 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8391 if (TrackGoAway (window_ptr
, er
.where
))
8393 inev
.kind
= DELETE_WINDOW_EVENT
;
8394 XSETFRAME (inev
.frame_or_window
,
8395 mac_window_to_frame (window_ptr
));
8399 /* window resize handling added --ben */
8401 do_grow_window (window_ptr
, &er
);
8404 /* window zoom handling added --ben */
8407 if (TrackBox (window_ptr
, er
.where
, part_code
))
8408 do_zoom_window (window_ptr
, part_code
);
8418 #if USE_CARBON_EVENTS
8419 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8420 != eventNotHandledErr
)
8423 do_window_update ((WindowPtr
) er
.message
);
8427 #if USE_CARBON_EVENTS
8428 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8429 != eventNotHandledErr
)
8432 switch ((er
.message
>> 24) & 0x000000FF)
8434 case suspendResumeMessage
:
8435 if ((er
.message
& resumeFlag
) == 1)
8441 case mouseMovedMessage
:
8442 previous_help_echo_string
= help_echo_string
;
8443 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
8446 do_mouse_moved (er
.where
, &f
);
8448 /* If the contents of the global variable
8449 help_echo_string has changed, generate a
8451 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
8459 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
8461 #if USE_CARBON_EVENTS
8462 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8463 != eventNotHandledErr
)
8466 if (window_ptr
== tip_window
)
8468 HideWindow (tip_window
);
8472 if (!is_emacs_window (window_ptr
))
8475 f
= mac_window_to_frame (window_ptr
);
8477 if ((er
.modifiers
& activeFlag
) != 0)
8479 /* A window has been activated */
8480 Point mouse_loc
= er
.where
;
8482 x_new_focus_frame (dpyinfo
, f
);
8483 activate_scroll_bars (f
);
8485 SetPortWindowPort (window_ptr
);
8486 GlobalToLocal (&mouse_loc
);
8487 /* Window-activated event counts as mouse movement,
8488 so update things that depend on mouse position. */
8489 note_mouse_movement (mac_window_to_frame (window_ptr
),
8494 /* A window has been deactivated */
8495 dpyinfo
->grabbed
= 0;
8497 if (f
== dpyinfo
->x_focus_frame
)
8499 x_new_focus_frame (dpyinfo
, 0);
8500 deactivate_scroll_bars (f
);
8504 if (f
== dpyinfo
->mouse_face_mouse_frame
)
8506 /* If we move outside the frame, then we're
8507 certainly no longer on any text in the
8509 clear_mouse_face (dpyinfo
);
8510 dpyinfo
->mouse_face_mouse_frame
= 0;
8513 /* Generate a nil HELP_EVENT to cancel a help-echo.
8514 Do it only if there's something to cancel.
8515 Otherwise, the startup message is cleared when the
8516 mouse leaves the frame. */
8517 if (any_help_event_p
)
8526 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8529 #if USE_CARBON_EVENTS
8530 /* When using Carbon Events, we need to pass raw keyboard
8531 events to the TSM ourselves. If TSM handles it, it
8532 will pass back noErr, otherwise it will pass back
8533 "eventNotHandledErr" and we can process it
8535 if ((!NILP (Vmac_pass_command_to_system
)
8536 || !(er
.modifiers
& cmdKey
))
8537 && (!NILP (Vmac_pass_control_to_system
)
8538 || !(er
.modifiers
& controlKey
)))
8539 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
8540 != eventNotHandledErr
)
8544 #if TARGET_API_MAC_CARBON
8545 if (!IsValidWindowPtr (front_emacs_window ()))
8554 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
8556 clear_mouse_face (dpyinfo
);
8557 dpyinfo
->mouse_face_hidden
= 1;
8560 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8562 inev
.code
= 0xff00 | xkeysym
;
8563 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8567 if (er
.modifiers
& (controlKey
|
8568 (NILP (Vmac_command_key_is_meta
) ? optionKey
8571 /* This code comes from Keyboard Resource,
8572 Appendix C of IM - Text. This is necessary
8573 since shift is ignored in KCHR table
8574 translation when option or command is pressed.
8575 It also does not translate correctly
8576 control-shift chars like C-% so mask off shift
8578 int new_modifiers
= er
.modifiers
& 0xe600;
8579 /* mask off option and command */
8580 int new_keycode
= keycode
| new_modifiers
;
8581 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8582 unsigned long some_state
= 0;
8583 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8584 &some_state
) & 0xff;
8585 } else if (!NILP(Vmac_option_modifier
) && (er
.modifiers
& optionKey
))
8587 /* When using the option key as an emacs modifier, convert
8588 the pressed key code back to one without the Mac option
8589 modifier applied. */
8590 int new_modifiers
= er
.modifiers
& ~optionKey
;
8591 int new_keycode
= keycode
| new_modifiers
;
8592 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8593 unsigned long some_state
= 0;
8594 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8595 &some_state
) & 0xff;
8598 inev
.code
= er
.message
& charCodeMask
;
8599 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8603 /* If variable mac-convert-keyboard-input-to-latin-1 is
8604 non-nil, convert non-ASCII characters typed at the Mac
8605 keyboard (presumed to be in the Mac Roman encoding) to
8606 iso-latin-1 encoding before they are passed to Emacs.
8607 This enables the Mac keyboard to be used to enter
8608 non-ASCII iso-latin-1 characters directly. */
8609 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8610 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8612 static TECObjectRef converter
= NULL
;
8613 OSStatus the_err
= noErr
;
8614 OSStatus convert_status
= noErr
;
8616 if (converter
== NULL
)
8618 the_err
= TECCreateConverter (&converter
,
8619 kTextEncodingMacRoman
,
8620 mac_keyboard_text_encoding
);
8621 current_mac_keyboard_text_encoding
8622 = mac_keyboard_text_encoding
;
8624 else if (mac_keyboard_text_encoding
8625 != current_mac_keyboard_text_encoding
)
8627 /* Free the converter for the current encoding
8628 before creating a new one. */
8629 TECDisposeConverter (converter
);
8630 the_err
= TECCreateConverter (&converter
,
8631 kTextEncodingMacRoman
,
8632 mac_keyboard_text_encoding
);
8633 current_mac_keyboard_text_encoding
8634 = mac_keyboard_text_encoding
;
8637 if (the_err
== noErr
)
8639 unsigned char ch
= inev
.code
;
8640 ByteCount actual_input_length
, actual_output_length
;
8641 unsigned char outbuf
[32];
8643 convert_status
= TECConvertText (converter
, &ch
, 1,
8644 &actual_input_length
,
8646 &actual_output_length
);
8647 if (convert_status
== noErr
8648 && actual_input_length
== 1
8649 && actual_output_length
== 1)
8650 inev
.code
= *outbuf
;
8652 /* Reset internal states of the converter object.
8653 If it fails, create another one. */
8654 convert_status
= TECFlushText (converter
, outbuf
,
8656 &actual_output_length
);
8657 if (convert_status
!= noErr
)
8659 TECDisposeConverter (converter
);
8660 TECCreateConverter (&converter
,
8661 kTextEncodingMacRoman
,
8662 mac_keyboard_text_encoding
);
8667 #if USE_CARBON_EVENTS
8668 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8670 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8672 XSETFRAME (inev
.frame_or_window
,
8673 mac_window_to_frame (front_emacs_window ()));
8674 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8677 case kHighLevelEvent
:
8678 drag_and_drop_file_list
= Qnil
;
8680 AEProcessAppleEvent(&er
);
8682 /* Build a DRAG_N_DROP_EVENT type event as is done in
8683 constuct_drag_n_drop in w32term.c. */
8684 if (!NILP (drag_and_drop_file_list
))
8686 struct frame
*f
= NULL
;
8690 wp
= front_emacs_window ();
8694 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8695 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8696 wp
= front_emacs_window ();
8700 f
= mac_window_to_frame (wp
);
8702 inev
.kind
= DRAG_N_DROP_EVENT
;
8704 inev
.timestamp
= er
.when
* (1000 / 60);
8705 /* ticks to milliseconds */
8706 #if USE_CARBON_EVENTS
8707 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8709 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8712 XSETINT (inev
.x
, 0);
8713 XSETINT (inev
.y
, 0);
8715 XSETFRAME (frame
, f
);
8716 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8718 /* Regardless of whether Emacs was suspended or in the
8719 foreground, ask it to redraw its entire screen.
8720 Otherwise parts of the screen can be left in an
8721 inconsistent state. */
8723 #if TARGET_API_MAC_CARBON
8727 GetWindowPortBounds (wp
, &r
);
8728 InvalWindowRect (wp
, &r
);
8730 #else /* not TARGET_API_MAC_CARBON */
8731 InvalRect (&(wp
->portRect
));
8732 #endif /* not TARGET_API_MAC_CARBON */
8737 #if USE_CARBON_EVENTS
8738 ReleaseEvent (eventRef
);
8741 if (inev
.kind
!= NO_EVENT
)
8743 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8748 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
8753 XSETFRAME (frame
, f
);
8759 any_help_event_p
= 1;
8760 gen_help_event (help_echo_string
, frame
, help_echo_window
,
8761 help_echo_object
, help_echo_pos
);
8765 help_echo_string
= Qnil
;
8766 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
8773 /* If the focus was just given to an autoraising frame,
8775 /* ??? This ought to be able to handle more than one such frame. */
8776 if (pending_autoraise_frame
)
8778 x_raise_frame (pending_autoraise_frame
);
8779 pending_autoraise_frame
= 0;
8782 #if !TARGET_API_MAC_CARBON
8783 check_alarm (); /* simulate the handling of a SIGALRM */
8791 /* Need to override CodeWarrior's input function so no conversion is
8792 done on newlines Otherwise compiled functions in .elc files will be
8793 read incorrectly. Defined in ...:MSL C:MSL
8794 Common:Source:buffer_io.c. */
8797 __convert_to_newlines (unsigned char * p
, size_t * n
)
8803 __convert_from_newlines (unsigned char * p
, size_t * n
)
8810 /* Initialize the struct pointed to by MW to represent a new COLS x
8811 ROWS Macintosh window, using font with name FONTNAME and size
8814 make_mac_frame (FRAME_PTR fp
)
8817 #if TARGET_API_MAC_CARBON
8818 static int making_terminal_window
= 0;
8820 static int making_terminal_window
= 1;
8823 mwp
= fp
->output_data
.mac
;
8826 if (making_terminal_window
)
8828 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8831 making_terminal_window
= 0;
8835 #if TARGET_API_MAC_CARBON
8838 SetRect (&r
, 0, 0, 1, 1);
8839 if (CreateNewWindow (kDocumentWindowClass
,
8840 kWindowStandardDocumentAttributes
8841 /* | kWindowToolbarButtonAttribute */,
8842 &r
, &mwp
->mWP
) != noErr
)
8844 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8849 SetWRefCon (mwp
->mWP
, (long) mwp
);
8850 /* so that update events can find this mac_output struct */
8851 mwp
->mFP
= fp
; /* point back to emacs frame */
8853 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8859 make_mac_terminal_frame (struct frame
*f
)
8863 XSETFRAME (frame
, f
);
8865 f
->output_method
= output_mac
;
8866 f
->output_data
.mac
= (struct mac_output
*)
8867 xmalloc (sizeof (struct mac_output
));
8868 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8870 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8872 FRAME_COLS (f
) = 96;
8873 FRAME_LINES (f
) = 4;
8875 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8876 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8878 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8880 f
->output_data
.mac
->cursor_pixel
= 0;
8881 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8882 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8883 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8885 FRAME_FONTSET (f
) = -1;
8886 f
->output_data
.mac
->explicit_parent
= 0;
8889 f
->border_width
= 0;
8891 f
->internal_border_width
= 0;
8896 f
->new_text_cols
= 0;
8897 f
->new_text_lines
= 0;
8903 /* Need to be initialized for unshow_buffer in window.c. */
8904 selected_window
= f
->selected_window
;
8906 Fmodify_frame_parameters (frame
,
8907 Fcons (Fcons (Qfont
,
8908 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8909 Fmodify_frame_parameters (frame
,
8910 Fcons (Fcons (Qforeground_color
,
8911 build_string ("black")), Qnil
));
8912 Fmodify_frame_parameters (frame
,
8913 Fcons (Fcons (Qbackground_color
,
8914 build_string ("white")), Qnil
));
8916 ShowWindow (f
->output_data
.mac
->mWP
);
8920 /***********************************************************************
8922 ***********************************************************************/
8924 int mac_initialized
= 0;
8927 mac_initialize_display_info ()
8929 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8930 GDHandle main_device_handle
;
8932 bzero (dpyinfo
, sizeof (*dpyinfo
));
8934 /* Put it on x_display_name_list. */
8935 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8936 x_display_name_list
);
8937 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8940 dpyinfo
->mac_id_name
8941 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8942 + SCHARS (Vsystem_name
)
8944 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8945 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8947 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8948 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8951 main_device_handle
= LMGetMainDevice();
8953 dpyinfo
->reference_count
= 0;
8954 dpyinfo
->resx
= 75.0;
8955 dpyinfo
->resy
= 75.0;
8956 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
8958 /* HasDepth returns true if it is possible to have a 32 bit display,
8959 but this may not be what is actually used. Mac OSX can do better.
8960 CGMainDisplayID is only available on OSX 10.2 and higher, but the
8961 header for CGGetActiveDisplayList says that the first display returned
8962 is the active one, so we use that. */
8964 CGDirectDisplayID disp_id
[1];
8965 CGDisplayCount disp_count
;
8966 CGDisplayErr error_code
;
8968 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
8969 if (error_code
!= 0)
8970 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
8972 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
8975 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8976 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
8977 gdDevType
, dpyinfo
->color_p
))
8980 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8981 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8982 dpyinfo
->grabbed
= 0;
8983 dpyinfo
->root_window
= NULL
;
8984 dpyinfo
->image_cache
= make_image_cache ();
8986 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8987 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8988 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8989 dpyinfo
->mouse_face_window
= Qnil
;
8990 dpyinfo
->mouse_face_overlay
= Qnil
;
8991 dpyinfo
->mouse_face_hidden
= 0;
8994 struct mac_display_info
*
8995 mac_term_init (display_name
, xrm_option
, resource_name
)
8996 Lisp_Object display_name
;
8998 char *resource_name
;
9000 struct mac_display_info
*dpyinfo
;
9001 GDHandle main_device_handle
;
9003 if (!mac_initialized
)
9006 mac_initialized
= 1;
9009 mac_initialize_display_info (display_name
);
9011 dpyinfo
= &one_mac_display_info
;
9013 main_device_handle
= LMGetMainDevice();
9015 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
9016 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
9025 extern int inhibit_window_system
;
9026 extern int noninteractive
;
9027 CFBundleRef appsBundle
;
9030 /* No need to test if already -nw*/
9031 if (inhibit_window_system
|| noninteractive
)
9034 appsBundle
= CFBundleGetMainBundle();
9035 if (appsBundle
!= NULL
)
9037 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
9038 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
9039 /* We found the bundle identifier, now we know we are valid. */
9046 /* MAC_TODO: Have this start the bundled executable */
9048 /* For now, prevent the fatal error by bringing it up in the terminal */
9049 inhibit_window_system
= 1;
9053 MakeMeTheFrontProcess ()
9055 ProcessSerialNumber psn
;
9058 err
= GetCurrentProcess (&psn
);
9060 (void) SetFrontProcess (&psn
);
9063 /***** Code to handle C-g testing *****/
9065 /* Contains the Mac modifier formed from quit_char */
9066 static mac_quit_char_modifiers
= 0;
9067 static mac_quit_char_keycode
;
9068 extern int quit_char
;
9071 mac_determine_quit_char_modifiers()
9073 /* Todo: Determine modifiers from quit_char. */
9074 UInt32 qc_modifiers
= ctrl_modifier
;
9077 mac_quit_char_modifiers
= 0;
9078 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
9079 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
9080 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
9081 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
9085 init_quit_char_handler ()
9087 /* TODO: Let this support keys other the 'g' */
9088 mac_quit_char_keycode
= 5;
9089 /* Look at <architecture/adb_kb_map.h> for details */
9090 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
9092 mac_determine_quit_char_modifiers();
9096 quit_char_comp (EventRef inEvent
, void *inCompData
)
9098 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
9100 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
9104 UInt32 keyModifiers
;
9105 GetEventParameter(inEvent
, kEventParamKeyCode
,
9106 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
9107 if (keyCode
!= mac_quit_char_keycode
)
9109 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
9110 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
9111 if (keyModifiers
!= mac_quit_char_modifiers
)
9118 mac_check_for_quit_char ()
9121 static EMACS_TIME last_check_time
= { 0, 0 };
9122 static EMACS_TIME one_second
= { 1, 0 };
9125 /* If windows are not initialized, return immediately (keep it bouncin'). */
9126 if (!mac_quit_char_modifiers
)
9129 /* Don't check if last check is less than a second ago. */
9130 EMACS_GET_TIME (now
);
9131 EMACS_SUB_TIME (t
, now
, last_check_time
);
9132 if (EMACS_TIME_LT (t
, one_second
))
9134 last_check_time
= now
;
9136 /* Redetermine modifiers because they are based on lisp variables */
9137 mac_determine_quit_char_modifiers ();
9139 /* Fill the queue with events */
9141 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
9142 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
9147 struct input_event e
;
9149 /* Use an input_event to emulate what the interrupt handler does. */
9151 e
.kind
= ASCII_KEYSTROKE_EVENT
;
9155 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
9156 XSETFRAME (e
.frame_or_window
, mac_window_to_frame (front_emacs_window ()));
9157 /* Remove event from queue to prevent looping. */
9158 RemoveEventFromQueue (GetMainEventQueue (), event
);
9159 ReleaseEvent (event
);
9160 kbd_buffer_store_event (&e
);
9164 #endif /* MAC_OSX */
9166 /* Set up use of X before we make the first connection. */
9168 extern frame_parm_handler mac_frame_parm_handlers
[];
9170 static struct redisplay_interface x_redisplay_interface
=
9172 mac_frame_parm_handlers
,
9176 x_clear_end_of_line
,
9178 x_after_update_window_line
,
9179 x_update_window_begin
,
9180 x_update_window_end
,
9183 0, /* flush_display_optional */
9184 x_clear_window_mouse_face
,
9185 x_get_glyph_overhangs
,
9186 x_fix_overlapping_area
,
9187 x_draw_fringe_bitmap
,
9188 0, /* define_fringe_bitmap */
9189 0, /* destroy_fringe_bitmap */
9190 mac_per_char_metric
,
9192 NULL
, /* mac_compute_glyph_string_overhangs */
9193 x_draw_glyph_string
,
9194 mac_define_frame_cursor
,
9195 mac_clear_frame_area
,
9196 mac_draw_window_cursor
,
9197 mac_draw_vertical_window_border
,
9198 mac_shift_glyphs_for_insert
9204 rif
= &x_redisplay_interface
;
9206 clear_frame_hook
= x_clear_frame
;
9207 ins_del_lines_hook
= x_ins_del_lines
;
9208 delete_glyphs_hook
= x_delete_glyphs
;
9209 ring_bell_hook
= XTring_bell
;
9210 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9211 set_terminal_modes_hook
= XTset_terminal_modes
;
9212 update_begin_hook
= x_update_begin
;
9213 update_end_hook
= x_update_end
;
9214 set_terminal_window_hook
= XTset_terminal_window
;
9215 read_socket_hook
= XTread_socket
;
9216 frame_up_to_date_hook
= XTframe_up_to_date
;
9217 mouse_position_hook
= XTmouse_position
;
9218 frame_rehighlight_hook
= XTframe_rehighlight
;
9219 frame_raise_lower_hook
= XTframe_raise_lower
;
9221 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9222 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9223 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9224 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9226 scroll_region_ok
= 1; /* we'll scroll partial frames */
9227 char_ins_del_ok
= 1;
9228 line_ins_del_ok
= 1; /* we'll just blt 'em */
9229 fast_clear_end_of_line
= 1; /* X does this well */
9230 memory_below_frame
= 0; /* we don't remember what scrolls
9235 last_tool_bar_item
= -1;
9236 any_help_event_p
= 0;
9238 /* Try to use interrupt input; if we can't, then start polling. */
9239 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9241 #ifdef USE_X_TOOLKIT
9242 XtToolkitInitialize ();
9243 Xt_app_con
= XtCreateApplicationContext ();
9244 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9246 /* Install an asynchronous timer that processes Xt timeout events
9247 every 0.1s. This is necessary because some widget sets use
9248 timeouts internally, for example the LessTif menu bar, or the
9249 Xaw3d scroll bar. When Xt timouts aren't processed, these
9250 widgets don't behave normally. */
9252 EMACS_TIME interval
;
9253 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9254 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9258 #if USE_TOOLKIT_SCROLL_BARS
9259 xaw3d_arrow_scroll
= False
;
9260 xaw3d_pick_top
= True
;
9264 /* Note that there is no real way portable across R3/R4 to get the
9265 original error handler. */
9266 XSetErrorHandler (x_error_handler
);
9267 XSetIOErrorHandler (x_io_error_quitter
);
9269 /* Disable Window Change signals; they are handled by X events. */
9271 signal (SIGWINCH
, SIG_DFL
);
9272 #endif /* ! defined (SIGWINCH) */
9274 signal (SIGPIPE
, x_connection_signal
);
9278 mac_initialize_display_info ();
9280 #if TARGET_API_MAC_CARBON
9281 init_required_apple_events ();
9283 init_mac_drag_n_drop ();
9285 #if USE_CARBON_EVENTS
9286 init_service_handler ();
9288 init_quit_char_handler ();
9291 DisableMenuCommand (NULL
, kHICommandQuit
);
9293 if (!inhibit_window_system
)
9294 MakeMeTheFrontProcess ();
9304 staticpro (&x_error_message_string
);
9305 x_error_message_string
= Qnil
;
9308 Qmodifier_value
= intern ("modifier-value");
9309 Qalt
= intern ("alt");
9310 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
9311 Qhyper
= intern ("hyper");
9312 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
9313 Qsuper
= intern ("super");
9314 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
9316 Fprovide (intern ("mac-carbon"), Qnil
);
9318 staticpro (&Qreverse
);
9319 Qreverse
= intern ("reverse");
9321 staticpro (&x_display_name_list
);
9322 x_display_name_list
= Qnil
;
9324 staticpro (&last_mouse_scroll_bar
);
9325 last_mouse_scroll_bar
= Qnil
;
9327 staticpro (&Qvendor_specific_keysyms
);
9328 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9330 staticpro (&last_mouse_press_frame
);
9331 last_mouse_press_frame
= Qnil
;
9333 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9334 staticpro (&Qmac_ready_for_drag_n_drop
);
9336 Qbig5
= intern ("big5");
9339 Qcn_gb
= intern ("cn-gb");
9340 staticpro (&Qcn_gb
);
9342 Qsjis
= intern ("sjis");
9345 Qeuc_kr
= intern ("euc-kr");
9346 staticpro (&Qeuc_kr
);
9348 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9349 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9350 x_autoselect_window_p
= 0;
9352 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9353 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9354 Vx_toolkit_scroll_bars
= Qt
;
9356 DEFVAR_BOOL ("x-use-underline-position-properties",
9357 &x_use_underline_position_properties
,
9358 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9359 nil means ignore them. If you encounter fonts with bogus
9360 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9361 to 4.1, set this to nil. */);
9362 x_use_underline_position_properties
= 0;
9364 staticpro (&last_mouse_motion_frame
);
9365 last_mouse_motion_frame
= Qnil
;
9367 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9368 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9369 Otherwise the option key is used. */);
9370 Vmac_command_key_is_meta
= Qt
;
9372 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
9373 doc
: /* Modifier to use for the Mac alt/option key. The value can
9374 be alt, hyper, or super for the respective modifier. If the value is
9375 nil then the key will act as the normal Mac option modifier. */);
9376 Vmac_option_modifier
= Qnil
;
9378 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9379 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9380 useful for non-standard keyboard layouts. */);
9381 Vmac_reverse_ctrl_meta
= Qnil
;
9383 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9384 &Vmac_emulate_three_button_mouse
,
9385 doc
: /* t means that when the option-key is held down while pressing the
9386 mouse button, the click will register as mouse-2 and while the
9387 command-key is held down, the click will register as mouse-3.
9388 'reverse means that the the option-key will register for mouse-3
9389 and the command-key will register for mouse-2. nil means that
9390 not emulation should be done and the modifiers should be placed
9391 on the mouse-1 event. */);
9392 Vmac_emulate_three_button_mouse
= Qnil
;
9394 #if USE_CARBON_EVENTS
9395 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9396 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9397 the right click will be mouse-3.
9398 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9399 Vmac_wheel_button_is_mouse_2
= Qt
;
9401 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9402 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9403 Toolbox for processing before Emacs sees it. */);
9404 Vmac_pass_command_to_system
= Qt
;
9406 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9407 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9408 Toolbox for processing before Emacs sees it. */);
9409 Vmac_pass_control_to_system
= Qt
;
9412 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9413 doc
: /* One of the Text Encoding Base constant values defined in the
9414 Basic Text Constants section of Inside Macintosh - Text Encoding
9415 Conversion Manager. Its value determines the encoding characters
9416 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9417 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9418 its default value, no conversion takes place. If it is set to
9419 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9420 characters typed on Mac keyboard are first converted into the
9421 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9422 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9423 command, this enables the Mac keyboard to be used to enter non-ASCII
9424 characters directly. */);
9425 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9428 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9429 (do not change this comment) */