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"
43 /* Macros max and min defined in lisp.h conflict with those in
44 precompiled header Carbon.h. */
48 #include <Carbon/Carbon.h>
50 #define free unexec_free
52 #define malloc unexec_malloc
54 #define realloc unexec_realloc
56 #define min(a, b) ((a) < (b) ? (a) : (b))
58 #define max(a, b) ((a) > (b) ? (a) : (b))
60 #define init_process emacs_init_process
61 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
62 obtain events from the event queue. If set to 0, WaitNextEvent is
64 #define USE_CARBON_EVENTS 1
65 #else /* not MAC_OSX */
66 #include <Quickdraw.h>
67 #include <ToolUtils.h>
71 #include <Resources.h>
73 #include <TextUtils.h>
76 #if defined (__MRC__) || (__MSL__ >= 0x6000)
77 #include <ControlDefinitions.h>
84 #endif /* not MAC_OSX */
98 #include "dispextern.h"
100 #include "termhooks.h"
101 #include "termopts.h"
102 #include "termchar.h"
107 #include "intervals.h"
108 #include "composite.h"
111 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
112 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
113 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
114 #define macShiftKey (shiftKey)
115 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
116 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
118 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
122 /* Non-nil means Emacs uses toolkit scroll bars. */
124 Lisp_Object Vx_toolkit_scroll_bars
;
126 /* Non-zero means that a HELP_EVENT has been generated since Emacs
129 static int any_help_event_p
;
131 /* Non-zero means autoselect window with the mouse cursor. */
133 int x_autoselect_window_p
;
135 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
137 int x_use_underline_position_properties
;
139 /* Non-zero means draw block and hollow cursor as wide as the glyph
140 under it. For example, if a block cursor is over a tab, it will be
141 drawn as wide as that tab on the display. */
144 /* This is a chain of structures for all the X displays currently in
147 struct x_display_info
*x_display_list
;
149 /* This is a list of cons cells, each of the form (NAME
150 . FONT-LIST-CACHE), one for each element of x_display_list and in
151 the same order. NAME is the name of the frame. FONT-LIST-CACHE
152 records previous values returned by x-list-fonts. */
154 Lisp_Object x_display_name_list
;
156 /* This is display since Mac does not support multiple ones. */
157 struct mac_display_info one_mac_display_info
;
159 /* Frame being updated by update_frame. This is declared in term.c.
160 This is set by update_begin and looked at by all the XT functions.
161 It is zero while not inside an update. In that case, the XT
162 functions assume that `selected_frame' is the frame to apply to. */
164 extern struct frame
*updating_frame
;
166 extern int waiting_for_input
;
168 /* This is a frame waiting to be auto-raised, within XTread_socket. */
170 struct frame
*pending_autoraise_frame
;
172 /* Non-zero means user is interacting with a toolkit scroll bar. */
174 static int toolkit_scroll_bar_interaction
;
178 Formerly, we used PointerMotionHintMask (in standard_event_mask)
179 so that we would have to call XQueryPointer after each MotionNotify
180 event to ask for another such event. However, this made mouse tracking
181 slow, and there was a bug that made it eventually stop.
183 Simply asking for MotionNotify all the time seems to work better.
185 In order to avoid asking for motion events and then throwing most
186 of them away or busy-polling the server for mouse positions, we ask
187 the server for pointer motion hints. This means that we get only
188 one event per group of mouse movements. "Groups" are delimited by
189 other kinds of events (focus changes and button clicks, for
190 example), or by XQueryPointer calls; when one of these happens, we
191 get another MotionNotify event the next time the mouse moves. This
192 is at least as efficient as getting motion events when mouse
193 tracking is on, and I suspect only negligibly worse when tracking
196 /* Where the mouse was last time we reported a mouse event. */
198 static Rect last_mouse_glyph
;
199 static Lisp_Object last_mouse_press_frame
;
201 /* The scroll bar in which the last X motion event occurred.
203 If the last X motion event occurred in a scroll bar, we set this so
204 XTmouse_position can know whether to report a scroll bar motion or
207 If the last X motion event didn't occur in a scroll bar, we set
208 this to Qnil, to tell XTmouse_position to return an ordinary motion
211 static Lisp_Object last_mouse_scroll_bar
;
213 /* This is a hack. We would really prefer that XTmouse_position would
214 return the time associated with the position it returns, but there
215 doesn't seem to be any way to wrest the time-stamp from the server
216 along with the position query. So, we just keep track of the time
217 of the last movement we received, and return that in hopes that
218 it's somewhat accurate. */
220 static Time last_mouse_movement_time
;
222 enum mouse_tracking_type
{
224 mouse_tracking_mouse_movement
,
225 mouse_tracking_scroll_bar
228 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
230 struct scroll_bar
*tracked_scroll_bar
= NULL
;
232 /* Incremented by XTread_socket whenever it really tries to read
236 static int volatile input_signal_count
;
238 static int input_signal_count
;
241 /* Used locally within XTread_socket. */
243 static int x_noop_count
;
245 /* Initial values of argv and argc. */
247 extern char **initial_argv
;
248 extern int initial_argc
;
250 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
252 /* Tells if a window manager is present or not. */
254 extern Lisp_Object Vx_no_window_manager
;
258 /* A mask of extra modifier bits to put into every keyboard char. */
260 extern int extra_keyboard_modifiers
;
262 static Lisp_Object Qvendor_specific_keysyms
;
265 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
268 extern int inhibit_window_system
;
271 QDGlobals qd
; /* QuickDraw global information structure. */
275 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
276 struct mac_display_info
*mac_display_info_for_display (Display
*);
277 static void x_update_window_end
P_ ((struct window
*, int, int));
278 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
279 static int x_io_error_quitter
P_ ((Display
*));
280 int x_catch_errors
P_ ((Display
*));
281 void x_uncatch_errors
P_ ((Display
*, int));
282 void x_lower_frame
P_ ((struct frame
*));
283 void x_scroll_bar_clear
P_ ((struct frame
*));
284 int x_had_errors_p
P_ ((Display
*));
285 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
286 void x_raise_frame
P_ ((struct frame
*));
287 void x_set_window_size
P_ ((struct frame
*, int, int, int));
288 void x_wm_set_window_state
P_ ((struct frame
*, int));
289 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
290 void mac_initialize
P_ ((void));
291 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
292 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
293 static void x_update_end
P_ ((struct frame
*));
294 static void XTframe_up_to_date
P_ ((struct frame
*));
295 static void XTreassert_line_highlight
P_ ((int, int));
296 static void x_change_line_highlight
P_ ((int, int, int, int));
297 static void XTset_terminal_modes
P_ ((void));
298 static void XTreset_terminal_modes
P_ ((void));
299 static void x_clear_frame
P_ ((void));
300 static void frame_highlight
P_ ((struct frame
*));
301 static void frame_unhighlight
P_ ((struct frame
*));
302 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
303 static void XTframe_rehighlight
P_ ((struct frame
*));
304 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
305 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
306 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int));
307 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, GC
));
308 static void x_flush
P_ ((struct frame
*f
));
309 static void x_update_begin
P_ ((struct frame
*));
310 static void x_update_window_begin
P_ ((struct window
*));
311 static void x_after_update_window_line
P_ ((struct glyph_row
*));
313 void activate_scroll_bars (FRAME_PTR
);
314 void deactivate_scroll_bars (FRAME_PTR
);
316 static int is_emacs_window (WindowPtr
);
318 extern int image_ascent (struct image
*, struct face
*);
319 int x_bitmap_icon (struct frame
*, Lisp_Object
);
320 void x_make_frame_visible (struct frame
*);
322 extern void window_scroll (Lisp_Object
, int, int, int);
324 /* Defined in macmenu.h. */
325 extern void menubar_selection_callback (FRAME_PTR
, int);
326 extern void set_frame_menubar (FRAME_PTR
, int, int);
328 /* X display function emulation */
331 XFreePixmap (display
, pixmap
)
335 PixMap
*p
= (PixMap
*) pixmap
;
342 /* Set foreground color for subsequent QuickDraw commands. Assume
343 graphic port has already been set. */
346 mac_set_forecolor (unsigned long color
)
350 fg_color
.red
= RED_FROM_ULONG (color
) * 256;
351 fg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
352 fg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
354 RGBForeColor (&fg_color
);
358 /* Set background color for subsequent QuickDraw commands. Assume
359 graphic port has already been set. */
362 mac_set_backcolor (unsigned long color
)
366 bg_color
.red
= RED_FROM_ULONG (color
) * 256;
367 bg_color
.green
= GREEN_FROM_ULONG (color
) * 256;
368 bg_color
.blue
= BLUE_FROM_ULONG (color
) * 256;
370 RGBBackColor (&bg_color
);
373 /* Set foreground and background color for subsequent QuickDraw
374 commands. Assume that the graphic port has already been set. */
377 mac_set_colors (GC gc
)
379 mac_set_forecolor (gc
->foreground
);
380 mac_set_backcolor (gc
->background
);
383 /* Mac version of XDrawLine. */
386 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
392 #if TARGET_API_MAC_CARBON
393 SetPort (GetWindowPort (w
));
404 /* Mac version of XClearArea. */
407 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
411 unsigned int width
, height
;
414 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
418 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
419 xgc
.background
= mwp
->x_compatible
.background_pixel
;
421 #if TARGET_API_MAC_CARBON
422 SetPort (GetWindowPort (w
));
427 mac_set_colors (&xgc
);
428 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
433 /* Mac version of XClearWindow. */
436 XClearWindow (display
, w
)
440 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
443 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
444 xgc
.background
= mwp
->x_compatible
.background_pixel
;
446 #if TARGET_API_MAC_CARBON
447 SetPort (GetWindowPort (w
));
452 mac_set_colors (&xgc
);
454 #if TARGET_API_MAC_CARBON
458 GetWindowPortBounds (w
, &r
);
461 #else /* not TARGET_API_MAC_CARBON */
462 EraseRect (&(w
->portRect
));
463 #endif /* not TARGET_API_MAC_CARBON */
467 /* Mac replacement for XCopyArea. */
470 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
474 int x
, y
, width
, height
;
475 unsigned short *bits
;
481 bitmap
.rowBytes
= sizeof(unsigned short);
482 bitmap
.baseAddr
= bits
;
483 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
485 #if TARGET_API_MAC_CARBON
486 SetPort (GetWindowPort (w
));
492 SetRect (&r
, x
, y
, x
+ bitmap
.bounds
.right
, y
+ bitmap
.bounds
.bottom
);
494 #if TARGET_API_MAC_CARBON
498 LockPortBits (GetWindowPort (w
));
499 pmh
= GetPortPixMap (GetWindowPort (w
));
500 CopyBits (&bitmap
, (BitMap
*) *pmh
, &(bitmap
.bounds
), &r
,
501 overlay_p
? srcOr
: srcCopy
, 0);
502 UnlockPortBits (GetWindowPort (w
));
504 #else /* not TARGET_API_MAC_CARBON */
505 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
506 overlay_p
? srcOr
: srcCopy
, 0);
507 #endif /* not TARGET_API_MAC_CARBON */
511 /* Mac replacement for XSetClipRectangles. */
514 mac_set_clip_rectangle (display
, w
, r
)
519 #if TARGET_API_MAC_CARBON
520 SetPort (GetWindowPort (w
));
529 /* Mac replacement for XSetClipMask. */
532 mac_reset_clipping (display
, w
)
538 #if TARGET_API_MAC_CARBON
539 SetPort (GetWindowPort (w
));
544 SetRect (&r
, -32767, -32767, 32767, 32767);
549 /* Mac replacement for XCreateBitmapFromBitmapData. */
552 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
557 int bytes_per_row
, i
, j
;
559 bitmap
->rowBytes
= (w
+ 15) / 16 * 2; /* must be on word boundary */
560 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
561 if (!bitmap
->baseAddr
)
564 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
565 for (i
= 0; i
< h
; i
++)
566 for (j
= 0; j
< w
; j
++)
567 if (BitTst (bits
, i
* w
+ j
))
568 BitSet (bitmap
->baseAddr
, i
* bitmap
->rowBytes
* 8 + j
);
570 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
575 mac_free_bitmap (bitmap
)
578 xfree (bitmap
->baseAddr
);
581 /* Mac replacement for XFillRectangle. */
584 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
589 unsigned int width
, height
;
593 #if TARGET_API_MAC_CARBON
594 SetPort (GetWindowPort (w
));
600 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
602 PaintRect (&r
); /* using foreground color of gc */
606 /* Mac replacement for XDrawRectangle: dest is a window. */
609 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
614 unsigned int width
, height
;
618 #if TARGET_API_MAC_CARBON
619 SetPort (GetWindowPort (w
));
625 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
627 FrameRect (&r
); /* using foreground color of gc */
631 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
634 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
639 unsigned int width
, height
;
641 #if 0 /* MAC_TODO: draw a rectangle in a PixMap */
644 #if TARGET_API_MAC_CARBON
645 SetPort (GetWindowPort (w
));
651 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
653 FrameRect (&r
); /* using foreground color of gc */
659 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
666 int nchars
, mode
, bytes_per_char
;
668 #if TARGET_API_MAC_CARBON
669 SetPort (GetWindowPort (w
));
676 TextFont (gc
->font
->mac_fontnum
);
677 TextSize (gc
->font
->mac_fontsize
);
678 TextFace (gc
->font
->mac_fontface
);
682 DrawText (buf
, 0, nchars
* bytes_per_char
);
686 /* Mac replacement for XDrawString. */
689 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
697 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
701 /* Mac replacement for XDrawString16. */
704 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
712 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
717 /* Mac replacement for XDrawImageString. */
720 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
728 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
732 /* Mac replacement for XDrawString16. */
735 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
743 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
748 /* Mac replacement for XCopyArea: dest must be window. */
751 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
758 unsigned int width
, height
;
763 #if TARGET_API_MAC_CARBON
764 SetPort (GetWindowPort (dest
));
771 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
772 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
774 #if TARGET_API_MAC_CARBON
778 LockPortBits (GetWindowPort (dest
));
779 pmh
= GetPortPixMap (GetWindowPort (dest
));
780 CopyBits ((BitMap
*) &src
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
781 UnlockPortBits (GetWindowPort (dest
));
783 #else /* not TARGET_API_MAC_CARBON */
784 CopyBits ((BitMap
*) &src
, &(dest
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
785 #endif /* not TARGET_API_MAC_CARBON */
790 /* Convert a pair of local coordinates to global (screen) coordinates.
791 Assume graphic port has been properly set. */
793 local_to_global_coord (short *h
, short *v
)
807 /* Mac replacement for XCopyArea: used only for scrolling. */
810 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
815 unsigned int width
, height
;
818 #if TARGET_API_MAC_CARBON
819 Rect gw_r
, src_r
, dest_r
;
822 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
823 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
825 SetPort (GetWindowPort (w
));
827 ForeColor (blackColor
);
828 BackColor (whiteColor
);
830 LockPortBits (GetWindowPort (w
));
831 pmh
= GetPortPixMap (GetWindowPort (w
));
832 CopyBits ((BitMap
*) *pmh
, (BitMap
*) *pmh
, &src_r
, &dest_r
, srcCopy
, 0);
833 UnlockPortBits (GetWindowPort (w
));
836 #else /* not TARGET_API_MAC_CARBON */
844 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
845 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
848 /* Need to use global coordinates and screenBits since src and dest
849 areas overlap in general. */
850 local_to_global_coord (&src_r
.left
, &src_r
.top
);
851 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
852 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
853 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
855 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
857 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
858 color mapping in CopyBits. Otherwise, it will be slow. */
859 ForeColor (blackColor
);
860 BackColor (whiteColor
);
861 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
865 #endif /* not TARGET_API_MAC_CARBON */
869 /* Mac replacement for XCopyArea: dest must be Pixmap. */
872 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
879 unsigned int width
, height
;
883 int src_right
= ((PixMap
*) src
)->bounds
.right
;
884 int src_bottom
= ((PixMap
*) src
)->bounds
.bottom
;
885 int w
= src_right
- src_x
;
886 int h
= src_bottom
- src_y
;
890 SetRect (&src_r
, src_x
, src_y
, src_right
, src_bottom
);
891 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ w
, dest_y
+ h
);
893 CopyBits ((BitMap
*) &src
, (BitMap
*) &dest
, &src_r
, &dest_r
, srcCopy
, 0);
897 /* Mac replacement for XChangeGC. */
900 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
903 if (mask
& GCForeground
)
904 gc
->foreground
= xgcv
->foreground
;
905 if (mask
& GCBackground
)
906 gc
->background
= xgcv
->background
;
908 gc
->font
= xgcv
->font
;
912 /* Mac replacement for XCreateGC. */
915 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
918 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
919 bzero (gc
, sizeof (XGCValues
));
921 XChangeGC (ignore
, gc
, mask
, xgcv
);
927 /* Used in xfaces.c. */
930 XFreeGC (display
, gc
)
938 /* Mac replacement for XGetGCValues. */
941 XGetGCValues (void* ignore
, XGCValues
*gc
,
942 unsigned long mask
, XGCValues
*xgcv
)
944 XChangeGC (ignore
, xgcv
, mask
, gc
);
948 /* Mac replacement for XSetForeground. */
951 XSetForeground (display
, gc
, color
)
956 gc
->foreground
= color
;
960 /* Mac replacement for XSetFont. */
963 XSetFont (display
, gc
, font
)
973 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
974 int *direction
,int *font_ascent
,
975 int *font_descent
, XCharStruct
*cs
)
977 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
981 /* x_sync is a no-op on Mac. */
989 /* Remove calls to XFlush by defining XFlush to an empty replacement.
990 Calls to XFlush should be unnecessary because the X output buffer
991 is flushed automatically as needed by calls to XPending,
992 XNextEvent, or XWindowEvent according to the XFlush man page.
993 XTread_socket calls XPending. Removing XFlush improves
996 #if TARGET_API_MAC_CARBON
997 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
999 #define XFlush(DISPLAY) (void) 0
1002 /* Flush display of frame F, or of all frames if F is null. */
1008 #if TARGET_API_MAC_CARBON
1012 Lisp_Object rest
, frame
;
1013 FOR_EACH_FRAME (rest
, frame
)
1014 x_flush (XFRAME (frame
));
1016 else if (FRAME_X_P (f
))
1017 XFlush (FRAME_MAC_DISPLAY (f
));
1019 #endif /* TARGET_API_MAC_CARBON */
1024 /* Return the struct mac_display_info corresponding to DPY. There's
1027 struct mac_display_info
*
1028 mac_display_info_for_display (dpy
)
1031 return &one_mac_display_info
;
1036 /***********************************************************************
1037 Starting and ending an update
1038 ***********************************************************************/
1040 /* Start an update of frame F. This function is installed as a hook
1041 for update_begin, i.e. it is called when update_begin is called.
1042 This function is called prior to calls to x_update_window_begin for
1043 each window being updated. */
1049 /* Nothing to do. */
1053 /* Start update of window W. Set the global variable updated_window
1054 to the window being updated and set output_cursor to the cursor
1058 x_update_window_begin (w
)
1061 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1062 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1065 set_output_cursor (&w
->cursor
);
1069 if (f
== display_info
->mouse_face_mouse_frame
)
1071 /* Don't do highlighting for mouse motion during the update. */
1072 display_info
->mouse_face_defer
= 1;
1074 /* If F needs to be redrawn, simply forget about any prior mouse
1076 if (FRAME_GARBAGED_P (f
))
1077 display_info
->mouse_face_window
= Qnil
;
1079 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1080 their mouse_face_p flag set, which means that they are always
1081 unequal to rows in a desired matrix which never have that
1082 flag set. So, rows containing mouse-face glyphs are never
1083 scrolled, and we don't have to switch the mouse highlight off
1084 here to prevent it from being scrolled. */
1086 /* Can we tell that this update does not affect the window
1087 where the mouse highlight is? If so, no need to turn off.
1088 Likewise, don't do anything if the frame is garbaged;
1089 in that case, the frame's current matrix that we would use
1090 is all wrong, and we will redisplay that line anyway. */
1091 if (!NILP (display_info
->mouse_face_window
)
1092 && w
== XWINDOW (display_info
->mouse_face_window
))
1096 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1097 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1100 if (i
< w
->desired_matrix
->nrows
)
1101 clear_mouse_face (display_info
);
1110 /* Draw a vertical window border from (x,y0) to (x,y1) */
1113 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1117 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1119 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1120 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1124 /* End update of window W (which is equal to updated_window).
1126 Draw vertical borders between horizontally adjacent windows, and
1127 display W's cursor if CURSOR_ON_P is non-zero.
1129 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1130 glyphs in mouse-face were overwritten. In that case we have to
1131 make sure that the mouse-highlight is properly redrawn.
1133 W may be a menu bar pseudo-window in case we don't have X toolkit
1134 support. Such windows don't have a cursor, so don't display it
1138 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1140 int cursor_on_p
, mouse_face_overwritten_p
;
1142 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1144 if (!w
->pseudo_window_p
)
1149 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1151 output_cursor
.x
, output_cursor
.y
);
1153 x_draw_vertical_border (w
);
1155 draw_window_fringes (w
);
1160 /* If a row with mouse-face was overwritten, arrange for
1161 XTframe_up_to_date to redisplay the mouse highlight. */
1162 if (mouse_face_overwritten_p
)
1164 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1165 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1166 dpyinfo
->mouse_face_window
= Qnil
;
1170 /* Unhide the caret. This won't actually show the cursor, unless it
1171 was visible before the corresponding call to HideCaret in
1172 x_update_window_begin. */
1173 if (w32_use_visible_system_caret
)
1174 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1177 updated_window
= NULL
;
1181 /* End update of frame F. This function is installed as a hook in
1188 /* Reset the background color of Mac OS Window to that of the frame after
1189 update so that it is used by Mac Toolbox to clear the update region before
1190 an update event is generated. */
1191 #if TARGET_API_MAC_CARBON
1192 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1194 SetPort (FRAME_MAC_WINDOW (f
));
1197 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1199 /* Mouse highlight may be displayed again. */
1200 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1203 XFlush (FRAME_MAC_DISPLAY (f
));
1208 /* This function is called from various places in xdisp.c whenever a
1209 complete update has been performed. The global variable
1210 updated_window is not available here. */
1213 XTframe_up_to_date (f
)
1218 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1220 if (dpyinfo
->mouse_face_deferred_gc
1221 || f
== dpyinfo
->mouse_face_mouse_frame
)
1224 if (dpyinfo
->mouse_face_mouse_frame
)
1225 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1226 dpyinfo
->mouse_face_mouse_x
,
1227 dpyinfo
->mouse_face_mouse_y
);
1228 dpyinfo
->mouse_face_deferred_gc
= 0;
1235 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1236 arrow bitmaps, or clear the fringes if no bitmaps are required
1237 before DESIRED_ROW is made current. The window being updated is
1238 found in updated_window. This function is called from
1239 update_window_line only if it is known that there are differences
1240 between bitmaps to be drawn between current row and DESIRED_ROW. */
1243 x_after_update_window_line (desired_row
)
1244 struct glyph_row
*desired_row
;
1246 struct window
*w
= updated_window
;
1252 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1253 desired_row
->redraw_fringe_bitmaps_p
= 1;
1255 /* When a window has disappeared, make sure that no rest of
1256 full-width rows stays visible in the internal border. Could
1257 check here if updated_window is the leftmost/rightmost window,
1258 but I guess it's not worth doing since vertically split windows
1259 are almost never used, internal border is rarely set, and the
1260 overhead is very small. */
1261 if (windows_or_buffers_changed
1262 && desired_row
->full_width_p
1263 && (f
= XFRAME (w
->frame
),
1264 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1266 && (height
= desired_row
->visible_height
,
1269 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1270 /* Internal border is drawn below the tool bar. */
1271 if (WINDOWP (f
->tool_bar_window
)
1272 && w
== XWINDOW (f
->tool_bar_window
))
1277 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1278 0, y
, width
, height
, 0);
1279 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1280 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1288 /* Draw the bitmap WHICH in one of the left or right fringes of
1289 window W. ROW is the glyph row for which to display the bitmap; it
1290 determines the vertical position at which the bitmap has to be
1294 x_draw_fringe_bitmap (w
, row
, p
)
1296 struct glyph_row
*row
;
1297 struct draw_fringe_bitmap_params
*p
;
1299 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1300 Display
*display
= FRAME_MAC_DISPLAY (f
);
1301 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1303 GC gc
= f
->output_data
.mac
->normal_gc
;
1304 struct face
*face
= p
->face
;
1307 /* Must clip because of partially visible lines. */
1308 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1311 /* Adjust position of "bottom aligned" bitmap on partially
1312 visible last row. */
1314 int oldVH
= row
->visible_height
;
1315 row
->visible_height
= p
->h
;
1316 row
->y
-= rowY
- p
->y
;
1317 x_clip_to_row (w
, row
, gc
);
1319 row
->visible_height
= oldVH
;
1322 x_clip_to_row (w
, row
, gc
);
1324 if (p
->bx
>= 0 && !p
->overlay_p
)
1327 gcv
.foreground
= face
->background
;
1329 #if 0 /* MAC_TODO: stipple */
1330 /* In case the same realized face is used for fringes and
1331 for something displayed in the text (e.g. face `region' on
1332 mono-displays, the fill style may have been changed to
1333 FillSolid in x_draw_glyph_string_background. */
1335 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1337 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1340 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1342 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1344 #if 0 /* MAC_TODO: stipple */
1346 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1352 unsigned short *bits
= p
->bits
+ p
->dh
;
1354 gcv
.foreground
= (p
->cursor_p
1355 ? (p
->overlay_p
? face
->background
1356 : f
->output_data
.mac
->cursor_pixel
)
1357 : face
->foreground
);
1358 gcv
.background
= face
->background
;
1360 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1361 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1364 mac_reset_clipping (display
, window
);
1368 /* This is called when starting Emacs and when restarting after
1369 suspend. When starting Emacs, no window is mapped. And nothing
1370 must be done to Emacs's own window if it is suspended (though that
1374 XTset_terminal_modes ()
1378 /* This is called when exiting or suspending Emacs. Exiting will make
1379 the windows go away, and suspending requires no action. */
1382 XTreset_terminal_modes ()
1387 /***********************************************************************
1389 ***********************************************************************/
1391 /* Function prototypes of this page. */
1393 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1394 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1397 /* Return a pointer to per-char metric information in FONT of a
1398 character pointed by B which is a pointer to an XChar2b. */
1400 #define PER_CHAR_METRIC(font, b) \
1402 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1403 + (((font)->min_byte1 || (font)->max_byte1) \
1404 ? (((b)->byte1 - (font)->min_byte1) \
1405 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1407 : &((font)->max_bounds))
1410 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1411 is not contained in the font. */
1413 static INLINE XCharStruct
*
1414 x_per_char_metric (font
, char2b
)
1418 /* The result metric information. */
1419 XCharStruct
*pcm
= NULL
;
1421 xassert (font
&& char2b
);
1423 if (font
->per_char
!= NULL
)
1425 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1427 /* min_char_or_byte2 specifies the linear character index
1428 corresponding to the first element of the per_char array,
1429 max_char_or_byte2 is the index of the last character. A
1430 character with non-zero CHAR2B->byte1 is not in the font.
1431 A character with byte2 less than min_char_or_byte2 or
1432 greater max_char_or_byte2 is not in the font. */
1433 if (char2b
->byte1
== 0
1434 && char2b
->byte2
>= font
->min_char_or_byte2
1435 && char2b
->byte2
<= font
->max_char_or_byte2
)
1436 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1440 /* If either min_byte1 or max_byte1 are nonzero, both
1441 min_char_or_byte2 and max_char_or_byte2 are less than
1442 256, and the 2-byte character index values corresponding
1443 to the per_char array element N (counting from 0) are:
1445 byte1 = N/D + min_byte1
1446 byte2 = N\D + min_char_or_byte2
1450 D = max_char_or_byte2 - min_char_or_byte2 + 1
1451 / = integer division
1452 \ = integer modulus */
1453 if (char2b
->byte1
>= font
->min_byte1
1454 && char2b
->byte1
<= font
->max_byte1
1455 && char2b
->byte2
>= font
->min_char_or_byte2
1456 && char2b
->byte2
<= font
->max_char_or_byte2
)
1458 pcm
= (font
->per_char
1459 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1460 * (char2b
->byte1
- font
->min_byte1
))
1461 + (char2b
->byte2
- font
->min_char_or_byte2
));
1467 /* If the per_char pointer is null, all glyphs between the first
1468 and last character indexes inclusive have the same
1469 information, as given by both min_bounds and max_bounds. */
1470 if (char2b
->byte2
>= font
->min_char_or_byte2
1471 && char2b
->byte2
<= font
->max_char_or_byte2
)
1472 pcm
= &font
->max_bounds
;
1475 return ((pcm
== NULL
1476 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1483 static XCharStruct
*
1484 mac_per_char_metric (font
, char2b
, font_type
)
1489 return x_per_char_metric (font
, char2b
);
1493 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1494 the two-byte form of C. Encoding is returned in *CHAR2B. */
1497 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1500 struct font_info
*font_info
;
1503 int charset
= CHAR_CHARSET (c
);
1504 XFontStruct
*font
= font_info
->font
;
1506 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1507 This may be either a program in a special encoder language or a
1509 if (font_info
->font_encoder
)
1511 /* It's a program. */
1512 struct ccl_program
*ccl
= font_info
->font_encoder
;
1514 if (CHARSET_DIMENSION (charset
) == 1)
1516 ccl
->reg
[0] = charset
;
1517 ccl
->reg
[1] = char2b
->byte2
;
1521 ccl
->reg
[0] = charset
;
1522 ccl
->reg
[1] = char2b
->byte1
;
1523 ccl
->reg
[2] = char2b
->byte2
;
1526 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1528 /* We assume that MSBs are appropriately set/reset by CCL
1530 if (font
->max_byte1
== 0) /* 1-byte font */
1531 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1533 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1535 else if (font_info
->encoding
[charset
])
1537 /* Fixed encoding scheme. See fontset.h for the meaning of the
1538 encoding numbers. */
1539 int enc
= font_info
->encoding
[charset
];
1541 if ((enc
== 1 || enc
== 2)
1542 && CHARSET_DIMENSION (charset
) == 2)
1543 char2b
->byte1
|= 0x80;
1545 if (enc
== 1 || enc
== 3)
1546 char2b
->byte2
|= 0x80;
1552 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1553 char2b
->byte1
= sjis1
;
1554 char2b
->byte2
= sjis2
;
1559 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1561 return FONT_TYPE_UNKNOWN
;
1566 /***********************************************************************
1568 ***********************************************************************/
1571 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1572 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1573 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1575 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1576 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1577 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1578 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1579 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1580 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1581 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1582 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1583 unsigned long *, double, int));*/
1584 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1585 double, int, unsigned long));
1586 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1587 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1588 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1589 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1590 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1591 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1593 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1594 int, int, int, int, Rect
*));
1595 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1596 int, int, int, Rect
*));
1599 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1603 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1608 struct glyph_string
*s
;
1610 if (s
->font
== FRAME_FONT (s
->f
)
1611 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1612 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1614 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1617 /* Cursor on non-default face: must merge. */
1621 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1622 xgcv
.foreground
= s
->face
->background
;
1624 /* If the glyph would be invisible, try a different foreground. */
1625 if (xgcv
.foreground
== xgcv
.background
)
1626 xgcv
.foreground
= s
->face
->foreground
;
1627 if (xgcv
.foreground
== xgcv
.background
)
1628 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1629 if (xgcv
.foreground
== xgcv
.background
)
1630 xgcv
.foreground
= s
->face
->foreground
;
1632 /* Make sure the cursor is distinct from text in this face. */
1633 if (xgcv
.background
== s
->face
->background
1634 && xgcv
.foreground
== s
->face
->foreground
)
1636 xgcv
.background
= s
->face
->foreground
;
1637 xgcv
.foreground
= s
->face
->background
;
1640 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1641 xgcv
.font
= s
->font
;
1642 mask
= GCForeground
| GCBackground
| GCFont
;
1644 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1645 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1648 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1649 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1651 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1656 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1659 x_set_mouse_face_gc (s
)
1660 struct glyph_string
*s
;
1665 /* What face has to be used last for the mouse face? */
1666 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1667 face
= FACE_FROM_ID (s
->f
, face_id
);
1669 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1671 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1672 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1674 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1675 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1676 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1678 /* If font in this face is same as S->font, use it. */
1679 if (s
->font
== s
->face
->font
)
1680 s
->gc
= s
->face
->gc
;
1683 /* Otherwise construct scratch_cursor_gc with values from FACE
1688 xgcv
.background
= s
->face
->background
;
1689 xgcv
.foreground
= s
->face
->foreground
;
1690 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1691 xgcv
.font
= s
->font
;
1692 mask
= GCForeground
| GCBackground
| GCFont
;
1694 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1695 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1698 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1699 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1701 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1704 xassert (s
->gc
!= 0);
1708 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1709 Faces to use in the mode line have already been computed when the
1710 matrix was built, so there isn't much to do, here. */
1713 x_set_mode_line_face_gc (s
)
1714 struct glyph_string
*s
;
1716 s
->gc
= s
->face
->gc
;
1720 /* Set S->gc of glyph string S for drawing that glyph string. Set
1721 S->stippled_p to a non-zero value if the face of S has a stipple
1725 x_set_glyph_string_gc (s
)
1726 struct glyph_string
*s
;
1728 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1730 if (s
->hl
== DRAW_NORMAL_TEXT
)
1732 s
->gc
= s
->face
->gc
;
1733 s
->stippled_p
= s
->face
->stipple
!= 0;
1735 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1737 x_set_mode_line_face_gc (s
);
1738 s
->stippled_p
= s
->face
->stipple
!= 0;
1740 else if (s
->hl
== DRAW_CURSOR
)
1742 x_set_cursor_gc (s
);
1745 else if (s
->hl
== DRAW_MOUSE_FACE
)
1747 x_set_mouse_face_gc (s
);
1748 s
->stippled_p
= s
->face
->stipple
!= 0;
1750 else if (s
->hl
== DRAW_IMAGE_RAISED
1751 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1753 s
->gc
= s
->face
->gc
;
1754 s
->stippled_p
= s
->face
->stipple
!= 0;
1758 s
->gc
= s
->face
->gc
;
1759 s
->stippled_p
= s
->face
->stipple
!= 0;
1762 /* GC must have been set. */
1763 xassert (s
->gc
!= 0);
1767 /* Set clipping for output of glyph string S. S may be part of a mode
1768 line or menu if we don't have X toolkit support. */
1771 x_set_glyph_string_clipping (s
)
1772 struct glyph_string
*s
;
1775 get_glyph_string_clip_rect (s
, &r
);
1776 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1781 Compute left and right overhang of glyph string S. If S is a glyph
1782 string for a composition, assume overhangs don't exist. */
1785 mac_compute_glyph_string_overhangs (s
)
1786 struct glyph_string
*s
;
1789 /* MAC_TODO: XTextExtents16 does nothing yet... */
1792 && s
->first_glyph
->type
== CHAR_GLYPH
)
1795 int direction
, font_ascent
, font_descent
;
1796 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1797 &font_ascent
, &font_descent
, &cs
);
1798 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1799 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1805 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1808 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1809 struct glyph_string
*s
;
1814 xgcv
.foreground
= s
->gc
->background
;
1815 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1819 /* Draw the background of glyph_string S. If S->background_filled_p
1820 is non-zero don't draw it. FORCE_P non-zero means draw the
1821 background even if it wouldn't be drawn normally. This is used
1822 when a string preceding S draws into the background of S, or S
1823 contains the first component of a composition. */
1826 x_draw_glyph_string_background (s
, force_p
)
1827 struct glyph_string
*s
;
1830 /* Nothing to do if background has already been drawn or if it
1831 shouldn't be drawn in the first place. */
1832 if (!s
->background_filled_p
)
1834 int box_line_width
= max (s
->face
->box_line_width
, 0);
1836 #if 0 /* MAC_TODO: stipple */
1839 /* Fill background with a stipple pattern. */
1840 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
1841 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
1842 s
->y
+ box_line_width
,
1843 s
->background_width
,
1844 s
->height
- 2 * box_line_width
);
1845 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
1846 s
->background_filled_p
= 1;
1850 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
1851 || s
->font_not_found_p
1852 || s
->extends_to_end_of_line_p
1855 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
1856 s
->background_width
,
1857 s
->height
- 2 * box_line_width
);
1858 s
->background_filled_p
= 1;
1864 /* Draw the foreground of glyph string S. */
1867 x_draw_glyph_string_foreground (s
)
1868 struct glyph_string
*s
;
1872 /* If first glyph of S has a left box line, start drawing the text
1873 of S to the right of that box line. */
1874 if (s
->face
->box
!= FACE_NO_BOX
1875 && s
->first_glyph
->left_box_line_p
)
1876 x
= s
->x
+ abs (s
->face
->box_line_width
);
1880 /* Draw characters of S as rectangles if S's font could not be
1882 if (s
->font_not_found_p
)
1884 for (i
= 0; i
< s
->nchars
; ++i
)
1886 struct glyph
*g
= s
->first_glyph
+ i
;
1887 mac_draw_rectangle (s
->display
, s
->window
,
1888 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
1890 x
+= g
->pixel_width
;
1895 char *char1b
= (char *) s
->char2b
;
1896 int boff
= s
->font_info
->baseline_offset
;
1898 if (s
->font_info
->vertical_centering
)
1899 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
1901 /* If we can use 8-bit functions, condense S->char2b. */
1903 for (i
= 0; i
< s
->nchars
; ++i
)
1904 char1b
[i
] = s
->char2b
[i
].byte2
;
1906 /* Draw text with XDrawString if background has already been
1907 filled. Otherwise, use XDrawImageString. (Note that
1908 XDrawImageString is usually faster than XDrawString.) Always
1909 use XDrawImageString when drawing the cursor so that there is
1910 no chance that characters under a box cursor are invisible. */
1911 if (s
->for_overlaps_p
1912 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
1914 /* Draw characters with 16-bit or 8-bit functions. */
1916 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
1917 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1919 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
1920 s
->ybase
- boff
, char1b
, s
->nchars
);
1925 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
1926 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
1928 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
1929 s
->ybase
- boff
, char1b
, s
->nchars
);
1934 /* Draw the foreground of composite glyph string S. */
1937 x_draw_composite_glyph_string_foreground (s
)
1938 struct glyph_string
*s
;
1942 /* If first glyph of S has a left box line, start drawing the text
1943 of S to the right of that box line. */
1944 if (s
->face
->box
!= FACE_NO_BOX
1945 && s
->first_glyph
->left_box_line_p
)
1946 x
= s
->x
+ abs (s
->face
->box_line_width
);
1950 /* S is a glyph string for a composition. S->gidx is the index of
1951 the first character drawn for glyphs of this composition.
1952 S->gidx == 0 means we are drawing the very first character of
1953 this composition. */
1955 /* Draw a rectangle for the composition if the font for the very
1956 first character of the composition could not be loaded. */
1957 if (s
->font_not_found_p
)
1960 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
1961 s
->width
- 1, s
->height
- 1);
1965 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
1966 XDrawString16 (s
->display
, s
->window
, s
->gc
,
1967 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
1968 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
1974 #ifdef USE_X_TOOLKIT
1976 static struct frame
*x_frame_of_widget
P_ ((Widget
));
1979 /* Return the frame on which widget WIDGET is used.. Abort if frame
1980 cannot be determined. */
1982 static struct frame
*
1983 x_frame_of_widget (widget
)
1986 struct x_display_info
*dpyinfo
;
1990 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
1992 /* Find the top-level shell of the widget. Note that this function
1993 can be called when the widget is not yet realized, so XtWindow
1994 (widget) == 0. That's the reason we can't simply use
1995 x_any_window_to_frame. */
1996 while (!XtIsTopLevelShell (widget
))
1997 widget
= XtParent (widget
);
1999 /* Look for a frame with that top-level widget. Allocate the color
2000 on that frame to get the right gamma correction value. */
2001 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2002 if (GC_FRAMEP (XCAR (tail
))
2003 && (f
= XFRAME (XCAR (tail
)),
2004 (f
->output_data
.nothing
!= 1
2005 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2006 && f
->output_data
.x
->widget
== widget
)
2013 /* Allocate the color COLOR->pixel on the screen and display of
2014 widget WIDGET in colormap CMAP. If an exact match cannot be
2015 allocated, try the nearest color available. Value is non-zero
2016 if successful. This is called from lwlib. */
2019 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2024 struct frame
*f
= x_frame_of_widget (widget
);
2025 return x_alloc_nearest_color (f
, cmap
, color
);
2029 #endif /* USE_X_TOOLKIT */
2031 #if 0 /* MAC_TODO */
2033 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2034 CMAP. If an exact match can't be allocated, try the nearest color
2035 available. Value is non-zero if successful. Set *COLOR to the
2039 x_alloc_nearest_color (f
, cmap
, color
)
2044 Display
*display
= FRAME_X_DISPLAY (f
);
2045 Screen
*screen
= FRAME_X_SCREEN (f
);
2048 gamma_correct (f
, color
);
2049 rc
= XAllocColor (display
, cmap
, color
);
2052 /* If we got to this point, the colormap is full, so we're going
2053 to try to get the next closest color. The algorithm used is
2054 a least-squares matching, which is what X uses for closest
2055 color matching with StaticColor visuals. */
2057 unsigned long nearest_delta
= ~0;
2058 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2059 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2061 for (i
= 0; i
< ncells
; ++i
)
2063 XQueryColors (display
, cmap
, cells
, ncells
);
2065 for (nearest
= i
= 0; i
< ncells
; ++i
)
2067 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2068 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2069 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2070 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2072 if (delta
< nearest_delta
)
2075 nearest_delta
= delta
;
2079 color
->red
= cells
[nearest
].red
;
2080 color
->green
= cells
[nearest
].green
;
2081 color
->blue
= cells
[nearest
].blue
;
2082 rc
= XAllocColor (display
, cmap
, color
);
2085 #ifdef DEBUG_X_COLORS
2087 register_color (color
->pixel
);
2088 #endif /* DEBUG_X_COLORS */
2094 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2095 It's necessary to do this instead of just using PIXEL directly to
2096 get color reference counts right. */
2099 x_copy_color (f
, pixel
)
2101 unsigned long pixel
;
2105 color
.pixel
= pixel
;
2107 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2108 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2110 #ifdef DEBUG_X_COLORS
2111 register_color (pixel
);
2117 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2118 It's necessary to do this instead of just using PIXEL directly to
2119 get color reference counts right. */
2122 x_copy_dpy_color (dpy
, cmap
, pixel
)
2125 unsigned long pixel
;
2129 color
.pixel
= pixel
;
2131 XQueryColor (dpy
, cmap
, &color
);
2132 XAllocColor (dpy
, cmap
, &color
);
2134 #ifdef DEBUG_X_COLORS
2135 register_color (pixel
);
2140 #endif /* MAC_TODO */
2142 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2143 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2144 If this produces the same color as COLOR, try a color where all RGB
2145 values have DELTA added. Return the allocated color in *COLOR.
2146 DISPLAY is the X display, CMAP is the colormap to operate on.
2147 Value is non-zero if successful. */
2150 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2152 unsigned long *color
;
2158 /* Change RGB values by specified FACTOR. Avoid overflow! */
2159 xassert (factor
>= 0);
2160 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2161 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2162 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2164 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2165 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2166 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2168 /* MAC_TODO: Map to palette and retry with delta if same? */
2169 /* MAC_TODO: Free colors (if using palette)? */
2180 /* Set up the foreground color for drawing relief lines of glyph
2181 string S. RELIEF is a pointer to a struct relief containing the GC
2182 with which lines will be drawn. Use a color that is FACTOR or
2183 DELTA lighter or darker than the relief's background which is found
2184 in S->f->output_data.x->relief_background. If such a color cannot
2185 be allocated, use DEFAULT_PIXEL, instead. */
2188 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2190 struct relief
*relief
;
2193 unsigned long default_pixel
;
2196 struct mac_output
*di
= f
->output_data
.mac
;
2197 unsigned long mask
= GCForeground
;
2198 unsigned long pixel
;
2199 unsigned long background
= di
->relief_background
;
2200 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2202 /* MAC_TODO: Free colors (if using palette)? */
2204 /* Allocate new color. */
2205 xgcv
.foreground
= default_pixel
;
2207 if (mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2209 relief
->allocated_p
= 1;
2210 xgcv
.foreground
= relief
->pixel
= pixel
;
2213 if (relief
->gc
== 0)
2215 #if 0 /* MAC_TODO: stipple */
2216 xgcv
.stipple
= dpyinfo
->gray
;
2219 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2222 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2226 /* Set up colors for the relief lines around glyph string S. */
2229 x_setup_relief_colors (s
)
2230 struct glyph_string
*s
;
2232 struct mac_output
*di
= s
->f
->output_data
.mac
;
2233 unsigned long color
;
2235 if (s
->face
->use_box_color_for_shadows_p
)
2236 color
= s
->face
->box_color
;
2241 /* Get the background color of the face. */
2242 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2243 color
= xgcv
.background
;
2246 if (di
->white_relief
.gc
== 0
2247 || color
!= di
->relief_background
)
2249 di
->relief_background
= color
;
2250 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2251 WHITE_PIX_DEFAULT (s
->f
));
2252 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2253 BLACK_PIX_DEFAULT (s
->f
));
2258 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2259 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2260 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2261 relief. LEFT_P non-zero means draw a relief on the left side of
2262 the rectangle. RIGHT_P non-zero means draw a relief on the right
2263 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2267 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2268 raised_p
, left_p
, right_p
, clip_rect
)
2270 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
, raised_p
;
2277 gc
= f
->output_data
.mac
->white_relief
.gc
;
2279 gc
= f
->output_data
.mac
->black_relief
.gc
;
2280 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), clip_rect
);
2283 for (i
= 0; i
< width
; ++i
)
2284 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2285 left_x
+ i
* left_p
, top_y
+ i
,
2286 right_x
+ 1 - i
* right_p
, top_y
+ i
);
2290 for (i
= 0; i
< width
; ++i
)
2291 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2292 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2294 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2296 gc
= f
->output_data
.mac
->black_relief
.gc
;
2298 gc
= f
->output_data
.mac
->white_relief
.gc
;
2299 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2303 for (i
= 0; i
< width
; ++i
)
2304 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2305 left_x
+ i
* left_p
, bottom_y
- i
,
2306 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
2310 for (i
= 0; i
< width
; ++i
)
2311 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), gc
,
2312 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
2314 mac_reset_clipping (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
2318 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2319 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2320 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2321 left side of the rectangle. RIGHT_P non-zero means draw a line
2322 on the right side of the rectangle. CLIP_RECT is the clipping
2323 rectangle to use when drawing. */
2326 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2327 left_p
, right_p
, clip_rect
)
2328 struct glyph_string
*s
;
2329 int left_x
, top_y
, right_x
, bottom_y
, left_p
, right_p
;
2334 xgcv
.foreground
= s
->face
->box_color
;
2335 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2338 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2339 left_x
, top_y
, right_x
- left_x
, width
);
2343 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2344 left_x
, top_y
, width
, bottom_y
- top_y
);
2347 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2348 left_x
, bottom_y
- width
, right_x
- left_x
, width
);
2352 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2353 right_x
- width
, top_y
, width
, bottom_y
- top_y
);
2355 mac_reset_clipping (s
->display
, s
->window
);
2359 /* Draw a box around glyph string S. */
2362 x_draw_glyph_string_box (s
)
2363 struct glyph_string
*s
;
2365 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2366 int left_p
, right_p
;
2367 struct glyph
*last_glyph
;
2370 last_x
= window_box_right (s
->w
, s
->area
);
2371 if (s
->row
->full_width_p
2372 && !s
->w
->pseudo_window_p
)
2374 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2375 if (s
->area
!= RIGHT_MARGIN_AREA
2376 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2377 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2380 /* The glyph that may have a right box line. */
2381 last_glyph
= (s
->cmp
|| s
->img
2383 : s
->first_glyph
+ s
->nchars
- 1);
2385 width
= abs (s
->face
->box_line_width
);
2386 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2388 right_x
= ((s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2390 : min (last_x
, s
->x
+ s
->background_width
) - 1));
2392 bottom_y
= top_y
+ s
->height
- 1;
2394 left_p
= (s
->first_glyph
->left_box_line_p
2395 || (s
->hl
== DRAW_MOUSE_FACE
2397 || s
->prev
->hl
!= s
->hl
)));
2398 right_p
= (last_glyph
->right_box_line_p
2399 || (s
->hl
== DRAW_MOUSE_FACE
2401 || s
->next
->hl
!= s
->hl
)));
2403 get_glyph_string_clip_rect (s
, &clip_rect
);
2405 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2406 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2407 left_p
, right_p
, &clip_rect
);
2410 x_setup_relief_colors (s
);
2411 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2412 width
, raised_p
, left_p
, right_p
, &clip_rect
);
2417 /* Draw foreground of image glyph string S. */
2420 x_draw_image_foreground (s
)
2421 struct glyph_string
*s
;
2424 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2426 /* If first glyph of S has a left box line, start drawing it to the
2427 right of that line. */
2428 if (s
->face
->box
!= FACE_NO_BOX
2429 && s
->first_glyph
->left_box_line_p
)
2430 x
= s
->x
+ abs (s
->face
->box_line_width
);
2434 /* If there is a margin around the image, adjust x- and y-position
2436 x
+= s
->img
->hmargin
;
2437 y
+= s
->img
->vmargin
;
2441 #if 0 /* MAC_TODO: image mask */
2444 /* We can't set both a clip mask and use XSetClipRectangles
2445 because the latter also sets a clip mask. We also can't
2446 trust on the shape extension to be available
2447 (XShapeCombineRegion). So, compute the rectangle to draw
2449 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
2452 XRectangle clip_rect
, image_rect
, r
;
2454 xgcv
.clip_mask
= s
->img
->mask
;
2455 xgcv
.clip_x_origin
= x
;
2456 xgcv
.clip_y_origin
= y
;
2457 xgcv
.function
= GXcopy
;
2458 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
2460 get_glyph_string_clip_rect (s
, &clip_rect
);
2463 image_rect
.width
= s
->img
->width
;
2464 image_rect
.height
= s
->img
->height
;
2465 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2466 XCopyArea (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2467 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
2470 #endif /* MAC_TODO */
2472 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2473 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2475 /* When the image has a mask, we can expect that at
2476 least part of a mouse highlight or a block cursor will
2477 be visible. If the image doesn't have a mask, make
2478 a block cursor visible by drawing a rectangle around
2479 the image. I believe it's looking better if we do
2480 nothing here for mouse-face. */
2481 if (s
->hl
== DRAW_CURSOR
)
2483 int r
= s
->img
->relief
;
2485 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2486 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
2491 /* Draw a rectangle if image could not be loaded. */
2492 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2493 s
->img
->width
- 1, s
->img
->height
- 1);
2498 /* Draw a relief around the image glyph string S. */
2501 x_draw_image_relief (s
)
2502 struct glyph_string
*s
;
2504 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2507 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2509 /* If first glyph of S has a left box line, start drawing it to the
2510 right of that line. */
2511 if (s
->face
->box
!= FACE_NO_BOX
2512 && s
->first_glyph
->left_box_line_p
)
2513 x
= s
->x
+ abs (s
->face
->box_line_width
);
2517 /* If there is a margin around the image, adjust x- and y-position
2519 x
+= s
->img
->hmargin
;
2520 y
+= s
->img
->vmargin
;
2522 if (s
->hl
== DRAW_IMAGE_SUNKEN
2523 || s
->hl
== DRAW_IMAGE_RAISED
)
2525 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2526 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2530 thick
= abs (s
->img
->relief
);
2531 raised_p
= s
->img
->relief
> 0;
2536 x1
= x
+ s
->img
->width
+ thick
- 1;
2537 y1
= y
+ s
->img
->height
+ thick
- 1;
2539 x_setup_relief_colors (s
);
2540 get_glyph_string_clip_rect (s
, &r
);
2541 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
2545 /* Draw the foreground of image glyph string S to PIXMAP. */
2548 x_draw_image_foreground_1 (s
, pixmap
)
2549 struct glyph_string
*s
;
2553 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
2555 /* If first glyph of S has a left box line, start drawing it to the
2556 right of that line. */
2557 if (s
->face
->box
!= FACE_NO_BOX
2558 && s
->first_glyph
->left_box_line_p
)
2559 x
= abs (s
->face
->box_line_width
);
2563 /* If there is a margin around the image, adjust x- and y-position
2565 x
+= s
->img
->hmargin
;
2566 y
+= s
->img
->vmargin
;
2570 #if 0 /* MAC_TODO: image mask */
2573 /* We can't set both a clip mask and use XSetClipRectangles
2574 because the latter also sets a clip mask. We also can't
2575 trust on the shape extension to be available
2576 (XShapeCombineRegion). So, compute the rectangle to draw
2578 unsigned long mask
= (GCClipMask
| GCClipXOrigin
| GCClipYOrigin
2582 xgcv
.clip_mask
= s
->img
->mask
;
2583 xgcv
.clip_x_origin
= x
;
2584 xgcv
.clip_y_origin
= y
;
2585 xgcv
.function
= GXcopy
;
2586 XChangeGC (s
->display
, s
->gc
, mask
, &xgcv
);
2588 XCopyArea (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2589 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2590 XSetClipMask (s
->display
, s
->gc
, None
);
2593 #endif /* MAC_TODO */
2595 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2596 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2598 /* When the image has a mask, we can expect that at
2599 least part of a mouse highlight or a block cursor will
2600 be visible. If the image doesn't have a mask, make
2601 a block cursor visible by drawing a rectangle around
2602 the image. I believe it's looking better if we do
2603 nothing here for mouse-face. */
2604 if (s
->hl
== DRAW_CURSOR
)
2606 int r
= s
->img
->relief
;
2608 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
- r
, y
- r
,
2609 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
2614 /* Draw a rectangle if image could not be loaded. */
2615 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2616 s
->img
->width
- 1, s
->img
->height
- 1);
2620 /* Draw part of the background of glyph string S. X, Y, W, and H
2621 give the rectangle to draw. */
2624 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2625 struct glyph_string
*s
;
2628 #if 0 /* MAC_TODO: stipple */
2631 /* Fill background with a stipple pattern. */
2632 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2633 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2634 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2637 #endif /* MAC_TODO */
2638 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2642 /* Draw image glyph string S.
2645 s->x +-------------------------
2648 | +-------------------------
2651 | | +-------------------
2657 x_draw_image_glyph_string (s
)
2658 struct glyph_string
*s
;
2661 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2662 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2666 height
= s
->height
- 2 * box_line_vwidth
;
2668 /* Fill background with face under the image. Do it only if row is
2669 taller than image or if image has a clip mask to reduce
2671 s
->stippled_p
= s
->face
->stipple
!= 0;
2672 if (height
> s
->img
->height
2675 #if 0 /* TODO: image mask */
2678 || s
->img
->pixmap
== 0
2679 || s
->width
!= s
->background_width
)
2681 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
2682 x
= s
->x
+ box_line_hwidth
;
2686 y
= s
->y
+ box_line_vwidth
;
2687 #if 0 /* TODO: image mask */
2690 /* Create a pixmap as large as the glyph string. Fill it
2691 with the background color. Copy the image to it, using
2692 its mask. Copy the temporary pixmap to the display. */
2693 Screen
*screen
= FRAME_X_SCREEN (s
->f
);
2694 int depth
= DefaultDepthOfScreen (screen
);
2696 /* Create a pixmap as large as the glyph string. */
2697 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2698 s
->background_width
,
2701 /* Don't clip in the following because we're working on the
2703 XSetClipMask (s
->display
, s
->gc
, None
);
2705 /* Fill the pixmap with the background color/stipple. */
2708 /* Fill background with a stipple pattern. */
2709 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2710 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2711 0, 0, s
->background_width
, s
->height
);
2712 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2717 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2719 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2720 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2721 0, 0, s
->background_width
, s
->height
);
2722 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2727 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2729 s
->background_filled_p
= 1;
2732 /* Draw the foreground. */
2735 x_draw_image_foreground_1 (s
, pixmap
);
2736 x_set_glyph_string_clipping (s
);
2737 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2738 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2739 mac_reset_clipping (s
->display
, s
->window
);
2740 XFreePixmap (s
->display
, pixmap
);
2743 x_draw_image_foreground (s
);
2745 /* If we must draw a relief around the image, do it. */
2747 || s
->hl
== DRAW_IMAGE_RAISED
2748 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2749 x_draw_image_relief (s
);
2753 /* Draw stretch glyph string S. */
2756 x_draw_stretch_glyph_string (s
)
2757 struct glyph_string
*s
;
2759 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2760 s
->stippled_p
= s
->face
->stipple
!= 0;
2762 if (s
->hl
== DRAW_CURSOR
2763 && !x_stretch_cursor_p
)
2765 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2766 as wide as the stretch glyph. */
2767 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2770 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2772 /* Clear rest using the GC of the original non-cursor face. */
2773 if (width
< s
->background_width
)
2775 GC gc
= s
->face
->gc
;
2776 int x
= s
->x
+ width
, y
= s
->y
;
2777 int w
= s
->background_width
- width
, h
= s
->height
;
2780 if (s
->row
->mouse_face_p
2781 && cursor_in_mouse_face_p (s
->w
))
2783 x_set_mouse_face_gc (s
);
2789 get_glyph_string_clip_rect (s
, &r
);
2790 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2792 #if 0 /* MAC_TODO: stipple */
2793 if (s
->face
->stipple
)
2795 /* Fill background with a stipple pattern. */
2796 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2797 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2798 XSetFillStyle (s
->display
, gc
, FillSolid
);
2801 #endif /* MAC_TODO */
2804 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
2805 XSetForeground (s
->display
, gc
, xgcv
.background
);
2806 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2807 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
2810 mac_reset_clipping (s
->display
, s
->window
);
2813 else if (!s
->background_filled_p
)
2814 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
2817 s
->background_filled_p
= 1;
2821 /* Draw glyph string S. */
2824 x_draw_glyph_string (s
)
2825 struct glyph_string
*s
;
2827 int relief_drawn_p
= 0;
2829 /* If S draws into the background of its successor, draw the
2830 background of the successor first so that S can draw into it.
2831 This makes S->next use XDrawString instead of XDrawImageString. */
2832 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
2834 xassert (s
->next
->img
== NULL
);
2835 x_set_glyph_string_gc (s
->next
);
2836 x_set_glyph_string_clipping (s
->next
);
2837 x_draw_glyph_string_background (s
->next
, 1);
2841 /* Set up S->gc, set clipping and draw S. */
2842 x_set_glyph_string_gc (s
);
2844 /* Draw relief (if any) in advance for char/composition so that the
2845 glyph string can be drawn over it. */
2846 if (!s
->for_overlaps_p
2847 && s
->face
->box
!= FACE_NO_BOX
2848 && (s
->first_glyph
->type
== CHAR_GLYPH
2849 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
2852 x_set_glyph_string_clipping (s
);
2853 x_draw_glyph_string_background (s
, 1);
2854 x_draw_glyph_string_box (s
);
2855 x_set_glyph_string_clipping (s
);
2859 x_set_glyph_string_clipping (s
);
2861 switch (s
->first_glyph
->type
)
2864 x_draw_image_glyph_string (s
);
2868 x_draw_stretch_glyph_string (s
);
2872 if (s
->for_overlaps_p
)
2873 s
->background_filled_p
= 1;
2875 x_draw_glyph_string_background (s
, 0);
2876 x_draw_glyph_string_foreground (s
);
2879 case COMPOSITE_GLYPH
:
2880 if (s
->for_overlaps_p
|| s
->gidx
> 0)
2881 s
->background_filled_p
= 1;
2883 x_draw_glyph_string_background (s
, 1);
2884 x_draw_composite_glyph_string_foreground (s
);
2891 if (!s
->for_overlaps_p
)
2893 /* Draw underline. */
2894 if (s
->face
->underline_p
)
2896 unsigned long h
= 1;
2897 unsigned long dy
= s
->height
- h
;
2899 if (s
->face
->underline_defaulted_p
)
2900 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2905 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2906 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
2907 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2909 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2913 /* Draw overline. */
2914 if (s
->face
->overline_p
)
2916 unsigned long dy
= 0, h
= 1;
2918 if (s
->face
->overline_color_defaulted_p
)
2919 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2924 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2925 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
2926 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2928 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2932 /* Draw strike-through. */
2933 if (s
->face
->strike_through_p
)
2935 unsigned long h
= 1;
2936 unsigned long dy
= (s
->height
- h
) / 2;
2938 if (s
->face
->strike_through_color_defaulted_p
)
2939 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2944 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2945 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
2946 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
2948 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2953 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
2954 x_draw_glyph_string_box (s
);
2957 /* Reset clipping. */
2958 mac_reset_clipping (s
->display
, s
->window
);
2961 /* Shift display to make room for inserted glyphs. */
2964 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
2966 int x
, y
, width
, height
, shift_by
;
2968 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
2969 f
->output_data
.mac
->normal_gc
,
2970 x
, y
, width
, height
,
2975 /* Delete N glyphs at the nominal cursor position. Not implemented
2986 /* Clear entire frame. If updating_frame is non-null, clear that
2987 frame. Otherwise clear the selected frame. */
2997 f
= SELECTED_FRAME ();
2999 /* Clearing the frame will erase any cursor, so mark them all as no
3001 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3002 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3003 output_cursor
.x
= -1;
3005 /* We don't set the output cursor here because there will always
3006 follow an explicit cursor_to. */
3008 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3010 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3011 /* We have to clear the scroll bars, too. If we have changed
3012 colors or something like that, then they should be notified. */
3013 x_scroll_bar_clear (f
);
3016 XFlush (FRAME_MAC_DISPLAY (f
));
3022 /* Invert the middle quarter of the frame for .15 sec. */
3024 /* We use the select system call to do the waiting, so we have to make
3025 sure it's available. If it isn't, we just won't do visual bells. */
3027 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3029 /* Subtract the `struct timeval' values X and Y, storing the result in
3030 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3033 timeval_subtract (result
, x
, y
)
3034 struct timeval
*result
, x
, y
;
3036 /* Perform the carry for the later subtraction by updating y. This
3037 is safer because on some systems the tv_sec member is unsigned. */
3038 if (x
.tv_usec
< y
.tv_usec
)
3040 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3041 y
.tv_usec
-= 1000000 * nsec
;
3045 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3047 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3048 y
.tv_usec
+= 1000000 * nsec
;
3052 /* Compute the time remaining to wait. tv_usec is certainly
3054 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3055 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3057 /* Return indication of whether the result should be considered
3059 return x
.tv_sec
< y
.tv_sec
;
3071 struct timeval wakeup
;
3073 EMACS_GET_TIME (wakeup
);
3075 /* Compute time to wait until, propagating carry from usecs. */
3076 wakeup
.tv_usec
+= 150000;
3077 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3078 wakeup
.tv_usec
%= 1000000;
3080 /* Keep waiting until past the time wakeup. */
3083 struct timeval timeout
;
3085 EMACS_GET_TIME (timeout
);
3087 /* In effect, timeout = wakeup - timeout.
3088 Break if result would be negative. */
3089 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3092 /* Try to wait that long--but we might wake up sooner. */
3093 select (0, NULL
, NULL
, NULL
, &timeout
);
3102 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3105 /* Make audible bell. */
3110 struct frame
*f
= SELECTED_FRAME ();
3112 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3120 XFlush (FRAME_MAC_DISPLAY (f
));
3127 /* Specify how many text lines, from the top of the window,
3128 should be affected by insert-lines and delete-lines operations.
3129 This, and those operations, are used only within an update
3130 that is bounded by calls to x_update_begin and x_update_end. */
3133 XTset_terminal_window (n
)
3136 /* This function intentionally left blank. */
3141 /***********************************************************************
3143 ***********************************************************************/
3145 /* Perform an insert-lines or delete-lines operation, inserting N
3146 lines or deleting -N lines at vertical position VPOS. */
3149 x_ins_del_lines (vpos
, n
)
3156 /* Scroll part of the display as described by RUN. */
3159 x_scroll_run (w
, run
)
3163 struct frame
*f
= XFRAME (w
->frame
);
3164 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3166 /* Get frame-relative bounding box of the text display area of W,
3167 without mode lines. Include in this box the left and right
3169 window_box (w
, -1, &x
, &y
, &width
, &height
);
3171 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3172 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3173 bottom_y
= y
+ height
;
3177 /* Scrolling up. Make sure we don't copy part of the mode
3178 line at the bottom. */
3179 if (from_y
+ run
->height
> bottom_y
)
3180 height
= bottom_y
- from_y
;
3182 height
= run
->height
;
3186 /* Scolling down. Make sure we don't copy over the mode line.
3188 if (to_y
+ run
->height
> bottom_y
)
3189 height
= bottom_y
- to_y
;
3191 height
= run
->height
;
3196 /* Cursor off. Will be switched on again in x_update_window_end. */
3200 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3201 f
->output_data
.mac
->normal_gc
,
3211 /***********************************************************************
3213 ***********************************************************************/
3220 x_update_cursor (f
, 1);
3224 frame_unhighlight (f
)
3227 x_update_cursor (f
, 1);
3230 /* The focus has changed. Update the frames as necessary to reflect
3231 the new situation. Note that we can't change the selected frame
3232 here, because the Lisp code we are interrupting might become confused.
3233 Each event gets marked with the frame in which it occurred, so the
3234 Lisp code can tell when the switch took place by examining the events. */
3237 x_new_focus_frame (dpyinfo
, frame
)
3238 struct x_display_info
*dpyinfo
;
3239 struct frame
*frame
;
3241 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3243 if (frame
!= dpyinfo
->x_focus_frame
)
3245 /* Set this before calling other routines, so that they see
3246 the correct value of x_focus_frame. */
3247 dpyinfo
->x_focus_frame
= frame
;
3249 if (old_focus
&& old_focus
->auto_lower
)
3250 x_lower_frame (old_focus
);
3253 selected_frame
= frame
;
3254 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3256 Fselect_window (selected_frame
->selected_window
, Qnil
);
3257 choose_minibuf_frame ();
3260 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3261 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3263 pending_autoraise_frame
= 0;
3266 x_frame_rehighlight (dpyinfo
);
3269 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3272 x_mouse_leave (dpyinfo
)
3273 struct x_display_info
*dpyinfo
;
3275 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3278 /* The focus has changed, or we have redirected a frame's focus to
3279 another frame (this happens when a frame uses a surrogate
3280 mini-buffer frame). Shift the highlight as appropriate.
3282 The FRAME argument doesn't necessarily have anything to do with which
3283 frame is being highlighted or un-highlighted; we only use it to find
3284 the appropriate X display info. */
3287 XTframe_rehighlight (frame
)
3288 struct frame
*frame
;
3292 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3296 x_frame_rehighlight (dpyinfo
)
3297 struct x_display_info
*dpyinfo
;
3299 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3301 if (dpyinfo
->x_focus_frame
)
3303 dpyinfo
->x_highlight_frame
3304 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3305 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3306 : dpyinfo
->x_focus_frame
);
3307 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3309 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3310 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3314 dpyinfo
->x_highlight_frame
= 0;
3316 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3319 frame_unhighlight (old_highlight
);
3320 if (dpyinfo
->x_highlight_frame
)
3321 frame_highlight (dpyinfo
->x_highlight_frame
);
3327 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3329 #if 0 /* MAC_TODO */
3330 /* Initialize mode_switch_bit and modifier_meaning. */
3332 x_find_modifier_meanings (dpyinfo
)
3333 struct x_display_info
*dpyinfo
;
3335 int min_code
, max_code
;
3338 XModifierKeymap
*mods
;
3340 dpyinfo
->meta_mod_mask
= 0;
3341 dpyinfo
->shift_lock_mask
= 0;
3342 dpyinfo
->alt_mod_mask
= 0;
3343 dpyinfo
->super_mod_mask
= 0;
3344 dpyinfo
->hyper_mod_mask
= 0;
3347 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3349 min_code
= dpyinfo
->display
->min_keycode
;
3350 max_code
= dpyinfo
->display
->max_keycode
;
3353 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3354 min_code
, max_code
- min_code
+ 1,
3356 mods
= XGetModifierMapping (dpyinfo
->display
);
3358 /* Scan the modifier table to see which modifier bits the Meta and
3359 Alt keysyms are on. */
3361 int row
, col
; /* The row and column in the modifier table. */
3363 for (row
= 3; row
< 8; row
++)
3364 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3367 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3369 /* Zeroes are used for filler. Skip them. */
3373 /* Are any of this keycode's keysyms a meta key? */
3377 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3379 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3385 dpyinfo
->meta_mod_mask
|= (1 << row
);
3390 dpyinfo
->alt_mod_mask
|= (1 << row
);
3395 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3400 dpyinfo
->super_mod_mask
|= (1 << row
);
3404 /* Ignore this if it's not on the lock modifier. */
3405 if ((1 << row
) == LockMask
)
3406 dpyinfo
->shift_lock_mask
= LockMask
;
3414 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3415 if (! dpyinfo
->meta_mod_mask
)
3417 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3418 dpyinfo
->alt_mod_mask
= 0;
3421 /* If some keys are both alt and meta,
3422 make them just meta, not alt. */
3423 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3425 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3428 XFree ((char *) syms
);
3429 XFreeModifiermap (mods
);
3432 #endif /* MAC_TODO */
3434 /* Convert between the modifier bits X uses and the modifier bits
3438 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3439 struct x_display_info
*dpyinfo
;
3440 unsigned short state
;
3442 return (((state
& shiftKey
) ? shift_modifier
: 0)
3443 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3444 | ((state
& cmdKey
) ? meta_modifier
: 0)
3445 | ((state
& optionKey
) ? alt_modifier
: 0));
3448 #if 0 /* MAC_TODO */
3449 static unsigned short
3450 x_emacs_to_x_modifiers (dpyinfo
, state
)
3451 struct x_display_info
*dpyinfo
;
3454 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3455 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3456 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3457 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3458 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3459 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3461 #endif /* MAC_TODO */
3463 /* Convert a keysym to its name. */
3466 x_get_keysym_name (keysym
)
3473 value
= XKeysymToString (keysym
);
3484 /* Mouse clicks and mouse movement. Rah. */
3486 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3488 If the event is a button press, then note that we have grabbed
3492 construct_mouse_click (result
, event
, f
)
3493 struct input_event
*result
;
3499 result
->kind
= MOUSE_CLICK_EVENT
;
3500 result
->code
= 0; /* only one mouse button */
3501 result
->timestamp
= event
->when
;
3502 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3504 mouseLoc
= event
->where
;
3506 #if TARGET_API_MAC_CARBON
3507 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
3509 SetPort (FRAME_MAC_WINDOW (f
));
3512 GlobalToLocal (&mouseLoc
);
3513 XSETINT (result
->x
, mouseLoc
.h
);
3514 XSETINT (result
->y
, mouseLoc
.v
);
3516 XSETFRAME (result
->frame_or_window
, f
);
3523 /* Function to report a mouse movement to the mainstream Emacs code.
3524 The input handler calls this.
3526 We have received a mouse movement event, which is given in *event.
3527 If the mouse is over a different glyph than it was last time, tell
3528 the mainstream emacs code by setting mouse_moved. If not, ask for
3529 another motion event, so we can check again the next time it moves. */
3531 static Point last_mouse_motion_position
;
3532 static Lisp_Object last_mouse_motion_frame
;
3535 note_mouse_movement (frame
, pos
)
3539 #if TARGET_API_MAC_CARBON
3543 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3544 last_mouse_motion_position
= *pos
;
3545 XSETFRAME (last_mouse_motion_frame
, frame
);
3547 #if TARGET_API_MAC_CARBON
3548 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3550 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3553 frame
->mouse_moved
= 1;
3554 last_mouse_scroll_bar
= Qnil
;
3555 note_mouse_highlight (frame
, -1, -1);
3557 /* Has the mouse moved off the glyph it was on at the last sighting? */
3558 else if (pos
->h
< last_mouse_glyph
.left
3559 || pos
->h
>= last_mouse_glyph
.right
3560 || pos
->v
< last_mouse_glyph
.top
3561 || pos
->v
>= last_mouse_glyph
.bottom
)
3563 frame
->mouse_moved
= 1;
3564 last_mouse_scroll_bar
= Qnil
;
3565 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3569 /* This is used for debugging, to turn off note_mouse_highlight. */
3571 int disable_mouse_highlight
;
3575 /************************************************************************
3577 ************************************************************************/
3579 static struct scroll_bar
*x_window_to_scroll_bar ();
3580 static void x_scroll_bar_report_motion ();
3581 static void x_check_fullscreen
P_ ((struct frame
*));
3582 static void x_check_fullscreen_move
P_ ((struct frame
*));
3583 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3586 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3589 redo_mouse_highlight ()
3591 if (!NILP (last_mouse_motion_frame
)
3592 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3593 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3594 last_mouse_motion_position
.h
,
3595 last_mouse_motion_position
.v
);
3599 /* Try to determine frame pixel position and size of the glyph under
3600 frame pixel coordinates X/Y on frame F . Return the position and
3601 size in *RECT. Value is non-zero if we could compute these
3605 glyph_rect (f
, x
, y
, rect
)
3612 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3616 struct window
*w
= XWINDOW (window
);
3617 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3618 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3620 for (; r
< end
&& r
->enabled_p
; ++r
)
3621 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3623 /* Found the row at y. */
3624 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3625 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3628 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3629 rect
->bottom
= rect
->top
+ r
->height
;
3633 /* x is to the left of the first glyph in the row. */
3634 /* Shouldn't this be a pixel value?
3635 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3637 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3638 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3642 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3643 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3645 /* x is on a glyph. */
3646 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3647 rect
->right
= rect
->left
+ g
->pixel_width
;
3651 /* x is to the right of the last glyph in the row. */
3652 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3653 /* Shouldn't this be a pixel value?
3654 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3656 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3661 /* The y is not on any row. */
3665 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3667 /* Record the position of the mouse in last_mouse_glyph. */
3669 remember_mouse_glyph (f1
, gx
, gy
)
3673 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3675 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3676 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3678 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3679 round down even for negative values. */
3685 /* This was the original code from XTmouse_position, but it seems
3686 to give the position of the glyph diagonally next to the one
3687 the mouse is over. */
3688 gx
= (gx
+ width
- 1) / width
* width
;
3689 gy
= (gy
+ height
- 1) / height
* height
;
3691 gx
= gx
/ width
* width
;
3692 gy
= gy
/ height
* height
;
3695 last_mouse_glyph
.left
= gx
;
3696 last_mouse_glyph
.top
= gy
;
3697 last_mouse_glyph
.right
= gx
+ width
;
3698 last_mouse_glyph
.bottom
= gy
+ height
;
3703 /* Return the current position of the mouse.
3704 *fp should be a frame which indicates which display to ask about.
3706 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3707 and *part to the frame, window, and scroll bar part that the mouse
3708 is over. Set *x and *y to the portion and whole of the mouse's
3709 position on the scroll bar.
3711 If the mouse movement started elsewhere, set *fp to the frame the
3712 mouse is on, *bar_window to nil, and *x and *y to the character cell
3715 Set *time to the server time-stamp for the time at which the mouse
3716 was at this position.
3718 Don't store anything if we don't have a valid set of values to report.
3720 This clears the mouse_moved flag, so we can wait for the next mouse
3724 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3727 Lisp_Object
*bar_window
;
3728 enum scroll_bar_part
*part
;
3730 unsigned long *time
;
3733 int ignore1
, ignore2
;
3734 WindowPtr wp
= FrontWindow ();
3736 Lisp_Object frame
, tail
;
3738 if (is_emacs_window(wp
))
3739 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
3743 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3744 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3747 /* Clear the mouse-moved flag for every frame on this display. */
3748 FOR_EACH_FRAME (tail
, frame
)
3749 XFRAME (frame
)->mouse_moved
= 0;
3751 last_mouse_scroll_bar
= Qnil
;
3753 #if TARGET_API_MAC_CARBON
3754 SetPort (GetWindowPort (wp
));
3759 GetMouse (&mouse_pos
);
3761 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3762 &last_mouse_glyph
, insist
);
3765 *part
= scroll_bar_handle
;
3767 XSETINT (*x
, mouse_pos
.h
);
3768 XSETINT (*y
, mouse_pos
.v
);
3769 *time
= last_mouse_movement_time
;
3776 /***********************************************************************
3778 ***********************************************************************/
3780 /* Handle mouse button event on the tool-bar of frame F, at
3781 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3785 mac_handle_tool_bar_click (f
, button_event
)
3787 EventRecord
*button_event
;
3789 int x
= button_event
->where
.h
;
3790 int y
= button_event
->where
.v
;
3792 if (button_event
->what
== mouseDown
)
3793 handle_tool_bar_click (f
, x
, y
, 1, 0);
3795 handle_tool_bar_click (f
, x
, y
, 0,
3796 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3797 button_event
->modifiers
));
3801 /************************************************************************
3802 Scroll bars, general
3803 ************************************************************************/
3805 /* Create a scroll bar and return the scroll bar vector for it. W is
3806 the Emacs window on which to create the scroll bar. TOP, LEFT,
3807 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
3810 static struct scroll_bar
*
3811 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
3813 int top
, left
, width
, height
, disp_top
, disp_height
;
3815 struct frame
*f
= XFRAME (w
->frame
);
3816 struct scroll_bar
*bar
3817 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
3825 r
.right
= left
+ width
;
3826 r
.bottom
= disp_top
+ disp_height
;
3828 #ifdef TARGET_API_MAC_CARBON
3829 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
3830 kControlScrollBarProc
, 0L);
3832 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
3835 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
3836 SetControlReference (ch
, (long) bar
);
3838 XSETWINDOW (bar
->window
, w
);
3839 XSETINT (bar
->top
, top
);
3840 XSETINT (bar
->left
, left
);
3841 XSETINT (bar
->width
, width
);
3842 XSETINT (bar
->height
, height
);
3843 XSETINT (bar
->start
, 0);
3844 XSETINT (bar
->end
, 0);
3845 bar
->dragging
= Qnil
;
3847 /* Add bar to its frame's list of scroll bars. */
3848 bar
->next
= FRAME_SCROLL_BARS (f
);
3850 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
3851 if (!NILP (bar
->next
))
3852 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
3859 /* Draw BAR's handle in the proper position.
3861 If the handle is already drawn from START to END, don't bother
3862 redrawing it, unless REBUILD is non-zero; in that case, always
3863 redraw it. (REBUILD is handy for drawing the handle after expose
3866 Normally, we want to constrain the start and end of the handle to
3867 fit inside its rectangle, but if the user is dragging the scroll
3868 bar handle, we want to let them drag it down all the way, so that
3869 the bar's top is as far down as it goes; otherwise, there's no way
3870 to move to the very end of the buffer. */
3873 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
3874 struct scroll_bar
*bar
;
3878 int dragging
= ! NILP (bar
->dragging
);
3879 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
3880 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3881 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
3882 int length
= end
- start
;
3884 /* If the display is already accurate, do nothing. */
3886 && start
== XINT (bar
->start
)
3887 && end
== XINT (bar
->end
))
3892 /* Make sure the values are reasonable, and try to preserve the
3893 distance between start and end. */
3896 else if (start
> top_range
)
3898 end
= start
+ length
;
3902 else if (end
> top_range
&& ! dragging
)
3905 /* Store the adjusted setting in the scroll bar. */
3906 XSETINT (bar
->start
, start
);
3907 XSETINT (bar
->end
, end
);
3909 /* Clip the end position, just for display. */
3910 if (end
> top_range
)
3913 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
3914 top positions, to make sure the handle is always at least that
3915 many pixels tall. */
3916 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
3918 SetControlMinimum (ch
, 0);
3919 /* Don't inadvertently activate deactivated scroll bars */
3920 if (GetControlMaximum (ch
) != -1)
3921 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
3923 SetControlValue (ch
, start
);
3924 #if TARGET_API_MAC_CARBON
3925 SetControlViewSize (ch
, end
- start
);
3932 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
3936 x_scroll_bar_remove (bar
)
3937 struct scroll_bar
*bar
;
3939 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
3943 /* Destroy the Mac scroll bar control */
3944 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
3946 /* Disassociate this scroll bar from its window. */
3947 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
3952 /* Set the handle of the vertical scroll bar for WINDOW to indicate
3953 that we are displaying PORTION characters out of a total of WHOLE
3954 characters, starting at POSITION. If WINDOW has no scroll bar,
3957 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
3959 int portion
, whole
, position
;
3961 struct frame
*f
= XFRAME (w
->frame
);
3962 struct scroll_bar
*bar
;
3963 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
3964 int window_y
, window_height
;
3966 /* Get window dimensions. */
3967 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
3972 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
3974 height
= window_height
;
3976 /* Compute the left edge of the scroll bar area. */
3977 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
3979 /* Compute the width of the scroll bar which might be less than
3980 the width of the area reserved for the scroll bar. */
3981 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
3982 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
3986 /* Compute the left edge of the scroll bar. */
3987 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
3988 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
3990 sb_left
= left
+ (width
- sb_width
) / 2;
3992 /* Adjustments according to Inside Macintosh to make it look nice */
3994 disp_height
= height
;
4000 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4006 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4009 /* Does the scroll bar exist yet? */
4010 if (NILP (w
->vertical_scroll_bar
))
4013 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4014 left
, top
, width
, height
, 0);
4016 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4018 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4022 /* It may just need to be moved and resized. */
4025 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4026 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4030 /* If already correctly positioned, do nothing. */
4031 if (XINT (bar
->left
) == sb_left
4032 && XINT (bar
->top
) == top
4033 && XINT (bar
->width
) == sb_width
4034 && XINT (bar
->height
) == height
)
4038 /* Clear areas not covered by the scroll bar because it's not as
4039 wide as the area reserved for it . This makes sure a
4040 previous mode line display is cleared after C-x 2 C-x 1, for
4042 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4043 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4044 left
, top
, area_width
, height
, 0);
4047 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4048 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4049 sb_left
- 1, top
, 1, height
, 0);
4053 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4054 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4058 /* Remember new settings. */
4059 XSETINT (bar
->left
, sb_left
);
4060 XSETINT (bar
->top
, top
);
4061 XSETINT (bar
->width
, sb_width
);
4062 XSETINT (bar
->height
, height
);
4068 /* Set the scroll bar's current state, unless we're currently being
4070 if (NILP (bar
->dragging
))
4072 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4075 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4078 int start
= ((double) position
* top_range
) / whole
;
4079 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4080 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4086 /* The following three hooks are used when we're doing a thorough
4087 redisplay of the frame. We don't explicitly know which scroll bars
4088 are going to be deleted, because keeping track of when windows go
4089 away is a real pain - "Can you say set-window-configuration, boys
4090 and girls?" Instead, we just assert at the beginning of redisplay
4091 that *all* scroll bars are to be removed, and then save a scroll bar
4092 from the fiery pit when we actually redisplay its window. */
4094 /* Arrange for all scroll bars on FRAME to be removed at the next call
4095 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4096 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4099 XTcondemn_scroll_bars (frame
)
4102 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4103 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4106 bar
= FRAME_SCROLL_BARS (frame
);
4107 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4108 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4109 XSCROLL_BAR (bar
)->prev
= Qnil
;
4110 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4111 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4112 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4117 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4118 Note that WINDOW isn't necessarily condemned at all. */
4121 XTredeem_scroll_bar (window
)
4122 struct window
*window
;
4124 struct scroll_bar
*bar
;
4126 /* We can't redeem this window's scroll bar if it doesn't have one. */
4127 if (NILP (window
->vertical_scroll_bar
))
4130 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4132 /* Unlink it from the condemned list. */
4134 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4136 if (NILP (bar
->prev
))
4138 /* If the prev pointer is nil, it must be the first in one of
4140 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4141 /* It's not condemned. Everything's fine. */
4143 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4144 window
->vertical_scroll_bar
))
4145 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4147 /* If its prev pointer is nil, it must be at the front of
4148 one or the other! */
4152 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4154 if (! NILP (bar
->next
))
4155 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4157 bar
->next
= FRAME_SCROLL_BARS (f
);
4159 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4160 if (! NILP (bar
->next
))
4161 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4165 /* Remove all scroll bars on FRAME that haven't been saved since the
4166 last call to `*condemn_scroll_bars_hook'. */
4169 XTjudge_scroll_bars (f
)
4172 Lisp_Object bar
, next
;
4174 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4176 /* Clear out the condemned list now so we won't try to process any
4177 more events on the hapless scroll bars. */
4178 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4180 for (; ! NILP (bar
); bar
= next
)
4182 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4184 x_scroll_bar_remove (b
);
4187 b
->next
= b
->prev
= Qnil
;
4190 /* Now there should be no references to the condemned scroll bars,
4191 and they should get garbage-collected. */
4196 activate_scroll_bars (frame
)
4202 bar
= FRAME_SCROLL_BARS (frame
);
4203 while (! NILP (bar
))
4205 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4206 #ifdef TARGET_API_MAC_CARBON
4207 ActivateControl (ch
);
4209 SetControlMaximum (ch
,
4210 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4211 XINT (XSCROLL_BAR (bar
)
4214 bar
= XSCROLL_BAR (bar
)->next
;
4220 deactivate_scroll_bars (frame
)
4226 bar
= FRAME_SCROLL_BARS (frame
);
4227 while (! NILP (bar
))
4229 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4230 #ifdef TARGET_API_MAC_CARBON
4231 DeactivateControl (ch
);
4233 SetControlMaximum (ch
, XINT (-1));
4235 bar
= XSCROLL_BAR (bar
)->next
;
4239 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4240 is set to something other than NO_EVENT, it is enqueued.
4242 This may be called from a signal handler, so we have to ignore GC
4246 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4247 struct scroll_bar
*bar
;
4250 struct input_event
*bufp
;
4252 if (! GC_WINDOWP (bar
->window
))
4255 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4256 bufp
->frame_or_window
= bar
->window
;
4259 bar
->dragging
= Qnil
;
4263 case kControlUpButtonPart
:
4264 bufp
->part
= scroll_bar_up_arrow
;
4266 case kControlDownButtonPart
:
4267 bufp
->part
= scroll_bar_down_arrow
;
4269 case kControlPageUpPart
:
4270 bufp
->part
= scroll_bar_above_handle
;
4272 case kControlPageDownPart
:
4273 bufp
->part
= scroll_bar_below_handle
;
4275 #ifdef TARGET_API_MAC_CARBON
4278 case kControlIndicatorPart
:
4280 if (er
->what
== mouseDown
)
4281 bar
->dragging
= make_number (0);
4282 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4283 bufp
->part
= scroll_bar_handle
;
4289 /* Handle some mouse motion while someone is dragging the scroll bar.
4291 This may be called from a signal handler, so we have to ignore GC
4295 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4296 struct scroll_bar
*bar
;
4300 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4302 last_mouse_movement_time
= t
;
4305 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4307 /* If we're dragging the bar, display it. */
4308 if (! GC_NILP (bar
->dragging
))
4310 /* Where should the handle be now? */
4311 int new_start
= y_pos
- 24;
4313 if (new_start
!= XINT (bar
->start
))
4315 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4317 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4323 /* Return information to the user about the current position of the
4324 mouse on the scroll bar. */
4327 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4329 Lisp_Object
*bar_window
;
4330 enum scroll_bar_part
*part
;
4332 unsigned long *time
;
4334 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4335 WindowPtr wp
= FrontWindow ();
4337 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
4338 int win_y
, top_range
;
4340 #if TARGET_API_MAC_CARBON
4341 SetPort (GetWindowPort (wp
));
4346 GetMouse (&mouse_pos
);
4348 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4349 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4351 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4355 if (! NILP (bar
->dragging
))
4356 win_y
-= XINT (bar
->dragging
);
4360 if (win_y
> top_range
)
4364 *bar_window
= bar
->window
;
4366 if (! NILP (bar
->dragging
))
4367 *part
= scroll_bar_handle
;
4368 else if (win_y
< XINT (bar
->start
))
4369 *part
= scroll_bar_above_handle
;
4370 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4371 *part
= scroll_bar_handle
;
4373 *part
= scroll_bar_below_handle
;
4375 XSETINT (*x
, win_y
);
4376 XSETINT (*y
, top_range
);
4379 last_mouse_scroll_bar
= Qnil
;
4381 *time
= last_mouse_movement_time
;
4384 /***********************************************************************
4386 ***********************************************************************/
4388 /* Set clipping for output in glyph row ROW. W is the window in which
4389 we operate. GC is the graphics context to set clipping in.
4391 ROW may be a text row or, e.g., a mode line. Text rows must be
4392 clipped to the interior of the window dedicated to text display,
4393 mode lines must be clipped to the whole window. */
4396 x_clip_to_row (w
, row
, gc
)
4398 struct glyph_row
*row
;
4401 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4403 int window_y
, window_width
;
4405 window_box (w
, -1, 0, &window_y
, &window_width
, 0);
4407 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4408 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4409 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4410 clip_rect
.right
= clip_rect
.left
+ window_width
;
4411 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4413 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4417 /* Draw a hollow box cursor on window W in glyph row ROW. */
4420 x_draw_hollow_cursor (w
, row
)
4422 struct glyph_row
*row
;
4424 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4425 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4426 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4429 struct glyph
*cursor_glyph
;
4432 /* Compute frame-relative coordinates from window-relative
4434 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4435 y
= (WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
)
4436 + row
->ascent
- w
->phys_cursor_ascent
);
4437 h
= row
->height
- 1;
4439 /* Get the glyph the cursor is on. If we can't tell because
4440 the current matrix is invalid or such, give up. */
4441 cursor_glyph
= get_phys_cursor_glyph (w
);
4442 if (cursor_glyph
== NULL
)
4445 /* Compute the width of the rectangle to draw. If on a stretch
4446 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4447 rectangle as wide as the glyph, but use a canonical character
4449 wd
= cursor_glyph
->pixel_width
- 1;
4450 if (cursor_glyph
->type
== STRETCH_GLYPH
4451 && !x_stretch_cursor_p
)
4452 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4454 /* The foreground of cursor_gc is typically the same as the normal
4455 background color, which can cause the cursor box to be invisible. */
4456 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4457 if (dpyinfo
->scratch_cursor_gc
)
4458 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4460 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4461 GCForeground
, &xgcv
);
4462 gc
= dpyinfo
->scratch_cursor_gc
;
4464 /* Set clipping, draw the rectangle, and reset clipping again. */
4465 x_clip_to_row (w
, row
, gc
);
4466 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4467 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4471 /* Draw a bar cursor on window W in glyph row ROW.
4473 Implementation note: One would like to draw a bar cursor with an
4474 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4475 Unfortunately, I didn't find a font yet that has this property set.
4479 x_draw_bar_cursor (w
, row
, width
)
4481 struct glyph_row
*row
;
4484 /* If cursor hpos is out of bounds, don't draw garbage. This can
4485 happen in mini-buffer windows when switching between echo area
4486 glyphs and mini-buffer. */
4487 if (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])
4489 struct frame
*f
= XFRAME (w
->frame
);
4490 struct glyph
*cursor_glyph
;
4498 cursor_glyph
= get_phys_cursor_glyph (w
);
4499 if (cursor_glyph
== NULL
)
4502 xgcv
.background
= f
->output_data
.mac
->cursor_pixel
;
4503 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4504 mask
= GCForeground
| GCBackground
;
4505 dpy
= FRAME_MAC_DISPLAY (f
);
4506 window
= FRAME_MAC_WINDOW (f
);
4507 gc
= FRAME_X_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4510 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4513 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4514 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4518 width
= FRAME_CURSOR_WIDTH (f
);
4520 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4521 x_clip_to_row (w
, row
, gc
);
4522 XFillRectangle (dpy
, window
, gc
,
4524 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4525 min (cursor_glyph
->pixel_width
, width
),
4527 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4532 /* RIF: Define cursor CURSOR on frame F. */
4535 mac_define_frame_cursor (f
, cursor
)
4543 /* RIF: Clear area on frame F. */
4546 mac_clear_frame_area (f
, x
, y
, width
, height
)
4548 int x
, y
, width
, height
;
4550 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4551 x
, y
, width
, height
, 0);
4555 /* RIF: Draw cursor on window W. */
4558 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4560 struct glyph_row
*glyph_row
;
4562 int cursor_type
, cursor_width
;
4567 w
->phys_cursor_type
= cursor_type
;
4568 w
->phys_cursor_width
= cursor_width
;
4569 w
->phys_cursor_on_p
= 1;
4571 if (glyph_row
->exact_window_width_line_p
4572 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4574 glyph_row
->cursor_in_fringe_p
= 1;
4575 draw_fringe_bitmap (w
, glyph_row
, 0);
4579 switch (cursor_type
)
4581 case HOLLOW_BOX_CURSOR
:
4582 x_draw_hollow_cursor (w
, glyph_row
);
4585 case FILLED_BOX_CURSOR
:
4586 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4590 /* TODO. For now, just draw bar cursor. */
4592 x_draw_bar_cursor (w
, glyph_row
, cursor_width
);
4607 #if 0 /* MAC_TODO: no icon support yet. */
4609 x_bitmap_icon (f
, icon
)
4615 if (FRAME_W32_WINDOW (f
) == 0)
4619 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4620 else if (STRINGP (icon
))
4621 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4622 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4623 else if (SYMBOLP (icon
))
4627 if (EQ (icon
, intern ("application")))
4628 name
= (LPCTSTR
) IDI_APPLICATION
;
4629 else if (EQ (icon
, intern ("hand")))
4630 name
= (LPCTSTR
) IDI_HAND
;
4631 else if (EQ (icon
, intern ("question")))
4632 name
= (LPCTSTR
) IDI_QUESTION
;
4633 else if (EQ (icon
, intern ("exclamation")))
4634 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4635 else if (EQ (icon
, intern ("asterisk")))
4636 name
= (LPCTSTR
) IDI_ASTERISK
;
4637 else if (EQ (icon
, intern ("winlogo")))
4638 name
= (LPCTSTR
) IDI_WINLOGO
;
4642 hicon
= LoadIcon (NULL
, name
);
4650 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4655 #endif /* MAC_TODO */
4657 /************************************************************************
4659 ************************************************************************/
4661 /* Display Error Handling functions not used on W32. Listing them here
4662 helps diff stay in step when comparing w32term.c with xterm.c.
4664 x_error_catcher (display, error)
4665 x_catch_errors (dpy)
4666 x_catch_errors_unwind (old_val)
4667 x_check_errors (dpy, format)
4668 x_had_errors_p (dpy)
4669 x_clear_errors (dpy)
4670 x_uncatch_errors (dpy, count)
4672 x_connection_signal (signalnum)
4673 x_connection_closed (dpy, error_message)
4674 x_error_quitter (display, error)
4675 x_error_handler (display, error)
4676 x_io_error_quitter (display)
4681 /* Changing the font of the frame. */
4683 /* Give frame F the font named FONTNAME as its default font, and
4684 return the full name of that font. FONTNAME may be a wildcard
4685 pattern; in that case, we choose some font that fits the pattern.
4686 The return value shows which font we chose. */
4689 x_new_font (f
, fontname
)
4691 register char *fontname
;
4693 struct font_info
*fontp
4694 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4699 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4700 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4701 FRAME_FONTSET (f
) = -1;
4703 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4704 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4706 compute_fringe_widths (f
, 1);
4708 /* Compute the scroll bar width in character columns. */
4709 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4711 int wid
= FRAME_COLUMN_WIDTH (f
);
4712 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4713 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4717 int wid
= FRAME_COLUMN_WIDTH (f
);
4718 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4721 /* Now make the frame display the given font. */
4722 if (FRAME_MAC_WINDOW (f
) != 0)
4724 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4726 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4728 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4731 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4732 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4735 return build_string (fontp
->full_name
);
4738 /* Give frame F the fontset named FONTSETNAME as its default font, and
4739 return the full name of that fontset. FONTSETNAME may be a wildcard
4740 pattern; in that case, we choose some fontset that fits the pattern.
4741 The return value shows which fontset we chose. */
4744 x_new_fontset (f
, fontsetname
)
4748 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
4754 if (FRAME_FONTSET (f
) == fontset
)
4755 /* This fontset is already set in frame F. There's nothing more
4757 return fontset_name (fontset
);
4759 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
4761 if (!STRINGP (result
))
4762 /* Can't load ASCII font. */
4765 /* Since x_new_font doesn't update any fontset information, do it now. */
4766 FRAME_FONTSET(f
) = fontset
;
4768 return build_string (fontsetname
);
4772 /***********************************************************************
4773 TODO: W32 Input Methods
4774 ***********************************************************************/
4775 /* Listing missing functions from xterm.c helps diff stay in step.
4777 xim_destroy_callback (xim, client_data, call_data)
4778 xim_open_dpy (dpyinfo, resource_name)
4780 xim_instantiate_callback (display, client_data, call_data)
4781 xim_initialize (dpyinfo, resource_name)
4782 xim_close_dpy (dpyinfo)
4787 /* Calculate the absolute position in frame F
4788 from its current recorded position values and gravity. */
4791 x_calc_absolute_position (f
)
4795 int flags
= f
->size_hint_flags
;
4799 /* Find the position of the outside upper-left corner of
4800 the inner window, with respect to the outer window. */
4801 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
4804 GetPort (&savePort
);
4806 #if TARGET_API_MAC_CARBON
4807 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
4809 SetPort (FRAME_MAC_WINDOW (f
));
4812 #if TARGET_API_MAC_CARBON
4816 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
4817 SetPt(&pt
, r
.left
, r
.top
);
4819 #else /* not TARGET_API_MAC_CARBON */
4820 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
4821 #endif /* not TARGET_API_MAC_CARBON */
4822 LocalToGlobal (&pt
);
4826 /* Treat negative positions as relative to the leftmost bottommost
4827 position that fits on the screen. */
4828 if (flags
& XNegative
)
4829 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
4830 - 2 * f
->border_width
- pt
.h
4831 - FRAME_PIXEL_WIDTH (f
)
4833 /* NTEMACS_TODO: Subtract menubar height? */
4834 if (flags
& YNegative
)
4835 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
4836 - 2 * f
->border_width
- pt
.v
4837 - FRAME_PIXEL_HEIGHT (f
)
4839 /* The left_pos and top_pos
4840 are now relative to the top and left screen edges,
4841 so the flags should correspond. */
4842 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4845 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
4846 to really change the position, and 0 when calling from
4847 x_make_frame_visible (in that case, XOFF and YOFF are the current
4848 position values). It is -1 when calling from x_set_frame_parameters,
4849 which means, do adjust for borders but don't change the gravity. */
4852 x_set_offset (f
, xoff
, yoff
, change_gravity
)
4854 register int xoff
, yoff
;
4857 int modified_top
, modified_left
;
4859 if (change_gravity
> 0)
4863 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
4865 f
->size_hint_flags
|= XNegative
;
4867 f
->size_hint_flags
|= YNegative
;
4868 f
->win_gravity
= NorthWestGravity
;
4870 x_calc_absolute_position (f
);
4873 x_wm_set_size_hint (f
, (long) 0, 0);
4875 modified_left
= f
->left_pos
;
4876 modified_top
= f
->top_pos
;
4878 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
4879 modified_top
+ 42, false);
4884 /* Call this to change the size of frame F's x-window.
4885 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
4886 for this size change and subsequent size changes.
4887 Otherwise we leave the window gravity unchanged. */
4890 x_set_window_size (f
, change_gravity
, cols
, rows
)
4895 int pixelwidth
, pixelheight
;
4899 check_frame_size (f
, &rows
, &cols
);
4900 f
->scroll_bar_actual_width
4901 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
4903 compute_fringe_widths (f
, 0);
4905 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
4906 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
4908 f
->win_gravity
= NorthWestGravity
;
4909 x_wm_set_size_hint (f
, (long) 0, 0);
4911 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
4913 /* Now, strictly speaking, we can't be sure that this is accurate,
4914 but the window manager will get around to dealing with the size
4915 change request eventually, and we'll hear how it went when the
4916 ConfigureNotify event gets here.
4918 We could just not bother storing any of this information here,
4919 and let the ConfigureNotify event set everything up, but that
4920 might be kind of confusing to the Lisp code, since size changes
4921 wouldn't be reported in the frame parameters until some random
4922 point in the future when the ConfigureNotify event arrives.
4924 We pass 1 for DELAY since we can't run Lisp code inside of
4926 change_frame_size (f
, rows
, cols
, 0, 1, 0);
4927 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
4928 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
4930 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
4931 receive in the ConfigureNotify event; if we get what we asked
4932 for, then the event won't cause the screen to become garbaged, so
4933 we have to make sure to do it here. */
4934 SET_FRAME_GARBAGED (f
);
4936 XFlush (FRAME_X_DISPLAY (f
));
4938 /* If cursor was outside the new size, mark it as off. */
4939 mark_window_cursors_off (XWINDOW (f
->root_window
));
4941 /* Clear out any recollection of where the mouse highlighting was,
4942 since it might be in a place that's outside the new frame size.
4943 Actually checking whether it is outside is a pain in the neck,
4944 so don't try--just let the highlighting be done afresh with new size. */
4945 cancel_mouse_face (f
);
4950 /* Mouse warping. */
4952 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
4955 x_set_mouse_position (f
, x
, y
)
4961 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
4962 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
4964 if (pix_x
< 0) pix_x
= 0;
4965 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
4967 if (pix_y
< 0) pix_y
= 0;
4968 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
4970 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
4974 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
4978 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
4981 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
4982 0, 0, 0, 0, pix_x
, pix_y
);
4988 /* focus shifting, raising and lowering. */
4991 x_focus_on_frame (f
)
4994 #if 0 /* This proves to be unpleasant. */
4998 /* I don't think that the ICCCM allows programs to do things like this
4999 without the interaction of the window manager. Whatever you end up
5000 doing with this code, do it to x_unfocus_frame too. */
5001 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5002 RevertToPointerRoot
, CurrentTime
);
5012 /* Raise frame F. */
5017 if (f
->async_visible
)
5018 SelectWindow (FRAME_MAC_WINDOW (f
));
5021 /* Lower frame F. */
5026 if (f
->async_visible
)
5027 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5031 XTframe_raise_lower (f
, raise_flag
)
5041 /* Change of visibility. */
5043 /* This tries to wait until the frame is really visible.
5044 However, if the window manager asks the user where to position
5045 the frame, this will return before the user finishes doing that.
5046 The frame will not actually be visible at that time,
5047 but it will become visible later when the window manager
5048 finishes with it. */
5051 x_make_frame_visible (f
)
5055 int original_top
, original_left
;
5059 if (! FRAME_VISIBLE_P (f
))
5061 /* We test FRAME_GARBAGED_P here to make sure we don't
5062 call x_set_offset a second time
5063 if we get to x_make_frame_visible a second time
5064 before the window gets really visible. */
5065 if (! FRAME_ICONIFIED_P (f
)
5066 && ! f
->output_data
.mac
->asked_for_visible
)
5067 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5069 f
->output_data
.mac
->asked_for_visible
= 1;
5071 ShowWindow (FRAME_MAC_WINDOW (f
));
5074 XFlush (FRAME_MAC_DISPLAY (f
));
5076 #if 0 /* MAC_TODO */
5077 /* Synchronize to ensure Emacs knows the frame is visible
5078 before we do anything else. We do this loop with input not blocked
5079 so that incoming events are handled. */
5084 /* This must come after we set COUNT. */
5087 XSETFRAME (frame
, f
);
5089 /* Wait until the frame is visible. Process X events until a
5090 MapNotify event has been seen, or until we think we won't get a
5091 MapNotify at all.. */
5092 for (count
= input_signal_count
+ 10;
5093 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5095 /* Force processing of queued events. */
5098 /* Machines that do polling rather than SIGIO have been
5099 observed to go into a busy-wait here. So we'll fake an
5100 alarm signal to let the handler know that there's something
5101 to be read. We used to raise a real alarm, but it seems
5102 that the handler isn't always enabled here. This is
5104 if (input_polling_used ())
5106 /* It could be confusing if a real alarm arrives while
5107 processing the fake one. Turn it off and let the
5108 handler reset it. */
5109 extern void poll_for_input_1
P_ ((void));
5110 int old_poll_suppress_count
= poll_suppress_count
;
5111 poll_suppress_count
= 1;
5112 poll_for_input_1 ();
5113 poll_suppress_count
= old_poll_suppress_count
;
5116 /* See if a MapNotify event has been processed. */
5117 FRAME_SAMPLE_VISIBILITY (f
);
5120 #endif /* MAC_TODO */
5123 /* Change from mapped state to withdrawn state. */
5125 /* Make the frame visible (mapped and not iconified). */
5128 x_make_frame_invisible (f
)
5131 /* Don't keep the highlight on an invisible frame. */
5132 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5133 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5137 HideWindow (FRAME_MAC_WINDOW (f
));
5139 /* We can't distinguish this from iconification
5140 just by the event that we get from the server.
5141 So we can't win using the usual strategy of letting
5142 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5143 and synchronize with the server to make sure we agree. */
5145 FRAME_ICONIFIED_P (f
) = 0;
5146 f
->async_visible
= 0;
5147 f
->async_iconified
= 0;
5152 /* Change window state from mapped to iconified. */
5158 /* Don't keep the highlight on an invisible frame. */
5159 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5160 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5163 /* Review: Since window is still visible in dock, still allow updates? */
5164 if (f
->async_iconified
)
5170 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5176 /* Destroy the X window of frame F. */
5179 x_destroy_window (f
)
5182 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5186 DisposeWindow (FRAME_MAC_WINDOW (f
));
5188 free_frame_menubar (f
);
5189 free_frame_faces (f
);
5191 xfree (f
->output_data
.mac
);
5192 f
->output_data
.mac
= 0;
5193 if (f
== dpyinfo
->x_focus_frame
)
5194 dpyinfo
->x_focus_frame
= 0;
5195 if (f
== dpyinfo
->x_focus_event_frame
)
5196 dpyinfo
->x_focus_event_frame
= 0;
5197 if (f
== dpyinfo
->x_highlight_frame
)
5198 dpyinfo
->x_highlight_frame
= 0;
5200 dpyinfo
->reference_count
--;
5202 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5204 dpyinfo
->mouse_face_beg_row
5205 = dpyinfo
->mouse_face_beg_col
= -1;
5206 dpyinfo
->mouse_face_end_row
5207 = dpyinfo
->mouse_face_end_col
= -1;
5208 dpyinfo
->mouse_face_window
= Qnil
;
5209 dpyinfo
->mouse_face_deferred_gc
= 0;
5210 dpyinfo
->mouse_face_mouse_frame
= 0;
5216 /* Setting window manager hints. */
5218 /* Set the normal size hints for the window manager, for frame F.
5219 FLAGS is the flags word to use--or 0 meaning preserve the flags
5220 that the window now has.
5221 If USER_POSITION is nonzero, we set the USPosition
5222 flag (this is useful when FLAGS is 0). */
5224 x_wm_set_size_hint (f
, flags
, user_position
)
5229 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5230 XSizeHints size_hints
;
5232 #ifdef USE_X_TOOLKIT
5235 Dimension widget_width
, widget_height
;
5236 Window window
= XtWindow (f
->output_data
.x
->widget
);
5237 #else /* not USE_X_TOOLKIT */
5238 Window window
= FRAME_X_WINDOW (f
);
5239 #endif /* not USE_X_TOOLKIT */
5241 /* Setting PMaxSize caused various problems. */
5242 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5244 size_hints
.x
= f
->left_pos
;
5245 size_hints
.y
= f
->top_pos
;
5247 #ifdef USE_X_TOOLKIT
5248 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5249 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5250 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5251 size_hints
.height
= widget_height
;
5252 size_hints
.width
= widget_width
;
5253 #else /* not USE_X_TOOLKIT */
5254 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5255 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5256 #endif /* not USE_X_TOOLKIT */
5258 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5259 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5260 size_hints
.max_width
5261 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5262 size_hints
.max_height
5263 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5265 /* Calculate the base and minimum sizes.
5267 (When we use the X toolkit, we don't do it here.
5268 Instead we copy the values that the widgets are using, below.) */
5269 #ifndef USE_X_TOOLKIT
5271 int base_width
, base_height
;
5272 int min_rows
= 0, min_cols
= 0;
5274 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5275 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5277 check_frame_size (f
, &min_rows
, &min_cols
);
5279 /* The window manager uses the base width hints to calculate the
5280 current number of rows and columns in the frame while
5281 resizing; min_width and min_height aren't useful for this
5282 purpose, since they might not give the dimensions for a
5283 zero-row, zero-column frame.
5285 We use the base_width and base_height members if we have
5286 them; otherwise, we set the min_width and min_height members
5287 to the size for a zero x zero frame. */
5290 size_hints
.flags
|= PBaseSize
;
5291 size_hints
.base_width
= base_width
;
5292 size_hints
.base_height
= base_height
;
5293 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5294 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5296 size_hints
.min_width
= base_width
;
5297 size_hints
.min_height
= base_height
;
5301 /* If we don't need the old flags, we don't need the old hint at all. */
5304 size_hints
.flags
|= flags
;
5307 #endif /* not USE_X_TOOLKIT */
5310 XSizeHints hints
; /* Sometimes I hate X Windows... */
5311 long supplied_return
;
5315 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5318 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5321 #ifdef USE_X_TOOLKIT
5322 size_hints
.base_height
= hints
.base_height
;
5323 size_hints
.base_width
= hints
.base_width
;
5324 size_hints
.min_height
= hints
.min_height
;
5325 size_hints
.min_width
= hints
.min_width
;
5329 size_hints
.flags
|= flags
;
5334 if (hints
.flags
& PSize
)
5335 size_hints
.flags
|= PSize
;
5336 if (hints
.flags
& PPosition
)
5337 size_hints
.flags
|= PPosition
;
5338 if (hints
.flags
& USPosition
)
5339 size_hints
.flags
|= USPosition
;
5340 if (hints
.flags
& USSize
)
5341 size_hints
.flags
|= USSize
;
5345 #ifndef USE_X_TOOLKIT
5350 size_hints
.win_gravity
= f
->win_gravity
;
5351 size_hints
.flags
|= PWinGravity
;
5355 size_hints
.flags
&= ~ PPosition
;
5356 size_hints
.flags
|= USPosition
;
5358 #endif /* PWinGravity */
5361 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5363 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5365 #endif /* MAC_TODO */
5368 #if 0 /* MAC_TODO: hide application instead of iconify? */
5369 /* Used for IconicState or NormalState */
5372 x_wm_set_window_state (f
, state
)
5376 #ifdef USE_X_TOOLKIT
5379 XtSetArg (al
[0], XtNinitialState
, state
);
5380 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5381 #else /* not USE_X_TOOLKIT */
5382 Window window
= FRAME_X_WINDOW (f
);
5384 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5385 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5387 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5388 #endif /* not USE_X_TOOLKIT */
5392 x_wm_set_icon_pixmap (f
, pixmap_id
)
5398 #ifndef USE_X_TOOLKIT
5399 Window window
= FRAME_X_WINDOW (f
);
5404 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5405 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5409 /* It seems there is no way to turn off use of an icon pixmap.
5410 The following line does it, only if no icon has yet been created,
5411 for some window managers. But with mwm it crashes.
5412 Some people say it should clear the IconPixmapHint bit in this case,
5413 but that doesn't work, and the X consortium said it isn't the
5414 right thing at all. Since there is no way to win,
5415 best to explicitly give up. */
5417 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5423 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5427 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5428 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5431 #else /* not USE_X_TOOLKIT */
5433 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5434 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5436 #endif /* not USE_X_TOOLKIT */
5439 #endif /* MAC_TODO */
5442 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5446 #if 0 /* MAC_TODO: no icons on Mac */
5447 #ifdef USE_X_TOOLKIT
5448 Window window
= XtWindow (f
->output_data
.x
->widget
);
5450 Window window
= FRAME_X_WINDOW (f
);
5453 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5454 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5455 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5457 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5458 #endif /* MAC_TODO */
5462 /***********************************************************************
5464 ***********************************************************************/
5466 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5469 x_get_font_info (f
, font_idx
)
5473 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5476 /* the global font name table */
5477 char **font_name_table
= NULL
;
5478 int font_name_table_size
= 0;
5479 int font_name_count
= 0;
5481 /* compare two strings ignoring case */
5483 stricmp (const char *s
, const char *t
)
5485 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5488 return tolower (*s
) - tolower (*t
);
5491 /* compare two strings ignoring case and handling wildcard */
5493 wildstrieq (char *s1
, char *s2
)
5495 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5498 return stricmp (s1
, s2
) == 0;
5501 /* Assume parameter 1 is fully qualified, no wildcards. */
5503 mac_font_pattern_match (fontname
, pattern
)
5507 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5508 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5511 /* Copy fontname so we can modify it during comparison. */
5512 strcpy (font_name_copy
, fontname
);
5517 /* Turn pattern into a regexp and do a regexp match. */
5518 for (; *pattern
; pattern
++)
5520 if (*pattern
== '?')
5522 else if (*pattern
== '*')
5533 return (fast_c_string_match_ignore_case (build_string (regex
),
5534 font_name_copy
) >= 0);
5537 /* Two font specs are considered to match if their foundry, family,
5538 weight, slant, and charset match. */
5540 mac_font_match (char *mf
, char *xf
)
5542 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5543 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5545 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5546 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5547 return mac_font_pattern_match (mf
, xf
);
5549 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5550 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5551 return mac_font_pattern_match (mf
, xf
);
5553 return (wildstrieq (m_foundry
, x_foundry
)
5554 && wildstrieq (m_family
, x_family
)
5555 && wildstrieq (m_weight
, x_weight
)
5556 && wildstrieq (m_slant
, x_slant
)
5557 && wildstrieq (m_charset
, x_charset
))
5558 || mac_font_pattern_match (mf
, xf
);
5563 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5565 char foundry
[32], family
[32], cs
[32];
5566 char xf
[255], *result
, *p
;
5568 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5570 strcpy(foundry
, "Apple");
5571 strcpy(family
, name
);
5576 strcpy(cs
, "big5-0");
5579 strcpy(cs
, "gb2312.1980-0");
5582 strcpy(cs
, "jisx0208.1983-sjis");
5585 /* Each Apple Japanese font is entered into the font table
5586 twice: once as a jisx0208.1983-sjis font and once as a
5587 jisx0201.1976-0 font. The latter can be used to display
5588 the ascii charset and katakana-jisx0201 charset. A
5589 negative script code signals that the name of this latter
5590 font is being built. */
5591 strcpy(cs
, "jisx0201.1976-0");
5594 strcpy(cs
, "ksc5601.1989-0");
5597 strcpy(cs
, "mac-roman");
5602 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5603 foundry
, family
, style
& bold
? "bold" : "medium",
5604 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5606 result
= (char *) xmalloc (strlen (xf
) + 1);
5607 strcpy (result
, xf
);
5608 for (p
= result
; *p
; p
++)
5614 /* Convert an X font spec to the corresponding mac font name, which
5615 can then be passed to GetFNum after conversion to a Pascal string.
5616 For ordinary Mac fonts, this should just be their names, like
5617 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5618 collection contain their charset designation in their names, like
5619 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5620 names are handled accordingly. */
5622 x_font_name_to_mac_font_name (char *xf
, char *mf
)
5624 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
5628 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5629 foundry
, family
, weight
, slant
, cs
) != 5 &&
5630 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5631 foundry
, family
, weight
, slant
, cs
) != 5)
5634 if (strcmp (cs
, "big5-0") == 0 || strcmp (cs
, "gb2312.1980-0") == 0
5635 || strcmp (cs
, "jisx0208.1983-sjis") == 0
5636 || strcmp (cs
, "jisx0201.1976-0") == 0
5637 || strcmp (cs
, "ksc5601.1989-0") == 0 || strcmp (cs
, "mac-roman") == 0)
5640 sprintf(mf
, "%s-%s-%s", foundry
, family
, cs
);
5645 add_font_name_table_entry (char *font_name
)
5647 if (font_name_table_size
== 0)
5649 font_name_table_size
= 16;
5650 font_name_table
= (char **)
5651 xmalloc (font_name_table_size
* sizeof (char *));
5653 else if (font_name_count
+ 1 >= font_name_table_size
)
5655 font_name_table_size
+= 16;
5656 font_name_table
= (char **)
5657 xrealloc (font_name_table
,
5658 font_name_table_size
* sizeof (char *));
5661 font_name_table
[font_name_count
++] = font_name
;
5664 /* Sets up the table font_name_table to contain the list of all fonts
5665 in the system the first time the table is used so that the Resource
5666 Manager need not be accessed every time this information is
5670 init_font_name_table ()
5672 #if TARGET_API_MAC_CARBON
5675 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
5677 FMFontFamilyIterator ffi
;
5678 FMFontFamilyInstanceIterator ffii
;
5681 /* Create a dummy instance iterator here to avoid creating and
5682 destroying it in the loop. */
5683 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
5685 /* Create an iterator to enumerate the font families. */
5686 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
5689 FMDisposeFontFamilyInstanceIterator (&ffii
);
5693 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
5701 if (FMGetFontFamilyName (ff
, name
) != noErr
)
5705 sc
= FontToScript (ff
);
5707 /* Point the instance iterator at the current font family. */
5708 if (FMResetFontFamilyInstanceIterator(ff
, &ffii
) != noErr
)
5711 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
5715 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5717 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5719 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5721 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5727 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5729 if (smJapanese
== sc
)
5730 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
5736 /* Dispose of the iterators. */
5737 FMDisposeFontFamilyIterator (&ffi
);
5738 FMDisposeFontFamilyInstanceIterator (&ffii
);
5742 #endif /* TARGET_API_MAC_CARBON */
5744 SInt16 fontnum
, old_fontnum
;
5745 int num_mac_fonts
= CountResources('FOND');
5747 Handle font_handle
, font_handle_2
;
5748 short id
, scriptcode
;
5751 struct FontAssoc
*fat
;
5752 struct AsscEntry
*assc_entry
;
5754 GetPort (&port
); /* save the current font number used */
5755 #if TARGET_API_MAC_CARBON
5756 old_fontnum
= GetPortTextFont (port
);
5758 old_fontnum
= port
->txFont
;
5761 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
5763 font_handle
= GetIndResource ('FOND', i
);
5767 GetResInfo (font_handle
, &id
, &type
, name
);
5768 GetFNum (name
, &fontnum
);
5774 scriptcode
= FontToScript (fontnum
);
5777 HLock (font_handle
);
5779 if (GetResourceSizeOnDisk (font_handle
)
5780 >= sizeof (struct FamRec
))
5782 fat
= (struct FontAssoc
*) (*font_handle
5783 + sizeof (struct FamRec
));
5785 = (struct AsscEntry
*) (*font_handle
5786 + sizeof (struct FamRec
)
5787 + sizeof (struct FontAssoc
));
5789 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
5791 if (font_name_table_size
== 0)
5793 font_name_table_size
= 16;
5794 font_name_table
= (char **)
5795 xmalloc (font_name_table_size
* sizeof (char *));
5797 else if (font_name_count
>= font_name_table_size
)
5799 font_name_table_size
+= 16;
5800 font_name_table
= (char **)
5801 xrealloc (font_name_table
,
5802 font_name_table_size
* sizeof (char *));
5804 font_name_table
[font_name_count
++]
5805 = mac_to_x_fontname (name
,
5806 assc_entry
->fontSize
,
5807 assc_entry
->fontStyle
,
5809 /* Both jisx0208.1983-sjis and
5810 jisx0201.1976-sjis parts are contained in
5811 Apple Japanese (SJIS) font. */
5812 if (smJapanese
== scriptcode
)
5814 font_name_table
[font_name_count
++]
5815 = mac_to_x_fontname (name
,
5816 assc_entry
->fontSize
,
5817 assc_entry
->fontStyle
,
5823 HUnlock (font_handle
);
5824 font_handle_2
= GetNextFOND (font_handle
);
5825 ReleaseResource (font_handle
);
5826 font_handle
= font_handle_2
;
5828 while (ResError () == noErr
&& font_handle
);
5831 TextFont (old_fontnum
);
5832 #if TARGET_API_MAC_CARBON
5834 #endif /* TARGET_API_MAC_CARBON */
5838 /* Return a list of at most MAXNAMES font specs matching the one in
5839 PATTERN. Cache matching fonts for patterns in
5840 dpyinfo->name_list_element to avoid looking them up again by
5841 calling mac_font_pattern_match (slow). Return as many matching
5842 fonts as possible if MAXNAMES = -1. */
5845 x_list_fonts (struct frame
*f
,
5846 Lisp_Object pattern
,
5851 Lisp_Object newlist
= Qnil
, tem
, key
;
5854 struct gcpro gcpro1
, gcpro2
;
5855 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
5857 if (font_name_table
== NULL
) /* Initialize when first used. */
5858 init_font_name_table ();
5862 tem
= XCDR (dpyinfo
->name_list_element
);
5863 key
= Fcons (pattern
, make_number (maxnames
));
5865 newlist
= Fassoc (key
, tem
);
5866 if (!NILP (newlist
))
5868 newlist
= Fcdr_safe (newlist
);
5873 ptnstr
= SDATA (pattern
);
5875 GCPRO2 (pattern
, newlist
);
5877 /* Scan and matching bitmap fonts. */
5878 for (i
= 0; i
< font_name_count
; i
++)
5880 if (mac_font_pattern_match (font_name_table
[i
], ptnstr
))
5882 newlist
= Fcons (build_string (font_name_table
[i
]), newlist
);
5885 if (maxnames
> 0 && n_fonts
>= maxnames
)
5890 /* MAC_TODO: add code for matching outline fonts here */
5896 XSETCDR (dpyinfo
->name_list_element
,
5897 Fcons (Fcons (key
, newlist
),
5898 XCDR (dpyinfo
->name_list_element
)));
5908 /* Check that FONT is valid on frame F. It is if it can be found in F's
5912 x_check_font (f
, font
)
5917 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
5919 xassert (font
!= NULL
);
5921 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
5922 if (dpyinfo
->font_table
[i
].name
5923 && font
== dpyinfo
->font_table
[i
].font
)
5926 xassert (i
< dpyinfo
->n_fonts
);
5929 #endif /* GLYPH_DEBUG != 0 */
5931 /* Set *W to the minimum width, *H to the minimum font height of FONT.
5932 Note: There are (broken) X fonts out there with invalid XFontStruct
5933 min_bounds contents. For example, handa@etl.go.jp reports that
5934 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
5935 have font->min_bounds.width == 0. */
5938 x_font_min_bounds (font
, w
, h
)
5939 MacFontStruct
*font
;
5943 * TODO: Windows does not appear to offer min bound, only
5944 * average and maximum width, and maximum height.
5946 *h
= FONT_HEIGHT (font
);
5947 *w
= FONT_WIDTH (font
);
5951 /* Compute the smallest character width and smallest font height over
5952 all fonts available on frame F. Set the members smallest_char_width
5953 and smallest_font_height in F's x_display_info structure to
5954 the values computed. Value is non-zero if smallest_font_height or
5955 smallest_char_width become smaller than they were before. */
5958 x_compute_min_glyph_bounds (f
)
5962 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5963 MacFontStruct
*font
;
5964 int old_width
= dpyinfo
->smallest_char_width
;
5965 int old_height
= dpyinfo
->smallest_font_height
;
5967 dpyinfo
->smallest_font_height
= 100000;
5968 dpyinfo
->smallest_char_width
= 100000;
5970 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
5971 if (dpyinfo
->font_table
[i
].name
)
5973 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
5976 font
= (MacFontStruct
*) fontp
->font
;
5977 xassert (font
!= (MacFontStruct
*) ~0);
5978 x_font_min_bounds (font
, &w
, &h
);
5980 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
5981 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
5984 xassert (dpyinfo
->smallest_char_width
> 0
5985 && dpyinfo
->smallest_font_height
> 0);
5987 return (dpyinfo
->n_fonts
== 1
5988 || dpyinfo
->smallest_char_width
< old_width
5989 || dpyinfo
->smallest_font_height
< old_height
);
5993 /* Determine whether given string is a fully-specified XLFD: all 14
5994 fields are present, none is '*'. */
5997 is_fully_specified_xlfd (char *p
)
6005 for (i
= 0; i
< 13; i
++)
6007 q
= strchr (p
+ 1, '-');
6010 if (q
- p
== 2 && *(p
+ 1) == '*')
6015 if (strchr (p
+ 1, '-') != NULL
)
6018 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6025 const int kDefaultFontSize
= 9;
6028 /* XLoadQueryFont creates and returns an internal representation for a
6029 font in a MacFontStruct struct. There is really no concept
6030 corresponding to "loading" a font on the Mac. But we check its
6031 existence and find the font number and all other information for it
6032 and store them in the returned MacFontStruct. */
6034 static MacFontStruct
*
6035 XLoadQueryFont (Display
*dpy
, char *fontname
)
6037 int i
, size
, is_two_byte_font
, char_width
;
6040 SInt16 old_fontnum
, old_fontsize
;
6044 Style fontface
= normal
;
6045 MacFontStruct
*font
;
6046 FontInfo the_fontinfo
;
6047 char s_weight
[7], c_slant
;
6049 if (is_fully_specified_xlfd (fontname
))
6053 for (i
= 0; i
< font_name_count
; i
++)
6054 if (mac_font_pattern_match (font_name_table
[i
], fontname
))
6057 if (i
>= font_name_count
)
6060 name
= font_name_table
[i
];
6063 GetPort (&port
); /* save the current font number used */
6064 #if TARGET_API_MAC_CARBON
6065 old_fontnum
= GetPortTextFont (port
);
6066 old_fontsize
= GetPortTextSize (port
);
6067 old_fontface
= GetPortTextFace (port
);
6069 old_fontnum
= port
->txFont
;
6070 old_fontsize
= port
->txSize
;
6071 old_fontface
= port
->txFace
;
6074 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6075 size
= kDefaultFontSize
;
6077 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6078 if (strcmp (s_weight
, "bold") == 0)
6081 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6085 x_font_name_to_mac_font_name (name
, mfontname
);
6087 GetFNum (mfontname
, &fontnum
);
6091 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6093 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6094 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6096 font
->mac_fontnum
= fontnum
;
6097 font
->mac_fontsize
= size
;
6098 font
->mac_fontface
= fontface
;
6099 font
->mac_scriptcode
= FontToScript (fontnum
);
6101 /* Apple Japanese (SJIS) font is listed as both
6102 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6103 (Roman script) in init_font_name_table (). The latter should be
6104 treated as a one-byte font. */
6109 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6111 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6112 font
->mac_scriptcode
= smRoman
;
6115 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6116 font
->mac_scriptcode
== smTradChinese
||
6117 font
->mac_scriptcode
== smSimpChinese
||
6118 font
->mac_scriptcode
== smKorean
;
6122 TextFace (fontface
);
6124 GetFontInfo (&the_fontinfo
);
6126 font
->ascent
= the_fontinfo
.ascent
;
6127 font
->descent
= the_fontinfo
.descent
;
6129 font
->min_byte1
= 0;
6130 if (is_two_byte_font
)
6131 font
->max_byte1
= 1;
6133 font
->max_byte1
= 0;
6134 font
->min_char_or_byte2
= 0x20;
6135 font
->max_char_or_byte2
= 0xff;
6137 if (is_two_byte_font
)
6139 /* Use the width of an "ideographic space" of that font because
6140 the_fontinfo.widMax returns the wrong width for some fonts. */
6141 switch (font
->mac_scriptcode
)
6144 char_width
= StringWidth("\p\x81\x40");
6147 char_width
= StringWidth("\p\xa1\x40");
6150 char_width
= StringWidth("\p\xa1\xa1");
6153 char_width
= StringWidth("\p\xa1\xa1");
6158 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6159 returns 15 for 12-point Monaco! */
6160 char_width
= CharWidth ('m');
6162 font
->max_bounds
.rbearing
= char_width
;
6163 font
->max_bounds
.lbearing
= 0;
6164 font
->max_bounds
.width
= char_width
;
6165 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6166 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6168 font
->min_bounds
= font
->max_bounds
;
6170 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6171 font
->per_char
= NULL
;
6174 font
->per_char
= (XCharStruct
*)
6175 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6179 for (c
= 0x20; c
<= 0xff; c
++)
6181 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6182 font
->per_char
[c
- 0x20].width
= CharWidth (c
);
6187 TextFont (old_fontnum
); /* restore previous font number, size and face */
6188 TextSize (old_fontsize
);
6189 TextFace (old_fontface
);
6195 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6196 pointer to the structure font_info while allocating it dynamically.
6197 If SIZE is 0, load any size of font.
6198 If loading is failed, return NULL. */
6201 x_load_font (f
, fontname
, size
)
6203 register char *fontname
;
6206 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6207 Lisp_Object font_names
;
6209 /* Get a list of all the fonts that match this name. Once we
6210 have a list of matching fonts, we compare them against the fonts
6211 we already have by comparing names. */
6212 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6214 if (!NILP (font_names
))
6219 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6220 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6221 if (dpyinfo
->font_table
[i
].name
6222 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6223 SDATA (XCAR (tail
)))
6224 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6225 SDATA (XCAR (tail
)))))
6226 return (dpyinfo
->font_table
+ i
);
6229 /* Load the font and add it to the table. */
6232 struct MacFontStruct
*font
;
6233 struct font_info
*fontp
;
6234 unsigned long value
;
6237 /* If we have found fonts by x_list_font, load one of them. If
6238 not, we still try to load a font by the name given as FONTNAME
6239 because XListFonts (called in x_list_font) of some X server has
6240 a bug of not finding a font even if the font surely exists and
6241 is loadable by XLoadQueryFont. */
6242 if (size
> 0 && !NILP (font_names
))
6243 fontname
= (char *) SDATA (XCAR (font_names
));
6245 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6249 /* Find a free slot in the font table. */
6250 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6251 if (dpyinfo
->font_table
[i
].name
== NULL
)
6254 /* If no free slot found, maybe enlarge the font table. */
6255 if (i
== dpyinfo
->n_fonts
6256 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6259 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6260 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6262 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6265 fontp
= dpyinfo
->font_table
+ i
;
6266 if (i
== dpyinfo
->n_fonts
)
6269 /* Now fill in the slots of *FONTP. */
6271 bzero (fontp
, sizeof (*fontp
));
6273 fontp
->font_idx
= i
;
6274 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6275 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6277 fontp
->full_name
= fontp
->name
;
6279 fontp
->size
= font
->max_bounds
.width
;
6280 fontp
->height
= FONT_HEIGHT (font
);
6282 /* For some font, ascent and descent in max_bounds field is
6283 larger than the above value. */
6284 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6285 if (max_height
> fontp
->height
)
6286 fontp
->height
= max_height
;
6289 /* The slot `encoding' specifies how to map a character
6290 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6291 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6292 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6293 2:0xA020..0xFF7F). For the moment, we don't know which charset
6294 uses this font. So, we set information in fontp->encoding[1]
6295 which is never used by any charset. If mapping can't be
6296 decided, set FONT_ENCODING_NOT_DECIDED. */
6297 if (font
->mac_scriptcode
== smJapanese
)
6298 fontp
->encoding
[1] = 4;
6302 = (font
->max_byte1
== 0
6304 ? (font
->min_char_or_byte2
< 0x80
6305 ? (font
->max_char_or_byte2
< 0x80
6306 ? 0 /* 0x20..0x7F */
6307 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6308 : 1) /* 0xA0..0xFF */
6310 : (font
->min_byte1
< 0x80
6311 ? (font
->max_byte1
< 0x80
6312 ? (font
->min_char_or_byte2
< 0x80
6313 ? (font
->max_char_or_byte2
< 0x80
6314 ? 0 /* 0x2020..0x7F7F */
6315 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6316 : 3) /* 0x20A0..0x7FFF */
6317 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6318 : (font
->min_char_or_byte2
< 0x80
6319 ? (font
->max_char_or_byte2
< 0x80
6320 ? 2 /* 0xA020..0xFF7F */
6321 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6322 : 1))); /* 0xA0A0..0xFFFF */
6325 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6326 fontp
->baseline_offset
6327 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6328 ? (long) value
: 0);
6329 fontp
->relative_compose
6330 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6331 ? (long) value
: 0);
6332 fontp
->default_ascent
6333 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6334 ? (long) value
: 0);
6336 fontp
->baseline_offset
= 0;
6337 fontp
->relative_compose
= 0;
6338 fontp
->default_ascent
= 0;
6341 /* Set global flag fonts_changed_p to non-zero if the font loaded
6342 has a character with a smaller width than any other character
6343 before, or if the font loaded has a smalle>r height than any
6344 other font loaded before. If this happens, it will make a
6345 glyph matrix reallocation necessary. */
6346 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6353 /* Return a pointer to struct font_info of a font named FONTNAME for
6354 frame F. If no such font is loaded, return NULL. */
6357 x_query_font (f
, fontname
)
6359 register char *fontname
;
6361 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6364 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6365 if (dpyinfo
->font_table
[i
].name
6366 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6367 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6368 return (dpyinfo
->font_table
+ i
);
6373 /* Find a CCL program for a font specified by FONTP, and set the member
6374 `encoder' of the structure. */
6377 x_find_ccl_program (fontp
)
6378 struct font_info
*fontp
;
6380 Lisp_Object list
, elt
;
6382 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6386 && STRINGP (XCAR (elt
))
6387 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6393 struct ccl_program
*ccl
6394 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6396 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6399 fontp
->font_encoder
= ccl
;
6405 /* The Mac Event loop code */
6409 #include <Quickdraw.h>
6410 #include <Balloons.h>
6411 #include <Devices.h>
6413 #include <Gestalt.h>
6415 #include <Processes.h>
6417 #include <ToolUtils.h>
6418 #include <TextUtils.h>
6419 #include <Dialogs.h>
6422 #include <TextEncodingConverter.h>
6423 #include <Resources.h>
6428 #endif /* ! MAC_OSX */
6433 #define WINDOW_RESOURCE 128
6434 #define TERM_WINDOW_RESOURCE 129
6436 #define DEFAULT_NUM_COLS 80
6438 #define MIN_DOC_SIZE 64
6439 #define MAX_DOC_SIZE 32767
6441 /* sleep time for WaitNextEvent */
6442 #define WNE_SLEEP_AT_SUSPEND 10
6443 #define WNE_SLEEP_AT_RESUME 1
6445 /* true when cannot handle any Mac OS events */
6446 static int handling_window_update
= 0;
6448 /* the flag appl_is_suspended is used both for determining the sleep
6449 time to be passed to WaitNextEvent and whether the cursor should be
6450 drawn when updating the display. The cursor is turned off when
6451 Emacs is suspended. Redrawing it is unnecessary and what needs to
6452 be done depends on whether the cursor lies inside or outside the
6453 redraw region. So we might as well skip drawing it when Emacs is
6455 static Boolean app_is_suspended
= false;
6456 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6458 #define EXTRA_STACK_ALLOC (256 * 1024)
6460 #define ARGV_STRING_LIST_ID 129
6461 #define ABOUT_ALERT_ID 128
6462 #define RAM_TOO_LARGE_ALERT_ID 129
6464 Boolean terminate_flag
= false;
6466 /* Contains the string "reverse", which is a constant for mouse button emu.*/
6467 Lisp_Object Qreverse
;
6469 /* True if using command key as meta key. */
6470 Lisp_Object Vmac_command_key_is_meta
;
6472 /* True if the ctrl and meta keys should be reversed. */
6473 Lisp_Object Vmac_reverse_ctrl_meta
;
6475 /* True if the option and command modifiers should be used to emulate
6476 a three button mouse */
6477 Lisp_Object Vmac_emulate_three_button_mouse
;
6479 #if USE_CARBON_EVENTS
6480 /* True if the mouse wheel button (i.e. button 4) should map to
6481 mouse-2, instead of mouse-3. */
6482 Lisp_Object Vmac_wheel_button_is_mouse_2
;
6484 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
6485 for processing before Emacs sees it. */
6486 Lisp_Object Vmac_pass_command_to_system
;
6488 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
6489 for processing before Emacs sees it. */
6490 Lisp_Object Vmac_pass_control_to_system
;
6493 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
6494 to this text encoding */
6495 int mac_keyboard_text_encoding
;
6496 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
6498 /* Set in term/mac-win.el to indicate that event loop can now generate
6499 drag and drop events. */
6500 Lisp_Object Qmac_ready_for_drag_n_drop
;
6502 Lisp_Object drag_and_drop_file_list
;
6504 Point saved_menu_event_location
;
6507 static void init_required_apple_events (void);
6509 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
6511 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
6512 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
6513 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
6516 static OSErr
init_mac_drag_n_drop ();
6517 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
6519 #if USE_CARBON_EVENTS
6520 /* Preliminary Support for the OSX Services Menu */
6521 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
6522 static void init_service_handler ();
6525 extern void init_emacs_passwd_dir ();
6526 extern int emacs_main (int, char **, char **);
6527 extern void check_alarm ();
6529 extern void initialize_applescript();
6530 extern void terminate_applescript();
6533 #if USE_CARBON_EVENTS
6534 mac_to_emacs_modifiers (UInt32 mods
)
6536 mac_to_emacs_modifiers (EventModifiers mods
)
6539 unsigned int result
= 0;
6540 if (mods
& macShiftKey
)
6541 result
|= shift_modifier
;
6542 if (mods
& macCtrlKey
)
6543 result
|= ctrl_modifier
;
6544 if (mods
& macMetaKey
)
6545 result
|= meta_modifier
;
6546 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
6547 result
|= alt_modifier
;
6552 mac_get_emulated_btn ( UInt32 modifiers
)
6555 if (Vmac_emulate_three_button_mouse
!= Qnil
) {
6556 int cmdIs3
= (Vmac_emulate_three_button_mouse
!= Qreverse
);
6557 if (modifiers
& controlKey
)
6558 result
= cmdIs3
? 2 : 1;
6559 else if (modifiers
& optionKey
)
6560 result
= cmdIs3
? 1 : 2;
6565 #if USE_CARBON_EVENTS
6566 /* Obtains the event modifiers from the event ref and then calls
6567 mac_to_emacs_modifiers. */
6569 mac_event_to_emacs_modifiers (EventRef eventRef
)
6572 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
6573 sizeof (UInt32
), NULL
, &mods
);
6574 if (Vmac_emulate_three_button_mouse
!= Qnil
&&
6575 GetEventClass(eventRef
) == kEventClassMouse
)
6577 mods
&= ~(optionKey
& cmdKey
);
6579 return mac_to_emacs_modifiers (mods
);
6582 /* Given an event ref, return the code to use for the mouse button
6583 code in the emacs input_event. */
6585 mac_get_mouse_btn (EventRef ref
)
6587 EventMouseButton result
= kEventMouseButtonPrimary
;
6588 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
6589 sizeof (EventMouseButton
), NULL
, &result
);
6592 case kEventMouseButtonPrimary
:
6593 if (Vmac_emulate_three_button_mouse
== Qnil
)
6597 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
6598 sizeof (UInt32
), NULL
, &mods
);
6599 return mac_get_emulated_btn(mods
);
6601 case kEventMouseButtonSecondary
:
6602 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
6603 case kEventMouseButtonTertiary
:
6604 case 4: /* 4 is the number for the mouse wheel button */
6605 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
6611 /* Normally, ConvertEventRefToEventRecord will correctly handle all
6612 events. However the click of the mouse wheel is not converted to a
6613 mouseDown or mouseUp event. This calls ConvertEventRef, but then
6614 checks to see if it is a mouse up or down carbon event that has not
6615 been converted, and if so, converts it by hand (to be picked up in
6616 the XTread_socket loop). */
6617 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
6619 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
6620 /* Do special case for mouse wheel button. */
6621 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
6623 UInt32 kind
= GetEventKind (eventRef
);
6624 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
6626 eventRec
->what
= mouseDown
;
6629 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
6631 eventRec
->what
= mouseUp
;
6636 /* Need where and when. */
6638 GetEventParameter (eventRef
, kEventParamMouseLocation
,
6639 typeQDPoint
, NULL
, sizeof (Point
),
6640 NULL
, &eventRec
->where
);
6641 /* Use two step process because new event modifiers are
6642 32-bit and old are 16-bit. Currently, only loss is
6644 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
6645 typeUInt32
, NULL
, sizeof (UInt32
),
6647 eventRec
->modifiers
= mods
;
6649 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
6660 Handle menubar_handle
;
6661 MenuHandle menu_handle
;
6663 menubar_handle
= GetNewMBar (128);
6664 if(menubar_handle
== NULL
)
6666 SetMenuBar (menubar_handle
);
6669 menu_handle
= GetMenuHandle (M_APPLE
);
6670 if(menu_handle
!= NULL
)
6671 AppendResMenu (menu_handle
,'DRVR');
6678 do_init_managers (void)
6680 #if !TARGET_API_MAC_CARBON
6681 InitGraf (&qd
.thePort
);
6683 FlushEvents (everyEvent
, 0);
6688 #endif /* !TARGET_API_MAC_CARBON */
6691 #if !TARGET_API_MAC_CARBON
6692 /* set up some extra stack space for use by emacs */
6693 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
6695 /* MaxApplZone must be called for AppleScript to execute more
6696 complicated scripts */
6699 #endif /* !TARGET_API_MAC_CARBON */
6703 do_check_ram_size (void)
6705 SInt32 physical_ram_size
, logical_ram_size
;
6707 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
6708 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
6709 || physical_ram_size
> (1 << VALBITS
)
6710 || logical_ram_size
> (1 << VALBITS
))
6712 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
6718 do_window_update (WindowPtr win
)
6720 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
6721 struct frame
*f
= mwp
->mFP
;
6725 if (f
->async_visible
== 0)
6727 f
->async_visible
= 1;
6728 f
->async_iconified
= 0;
6729 SET_FRAME_GARBAGED (f
);
6731 /* An update event is equivalent to MapNotify on X, so report
6732 visibility changes properly. */
6733 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
6734 /* Force a redisplay sooner or later to update the
6735 frame titles in case this is the second frame. */
6736 record_asynch_buffer_change ();
6741 handling_window_update
= 1;
6743 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
6745 expose_frame (f
, 0, 0, 0, 0);
6747 handling_window_update
= 0;
6754 is_emacs_window (WindowPtr win
)
6756 Lisp_Object tail
, frame
;
6761 FOR_EACH_FRAME (tail
, frame
)
6762 if (FRAME_MAC_P (XFRAME (frame
)))
6763 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
6770 do_window_activate (WindowPtr win
)
6775 if (is_emacs_window (win
))
6777 mwp
= (mac_output
*) GetWRefCon (win
);
6782 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6783 activate_scroll_bars (f
);
6789 do_window_deactivate (WindowPtr win
)
6794 if (is_emacs_window (win
))
6796 mwp
= (mac_output
*) GetWRefCon (win
);
6799 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6801 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6802 deactivate_scroll_bars (f
);
6815 if (is_emacs_window (wp
))
6817 mwp
= (mac_output
*) GetWRefCon (wp
);
6822 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
6823 activate_scroll_bars (f
);
6827 app_is_suspended
= false;
6828 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6839 if (is_emacs_window (wp
))
6841 mwp
= (mac_output
*) GetWRefCon (wp
);
6844 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
6846 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
6847 deactivate_scroll_bars (f
);
6851 app_is_suspended
= true;
6852 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
6857 do_mouse_moved (Point mouse_pos
)
6859 WindowPtr wp
= FrontWindow ();
6862 if (is_emacs_window (wp
))
6864 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6866 #if TARGET_API_MAC_CARBON
6867 SetPort (GetWindowPort (wp
));
6872 GlobalToLocal (&mouse_pos
);
6874 note_mouse_movement (f
, &mouse_pos
);
6880 do_os_event (EventRecord
*erp
)
6882 switch((erp
->message
>> 24) & 0x000000FF)
6884 case suspendResumeMessage
:
6885 if((erp
->message
& resumeFlag
) == 1)
6891 case mouseMovedMessage
:
6892 do_mouse_moved (erp
->where
);
6898 do_events (EventRecord
*erp
)
6903 do_window_update ((WindowPtr
) erp
->message
);
6911 if ((erp
->modifiers
& activeFlag
) != 0)
6912 do_window_activate ((WindowPtr
) erp
->message
);
6914 do_window_deactivate ((WindowPtr
) erp
->message
);
6920 do_apple_menu (SInt16 menu_item
)
6922 #if !TARGET_API_MAC_CARBON
6924 SInt16 da_driver_refnum
;
6926 if (menu_item
== I_ABOUT
)
6927 NoteAlert (ABOUT_ALERT_ID
, NULL
);
6930 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
6931 da_driver_refnum
= OpenDeskAcc (item_name
);
6933 #endif /* !TARGET_API_MAC_CARBON */
6937 do_menu_choice (SInt32 menu_choice
)
6939 SInt16 menu_id
, menu_item
;
6941 menu_id
= HiWord (menu_choice
);
6942 menu_item
= LoWord (menu_choice
);
6950 do_apple_menu (menu_item
);
6955 WindowPtr wp
= FrontWindow ();
6956 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
6957 MenuHandle menu
= GetMenuHandle (menu_id
);
6962 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
6963 menubar_selection_callback (f
, refcon
);
6972 /* Handle drags in size box. Based on code contributed by Ben
6973 Mesander and IM - Window Manager A. */
6976 do_grow_window (WindowPtr w
, EventRecord
*e
)
6981 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
6982 struct frame
*f
= mwp
->mFP
;
6984 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
6986 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
6988 /* see if it really changed size */
6991 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
6992 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
6994 x_set_window_size (f
, 0, columns
, rows
);
6999 /* Handle clicks in zoom box. Calculation of "standard state" based
7000 on code in IM - Window Manager A and code contributed by Ben
7001 Mesander. The standard state of an Emacs window is 80-characters
7002 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7005 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7008 Rect zoom_rect
, port_rect
;
7010 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
7011 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7012 struct frame
*f
= mwp
->mFP
;
7014 GetPort (&save_port
);
7016 #if TARGET_API_MAC_CARBON
7017 SetPort (GetWindowPort (w
));
7022 /* Clear window to avoid flicker. */
7023 #if TARGET_API_MAC_CARBON
7028 GetWindowPortBounds (w
, &r
);
7031 if (zoom_in_or_out
== inZoomOut
)
7033 /* calculate height of window's title bar (hard card it for now). */
7034 w_title_height
= 20 + GetMBarHeight ();
7036 /* get maximum height of window into zoom_rect.bottom -
7038 GetQDGlobalsScreenBits (&bm
);
7039 zoom_rect
= bm
.bounds
;
7040 zoom_rect
.top
+= w_title_height
;
7041 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7043 zoom_rect
.right
= zoom_rect
.left
7044 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7046 SetWindowStandardState (w
, &zoom_rect
);
7049 #else /* not TARGET_API_MAC_CARBON */
7050 EraseRect (&(w
->portRect
));
7051 if (zoom_in_or_out
== inZoomOut
)
7053 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7054 LocalToGlobal (&top_left
);
7056 /* calculate height of window's title bar */
7057 w_title_height
= top_left
.v
- 1
7058 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7060 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7061 zoom_rect
= qd
.screenBits
.bounds
;
7062 zoom_rect
.top
+= w_title_height
;
7063 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7065 zoom_rect
.right
= zoom_rect
.left
7066 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7068 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7071 #endif /* not TARGET_API_MAC_CARBON */
7073 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
7075 /* retrieve window size and update application values */
7076 #if TARGET_API_MAC_CARBON
7077 GetWindowPortBounds (w
, &port_rect
);
7079 port_rect
= w
->portRect
;
7081 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7082 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7083 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
7085 SetPort (save_port
);
7088 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7090 init_mac_drag_n_drop ()
7092 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7096 /* Intialize AppleEvent dispatcher table for the required events. */
7098 init_required_apple_events ()
7103 /* Make sure we have apple events before starting. */
7104 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7108 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7111 #if TARGET_API_MAC_CARBON
7112 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7113 NewAEEventHandlerUPP
7114 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7117 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7118 NewAEEventHandlerProc
7119 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7125 #if TARGET_API_MAC_CARBON
7126 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7127 NewAEEventHandlerUPP
7128 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7131 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7132 NewAEEventHandlerProc
7133 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7139 #if TARGET_API_MAC_CARBON
7140 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7141 NewAEEventHandlerUPP
7142 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7145 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7146 NewAEEventHandlerProc
7147 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7153 #if TARGET_API_MAC_CARBON
7154 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7155 NewAEEventHandlerUPP
7156 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7159 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7160 NewAEEventHandlerProc
7161 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7168 #if USE_CARBON_EVENTS
7171 init_service_handler ()
7173 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7174 {kEventClassService
, kEventServiceCopy
},
7175 {kEventClassService
, kEventServicePaste
}};
7176 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7177 3, specs
, NULL
, NULL
);
7181 MAC_TODO: Check to see if this is called by AEProcessDesc...
7184 mac_handle_service_event (EventHandlerCallRef callRef
,
7185 EventRef event
, void *data
)
7187 OSStatus err
= noErr
;
7188 switch (GetEventKind (event
))
7190 case kEventServiceGetTypes
:
7192 CFMutableArrayRef copyTypes
, pasteTypes
;
7194 Boolean selection
= true;
7196 GetEventParameter(event, kEventParamServicePasteTypes,
7197 typeCFMutableArrayRef, NULL,
7198 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7200 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7201 typeCFMutableArrayRef
, NULL
,
7202 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7203 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7205 CFArrayAppendValue (copyTypes
, type
);
7206 //CFArrayAppendValue (pasteTypes, type);
7210 case kEventServiceCopy
:
7212 ScrapRef currentScrap
, specificScrap
;
7216 GetCurrentScrap (¤tScrap
);
7218 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7221 void *buffer
= xmalloc (byteCount
);
7224 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7225 sizeof (ScrapRef
), NULL
, &specificScrap
);
7227 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7228 &byteCount
, buffer
);
7230 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7231 kScrapFlavorMaskNone
, byteCount
, buffer
);
7237 case kEventServicePaste
:
7240 // Get the current location
7242 ScrapRef specificScrap;
7243 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7244 sizeof(ScrapRef), NULL, &specificScrap);
7245 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7247 void * buffer = xmalloc(byteCount);
7248 if (buffer != NULL ) {
7249 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7250 &byteCount, buffer);
7252 // Actually place in the buffer
7254 // Get the current "selection" string here
7267 /* Open Application Apple Event */
7269 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7275 /* Defined in mac.c. */
7277 path_from_vol_dir_name (char *, int, short, long, char *);
7280 /* Called when we receive an AppleEvent with an ID of
7281 "kAEOpenDocuments". This routine gets the direct parameter,
7282 extracts the FSSpecs in it, and puts their names on a list. */
7284 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7289 DescType actual_type
;
7292 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7294 goto descriptor_error_exit
;
7296 /* Check to see that we got all of the required parameters from the
7297 event descriptor. For an 'odoc' event this should just be the
7299 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7300 &actual_type
, (Ptr
) &keyword
,
7301 sizeof (keyword
), &actual_size
);
7302 /* No error means that we found some unused parameters.
7303 errAEDescNotFound means that there are no more parameters. If we
7304 get an error code other than that, flag it. */
7305 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7307 err
= errAEEventNotHandled
;
7312 /* Got all the parameters we need. Now, go through the direct
7313 object list and parse it up. */
7315 long num_files_to_open
;
7317 err
= AECountItems (&the_desc
, &num_files_to_open
);
7322 /* AE file list is one based so just use that for indexing here. */
7323 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7326 Str255 path_name
, unix_path_name
;
7331 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7332 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7333 if (err
!= noErr
) break;
7336 err
= FSpMakeFSRef (&fs
, &fref
);
7337 if (err
!= noErr
) break;
7339 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7341 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7343 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7345 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7346 drag_and_drop_file_list
);
7352 /* Nuke the coerced file list in any case */
7353 err2
= AEDisposeDesc(&the_desc
);
7355 descriptor_error_exit
:
7356 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7362 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7363 DragReference theDrag
)
7367 FlavorFlags theFlags
;
7370 ItemReference theItem
;
7373 Size size
= sizeof (HFSFlavor
);
7375 drag_and_drop_file_list
= Qnil
;
7376 GetDragMouse (theDrag
, &mouse
, 0L);
7377 CountDragItems (theDrag
, &items
);
7378 for (index
= 1; index
<= items
; index
++)
7380 /* Only handle file references. */
7381 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7382 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7383 if (result
== noErr
)
7390 Str255 unix_path_name
;
7391 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7393 /* Use Carbon routines, otherwise it converts the file name
7394 to /Macintosh HD/..., which is not correct. */
7395 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7396 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7398 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7399 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7400 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7402 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7403 drag_and_drop_file_list
);
7408 /* If there are items in the list, construct an event and post it to
7409 the queue like an interrupt using kbd_buffer_store_event. */
7410 if (!NILP (drag_and_drop_file_list
))
7412 struct input_event event
;
7414 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
7415 SetPort (GetWindowPort (window
));
7416 GlobalToLocal (&mouse
);
7418 event
.kind
= DRAG_N_DROP_EVENT
;
7420 event
.modifiers
= 0;
7421 event
.timestamp
= TickCount () * (1000 / 60);
7422 XSETINT (event
.x
, mouse
.h
);
7423 XSETINT (event
.y
, mouse
.v
);
7424 XSETFRAME (frame
, f
);
7425 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7427 /* Post to the interrupt queue */
7428 kbd_buffer_store_event (&event
);
7429 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7431 ProcessSerialNumber psn
;
7432 GetCurrentProcess (&psn
);
7433 SetFrontProcess (&psn
);
7439 /* Print Document Apple Event */
7441 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7443 return errAEEventNotHandled
;
7448 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7450 /* FixMe: Do we need an unwind-protect or something here? And what
7451 do we do about unsaved files. Currently just forces quit rather
7452 than doing recursive callback to get user input. */
7454 terminate_flag
= true;
7456 /* Fkill_emacs doesn't return. We have to return. (TI) */
7463 profiler_exit_proc ()
7465 ProfilerDump ("\pEmacs.prof");
7470 /* These few functions implement Emacs as a normal Mac application
7471 (almost): set up the heap and the Toolbox, handle necessary
7472 system events plus a few simple menu events. They also set up
7473 Emacs's access to functions defined in the rest of this file.
7474 Emacs uses function hooks to perform all its terminal I/O. A
7475 complete list of these functions appear in termhooks.h. For what
7476 they do, read the comments there and see also w32term.c and
7477 xterm.c. What's noticeably missing here is the event loop, which
7478 is normally present in most Mac application. After performing the
7479 necessary Mac initializations, main passes off control to
7480 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7481 mac_read_socket (defined further below) to read input. This is
7482 where WaitNextEvent is called to process Mac events. This is also
7483 where check_alarm in sysdep.c is called to simulate alarm signals.
7484 This makes the cursor jump back to its correct position after
7485 briefly jumping to that of the matching parenthesis, print useful
7486 hints and prompts in the minibuffer after the user stops typing for
7489 #if !TARGET_API_MAC_CARBON
7494 #if __profile__ /* is the profiler on? */
7495 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7500 /* set creator and type for files created by MSL */
7505 do_init_managers ();
7510 do_check_ram_size ();
7513 init_emacs_passwd_dir ();
7517 initialize_applescript ();
7519 init_required_apple_events ();
7525 /* set up argv array from STR# resource */
7526 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
7530 /* free up AppleScript resources on exit */
7531 atexit (terminate_applescript
);
7533 #if __profile__ /* is the profiler on? */
7534 atexit (profiler_exit_proc
);
7537 /* 3rd param "envp" never used in emacs_main */
7538 (void) emacs_main (argc
, argv
, 0);
7541 /* Never reached - real exit in Fkill_emacs */
7546 /* Table for translating Mac keycode to X keysym values. Contributed
7547 by Sudhir Shenoy. */
7548 static unsigned char keycode_to_xkeysym_table
[] = {
7549 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7550 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7551 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7553 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
7554 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
7555 /*0x38*/ 0, 0, 0, 0,
7556 /*0x3C*/ 0, 0, 0, 0,
7558 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
7559 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
7560 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
7561 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
7563 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
7564 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
7565 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
7566 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
7568 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
7569 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
7570 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
7571 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
7573 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
7574 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
7575 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
7576 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
7580 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
7582 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
7583 return *xKeySym
!= 0;
7586 /* Emacs calls this whenever it wants to read an input event from the
7589 XTread_socket (int sd
, struct input_event
*bufp
, int numchars
, int expected
)
7592 #if USE_CARBON_EVENTS
7595 EventMouseButton mouseBtn
;
7599 EventMask event_mask
;
7602 if (interrupt_input_blocked
)
7604 interrupt_input_pending
= 1;
7609 interrupt_input_pending
= 0;
7612 /* So people can tell when we have read the available input. */
7613 input_signal_count
++;
7618 /* Don't poll for events to process (specifically updateEvt) if
7619 window update currently already in progress. A call to redisplay
7620 (in do_window_update) can be preempted by another call to
7621 redisplay, causing blank regions to be left on the screen and the
7622 cursor to be left at strange places. */
7623 if (handling_window_update
)
7630 Fkill_emacs (make_number (1));
7632 /* It is necessary to set this (additional) argument slot of an
7633 event to nil because keyboard.c protects incompletely processed
7634 event from being garbage collected by placing them in the
7635 kbd_buffer_gcpro vector. */
7638 event_mask
= everyEvent
;
7639 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
7640 event_mask
-= highLevelEventMask
;
7642 #if USE_CARBON_EVENTS
7643 rneResult
= ReceiveNextEvent (0, NULL
,
7645 ? TicksToEventTime (app_sleep_time
)
7647 kEventRemoveFromQueue
, &eventRef
);
7650 /* Handle new events */
7651 if (!mac_convert_event_ref (eventRef
, &er
))
7652 switch (GetEventClass (eventRef
))
7654 case kEventClassMouse
:
7655 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
7659 WindowPtr window_ptr
= FrontNonFloatingWindow ();
7660 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7661 if (!IsValidWindowPtr (window_ptr
))
7668 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
7669 typeSInt32
, NULL
, sizeof (SInt32
),
7671 GetEventParameter(eventRef
, kEventParamMouseLocation
,
7672 typeQDPoint
, NULL
, sizeof (Point
),
7674 bufp
->kind
= WHEEL_EVENT
;
7676 bufp
->modifiers
= (mac_event_to_emacs_modifiers(eventRef
)
7677 | ((delta
< 0) ? down_modifier
7679 SetPort (GetWindowPort (window_ptr
));
7680 GlobalToLocal (&point
);
7681 XSETINT (bufp
->x
, point
.h
);
7682 XSETINT (bufp
->y
, point
.v
);
7683 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7684 bufp
->timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
7688 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7692 /* Send the event to the appropriate receiver. */
7693 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
7697 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
7698 #endif /* USE_CARBON_EVENTS */
7704 WindowPtr window_ptr
= FrontWindow ();
7707 #if USE_CARBON_EVENTS
7708 /* This is needed to send mouse events like aqua window buttons
7709 to the correct handler. */
7710 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
7714 if (!is_emacs_window(window_ptr
))
7718 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
7719 && er
.what
== mouseUp
)
7721 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
7722 Point mouse_loc
= er
.where
;
7724 /* Convert to local coordinates of new window. */
7725 #if TARGET_API_MAC_CARBON
7726 SetPort (GetWindowPort (window_ptr
));
7728 SetPort (window_ptr
);
7731 GlobalToLocal (&mouse_loc
);
7733 #if USE_CARBON_EVENTS
7734 bufp
->code
= mac_get_mouse_btn (eventRef
);
7736 bufp_
.code
= mac_get_emulate_btn (er
.modifiers
);
7738 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
7739 bufp
->frame_or_window
= tracked_scroll_bar
->window
;
7740 bufp
->part
= scroll_bar_handle
;
7741 #if USE_CARBON_EVENTS
7742 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7744 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7746 bufp
->modifiers
|= up_modifier
;
7747 bufp
->timestamp
= er
.when
* (1000 / 60);
7748 /* ticks to milliseconds */
7750 XSETINT (bufp
->x
, tracked_scroll_bar
->left
+ 2);
7751 XSETINT (bufp
->y
, mouse_loc
.v
- 24);
7752 tracked_scroll_bar
->dragging
= Qnil
;
7753 mouse_tracking_in_progress
= mouse_tracking_none
;
7754 tracked_scroll_bar
= NULL
;
7759 part_code
= FindWindow (er
.where
, &window_ptr
);
7764 if (er
.what
== mouseDown
)
7766 struct frame
*f
= ((mac_output
*)
7767 GetWRefCon (FrontWindow ()))->mFP
;
7768 saved_menu_event_location
= er
.where
;
7769 bufp
->kind
= MENU_BAR_ACTIVATE_EVENT
;
7770 XSETFRAME (bufp
->frame_or_window
, f
);
7776 if (window_ptr
!= FrontWindow ())
7777 SelectWindow (window_ptr
);
7780 SInt16 control_part_code
;
7782 struct mac_output
*mwp
= (mac_output
*)
7783 GetWRefCon (window_ptr
);
7784 Point mouse_loc
= er
.where
;
7786 /* convert to local coordinates of new window */
7787 #if TARGET_API_MAC_CARBON
7788 SetPort (GetWindowPort (window_ptr
));
7790 SetPort (window_ptr
);
7793 GlobalToLocal (&mouse_loc
);
7794 #if TARGET_API_MAC_CARBON
7795 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
7796 &control_part_code
);
7798 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
7801 #if USE_CARBON_EVENTS
7802 bufp
->code
= mac_get_mouse_btn (eventRef
);
7804 bufp_
.code
= mac_get_emulate_btn (er
.modifiers
);
7806 XSETINT (bufp
->x
, mouse_loc
.h
);
7807 XSETINT (bufp
->y
, mouse_loc
.v
);
7808 bufp
->timestamp
= er
.when
* (1000 / 60);
7809 /* ticks to milliseconds */
7811 #if TARGET_API_MAC_CARBON
7814 if (control_part_code
!= 0)
7817 struct scroll_bar
*bar
= (struct scroll_bar
*)
7818 GetControlReference (ch
);
7819 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
7821 if (er
.what
== mouseDown
7822 && control_part_code
== kControlIndicatorPart
)
7824 mouse_tracking_in_progress
7825 = mouse_tracking_scroll_bar
;
7826 tracked_scroll_bar
= bar
;
7830 mouse_tracking_in_progress
= mouse_tracking_none
;
7831 tracked_scroll_bar
= NULL
;
7836 bufp
->kind
= MOUSE_CLICK_EVENT
;
7837 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
7838 if (er
.what
== mouseDown
)
7839 mouse_tracking_in_progress
7840 = mouse_tracking_mouse_movement
;
7842 mouse_tracking_in_progress
= mouse_tracking_none
;
7845 #if USE_CARBON_EVENTS
7846 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
7848 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
7854 bufp
->modifiers
|= down_modifier
;
7857 bufp
->modifiers
|= up_modifier
;
7866 #if TARGET_API_MAC_CARBON
7867 if (er
.what
== mouseDown
)
7871 GetQDGlobalsScreenBits (&bm
);
7872 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
7874 #else /* not TARGET_API_MAC_CARBON */
7875 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
7876 #endif /* not TARGET_API_MAC_CARBON */
7880 if (TrackGoAway (window_ptr
, er
.where
))
7882 bufp
->kind
= DELETE_WINDOW_EVENT
;
7883 XSETFRAME (bufp
->frame_or_window
,
7884 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
7889 /* window resize handling added --ben */
7891 if (er
.what
== mouseDown
)
7893 do_grow_window(window_ptr
, &er
);
7897 /* window zoom handling added --ben */
7900 if (TrackBox (window_ptr
, er
.where
, part_code
))
7901 do_zoom_window (window_ptr
, part_code
);
7913 #if USE_CARBON_EVENTS
7914 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
7922 int keycode
= (er
.message
& keyCodeMask
) >> 8;
7925 #if USE_CARBON_EVENTS
7926 /* When using Carbon Events, we need to pass raw keyboard events
7927 to the TSM ourselves. If TSM handles it, it will pass back
7928 noErr, otherwise it will pass back "eventNotHandledErr" and
7929 we can process it normally. */
7930 if ((!NILP (Vmac_pass_command_to_system
)
7931 || !(er
.modifiers
& cmdKey
))
7932 && (!NILP (Vmac_pass_control_to_system
)
7933 || !(er
.modifiers
& controlKey
)))
7936 err
= SendEventToEventTarget (eventRef
,
7937 GetEventDispatcherTarget ());
7938 if (err
!= eventNotHandledErr
)
7943 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
7952 if (keycode_to_xkeysym (keycode
, &xkeysym
))
7954 bufp
->code
= 0xff00 | xkeysym
;
7955 bufp
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
7959 if (er
.modifiers
& (controlKey
|
7960 (NILP (Vmac_command_key_is_meta
) ? optionKey
7963 /* This code comes from Keyboard Resource, Appendix
7964 C of IM - Text. This is necessary since shift is
7965 ignored in KCHR table translation when option or
7966 command is pressed. It also does not translate
7967 correctly control-shift chars like C-% so mask off
7969 int new_modifiers
= er
.modifiers
& 0xe600;
7970 /* mask off option and command */
7971 int new_keycode
= keycode
| new_modifiers
;
7972 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
7973 unsigned long some_state
= 0;
7974 bufp
->code
= KeyTranslate (kchr_ptr
, new_keycode
,
7975 &some_state
) & 0xff;
7978 bufp
->code
= er
.message
& charCodeMask
;
7979 bufp
->kind
= ASCII_KEYSTROKE_EVENT
;
7983 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
7984 convert non-ASCII characters typed at the Mac keyboard
7985 (presumed to be in the Mac Roman encoding) to iso-latin-1
7986 encoding before they are passed to Emacs. This enables the
7987 Mac keyboard to be used to enter non-ASCII iso-latin-1
7988 characters directly. */
7989 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
7990 && bufp
->kind
== ASCII_KEYSTROKE_EVENT
&& bufp
->code
>= 128)
7992 static TECObjectRef converter
= NULL
;
7993 OSStatus the_err
= noErr
;
7994 OSStatus convert_status
= noErr
;
7996 if (converter
== NULL
)
7998 the_err
= TECCreateConverter (&converter
,
7999 kTextEncodingMacRoman
,
8000 mac_keyboard_text_encoding
);
8001 current_mac_keyboard_text_encoding
8002 = mac_keyboard_text_encoding
;
8004 else if (mac_keyboard_text_encoding
8005 != current_mac_keyboard_text_encoding
)
8007 /* Free the converter for the current encoding before
8008 creating a new one. */
8009 TECDisposeConverter (converter
);
8010 the_err
= TECCreateConverter (&converter
,
8011 kTextEncodingMacRoman
,
8012 mac_keyboard_text_encoding
);
8013 current_mac_keyboard_text_encoding
8014 = mac_keyboard_text_encoding
;
8017 if (the_err
== noErr
)
8019 unsigned char ch
= bufp
->code
;
8020 ByteCount actual_input_length
, actual_output_length
;
8021 unsigned char outch
;
8023 convert_status
= TECConvertText (converter
, &ch
, 1,
8024 &actual_input_length
,
8026 &actual_output_length
);
8027 if (convert_status
== noErr
8028 && actual_input_length
== 1
8029 && actual_output_length
== 1)
8034 #if USE_CARBON_EVENTS
8035 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8037 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8042 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8043 XSETFRAME (bufp
->frame_or_window
, mwp
->mFP
);
8046 bufp
->timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8051 case kHighLevelEvent
:
8052 drag_and_drop_file_list
= Qnil
;
8054 AEProcessAppleEvent(&er
);
8056 /* Build a DRAG_N_DROP_EVENT type event as is done in
8057 constuct_drag_n_drop in w32term.c. */
8058 if (!NILP (drag_and_drop_file_list
))
8060 struct frame
*f
= NULL
;
8064 wp
= FrontNonFloatingWindow ();
8068 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8069 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8070 wp
= FrontNonFloatingWindow ();
8073 if (wp
&& is_emacs_window(wp
))
8074 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8076 bufp
->kind
= DRAG_N_DROP_EVENT
;
8078 bufp
->timestamp
= er
.when
* (1000 / 60);
8079 /* ticks to milliseconds */
8080 #if USE_CARBON_EVENTS
8081 bufp
->modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8083 bufp
->modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8086 XSETINT (bufp
->x
, 0);
8087 XSETINT (bufp
->y
, 0);
8089 XSETFRAME (frame
, f
);
8090 bufp
->frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8092 /* Regardless of whether Emacs was suspended or in the
8093 foreground, ask it to redraw its entire screen.
8094 Otherwise parts of the screen can be left in an
8095 inconsistent state. */
8097 #if TARGET_API_MAC_CARBON
8101 GetWindowPortBounds (wp
, &r
);
8102 InvalWindowRect (wp
, &r
);
8104 #else /* not TARGET_API_MAC_CARBON */
8105 InvalRect (&(wp
->portRect
));
8106 #endif /* not TARGET_API_MAC_CARBON */
8113 #if USE_CARBON_EVENTS
8114 ReleaseEvent (eventRef
);
8118 /* If the focus was just given to an autoraising frame,
8120 /* ??? This ought to be able to handle more than one such frame. */
8121 if (pending_autoraise_frame
)
8123 x_raise_frame (pending_autoraise_frame
);
8124 pending_autoraise_frame
= 0;
8127 #if !TARGET_API_MAC_CARBON
8128 check_alarm (); /* simulate the handling of a SIGALRM */
8132 static Point old_mouse_pos
= { -1, -1 };
8134 if (app_is_suspended
)
8136 old_mouse_pos
.h
= -1;
8137 old_mouse_pos
.v
= -1;
8145 struct scroll_bar
*sb
;
8147 wp
= FrontWindow ();
8148 if (is_emacs_window (wp
))
8150 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8152 #if TARGET_API_MAC_CARBON
8153 SetPort (GetWindowPort (wp
));
8158 GetMouse (&mouse_pos
);
8160 if (!EqualPt (mouse_pos
, old_mouse_pos
))
8162 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8163 && tracked_scroll_bar
)
8164 x_scroll_bar_note_movement (tracked_scroll_bar
,
8166 - XINT (tracked_scroll_bar
->top
),
8167 TickCount() * (1000 / 60));
8169 note_mouse_movement (f
, &mouse_pos
);
8171 old_mouse_pos
= mouse_pos
;
8183 /* Need to override CodeWarrior's input function so no conversion is
8184 done on newlines Otherwise compiled functions in .elc files will be
8185 read incorrectly. Defined in ...:MSL C:MSL
8186 Common:Source:buffer_io.c. */
8189 __convert_to_newlines (unsigned char * p
, size_t * n
)
8195 __convert_from_newlines (unsigned char * p
, size_t * n
)
8202 /* Initialize the struct pointed to by MW to represent a new COLS x
8203 ROWS Macintosh window, using font with name FONTNAME and size
8206 NewMacWindow (FRAME_PTR fp
)
8209 #if TARGET_API_MAC_CARBON
8210 static int making_terminal_window
= 0;
8212 static int making_terminal_window
= 1;
8215 mwp
= fp
->output_data
.mac
;
8217 if (making_terminal_window
)
8219 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8222 making_terminal_window
= 0;
8225 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8228 SetWRefCon (mwp
->mWP
, (long) mwp
);
8229 /* so that update events can find this mac_output struct */
8230 mwp
->mFP
= fp
; /* point back to emacs frame */
8232 #if TARGET_API_MAC_CARBON
8233 SetPort (GetWindowPort (mwp
->mWP
));
8240 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8241 ShowWindow (mwp
->mWP
);
8247 make_mac_frame (struct frame
*f
)
8249 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8253 f
->output_data
.mac
->cursor_pixel
= 0;
8254 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8255 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8256 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8258 FRAME_FONTSET (f
) = -1;
8259 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8260 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8261 f
->output_data
.mac
->explicit_parent
= 0;
8264 f
->border_width
= 0;
8266 f
->internal_border_width
= 0;
8268 f
->output_method
= output_mac
;
8273 f
->new_text_cols
= 0;
8274 f
->new_text_lines
= 0;
8278 make_mac_terminal_frame (struct frame
*f
)
8282 XSETFRAME (frame
, f
);
8284 f
->output_method
= output_mac
;
8285 f
->output_data
.mac
= (struct mac_output
*)
8286 xmalloc (sizeof (struct mac_output
));
8287 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8288 FRAME_FONTSET (f
) = -1;
8289 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8290 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8292 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8294 FRAME_COLS (f
) = 96;
8295 FRAME_LINES (f
) = 4;
8297 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8298 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8304 /* Need to be initialized for unshow_buffer in window.c. */
8305 selected_window
= f
->selected_window
;
8307 Fmodify_frame_parameters (frame
,
8308 Fcons (Fcons (Qfont
,
8309 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8310 Fmodify_frame_parameters (frame
,
8311 Fcons (Fcons (Qforeground_color
,
8312 build_string ("black")), Qnil
));
8313 Fmodify_frame_parameters (frame
,
8314 Fcons (Fcons (Qbackground_color
,
8315 build_string ("white")), Qnil
));
8319 /***********************************************************************
8321 ***********************************************************************/
8323 int mac_initialized
= 0;
8326 mac_initialize_display_info ()
8328 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8329 GDHandle main_device_handle
;
8331 bzero (dpyinfo
, sizeof (*dpyinfo
));
8333 /* Put it on x_display_name_list. */
8334 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8335 x_display_name_list
);
8336 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8339 dpyinfo
->mac_id_name
8340 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8341 + SCHARS (Vsystem_name
)
8343 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8344 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8346 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8347 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8350 main_device_handle
= LMGetMainDevice();
8352 dpyinfo
->reference_count
= 0;
8353 dpyinfo
->resx
= 75.0;
8354 dpyinfo
->resy
= 75.0;
8355 dpyinfo
->n_planes
= 1;
8356 dpyinfo
->n_cbits
= 16;
8357 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8358 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8359 dpyinfo
->grabbed
= 0;
8360 dpyinfo
->root_window
= NULL
;
8362 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8363 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8364 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8365 dpyinfo
->mouse_face_window
= Qnil
;
8368 struct mac_display_info
*
8369 mac_term_init (display_name
, xrm_option
, resource_name
)
8370 Lisp_Object display_name
;
8372 char *resource_name
;
8374 struct mac_display_info
*dpyinfo
;
8375 GDHandle main_device_handle
;
8377 if (!mac_initialized
)
8380 mac_initialized
= 1;
8383 mac_initialize_display_info (display_name
);
8385 dpyinfo
= &one_mac_display_info
;
8387 main_device_handle
= LMGetMainDevice();
8389 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8390 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8399 extern int inhibit_window_system
;
8400 extern int noninteractive
;
8401 CFBundleRef appsBundle
;
8404 /* No need to test if already -nw*/
8405 if (inhibit_window_system
|| noninteractive
)
8408 appsBundle
= CFBundleGetMainBundle();
8409 if (appsBundle
!= NULL
)
8411 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
8412 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
8413 /* We found the bundle identifier, now we know we are valid. */
8420 /* MAC_TODO: Have this start the bundled executable */
8422 /* For now, prevent the fatal error by bringing it up in the terminal */
8423 inhibit_window_system
= 1;
8427 MakeMeTheFrontProcess ()
8429 ProcessSerialNumber psn
;
8432 err
= GetCurrentProcess (&psn
);
8434 (void) SetFrontProcess (&psn
);
8437 /***** Code to handle C-g testing *****/
8439 /* Contains the Mac modifier formed from quit_char */
8440 static mac_quit_char_modifiers
= 0;
8441 static mac_quit_char_keycode
;
8442 extern int quit_char
;
8445 mac_determine_quit_char_modifiers()
8447 /* Todo: Determine modifiers from quit_char. */
8448 UInt32 qc_modifiers
= ctrl_modifier
;
8451 mac_quit_char_modifiers
= 0;
8452 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
8453 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
8454 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
8455 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
8459 init_quit_char_handler ()
8461 /* TODO: Let this support keys other the 'g' */
8462 mac_quit_char_keycode
= 5;
8463 /* Look at <architecture/adb_kb_map.h> for details */
8464 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
8466 mac_determine_quit_char_modifiers();
8470 quit_char_comp (EventRef inEvent
, void *inCompData
)
8472 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
8474 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
8478 UInt32 keyModifiers
;
8479 GetEventParameter(inEvent
, kEventParamKeyCode
,
8480 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
8481 if (keyCode
!= mac_quit_char_keycode
)
8483 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
8484 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
8485 if (keyModifiers
!= mac_quit_char_modifiers
)
8492 mac_check_for_quit_char ()
8495 static EMACS_TIME last_check_time
= { 0, 0 };
8496 static EMACS_TIME one_second
= { 1, 0 };
8499 /* If windows are not initialized, return immediately (keep it bouncin'). */
8500 if (!mac_quit_char_modifiers
)
8503 /* Don't check if last check is less than a second ago. */
8504 EMACS_GET_TIME (now
);
8505 EMACS_SUB_TIME (t
, now
, last_check_time
);
8506 if (EMACS_TIME_LT (t
, one_second
))
8508 last_check_time
= now
;
8510 /* Redetermine modifiers because they are based on lisp variables */
8511 mac_determine_quit_char_modifiers ();
8513 /* Fill the queue with events */
8514 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
8515 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
8519 struct input_event e
;
8520 struct mac_output
*mwp
=
8521 (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8522 /* Use an input_event to emulate what the interrupt handler does. */
8524 e
.kind
= ASCII_KEYSTROKE_EVENT
;
8528 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
8529 XSETFRAME (e
.frame_or_window
, mwp
->mFP
);
8530 /* Remove event from queue to prevent looping. */
8531 RemoveEventFromQueue (GetMainEventQueue (), event
);
8532 ReleaseEvent (event
);
8533 kbd_buffer_store_event (&e
);
8537 #endif /* MAC_OSX */
8539 /* Set up use of X before we make the first connection. */
8541 extern frame_parm_handler mac_frame_parm_handlers
[];
8543 static struct redisplay_interface x_redisplay_interface
=
8545 mac_frame_parm_handlers
,
8549 x_clear_end_of_line
,
8551 x_after_update_window_line
,
8552 x_update_window_begin
,
8553 x_update_window_end
,
8557 x_clear_window_mouse_face
,
8558 x_get_glyph_overhangs
,
8559 x_fix_overlapping_area
,
8560 x_draw_fringe_bitmap
,
8561 0, /* define_fringe_bitmap */
8562 0, /* destroy_fringe_bitmap */
8563 mac_per_char_metric
,
8565 NULL
, /* mac_compute_glyph_string_overhangs */
8566 x_draw_glyph_string
,
8567 mac_define_frame_cursor
,
8568 mac_clear_frame_area
,
8569 mac_draw_window_cursor
,
8570 mac_draw_vertical_window_border
,
8571 mac_shift_glyphs_for_insert
8577 rif
= &x_redisplay_interface
;
8579 clear_frame_hook
= x_clear_frame
;
8580 ins_del_lines_hook
= x_ins_del_lines
;
8581 delete_glyphs_hook
= x_delete_glyphs
;
8582 ring_bell_hook
= XTring_bell
;
8583 reset_terminal_modes_hook
= XTreset_terminal_modes
;
8584 set_terminal_modes_hook
= XTset_terminal_modes
;
8585 update_begin_hook
= x_update_begin
;
8586 update_end_hook
= x_update_end
;
8587 set_terminal_window_hook
= XTset_terminal_window
;
8588 read_socket_hook
= XTread_socket
;
8589 frame_up_to_date_hook
= XTframe_up_to_date
;
8590 mouse_position_hook
= XTmouse_position
;
8591 frame_rehighlight_hook
= XTframe_rehighlight
;
8592 frame_raise_lower_hook
= XTframe_raise_lower
;
8594 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
8595 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
8596 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
8597 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
8599 scroll_region_ok
= 1; /* we'll scroll partial frames */
8600 char_ins_del_ok
= 1;
8601 line_ins_del_ok
= 1; /* we'll just blt 'em */
8602 fast_clear_end_of_line
= 1; /* X does this well */
8603 memory_below_frame
= 0; /* we don't remember what scrolls
8608 last_tool_bar_item
= -1;
8609 any_help_event_p
= 0;
8611 /* Try to use interrupt input; if we can't, then start polling. */
8612 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
8614 #ifdef USE_X_TOOLKIT
8615 XtToolkitInitialize ();
8616 Xt_app_con
= XtCreateApplicationContext ();
8617 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
8619 /* Install an asynchronous timer that processes Xt timeout events
8620 every 0.1s. This is necessary because some widget sets use
8621 timeouts internally, for example the LessTif menu bar, or the
8622 Xaw3d scroll bar. When Xt timouts aren't processed, these
8623 widgets don't behave normally. */
8625 EMACS_TIME interval
;
8626 EMACS_SET_SECS_USECS (interval
, 0, 100000);
8627 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
8631 #if USE_TOOLKIT_SCROLL_BARS
8632 xaw3d_arrow_scroll
= False
;
8633 xaw3d_pick_top
= True
;
8637 /* Note that there is no real way portable across R3/R4 to get the
8638 original error handler. */
8639 XSetErrorHandler (x_error_handler
);
8640 XSetIOErrorHandler (x_io_error_quitter
);
8642 /* Disable Window Change signals; they are handled by X events. */
8644 signal (SIGWINCH
, SIG_DFL
);
8645 #endif /* ! defined (SIGWINCH) */
8647 signal (SIGPIPE
, x_connection_signal
);
8650 mac_initialize_display_info ();
8652 #if TARGET_API_MAC_CARBON
8653 init_required_apple_events ();
8655 init_mac_drag_n_drop ();
8657 #if USE_CARBON_EVENTS
8658 init_service_handler ();
8660 init_quit_char_handler ();
8663 DisableMenuCommand (NULL
, kHICommandQuit
);
8665 if (!inhibit_window_system
)
8666 MakeMeTheFrontProcess ();
8675 staticpro (&x_error_message_string
);
8676 x_error_message_string
= Qnil
;
8679 Fprovide (intern ("mac-carbon"), Qnil
);
8681 staticpro (&Qreverse
);
8682 Qreverse
= intern ("reverse");
8684 staticpro (&x_display_name_list
);
8685 x_display_name_list
= Qnil
;
8687 staticpro (&last_mouse_scroll_bar
);
8688 last_mouse_scroll_bar
= Qnil
;
8690 staticpro (&Qvendor_specific_keysyms
);
8691 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
8693 staticpro (&last_mouse_press_frame
);
8694 last_mouse_press_frame
= Qnil
;
8696 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
8697 staticpro (&Qmac_ready_for_drag_n_drop
);
8699 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
8700 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
8701 x_autoselect_window_p
= 0;
8703 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
8704 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
8705 Vx_toolkit_scroll_bars
= Qt
;
8707 DEFVAR_BOOL ("x-use-underline-position-properties",
8708 &x_use_underline_position_properties
,
8709 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
8710 nil means ignore them. If you encounter fonts with bogus
8711 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
8712 to 4.1, set this to nil. */);
8713 x_use_underline_position_properties
= 0;
8715 staticpro (&last_mouse_motion_frame
);
8716 last_mouse_motion_frame
= Qnil
;
8718 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
8719 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
8720 Otherwise the option key is used. */);
8721 Vmac_command_key_is_meta
= Qt
;
8723 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
8724 doc
: /* Non-nil means that the control and meta keys are reversed. This is
8725 useful for non-standard keyboard layouts. */);
8726 Vmac_reverse_ctrl_meta
= Qnil
;
8728 DEFVAR_LISP ("mac-emulate-three-button-mouse",
8729 &Vmac_emulate_three_button_mouse
,
8730 doc
: /* t means that when the option-key is held down while pressing the
8731 mouse button, the click will register as mouse-2 and while the
8732 command-key is held down, the click will register as mouse-3.
8733 'reverse means that the the option-key will register for mouse-3
8734 and the command-key will register for mouse-2. nil means that
8735 not emulation should be done and the modifiers should be placed
8736 on the mouse-1 event. */);
8737 Vmac_emulate_three_button_mouse
= Qnil
;
8739 #if USE_CARBON_EVENTS
8740 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
8741 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
8742 the right click will be mouse-3.
8743 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
8744 Vmac_wheel_button_is_mouse_2
= Qt
;
8746 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
8747 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
8748 Toolbox for processing before Emacs sees it. */);
8749 Vmac_pass_command_to_system
= Qt
;
8751 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
8752 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
8753 Toolbox for processing before Emacs sees it. */);
8754 Vmac_pass_control_to_system
= Qt
;
8757 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
8758 doc
: /* One of the Text Encoding Base constant values defined in the
8759 Basic Text Constants section of Inside Macintosh - Text Encoding
8760 Conversion Manager. Its value determines the encoding characters
8761 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
8762 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
8763 its default value, no conversion takes place. If it is set to
8764 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
8765 characters typed on Mac keyboard are first converted into the
8766 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
8767 passed to Emacs. Together with Emacs's set-keyboard-coding-system
8768 command, this enables the Mac keyboard to be used to enter non-ASCII
8769 characters directly. */);
8770 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
8773 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
8774 (do not change this comment) */