1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Contributed by Andrew Choi (akochoi@mac.com). */
29 #include "blockinput.h"
38 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
39 obtain events from the event queue. If set to 0, WaitNextEvent is
41 #define USE_CARBON_EVENTS 1
42 #else /* not MAC_OSX */
43 #include <Quickdraw.h>
44 #include <ToolUtils.h>
48 #include <Resources.h>
50 #include <TextUtils.h>
53 #if defined (__MRC__) || (__MSL__ >= 0x6000)
54 #include <ControlDefinitions.h>
61 #endif /* not MAC_OSX */
75 #include "dispextern.h"
77 #include "termhooks.h"
84 #include "intervals.h"
85 #include "composite.h"
88 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
89 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
90 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
91 #define macShiftKey (shiftKey)
92 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
93 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
95 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
99 /* Non-nil means Emacs uses toolkit scroll bars. */
101 Lisp_Object Vx_toolkit_scroll_bars
;
103 /* Non-zero means that a HELP_EVENT has been generated since Emacs
106 static int any_help_event_p
;
108 /* Non-zero means autoselect window with the mouse cursor. */
110 int x_autoselect_window_p
;
112 /* Non-zero means make use of UNDERLINE_POSITION font properties. */
114 int x_use_underline_position_properties
;
116 /* Non-zero means draw block and hollow cursor as wide as the glyph
117 under it. For example, if a block cursor is over a tab, it will be
118 drawn as wide as that tab on the display. */
121 /* This is a chain of structures for all the X displays currently in
124 struct x_display_info
*x_display_list
;
126 /* This is a list of cons cells, each of the form (NAME
127 . FONT-LIST-CACHE), one for each element of x_display_list and in
128 the same order. NAME is the name of the frame. FONT-LIST-CACHE
129 records previous values returned by x-list-fonts. */
131 Lisp_Object x_display_name_list
;
133 /* This is display since Mac does not support multiple ones. */
134 struct mac_display_info one_mac_display_info
;
136 /* Frame being updated by update_frame. This is declared in term.c.
137 This is set by update_begin and looked at by all the XT functions.
138 It is zero while not inside an update. In that case, the XT
139 functions assume that `selected_frame' is the frame to apply to. */
141 extern struct frame
*updating_frame
;
143 extern int waiting_for_input
;
145 /* This is a frame waiting to be auto-raised, within XTread_socket. */
147 struct frame
*pending_autoraise_frame
;
149 /* Non-zero means user is interacting with a toolkit scroll bar. */
151 static int toolkit_scroll_bar_interaction
;
155 Formerly, we used PointerMotionHintMask (in standard_event_mask)
156 so that we would have to call XQueryPointer after each MotionNotify
157 event to ask for another such event. However, this made mouse tracking
158 slow, and there was a bug that made it eventually stop.
160 Simply asking for MotionNotify all the time seems to work better.
162 In order to avoid asking for motion events and then throwing most
163 of them away or busy-polling the server for mouse positions, we ask
164 the server for pointer motion hints. This means that we get only
165 one event per group of mouse movements. "Groups" are delimited by
166 other kinds of events (focus changes and button clicks, for
167 example), or by XQueryPointer calls; when one of these happens, we
168 get another MotionNotify event the next time the mouse moves. This
169 is at least as efficient as getting motion events when mouse
170 tracking is on, and I suspect only negligibly worse when tracking
173 /* Where the mouse was last time we reported a mouse event. */
175 static Rect last_mouse_glyph
;
176 static Lisp_Object last_mouse_press_frame
;
178 /* The scroll bar in which the last X motion event occurred.
180 If the last X motion event occurred in a scroll bar, we set this so
181 XTmouse_position can know whether to report a scroll bar motion or
184 If the last X motion event didn't occur in a scroll bar, we set
185 this to Qnil, to tell XTmouse_position to return an ordinary motion
188 static Lisp_Object last_mouse_scroll_bar
;
190 /* This is a hack. We would really prefer that XTmouse_position would
191 return the time associated with the position it returns, but there
192 doesn't seem to be any way to wrest the time-stamp from the server
193 along with the position query. So, we just keep track of the time
194 of the last movement we received, and return that in hopes that
195 it's somewhat accurate. */
197 static Time last_mouse_movement_time
;
199 enum mouse_tracking_type
{
201 mouse_tracking_mouse_movement
,
202 mouse_tracking_scroll_bar
205 enum mouse_tracking_type mouse_tracking_in_progress
= mouse_tracking_none
;
207 struct scroll_bar
*tracked_scroll_bar
= NULL
;
209 /* Incremented by XTread_socket whenever it really tries to read
213 static int volatile input_signal_count
;
215 static int input_signal_count
;
218 /* Used locally within XTread_socket. */
220 static int x_noop_count
;
222 /* Initial values of argv and argc. */
224 extern char **initial_argv
;
225 extern int initial_argc
;
227 extern Lisp_Object Vcommand_line_args
, Vsystem_name
;
229 /* Tells if a window manager is present or not. */
231 extern Lisp_Object Vx_no_window_manager
;
235 /* A mask of extra modifier bits to put into every keyboard char. */
237 extern int extra_keyboard_modifiers
;
239 static Lisp_Object Qvendor_specific_keysyms
;
242 extern XrmDatabase x_load_resources
P_ ((Display
*, char *, char *, char *));
245 extern int inhibit_window_system
;
248 QDGlobals qd
; /* QuickDraw global information structure. */
252 struct frame
* x_window_to_frame (struct mac_display_info
*, WindowPtr
);
253 struct mac_display_info
*mac_display_info_for_display (Display
*);
254 static void x_update_window_end
P_ ((struct window
*, int, int));
255 static void mac_handle_tool_bar_click
P_ ((struct frame
*, EventRecord
*));
256 static int x_io_error_quitter
P_ ((Display
*));
257 int x_catch_errors
P_ ((Display
*));
258 void x_uncatch_errors
P_ ((Display
*, int));
259 void x_lower_frame
P_ ((struct frame
*));
260 void x_scroll_bar_clear
P_ ((struct frame
*));
261 int x_had_errors_p
P_ ((Display
*));
262 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
263 void x_raise_frame
P_ ((struct frame
*));
264 void x_set_window_size
P_ ((struct frame
*, int, int, int));
265 void x_wm_set_window_state
P_ ((struct frame
*, int));
266 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
267 void mac_initialize
P_ ((void));
268 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
269 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
270 static void x_update_end
P_ ((struct frame
*));
271 static void XTframe_up_to_date
P_ ((struct frame
*));
272 static void XTreassert_line_highlight
P_ ((int, int));
273 static void x_change_line_highlight
P_ ((int, int, int, int));
274 static void XTset_terminal_modes
P_ ((void));
275 static void XTreset_terminal_modes
P_ ((void));
276 static void x_clear_frame
P_ ((void));
277 static void frame_highlight
P_ ((struct frame
*));
278 static void frame_unhighlight
P_ ((struct frame
*));
279 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
280 static void XTframe_rehighlight
P_ ((struct frame
*));
281 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
282 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
283 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
284 enum text_cursor_kinds
));
286 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, GC
));
287 static void x_flush
P_ ((struct frame
*f
));
288 static void x_update_begin
P_ ((struct frame
*));
289 static void x_update_window_begin
P_ ((struct window
*));
290 static void x_after_update_window_line
P_ ((struct glyph_row
*));
292 void activate_scroll_bars (FRAME_PTR
);
293 void deactivate_scroll_bars (FRAME_PTR
);
295 static int is_emacs_window (WindowPtr
);
297 int x_bitmap_icon (struct frame
*, Lisp_Object
);
298 void x_make_frame_visible (struct frame
*);
300 extern void window_scroll (Lisp_Object
, int, int, int);
302 /* Defined in macmenu.h. */
303 extern void menubar_selection_callback (FRAME_PTR
, int);
304 extern void set_frame_menubar (FRAME_PTR
, int, int);
306 /* X display function emulation */
309 XFreePixmap (display
, pixmap
)
310 Display
*display
; /* not used */
313 DisposeGWorld (pixmap
);
317 /* Set foreground color for subsequent QuickDraw commands. Assume
318 graphic port has already been set. */
321 mac_set_forecolor (unsigned long color
)
325 fg_color
.red
= RED16_FROM_ULONG (color
);
326 fg_color
.green
= GREEN16_FROM_ULONG (color
);
327 fg_color
.blue
= BLUE16_FROM_ULONG (color
);
329 RGBForeColor (&fg_color
);
333 /* Set background color for subsequent QuickDraw commands. Assume
334 graphic port has already been set. */
337 mac_set_backcolor (unsigned long color
)
341 bg_color
.red
= RED16_FROM_ULONG (color
);
342 bg_color
.green
= GREEN16_FROM_ULONG (color
);
343 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
345 RGBBackColor (&bg_color
);
348 /* Set foreground and background color for subsequent QuickDraw
349 commands. Assume that the graphic port has already been set. */
352 mac_set_colors (GC gc
)
354 mac_set_forecolor (gc
->foreground
);
355 mac_set_backcolor (gc
->background
);
358 /* Mac version of XDrawLine. */
361 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
367 #if TARGET_API_MAC_CARBON
368 SetPort (GetWindowPort (w
));
380 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
390 LockPixels (GetGWorldPixMap (p
));
393 UnlockPixels (GetGWorldPixMap (p
));
396 /* Mac version of XClearArea. */
399 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
403 unsigned int width
, height
;
406 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
410 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
411 xgc
.background
= mwp
->x_compatible
.background_pixel
;
413 #if TARGET_API_MAC_CARBON
414 SetPort (GetWindowPort (w
));
419 mac_set_colors (&xgc
);
420 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
425 /* Mac version of XClearWindow. */
428 XClearWindow (display
, w
)
432 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
435 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
436 xgc
.background
= mwp
->x_compatible
.background_pixel
;
438 #if TARGET_API_MAC_CARBON
439 SetPort (GetWindowPort (w
));
444 mac_set_colors (&xgc
);
446 #if TARGET_API_MAC_CARBON
450 GetWindowPortBounds (w
, &r
);
453 #else /* not TARGET_API_MAC_CARBON */
454 EraseRect (&(w
->portRect
));
455 #endif /* not TARGET_API_MAC_CARBON */
459 /* Mac replacement for XCopyArea. */
462 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
466 int x
, y
, width
, height
;
467 unsigned short *bits
;
473 bitmap
.rowBytes
= sizeof(unsigned short);
474 bitmap
.baseAddr
= (char *)bits
;
475 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
477 #if TARGET_API_MAC_CARBON
478 SetPort (GetWindowPort (w
));
484 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
486 #if TARGET_API_MAC_CARBON
487 LockPortBits (GetWindowPort (w
));
488 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
489 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
490 UnlockPortBits (GetWindowPort (w
));
491 #else /* not TARGET_API_MAC_CARBON */
492 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
493 overlay_p
? srcOr
: srcCopy
, 0);
494 #endif /* not TARGET_API_MAC_CARBON */
498 /* Mac replacement for XSetClipRectangles. */
501 mac_set_clip_rectangle (display
, w
, r
)
506 #if TARGET_API_MAC_CARBON
507 SetPort (GetWindowPort (w
));
516 /* Mac replacement for XSetClipMask. */
519 mac_reset_clipping (display
, w
)
525 #if TARGET_API_MAC_CARBON
526 SetPort (GetWindowPort (w
));
531 SetRect (&r
, -32767, -32767, 32767, 32767);
536 /* XBM bits seem to be backward within bytes compared with how
543 unsigned char reflected
= 0x00;
544 for (i
= 0; i
< 8; i
++)
546 if (orig
& (0x01 << i
))
547 reflected
|= 0x80 >> i
;
553 /* Mac replacement for XCreateBitmapFromBitmapData. */
556 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
564 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
565 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
566 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
567 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
568 for (i
= 0; i
< h
; i
++)
570 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
571 for (j
= 0; j
< w1
; j
++)
572 *p
++ = reflect_byte (*bits
++);
575 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
580 mac_free_bitmap (bitmap
)
583 xfree (bitmap
->baseAddr
);
588 XCreatePixmap (display
, w
, width
, height
, depth
)
589 Display
*display
; /* not used */
591 unsigned int width
, height
;
592 unsigned int depth
; /* not used */
598 #if TARGET_API_MAC_CARBON
599 SetPort (GetWindowPort (w
));
604 SetRect (&r
, 0, 0, width
, height
);
605 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
613 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
614 Display
*display
; /* not used */
617 unsigned int width
, height
;
618 unsigned long fg
, bg
;
619 unsigned int depth
; /* not used */
624 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
628 SetGWorld (pixmap
, NULL
);
629 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
630 mac_set_forecolor (fg
);
631 mac_set_backcolor (bg
);
632 LockPixels (GetGWorldPixMap (pixmap
));
633 #if TARGET_API_MAC_CARBON
634 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
635 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
636 #else /* not TARGET_API_MAC_CARBON */
637 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
638 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
639 #endif /* not TARGET_API_MAC_CARBON */
640 UnlockPixels (GetGWorldPixMap (pixmap
));
641 mac_free_bitmap (&bitmap
);
647 /* Mac replacement for XFillRectangle. */
650 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
655 unsigned int width
, height
;
659 #if TARGET_API_MAC_CARBON
660 SetPort (GetWindowPort (w
));
666 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
668 PaintRect (&r
); /* using foreground color of gc */
673 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
678 unsigned int width
, height
;
684 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
686 LockPixels (GetGWorldPixMap (p
));
687 PaintRect (&r
); /* using foreground color of gc */
688 UnlockPixels (GetGWorldPixMap (p
));
692 /* Mac replacement for XDrawRectangle: dest is a window. */
695 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
700 unsigned int width
, height
;
704 #if TARGET_API_MAC_CARBON
705 SetPort (GetWindowPort (w
));
711 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
713 FrameRect (&r
); /* using foreground color of gc */
717 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
720 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
725 unsigned int width
, height
;
731 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
733 LockPixels (GetGWorldPixMap (p
));
734 FrameRect (&r
); /* using foreground color of gc */
735 UnlockPixels (GetGWorldPixMap (p
));
740 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
747 int nchars
, mode
, bytes_per_char
;
749 #if TARGET_API_MAC_CARBON
750 SetPort (GetWindowPort (w
));
757 TextFont (gc
->font
->mac_fontnum
);
758 TextSize (gc
->font
->mac_fontsize
);
759 TextFace (gc
->font
->mac_fontface
);
763 DrawText (buf
, 0, nchars
* bytes_per_char
);
767 /* Mac replacement for XDrawString. */
770 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
778 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
782 /* Mac replacement for XDrawString16. */
785 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
793 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
798 /* Mac replacement for XDrawImageString. */
801 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
809 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
813 /* Mac replacement for XDrawString16. */
816 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
824 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
829 /* Mac replacement for XCopyArea: dest must be window. */
832 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
839 unsigned int width
, height
;
844 #if TARGET_API_MAC_CARBON
845 SetPort (GetWindowPort (dest
));
850 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
851 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
853 ForeColor (blackColor
);
854 BackColor (whiteColor
);
856 LockPixels (GetGWorldPixMap (src
));
857 #if TARGET_API_MAC_CARBON
858 LockPortBits (GetWindowPort (dest
));
859 CopyBits (GetPortBitMapForCopyBits (src
),
860 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
861 &src_r
, &dest_r
, srcCopy
, 0);
862 UnlockPortBits (GetWindowPort (dest
));
863 #else /* not TARGET_API_MAC_CARBON */
864 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
865 &src_r
, &dest_r
, srcCopy
, 0);
866 #endif /* not TARGET_API_MAC_CARBON */
867 UnlockPixels (GetGWorldPixMap (src
));
872 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
873 width
, height
, dest_x
, dest_y
)
879 unsigned int width
, height
;
884 #if TARGET_API_MAC_CARBON
885 SetPort (GetWindowPort (dest
));
890 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
891 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
893 ForeColor (blackColor
);
894 BackColor (whiteColor
);
896 LockPixels (GetGWorldPixMap (src
));
897 LockPixels (GetGWorldPixMap (mask
));
898 #if TARGET_API_MAC_CARBON
899 LockPortBits (GetWindowPort (dest
));
900 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
901 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
902 &src_r
, &src_r
, &dest_r
);
903 UnlockPortBits (GetWindowPort (dest
));
904 #else /* not TARGET_API_MAC_CARBON */
905 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
906 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
907 #endif /* not TARGET_API_MAC_CARBON */
908 UnlockPixels (GetGWorldPixMap (mask
));
909 UnlockPixels (GetGWorldPixMap (src
));
914 /* Convert a pair of local coordinates to global (screen) coordinates.
915 Assume graphic port has been properly set. */
917 local_to_global_coord (short *h
, short *v
)
931 /* Mac replacement for XCopyArea: used only for scrolling. */
934 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
939 unsigned int width
, height
;
942 #if TARGET_API_MAC_CARBON
943 Rect gw_r
, src_r
, dest_r
;
945 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
946 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
948 SetPort (GetWindowPort (w
));
950 ForeColor (blackColor
);
951 BackColor (whiteColor
);
953 LockPortBits (GetWindowPort (w
));
955 const BitMap
*bitmap
= GetPortBitMapForCopyBits (GetWindowPort (w
));
956 CopyBits (bitmap
, bitmap
, &src_r
, &dest_r
, srcCopy
, 0);
958 UnlockPortBits (GetWindowPort (w
));
961 #else /* not TARGET_API_MAC_CARBON */
969 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
970 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
973 /* Need to use global coordinates and screenBits since src and dest
974 areas overlap in general. */
975 local_to_global_coord (&src_r
.left
, &src_r
.top
);
976 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
977 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
978 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
980 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
982 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
983 color mapping in CopyBits. Otherwise, it will be slow. */
984 ForeColor (blackColor
);
985 BackColor (whiteColor
);
986 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
990 #endif /* not TARGET_API_MAC_CARBON */
994 /* Mac replacement for XCopyArea: dest must be Pixmap. */
997 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1003 unsigned int width
, height
;
1008 SetGWorld (dest
, NULL
);
1009 ForeColor (blackColor
);
1010 BackColor (whiteColor
);
1012 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1013 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1015 LockPixels (GetGWorldPixMap (src
));
1016 LockPixels (GetGWorldPixMap (dest
));
1017 #if TARGET_API_MAC_CARBON
1018 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
1019 &src_r
, &dest_r
, srcCopy
, 0);
1020 #else /* not TARGET_API_MAC_CARBON */
1021 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
1022 &src_r
, &dest_r
, srcCopy
, 0);
1023 #endif /* not TARGET_API_MAC_CARBON */
1024 UnlockPixels (GetGWorldPixMap (dest
));
1025 UnlockPixels (GetGWorldPixMap (src
));
1030 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
1031 width
, height
, dest_x
, dest_y
)
1033 Pixmap src
, mask
, dest
;
1036 unsigned int width
, height
;
1041 SetGWorld (dest
, NULL
);
1042 ForeColor (blackColor
);
1043 BackColor (whiteColor
);
1045 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1046 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1048 LockPixels (GetGWorldPixMap (src
));
1049 LockPixels (GetGWorldPixMap (mask
));
1050 LockPixels (GetGWorldPixMap (dest
));
1051 #if TARGET_API_MAC_CARBON
1052 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1053 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1054 #else /* not TARGET_API_MAC_CARBON */
1055 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1056 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1057 #endif /* not TARGET_API_MAC_CARBON */
1058 UnlockPixels (GetGWorldPixMap (dest
));
1059 UnlockPixels (GetGWorldPixMap (mask
));
1060 UnlockPixels (GetGWorldPixMap (src
));
1064 /* Mac replacement for XChangeGC. */
1067 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1070 if (mask
& GCForeground
)
1071 gc
->foreground
= xgcv
->foreground
;
1072 if (mask
& GCBackground
)
1073 gc
->background
= xgcv
->background
;
1075 gc
->font
= xgcv
->font
;
1079 /* Mac replacement for XCreateGC. */
1082 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1085 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1086 bzero (gc
, sizeof (XGCValues
));
1088 XChangeGC (ignore
, gc
, mask
, xgcv
);
1094 /* Used in xfaces.c. */
1097 XFreeGC (display
, gc
)
1105 /* Mac replacement for XGetGCValues. */
1108 XGetGCValues (void* ignore
, XGCValues
*gc
,
1109 unsigned long mask
, XGCValues
*xgcv
)
1111 XChangeGC (ignore
, xgcv
, mask
, gc
);
1115 /* Mac replacement for XSetForeground. */
1118 XSetForeground (display
, gc
, color
)
1121 unsigned long color
;
1123 gc
->foreground
= color
;
1127 /* Mac replacement for XSetFont. */
1130 XSetFont (display
, gc
, font
)
1140 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1141 int *direction
,int *font_ascent
,
1142 int *font_descent
, XCharStruct
*cs
)
1144 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1148 /* x_sync is a no-op on Mac. */
1156 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1157 Calls to XFlush should be unnecessary because the X output buffer
1158 is flushed automatically as needed by calls to XPending,
1159 XNextEvent, or XWindowEvent according to the XFlush man page.
1160 XTread_socket calls XPending. Removing XFlush improves
1163 #if TARGET_API_MAC_CARBON
1164 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1166 #define XFlush(DISPLAY) (void) 0
1169 /* Flush display of frame F, or of all frames if F is null. */
1175 #if TARGET_API_MAC_CARBON
1179 Lisp_Object rest
, frame
;
1180 FOR_EACH_FRAME (rest
, frame
)
1181 x_flush (XFRAME (frame
));
1183 else if (FRAME_X_P (f
))
1184 XFlush (FRAME_MAC_DISPLAY (f
));
1186 #endif /* TARGET_API_MAC_CARBON */
1191 /* Return the struct mac_display_info corresponding to DPY. There's
1194 struct mac_display_info
*
1195 mac_display_info_for_display (dpy
)
1198 return &one_mac_display_info
;
1203 /***********************************************************************
1204 Starting and ending an update
1205 ***********************************************************************/
1207 /* Start an update of frame F. This function is installed as a hook
1208 for update_begin, i.e. it is called when update_begin is called.
1209 This function is called prior to calls to x_update_window_begin for
1210 each window being updated. */
1216 /* Nothing to do. */
1220 /* Start update of window W. Set the global variable updated_window
1221 to the window being updated and set output_cursor to the cursor
1225 x_update_window_begin (w
)
1228 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1229 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1232 set_output_cursor (&w
->cursor
);
1236 if (f
== display_info
->mouse_face_mouse_frame
)
1238 /* Don't do highlighting for mouse motion during the update. */
1239 display_info
->mouse_face_defer
= 1;
1241 /* If F needs to be redrawn, simply forget about any prior mouse
1243 if (FRAME_GARBAGED_P (f
))
1244 display_info
->mouse_face_window
= Qnil
;
1246 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1247 their mouse_face_p flag set, which means that they are always
1248 unequal to rows in a desired matrix which never have that
1249 flag set. So, rows containing mouse-face glyphs are never
1250 scrolled, and we don't have to switch the mouse highlight off
1251 here to prevent it from being scrolled. */
1253 /* Can we tell that this update does not affect the window
1254 where the mouse highlight is? If so, no need to turn off.
1255 Likewise, don't do anything if the frame is garbaged;
1256 in that case, the frame's current matrix that we would use
1257 is all wrong, and we will redisplay that line anyway. */
1258 if (!NILP (display_info
->mouse_face_window
)
1259 && w
== XWINDOW (display_info
->mouse_face_window
))
1263 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1264 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1267 if (i
< w
->desired_matrix
->nrows
)
1268 clear_mouse_face (display_info
);
1277 /* Draw a vertical window border from (x,y0) to (x,y1) */
1280 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1284 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1286 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1287 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1291 /* End update of window W (which is equal to updated_window).
1293 Draw vertical borders between horizontally adjacent windows, and
1294 display W's cursor if CURSOR_ON_P is non-zero.
1296 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1297 glyphs in mouse-face were overwritten. In that case we have to
1298 make sure that the mouse-highlight is properly redrawn.
1300 W may be a menu bar pseudo-window in case we don't have X toolkit
1301 support. Such windows don't have a cursor, so don't display it
1305 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1307 int cursor_on_p
, mouse_face_overwritten_p
;
1309 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1311 if (!w
->pseudo_window_p
)
1316 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1318 output_cursor
.x
, output_cursor
.y
);
1320 x_draw_vertical_border (w
);
1322 draw_window_fringes (w
);
1327 /* If a row with mouse-face was overwritten, arrange for
1328 XTframe_up_to_date to redisplay the mouse highlight. */
1329 if (mouse_face_overwritten_p
)
1331 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1332 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1333 dpyinfo
->mouse_face_window
= Qnil
;
1337 /* Unhide the caret. This won't actually show the cursor, unless it
1338 was visible before the corresponding call to HideCaret in
1339 x_update_window_begin. */
1340 if (w32_use_visible_system_caret
)
1341 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1344 updated_window
= NULL
;
1348 /* End update of frame F. This function is installed as a hook in
1355 /* Reset the background color of Mac OS Window to that of the frame after
1356 update so that it is used by Mac Toolbox to clear the update region before
1357 an update event is generated. */
1358 #if TARGET_API_MAC_CARBON
1359 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1361 SetPort (FRAME_MAC_WINDOW (f
));
1364 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1366 /* Mouse highlight may be displayed again. */
1367 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1370 XFlush (FRAME_MAC_DISPLAY (f
));
1375 /* This function is called from various places in xdisp.c whenever a
1376 complete update has been performed. The global variable
1377 updated_window is not available here. */
1380 XTframe_up_to_date (f
)
1385 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1387 if (dpyinfo
->mouse_face_deferred_gc
1388 || f
== dpyinfo
->mouse_face_mouse_frame
)
1391 if (dpyinfo
->mouse_face_mouse_frame
)
1392 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1393 dpyinfo
->mouse_face_mouse_x
,
1394 dpyinfo
->mouse_face_mouse_y
);
1395 dpyinfo
->mouse_face_deferred_gc
= 0;
1402 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1403 arrow bitmaps, or clear the fringes if no bitmaps are required
1404 before DESIRED_ROW is made current. The window being updated is
1405 found in updated_window. This function is called from
1406 update_window_line only if it is known that there are differences
1407 between bitmaps to be drawn between current row and DESIRED_ROW. */
1410 x_after_update_window_line (desired_row
)
1411 struct glyph_row
*desired_row
;
1413 struct window
*w
= updated_window
;
1419 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1420 desired_row
->redraw_fringe_bitmaps_p
= 1;
1422 /* When a window has disappeared, make sure that no rest of
1423 full-width rows stays visible in the internal border. Could
1424 check here if updated_window is the leftmost/rightmost window,
1425 but I guess it's not worth doing since vertically split windows
1426 are almost never used, internal border is rarely set, and the
1427 overhead is very small. */
1428 if (windows_or_buffers_changed
1429 && desired_row
->full_width_p
1430 && (f
= XFRAME (w
->frame
),
1431 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1433 && (height
= desired_row
->visible_height
,
1436 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1437 /* Internal border is drawn below the tool bar. */
1438 if (WINDOWP (f
->tool_bar_window
)
1439 && w
== XWINDOW (f
->tool_bar_window
))
1444 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1445 0, y
, width
, height
, 0);
1446 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1447 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1455 /* Draw the bitmap WHICH in one of the left or right fringes of
1456 window W. ROW is the glyph row for which to display the bitmap; it
1457 determines the vertical position at which the bitmap has to be
1461 x_draw_fringe_bitmap (w
, row
, p
)
1463 struct glyph_row
*row
;
1464 struct draw_fringe_bitmap_params
*p
;
1466 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1467 Display
*display
= FRAME_MAC_DISPLAY (f
);
1468 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1470 GC gc
= f
->output_data
.mac
->normal_gc
;
1471 struct face
*face
= p
->face
;
1474 /* Must clip because of partially visible lines. */
1475 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1478 /* Adjust position of "bottom aligned" bitmap on partially
1479 visible last row. */
1481 int oldVH
= row
->visible_height
;
1482 row
->visible_height
= p
->h
;
1483 row
->y
-= rowY
- p
->y
;
1484 x_clip_to_row (w
, row
, gc
);
1486 row
->visible_height
= oldVH
;
1489 x_clip_to_row (w
, row
, gc
);
1491 if (p
->bx
>= 0 && !p
->overlay_p
)
1494 gcv
.foreground
= face
->background
;
1496 #if 0 /* MAC_TODO: stipple */
1497 /* In case the same realized face is used for fringes and
1498 for something displayed in the text (e.g. face `region' on
1499 mono-displays, the fill style may have been changed to
1500 FillSolid in x_draw_glyph_string_background. */
1502 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1504 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1507 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1509 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1511 #if 0 /* MAC_TODO: stipple */
1513 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1519 unsigned short *bits
= p
->bits
+ p
->dh
;
1521 gcv
.foreground
= (p
->cursor_p
1522 ? (p
->overlay_p
? face
->background
1523 : f
->output_data
.mac
->cursor_pixel
)
1524 : face
->foreground
);
1525 gcv
.background
= face
->background
;
1527 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1528 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1531 mac_reset_clipping (display
, window
);
1535 /* This is called when starting Emacs and when restarting after
1536 suspend. When starting Emacs, no window is mapped. And nothing
1537 must be done to Emacs's own window if it is suspended (though that
1541 XTset_terminal_modes ()
1545 /* This is called when exiting or suspending Emacs. Exiting will make
1546 the windows go away, and suspending requires no action. */
1549 XTreset_terminal_modes ()
1554 /***********************************************************************
1556 ***********************************************************************/
1558 /* Function prototypes of this page. */
1560 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1561 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1564 /* Return a pointer to per-char metric information in FONT of a
1565 character pointed by B which is a pointer to an XChar2b. */
1567 #define PER_CHAR_METRIC(font, b) \
1569 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1570 + (((font)->min_byte1 || (font)->max_byte1) \
1571 ? (((b)->byte1 - (font)->min_byte1) \
1572 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1574 : &((font)->max_bounds))
1577 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1578 is not contained in the font. */
1580 static INLINE XCharStruct
*
1581 x_per_char_metric (font
, char2b
)
1585 /* The result metric information. */
1586 XCharStruct
*pcm
= NULL
;
1588 xassert (font
&& char2b
);
1590 if (font
->per_char
!= NULL
)
1592 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1594 /* min_char_or_byte2 specifies the linear character index
1595 corresponding to the first element of the per_char array,
1596 max_char_or_byte2 is the index of the last character. A
1597 character with non-zero CHAR2B->byte1 is not in the font.
1598 A character with byte2 less than min_char_or_byte2 or
1599 greater max_char_or_byte2 is not in the font. */
1600 if (char2b
->byte1
== 0
1601 && char2b
->byte2
>= font
->min_char_or_byte2
1602 && char2b
->byte2
<= font
->max_char_or_byte2
)
1603 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1607 /* If either min_byte1 or max_byte1 are nonzero, both
1608 min_char_or_byte2 and max_char_or_byte2 are less than
1609 256, and the 2-byte character index values corresponding
1610 to the per_char array element N (counting from 0) are:
1612 byte1 = N/D + min_byte1
1613 byte2 = N\D + min_char_or_byte2
1617 D = max_char_or_byte2 - min_char_or_byte2 + 1
1618 / = integer division
1619 \ = integer modulus */
1620 if (char2b
->byte1
>= font
->min_byte1
1621 && char2b
->byte1
<= font
->max_byte1
1622 && char2b
->byte2
>= font
->min_char_or_byte2
1623 && char2b
->byte2
<= font
->max_char_or_byte2
)
1625 pcm
= (font
->per_char
1626 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1627 * (char2b
->byte1
- font
->min_byte1
))
1628 + (char2b
->byte2
- font
->min_char_or_byte2
));
1634 /* If the per_char pointer is null, all glyphs between the first
1635 and last character indexes inclusive have the same
1636 information, as given by both min_bounds and max_bounds. */
1637 if (char2b
->byte2
>= font
->min_char_or_byte2
1638 && char2b
->byte2
<= font
->max_char_or_byte2
)
1639 pcm
= &font
->max_bounds
;
1642 return ((pcm
== NULL
1643 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1650 static XCharStruct
*
1651 mac_per_char_metric (font
, char2b
, font_type
)
1656 return x_per_char_metric (font
, char2b
);
1660 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1661 the two-byte form of C. Encoding is returned in *CHAR2B. */
1664 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1667 struct font_info
*font_info
;
1670 int charset
= CHAR_CHARSET (c
);
1671 XFontStruct
*font
= font_info
->font
;
1673 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1674 This may be either a program in a special encoder language or a
1676 if (font_info
->font_encoder
)
1678 /* It's a program. */
1679 struct ccl_program
*ccl
= font_info
->font_encoder
;
1681 if (CHARSET_DIMENSION (charset
) == 1)
1683 ccl
->reg
[0] = charset
;
1684 ccl
->reg
[1] = char2b
->byte2
;
1688 ccl
->reg
[0] = charset
;
1689 ccl
->reg
[1] = char2b
->byte1
;
1690 ccl
->reg
[2] = char2b
->byte2
;
1693 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1695 /* We assume that MSBs are appropriately set/reset by CCL
1697 if (font
->max_byte1
== 0) /* 1-byte font */
1698 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1700 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1702 else if (font_info
->encoding
[charset
])
1704 /* Fixed encoding scheme. See fontset.h for the meaning of the
1705 encoding numbers. */
1706 int enc
= font_info
->encoding
[charset
];
1708 if ((enc
== 1 || enc
== 2)
1709 && CHARSET_DIMENSION (charset
) == 2)
1710 char2b
->byte1
|= 0x80;
1712 if (enc
== 1 || enc
== 3)
1713 char2b
->byte2
|= 0x80;
1719 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1720 char2b
->byte1
= sjis1
;
1721 char2b
->byte2
= sjis2
;
1726 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1728 return FONT_TYPE_UNKNOWN
;
1733 /***********************************************************************
1735 ***********************************************************************/
1738 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1739 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1740 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1742 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1743 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1744 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1745 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1746 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1747 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1748 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1749 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1750 unsigned long *, double, int));*/
1751 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1752 double, int, unsigned long));
1753 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1754 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1755 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1756 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1757 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1758 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1760 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1761 int, int, int, int, int, int,
1763 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
1764 int, int, int, Rect
*));
1767 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
1771 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
1776 struct glyph_string
*s
;
1778 if (s
->font
== FRAME_FONT (s
->f
)
1779 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
1780 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
1782 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
1785 /* Cursor on non-default face: must merge. */
1789 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
1790 xgcv
.foreground
= s
->face
->background
;
1792 /* If the glyph would be invisible, try a different foreground. */
1793 if (xgcv
.foreground
== xgcv
.background
)
1794 xgcv
.foreground
= s
->face
->foreground
;
1795 if (xgcv
.foreground
== xgcv
.background
)
1796 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
1797 if (xgcv
.foreground
== xgcv
.background
)
1798 xgcv
.foreground
= s
->face
->foreground
;
1800 /* Make sure the cursor is distinct from text in this face. */
1801 if (xgcv
.background
== s
->face
->background
1802 && xgcv
.foreground
== s
->face
->foreground
)
1804 xgcv
.background
= s
->face
->foreground
;
1805 xgcv
.foreground
= s
->face
->background
;
1808 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1809 xgcv
.font
= s
->font
;
1810 mask
= GCForeground
| GCBackground
| GCFont
;
1812 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1813 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1816 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1817 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1819 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1824 /* Set up S->gc of glyph string S for drawing text in mouse face. */
1827 x_set_mouse_face_gc (s
)
1828 struct glyph_string
*s
;
1833 /* What face has to be used last for the mouse face? */
1834 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
1835 face
= FACE_FROM_ID (s
->f
, face_id
);
1837 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
1839 if (s
->first_glyph
->type
== CHAR_GLYPH
)
1840 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
1842 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
1843 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
1844 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1846 /* If font in this face is same as S->font, use it. */
1847 if (s
->font
== s
->face
->font
)
1848 s
->gc
= s
->face
->gc
;
1851 /* Otherwise construct scratch_cursor_gc with values from FACE
1856 xgcv
.background
= s
->face
->background
;
1857 xgcv
.foreground
= s
->face
->foreground
;
1858 IF_DEBUG (x_check_font (s
->f
, s
->font
));
1859 xgcv
.font
= s
->font
;
1860 mask
= GCForeground
| GCBackground
| GCFont
;
1862 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
1863 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
1866 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
1867 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
1869 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
1872 xassert (s
->gc
!= 0);
1876 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1877 Faces to use in the mode line have already been computed when the
1878 matrix was built, so there isn't much to do, here. */
1881 x_set_mode_line_face_gc (s
)
1882 struct glyph_string
*s
;
1884 s
->gc
= s
->face
->gc
;
1888 /* Set S->gc of glyph string S for drawing that glyph string. Set
1889 S->stippled_p to a non-zero value if the face of S has a stipple
1893 x_set_glyph_string_gc (s
)
1894 struct glyph_string
*s
;
1896 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
1898 if (s
->hl
== DRAW_NORMAL_TEXT
)
1900 s
->gc
= s
->face
->gc
;
1901 s
->stippled_p
= s
->face
->stipple
!= 0;
1903 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
1905 x_set_mode_line_face_gc (s
);
1906 s
->stippled_p
= s
->face
->stipple
!= 0;
1908 else if (s
->hl
== DRAW_CURSOR
)
1910 x_set_cursor_gc (s
);
1913 else if (s
->hl
== DRAW_MOUSE_FACE
)
1915 x_set_mouse_face_gc (s
);
1916 s
->stippled_p
= s
->face
->stipple
!= 0;
1918 else if (s
->hl
== DRAW_IMAGE_RAISED
1919 || s
->hl
== DRAW_IMAGE_SUNKEN
)
1921 s
->gc
= s
->face
->gc
;
1922 s
->stippled_p
= s
->face
->stipple
!= 0;
1926 s
->gc
= s
->face
->gc
;
1927 s
->stippled_p
= s
->face
->stipple
!= 0;
1930 /* GC must have been set. */
1931 xassert (s
->gc
!= 0);
1935 /* Set clipping for output of glyph string S. S may be part of a mode
1936 line or menu if we don't have X toolkit support. */
1939 x_set_glyph_string_clipping (s
)
1940 struct glyph_string
*s
;
1943 get_glyph_string_clip_rect (s
, &r
);
1944 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
1949 Compute left and right overhang of glyph string S. If S is a glyph
1950 string for a composition, assume overhangs don't exist. */
1953 mac_compute_glyph_string_overhangs (s
)
1954 struct glyph_string
*s
;
1957 /* MAC_TODO: XTextExtents16 does nothing yet... */
1960 && s
->first_glyph
->type
== CHAR_GLYPH
)
1963 int direction
, font_ascent
, font_descent
;
1964 XTextExtents16 (s
->font
, s
->char2b
, s
->nchars
, &direction
,
1965 &font_ascent
, &font_descent
, &cs
);
1966 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
1967 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
1973 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
1976 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
1977 struct glyph_string
*s
;
1982 xgcv
.foreground
= s
->gc
->background
;
1983 XFillRectangle (s
->display
, s
->window
, &xgcv
, x
, y
, w
, h
);
1987 /* Draw the background of glyph_string S. If S->background_filled_p
1988 is non-zero don't draw it. FORCE_P non-zero means draw the
1989 background even if it wouldn't be drawn normally. This is used
1990 when a string preceding S draws into the background of S, or S
1991 contains the first component of a composition. */
1994 x_draw_glyph_string_background (s
, force_p
)
1995 struct glyph_string
*s
;
1998 /* Nothing to do if background has already been drawn or if it
1999 shouldn't be drawn in the first place. */
2000 if (!s
->background_filled_p
)
2002 int box_line_width
= max (s
->face
->box_line_width
, 0);
2004 #if 0 /* MAC_TODO: stipple */
2007 /* Fill background with a stipple pattern. */
2008 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2009 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2010 s
->y
+ box_line_width
,
2011 s
->background_width
,
2012 s
->height
- 2 * box_line_width
);
2013 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2014 s
->background_filled_p
= 1;
2018 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2019 || s
->font_not_found_p
2020 || s
->extends_to_end_of_line_p
2023 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2024 s
->background_width
,
2025 s
->height
- 2 * box_line_width
);
2026 s
->background_filled_p
= 1;
2032 /* Draw the foreground of glyph string S. */
2035 x_draw_glyph_string_foreground (s
)
2036 struct glyph_string
*s
;
2040 /* If first glyph of S has a left box line, start drawing the text
2041 of S to the right of that box line. */
2042 if (s
->face
->box
!= FACE_NO_BOX
2043 && s
->first_glyph
->left_box_line_p
)
2044 x
= s
->x
+ abs (s
->face
->box_line_width
);
2048 /* Draw characters of S as rectangles if S's font could not be
2050 if (s
->font_not_found_p
)
2052 for (i
= 0; i
< s
->nchars
; ++i
)
2054 struct glyph
*g
= s
->first_glyph
+ i
;
2055 mac_draw_rectangle (s
->display
, s
->window
,
2056 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2058 x
+= g
->pixel_width
;
2063 char *char1b
= (char *) s
->char2b
;
2064 int boff
= s
->font_info
->baseline_offset
;
2066 if (s
->font_info
->vertical_centering
)
2067 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2069 /* If we can use 8-bit functions, condense S->char2b. */
2071 for (i
= 0; i
< s
->nchars
; ++i
)
2072 char1b
[i
] = s
->char2b
[i
].byte2
;
2074 /* Draw text with XDrawString if background has already been
2075 filled. Otherwise, use XDrawImageString. (Note that
2076 XDrawImageString is usually faster than XDrawString.) Always
2077 use XDrawImageString when drawing the cursor so that there is
2078 no chance that characters under a box cursor are invisible. */
2079 if (s
->for_overlaps_p
2080 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2082 /* Draw characters with 16-bit or 8-bit functions. */
2084 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2085 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2087 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2088 s
->ybase
- boff
, char1b
, s
->nchars
);
2093 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2094 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2096 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2097 s
->ybase
- boff
, char1b
, s
->nchars
);
2102 /* Draw the foreground of composite glyph string S. */
2105 x_draw_composite_glyph_string_foreground (s
)
2106 struct glyph_string
*s
;
2110 /* If first glyph of S has a left box line, start drawing the text
2111 of S to the right of that box line. */
2112 if (s
->face
->box
!= FACE_NO_BOX
2113 && s
->first_glyph
->left_box_line_p
)
2114 x
= s
->x
+ abs (s
->face
->box_line_width
);
2118 /* S is a glyph string for a composition. S->gidx is the index of
2119 the first character drawn for glyphs of this composition.
2120 S->gidx == 0 means we are drawing the very first character of
2121 this composition. */
2123 /* Draw a rectangle for the composition if the font for the very
2124 first character of the composition could not be loaded. */
2125 if (s
->font_not_found_p
)
2128 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2129 s
->width
- 1, s
->height
- 1);
2133 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2134 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2135 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2136 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2142 #ifdef USE_X_TOOLKIT
2144 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2147 /* Return the frame on which widget WIDGET is used.. Abort if frame
2148 cannot be determined. */
2150 static struct frame
*
2151 x_frame_of_widget (widget
)
2154 struct x_display_info
*dpyinfo
;
2158 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2160 /* Find the top-level shell of the widget. Note that this function
2161 can be called when the widget is not yet realized, so XtWindow
2162 (widget) == 0. That's the reason we can't simply use
2163 x_any_window_to_frame. */
2164 while (!XtIsTopLevelShell (widget
))
2165 widget
= XtParent (widget
);
2167 /* Look for a frame with that top-level widget. Allocate the color
2168 on that frame to get the right gamma correction value. */
2169 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2170 if (GC_FRAMEP (XCAR (tail
))
2171 && (f
= XFRAME (XCAR (tail
)),
2172 (f
->output_data
.nothing
!= 1
2173 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2174 && f
->output_data
.x
->widget
== widget
)
2181 /* Allocate the color COLOR->pixel on the screen and display of
2182 widget WIDGET in colormap CMAP. If an exact match cannot be
2183 allocated, try the nearest color available. Value is non-zero
2184 if successful. This is called from lwlib. */
2187 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2192 struct frame
*f
= x_frame_of_widget (widget
);
2193 return x_alloc_nearest_color (f
, cmap
, color
);
2197 #endif /* USE_X_TOOLKIT */
2199 #if 0 /* MAC_TODO */
2201 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2202 CMAP. If an exact match can't be allocated, try the nearest color
2203 available. Value is non-zero if successful. Set *COLOR to the
2207 x_alloc_nearest_color (f
, cmap
, color
)
2212 Display
*display
= FRAME_X_DISPLAY (f
);
2213 Screen
*screen
= FRAME_X_SCREEN (f
);
2216 gamma_correct (f
, color
);
2217 rc
= XAllocColor (display
, cmap
, color
);
2220 /* If we got to this point, the colormap is full, so we're going
2221 to try to get the next closest color. The algorithm used is
2222 a least-squares matching, which is what X uses for closest
2223 color matching with StaticColor visuals. */
2225 unsigned long nearest_delta
= ~0;
2226 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2227 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2229 for (i
= 0; i
< ncells
; ++i
)
2231 XQueryColors (display
, cmap
, cells
, ncells
);
2233 for (nearest
= i
= 0; i
< ncells
; ++i
)
2235 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2236 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2237 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2238 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2240 if (delta
< nearest_delta
)
2243 nearest_delta
= delta
;
2247 color
->red
= cells
[nearest
].red
;
2248 color
->green
= cells
[nearest
].green
;
2249 color
->blue
= cells
[nearest
].blue
;
2250 rc
= XAllocColor (display
, cmap
, color
);
2253 #ifdef DEBUG_X_COLORS
2255 register_color (color
->pixel
);
2256 #endif /* DEBUG_X_COLORS */
2262 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2263 It's necessary to do this instead of just using PIXEL directly to
2264 get color reference counts right. */
2267 x_copy_color (f
, pixel
)
2269 unsigned long pixel
;
2273 color
.pixel
= pixel
;
2275 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2276 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2278 #ifdef DEBUG_X_COLORS
2279 register_color (pixel
);
2285 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2286 It's necessary to do this instead of just using PIXEL directly to
2287 get color reference counts right. */
2290 x_copy_dpy_color (dpy
, cmap
, pixel
)
2293 unsigned long pixel
;
2297 color
.pixel
= pixel
;
2299 XQueryColor (dpy
, cmap
, &color
);
2300 XAllocColor (dpy
, cmap
, &color
);
2302 #ifdef DEBUG_X_COLORS
2303 register_color (pixel
);
2308 #endif /* MAC_TODO */
2311 /* Brightness beyond which a color won't have its highlight brightness
2314 Nominally, highlight colors for `3d' faces are calculated by
2315 brightening an object's color by a constant scale factor, but this
2316 doesn't yield good results for dark colors, so for colors who's
2317 brightness is less than this value (on a scale of 0-255) have to
2318 use an additional additive factor.
2320 The value here is set so that the default menu-bar/mode-line color
2321 (grey75) will not have its highlights changed at all. */
2322 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2325 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2326 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2327 If this produces the same color as COLOR, try a color where all RGB
2328 values have DELTA added. Return the allocated color in *COLOR.
2329 DISPLAY is the X display, CMAP is the colormap to operate on.
2330 Value is non-zero if successful. */
2333 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2335 unsigned long *color
;
2342 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2345 /* Change RGB values by specified FACTOR. Avoid overflow! */
2346 xassert (factor
>= 0);
2347 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2348 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2349 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2351 /* Calculate brightness of COLOR. */
2352 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2353 + BLUE_FROM_ULONG (*color
)) / 6;
2355 /* We only boost colors that are darker than
2356 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2357 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2358 /* Make an additive adjustment to NEW, because it's dark enough so
2359 that scaling by FACTOR alone isn't enough. */
2361 /* How far below the limit this color is (0 - 1, 1 being darker). */
2362 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2363 /* The additive adjustment. */
2364 int min_delta
= delta
* dimness
* factor
/ 2;
2367 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2368 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2369 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2371 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2372 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2373 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2377 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2378 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2379 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2381 /* MAC_TODO: Map to palette and retry with delta if same? */
2382 /* MAC_TODO: Free colors (if using palette)? */
2393 /* Set up the foreground color for drawing relief lines of glyph
2394 string S. RELIEF is a pointer to a struct relief containing the GC
2395 with which lines will be drawn. Use a color that is FACTOR or
2396 DELTA lighter or darker than the relief's background which is found
2397 in S->f->output_data.x->relief_background. If such a color cannot
2398 be allocated, use DEFAULT_PIXEL, instead. */
2401 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2403 struct relief
*relief
;
2406 unsigned long default_pixel
;
2409 struct mac_output
*di
= f
->output_data
.mac
;
2410 unsigned long mask
= GCForeground
;
2411 unsigned long pixel
;
2412 unsigned long background
= di
->relief_background
;
2413 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2415 /* MAC_TODO: Free colors (if using palette)? */
2417 /* Allocate new color. */
2418 xgcv
.foreground
= default_pixel
;
2420 if (dpyinfo
->n_planes
!= 1
2421 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2423 relief
->allocated_p
= 1;
2424 xgcv
.foreground
= relief
->pixel
= pixel
;
2427 if (relief
->gc
== 0)
2429 #if 0 /* MAC_TODO: stipple */
2430 xgcv
.stipple
= dpyinfo
->gray
;
2433 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2436 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2440 /* Set up colors for the relief lines around glyph string S. */
2443 x_setup_relief_colors (s
)
2444 struct glyph_string
*s
;
2446 struct mac_output
*di
= s
->f
->output_data
.mac
;
2447 unsigned long color
;
2449 if (s
->face
->use_box_color_for_shadows_p
)
2450 color
= s
->face
->box_color
;
2451 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2453 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2454 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2459 /* Get the background color of the face. */
2460 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2461 color
= xgcv
.background
;
2464 if (di
->white_relief
.gc
== 0
2465 || color
!= di
->relief_background
)
2467 di
->relief_background
= color
;
2468 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2469 WHITE_PIX_DEFAULT (s
->f
));
2470 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2471 BLACK_PIX_DEFAULT (s
->f
));
2476 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2477 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2478 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2479 relief. LEFT_P non-zero means draw a relief on the left side of
2480 the rectangle. RIGHT_P non-zero means draw a relief on the right
2481 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2485 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2486 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2488 int left_x
, top_y
, right_x
, bottom_y
, width
;
2489 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2492 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2493 Window window
= FRAME_MAC_WINDOW (f
);
2498 gc
= f
->output_data
.mac
->white_relief
.gc
;
2500 gc
= f
->output_data
.mac
->black_relief
.gc
;
2501 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2505 for (i
= 0; i
< width
; ++i
)
2506 XDrawLine (dpy
, window
, gc
,
2507 left_x
+ i
* left_p
, top_y
+ i
,
2508 right_x
- i
* right_p
, top_y
+ i
);
2512 for (i
= 0; i
< width
; ++i
)
2513 XDrawLine (dpy
, window
, gc
,
2514 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2516 mac_reset_clipping (dpy
, window
);
2518 gc
= f
->output_data
.mac
->black_relief
.gc
;
2520 gc
= f
->output_data
.mac
->white_relief
.gc
;
2521 mac_set_clip_rectangle (dpy
, window
,
2526 for (i
= 0; i
< width
; ++i
)
2527 XDrawLine (dpy
, window
, gc
,
2528 left_x
+ i
* left_p
, bottom_y
- i
,
2529 right_x
- i
* right_p
, bottom_y
- i
);
2533 for (i
= 0; i
< width
; ++i
)
2534 XDrawLine (dpy
, window
, gc
,
2535 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2537 mac_reset_clipping (dpy
, window
);
2541 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2542 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2543 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2544 left side of the rectangle. RIGHT_P non-zero means draw a line
2545 on the right side of the rectangle. CLIP_RECT is the clipping
2546 rectangle to use when drawing. */
2549 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2550 left_p
, right_p
, clip_rect
)
2551 struct glyph_string
*s
;
2552 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2557 xgcv
.foreground
= s
->face
->box_color
;
2558 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2561 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2562 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2566 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2567 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2570 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2571 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2575 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2576 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2578 mac_reset_clipping (s
->display
, s
->window
);
2582 /* Draw a box around glyph string S. */
2585 x_draw_glyph_string_box (s
)
2586 struct glyph_string
*s
;
2588 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2589 int left_p
, right_p
;
2590 struct glyph
*last_glyph
;
2593 last_x
= window_box_right (s
->w
, s
->area
);
2594 if (s
->row
->full_width_p
2595 && !s
->w
->pseudo_window_p
)
2597 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2598 if (s
->area
!= RIGHT_MARGIN_AREA
2599 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2600 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2603 /* The glyph that may have a right box line. */
2604 last_glyph
= (s
->cmp
|| s
->img
2606 : s
->first_glyph
+ s
->nchars
- 1);
2608 width
= abs (s
->face
->box_line_width
);
2609 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2611 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2613 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2615 bottom_y
= top_y
+ s
->height
- 1;
2617 left_p
= (s
->first_glyph
->left_box_line_p
2618 || (s
->hl
== DRAW_MOUSE_FACE
2620 || s
->prev
->hl
!= s
->hl
)));
2621 right_p
= (last_glyph
->right_box_line_p
2622 || (s
->hl
== DRAW_MOUSE_FACE
2624 || s
->next
->hl
!= s
->hl
)));
2626 get_glyph_string_clip_rect (s
, &clip_rect
);
2628 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2629 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2630 left_p
, right_p
, &clip_rect
);
2633 x_setup_relief_colors (s
);
2634 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2635 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2640 /* Draw foreground of image glyph string S. */
2643 x_draw_image_foreground (s
)
2644 struct glyph_string
*s
;
2647 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2649 /* If first glyph of S has a left box line, start drawing it to the
2650 right of that line. */
2651 if (s
->face
->box
!= FACE_NO_BOX
2652 && s
->first_glyph
->left_box_line_p
2654 x
+= abs (s
->face
->box_line_width
);
2656 /* If there is a margin around the image, adjust x- and y-position
2658 if (s
->slice
.x
== 0)
2659 x
+= s
->img
->hmargin
;
2660 if (s
->slice
.y
== 0)
2661 y
+= s
->img
->vmargin
;
2668 XRectangle clip_rect
, image_rect
, r
;
2670 get_glyph_string_clip_rect (s
, &nr
);
2671 CONVERT_TO_XRECT (clip_rect
, nr
);
2674 image_rect
.width
= s
->slice
.width
;
2675 image_rect
.height
= s
->slice
.height
;
2676 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2677 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2679 s
->slice
.x
+ r
.x
- x
, s
->slice
.y
+ r
.y
- y
,
2680 r
.width
, r
.height
, r
.x
, r
.y
);
2685 XRectangle clip_rect
, image_rect
, r
;
2687 get_glyph_string_clip_rect (s
, &nr
);
2688 CONVERT_TO_XRECT (clip_rect
, nr
);
2691 image_rect
.width
= s
->slice
.width
;
2692 image_rect
.height
= s
->slice
.height
;
2693 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2694 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2695 s
->slice
.x
+ r
.x
- x
, s
->slice
.y
+ r
.y
- y
,
2696 r
.width
, r
.height
, r
.x
, r
.y
);
2698 /* When the image has a mask, we can expect that at
2699 least part of a mouse highlight or a block cursor will
2700 be visible. If the image doesn't have a mask, make
2701 a block cursor visible by drawing a rectangle around
2702 the image. I believe it's looking better if we do
2703 nothing here for mouse-face. */
2704 if (s
->hl
== DRAW_CURSOR
)
2706 int r
= s
->img
->relief
;
2708 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
2710 s
->slice
.width
+ r
*2 - 1,
2711 s
->slice
.height
+ r
*2 - 1);
2716 /* Draw a rectangle if image could not be loaded. */
2717 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2718 s
->slice
.width
- 1, s
->slice
.height
- 1);
2722 /* Draw a relief around the image glyph string S. */
2725 x_draw_image_relief (s
)
2726 struct glyph_string
*s
;
2728 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2731 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2733 /* If first glyph of S has a left box line, start drawing it to the
2734 right of that line. */
2735 if (s
->face
->box
!= FACE_NO_BOX
2736 && s
->first_glyph
->left_box_line_p
2738 x
+= abs (s
->face
->box_line_width
);
2740 /* If there is a margin around the image, adjust x- and y-position
2742 if (s
->slice
.x
== 0)
2743 x
+= s
->img
->hmargin
;
2744 if (s
->slice
.y
== 0)
2745 y
+= s
->img
->vmargin
;
2747 if (s
->hl
== DRAW_IMAGE_SUNKEN
2748 || s
->hl
== DRAW_IMAGE_RAISED
)
2750 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2751 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2755 thick
= abs (s
->img
->relief
);
2756 raised_p
= s
->img
->relief
> 0;
2761 x1
= x
+ s
->slice
.width
+ thick
- 1;
2762 y1
= y
+ s
->slice
.height
+ thick
- 1;
2764 x_setup_relief_colors (s
);
2765 get_glyph_string_clip_rect (s
, &r
);
2766 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
2768 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
2770 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
2775 /* Draw the foreground of image glyph string S to PIXMAP. */
2778 x_draw_image_foreground_1 (s
, pixmap
)
2779 struct glyph_string
*s
;
2783 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2785 /* If first glyph of S has a left box line, start drawing it to the
2786 right of that line. */
2787 if (s
->face
->box
!= FACE_NO_BOX
2788 && s
->first_glyph
->left_box_line_p
2790 x
+= abs (s
->face
->box_line_width
);
2792 /* If there is a margin around the image, adjust x- and y-position
2794 if (s
->slice
.x
== 0)
2795 x
+= s
->img
->hmargin
;
2796 if (s
->slice
.y
== 0)
2797 y
+= s
->img
->vmargin
;
2802 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2803 s
->img
->mask
, pixmap
, s
->gc
,
2804 s
->slice
.x
, s
->slice
.y
,
2805 s
->slice
.width
, s
->slice
.height
,
2809 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2810 s
->slice
.x
, s
->slice
.y
,
2811 s
->slice
.width
, s
->slice
.height
,
2814 /* When the image has a mask, we can expect that at
2815 least part of a mouse highlight or a block cursor will
2816 be visible. If the image doesn't have a mask, make
2817 a block cursor visible by drawing a rectangle around
2818 the image. I believe it's looking better if we do
2819 nothing here for mouse-face. */
2820 if (s
->hl
== DRAW_CURSOR
)
2822 int r
= s
->img
->relief
;
2824 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2825 s
->slice
.width
+ r
*2 - 1,
2826 s
->slice
.height
+ r
*2 - 1);
2831 /* Draw a rectangle if image could not be loaded. */
2832 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2833 s
->slice
.width
- 1, s
->slice
.height
- 1);
2837 /* Draw part of the background of glyph string S. X, Y, W, and H
2838 give the rectangle to draw. */
2841 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2842 struct glyph_string
*s
;
2845 #if 0 /* MAC_TODO: stipple */
2848 /* Fill background with a stipple pattern. */
2849 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2850 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2851 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2854 #endif /* MAC_TODO */
2855 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2859 /* Draw image glyph string S.
2862 s->x +-------------------------
2865 | +-------------------------
2868 | | +-------------------
2874 x_draw_image_glyph_string (s
)
2875 struct glyph_string
*s
;
2878 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2879 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2883 height
= s
->height
- 2 * box_line_vwidth
;
2886 /* Fill background with face under the image. Do it only if row is
2887 taller than image or if image has a clip mask to reduce
2889 s
->stippled_p
= s
->face
->stipple
!= 0;
2890 if (height
> s
->slice
.height
2894 || s
->img
->pixmap
== 0
2895 || s
->width
!= s
->background_width
)
2898 if (s
->first_glyph
->left_box_line_p
2900 x
+= box_line_hwidth
;
2903 if (s
->slice
.y
== 0)
2904 y
+= box_line_vwidth
;
2908 /* Create a pixmap as large as the glyph string. Fill it
2909 with the background color. Copy the image to it, using
2910 its mask. Copy the temporary pixmap to the display. */
2911 int depth
= one_mac_display_info
.n_planes
;
2913 /* Create a pixmap as large as the glyph string. */
2914 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2915 s
->background_width
,
2918 /* Fill the pixmap with the background color/stipple. */
2919 #if 0 /* TODO: stipple */
2922 /* Fill background with a stipple pattern. */
2923 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2924 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2925 0, 0, s
->background_width
, s
->height
);
2926 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2932 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2934 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2935 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2936 0, 0, s
->background_width
,
2938 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2942 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2944 s
->background_filled_p
= 1;
2947 /* Draw the foreground. */
2950 x_draw_image_foreground_1 (s
, pixmap
);
2951 x_set_glyph_string_clipping (s
);
2952 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2953 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2954 mac_reset_clipping (s
->display
, s
->window
);
2955 XFreePixmap (s
->display
, pixmap
);
2958 x_draw_image_foreground (s
);
2960 /* If we must draw a relief around the image, do it. */
2962 || s
->hl
== DRAW_IMAGE_RAISED
2963 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2964 x_draw_image_relief (s
);
2968 /* Draw stretch glyph string S. */
2971 x_draw_stretch_glyph_string (s
)
2972 struct glyph_string
*s
;
2974 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2975 s
->stippled_p
= s
->face
->stipple
!= 0;
2977 if (s
->hl
== DRAW_CURSOR
2978 && !x_stretch_cursor_p
)
2980 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2981 as wide as the stretch glyph. */
2982 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2985 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2987 /* Clear rest using the GC of the original non-cursor face. */
2988 if (width
< s
->background_width
)
2990 int x
= s
->x
+ width
, y
= s
->y
;
2991 int w
= s
->background_width
- width
, h
= s
->height
;
2995 if (s
->row
->mouse_face_p
2996 && cursor_in_mouse_face_p (s
->w
))
2998 x_set_mouse_face_gc (s
);
3004 get_glyph_string_clip_rect (s
, &r
);
3005 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
3007 #if 0 /* MAC_TODO: stipple */
3008 if (s
->face
->stipple
)
3010 /* Fill background with a stipple pattern. */
3011 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3012 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3013 XSetFillStyle (s
->display
, gc
, FillSolid
);
3016 #endif /* MAC_TODO */
3019 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
3020 XSetForeground (s
->display
, gc
, xgcv
.background
);
3021 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3022 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
3025 mac_reset_clipping (s
->display
, s
->window
);
3028 else if (!s
->background_filled_p
)
3029 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3032 s
->background_filled_p
= 1;
3036 /* Draw glyph string S. */
3039 x_draw_glyph_string (s
)
3040 struct glyph_string
*s
;
3042 int relief_drawn_p
= 0;
3044 /* If S draws into the background of its successor, draw the
3045 background of the successor first so that S can draw into it.
3046 This makes S->next use XDrawString instead of XDrawImageString. */
3047 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3049 xassert (s
->next
->img
== NULL
);
3050 x_set_glyph_string_gc (s
->next
);
3051 x_set_glyph_string_clipping (s
->next
);
3052 x_draw_glyph_string_background (s
->next
, 1);
3055 /* Set up S->gc, set clipping and draw S. */
3056 x_set_glyph_string_gc (s
);
3058 /* Draw relief (if any) in advance for char/composition so that the
3059 glyph string can be drawn over it. */
3060 if (!s
->for_overlaps_p
3061 && s
->face
->box
!= FACE_NO_BOX
3062 && (s
->first_glyph
->type
== CHAR_GLYPH
3063 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3066 x_set_glyph_string_clipping (s
);
3067 x_draw_glyph_string_background (s
, 1);
3068 x_draw_glyph_string_box (s
);
3069 x_set_glyph_string_clipping (s
);
3073 x_set_glyph_string_clipping (s
);
3075 switch (s
->first_glyph
->type
)
3078 x_draw_image_glyph_string (s
);
3082 x_draw_stretch_glyph_string (s
);
3086 if (s
->for_overlaps_p
)
3087 s
->background_filled_p
= 1;
3089 x_draw_glyph_string_background (s
, 0);
3090 x_draw_glyph_string_foreground (s
);
3093 case COMPOSITE_GLYPH
:
3094 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3095 s
->background_filled_p
= 1;
3097 x_draw_glyph_string_background (s
, 1);
3098 x_draw_composite_glyph_string_foreground (s
);
3105 if (!s
->for_overlaps_p
)
3107 /* Draw underline. */
3108 if (s
->face
->underline_p
)
3110 unsigned long h
= 1;
3111 unsigned long dy
= s
->height
- h
;
3113 if (s
->face
->underline_defaulted_p
)
3114 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3119 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3120 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3121 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3123 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3127 /* Draw overline. */
3128 if (s
->face
->overline_p
)
3130 unsigned long dy
= 0, h
= 1;
3132 if (s
->face
->overline_color_defaulted_p
)
3133 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3138 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3139 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3140 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3142 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3146 /* Draw strike-through. */
3147 if (s
->face
->strike_through_p
)
3149 unsigned long h
= 1;
3150 unsigned long dy
= (s
->height
- h
) / 2;
3152 if (s
->face
->strike_through_color_defaulted_p
)
3153 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3158 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3159 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3160 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3162 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3166 /* Draw relief if not yet drawn. */
3167 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3168 x_draw_glyph_string_box (s
);
3171 /* Reset clipping. */
3172 mac_reset_clipping (s
->display
, s
->window
);
3175 /* Shift display to make room for inserted glyphs. */
3178 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3180 int x
, y
, width
, height
, shift_by
;
3182 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3183 f
->output_data
.mac
->normal_gc
,
3184 x
, y
, width
, height
,
3188 /* Delete N glyphs at the nominal cursor position. Not implemented
3199 /* Clear entire frame. If updating_frame is non-null, clear that
3200 frame. Otherwise clear the selected frame. */
3210 f
= SELECTED_FRAME ();
3212 /* Clearing the frame will erase any cursor, so mark them all as no
3214 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3215 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3216 output_cursor
.x
= -1;
3218 /* We don't set the output cursor here because there will always
3219 follow an explicit cursor_to. */
3221 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3223 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3224 /* We have to clear the scroll bars, too. If we have changed
3225 colors or something like that, then they should be notified. */
3226 x_scroll_bar_clear (f
);
3229 XFlush (FRAME_MAC_DISPLAY (f
));
3235 /* Invert the middle quarter of the frame for .15 sec. */
3237 /* We use the select system call to do the waiting, so we have to make
3238 sure it's available. If it isn't, we just won't do visual bells. */
3240 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3243 /* Subtract the `struct timeval' values X and Y, storing the result in
3244 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3247 timeval_subtract (result
, x
, y
)
3248 struct timeval
*result
, x
, y
;
3250 /* Perform the carry for the later subtraction by updating y. This
3251 is safer because on some systems the tv_sec member is unsigned. */
3252 if (x
.tv_usec
< y
.tv_usec
)
3254 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3255 y
.tv_usec
-= 1000000 * nsec
;
3259 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3261 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3262 y
.tv_usec
+= 1000000 * nsec
;
3266 /* Compute the time remaining to wait. tv_usec is certainly
3268 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3269 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3271 /* Return indication of whether the result should be considered
3273 return x
.tv_sec
< y
.tv_sec
;
3285 struct timeval wakeup
;
3287 EMACS_GET_TIME (wakeup
);
3289 /* Compute time to wait until, propagating carry from usecs. */
3290 wakeup
.tv_usec
+= 150000;
3291 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3292 wakeup
.tv_usec
%= 1000000;
3294 /* Keep waiting until past the time wakeup. */
3297 struct timeval timeout
;
3299 EMACS_GET_TIME (timeout
);
3301 /* In effect, timeout = wakeup - timeout.
3302 Break if result would be negative. */
3303 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3306 /* Try to wait that long--but we might wake up sooner. */
3307 select (0, NULL
, NULL
, NULL
, &timeout
);
3316 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3319 /* Make audible bell. */
3324 struct frame
*f
= SELECTED_FRAME ();
3326 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3334 XFlush (FRAME_MAC_DISPLAY (f
));
3341 /* Specify how many text lines, from the top of the window,
3342 should be affected by insert-lines and delete-lines operations.
3343 This, and those operations, are used only within an update
3344 that is bounded by calls to x_update_begin and x_update_end. */
3347 XTset_terminal_window (n
)
3350 /* This function intentionally left blank. */
3355 /***********************************************************************
3357 ***********************************************************************/
3359 /* Perform an insert-lines or delete-lines operation, inserting N
3360 lines or deleting -N lines at vertical position VPOS. */
3363 x_ins_del_lines (vpos
, n
)
3370 /* Scroll part of the display as described by RUN. */
3373 x_scroll_run (w
, run
)
3377 struct frame
*f
= XFRAME (w
->frame
);
3378 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3380 /* Get frame-relative bounding box of the text display area of W,
3381 without mode lines. Include in this box the left and right
3383 window_box (w
, -1, &x
, &y
, &width
, &height
);
3385 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3386 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3387 bottom_y
= y
+ height
;
3391 /* Scrolling up. Make sure we don't copy part of the mode
3392 line at the bottom. */
3393 if (from_y
+ run
->height
> bottom_y
)
3394 height
= bottom_y
- from_y
;
3396 height
= run
->height
;
3400 /* Scolling down. Make sure we don't copy over the mode line.
3402 if (to_y
+ run
->height
> bottom_y
)
3403 height
= bottom_y
- to_y
;
3405 height
= run
->height
;
3410 /* Cursor off. Will be switched on again in x_update_window_end. */
3414 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3415 f
->output_data
.mac
->normal_gc
,
3425 /***********************************************************************
3427 ***********************************************************************/
3434 x_update_cursor (f
, 1);
3438 frame_unhighlight (f
)
3441 x_update_cursor (f
, 1);
3444 /* The focus has changed. Update the frames as necessary to reflect
3445 the new situation. Note that we can't change the selected frame
3446 here, because the Lisp code we are interrupting might become confused.
3447 Each event gets marked with the frame in which it occurred, so the
3448 Lisp code can tell when the switch took place by examining the events. */
3451 x_new_focus_frame (dpyinfo
, frame
)
3452 struct x_display_info
*dpyinfo
;
3453 struct frame
*frame
;
3455 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3457 if (frame
!= dpyinfo
->x_focus_frame
)
3459 /* Set this before calling other routines, so that they see
3460 the correct value of x_focus_frame. */
3461 dpyinfo
->x_focus_frame
= frame
;
3463 if (old_focus
&& old_focus
->auto_lower
)
3464 x_lower_frame (old_focus
);
3467 selected_frame
= frame
;
3468 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3470 Fselect_window (selected_frame
->selected_window
, Qnil
);
3471 choose_minibuf_frame ();
3474 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3475 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3477 pending_autoraise_frame
= 0;
3480 x_frame_rehighlight (dpyinfo
);
3483 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3486 x_mouse_leave (dpyinfo
)
3487 struct x_display_info
*dpyinfo
;
3489 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3492 /* The focus has changed, or we have redirected a frame's focus to
3493 another frame (this happens when a frame uses a surrogate
3494 mini-buffer frame). Shift the highlight as appropriate.
3496 The FRAME argument doesn't necessarily have anything to do with which
3497 frame is being highlighted or un-highlighted; we only use it to find
3498 the appropriate X display info. */
3501 XTframe_rehighlight (frame
)
3502 struct frame
*frame
;
3504 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3508 x_frame_rehighlight (dpyinfo
)
3509 struct x_display_info
*dpyinfo
;
3511 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3513 if (dpyinfo
->x_focus_frame
)
3515 dpyinfo
->x_highlight_frame
3516 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3517 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3518 : dpyinfo
->x_focus_frame
);
3519 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3521 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3522 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3526 dpyinfo
->x_highlight_frame
= 0;
3528 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3531 frame_unhighlight (old_highlight
);
3532 if (dpyinfo
->x_highlight_frame
)
3533 frame_highlight (dpyinfo
->x_highlight_frame
);
3539 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3541 #if 0 /* MAC_TODO */
3542 /* Initialize mode_switch_bit and modifier_meaning. */
3544 x_find_modifier_meanings (dpyinfo
)
3545 struct x_display_info
*dpyinfo
;
3547 int min_code
, max_code
;
3550 XModifierKeymap
*mods
;
3552 dpyinfo
->meta_mod_mask
= 0;
3553 dpyinfo
->shift_lock_mask
= 0;
3554 dpyinfo
->alt_mod_mask
= 0;
3555 dpyinfo
->super_mod_mask
= 0;
3556 dpyinfo
->hyper_mod_mask
= 0;
3559 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3561 min_code
= dpyinfo
->display
->min_keycode
;
3562 max_code
= dpyinfo
->display
->max_keycode
;
3565 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3566 min_code
, max_code
- min_code
+ 1,
3568 mods
= XGetModifierMapping (dpyinfo
->display
);
3570 /* Scan the modifier table to see which modifier bits the Meta and
3571 Alt keysyms are on. */
3573 int row
, col
; /* The row and column in the modifier table. */
3575 for (row
= 3; row
< 8; row
++)
3576 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3579 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3581 /* Zeroes are used for filler. Skip them. */
3585 /* Are any of this keycode's keysyms a meta key? */
3589 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3591 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3597 dpyinfo
->meta_mod_mask
|= (1 << row
);
3602 dpyinfo
->alt_mod_mask
|= (1 << row
);
3607 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3612 dpyinfo
->super_mod_mask
|= (1 << row
);
3616 /* Ignore this if it's not on the lock modifier. */
3617 if ((1 << row
) == LockMask
)
3618 dpyinfo
->shift_lock_mask
= LockMask
;
3626 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3627 if (! dpyinfo
->meta_mod_mask
)
3629 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3630 dpyinfo
->alt_mod_mask
= 0;
3633 /* If some keys are both alt and meta,
3634 make them just meta, not alt. */
3635 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3637 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3640 XFree ((char *) syms
);
3641 XFreeModifiermap (mods
);
3644 #endif /* MAC_TODO */
3646 /* Convert between the modifier bits X uses and the modifier bits
3650 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3651 struct x_display_info
*dpyinfo
;
3652 unsigned short state
;
3654 return (((state
& shiftKey
) ? shift_modifier
: 0)
3655 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3656 | ((state
& cmdKey
) ? meta_modifier
: 0)
3657 | ((state
& optionKey
) ? alt_modifier
: 0));
3660 #if 0 /* MAC_TODO */
3661 static unsigned short
3662 x_emacs_to_x_modifiers (dpyinfo
, state
)
3663 struct x_display_info
*dpyinfo
;
3666 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3667 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3668 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3669 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3670 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3671 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3673 #endif /* MAC_TODO */
3675 /* Convert a keysym to its name. */
3678 x_get_keysym_name (keysym
)
3685 value
= XKeysymToString (keysym
);
3696 /* Mouse clicks and mouse movement. Rah. */
3698 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3700 If the event is a button press, then note that we have grabbed
3704 construct_mouse_click (result
, event
, f
)
3705 struct input_event
*result
;
3711 result
->kind
= MOUSE_CLICK_EVENT
;
3712 result
->code
= 0; /* only one mouse button */
3713 result
->timestamp
= event
->when
;
3714 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3716 mouseLoc
= event
->where
;
3718 #if TARGET_API_MAC_CARBON
3719 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
3721 SetPort (FRAME_MAC_WINDOW (f
));
3724 GlobalToLocal (&mouseLoc
);
3725 XSETINT (result
->x
, mouseLoc
.h
);
3726 XSETINT (result
->y
, mouseLoc
.v
);
3728 XSETFRAME (result
->frame_or_window
, f
);
3735 /* Function to report a mouse movement to the mainstream Emacs code.
3736 The input handler calls this.
3738 We have received a mouse movement event, which is given in *event.
3739 If the mouse is over a different glyph than it was last time, tell
3740 the mainstream emacs code by setting mouse_moved. If not, ask for
3741 another motion event, so we can check again the next time it moves. */
3743 static Point last_mouse_motion_position
;
3744 static Lisp_Object last_mouse_motion_frame
;
3747 note_mouse_movement (frame
, pos
)
3751 #if TARGET_API_MAC_CARBON
3755 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3756 last_mouse_motion_position
= *pos
;
3757 XSETFRAME (last_mouse_motion_frame
, frame
);
3759 #if TARGET_API_MAC_CARBON
3760 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3762 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3765 frame
->mouse_moved
= 1;
3766 last_mouse_scroll_bar
= Qnil
;
3767 note_mouse_highlight (frame
, -1, -1);
3769 /* Has the mouse moved off the glyph it was on at the last sighting? */
3770 else if (pos
->h
< last_mouse_glyph
.left
3771 || pos
->h
>= last_mouse_glyph
.right
3772 || pos
->v
< last_mouse_glyph
.top
3773 || pos
->v
>= last_mouse_glyph
.bottom
)
3775 frame
->mouse_moved
= 1;
3776 last_mouse_scroll_bar
= Qnil
;
3777 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3781 /* This is used for debugging, to turn off note_mouse_highlight. */
3783 int disable_mouse_highlight
;
3787 /************************************************************************
3789 ************************************************************************/
3791 static struct scroll_bar
*x_window_to_scroll_bar ();
3792 static void x_scroll_bar_report_motion ();
3793 static void x_check_fullscreen
P_ ((struct frame
*));
3794 static void x_check_fullscreen_move
P_ ((struct frame
*));
3795 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3798 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3801 redo_mouse_highlight ()
3803 if (!NILP (last_mouse_motion_frame
)
3804 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3805 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3806 last_mouse_motion_position
.h
,
3807 last_mouse_motion_position
.v
);
3811 /* Try to determine frame pixel position and size of the glyph under
3812 frame pixel coordinates X/Y on frame F . Return the position and
3813 size in *RECT. Value is non-zero if we could compute these
3817 glyph_rect (f
, x
, y
, rect
)
3824 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3828 struct window
*w
= XWINDOW (window
);
3829 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3830 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3832 for (; r
< end
&& r
->enabled_p
; ++r
)
3833 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3835 /* Found the row at y. */
3836 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3837 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3840 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3841 rect
->bottom
= rect
->top
+ r
->height
;
3845 /* x is to the left of the first glyph in the row. */
3846 /* Shouldn't this be a pixel value?
3847 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3849 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3850 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3854 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3855 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3857 /* x is on a glyph. */
3858 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3859 rect
->right
= rect
->left
+ g
->pixel_width
;
3863 /* x is to the right of the last glyph in the row. */
3864 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3865 /* Shouldn't this be a pixel value?
3866 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3868 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3873 /* The y is not on any row. */
3877 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3879 /* Record the position of the mouse in last_mouse_glyph. */
3881 remember_mouse_glyph (f1
, gx
, gy
)
3885 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3887 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3888 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3890 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3891 round down even for negative values. */
3897 /* This was the original code from XTmouse_position, but it seems
3898 to give the position of the glyph diagonally next to the one
3899 the mouse is over. */
3900 gx
= (gx
+ width
- 1) / width
* width
;
3901 gy
= (gy
+ height
- 1) / height
* height
;
3903 gx
= gx
/ width
* width
;
3904 gy
= gy
/ height
* height
;
3907 last_mouse_glyph
.left
= gx
;
3908 last_mouse_glyph
.top
= gy
;
3909 last_mouse_glyph
.right
= gx
+ width
;
3910 last_mouse_glyph
.bottom
= gy
+ height
;
3915 /* Return the current position of the mouse.
3916 *fp should be a frame which indicates which display to ask about.
3918 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3919 and *part to the frame, window, and scroll bar part that the mouse
3920 is over. Set *x and *y to the portion and whole of the mouse's
3921 position on the scroll bar.
3923 If the mouse movement started elsewhere, set *fp to the frame the
3924 mouse is on, *bar_window to nil, and *x and *y to the character cell
3927 Set *time to the server time-stamp for the time at which the mouse
3928 was at this position.
3930 Don't store anything if we don't have a valid set of values to report.
3932 This clears the mouse_moved flag, so we can wait for the next mouse
3936 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3939 Lisp_Object
*bar_window
;
3940 enum scroll_bar_part
*part
;
3942 unsigned long *time
;
3945 int ignore1
, ignore2
;
3946 WindowPtr wp
= FrontWindow ();
3948 Lisp_Object frame
, tail
;
3950 if (is_emacs_window(wp
))
3951 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
3955 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3956 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3959 /* Clear the mouse-moved flag for every frame on this display. */
3960 FOR_EACH_FRAME (tail
, frame
)
3961 XFRAME (frame
)->mouse_moved
= 0;
3963 last_mouse_scroll_bar
= Qnil
;
3965 #if TARGET_API_MAC_CARBON
3966 SetPort (GetWindowPort (wp
));
3971 GetMouse (&mouse_pos
);
3973 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3974 &last_mouse_glyph
, insist
);
3977 *part
= scroll_bar_handle
;
3979 XSETINT (*x
, mouse_pos
.h
);
3980 XSETINT (*y
, mouse_pos
.v
);
3981 *time
= last_mouse_movement_time
;
3988 /***********************************************************************
3990 ***********************************************************************/
3992 /* Handle mouse button event on the tool-bar of frame F, at
3993 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3997 mac_handle_tool_bar_click (f
, button_event
)
3999 EventRecord
*button_event
;
4001 int x
= button_event
->where
.h
;
4002 int y
= button_event
->where
.v
;
4004 if (button_event
->what
== mouseDown
)
4005 handle_tool_bar_click (f
, x
, y
, 1, 0);
4007 handle_tool_bar_click (f
, x
, y
, 0,
4008 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
4009 button_event
->modifiers
));
4013 /************************************************************************
4014 Scroll bars, general
4015 ************************************************************************/
4017 /* Create a scroll bar and return the scroll bar vector for it. W is
4018 the Emacs window on which to create the scroll bar. TOP, LEFT,
4019 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4022 static struct scroll_bar
*
4023 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4025 int top
, left
, width
, height
, disp_top
, disp_height
;
4027 struct frame
*f
= XFRAME (w
->frame
);
4028 struct scroll_bar
*bar
4029 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4037 r
.right
= left
+ width
;
4038 r
.bottom
= disp_top
+ disp_height
;
4040 #ifdef TARGET_API_MAC_CARBON
4041 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
4042 kControlScrollBarProc
, 0L);
4044 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
4047 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4048 SetControlReference (ch
, (long) bar
);
4050 XSETWINDOW (bar
->window
, w
);
4051 XSETINT (bar
->top
, top
);
4052 XSETINT (bar
->left
, left
);
4053 XSETINT (bar
->width
, width
);
4054 XSETINT (bar
->height
, height
);
4055 XSETINT (bar
->start
, 0);
4056 XSETINT (bar
->end
, 0);
4057 bar
->dragging
= Qnil
;
4059 /* Add bar to its frame's list of scroll bars. */
4060 bar
->next
= FRAME_SCROLL_BARS (f
);
4062 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4063 if (!NILP (bar
->next
))
4064 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4071 /* Draw BAR's handle in the proper position.
4073 If the handle is already drawn from START to END, don't bother
4074 redrawing it, unless REBUILD is non-zero; in that case, always
4075 redraw it. (REBUILD is handy for drawing the handle after expose
4078 Normally, we want to constrain the start and end of the handle to
4079 fit inside its rectangle, but if the user is dragging the scroll
4080 bar handle, we want to let them drag it down all the way, so that
4081 the bar's top is as far down as it goes; otherwise, there's no way
4082 to move to the very end of the buffer. */
4085 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4086 struct scroll_bar
*bar
;
4090 int dragging
= ! NILP (bar
->dragging
);
4091 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4092 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4093 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4094 int length
= end
- start
;
4096 /* If the display is already accurate, do nothing. */
4098 && start
== XINT (bar
->start
)
4099 && end
== XINT (bar
->end
))
4104 /* Make sure the values are reasonable, and try to preserve the
4105 distance between start and end. */
4108 else if (start
> top_range
)
4110 end
= start
+ length
;
4114 else if (end
> top_range
&& ! dragging
)
4117 /* Store the adjusted setting in the scroll bar. */
4118 XSETINT (bar
->start
, start
);
4119 XSETINT (bar
->end
, end
);
4121 /* Clip the end position, just for display. */
4122 if (end
> top_range
)
4125 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4126 top positions, to make sure the handle is always at least that
4127 many pixels tall. */
4128 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4130 SetControlMinimum (ch
, 0);
4131 /* Don't inadvertently activate deactivated scroll bars */
4132 if (GetControlMaximum (ch
) != -1)
4133 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4135 SetControlValue (ch
, start
);
4136 #if TARGET_API_MAC_CARBON
4137 SetControlViewSize (ch
, end
- start
);
4144 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4148 x_scroll_bar_remove (bar
)
4149 struct scroll_bar
*bar
;
4151 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4155 /* Destroy the Mac scroll bar control */
4156 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4158 /* Disassociate this scroll bar from its window. */
4159 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4164 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4165 that we are displaying PORTION characters out of a total of WHOLE
4166 characters, starting at POSITION. If WINDOW has no scroll bar,
4169 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4171 int portion
, whole
, position
;
4173 struct frame
*f
= XFRAME (w
->frame
);
4174 struct scroll_bar
*bar
;
4175 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4176 int window_y
, window_height
;
4178 /* Get window dimensions. */
4179 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4184 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4186 height
= window_height
;
4188 /* Compute the left edge of the scroll bar area. */
4189 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4191 /* Compute the width of the scroll bar which might be less than
4192 the width of the area reserved for the scroll bar. */
4193 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4194 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4198 /* Compute the left edge of the scroll bar. */
4199 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4200 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
4202 sb_left
= left
+ (width
- sb_width
) / 2;
4204 /* Adjustments according to Inside Macintosh to make it look nice */
4206 disp_height
= height
;
4212 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4218 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4221 /* Does the scroll bar exist yet? */
4222 if (NILP (w
->vertical_scroll_bar
))
4225 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4226 left
, top
, width
, height
, 0);
4228 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4230 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4234 /* It may just need to be moved and resized. */
4237 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4238 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4242 /* If already correctly positioned, do nothing. */
4243 if (XINT (bar
->left
) == sb_left
4244 && XINT (bar
->top
) == top
4245 && XINT (bar
->width
) == sb_width
4246 && XINT (bar
->height
) == height
)
4250 /* Clear areas not covered by the scroll bar because it's not as
4251 wide as the area reserved for it . This makes sure a
4252 previous mode line display is cleared after C-x 2 C-x 1, for
4254 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4255 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4256 left
, top
, area_width
, height
, 0);
4259 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4260 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4261 sb_left
- 1, top
, 1, height
, 0);
4265 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4266 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4270 /* Remember new settings. */
4271 XSETINT (bar
->left
, sb_left
);
4272 XSETINT (bar
->top
, top
);
4273 XSETINT (bar
->width
, sb_width
);
4274 XSETINT (bar
->height
, height
);
4280 /* Set the scroll bar's current state, unless we're currently being
4282 if (NILP (bar
->dragging
))
4284 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4287 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4290 int start
= ((double) position
* top_range
) / whole
;
4291 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4292 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4298 /* The following three hooks are used when we're doing a thorough
4299 redisplay of the frame. We don't explicitly know which scroll bars
4300 are going to be deleted, because keeping track of when windows go
4301 away is a real pain - "Can you say set-window-configuration, boys
4302 and girls?" Instead, we just assert at the beginning of redisplay
4303 that *all* scroll bars are to be removed, and then save a scroll bar
4304 from the fiery pit when we actually redisplay its window. */
4306 /* Arrange for all scroll bars on FRAME to be removed at the next call
4307 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4308 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4311 XTcondemn_scroll_bars (frame
)
4314 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4315 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4318 bar
= FRAME_SCROLL_BARS (frame
);
4319 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4320 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4321 XSCROLL_BAR (bar
)->prev
= Qnil
;
4322 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4323 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4324 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4329 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4330 Note that WINDOW isn't necessarily condemned at all. */
4333 XTredeem_scroll_bar (window
)
4334 struct window
*window
;
4336 struct scroll_bar
*bar
;
4338 /* We can't redeem this window's scroll bar if it doesn't have one. */
4339 if (NILP (window
->vertical_scroll_bar
))
4342 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4344 /* Unlink it from the condemned list. */
4346 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4348 if (NILP (bar
->prev
))
4350 /* If the prev pointer is nil, it must be the first in one of
4352 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4353 /* It's not condemned. Everything's fine. */
4355 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4356 window
->vertical_scroll_bar
))
4357 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4359 /* If its prev pointer is nil, it must be at the front of
4360 one or the other! */
4364 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4366 if (! NILP (bar
->next
))
4367 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4369 bar
->next
= FRAME_SCROLL_BARS (f
);
4371 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4372 if (! NILP (bar
->next
))
4373 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4377 /* Remove all scroll bars on FRAME that haven't been saved since the
4378 last call to `*condemn_scroll_bars_hook'. */
4381 XTjudge_scroll_bars (f
)
4384 Lisp_Object bar
, next
;
4386 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4388 /* Clear out the condemned list now so we won't try to process any
4389 more events on the hapless scroll bars. */
4390 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4392 for (; ! NILP (bar
); bar
= next
)
4394 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4396 x_scroll_bar_remove (b
);
4399 b
->next
= b
->prev
= Qnil
;
4402 /* Now there should be no references to the condemned scroll bars,
4403 and they should get garbage-collected. */
4408 activate_scroll_bars (frame
)
4414 bar
= FRAME_SCROLL_BARS (frame
);
4415 while (! NILP (bar
))
4417 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4418 #ifdef TARGET_API_MAC_CARBON
4419 ActivateControl (ch
);
4421 SetControlMaximum (ch
,
4422 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4423 XINT (XSCROLL_BAR (bar
)
4426 bar
= XSCROLL_BAR (bar
)->next
;
4432 deactivate_scroll_bars (frame
)
4438 bar
= FRAME_SCROLL_BARS (frame
);
4439 while (! NILP (bar
))
4441 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4442 #ifdef TARGET_API_MAC_CARBON
4443 DeactivateControl (ch
);
4445 SetControlMaximum (ch
, XINT (-1));
4447 bar
= XSCROLL_BAR (bar
)->next
;
4451 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4452 is set to something other than NO_EVENT, it is enqueued.
4454 This may be called from a signal handler, so we have to ignore GC
4458 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4459 struct scroll_bar
*bar
;
4462 struct input_event
*bufp
;
4464 if (! GC_WINDOWP (bar
->window
))
4467 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4468 bufp
->frame_or_window
= bar
->window
;
4471 bar
->dragging
= Qnil
;
4475 case kControlUpButtonPart
:
4476 bufp
->part
= scroll_bar_up_arrow
;
4478 case kControlDownButtonPart
:
4479 bufp
->part
= scroll_bar_down_arrow
;
4481 case kControlPageUpPart
:
4482 bufp
->part
= scroll_bar_above_handle
;
4484 case kControlPageDownPart
:
4485 bufp
->part
= scroll_bar_below_handle
;
4487 #ifdef TARGET_API_MAC_CARBON
4490 case kControlIndicatorPart
:
4492 if (er
->what
== mouseDown
)
4493 bar
->dragging
= make_number (0);
4494 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4495 bufp
->part
= scroll_bar_handle
;
4501 /* Handle some mouse motion while someone is dragging the scroll bar.
4503 This may be called from a signal handler, so we have to ignore GC
4507 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4508 struct scroll_bar
*bar
;
4512 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4514 last_mouse_movement_time
= t
;
4517 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4519 /* If we're dragging the bar, display it. */
4520 if (! GC_NILP (bar
->dragging
))
4522 /* Where should the handle be now? */
4523 int new_start
= y_pos
- 24;
4525 if (new_start
!= XINT (bar
->start
))
4527 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4529 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4535 /* Return information to the user about the current position of the
4536 mouse on the scroll bar. */
4539 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4541 Lisp_Object
*bar_window
;
4542 enum scroll_bar_part
*part
;
4544 unsigned long *time
;
4546 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4547 WindowPtr wp
= FrontWindow ();
4549 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
4550 int win_y
, top_range
;
4552 #if TARGET_API_MAC_CARBON
4553 SetPort (GetWindowPort (wp
));
4558 GetMouse (&mouse_pos
);
4560 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4561 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4563 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4567 if (! NILP (bar
->dragging
))
4568 win_y
-= XINT (bar
->dragging
);
4572 if (win_y
> top_range
)
4576 *bar_window
= bar
->window
;
4578 if (! NILP (bar
->dragging
))
4579 *part
= scroll_bar_handle
;
4580 else if (win_y
< XINT (bar
->start
))
4581 *part
= scroll_bar_above_handle
;
4582 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4583 *part
= scroll_bar_handle
;
4585 *part
= scroll_bar_below_handle
;
4587 XSETINT (*x
, win_y
);
4588 XSETINT (*y
, top_range
);
4591 last_mouse_scroll_bar
= Qnil
;
4593 *time
= last_mouse_movement_time
;
4596 /***********************************************************************
4598 ***********************************************************************/
4600 /* Set clipping for output in glyph row ROW. W is the window in which
4601 we operate. GC is the graphics context to set clipping in.
4603 ROW may be a text row or, e.g., a mode line. Text rows must be
4604 clipped to the interior of the window dedicated to text display,
4605 mode lines must be clipped to the whole window. */
4608 x_clip_to_row (w
, row
, gc
)
4610 struct glyph_row
*row
;
4613 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4615 int window_y
, window_width
;
4617 window_box (w
, -1, 0, &window_y
, &window_width
, 0);
4619 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4620 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4621 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4622 clip_rect
.right
= clip_rect
.left
+ window_width
;
4623 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4625 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4629 /* Draw a hollow box cursor on window W in glyph row ROW. */
4632 x_draw_hollow_cursor (w
, row
)
4634 struct glyph_row
*row
;
4636 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4637 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4638 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4641 struct glyph
*cursor_glyph
;
4644 /* Get the glyph the cursor is on. If we can't tell because
4645 the current matrix is invalid or such, give up. */
4646 cursor_glyph
= get_phys_cursor_glyph (w
);
4647 if (cursor_glyph
== NULL
)
4650 /* Compute the width of the rectangle to draw. If on a stretch
4651 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4652 rectangle as wide as the glyph, but use a canonical character
4654 wd
= cursor_glyph
->pixel_width
- 1;
4655 if (cursor_glyph
->type
== STRETCH_GLYPH
4656 && !x_stretch_cursor_p
)
4657 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4658 w
->phys_cursor_width
= wd
;
4660 /* Compute frame-relative coordinates from window-relative
4662 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4663 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4665 /* Compute the proper height and ascent of the rectangle, based
4666 on the actual glyph. Using the full height of the row looks
4667 bad when there are tall images on that row. */
4668 h
= max (FRAME_LINE_HEIGHT (f
), cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4669 if (h
< row
->height
)
4670 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4673 /* The foreground of cursor_gc is typically the same as the normal
4674 background color, which can cause the cursor box to be invisible. */
4675 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4676 if (dpyinfo
->scratch_cursor_gc
)
4677 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4679 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4680 GCForeground
, &xgcv
);
4681 gc
= dpyinfo
->scratch_cursor_gc
;
4683 /* Set clipping, draw the rectangle, and reset clipping again. */
4684 x_clip_to_row (w
, row
, gc
);
4685 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4686 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4690 /* Draw a bar cursor on window W in glyph row ROW.
4692 Implementation note: One would like to draw a bar cursor with an
4693 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4694 Unfortunately, I didn't find a font yet that has this property set.
4698 x_draw_bar_cursor (w
, row
, width
, kind
)
4700 struct glyph_row
*row
;
4702 enum text_cursor_kinds kind
;
4704 struct frame
*f
= XFRAME (w
->frame
);
4705 struct glyph
*cursor_glyph
;
4707 /* If cursor is out of bounds, don't draw garbage. This can happen
4708 in mini-buffer windows when switching between echo area glyphs
4710 cursor_glyph
= get_phys_cursor_glyph (w
);
4711 if (cursor_glyph
== NULL
)
4714 /* If on an image, draw like a normal cursor. That's usually better
4715 visible than drawing a bar, esp. if the image is large so that
4716 the bar might not be in the window. */
4717 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4719 struct glyph_row
*row
;
4720 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4721 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4725 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4726 Window window
= FRAME_MAC_WINDOW (f
);
4727 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4728 unsigned long mask
= GCForeground
| GCBackground
;
4729 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4732 /* If the glyph's background equals the color we normally draw
4733 the bar cursor in, the bar cursor in its normal color is
4734 invisible. Use the glyph's foreground color instead in this
4735 case, on the assumption that the glyph's colors are chosen so
4736 that the glyph is legible. */
4737 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4738 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4740 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4743 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4746 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4747 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4751 width
= FRAME_CURSOR_WIDTH (f
);
4752 width
= min (cursor_glyph
->pixel_width
, width
);
4754 w
->phys_cursor_width
= width
;
4755 x_clip_to_row (w
, row
, gc
);
4757 if (kind
== BAR_CURSOR
)
4758 XFillRectangle (dpy
, window
, gc
,
4759 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4760 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4761 width
, row
->height
);
4763 XFillRectangle (dpy
, window
, gc
,
4764 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4765 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4766 row
->height
- width
),
4767 cursor_glyph
->pixel_width
,
4770 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4775 /* RIF: Define cursor CURSOR on frame F. */
4778 mac_define_frame_cursor (f
, cursor
)
4786 /* RIF: Clear area on frame F. */
4789 mac_clear_frame_area (f
, x
, y
, width
, height
)
4791 int x
, y
, width
, height
;
4793 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4794 x
, y
, width
, height
, 0);
4798 /* RIF: Draw cursor on window W. */
4801 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4803 struct glyph_row
*glyph_row
;
4805 int cursor_type
, cursor_width
;
4810 w
->phys_cursor_type
= cursor_type
;
4811 w
->phys_cursor_on_p
= 1;
4813 if (glyph_row
->exact_window_width_line_p
4814 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4816 glyph_row
->cursor_in_fringe_p
= 1;
4817 draw_fringe_bitmap (w
, glyph_row
, 0);
4820 switch (cursor_type
)
4822 case HOLLOW_BOX_CURSOR
:
4823 x_draw_hollow_cursor (w
, glyph_row
);
4826 case FILLED_BOX_CURSOR
:
4827 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4831 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4835 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4839 w
->phys_cursor_width
= 0;
4851 #if 0 /* MAC_TODO: no icon support yet. */
4853 x_bitmap_icon (f
, icon
)
4859 if (FRAME_W32_WINDOW (f
) == 0)
4863 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4864 else if (STRINGP (icon
))
4865 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4866 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4867 else if (SYMBOLP (icon
))
4871 if (EQ (icon
, intern ("application")))
4872 name
= (LPCTSTR
) IDI_APPLICATION
;
4873 else if (EQ (icon
, intern ("hand")))
4874 name
= (LPCTSTR
) IDI_HAND
;
4875 else if (EQ (icon
, intern ("question")))
4876 name
= (LPCTSTR
) IDI_QUESTION
;
4877 else if (EQ (icon
, intern ("exclamation")))
4878 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4879 else if (EQ (icon
, intern ("asterisk")))
4880 name
= (LPCTSTR
) IDI_ASTERISK
;
4881 else if (EQ (icon
, intern ("winlogo")))
4882 name
= (LPCTSTR
) IDI_WINLOGO
;
4886 hicon
= LoadIcon (NULL
, name
);
4894 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4899 #endif /* MAC_TODO */
4901 /************************************************************************
4903 ************************************************************************/
4905 /* Display Error Handling functions not used on W32. Listing them here
4906 helps diff stay in step when comparing w32term.c with xterm.c.
4908 x_error_catcher (display, error)
4909 x_catch_errors (dpy)
4910 x_catch_errors_unwind (old_val)
4911 x_check_errors (dpy, format)
4912 x_had_errors_p (dpy)
4913 x_clear_errors (dpy)
4914 x_uncatch_errors (dpy, count)
4916 x_connection_signal (signalnum)
4917 x_connection_closed (dpy, error_message)
4918 x_error_quitter (display, error)
4919 x_error_handler (display, error)
4920 x_io_error_quitter (display)
4925 /* Changing the font of the frame. */
4927 /* Give frame F the font named FONTNAME as its default font, and
4928 return the full name of that font. FONTNAME may be a wildcard
4929 pattern; in that case, we choose some font that fits the pattern.
4930 The return value shows which font we chose. */
4933 x_new_font (f
, fontname
)
4935 register char *fontname
;
4937 struct font_info
*fontp
4938 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4943 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4944 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4945 FRAME_FONTSET (f
) = -1;
4947 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4948 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4950 compute_fringe_widths (f
, 1);
4952 /* Compute the scroll bar width in character columns. */
4953 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4955 int wid
= FRAME_COLUMN_WIDTH (f
);
4956 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4957 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4961 int wid
= FRAME_COLUMN_WIDTH (f
);
4962 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4965 /* Now make the frame display the given font. */
4966 if (FRAME_MAC_WINDOW (f
) != 0)
4968 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4970 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4972 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4975 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4976 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4979 return build_string (fontp
->full_name
);
4982 /* Give frame F the fontset named FONTSETNAME as its default font, and
4983 return the full name of that fontset. FONTSETNAME may be a wildcard
4984 pattern; in that case, we choose some fontset that fits the pattern.
4985 The return value shows which fontset we chose. */
4988 x_new_fontset (f
, fontsetname
)
4992 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
4998 if (FRAME_FONTSET (f
) == fontset
)
4999 /* This fontset is already set in frame F. There's nothing more
5001 return fontset_name (fontset
);
5003 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5005 if (!STRINGP (result
))
5006 /* Can't load ASCII font. */
5009 /* Since x_new_font doesn't update any fontset information, do it now. */
5010 FRAME_FONTSET(f
) = fontset
;
5012 return build_string (fontsetname
);
5016 /***********************************************************************
5017 TODO: W32 Input Methods
5018 ***********************************************************************/
5019 /* Listing missing functions from xterm.c helps diff stay in step.
5021 xim_destroy_callback (xim, client_data, call_data)
5022 xim_open_dpy (dpyinfo, resource_name)
5024 xim_instantiate_callback (display, client_data, call_data)
5025 xim_initialize (dpyinfo, resource_name)
5026 xim_close_dpy (dpyinfo)
5031 /* Calculate the absolute position in frame F
5032 from its current recorded position values and gravity. */
5035 x_calc_absolute_position (f
)
5039 int flags
= f
->size_hint_flags
;
5043 /* Find the position of the outside upper-left corner of
5044 the inner window, with respect to the outer window. */
5045 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
5048 GetPort (&savePort
);
5050 #if TARGET_API_MAC_CARBON
5051 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
5053 SetPort (FRAME_MAC_WINDOW (f
));
5056 #if TARGET_API_MAC_CARBON
5060 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
5061 SetPt(&pt
, r
.left
, r
.top
);
5063 #else /* not TARGET_API_MAC_CARBON */
5064 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
5065 #endif /* not TARGET_API_MAC_CARBON */
5066 LocalToGlobal (&pt
);
5070 /* Treat negative positions as relative to the leftmost bottommost
5071 position that fits on the screen. */
5072 if (flags
& XNegative
)
5073 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5074 - 2 * f
->border_width
- pt
.h
5075 - FRAME_PIXEL_WIDTH (f
)
5077 /* NTEMACS_TODO: Subtract menubar height? */
5078 if (flags
& YNegative
)
5079 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5080 - 2 * f
->border_width
- pt
.v
5081 - FRAME_PIXEL_HEIGHT (f
)
5083 /* The left_pos and top_pos
5084 are now relative to the top and left screen edges,
5085 so the flags should correspond. */
5086 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5089 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5090 to really change the position, and 0 when calling from
5091 x_make_frame_visible (in that case, XOFF and YOFF are the current
5092 position values). It is -1 when calling from x_set_frame_parameters,
5093 which means, do adjust for borders but don't change the gravity. */
5096 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5098 register int xoff
, yoff
;
5101 int modified_top
, modified_left
;
5103 if (change_gravity
> 0)
5107 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5109 f
->size_hint_flags
|= XNegative
;
5111 f
->size_hint_flags
|= YNegative
;
5112 f
->win_gravity
= NorthWestGravity
;
5114 x_calc_absolute_position (f
);
5117 x_wm_set_size_hint (f
, (long) 0, 0);
5119 modified_left
= f
->left_pos
;
5120 modified_top
= f
->top_pos
;
5122 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
5123 modified_top
+ 42, false);
5128 /* Call this to change the size of frame F's x-window.
5129 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5130 for this size change and subsequent size changes.
5131 Otherwise we leave the window gravity unchanged. */
5134 x_set_window_size (f
, change_gravity
, cols
, rows
)
5139 int pixelwidth
, pixelheight
;
5143 check_frame_size (f
, &rows
, &cols
);
5144 f
->scroll_bar_actual_width
5145 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5147 compute_fringe_widths (f
, 0);
5149 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5150 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5152 f
->win_gravity
= NorthWestGravity
;
5153 x_wm_set_size_hint (f
, (long) 0, 0);
5155 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5157 /* Now, strictly speaking, we can't be sure that this is accurate,
5158 but the window manager will get around to dealing with the size
5159 change request eventually, and we'll hear how it went when the
5160 ConfigureNotify event gets here.
5162 We could just not bother storing any of this information here,
5163 and let the ConfigureNotify event set everything up, but that
5164 might be kind of confusing to the Lisp code, since size changes
5165 wouldn't be reported in the frame parameters until some random
5166 point in the future when the ConfigureNotify event arrives.
5168 We pass 1 for DELAY since we can't run Lisp code inside of
5170 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5171 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5172 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5174 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5175 receive in the ConfigureNotify event; if we get what we asked
5176 for, then the event won't cause the screen to become garbaged, so
5177 we have to make sure to do it here. */
5178 SET_FRAME_GARBAGED (f
);
5180 XFlush (FRAME_X_DISPLAY (f
));
5182 /* If cursor was outside the new size, mark it as off. */
5183 mark_window_cursors_off (XWINDOW (f
->root_window
));
5185 /* Clear out any recollection of where the mouse highlighting was,
5186 since it might be in a place that's outside the new frame size.
5187 Actually checking whether it is outside is a pain in the neck,
5188 so don't try--just let the highlighting be done afresh with new size. */
5189 cancel_mouse_face (f
);
5194 /* Mouse warping. */
5196 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5199 x_set_mouse_position (f
, x
, y
)
5205 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5206 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5208 if (pix_x
< 0) pix_x
= 0;
5209 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5211 if (pix_y
< 0) pix_y
= 0;
5212 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5214 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5218 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5222 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5225 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5226 0, 0, 0, 0, pix_x
, pix_y
);
5232 /* focus shifting, raising and lowering. */
5235 x_focus_on_frame (f
)
5238 #if 0 /* This proves to be unpleasant. */
5242 /* I don't think that the ICCCM allows programs to do things like this
5243 without the interaction of the window manager. Whatever you end up
5244 doing with this code, do it to x_unfocus_frame too. */
5245 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5246 RevertToPointerRoot
, CurrentTime
);
5256 /* Raise frame F. */
5261 if (f
->async_visible
)
5262 SelectWindow (FRAME_MAC_WINDOW (f
));
5265 /* Lower frame F. */
5270 if (f
->async_visible
)
5271 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5275 XTframe_raise_lower (f
, raise_flag
)
5285 /* Change of visibility. */
5287 /* This tries to wait until the frame is really visible.
5288 However, if the window manager asks the user where to position
5289 the frame, this will return before the user finishes doing that.
5290 The frame will not actually be visible at that time,
5291 but it will become visible later when the window manager
5292 finishes with it. */
5295 x_make_frame_visible (f
)
5299 int original_top
, original_left
;
5303 if (! FRAME_VISIBLE_P (f
))
5305 /* We test FRAME_GARBAGED_P here to make sure we don't
5306 call x_set_offset a second time
5307 if we get to x_make_frame_visible a second time
5308 before the window gets really visible. */
5309 if (! FRAME_ICONIFIED_P (f
)
5310 && ! f
->output_data
.mac
->asked_for_visible
)
5311 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5313 f
->output_data
.mac
->asked_for_visible
= 1;
5315 ShowWindow (FRAME_MAC_WINDOW (f
));
5318 XFlush (FRAME_MAC_DISPLAY (f
));
5320 #if 0 /* MAC_TODO */
5321 /* Synchronize to ensure Emacs knows the frame is visible
5322 before we do anything else. We do this loop with input not blocked
5323 so that incoming events are handled. */
5328 /* This must come after we set COUNT. */
5331 XSETFRAME (frame
, f
);
5333 /* Wait until the frame is visible. Process X events until a
5334 MapNotify event has been seen, or until we think we won't get a
5335 MapNotify at all.. */
5336 for (count
= input_signal_count
+ 10;
5337 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5339 /* Force processing of queued events. */
5342 /* Machines that do polling rather than SIGIO have been
5343 observed to go into a busy-wait here. So we'll fake an
5344 alarm signal to let the handler know that there's something
5345 to be read. We used to raise a real alarm, but it seems
5346 that the handler isn't always enabled here. This is
5348 if (input_polling_used ())
5350 /* It could be confusing if a real alarm arrives while
5351 processing the fake one. Turn it off and let the
5352 handler reset it. */
5353 extern void poll_for_input_1
P_ ((void));
5354 int old_poll_suppress_count
= poll_suppress_count
;
5355 poll_suppress_count
= 1;
5356 poll_for_input_1 ();
5357 poll_suppress_count
= old_poll_suppress_count
;
5360 /* See if a MapNotify event has been processed. */
5361 FRAME_SAMPLE_VISIBILITY (f
);
5366 #endif /* MAC_TODO */
5369 /* Change from mapped state to withdrawn state. */
5371 /* Make the frame visible (mapped and not iconified). */
5374 x_make_frame_invisible (f
)
5377 /* Don't keep the highlight on an invisible frame. */
5378 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5379 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5383 HideWindow (FRAME_MAC_WINDOW (f
));
5385 /* We can't distinguish this from iconification
5386 just by the event that we get from the server.
5387 So we can't win using the usual strategy of letting
5388 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5389 and synchronize with the server to make sure we agree. */
5391 FRAME_ICONIFIED_P (f
) = 0;
5392 f
->async_visible
= 0;
5393 f
->async_iconified
= 0;
5398 /* Change window state from mapped to iconified. */
5404 /* Don't keep the highlight on an invisible frame. */
5405 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5406 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5409 /* Review: Since window is still visible in dock, still allow updates? */
5410 if (f
->async_iconified
)
5416 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5422 /* Free X resources of frame F. */
5425 x_free_frame_resources (f
)
5428 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5432 DisposeWindow (FRAME_MAC_WINDOW (f
));
5434 free_frame_menubar (f
);
5436 if (FRAME_FACE_CACHE (f
))
5437 free_frame_faces (f
);
5441 xfree (f
->output_data
.mac
);
5442 f
->output_data
.mac
= NULL
;
5444 if (f
== dpyinfo
->x_focus_frame
)
5445 dpyinfo
->x_focus_frame
= 0;
5446 if (f
== dpyinfo
->x_focus_event_frame
)
5447 dpyinfo
->x_focus_event_frame
= 0;
5448 if (f
== dpyinfo
->x_highlight_frame
)
5449 dpyinfo
->x_highlight_frame
= 0;
5451 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5453 dpyinfo
->mouse_face_beg_row
5454 = dpyinfo
->mouse_face_beg_col
= -1;
5455 dpyinfo
->mouse_face_end_row
5456 = dpyinfo
->mouse_face_end_col
= -1;
5457 dpyinfo
->mouse_face_window
= Qnil
;
5458 dpyinfo
->mouse_face_deferred_gc
= 0;
5459 dpyinfo
->mouse_face_mouse_frame
= 0;
5466 /* Destroy the X window of frame F. */
5469 x_destroy_window (f
)
5472 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5474 x_free_frame_resources (f
);
5476 dpyinfo
->reference_count
--;
5480 /* Setting window manager hints. */
5482 /* Set the normal size hints for the window manager, for frame F.
5483 FLAGS is the flags word to use--or 0 meaning preserve the flags
5484 that the window now has.
5485 If USER_POSITION is nonzero, we set the USPosition
5486 flag (this is useful when FLAGS is 0). */
5488 x_wm_set_size_hint (f
, flags
, user_position
)
5493 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5494 XSizeHints size_hints
;
5496 #ifdef USE_X_TOOLKIT
5499 Dimension widget_width
, widget_height
;
5500 Window window
= XtWindow (f
->output_data
.x
->widget
);
5501 #else /* not USE_X_TOOLKIT */
5502 Window window
= FRAME_X_WINDOW (f
);
5503 #endif /* not USE_X_TOOLKIT */
5505 /* Setting PMaxSize caused various problems. */
5506 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5508 size_hints
.x
= f
->left_pos
;
5509 size_hints
.y
= f
->top_pos
;
5511 #ifdef USE_X_TOOLKIT
5512 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5513 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5514 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5515 size_hints
.height
= widget_height
;
5516 size_hints
.width
= widget_width
;
5517 #else /* not USE_X_TOOLKIT */
5518 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5519 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5520 #endif /* not USE_X_TOOLKIT */
5522 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5523 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5524 size_hints
.max_width
5525 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5526 size_hints
.max_height
5527 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5529 /* Calculate the base and minimum sizes.
5531 (When we use the X toolkit, we don't do it here.
5532 Instead we copy the values that the widgets are using, below.) */
5533 #ifndef USE_X_TOOLKIT
5535 int base_width
, base_height
;
5536 int min_rows
= 0, min_cols
= 0;
5538 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5539 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5541 check_frame_size (f
, &min_rows
, &min_cols
);
5543 /* The window manager uses the base width hints to calculate the
5544 current number of rows and columns in the frame while
5545 resizing; min_width and min_height aren't useful for this
5546 purpose, since they might not give the dimensions for a
5547 zero-row, zero-column frame.
5549 We use the base_width and base_height members if we have
5550 them; otherwise, we set the min_width and min_height members
5551 to the size for a zero x zero frame. */
5554 size_hints
.flags
|= PBaseSize
;
5555 size_hints
.base_width
= base_width
;
5556 size_hints
.base_height
= base_height
;
5557 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5558 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5560 size_hints
.min_width
= base_width
;
5561 size_hints
.min_height
= base_height
;
5565 /* If we don't need the old flags, we don't need the old hint at all. */
5568 size_hints
.flags
|= flags
;
5571 #endif /* not USE_X_TOOLKIT */
5574 XSizeHints hints
; /* Sometimes I hate X Windows... */
5575 long supplied_return
;
5579 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5582 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5585 #ifdef USE_X_TOOLKIT
5586 size_hints
.base_height
= hints
.base_height
;
5587 size_hints
.base_width
= hints
.base_width
;
5588 size_hints
.min_height
= hints
.min_height
;
5589 size_hints
.min_width
= hints
.min_width
;
5593 size_hints
.flags
|= flags
;
5598 if (hints
.flags
& PSize
)
5599 size_hints
.flags
|= PSize
;
5600 if (hints
.flags
& PPosition
)
5601 size_hints
.flags
|= PPosition
;
5602 if (hints
.flags
& USPosition
)
5603 size_hints
.flags
|= USPosition
;
5604 if (hints
.flags
& USSize
)
5605 size_hints
.flags
|= USSize
;
5609 #ifndef USE_X_TOOLKIT
5614 size_hints
.win_gravity
= f
->win_gravity
;
5615 size_hints
.flags
|= PWinGravity
;
5619 size_hints
.flags
&= ~ PPosition
;
5620 size_hints
.flags
|= USPosition
;
5622 #endif /* PWinGravity */
5625 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5627 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5629 #endif /* MAC_TODO */
5632 #if 0 /* MAC_TODO: hide application instead of iconify? */
5633 /* Used for IconicState or NormalState */
5636 x_wm_set_window_state (f
, state
)
5640 #ifdef USE_X_TOOLKIT
5643 XtSetArg (al
[0], XtNinitialState
, state
);
5644 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5645 #else /* not USE_X_TOOLKIT */
5646 Window window
= FRAME_X_WINDOW (f
);
5648 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5649 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5651 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5652 #endif /* not USE_X_TOOLKIT */
5656 x_wm_set_icon_pixmap (f
, pixmap_id
)
5662 #ifndef USE_X_TOOLKIT
5663 Window window
= FRAME_X_WINDOW (f
);
5668 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5669 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5673 /* It seems there is no way to turn off use of an icon pixmap.
5674 The following line does it, only if no icon has yet been created,
5675 for some window managers. But with mwm it crashes.
5676 Some people say it should clear the IconPixmapHint bit in this case,
5677 but that doesn't work, and the X consortium said it isn't the
5678 right thing at all. Since there is no way to win,
5679 best to explicitly give up. */
5681 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5687 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5691 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5692 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5695 #else /* not USE_X_TOOLKIT */
5697 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5698 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5700 #endif /* not USE_X_TOOLKIT */
5703 #endif /* MAC_TODO */
5706 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5710 #if 0 /* MAC_TODO: no icons on Mac */
5711 #ifdef USE_X_TOOLKIT
5712 Window window
= XtWindow (f
->output_data
.x
->widget
);
5714 Window window
= FRAME_X_WINDOW (f
);
5717 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5718 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5719 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5721 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5722 #endif /* MAC_TODO */
5726 /***********************************************************************
5728 ***********************************************************************/
5730 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5733 x_get_font_info (f
, font_idx
)
5737 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5740 /* the global font name table */
5741 char **font_name_table
= NULL
;
5742 int font_name_table_size
= 0;
5743 int font_name_count
= 0;
5746 /* compare two strings ignoring case */
5748 stricmp (const char *s
, const char *t
)
5750 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5753 return tolower (*s
) - tolower (*t
);
5756 /* compare two strings ignoring case and handling wildcard */
5758 wildstrieq (char *s1
, char *s2
)
5760 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5763 return stricmp (s1
, s2
) == 0;
5766 /* Assume parameter 1 is fully qualified, no wildcards. */
5768 mac_font_pattern_match (fontname
, pattern
)
5772 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5773 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5776 /* Copy fontname so we can modify it during comparison. */
5777 strcpy (font_name_copy
, fontname
);
5782 /* Turn pattern into a regexp and do a regexp match. */
5783 for (; *pattern
; pattern
++)
5785 if (*pattern
== '?')
5787 else if (*pattern
== '*')
5798 return (fast_c_string_match_ignore_case (build_string (regex
),
5799 font_name_copy
) >= 0);
5802 /* Two font specs are considered to match if their foundry, family,
5803 weight, slant, and charset match. */
5805 mac_font_match (char *mf
, char *xf
)
5807 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5808 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5810 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5811 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5812 return mac_font_pattern_match (mf
, xf
);
5814 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5815 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5816 return mac_font_pattern_match (mf
, xf
);
5818 return (wildstrieq (m_foundry
, x_foundry
)
5819 && wildstrieq (m_family
, x_family
)
5820 && wildstrieq (m_weight
, x_weight
)
5821 && wildstrieq (m_slant
, x_slant
)
5822 && wildstrieq (m_charset
, x_charset
))
5823 || mac_font_pattern_match (mf
, xf
);
5827 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5830 decode_mac_font_name (char *name
, int size
, short scriptcode
)
5832 Lisp_Object coding_system
;
5833 struct coding_system coding
;
5839 coding_system
= Qbig5
;
5842 coding_system
= Qcn_gb
;
5845 coding_system
= Qsjis
;
5848 coding_system
= Qeuc_kr
;
5854 setup_coding_system (coding_system
, &coding
);
5855 coding
.src_multibyte
= 0;
5856 coding
.dst_multibyte
= 1;
5857 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5858 coding
.composing
= COMPOSITION_DISABLED
;
5859 buf
= (char *) alloca (size
);
5861 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5862 bcopy (buf
, name
, coding
.produced
);
5863 name
[coding
.produced
] = '\0';
5868 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5870 char foundry
[32], family
[32], cs
[32];
5871 char xf
[256], *result
, *p
;
5873 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5875 strcpy(foundry
, "Apple");
5876 strcpy(family
, name
);
5881 strcpy(cs
, "big5-0");
5884 strcpy(cs
, "gb2312.1980-0");
5887 strcpy(cs
, "jisx0208.1983-sjis");
5890 /* Each Apple Japanese font is entered into the font table
5891 twice: once as a jisx0208.1983-sjis font and once as a
5892 jisx0201.1976-0 font. The latter can be used to display
5893 the ascii charset and katakana-jisx0201 charset. A
5894 negative script code signals that the name of this latter
5895 font is being built. */
5896 strcpy(cs
, "jisx0201.1976-0");
5899 strcpy(cs
, "ksc5601.1989-0");
5902 strcpy(cs
, "mac-roman");
5907 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5908 foundry
, family
, style
& bold
? "bold" : "medium",
5909 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5911 result
= (char *) xmalloc (strlen (xf
) + 1);
5912 strcpy (result
, xf
);
5913 for (p
= result
; *p
; p
++)
5919 /* Convert an X font spec to the corresponding mac font name, which
5920 can then be passed to GetFNum after conversion to a Pascal string.
5921 For ordinary Mac fonts, this should just be their names, like
5922 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5923 collection contain their charset designation in their names, like
5924 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5925 names are handled accordingly. */
5927 x_font_name_to_mac_font_name (char *xf
, char *mf
)
5929 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
5930 Lisp_Object coding_system
= Qnil
;
5931 struct coding_system coding
;
5935 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5936 foundry
, family
, weight
, slant
, cs
) != 5 &&
5937 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5938 foundry
, family
, weight
, slant
, cs
) != 5)
5941 if (strcmp (cs
, "big5-0") == 0)
5942 coding_system
= Qbig5
;
5943 else if (strcmp (cs
, "gb2312.1980-0") == 0)
5944 coding_system
= Qcn_gb
;
5945 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
5946 || strcmp (cs
, "jisx0201.1976-0") == 0)
5947 coding_system
= Qsjis
;
5948 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
5949 coding_system
= Qeuc_kr
;
5950 else if (strcmp (cs
, "mac-roman") == 0)
5951 strcpy (mf
, family
);
5953 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
5955 if (!NILP (coding_system
))
5957 setup_coding_system (coding_system
, &coding
);
5958 coding
.src_multibyte
= 1;
5959 coding
.dst_multibyte
= 1;
5960 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5961 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
5962 mf
[coding
.produced
] = '\0';
5968 add_font_name_table_entry (char *font_name
)
5970 if (font_name_table_size
== 0)
5972 font_name_table_size
= 16;
5973 font_name_table
= (char **)
5974 xmalloc (font_name_table_size
* sizeof (char *));
5976 else if (font_name_count
+ 1 >= font_name_table_size
)
5978 font_name_table_size
+= 16;
5979 font_name_table
= (char **)
5980 xrealloc (font_name_table
,
5981 font_name_table_size
* sizeof (char *));
5984 font_name_table
[font_name_count
++] = font_name
;
5987 /* Sets up the table font_name_table to contain the list of all fonts
5988 in the system the first time the table is used so that the Resource
5989 Manager need not be accessed every time this information is
5993 init_font_name_table ()
5995 #if TARGET_API_MAC_CARBON
5998 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
6000 FMFontFamilyIterator ffi
;
6001 FMFontFamilyInstanceIterator ffii
;
6004 /* Create a dummy instance iterator here to avoid creating and
6005 destroying it in the loop. */
6006 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6008 /* Create an iterator to enumerate the font families. */
6009 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6012 FMDisposeFontFamilyInstanceIterator (&ffii
);
6016 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6024 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6030 sc
= FontToScript (ff
);
6031 decode_mac_font_name (name
, sizeof (name
), sc
);
6033 /* Point the instance iterator at the current font family. */
6034 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6037 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6040 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6041 contained in Apple Japanese (SJIS) font. */
6045 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6047 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6049 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6051 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6056 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6058 if (sc
== smJapanese
)
6063 else if (sc
== -smJapanese
)
6068 /* Dispose of the iterators. */
6069 FMDisposeFontFamilyIterator (&ffi
);
6070 FMDisposeFontFamilyInstanceIterator (&ffii
);
6074 #endif /* TARGET_API_MAC_CARBON */
6076 SInt16 fontnum
, old_fontnum
;
6077 int num_mac_fonts
= CountResources('FOND');
6079 Handle font_handle
, font_handle_2
;
6080 short id
, scriptcode
;
6083 struct FontAssoc
*fat
;
6084 struct AsscEntry
*assc_entry
;
6086 GetPort (&port
); /* save the current font number used */
6087 #if TARGET_API_MAC_CARBON
6088 old_fontnum
= GetPortTextFont (port
);
6090 old_fontnum
= port
->txFont
;
6093 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6095 font_handle
= GetIndResource ('FOND', i
);
6099 GetResInfo (font_handle
, &id
, &type
, name
);
6100 GetFNum (name
, &fontnum
);
6106 scriptcode
= FontToScript (fontnum
);
6107 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6110 HLock (font_handle
);
6112 if (GetResourceSizeOnDisk (font_handle
)
6113 >= sizeof (struct FamRec
))
6115 fat
= (struct FontAssoc
*) (*font_handle
6116 + sizeof (struct FamRec
));
6118 = (struct AsscEntry
*) (*font_handle
6119 + sizeof (struct FamRec
)
6120 + sizeof (struct FontAssoc
));
6122 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6124 if (font_name_table_size
== 0)
6126 font_name_table_size
= 16;
6127 font_name_table
= (char **)
6128 xmalloc (font_name_table_size
* sizeof (char *));
6130 else if (font_name_count
>= font_name_table_size
)
6132 font_name_table_size
+= 16;
6133 font_name_table
= (char **)
6134 xrealloc (font_name_table
,
6135 font_name_table_size
* sizeof (char *));
6137 font_name_table
[font_name_count
++]
6138 = mac_to_x_fontname (name
,
6139 assc_entry
->fontSize
,
6140 assc_entry
->fontStyle
,
6142 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6143 parts are contained in Apple Japanese (SJIS)
6145 if (smJapanese
== scriptcode
)
6147 font_name_table
[font_name_count
++]
6148 = mac_to_x_fontname (name
,
6149 assc_entry
->fontSize
,
6150 assc_entry
->fontStyle
,
6156 HUnlock (font_handle
);
6157 font_handle_2
= GetNextFOND (font_handle
);
6158 ReleaseResource (font_handle
);
6159 font_handle
= font_handle_2
;
6161 while (ResError () == noErr
&& font_handle
);
6164 TextFont (old_fontnum
);
6165 #if TARGET_API_MAC_CARBON
6167 #endif /* TARGET_API_MAC_CARBON */
6171 enum xlfd_scalable_field_index
6173 XLFD_SCL_PIXEL_SIZE
,
6174 XLFD_SCL_POINT_SIZE
,
6179 static int xlfd_scalable_fields
[] =
6188 mac_do_list_fonts (pattern
, maxnames
)
6193 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6194 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6197 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6199 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6202 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6203 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6204 fonts are scaled according to the specified size. */
6207 field
= xlfd_scalable_fields
;
6215 if ('1' <= *ptr
&& *ptr
<= '9')
6217 *val
= *ptr
++ - '0';
6218 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6219 *val
= *val
* 10 + *ptr
++ - '0';
6226 ptr
= strchr (ptr
, '-');
6229 while (ptr
&& i
< 14);
6231 if (i
== 14 && ptr
== NULL
)
6233 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6235 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6236 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6238 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6240 scl_val
[XLFD_SCL_POINT_SIZE
] =
6241 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6243 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6245 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6246 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6250 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6255 /* Turn pattern into a regexp and do a regexp match. */
6256 for (; *pattern
; pattern
++)
6258 if (*pattern
== '?')
6260 else if (*pattern
== '*')
6266 *ptr
++ = tolower (*pattern
);
6271 pattern_regex
= build_string (regex
);
6273 for (i
= 0; i
< font_name_count
; i
++)
6275 fontname
= build_string (font_name_table
[i
]);
6276 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6278 font_list
= Fcons (fontname
, font_list
);
6281 if (maxnames
> 0 && n_fonts
>= maxnames
)
6284 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6285 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6287 int former_len
= ptr
- font_name_table
[i
];
6289 memcpy (scaled
, font_name_table
[i
], former_len
);
6290 sprintf (scaled
+ former_len
,
6291 "-%d-%d-75-75-m-%d-%s",
6292 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6293 scl_val
[XLFD_SCL_POINT_SIZE
],
6294 scl_val
[XLFD_SCL_AVGWIDTH
],
6295 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6296 fontname
= build_string (scaled
);
6297 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6299 font_list
= Fcons (fontname
, font_list
);
6302 if (maxnames
> 0 && n_fonts
>= maxnames
)
6310 /* Return a list of at most MAXNAMES font specs matching the one in
6311 PATTERN. Cache matching fonts for patterns in
6312 dpyinfo->name_list_element to avoid looking them up again by
6313 calling mac_font_pattern_match (slow). Return as many matching
6314 fonts as possible if MAXNAMES = -1. */
6317 x_list_fonts (struct frame
*f
,
6318 Lisp_Object pattern
,
6322 Lisp_Object newlist
= Qnil
, tem
, key
;
6323 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6325 if (font_name_table
== NULL
) /* Initialize when first used. */
6326 init_font_name_table ();
6330 tem
= XCDR (dpyinfo
->name_list_element
);
6331 key
= Fcons (pattern
, make_number (maxnames
));
6333 newlist
= Fassoc (key
, tem
);
6334 if (!NILP (newlist
))
6336 newlist
= Fcdr_safe (newlist
);
6341 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6343 /* MAC_TODO: add code for matching outline fonts here */
6347 XSETCDR (dpyinfo
->name_list_element
,
6348 Fcons (Fcons (key
, newlist
),
6349 XCDR (dpyinfo
->name_list_element
)));
6359 /* Check that FONT is valid on frame F. It is if it can be found in F's
6363 x_check_font (f
, font
)
6368 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6370 xassert (font
!= NULL
);
6372 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6373 if (dpyinfo
->font_table
[i
].name
6374 && font
== dpyinfo
->font_table
[i
].font
)
6377 xassert (i
< dpyinfo
->n_fonts
);
6380 #endif /* GLYPH_DEBUG != 0 */
6382 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6383 Note: There are (broken) X fonts out there with invalid XFontStruct
6384 min_bounds contents. For example, handa@etl.go.jp reports that
6385 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6386 have font->min_bounds.width == 0. */
6389 x_font_min_bounds (font
, w
, h
)
6390 MacFontStruct
*font
;
6394 * TODO: Windows does not appear to offer min bound, only
6395 * average and maximum width, and maximum height.
6397 *h
= FONT_HEIGHT (font
);
6398 *w
= FONT_WIDTH (font
);
6402 /* Compute the smallest character width and smallest font height over
6403 all fonts available on frame F. Set the members smallest_char_width
6404 and smallest_font_height in F's x_display_info structure to
6405 the values computed. Value is non-zero if smallest_font_height or
6406 smallest_char_width become smaller than they were before. */
6409 x_compute_min_glyph_bounds (f
)
6413 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6414 MacFontStruct
*font
;
6415 int old_width
= dpyinfo
->smallest_char_width
;
6416 int old_height
= dpyinfo
->smallest_font_height
;
6418 dpyinfo
->smallest_font_height
= 100000;
6419 dpyinfo
->smallest_char_width
= 100000;
6421 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6422 if (dpyinfo
->font_table
[i
].name
)
6424 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6427 font
= (MacFontStruct
*) fontp
->font
;
6428 xassert (font
!= (MacFontStruct
*) ~0);
6429 x_font_min_bounds (font
, &w
, &h
);
6431 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6432 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6435 xassert (dpyinfo
->smallest_char_width
> 0
6436 && dpyinfo
->smallest_font_height
> 0);
6438 return (dpyinfo
->n_fonts
== 1
6439 || dpyinfo
->smallest_char_width
< old_width
6440 || dpyinfo
->smallest_font_height
< old_height
);
6444 /* Determine whether given string is a fully-specified XLFD: all 14
6445 fields are present, none is '*'. */
6448 is_fully_specified_xlfd (char *p
)
6456 for (i
= 0; i
< 13; i
++)
6458 q
= strchr (p
+ 1, '-');
6461 if (q
- p
== 2 && *(p
+ 1) == '*')
6466 if (strchr (p
+ 1, '-') != NULL
)
6469 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6476 const int kDefaultFontSize
= 9;
6479 /* XLoadQueryFont creates and returns an internal representation for a
6480 font in a MacFontStruct struct. There is really no concept
6481 corresponding to "loading" a font on the Mac. But we check its
6482 existence and find the font number and all other information for it
6483 and store them in the returned MacFontStruct. */
6485 static MacFontStruct
*
6486 XLoadQueryFont (Display
*dpy
, char *fontname
)
6488 int i
, size
, is_two_byte_font
, char_width
;
6491 SInt16 old_fontnum
, old_fontsize
;
6495 Style fontface
= normal
;
6496 MacFontStruct
*font
;
6497 FontInfo the_fontinfo
;
6498 char s_weight
[7], c_slant
;
6500 if (is_fully_specified_xlfd (fontname
))
6504 Lisp_Object matched_fonts
;
6506 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6507 if (NILP (matched_fonts
))
6509 name
= SDATA (XCAR (matched_fonts
));
6512 GetPort (&port
); /* save the current font number used */
6513 #if TARGET_API_MAC_CARBON
6514 old_fontnum
= GetPortTextFont (port
);
6515 old_fontsize
= GetPortTextSize (port
);
6516 old_fontface
= GetPortTextFace (port
);
6518 old_fontnum
= port
->txFont
;
6519 old_fontsize
= port
->txSize
;
6520 old_fontface
= port
->txFace
;
6523 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6524 size
= kDefaultFontSize
;
6526 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6527 if (strcmp (s_weight
, "bold") == 0)
6530 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6534 x_font_name_to_mac_font_name (name
, mfontname
);
6536 GetFNum (mfontname
, &fontnum
);
6540 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6542 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6543 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6545 font
->mac_fontnum
= fontnum
;
6546 font
->mac_fontsize
= size
;
6547 font
->mac_fontface
= fontface
;
6548 font
->mac_scriptcode
= FontToScript (fontnum
);
6550 /* Apple Japanese (SJIS) font is listed as both
6551 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6552 (Roman script) in init_font_name_table (). The latter should be
6553 treated as a one-byte font. */
6558 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6560 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6561 font
->mac_scriptcode
= smRoman
;
6564 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6565 font
->mac_scriptcode
== smTradChinese
||
6566 font
->mac_scriptcode
== smSimpChinese
||
6567 font
->mac_scriptcode
== smKorean
;
6571 TextFace (fontface
);
6573 GetFontInfo (&the_fontinfo
);
6575 font
->ascent
= the_fontinfo
.ascent
;
6576 font
->descent
= the_fontinfo
.descent
;
6578 font
->min_byte1
= 0;
6579 if (is_two_byte_font
)
6580 font
->max_byte1
= 1;
6582 font
->max_byte1
= 0;
6583 font
->min_char_or_byte2
= 0x20;
6584 font
->max_char_or_byte2
= 0xff;
6586 if (is_two_byte_font
)
6588 /* Use the width of an "ideographic space" of that font because
6589 the_fontinfo.widMax returns the wrong width for some fonts. */
6590 switch (font
->mac_scriptcode
)
6593 char_width
= StringWidth("\p\x81\x40");
6596 char_width
= StringWidth("\p\xa1\x40");
6599 char_width
= StringWidth("\p\xa1\xa1");
6602 char_width
= StringWidth("\p\xa1\xa1");
6607 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6608 returns 15 for 12-point Monaco! */
6609 char_width
= CharWidth ('m');
6611 font
->max_bounds
.rbearing
= char_width
;
6612 font
->max_bounds
.lbearing
= 0;
6613 font
->max_bounds
.width
= char_width
;
6614 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6615 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6617 font
->min_bounds
= font
->max_bounds
;
6619 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6620 font
->per_char
= NULL
;
6623 font
->per_char
= (XCharStruct
*)
6624 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6628 for (c
= 0x20; c
<= 0xff; c
++)
6630 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6631 font
->per_char
[c
- 0x20].width
=
6632 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6637 TextFont (old_fontnum
); /* restore previous font number, size and face */
6638 TextSize (old_fontsize
);
6639 TextFace (old_fontface
);
6645 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6646 pointer to the structure font_info while allocating it dynamically.
6647 If SIZE is 0, load any size of font.
6648 If loading is failed, return NULL. */
6651 x_load_font (f
, fontname
, size
)
6653 register char *fontname
;
6656 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6657 Lisp_Object font_names
;
6659 /* Get a list of all the fonts that match this name. Once we
6660 have a list of matching fonts, we compare them against the fonts
6661 we already have by comparing names. */
6662 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6664 if (!NILP (font_names
))
6669 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6670 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6671 if (dpyinfo
->font_table
[i
].name
6672 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6673 SDATA (XCAR (tail
)))
6674 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6675 SDATA (XCAR (tail
)))))
6676 return (dpyinfo
->font_table
+ i
);
6679 /* Load the font and add it to the table. */
6682 struct MacFontStruct
*font
;
6683 struct font_info
*fontp
;
6684 unsigned long value
;
6687 /* If we have found fonts by x_list_font, load one of them. If
6688 not, we still try to load a font by the name given as FONTNAME
6689 because XListFonts (called in x_list_font) of some X server has
6690 a bug of not finding a font even if the font surely exists and
6691 is loadable by XLoadQueryFont. */
6692 if (size
> 0 && !NILP (font_names
))
6693 fontname
= (char *) SDATA (XCAR (font_names
));
6695 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6699 /* Find a free slot in the font table. */
6700 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6701 if (dpyinfo
->font_table
[i
].name
== NULL
)
6704 /* If no free slot found, maybe enlarge the font table. */
6705 if (i
== dpyinfo
->n_fonts
6706 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6709 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6710 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6712 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6715 fontp
= dpyinfo
->font_table
+ i
;
6716 if (i
== dpyinfo
->n_fonts
)
6719 /* Now fill in the slots of *FONTP. */
6721 bzero (fontp
, sizeof (*fontp
));
6723 fontp
->font_idx
= i
;
6724 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6725 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6727 fontp
->full_name
= fontp
->name
;
6729 fontp
->size
= font
->max_bounds
.width
;
6730 fontp
->height
= FONT_HEIGHT (font
);
6732 /* For some font, ascent and descent in max_bounds field is
6733 larger than the above value. */
6734 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6735 if (max_height
> fontp
->height
)
6736 fontp
->height
= max_height
;
6739 /* The slot `encoding' specifies how to map a character
6740 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6741 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6742 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6743 2:0xA020..0xFF7F). For the moment, we don't know which charset
6744 uses this font. So, we set information in fontp->encoding[1]
6745 which is never used by any charset. If mapping can't be
6746 decided, set FONT_ENCODING_NOT_DECIDED. */
6747 if (font
->mac_scriptcode
== smJapanese
)
6748 fontp
->encoding
[1] = 4;
6752 = (font
->max_byte1
== 0
6754 ? (font
->min_char_or_byte2
< 0x80
6755 ? (font
->max_char_or_byte2
< 0x80
6756 ? 0 /* 0x20..0x7F */
6757 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6758 : 1) /* 0xA0..0xFF */
6760 : (font
->min_byte1
< 0x80
6761 ? (font
->max_byte1
< 0x80
6762 ? (font
->min_char_or_byte2
< 0x80
6763 ? (font
->max_char_or_byte2
< 0x80
6764 ? 0 /* 0x2020..0x7F7F */
6765 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6766 : 3) /* 0x20A0..0x7FFF */
6767 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6768 : (font
->min_char_or_byte2
< 0x80
6769 ? (font
->max_char_or_byte2
< 0x80
6770 ? 2 /* 0xA020..0xFF7F */
6771 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6772 : 1))); /* 0xA0A0..0xFFFF */
6775 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6776 fontp
->baseline_offset
6777 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6778 ? (long) value
: 0);
6779 fontp
->relative_compose
6780 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6781 ? (long) value
: 0);
6782 fontp
->default_ascent
6783 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6784 ? (long) value
: 0);
6786 fontp
->baseline_offset
= 0;
6787 fontp
->relative_compose
= 0;
6788 fontp
->default_ascent
= 0;
6791 /* Set global flag fonts_changed_p to non-zero if the font loaded
6792 has a character with a smaller width than any other character
6793 before, or if the font loaded has a smalle>r height than any
6794 other font loaded before. If this happens, it will make a
6795 glyph matrix reallocation necessary. */
6796 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6803 /* Return a pointer to struct font_info of a font named FONTNAME for
6804 frame F. If no such font is loaded, return NULL. */
6807 x_query_font (f
, fontname
)
6809 register char *fontname
;
6811 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6814 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6815 if (dpyinfo
->font_table
[i
].name
6816 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6817 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6818 return (dpyinfo
->font_table
+ i
);
6823 /* Find a CCL program for a font specified by FONTP, and set the member
6824 `encoder' of the structure. */
6827 x_find_ccl_program (fontp
)
6828 struct font_info
*fontp
;
6830 Lisp_Object list
, elt
;
6832 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6836 && STRINGP (XCAR (elt
))
6837 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6843 struct ccl_program
*ccl
6844 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6846 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6849 fontp
->font_encoder
= ccl
;
6855 /* The Mac Event loop code */
6859 #include <Quickdraw.h>
6860 #include <Balloons.h>
6861 #include <Devices.h>
6863 #include <Gestalt.h>
6865 #include <Processes.h>
6867 #include <ToolUtils.h>
6868 #include <TextUtils.h>
6869 #include <Dialogs.h>
6872 #include <TextEncodingConverter.h>
6873 #include <Resources.h>
6878 #endif /* ! MAC_OSX */
6883 #define WINDOW_RESOURCE 128
6884 #define TERM_WINDOW_RESOURCE 129
6886 #define DEFAULT_NUM_COLS 80
6888 #define MIN_DOC_SIZE 64
6889 #define MAX_DOC_SIZE 32767
6891 /* sleep time for WaitNextEvent */
6892 #define WNE_SLEEP_AT_SUSPEND 10
6893 #define WNE_SLEEP_AT_RESUME 1
6895 /* true when cannot handle any Mac OS events */
6896 static int handling_window_update
= 0;
6898 /* the flag appl_is_suspended is used both for determining the sleep
6899 time to be passed to WaitNextEvent and whether the cursor should be
6900 drawn when updating the display. The cursor is turned off when
6901 Emacs is suspended. Redrawing it is unnecessary and what needs to
6902 be done depends on whether the cursor lies inside or outside the
6903 redraw region. So we might as well skip drawing it when Emacs is
6905 static Boolean app_is_suspended
= false;
6906 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6908 #define EXTRA_STACK_ALLOC (256 * 1024)
6910 #define ARGV_STRING_LIST_ID 129
6911 #define ABOUT_ALERT_ID 128
6912 #define RAM_TOO_LARGE_ALERT_ID 129
6914 Boolean terminate_flag
= false;
6916 /* Contains the string "reverse", which is a constant for mouse button emu.*/
6917 Lisp_Object Qreverse
;
6919 /* True if using command key as meta key. */
6920 Lisp_Object Vmac_command_key_is_meta
;
6922 /* True if the ctrl and meta keys should be reversed. */
6923 Lisp_Object Vmac_reverse_ctrl_meta
;
6925 /* True if the option and command modifiers should be used to emulate
6926 a three button mouse */
6927 Lisp_Object Vmac_emulate_three_button_mouse
;
6929 #if USE_CARBON_EVENTS
6930 /* True if the mouse wheel button (i.e. button 4) should map to
6931 mouse-2, instead of mouse-3. */
6932 Lisp_Object Vmac_wheel_button_is_mouse_2
;
6934 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
6935 for processing before Emacs sees it. */
6936 Lisp_Object Vmac_pass_command_to_system
;
6938 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
6939 for processing before Emacs sees it. */
6940 Lisp_Object Vmac_pass_control_to_system
;
6943 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
6944 to this text encoding */
6945 int mac_keyboard_text_encoding
;
6946 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
6948 /* Set in term/mac-win.el to indicate that event loop can now generate
6949 drag and drop events. */
6950 Lisp_Object Qmac_ready_for_drag_n_drop
;
6952 Lisp_Object drag_and_drop_file_list
;
6954 Point saved_menu_event_location
;
6957 static void init_required_apple_events (void);
6959 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
6961 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
6962 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
6963 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
6966 static OSErr
init_mac_drag_n_drop ();
6967 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
6969 #if USE_CARBON_EVENTS
6970 /* Preliminary Support for the OSX Services Menu */
6971 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
6972 static void init_service_handler ();
6975 extern void init_emacs_passwd_dir ();
6976 extern int emacs_main (int, char **, char **);
6977 extern void check_alarm ();
6979 extern void initialize_applescript();
6980 extern void terminate_applescript();
6983 #if USE_CARBON_EVENTS
6984 mac_to_emacs_modifiers (UInt32 mods
)
6986 mac_to_emacs_modifiers (EventModifiers mods
)
6989 unsigned int result
= 0;
6990 if (mods
& macShiftKey
)
6991 result
|= shift_modifier
;
6992 if (mods
& macCtrlKey
)
6993 result
|= ctrl_modifier
;
6994 if (mods
& macMetaKey
)
6995 result
|= meta_modifier
;
6996 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
6997 result
|= alt_modifier
;
7002 mac_get_emulated_btn ( UInt32 modifiers
)
7005 if (Vmac_emulate_three_button_mouse
!= Qnil
) {
7006 int cmdIs3
= (Vmac_emulate_three_button_mouse
!= Qreverse
);
7007 if (modifiers
& controlKey
)
7008 result
= cmdIs3
? 2 : 1;
7009 else if (modifiers
& optionKey
)
7010 result
= cmdIs3
? 1 : 2;
7015 #if USE_CARBON_EVENTS
7016 /* Obtains the event modifiers from the event ref and then calls
7017 mac_to_emacs_modifiers. */
7019 mac_event_to_emacs_modifiers (EventRef eventRef
)
7022 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7023 sizeof (UInt32
), NULL
, &mods
);
7024 if (Vmac_emulate_three_button_mouse
!= Qnil
&&
7025 GetEventClass(eventRef
) == kEventClassMouse
)
7027 mods
&= ~(optionKey
& cmdKey
);
7029 return mac_to_emacs_modifiers (mods
);
7032 /* Given an event ref, return the code to use for the mouse button
7033 code in the emacs input_event. */
7035 mac_get_mouse_btn (EventRef ref
)
7037 EventMouseButton result
= kEventMouseButtonPrimary
;
7038 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7039 sizeof (EventMouseButton
), NULL
, &result
);
7042 case kEventMouseButtonPrimary
:
7043 if (Vmac_emulate_three_button_mouse
== Qnil
)
7047 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7048 sizeof (UInt32
), NULL
, &mods
);
7049 return mac_get_emulated_btn(mods
);
7051 case kEventMouseButtonSecondary
:
7052 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7053 case kEventMouseButtonTertiary
:
7054 case 4: /* 4 is the number for the mouse wheel button */
7055 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7061 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7062 events. However the click of the mouse wheel is not converted to a
7063 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7064 checks to see if it is a mouse up or down carbon event that has not
7065 been converted, and if so, converts it by hand (to be picked up in
7066 the XTread_socket loop). */
7067 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7069 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7070 /* Do special case for mouse wheel button. */
7071 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7073 UInt32 kind
= GetEventKind (eventRef
);
7074 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7076 eventRec
->what
= mouseDown
;
7079 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7081 eventRec
->what
= mouseUp
;
7086 /* Need where and when. */
7088 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7089 typeQDPoint
, NULL
, sizeof (Point
),
7090 NULL
, &eventRec
->where
);
7091 /* Use two step process because new event modifiers are
7092 32-bit and old are 16-bit. Currently, only loss is
7094 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7095 typeUInt32
, NULL
, sizeof (UInt32
),
7097 eventRec
->modifiers
= mods
;
7099 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7110 Handle menubar_handle
;
7111 MenuHandle menu_handle
;
7113 menubar_handle
= GetNewMBar (128);
7114 if(menubar_handle
== NULL
)
7116 SetMenuBar (menubar_handle
);
7119 menu_handle
= GetMenuHandle (M_APPLE
);
7120 if(menu_handle
!= NULL
)
7121 AppendResMenu (menu_handle
,'DRVR');
7128 do_init_managers (void)
7130 #if !TARGET_API_MAC_CARBON
7131 InitGraf (&qd
.thePort
);
7133 FlushEvents (everyEvent
, 0);
7138 #endif /* !TARGET_API_MAC_CARBON */
7141 #if !TARGET_API_MAC_CARBON
7142 /* set up some extra stack space for use by emacs */
7143 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7145 /* MaxApplZone must be called for AppleScript to execute more
7146 complicated scripts */
7149 #endif /* !TARGET_API_MAC_CARBON */
7153 do_check_ram_size (void)
7155 SInt32 physical_ram_size
, logical_ram_size
;
7157 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7158 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7159 || physical_ram_size
> (1 << VALBITS
)
7160 || logical_ram_size
> (1 << VALBITS
))
7162 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7168 do_window_update (WindowPtr win
)
7170 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
7171 struct frame
*f
= mwp
->mFP
;
7175 if (f
->async_visible
== 0)
7177 f
->async_visible
= 1;
7178 f
->async_iconified
= 0;
7179 SET_FRAME_GARBAGED (f
);
7181 /* An update event is equivalent to MapNotify on X, so report
7182 visibility changes properly. */
7183 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7184 /* Force a redisplay sooner or later to update the
7185 frame titles in case this is the second frame. */
7186 record_asynch_buffer_change ();
7191 handling_window_update
= 1;
7193 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7195 expose_frame (f
, 0, 0, 0, 0);
7197 handling_window_update
= 0;
7204 is_emacs_window (WindowPtr win
)
7206 Lisp_Object tail
, frame
;
7211 FOR_EACH_FRAME (tail
, frame
)
7212 if (FRAME_MAC_P (XFRAME (frame
)))
7213 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7220 do_window_activate (WindowPtr win
)
7225 if (is_emacs_window (win
))
7227 mwp
= (mac_output
*) GetWRefCon (win
);
7232 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7233 activate_scroll_bars (f
);
7239 do_window_deactivate (WindowPtr win
)
7244 if (is_emacs_window (win
))
7246 mwp
= (mac_output
*) GetWRefCon (win
);
7249 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7251 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7252 deactivate_scroll_bars (f
);
7265 if (is_emacs_window (wp
))
7267 mwp
= (mac_output
*) GetWRefCon (wp
);
7272 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7273 activate_scroll_bars (f
);
7277 app_is_suspended
= false;
7278 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7289 if (is_emacs_window (wp
))
7291 mwp
= (mac_output
*) GetWRefCon (wp
);
7294 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7296 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7297 deactivate_scroll_bars (f
);
7301 app_is_suspended
= true;
7302 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7307 do_mouse_moved (Point mouse_pos
)
7309 WindowPtr wp
= FrontWindow ();
7312 if (is_emacs_window (wp
))
7314 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
7316 #if TARGET_API_MAC_CARBON
7317 SetPort (GetWindowPort (wp
));
7322 GlobalToLocal (&mouse_pos
);
7324 note_mouse_movement (f
, &mouse_pos
);
7330 do_os_event (EventRecord
*erp
)
7332 switch((erp
->message
>> 24) & 0x000000FF)
7334 case suspendResumeMessage
:
7335 if((erp
->message
& resumeFlag
) == 1)
7341 case mouseMovedMessage
:
7342 do_mouse_moved (erp
->where
);
7348 do_events (EventRecord
*erp
)
7353 do_window_update ((WindowPtr
) erp
->message
);
7361 if ((erp
->modifiers
& activeFlag
) != 0)
7362 do_window_activate ((WindowPtr
) erp
->message
);
7364 do_window_deactivate ((WindowPtr
) erp
->message
);
7370 do_apple_menu (SInt16 menu_item
)
7372 #if !TARGET_API_MAC_CARBON
7374 SInt16 da_driver_refnum
;
7376 if (menu_item
== I_ABOUT
)
7377 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7380 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7381 da_driver_refnum
= OpenDeskAcc (item_name
);
7383 #endif /* !TARGET_API_MAC_CARBON */
7387 do_menu_choice (SInt32 menu_choice
)
7389 SInt16 menu_id
, menu_item
;
7391 menu_id
= HiWord (menu_choice
);
7392 menu_item
= LoWord (menu_choice
);
7400 do_apple_menu (menu_item
);
7405 WindowPtr wp
= FrontWindow ();
7406 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
7407 MenuHandle menu
= GetMenuHandle (menu_id
);
7412 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7413 menubar_selection_callback (f
, refcon
);
7422 /* Handle drags in size box. Based on code contributed by Ben
7423 Mesander and IM - Window Manager A. */
7426 do_grow_window (WindowPtr w
, EventRecord
*e
)
7431 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7432 struct frame
*f
= mwp
->mFP
;
7434 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7436 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7438 /* see if it really changed size */
7441 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7442 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7444 x_set_window_size (f
, 0, columns
, rows
);
7449 /* Handle clicks in zoom box. Calculation of "standard state" based
7450 on code in IM - Window Manager A and code contributed by Ben
7451 Mesander. The standard state of an Emacs window is 80-characters
7452 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7455 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7458 Rect zoom_rect
, port_rect
;
7460 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
7461 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7462 struct frame
*f
= mwp
->mFP
;
7464 GetPort (&save_port
);
7466 #if TARGET_API_MAC_CARBON
7467 SetPort (GetWindowPort (w
));
7472 /* Clear window to avoid flicker. */
7473 #if TARGET_API_MAC_CARBON
7478 GetWindowPortBounds (w
, &r
);
7481 if (zoom_in_or_out
== inZoomOut
)
7483 /* calculate height of window's title bar (hard card it for now). */
7484 w_title_height
= 20 + GetMBarHeight ();
7486 /* get maximum height of window into zoom_rect.bottom -
7488 GetQDGlobalsScreenBits (&bm
);
7489 zoom_rect
= bm
.bounds
;
7490 zoom_rect
.top
+= w_title_height
;
7491 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7493 zoom_rect
.right
= zoom_rect
.left
7494 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7496 SetWindowStandardState (w
, &zoom_rect
);
7499 #else /* not TARGET_API_MAC_CARBON */
7500 EraseRect (&(w
->portRect
));
7501 if (zoom_in_or_out
== inZoomOut
)
7503 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7504 LocalToGlobal (&top_left
);
7506 /* calculate height of window's title bar */
7507 w_title_height
= top_left
.v
- 1
7508 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7510 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7511 zoom_rect
= qd
.screenBits
.bounds
;
7512 zoom_rect
.top
+= w_title_height
;
7513 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7515 zoom_rect
.right
= zoom_rect
.left
7516 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7518 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7521 #endif /* not TARGET_API_MAC_CARBON */
7523 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
7525 /* retrieve window size and update application values */
7526 #if TARGET_API_MAC_CARBON
7527 GetWindowPortBounds (w
, &port_rect
);
7529 port_rect
= w
->portRect
;
7531 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7532 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7533 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
7535 SetPort (save_port
);
7538 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7540 init_mac_drag_n_drop ()
7542 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7546 /* Intialize AppleEvent dispatcher table for the required events. */
7548 init_required_apple_events ()
7553 /* Make sure we have apple events before starting. */
7554 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7558 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7561 #if TARGET_API_MAC_CARBON
7562 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7563 NewAEEventHandlerUPP
7564 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7567 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7568 NewAEEventHandlerProc
7569 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7575 #if TARGET_API_MAC_CARBON
7576 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7577 NewAEEventHandlerUPP
7578 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7581 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7582 NewAEEventHandlerProc
7583 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7589 #if TARGET_API_MAC_CARBON
7590 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7591 NewAEEventHandlerUPP
7592 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7595 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7596 NewAEEventHandlerProc
7597 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7603 #if TARGET_API_MAC_CARBON
7604 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7605 NewAEEventHandlerUPP
7606 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7609 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7610 NewAEEventHandlerProc
7611 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7618 #if USE_CARBON_EVENTS
7621 init_service_handler ()
7623 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7624 {kEventClassService
, kEventServiceCopy
},
7625 {kEventClassService
, kEventServicePaste
}};
7626 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7627 3, specs
, NULL
, NULL
);
7631 MAC_TODO: Check to see if this is called by AEProcessDesc...
7634 mac_handle_service_event (EventHandlerCallRef callRef
,
7635 EventRef event
, void *data
)
7637 OSStatus err
= noErr
;
7638 switch (GetEventKind (event
))
7640 case kEventServiceGetTypes
:
7642 CFMutableArrayRef copyTypes
, pasteTypes
;
7644 Boolean selection
= true;
7646 GetEventParameter(event, kEventParamServicePasteTypes,
7647 typeCFMutableArrayRef, NULL,
7648 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7650 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7651 typeCFMutableArrayRef
, NULL
,
7652 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7653 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7655 CFArrayAppendValue (copyTypes
, type
);
7656 //CFArrayAppendValue (pasteTypes, type);
7660 case kEventServiceCopy
:
7662 ScrapRef currentScrap
, specificScrap
;
7666 GetCurrentScrap (¤tScrap
);
7668 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7671 void *buffer
= xmalloc (byteCount
);
7674 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7675 sizeof (ScrapRef
), NULL
, &specificScrap
);
7677 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7678 &byteCount
, buffer
);
7680 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7681 kScrapFlavorMaskNone
, byteCount
, buffer
);
7687 case kEventServicePaste
:
7690 // Get the current location
7692 ScrapRef specificScrap;
7693 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7694 sizeof(ScrapRef), NULL, &specificScrap);
7695 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7697 void * buffer = xmalloc(byteCount);
7698 if (buffer != NULL ) {
7699 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7700 &byteCount, buffer);
7702 // Actually place in the buffer
7704 // Get the current "selection" string here
7717 /* Open Application Apple Event */
7719 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7725 /* Defined in mac.c. */
7727 path_from_vol_dir_name (char *, int, short, long, char *);
7730 /* Called when we receive an AppleEvent with an ID of
7731 "kAEOpenDocuments". This routine gets the direct parameter,
7732 extracts the FSSpecs in it, and puts their names on a list. */
7734 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7739 DescType actual_type
;
7742 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7744 goto descriptor_error_exit
;
7746 /* Check to see that we got all of the required parameters from the
7747 event descriptor. For an 'odoc' event this should just be the
7749 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7750 &actual_type
, (Ptr
) &keyword
,
7751 sizeof (keyword
), &actual_size
);
7752 /* No error means that we found some unused parameters.
7753 errAEDescNotFound means that there are no more parameters. If we
7754 get an error code other than that, flag it. */
7755 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7757 err
= errAEEventNotHandled
;
7762 /* Got all the parameters we need. Now, go through the direct
7763 object list and parse it up. */
7765 long num_files_to_open
;
7767 err
= AECountItems (&the_desc
, &num_files_to_open
);
7772 /* AE file list is one based so just use that for indexing here. */
7773 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7776 Str255 path_name
, unix_path_name
;
7781 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7782 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7783 if (err
!= noErr
) break;
7786 err
= FSpMakeFSRef (&fs
, &fref
);
7787 if (err
!= noErr
) break;
7789 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7791 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7793 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7795 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7796 drag_and_drop_file_list
);
7802 /* Nuke the coerced file list in any case */
7803 err2
= AEDisposeDesc(&the_desc
);
7805 descriptor_error_exit
:
7806 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7812 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7813 DragReference theDrag
)
7817 FlavorFlags theFlags
;
7820 ItemReference theItem
;
7823 Size size
= sizeof (HFSFlavor
);
7825 drag_and_drop_file_list
= Qnil
;
7826 GetDragMouse (theDrag
, &mouse
, 0L);
7827 CountDragItems (theDrag
, &items
);
7828 for (index
= 1; index
<= items
; index
++)
7830 /* Only handle file references. */
7831 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7832 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7833 if (result
== noErr
)
7840 Str255 unix_path_name
;
7841 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7843 /* Use Carbon routines, otherwise it converts the file name
7844 to /Macintosh HD/..., which is not correct. */
7845 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7846 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7848 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7849 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7850 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7852 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7853 drag_and_drop_file_list
);
7858 /* If there are items in the list, construct an event and post it to
7859 the queue like an interrupt using kbd_buffer_store_event. */
7860 if (!NILP (drag_and_drop_file_list
))
7862 struct input_event event
;
7864 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
7865 SetPort (GetWindowPort (window
));
7866 GlobalToLocal (&mouse
);
7868 event
.kind
= DRAG_N_DROP_EVENT
;
7870 event
.modifiers
= 0;
7871 event
.timestamp
= TickCount () * (1000 / 60);
7872 XSETINT (event
.x
, mouse
.h
);
7873 XSETINT (event
.y
, mouse
.v
);
7874 XSETFRAME (frame
, f
);
7875 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7877 /* Post to the interrupt queue */
7878 kbd_buffer_store_event (&event
);
7879 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7881 ProcessSerialNumber psn
;
7882 GetCurrentProcess (&psn
);
7883 SetFrontProcess (&psn
);
7889 /* Print Document Apple Event */
7891 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7893 return errAEEventNotHandled
;
7898 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7900 /* FixMe: Do we need an unwind-protect or something here? And what
7901 do we do about unsaved files. Currently just forces quit rather
7902 than doing recursive callback to get user input. */
7904 terminate_flag
= true;
7906 /* Fkill_emacs doesn't return. We have to return. (TI) */
7913 profiler_exit_proc ()
7915 ProfilerDump ("\pEmacs.prof");
7920 /* These few functions implement Emacs as a normal Mac application
7921 (almost): set up the heap and the Toolbox, handle necessary
7922 system events plus a few simple menu events. They also set up
7923 Emacs's access to functions defined in the rest of this file.
7924 Emacs uses function hooks to perform all its terminal I/O. A
7925 complete list of these functions appear in termhooks.h. For what
7926 they do, read the comments there and see also w32term.c and
7927 xterm.c. What's noticeably missing here is the event loop, which
7928 is normally present in most Mac application. After performing the
7929 necessary Mac initializations, main passes off control to
7930 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7931 mac_read_socket (defined further below) to read input. This is
7932 where WaitNextEvent is called to process Mac events. This is also
7933 where check_alarm in sysdep.c is called to simulate alarm signals.
7934 This makes the cursor jump back to its correct position after
7935 briefly jumping to that of the matching parenthesis, print useful
7936 hints and prompts in the minibuffer after the user stops typing for
7939 #if !TARGET_API_MAC_CARBON
7944 #if __profile__ /* is the profiler on? */
7945 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7950 /* set creator and type for files created by MSL */
7955 do_init_managers ();
7960 do_check_ram_size ();
7963 init_emacs_passwd_dir ();
7967 initialize_applescript ();
7969 init_required_apple_events ();
7975 /* set up argv array from STR# resource */
7976 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
7980 /* free up AppleScript resources on exit */
7981 atexit (terminate_applescript
);
7983 #if __profile__ /* is the profiler on? */
7984 atexit (profiler_exit_proc
);
7987 /* 3rd param "envp" never used in emacs_main */
7988 (void) emacs_main (argc
, argv
, 0);
7991 /* Never reached - real exit in Fkill_emacs */
7996 /* Table for translating Mac keycode to X keysym values. Contributed
7997 by Sudhir Shenoy. */
7998 static unsigned char keycode_to_xkeysym_table
[] = {
7999 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8000 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8001 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8003 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8004 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
8005 /*0x38*/ 0, 0, 0, 0,
8006 /*0x3C*/ 0, 0, 0, 0,
8008 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
8009 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
8010 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
8011 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
8013 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8014 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8015 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8016 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8018 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8019 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8020 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8021 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8023 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8024 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8025 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8026 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8030 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8032 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8033 return *xKeySym
!= 0;
8036 /* Emacs calls this whenever it wants to read an input event from the
8039 XTread_socket (int sd
, int expected
, struct input_event
*hold_quit
)
8041 struct input_event inev
;
8043 #if USE_CARBON_EVENTS
8046 EventMouseButton mouseBtn
;
8050 EventMask event_mask
;
8053 if (interrupt_input_blocked
)
8055 interrupt_input_pending
= 1;
8060 interrupt_input_pending
= 0;
8063 /* So people can tell when we have read the available input. */
8064 input_signal_count
++;
8066 /* Don't poll for events to process (specifically updateEvt) if
8067 window update currently already in progress. A call to redisplay
8068 (in do_window_update) can be preempted by another call to
8069 redisplay, causing blank regions to be left on the screen and the
8070 cursor to be left at strange places. */
8071 if (handling_window_update
)
8078 Fkill_emacs (make_number (1));
8080 /* It is necessary to set this (additional) argument slot of an
8081 event to nil because keyboard.c protects incompletely processed
8082 event from being garbage collected by placing them in the
8083 kbd_buffer_gcpro vector. */
8085 inev
.kind
= NO_EVENT
;
8088 event_mask
= everyEvent
;
8089 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8090 event_mask
-= highLevelEventMask
;
8092 #if USE_CARBON_EVENTS
8093 rneResult
= ReceiveNextEvent (0, NULL
,
8095 ? TicksToEventTime (app_sleep_time
)
8097 kEventRemoveFromQueue
, &eventRef
);
8100 /* Handle new events */
8101 if (!mac_convert_event_ref (eventRef
, &er
))
8102 switch (GetEventClass (eventRef
))
8104 case kEventClassMouse
:
8105 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8109 WindowPtr window_ptr
= FrontNonFloatingWindow ();
8110 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
8111 if (!IsValidWindowPtr (window_ptr
))
8118 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8119 typeSInt32
, NULL
, sizeof (SInt32
),
8121 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8122 typeQDPoint
, NULL
, sizeof (Point
),
8124 inev
.kind
= WHEEL_EVENT
;
8126 inev
.modifiers
= (mac_event_to_emacs_modifiers(eventRef
)
8127 | ((delta
< 0) ? down_modifier
8129 SetPort (GetWindowPort (window_ptr
));
8130 GlobalToLocal (&point
);
8131 XSETINT (inev
.x
, point
.h
);
8132 XSETINT (inev
.y
, point
.v
);
8133 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8134 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8137 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
8141 /* Send the event to the appropriate receiver. */
8142 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
8146 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
8147 #endif /* USE_CARBON_EVENTS */
8153 WindowPtr window_ptr
= FrontWindow ();
8156 #if USE_CARBON_EVENTS
8157 /* This is needed to send mouse events like aqua window buttons
8158 to the correct handler. */
8159 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
8163 if (!is_emacs_window(window_ptr
))
8167 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8168 && er
.what
== mouseUp
)
8170 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
8171 Point mouse_loc
= er
.where
;
8173 /* Convert to local coordinates of new window. */
8174 #if TARGET_API_MAC_CARBON
8175 SetPort (GetWindowPort (window_ptr
));
8177 SetPort (window_ptr
);
8180 GlobalToLocal (&mouse_loc
);
8182 #if USE_CARBON_EVENTS
8183 inev
.code
= mac_get_mouse_btn (eventRef
);
8185 inev
.code
= mac_get_emulate_btn (er
.modifiers
);
8187 inev
.kind
= SCROLL_BAR_CLICK_EVENT
;
8188 inev
.frame_or_window
= tracked_scroll_bar
->window
;
8189 inev
.part
= scroll_bar_handle
;
8190 #if USE_CARBON_EVENTS
8191 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8193 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8195 inev
.modifiers
|= up_modifier
;
8196 inev
.timestamp
= er
.when
* (1000 / 60);
8197 /* ticks to milliseconds */
8199 XSETINT (inev
.x
, tracked_scroll_bar
->left
+ 2);
8200 XSETINT (inev
.y
, mouse_loc
.v
- 24);
8201 tracked_scroll_bar
->dragging
= Qnil
;
8202 mouse_tracking_in_progress
= mouse_tracking_none
;
8203 tracked_scroll_bar
= NULL
;
8207 part_code
= FindWindow (er
.where
, &window_ptr
);
8212 if (er
.what
== mouseDown
)
8214 struct frame
*f
= ((mac_output
*)
8215 GetWRefCon (FrontWindow ()))->mFP
;
8216 saved_menu_event_location
= er
.where
;
8217 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8218 XSETFRAME (inev
.frame_or_window
, f
);
8223 if (window_ptr
!= FrontWindow ())
8224 SelectWindow (window_ptr
);
8227 SInt16 control_part_code
;
8229 struct mac_output
*mwp
= (mac_output
*)
8230 GetWRefCon (window_ptr
);
8231 Point mouse_loc
= er
.where
;
8233 /* convert to local coordinates of new window */
8234 #if TARGET_API_MAC_CARBON
8235 SetPort (GetWindowPort (window_ptr
));
8237 SetPort (window_ptr
);
8240 GlobalToLocal (&mouse_loc
);
8241 #if TARGET_API_MAC_CARBON
8242 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8243 &control_part_code
);
8245 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
8248 #if USE_CARBON_EVENTS
8249 inev
.code
= mac_get_mouse_btn (eventRef
);
8251 inev
.code
= mac_get_emulate_btn (er
.modifiers
);
8253 XSETINT (inev
.x
, mouse_loc
.h
);
8254 XSETINT (inev
.y
, mouse_loc
.v
);
8255 inev
.timestamp
= er
.when
* (1000 / 60);
8256 /* ticks to milliseconds */
8258 #if TARGET_API_MAC_CARBON
8261 if (control_part_code
!= 0)
8264 struct scroll_bar
*bar
= (struct scroll_bar
*)
8265 GetControlReference (ch
);
8266 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
8268 if (er
.what
== mouseDown
8269 && control_part_code
== kControlIndicatorPart
)
8271 mouse_tracking_in_progress
8272 = mouse_tracking_scroll_bar
;
8273 tracked_scroll_bar
= bar
;
8277 mouse_tracking_in_progress
= mouse_tracking_none
;
8278 tracked_scroll_bar
= NULL
;
8285 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8286 if (er
.what
== mouseDown
)
8287 mouse_tracking_in_progress
8288 = mouse_tracking_mouse_movement
;
8290 mouse_tracking_in_progress
= mouse_tracking_none
;
8291 window
= window_from_coordinates (mwp
->mFP
, inev
.x
, inev
.y
, 0, 0, 0, 1);
8293 if (EQ (window
, mwp
->mFP
->tool_bar_window
))
8295 if (er
.what
== mouseDown
)
8296 handle_tool_bar_click (mwp
->mFP
, inev
.x
, inev
.y
, 1, 0);
8298 handle_tool_bar_click (mwp
->mFP
, inev
.x
, inev
.y
, 0,
8299 #if USE_CARBON_EVENTS
8300 mac_event_to_emacs_modifiers (eventRef
)
8308 inev
.kind
= MOUSE_CLICK_EVENT
;
8311 #if USE_CARBON_EVENTS
8312 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8314 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8320 inev
.modifiers
|= down_modifier
;
8323 inev
.modifiers
|= up_modifier
;
8330 #if TARGET_API_MAC_CARBON
8331 if (er
.what
== mouseDown
)
8335 GetQDGlobalsScreenBits (&bm
);
8336 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
8338 #else /* not TARGET_API_MAC_CARBON */
8339 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8340 #endif /* not TARGET_API_MAC_CARBON */
8344 if (TrackGoAway (window_ptr
, er
.where
))
8346 inev
.kind
= DELETE_WINDOW_EVENT
;
8347 XSETFRAME (inev
.frame_or_window
,
8348 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
8352 /* window resize handling added --ben */
8354 if (er
.what
== mouseDown
)
8356 do_grow_window(window_ptr
, &er
);
8360 /* window zoom handling added --ben */
8363 if (TrackBox (window_ptr
, er
.where
, part_code
))
8364 do_zoom_window (window_ptr
, part_code
);
8376 #if USE_CARBON_EVENTS
8377 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
8385 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8388 #if USE_CARBON_EVENTS
8389 /* When using Carbon Events, we need to pass raw keyboard events
8390 to the TSM ourselves. If TSM handles it, it will pass back
8391 noErr, otherwise it will pass back "eventNotHandledErr" and
8392 we can process it normally. */
8393 if ((!NILP (Vmac_pass_command_to_system
)
8394 || !(er
.modifiers
& cmdKey
))
8395 && (!NILP (Vmac_pass_control_to_system
)
8396 || !(er
.modifiers
& controlKey
)))
8399 err
= SendEventToEventTarget (eventRef
,
8400 GetEventDispatcherTarget ());
8401 if (err
!= eventNotHandledErr
)
8406 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
8415 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8417 inev
.code
= 0xff00 | xkeysym
;
8418 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8422 if (er
.modifiers
& (controlKey
|
8423 (NILP (Vmac_command_key_is_meta
) ? optionKey
8426 /* This code comes from Keyboard Resource, Appendix
8427 C of IM - Text. This is necessary since shift is
8428 ignored in KCHR table translation when option or
8429 command is pressed. It also does not translate
8430 correctly control-shift chars like C-% so mask off
8432 int new_modifiers
= er
.modifiers
& 0xe600;
8433 /* mask off option and command */
8434 int new_keycode
= keycode
| new_modifiers
;
8435 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8436 unsigned long some_state
= 0;
8437 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8438 &some_state
) & 0xff;
8441 inev
.code
= er
.message
& charCodeMask
;
8442 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8446 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
8447 convert non-ASCII characters typed at the Mac keyboard
8448 (presumed to be in the Mac Roman encoding) to iso-latin-1
8449 encoding before they are passed to Emacs. This enables the
8450 Mac keyboard to be used to enter non-ASCII iso-latin-1
8451 characters directly. */
8452 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8453 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8455 static TECObjectRef converter
= NULL
;
8456 OSStatus the_err
= noErr
;
8457 OSStatus convert_status
= noErr
;
8459 if (converter
== NULL
)
8461 the_err
= TECCreateConverter (&converter
,
8462 kTextEncodingMacRoman
,
8463 mac_keyboard_text_encoding
);
8464 current_mac_keyboard_text_encoding
8465 = mac_keyboard_text_encoding
;
8467 else if (mac_keyboard_text_encoding
8468 != current_mac_keyboard_text_encoding
)
8470 /* Free the converter for the current encoding before
8471 creating a new one. */
8472 TECDisposeConverter (converter
);
8473 the_err
= TECCreateConverter (&converter
,
8474 kTextEncodingMacRoman
,
8475 mac_keyboard_text_encoding
);
8476 current_mac_keyboard_text_encoding
8477 = mac_keyboard_text_encoding
;
8480 if (the_err
== noErr
)
8482 unsigned char ch
= inev
.code
;
8483 ByteCount actual_input_length
, actual_output_length
;
8484 unsigned char outch
;
8486 convert_status
= TECConvertText (converter
, &ch
, 1,
8487 &actual_input_length
,
8489 &actual_output_length
);
8490 if (convert_status
== noErr
8491 && actual_input_length
== 1
8492 && actual_output_length
== 1)
8497 #if USE_CARBON_EVENTS
8498 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8500 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8505 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8506 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8509 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8512 case kHighLevelEvent
:
8513 drag_and_drop_file_list
= Qnil
;
8515 AEProcessAppleEvent(&er
);
8517 /* Build a DRAG_N_DROP_EVENT type event as is done in
8518 constuct_drag_n_drop in w32term.c. */
8519 if (!NILP (drag_and_drop_file_list
))
8521 struct frame
*f
= NULL
;
8525 wp
= FrontNonFloatingWindow ();
8529 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8530 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8531 wp
= FrontNonFloatingWindow ();
8534 if (wp
&& is_emacs_window(wp
))
8535 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8537 inev
.kind
= DRAG_N_DROP_EVENT
;
8539 inev
.timestamp
= er
.when
* (1000 / 60);
8540 /* ticks to milliseconds */
8541 #if USE_CARBON_EVENTS
8542 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8544 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8547 XSETINT (inev
.x
, 0);
8548 XSETINT (inev
.y
, 0);
8550 XSETFRAME (frame
, f
);
8551 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8553 /* Regardless of whether Emacs was suspended or in the
8554 foreground, ask it to redraw its entire screen.
8555 Otherwise parts of the screen can be left in an
8556 inconsistent state. */
8558 #if TARGET_API_MAC_CARBON
8562 GetWindowPortBounds (wp
, &r
);
8563 InvalWindowRect (wp
, &r
);
8565 #else /* not TARGET_API_MAC_CARBON */
8566 InvalRect (&(wp
->portRect
));
8567 #endif /* not TARGET_API_MAC_CARBON */
8572 #if USE_CARBON_EVENTS
8573 ReleaseEvent (eventRef
);
8577 /* If the focus was just given to an autoraising frame,
8579 /* ??? This ought to be able to handle more than one such frame. */
8580 if (pending_autoraise_frame
)
8582 x_raise_frame (pending_autoraise_frame
);
8583 pending_autoraise_frame
= 0;
8586 #if !TARGET_API_MAC_CARBON
8587 check_alarm (); /* simulate the handling of a SIGALRM */
8591 static Point old_mouse_pos
= { -1, -1 };
8593 if (app_is_suspended
)
8595 old_mouse_pos
.h
= -1;
8596 old_mouse_pos
.v
= -1;
8604 struct scroll_bar
*sb
;
8606 wp
= FrontWindow ();
8607 if (is_emacs_window (wp
))
8609 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8611 #if TARGET_API_MAC_CARBON
8612 SetPort (GetWindowPort (wp
));
8617 GetMouse (&mouse_pos
);
8619 if (!EqualPt (mouse_pos
, old_mouse_pos
))
8621 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8622 && tracked_scroll_bar
)
8623 x_scroll_bar_note_movement (tracked_scroll_bar
,
8625 - XINT (tracked_scroll_bar
->top
),
8626 TickCount() * (1000 / 60));
8628 note_mouse_movement (f
, &mouse_pos
);
8630 old_mouse_pos
= mouse_pos
;
8636 if (inev
.kind
!= NO_EVENT
)
8638 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8647 /* Need to override CodeWarrior's input function so no conversion is
8648 done on newlines Otherwise compiled functions in .elc files will be
8649 read incorrectly. Defined in ...:MSL C:MSL
8650 Common:Source:buffer_io.c. */
8653 __convert_to_newlines (unsigned char * p
, size_t * n
)
8659 __convert_from_newlines (unsigned char * p
, size_t * n
)
8666 /* Initialize the struct pointed to by MW to represent a new COLS x
8667 ROWS Macintosh window, using font with name FONTNAME and size
8670 NewMacWindow (FRAME_PTR fp
)
8673 #if TARGET_API_MAC_CARBON
8674 static int making_terminal_window
= 0;
8676 static int making_terminal_window
= 1;
8679 mwp
= fp
->output_data
.mac
;
8681 if (making_terminal_window
)
8683 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8686 making_terminal_window
= 0;
8689 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8692 SetWRefCon (mwp
->mWP
, (long) mwp
);
8693 /* so that update events can find this mac_output struct */
8694 mwp
->mFP
= fp
; /* point back to emacs frame */
8696 #if TARGET_API_MAC_CARBON
8697 SetPort (GetWindowPort (mwp
->mWP
));
8704 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8705 ShowWindow (mwp
->mWP
);
8711 make_mac_frame (struct frame
*f
)
8713 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8717 f
->output_data
.mac
->cursor_pixel
= 0;
8718 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8719 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8720 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8722 FRAME_FONTSET (f
) = -1;
8723 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8724 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8725 f
->output_data
.mac
->explicit_parent
= 0;
8728 f
->border_width
= 0;
8730 f
->internal_border_width
= 0;
8732 f
->output_method
= output_mac
;
8737 f
->new_text_cols
= 0;
8738 f
->new_text_lines
= 0;
8742 make_mac_terminal_frame (struct frame
*f
)
8746 XSETFRAME (frame
, f
);
8748 f
->output_method
= output_mac
;
8749 f
->output_data
.mac
= (struct mac_output
*)
8750 xmalloc (sizeof (struct mac_output
));
8751 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8752 FRAME_FONTSET (f
) = -1;
8753 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8754 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8756 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8758 FRAME_COLS (f
) = 96;
8759 FRAME_LINES (f
) = 4;
8761 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8762 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8768 /* Need to be initialized for unshow_buffer in window.c. */
8769 selected_window
= f
->selected_window
;
8771 Fmodify_frame_parameters (frame
,
8772 Fcons (Fcons (Qfont
,
8773 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8774 Fmodify_frame_parameters (frame
,
8775 Fcons (Fcons (Qforeground_color
,
8776 build_string ("black")), Qnil
));
8777 Fmodify_frame_parameters (frame
,
8778 Fcons (Fcons (Qbackground_color
,
8779 build_string ("white")), Qnil
));
8783 /***********************************************************************
8785 ***********************************************************************/
8787 int mac_initialized
= 0;
8790 mac_initialize_display_info ()
8792 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8793 GDHandle main_device_handle
;
8795 bzero (dpyinfo
, sizeof (*dpyinfo
));
8797 /* Put it on x_display_name_list. */
8798 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8799 x_display_name_list
);
8800 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8803 dpyinfo
->mac_id_name
8804 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8805 + SCHARS (Vsystem_name
)
8807 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8808 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8810 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8811 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8814 main_device_handle
= LMGetMainDevice();
8816 dpyinfo
->reference_count
= 0;
8817 dpyinfo
->resx
= 75.0;
8818 dpyinfo
->resy
= 75.0;
8819 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
8820 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8821 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
8822 gdDevType
, dpyinfo
->color_p
))
8824 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8825 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8826 dpyinfo
->grabbed
= 0;
8827 dpyinfo
->root_window
= NULL
;
8828 dpyinfo
->image_cache
= make_image_cache ();
8830 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8831 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8832 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8833 dpyinfo
->mouse_face_window
= Qnil
;
8836 struct mac_display_info
*
8837 mac_term_init (display_name
, xrm_option
, resource_name
)
8838 Lisp_Object display_name
;
8840 char *resource_name
;
8842 struct mac_display_info
*dpyinfo
;
8843 GDHandle main_device_handle
;
8845 if (!mac_initialized
)
8848 mac_initialized
= 1;
8851 mac_initialize_display_info (display_name
);
8853 dpyinfo
= &one_mac_display_info
;
8855 main_device_handle
= LMGetMainDevice();
8857 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8858 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8867 extern int inhibit_window_system
;
8868 extern int noninteractive
;
8869 CFBundleRef appsBundle
;
8872 /* No need to test if already -nw*/
8873 if (inhibit_window_system
|| noninteractive
)
8876 appsBundle
= CFBundleGetMainBundle();
8877 if (appsBundle
!= NULL
)
8879 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
8880 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
8881 /* We found the bundle identifier, now we know we are valid. */
8888 /* MAC_TODO: Have this start the bundled executable */
8890 /* For now, prevent the fatal error by bringing it up in the terminal */
8891 inhibit_window_system
= 1;
8895 MakeMeTheFrontProcess ()
8897 ProcessSerialNumber psn
;
8900 err
= GetCurrentProcess (&psn
);
8902 (void) SetFrontProcess (&psn
);
8905 /***** Code to handle C-g testing *****/
8907 /* Contains the Mac modifier formed from quit_char */
8908 static mac_quit_char_modifiers
= 0;
8909 static mac_quit_char_keycode
;
8910 extern int quit_char
;
8913 mac_determine_quit_char_modifiers()
8915 /* Todo: Determine modifiers from quit_char. */
8916 UInt32 qc_modifiers
= ctrl_modifier
;
8919 mac_quit_char_modifiers
= 0;
8920 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
8921 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
8922 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
8923 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
8927 init_quit_char_handler ()
8929 /* TODO: Let this support keys other the 'g' */
8930 mac_quit_char_keycode
= 5;
8931 /* Look at <architecture/adb_kb_map.h> for details */
8932 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
8934 mac_determine_quit_char_modifiers();
8938 quit_char_comp (EventRef inEvent
, void *inCompData
)
8940 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
8942 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
8946 UInt32 keyModifiers
;
8947 GetEventParameter(inEvent
, kEventParamKeyCode
,
8948 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
8949 if (keyCode
!= mac_quit_char_keycode
)
8951 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
8952 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
8953 if (keyModifiers
!= mac_quit_char_modifiers
)
8960 mac_check_for_quit_char ()
8963 static EMACS_TIME last_check_time
= { 0, 0 };
8964 static EMACS_TIME one_second
= { 1, 0 };
8967 /* If windows are not initialized, return immediately (keep it bouncin'). */
8968 if (!mac_quit_char_modifiers
)
8971 /* Don't check if last check is less than a second ago. */
8972 EMACS_GET_TIME (now
);
8973 EMACS_SUB_TIME (t
, now
, last_check_time
);
8974 if (EMACS_TIME_LT (t
, one_second
))
8976 last_check_time
= now
;
8978 /* Redetermine modifiers because they are based on lisp variables */
8979 mac_determine_quit_char_modifiers ();
8981 /* Fill the queue with events */
8982 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
8983 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
8987 struct input_event e
;
8988 struct mac_output
*mwp
=
8989 (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8990 /* Use an input_event to emulate what the interrupt handler does. */
8992 e
.kind
= ASCII_KEYSTROKE_EVENT
;
8996 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
8997 XSETFRAME (e
.frame_or_window
, mwp
->mFP
);
8998 /* Remove event from queue to prevent looping. */
8999 RemoveEventFromQueue (GetMainEventQueue (), event
);
9000 ReleaseEvent (event
);
9001 kbd_buffer_store_event (&e
);
9005 #endif /* MAC_OSX */
9007 /* Set up use of X before we make the first connection. */
9009 extern frame_parm_handler mac_frame_parm_handlers
[];
9011 static struct redisplay_interface x_redisplay_interface
=
9013 mac_frame_parm_handlers
,
9017 x_clear_end_of_line
,
9019 x_after_update_window_line
,
9020 x_update_window_begin
,
9021 x_update_window_end
,
9025 x_clear_window_mouse_face
,
9026 x_get_glyph_overhangs
,
9027 x_fix_overlapping_area
,
9028 x_draw_fringe_bitmap
,
9029 0, /* define_fringe_bitmap */
9030 0, /* destroy_fringe_bitmap */
9031 mac_per_char_metric
,
9033 NULL
, /* mac_compute_glyph_string_overhangs */
9034 x_draw_glyph_string
,
9035 mac_define_frame_cursor
,
9036 mac_clear_frame_area
,
9037 mac_draw_window_cursor
,
9038 mac_draw_vertical_window_border
,
9039 mac_shift_glyphs_for_insert
9045 rif
= &x_redisplay_interface
;
9047 clear_frame_hook
= x_clear_frame
;
9048 ins_del_lines_hook
= x_ins_del_lines
;
9049 delete_glyphs_hook
= x_delete_glyphs
;
9050 ring_bell_hook
= XTring_bell
;
9051 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9052 set_terminal_modes_hook
= XTset_terminal_modes
;
9053 update_begin_hook
= x_update_begin
;
9054 update_end_hook
= x_update_end
;
9055 set_terminal_window_hook
= XTset_terminal_window
;
9056 read_socket_hook
= XTread_socket
;
9057 frame_up_to_date_hook
= XTframe_up_to_date
;
9058 mouse_position_hook
= XTmouse_position
;
9059 frame_rehighlight_hook
= XTframe_rehighlight
;
9060 frame_raise_lower_hook
= XTframe_raise_lower
;
9062 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9063 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9064 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9065 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9067 scroll_region_ok
= 1; /* we'll scroll partial frames */
9068 char_ins_del_ok
= 1;
9069 line_ins_del_ok
= 1; /* we'll just blt 'em */
9070 fast_clear_end_of_line
= 1; /* X does this well */
9071 memory_below_frame
= 0; /* we don't remember what scrolls
9076 last_tool_bar_item
= -1;
9077 any_help_event_p
= 0;
9079 /* Try to use interrupt input; if we can't, then start polling. */
9080 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9082 #ifdef USE_X_TOOLKIT
9083 XtToolkitInitialize ();
9084 Xt_app_con
= XtCreateApplicationContext ();
9085 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9087 /* Install an asynchronous timer that processes Xt timeout events
9088 every 0.1s. This is necessary because some widget sets use
9089 timeouts internally, for example the LessTif menu bar, or the
9090 Xaw3d scroll bar. When Xt timouts aren't processed, these
9091 widgets don't behave normally. */
9093 EMACS_TIME interval
;
9094 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9095 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9099 #if USE_TOOLKIT_SCROLL_BARS
9100 xaw3d_arrow_scroll
= False
;
9101 xaw3d_pick_top
= True
;
9105 /* Note that there is no real way portable across R3/R4 to get the
9106 original error handler. */
9107 XSetErrorHandler (x_error_handler
);
9108 XSetIOErrorHandler (x_io_error_quitter
);
9110 /* Disable Window Change signals; they are handled by X events. */
9112 signal (SIGWINCH
, SIG_DFL
);
9113 #endif /* ! defined (SIGWINCH) */
9115 signal (SIGPIPE
, x_connection_signal
);
9118 mac_initialize_display_info ();
9120 #if TARGET_API_MAC_CARBON
9121 init_required_apple_events ();
9123 init_mac_drag_n_drop ();
9125 #if USE_CARBON_EVENTS
9126 init_service_handler ();
9128 init_quit_char_handler ();
9131 DisableMenuCommand (NULL
, kHICommandQuit
);
9133 if (!inhibit_window_system
)
9134 MakeMeTheFrontProcess ();
9143 staticpro (&x_error_message_string
);
9144 x_error_message_string
= Qnil
;
9147 Fprovide (intern ("mac-carbon"), Qnil
);
9149 staticpro (&Qreverse
);
9150 Qreverse
= intern ("reverse");
9152 staticpro (&x_display_name_list
);
9153 x_display_name_list
= Qnil
;
9155 staticpro (&last_mouse_scroll_bar
);
9156 last_mouse_scroll_bar
= Qnil
;
9158 staticpro (&Qvendor_specific_keysyms
);
9159 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9161 staticpro (&last_mouse_press_frame
);
9162 last_mouse_press_frame
= Qnil
;
9164 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9165 staticpro (&Qmac_ready_for_drag_n_drop
);
9167 Qbig5
= intern ("big5");
9170 Qcn_gb
= intern ("cn-gb");
9171 staticpro (&Qcn_gb
);
9173 Qsjis
= intern ("sjis");
9176 Qeuc_kr
= intern ("euc-kr");
9177 staticpro (&Qeuc_kr
);
9179 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9180 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9181 x_autoselect_window_p
= 0;
9183 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9184 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9185 Vx_toolkit_scroll_bars
= Qt
;
9187 DEFVAR_BOOL ("x-use-underline-position-properties",
9188 &x_use_underline_position_properties
,
9189 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9190 nil means ignore them. If you encounter fonts with bogus
9191 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9192 to 4.1, set this to nil. */);
9193 x_use_underline_position_properties
= 0;
9195 staticpro (&last_mouse_motion_frame
);
9196 last_mouse_motion_frame
= Qnil
;
9198 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9199 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9200 Otherwise the option key is used. */);
9201 Vmac_command_key_is_meta
= Qt
;
9203 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9204 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9205 useful for non-standard keyboard layouts. */);
9206 Vmac_reverse_ctrl_meta
= Qnil
;
9208 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9209 &Vmac_emulate_three_button_mouse
,
9210 doc
: /* t means that when the option-key is held down while pressing the
9211 mouse button, the click will register as mouse-2 and while the
9212 command-key is held down, the click will register as mouse-3.
9213 'reverse means that the the option-key will register for mouse-3
9214 and the command-key will register for mouse-2. nil means that
9215 not emulation should be done and the modifiers should be placed
9216 on the mouse-1 event. */);
9217 Vmac_emulate_three_button_mouse
= Qnil
;
9219 #if USE_CARBON_EVENTS
9220 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9221 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9222 the right click will be mouse-3.
9223 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9224 Vmac_wheel_button_is_mouse_2
= Qt
;
9226 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9227 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9228 Toolbox for processing before Emacs sees it. */);
9229 Vmac_pass_command_to_system
= Qt
;
9231 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9232 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9233 Toolbox for processing before Emacs sees it. */);
9234 Vmac_pass_control_to_system
= Qt
;
9237 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9238 doc
: /* One of the Text Encoding Base constant values defined in the
9239 Basic Text Constants section of Inside Macintosh - Text Encoding
9240 Conversion Manager. Its value determines the encoding characters
9241 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9242 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9243 its default value, no conversion takes place. If it is set to
9244 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9245 characters typed on Mac keyboard are first converted into the
9246 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9247 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9248 command, this enables the Mac keyboard to be used to enter non-ASCII
9249 characters directly. */);
9250 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9253 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9254 (do not change this comment) */