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 extern int image_ascent (struct image
*, struct face
*);
298 int x_bitmap_icon (struct frame
*, Lisp_Object
);
299 void x_make_frame_visible (struct frame
*);
301 extern void window_scroll (Lisp_Object
, int, int, int);
303 /* Defined in macmenu.h. */
304 extern void menubar_selection_callback (FRAME_PTR
, int);
305 extern void set_frame_menubar (FRAME_PTR
, int, int);
307 /* X display function emulation */
310 XFreePixmap (display
, pixmap
)
311 Display
*display
; /* not used */
314 DisposeGWorld (pixmap
);
318 /* Set foreground color for subsequent QuickDraw commands. Assume
319 graphic port has already been set. */
322 mac_set_forecolor (unsigned long color
)
326 fg_color
.red
= RED16_FROM_ULONG (color
);
327 fg_color
.green
= GREEN16_FROM_ULONG (color
);
328 fg_color
.blue
= BLUE16_FROM_ULONG (color
);
330 RGBForeColor (&fg_color
);
334 /* Set background color for subsequent QuickDraw commands. Assume
335 graphic port has already been set. */
338 mac_set_backcolor (unsigned long color
)
342 bg_color
.red
= RED16_FROM_ULONG (color
);
343 bg_color
.green
= GREEN16_FROM_ULONG (color
);
344 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
346 RGBBackColor (&bg_color
);
349 /* Set foreground and background color for subsequent QuickDraw
350 commands. Assume that the graphic port has already been set. */
353 mac_set_colors (GC gc
)
355 mac_set_forecolor (gc
->foreground
);
356 mac_set_backcolor (gc
->background
);
359 /* Mac version of XDrawLine. */
362 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
368 #if TARGET_API_MAC_CARBON
369 SetPort (GetWindowPort (w
));
381 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
391 LockPixels (GetGWorldPixMap (p
));
394 UnlockPixels (GetGWorldPixMap (p
));
397 /* Mac version of XClearArea. */
400 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
404 unsigned int width
, height
;
407 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
411 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
412 xgc
.background
= mwp
->x_compatible
.background_pixel
;
414 #if TARGET_API_MAC_CARBON
415 SetPort (GetWindowPort (w
));
420 mac_set_colors (&xgc
);
421 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
426 /* Mac version of XClearWindow. */
429 XClearWindow (display
, w
)
433 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
436 xgc
.foreground
= mwp
->x_compatible
.foreground_pixel
;
437 xgc
.background
= mwp
->x_compatible
.background_pixel
;
439 #if TARGET_API_MAC_CARBON
440 SetPort (GetWindowPort (w
));
445 mac_set_colors (&xgc
);
447 #if TARGET_API_MAC_CARBON
451 GetWindowPortBounds (w
, &r
);
454 #else /* not TARGET_API_MAC_CARBON */
455 EraseRect (&(w
->portRect
));
456 #endif /* not TARGET_API_MAC_CARBON */
460 /* Mac replacement for XCopyArea. */
463 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
467 int x
, y
, width
, height
;
468 unsigned short *bits
;
474 bitmap
.rowBytes
= sizeof(unsigned short);
475 bitmap
.baseAddr
= (char *)bits
;
476 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
478 #if TARGET_API_MAC_CARBON
479 SetPort (GetWindowPort (w
));
485 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
487 #if TARGET_API_MAC_CARBON
488 LockPortBits (GetWindowPort (w
));
489 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
490 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
491 UnlockPortBits (GetWindowPort (w
));
492 #else /* not TARGET_API_MAC_CARBON */
493 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
494 overlay_p
? srcOr
: srcCopy
, 0);
495 #endif /* not TARGET_API_MAC_CARBON */
499 /* Mac replacement for XSetClipRectangles. */
502 mac_set_clip_rectangle (display
, w
, r
)
507 #if TARGET_API_MAC_CARBON
508 SetPort (GetWindowPort (w
));
517 /* Mac replacement for XSetClipMask. */
520 mac_reset_clipping (display
, w
)
526 #if TARGET_API_MAC_CARBON
527 SetPort (GetWindowPort (w
));
532 SetRect (&r
, -32767, -32767, 32767, 32767);
537 /* XBM bits seem to be backward within bytes compared with how
544 unsigned char reflected
= 0x00;
545 for (i
= 0; i
< 8; i
++)
547 if (orig
& (0x01 << i
))
548 reflected
|= 0x80 >> i
;
554 /* Mac replacement for XCreateBitmapFromBitmapData. */
557 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
565 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
566 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
567 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
568 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
569 for (i
= 0; i
< h
; i
++)
571 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
572 for (j
= 0; j
< w1
; j
++)
573 *p
++ = reflect_byte (*bits
++);
576 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
581 mac_free_bitmap (bitmap
)
584 xfree (bitmap
->baseAddr
);
589 XCreatePixmap (display
, w
, width
, height
, depth
)
590 Display
*display
; /* not used */
592 unsigned int width
, height
;
593 unsigned int depth
; /* not used */
599 #if TARGET_API_MAC_CARBON
600 SetPort (GetWindowPort (w
));
605 SetRect (&r
, 0, 0, width
, height
);
606 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
614 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
615 Display
*display
; /* not used */
618 unsigned int width
, height
;
619 unsigned long fg
, bg
;
620 unsigned int depth
; /* not used */
625 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
629 SetGWorld (pixmap
, NULL
);
630 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
631 mac_set_forecolor (fg
);
632 mac_set_backcolor (bg
);
633 LockPixels (GetGWorldPixMap (pixmap
));
634 #if TARGET_API_MAC_CARBON
635 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
636 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
637 #else /* not TARGET_API_MAC_CARBON */
638 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
639 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
640 #endif /* not TARGET_API_MAC_CARBON */
641 UnlockPixels (GetGWorldPixMap (pixmap
));
642 mac_free_bitmap (&bitmap
);
648 /* Mac replacement for XFillRectangle. */
651 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
656 unsigned int width
, height
;
660 #if TARGET_API_MAC_CARBON
661 SetPort (GetWindowPort (w
));
667 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
669 PaintRect (&r
); /* using foreground color of gc */
674 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
679 unsigned int width
, height
;
685 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
687 LockPixels (GetGWorldPixMap (p
));
688 PaintRect (&r
); /* using foreground color of gc */
689 UnlockPixels (GetGWorldPixMap (p
));
693 /* Mac replacement for XDrawRectangle: dest is a window. */
696 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
701 unsigned int width
, height
;
705 #if TARGET_API_MAC_CARBON
706 SetPort (GetWindowPort (w
));
712 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
714 FrameRect (&r
); /* using foreground color of gc */
718 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
721 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
726 unsigned int width
, height
;
732 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
734 LockPixels (GetGWorldPixMap (p
));
735 FrameRect (&r
); /* using foreground color of gc */
736 UnlockPixels (GetGWorldPixMap (p
));
741 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
748 int nchars
, mode
, bytes_per_char
;
750 #if TARGET_API_MAC_CARBON
751 SetPort (GetWindowPort (w
));
758 TextFont (gc
->font
->mac_fontnum
);
759 TextSize (gc
->font
->mac_fontsize
);
760 TextFace (gc
->font
->mac_fontface
);
764 DrawText (buf
, 0, nchars
* bytes_per_char
);
768 /* Mac replacement for XDrawString. */
771 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
779 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
783 /* Mac replacement for XDrawString16. */
786 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
794 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
799 /* Mac replacement for XDrawImageString. */
802 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
810 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
814 /* Mac replacement for XDrawString16. */
817 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
825 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
830 /* Mac replacement for XCopyArea: dest must be window. */
833 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
840 unsigned int width
, height
;
845 #if TARGET_API_MAC_CARBON
846 SetPort (GetWindowPort (dest
));
851 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
852 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
854 ForeColor (blackColor
);
855 BackColor (whiteColor
);
857 LockPixels (GetGWorldPixMap (src
));
858 #if TARGET_API_MAC_CARBON
859 LockPortBits (GetWindowPort (dest
));
860 CopyBits (GetPortBitMapForCopyBits (src
),
861 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
862 &src_r
, &dest_r
, srcCopy
, 0);
863 UnlockPortBits (GetWindowPort (dest
));
864 #else /* not TARGET_API_MAC_CARBON */
865 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
866 &src_r
, &dest_r
, srcCopy
, 0);
867 #endif /* not TARGET_API_MAC_CARBON */
868 UnlockPixels (GetGWorldPixMap (src
));
873 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
874 width
, height
, dest_x
, dest_y
)
880 unsigned int width
, height
;
885 #if TARGET_API_MAC_CARBON
886 SetPort (GetWindowPort (dest
));
891 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
892 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
894 ForeColor (blackColor
);
895 BackColor (whiteColor
);
897 LockPixels (GetGWorldPixMap (src
));
898 LockPixels (GetGWorldPixMap (mask
));
899 #if TARGET_API_MAC_CARBON
900 LockPortBits (GetWindowPort (dest
));
901 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
902 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
903 &src_r
, &src_r
, &dest_r
);
904 UnlockPortBits (GetWindowPort (dest
));
905 #else /* not TARGET_API_MAC_CARBON */
906 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
907 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
908 #endif /* not TARGET_API_MAC_CARBON */
909 UnlockPixels (GetGWorldPixMap (mask
));
910 UnlockPixels (GetGWorldPixMap (src
));
915 /* Convert a pair of local coordinates to global (screen) coordinates.
916 Assume graphic port has been properly set. */
918 local_to_global_coord (short *h
, short *v
)
932 /* Mac replacement for XCopyArea: used only for scrolling. */
935 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
940 unsigned int width
, height
;
943 #if TARGET_API_MAC_CARBON
944 Rect gw_r
, src_r
, dest_r
;
946 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
947 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
949 SetPort (GetWindowPort (w
));
951 ForeColor (blackColor
);
952 BackColor (whiteColor
);
954 LockPortBits (GetWindowPort (w
));
956 const BitMap
*bitmap
= GetPortBitMapForCopyBits (GetWindowPort (w
));
957 CopyBits (bitmap
, bitmap
, &src_r
, &dest_r
, srcCopy
, 0);
959 UnlockPortBits (GetWindowPort (w
));
962 #else /* not TARGET_API_MAC_CARBON */
970 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
971 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
974 /* Need to use global coordinates and screenBits since src and dest
975 areas overlap in general. */
976 local_to_global_coord (&src_r
.left
, &src_r
.top
);
977 local_to_global_coord (&src_r
.right
, &src_r
.bottom
);
978 local_to_global_coord (&dest_r
.left
, &dest_r
.top
);
979 local_to_global_coord (&dest_r
.right
, &dest_r
.bottom
);
981 CopyBits (&qd
.screenBits
, &qd
.screenBits
, &src_r
, &dest_r
, srcCopy
, 0);
983 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
984 color mapping in CopyBits. Otherwise, it will be slow. */
985 ForeColor (blackColor
);
986 BackColor (whiteColor
);
987 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
991 #endif /* not TARGET_API_MAC_CARBON */
995 /* Mac replacement for XCopyArea: dest must be Pixmap. */
998 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1004 unsigned int width
, height
;
1009 SetGWorld (dest
, NULL
);
1010 ForeColor (blackColor
);
1011 BackColor (whiteColor
);
1013 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1014 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1016 LockPixels (GetGWorldPixMap (src
));
1017 LockPixels (GetGWorldPixMap (dest
));
1018 #if TARGET_API_MAC_CARBON
1019 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
1020 &src_r
, &dest_r
, srcCopy
, 0);
1021 #else /* not TARGET_API_MAC_CARBON */
1022 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
1023 &src_r
, &dest_r
, srcCopy
, 0);
1024 #endif /* not TARGET_API_MAC_CARBON */
1025 UnlockPixels (GetGWorldPixMap (dest
));
1026 UnlockPixels (GetGWorldPixMap (src
));
1031 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
1032 width
, height
, dest_x
, dest_y
)
1034 Pixmap src
, mask
, dest
;
1037 unsigned int width
, height
;
1042 SetGWorld (dest
, NULL
);
1043 ForeColor (blackColor
);
1044 BackColor (whiteColor
);
1046 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1047 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1049 LockPixels (GetGWorldPixMap (src
));
1050 LockPixels (GetGWorldPixMap (mask
));
1051 LockPixels (GetGWorldPixMap (dest
));
1052 #if TARGET_API_MAC_CARBON
1053 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1054 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1055 #else /* not TARGET_API_MAC_CARBON */
1056 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1057 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1058 #endif /* not TARGET_API_MAC_CARBON */
1059 UnlockPixels (GetGWorldPixMap (dest
));
1060 UnlockPixels (GetGWorldPixMap (mask
));
1061 UnlockPixels (GetGWorldPixMap (src
));
1065 /* Mac replacement for XChangeGC. */
1068 XChangeGC (void * ignore
, XGCValues
* gc
, unsigned long mask
,
1071 if (mask
& GCForeground
)
1072 gc
->foreground
= xgcv
->foreground
;
1073 if (mask
& GCBackground
)
1074 gc
->background
= xgcv
->background
;
1076 gc
->font
= xgcv
->font
;
1080 /* Mac replacement for XCreateGC. */
1083 XCreateGC (void * ignore
, Window window
, unsigned long mask
,
1086 XGCValues
*gc
= (XGCValues
*) xmalloc (sizeof (XGCValues
));
1087 bzero (gc
, sizeof (XGCValues
));
1089 XChangeGC (ignore
, gc
, mask
, xgcv
);
1095 /* Used in xfaces.c. */
1098 XFreeGC (display
, gc
)
1106 /* Mac replacement for XGetGCValues. */
1109 XGetGCValues (void* ignore
, XGCValues
*gc
,
1110 unsigned long mask
, XGCValues
*xgcv
)
1112 XChangeGC (ignore
, xgcv
, mask
, gc
);
1116 /* Mac replacement for XSetForeground. */
1119 XSetForeground (display
, gc
, color
)
1122 unsigned long color
;
1124 gc
->foreground
= color
;
1128 /* Mac replacement for XSetFont. */
1131 XSetFont (display
, gc
, font
)
1141 XTextExtents16 (XFontStruct
*font
, XChar2b
*text
, int nchars
,
1142 int *direction
,int *font_ascent
,
1143 int *font_descent
, XCharStruct
*cs
)
1145 /* MAC_TODO: Use GetTextMetrics to do this and inline it below. */
1149 /* x_sync is a no-op on Mac. */
1157 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1158 Calls to XFlush should be unnecessary because the X output buffer
1159 is flushed automatically as needed by calls to XPending,
1160 XNextEvent, or XWindowEvent according to the XFlush man page.
1161 XTread_socket calls XPending. Removing XFlush improves
1164 #if TARGET_API_MAC_CARBON
1165 #define XFlush(DISPLAY) QDFlushPortBuffer (GetQDGlobalsThePort (), NULL)
1167 #define XFlush(DISPLAY) (void) 0
1170 /* Flush display of frame F, or of all frames if F is null. */
1176 #if TARGET_API_MAC_CARBON
1180 Lisp_Object rest
, frame
;
1181 FOR_EACH_FRAME (rest
, frame
)
1182 x_flush (XFRAME (frame
));
1184 else if (FRAME_X_P (f
))
1185 XFlush (FRAME_MAC_DISPLAY (f
));
1187 #endif /* TARGET_API_MAC_CARBON */
1192 /* Return the struct mac_display_info corresponding to DPY. There's
1195 struct mac_display_info
*
1196 mac_display_info_for_display (dpy
)
1199 return &one_mac_display_info
;
1204 /***********************************************************************
1205 Starting and ending an update
1206 ***********************************************************************/
1208 /* Start an update of frame F. This function is installed as a hook
1209 for update_begin, i.e. it is called when update_begin is called.
1210 This function is called prior to calls to x_update_window_begin for
1211 each window being updated. */
1217 /* Nothing to do. */
1221 /* Start update of window W. Set the global variable updated_window
1222 to the window being updated and set output_cursor to the cursor
1226 x_update_window_begin (w
)
1229 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1230 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1233 set_output_cursor (&w
->cursor
);
1237 if (f
== display_info
->mouse_face_mouse_frame
)
1239 /* Don't do highlighting for mouse motion during the update. */
1240 display_info
->mouse_face_defer
= 1;
1242 /* If F needs to be redrawn, simply forget about any prior mouse
1244 if (FRAME_GARBAGED_P (f
))
1245 display_info
->mouse_face_window
= Qnil
;
1247 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1248 their mouse_face_p flag set, which means that they are always
1249 unequal to rows in a desired matrix which never have that
1250 flag set. So, rows containing mouse-face glyphs are never
1251 scrolled, and we don't have to switch the mouse highlight off
1252 here to prevent it from being scrolled. */
1254 /* Can we tell that this update does not affect the window
1255 where the mouse highlight is? If so, no need to turn off.
1256 Likewise, don't do anything if the frame is garbaged;
1257 in that case, the frame's current matrix that we would use
1258 is all wrong, and we will redisplay that line anyway. */
1259 if (!NILP (display_info
->mouse_face_window
)
1260 && w
== XWINDOW (display_info
->mouse_face_window
))
1264 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1265 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1268 if (i
< w
->desired_matrix
->nrows
)
1269 clear_mouse_face (display_info
);
1278 /* Draw a vertical window border from (x,y0) to (x,y1) */
1281 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1285 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1287 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1288 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1292 /* End update of window W (which is equal to updated_window).
1294 Draw vertical borders between horizontally adjacent windows, and
1295 display W's cursor if CURSOR_ON_P is non-zero.
1297 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1298 glyphs in mouse-face were overwritten. In that case we have to
1299 make sure that the mouse-highlight is properly redrawn.
1301 W may be a menu bar pseudo-window in case we don't have X toolkit
1302 support. Such windows don't have a cursor, so don't display it
1306 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1308 int cursor_on_p
, mouse_face_overwritten_p
;
1310 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1312 if (!w
->pseudo_window_p
)
1317 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1319 output_cursor
.x
, output_cursor
.y
);
1321 x_draw_vertical_border (w
);
1323 draw_window_fringes (w
);
1328 /* If a row with mouse-face was overwritten, arrange for
1329 XTframe_up_to_date to redisplay the mouse highlight. */
1330 if (mouse_face_overwritten_p
)
1332 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1333 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1334 dpyinfo
->mouse_face_window
= Qnil
;
1338 /* Unhide the caret. This won't actually show the cursor, unless it
1339 was visible before the corresponding call to HideCaret in
1340 x_update_window_begin. */
1341 if (w32_use_visible_system_caret
)
1342 SendMessage (w32_system_caret_hwnd
, WM_EMACS_SHOW_CARET
, 0, 0);
1345 updated_window
= NULL
;
1349 /* End update of frame F. This function is installed as a hook in
1356 /* Reset the background color of Mac OS Window to that of the frame after
1357 update so that it is used by Mac Toolbox to clear the update region before
1358 an update event is generated. */
1359 #if TARGET_API_MAC_CARBON
1360 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
1362 SetPort (FRAME_MAC_WINDOW (f
));
1365 mac_set_backcolor (FRAME_BACKGROUND_PIXEL (f
));
1367 /* Mouse highlight may be displayed again. */
1368 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1371 XFlush (FRAME_MAC_DISPLAY (f
));
1376 /* This function is called from various places in xdisp.c whenever a
1377 complete update has been performed. The global variable
1378 updated_window is not available here. */
1381 XTframe_up_to_date (f
)
1386 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1388 if (dpyinfo
->mouse_face_deferred_gc
1389 || f
== dpyinfo
->mouse_face_mouse_frame
)
1392 if (dpyinfo
->mouse_face_mouse_frame
)
1393 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1394 dpyinfo
->mouse_face_mouse_x
,
1395 dpyinfo
->mouse_face_mouse_y
);
1396 dpyinfo
->mouse_face_deferred_gc
= 0;
1403 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1404 arrow bitmaps, or clear the fringes if no bitmaps are required
1405 before DESIRED_ROW is made current. The window being updated is
1406 found in updated_window. This function is called from
1407 update_window_line only if it is known that there are differences
1408 between bitmaps to be drawn between current row and DESIRED_ROW. */
1411 x_after_update_window_line (desired_row
)
1412 struct glyph_row
*desired_row
;
1414 struct window
*w
= updated_window
;
1420 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1421 desired_row
->redraw_fringe_bitmaps_p
= 1;
1423 /* When a window has disappeared, make sure that no rest of
1424 full-width rows stays visible in the internal border. Could
1425 check here if updated_window is the leftmost/rightmost window,
1426 but I guess it's not worth doing since vertically split windows
1427 are almost never used, internal border is rarely set, and the
1428 overhead is very small. */
1429 if (windows_or_buffers_changed
1430 && desired_row
->full_width_p
1431 && (f
= XFRAME (w
->frame
),
1432 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1434 && (height
= desired_row
->visible_height
,
1437 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1438 /* Internal border is drawn below the tool bar. */
1439 if (WINDOWP (f
->tool_bar_window
)
1440 && w
== XWINDOW (f
->tool_bar_window
))
1445 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1446 0, y
, width
, height
, 0);
1447 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1448 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1456 /* Draw the bitmap WHICH in one of the left or right fringes of
1457 window W. ROW is the glyph row for which to display the bitmap; it
1458 determines the vertical position at which the bitmap has to be
1462 x_draw_fringe_bitmap (w
, row
, p
)
1464 struct glyph_row
*row
;
1465 struct draw_fringe_bitmap_params
*p
;
1467 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1468 Display
*display
= FRAME_MAC_DISPLAY (f
);
1469 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1471 GC gc
= f
->output_data
.mac
->normal_gc
;
1472 struct face
*face
= p
->face
;
1475 /* Must clip because of partially visible lines. */
1476 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1479 /* Adjust position of "bottom aligned" bitmap on partially
1480 visible last row. */
1482 int oldVH
= row
->visible_height
;
1483 row
->visible_height
= p
->h
;
1484 row
->y
-= rowY
- p
->y
;
1485 x_clip_to_row (w
, row
, gc
);
1487 row
->visible_height
= oldVH
;
1490 x_clip_to_row (w
, row
, gc
);
1492 if (p
->bx
>= 0 && !p
->overlay_p
)
1495 gcv
.foreground
= face
->background
;
1497 #if 0 /* MAC_TODO: stipple */
1498 /* In case the same realized face is used for fringes and
1499 for something displayed in the text (e.g. face `region' on
1500 mono-displays, the fill style may have been changed to
1501 FillSolid in x_draw_glyph_string_background. */
1503 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1505 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1508 XFillRectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1510 p
->bx
, p
->by
, p
->nx
, p
->ny
);
1512 #if 0 /* MAC_TODO: stipple */
1514 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1520 unsigned short *bits
= p
->bits
+ p
->dh
;
1522 gcv
.foreground
= (p
->cursor_p
1523 ? (p
->overlay_p
? face
->background
1524 : f
->output_data
.mac
->cursor_pixel
)
1525 : face
->foreground
);
1526 gcv
.background
= face
->background
;
1528 mac_draw_bitmap (display
, window
, &gcv
, p
->x
, p
->y
,
1529 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1532 mac_reset_clipping (display
, window
);
1536 /* This is called when starting Emacs and when restarting after
1537 suspend. When starting Emacs, no window is mapped. And nothing
1538 must be done to Emacs's own window if it is suspended (though that
1542 XTset_terminal_modes ()
1546 /* This is called when exiting or suspending Emacs. Exiting will make
1547 the windows go away, and suspending requires no action. */
1550 XTreset_terminal_modes ()
1555 /***********************************************************************
1557 ***********************************************************************/
1559 /* Function prototypes of this page. */
1561 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1562 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1565 /* Return a pointer to per-char metric information in FONT of a
1566 character pointed by B which is a pointer to an XChar2b. */
1568 #define PER_CHAR_METRIC(font, b) \
1570 ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
1571 + (((font)->min_byte1 || (font)->max_byte1) \
1572 ? (((b)->byte1 - (font)->min_byte1) \
1573 * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
1575 : &((font)->max_bounds))
1578 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1579 is not contained in the font. */
1581 static INLINE XCharStruct
*
1582 x_per_char_metric (font
, char2b
)
1586 /* The result metric information. */
1587 XCharStruct
*pcm
= NULL
;
1589 xassert (font
&& char2b
);
1591 if (font
->per_char
!= NULL
)
1593 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1595 /* min_char_or_byte2 specifies the linear character index
1596 corresponding to the first element of the per_char array,
1597 max_char_or_byte2 is the index of the last character. A
1598 character with non-zero CHAR2B->byte1 is not in the font.
1599 A character with byte2 less than min_char_or_byte2 or
1600 greater max_char_or_byte2 is not in the font. */
1601 if (char2b
->byte1
== 0
1602 && char2b
->byte2
>= font
->min_char_or_byte2
1603 && char2b
->byte2
<= font
->max_char_or_byte2
)
1604 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1608 /* If either min_byte1 or max_byte1 are nonzero, both
1609 min_char_or_byte2 and max_char_or_byte2 are less than
1610 256, and the 2-byte character index values corresponding
1611 to the per_char array element N (counting from 0) are:
1613 byte1 = N/D + min_byte1
1614 byte2 = N\D + min_char_or_byte2
1618 D = max_char_or_byte2 - min_char_or_byte2 + 1
1619 / = integer division
1620 \ = integer modulus */
1621 if (char2b
->byte1
>= font
->min_byte1
1622 && char2b
->byte1
<= font
->max_byte1
1623 && char2b
->byte2
>= font
->min_char_or_byte2
1624 && char2b
->byte2
<= font
->max_char_or_byte2
)
1626 pcm
= (font
->per_char
1627 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1628 * (char2b
->byte1
- font
->min_byte1
))
1629 + (char2b
->byte2
- font
->min_char_or_byte2
));
1635 /* If the per_char pointer is null, all glyphs between the first
1636 and last character indexes inclusive have the same
1637 information, as given by both min_bounds and max_bounds. */
1638 if (char2b
->byte2
>= font
->min_char_or_byte2
1639 && char2b
->byte2
<= font
->max_char_or_byte2
)
1640 pcm
= &font
->max_bounds
;
1643 return ((pcm
== NULL
1644 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1651 static XCharStruct
*
1652 mac_per_char_metric (font
, char2b
, font_type
)
1657 return x_per_char_metric (font
, char2b
);
1661 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1662 the two-byte form of C. Encoding is returned in *CHAR2B. */
1665 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1668 struct font_info
*font_info
;
1671 int charset
= CHAR_CHARSET (c
);
1672 XFontStruct
*font
= font_info
->font
;
1674 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1675 This may be either a program in a special encoder language or a
1677 if (font_info
->font_encoder
)
1679 /* It's a program. */
1680 struct ccl_program
*ccl
= font_info
->font_encoder
;
1682 if (CHARSET_DIMENSION (charset
) == 1)
1684 ccl
->reg
[0] = charset
;
1685 ccl
->reg
[1] = char2b
->byte2
;
1689 ccl
->reg
[0] = charset
;
1690 ccl
->reg
[1] = char2b
->byte1
;
1691 ccl
->reg
[2] = char2b
->byte2
;
1694 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1696 /* We assume that MSBs are appropriately set/reset by CCL
1698 if (font
->max_byte1
== 0) /* 1-byte font */
1699 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1701 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1703 else if (font_info
->encoding
[charset
])
1705 /* Fixed encoding scheme. See fontset.h for the meaning of the
1706 encoding numbers. */
1707 int enc
= font_info
->encoding
[charset
];
1709 if ((enc
== 1 || enc
== 2)
1710 && CHARSET_DIMENSION (charset
) == 2)
1711 char2b
->byte1
|= 0x80;
1713 if (enc
== 1 || enc
== 3)
1714 char2b
->byte2
|= 0x80;
1720 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1721 char2b
->byte1
= sjis1
;
1722 char2b
->byte2
= sjis2
;
1727 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1729 return FONT_TYPE_UNKNOWN
;
1734 /***********************************************************************
1736 ***********************************************************************/
1739 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1740 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1741 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1743 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1744 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1745 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1746 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1747 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
1748 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
1749 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
1750 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
1751 unsigned long *, double, int));*/
1752 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
1753 double, int, unsigned long));
1754 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
1755 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
1756 static void x_draw_image_relief
P_ ((struct glyph_string
*));
1757 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
1758 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
1759 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
1761 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
1762 int, int, int, int, Rect
*));
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
, left_p
, right_p
, clip_rect
)
2488 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
, raised_p
;
2491 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2492 Window window
= FRAME_MAC_WINDOW (f
);
2497 gc
= f
->output_data
.mac
->white_relief
.gc
;
2499 gc
= f
->output_data
.mac
->black_relief
.gc
;
2500 mac_set_clip_rectangle (dpy
, window
, clip_rect
);
2503 for (i
= 0; i
< width
; ++i
)
2504 XDrawLine (dpy
, window
, gc
,
2505 left_x
+ i
* left_p
, top_y
+ i
,
2506 right_x
- i
* right_p
, top_y
+ i
);
2510 for (i
= 0; i
< width
; ++i
)
2511 XDrawLine (dpy
, window
, gc
,
2512 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2514 mac_reset_clipping (dpy
, window
);
2516 gc
= f
->output_data
.mac
->black_relief
.gc
;
2518 gc
= f
->output_data
.mac
->white_relief
.gc
;
2519 mac_set_clip_rectangle (dpy
, window
,
2523 for (i
= 0; i
< width
; ++i
)
2524 XDrawLine (dpy
, window
, gc
,
2525 left_x
+ i
* left_p
, bottom_y
- i
,
2526 right_x
- i
* right_p
, bottom_y
- i
);
2530 for (i
= 0; i
< width
; ++i
)
2531 XDrawLine (dpy
, window
, gc
,
2532 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2534 mac_reset_clipping (dpy
, window
);
2538 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2539 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2540 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2541 left side of the rectangle. RIGHT_P non-zero means draw a line
2542 on the right side of the rectangle. CLIP_RECT is the clipping
2543 rectangle to use when drawing. */
2546 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2547 left_p
, right_p
, clip_rect
)
2548 struct glyph_string
*s
;
2549 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2554 xgcv
.foreground
= s
->face
->box_color
;
2555 mac_set_clip_rectangle (s
->display
, s
->window
, clip_rect
);
2558 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2559 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2563 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2564 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2567 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2568 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2572 XFillRectangle (s
->display
, s
->window
, &xgcv
,
2573 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2575 mac_reset_clipping (s
->display
, s
->window
);
2579 /* Draw a box around glyph string S. */
2582 x_draw_glyph_string_box (s
)
2583 struct glyph_string
*s
;
2585 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2586 int left_p
, right_p
;
2587 struct glyph
*last_glyph
;
2590 last_x
= window_box_right (s
->w
, s
->area
);
2591 if (s
->row
->full_width_p
2592 && !s
->w
->pseudo_window_p
)
2594 last_x
+= WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s
->w
);
2595 if (s
->area
!= RIGHT_MARGIN_AREA
2596 || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s
->w
))
2597 last_x
+= WINDOW_RIGHT_FRINGE_WIDTH (s
->w
);
2600 /* The glyph that may have a right box line. */
2601 last_glyph
= (s
->cmp
|| s
->img
2603 : s
->first_glyph
+ s
->nchars
- 1);
2605 width
= abs (s
->face
->box_line_width
);
2606 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2608 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2610 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2612 bottom_y
= top_y
+ s
->height
- 1;
2614 left_p
= (s
->first_glyph
->left_box_line_p
2615 || (s
->hl
== DRAW_MOUSE_FACE
2617 || s
->prev
->hl
!= s
->hl
)));
2618 right_p
= (last_glyph
->right_box_line_p
2619 || (s
->hl
== DRAW_MOUSE_FACE
2621 || s
->next
->hl
!= s
->hl
)));
2623 get_glyph_string_clip_rect (s
, &clip_rect
);
2625 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2626 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2627 left_p
, right_p
, &clip_rect
);
2630 x_setup_relief_colors (s
);
2631 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2632 width
, raised_p
, left_p
, right_p
, &clip_rect
);
2637 /* Draw foreground of image glyph string S. */
2640 x_draw_image_foreground (s
)
2641 struct glyph_string
*s
;
2644 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2646 /* If first glyph of S has a left box line, start drawing it to the
2647 right of that line. */
2648 if (s
->face
->box
!= FACE_NO_BOX
2649 && s
->first_glyph
->left_box_line_p
)
2650 x
= s
->x
+ abs (s
->face
->box_line_width
);
2654 /* If there is a margin around the image, adjust x- and y-position
2656 x
+= s
->img
->hmargin
;
2657 y
+= s
->img
->vmargin
;
2664 XRectangle clip_rect
, image_rect
, r
;
2666 get_glyph_string_clip_rect (s
, &nr
);
2667 CONVERT_TO_XRECT (clip_rect
, nr
);
2670 image_rect
.width
= s
->img
->width
;
2671 image_rect
.height
= s
->img
->height
;
2672 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2673 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2674 s
->window
, s
->gc
, r
.x
- x
, r
.y
- y
,
2675 r
.width
, r
.height
, r
.x
, r
.y
);
2680 XRectangle clip_rect
, image_rect
, r
;
2682 get_glyph_string_clip_rect (s
, &nr
);
2683 CONVERT_TO_XRECT (clip_rect
, nr
);
2686 image_rect
.width
= s
->img
->width
;
2687 image_rect
.height
= s
->img
->height
;
2688 if (x_intersect_rectangles (&clip_rect
, &image_rect
, &r
))
2689 mac_copy_area (s
->display
, s
->img
->pixmap
, s
->window
, s
->gc
,
2690 r
.x
- x
, r
.y
- y
, r
.width
, r
.height
, r
.x
, r
.y
);
2692 /* When the image has a mask, we can expect that at
2693 least part of a mouse highlight or a block cursor will
2694 be visible. If the image doesn't have a mask, make
2695 a block cursor visible by drawing a rectangle around
2696 the image. I believe it's looking better if we do
2697 nothing here for mouse-face. */
2698 if (s
->hl
== DRAW_CURSOR
)
2700 int r
= s
->img
->relief
;
2702 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2703 s
->img
->width
+ r
*2 - 1, s
->img
->height
+ r
*2 - 1);
2708 /* Draw a rectangle if image could not be loaded. */
2709 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
2710 s
->img
->width
- 1, s
->img
->height
- 1);
2714 /* Draw a relief around the image glyph string S. */
2717 x_draw_image_relief (s
)
2718 struct glyph_string
*s
;
2720 int x0
, y0
, x1
, y1
, thick
, raised_p
;
2723 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
);
2725 /* If first glyph of S has a left box line, start drawing it to the
2726 right of that line. */
2727 if (s
->face
->box
!= FACE_NO_BOX
2728 && s
->first_glyph
->left_box_line_p
)
2729 x
= s
->x
+ abs (s
->face
->box_line_width
);
2733 /* If there is a margin around the image, adjust x- and y-position
2735 x
+= s
->img
->hmargin
;
2736 y
+= s
->img
->vmargin
;
2738 if (s
->hl
== DRAW_IMAGE_SUNKEN
2739 || s
->hl
== DRAW_IMAGE_RAISED
)
2741 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
2742 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
2746 thick
= abs (s
->img
->relief
);
2747 raised_p
= s
->img
->relief
> 0;
2752 x1
= x
+ s
->img
->width
+ thick
- 1;
2753 y1
= y
+ s
->img
->height
+ thick
- 1;
2755 x_setup_relief_colors (s
);
2756 get_glyph_string_clip_rect (s
, &r
);
2757 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
, 1, 1, &r
);
2761 /* Draw the foreground of image glyph string S to PIXMAP. */
2764 x_draw_image_foreground_1 (s
, pixmap
)
2765 struct glyph_string
*s
;
2769 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
);
2771 /* If first glyph of S has a left box line, start drawing it to the
2772 right of that line. */
2773 if (s
->face
->box
!= FACE_NO_BOX
2774 && s
->first_glyph
->left_box_line_p
)
2775 x
= abs (s
->face
->box_line_width
);
2779 /* If there is a margin around the image, adjust x- and y-position
2781 x
+= s
->img
->hmargin
;
2782 y
+= s
->img
->vmargin
;
2787 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
2788 s
->img
->mask
, pixmap
, s
->gc
,
2789 0, 0, s
->img
->width
, s
->img
->height
,
2793 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
2794 0, 0, s
->img
->width
, s
->img
->height
, x
, y
);
2796 /* When the image has a mask, we can expect that at
2797 least part of a mouse highlight or a block cursor will
2798 be visible. If the image doesn't have a mask, make
2799 a block cursor visible by drawing a rectangle around
2800 the image. I believe it's looking better if we do
2801 nothing here for mouse-face. */
2802 if (s
->hl
== DRAW_CURSOR
)
2804 int r
= s
->img
->relief
;
2806 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
2807 s
->img
->width
+ r
*2 - 1,
2808 s
->img
->height
+ r
*2 - 1);
2813 /* Draw a rectangle if image could not be loaded. */
2814 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
2815 s
->img
->width
- 1, s
->img
->height
- 1);
2819 /* Draw part of the background of glyph string S. X, Y, W, and H
2820 give the rectangle to draw. */
2823 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
2824 struct glyph_string
*s
;
2827 #if 0 /* MAC_TODO: stipple */
2830 /* Fill background with a stipple pattern. */
2831 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2832 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
2833 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2836 #endif /* MAC_TODO */
2837 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
2841 /* Draw image glyph string S.
2844 s->x +-------------------------
2847 | +-------------------------
2850 | | +-------------------
2856 x_draw_image_glyph_string (s
)
2857 struct glyph_string
*s
;
2860 int box_line_hwidth
= abs (s
->face
->box_line_width
);
2861 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
2865 height
= s
->height
- 2 * box_line_vwidth
;
2868 /* Fill background with face under the image. Do it only if row is
2869 taller than image or if image has a clip mask to reduce
2871 s
->stippled_p
= s
->face
->stipple
!= 0;
2872 if (height
> s
->img
->height
2876 || s
->img
->pixmap
== 0
2877 || s
->width
!= s
->background_width
)
2879 if (box_line_hwidth
&& s
->first_glyph
->left_box_line_p
)
2880 x
= s
->x
+ box_line_hwidth
;
2884 y
= s
->y
+ box_line_vwidth
;
2888 /* Create a pixmap as large as the glyph string. Fill it
2889 with the background color. Copy the image to it, using
2890 its mask. Copy the temporary pixmap to the display. */
2891 int depth
= one_mac_display_info
.n_planes
;
2893 /* Create a pixmap as large as the glyph string. */
2894 pixmap
= XCreatePixmap (s
->display
, s
->window
,
2895 s
->background_width
,
2898 /* Fill the pixmap with the background color/stipple. */
2899 #if 0 /* TODO: stipple */
2902 /* Fill background with a stipple pattern. */
2903 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2904 XFillRectangle (s
->display
, pixmap
, s
->gc
,
2905 0, 0, s
->background_width
, s
->height
);
2906 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2912 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
2914 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
2915 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
2916 0, 0, s
->background_width
,
2918 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2922 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
2924 s
->background_filled_p
= 1;
2927 /* Draw the foreground. */
2930 x_draw_image_foreground_1 (s
, pixmap
);
2931 x_set_glyph_string_clipping (s
);
2932 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
2933 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
2934 mac_reset_clipping (s
->display
, s
->window
);
2935 XFreePixmap (s
->display
, pixmap
);
2938 x_draw_image_foreground (s
);
2940 /* If we must draw a relief around the image, do it. */
2942 || s
->hl
== DRAW_IMAGE_RAISED
2943 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2944 x_draw_image_relief (s
);
2948 /* Draw stretch glyph string S. */
2951 x_draw_stretch_glyph_string (s
)
2952 struct glyph_string
*s
;
2954 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
2955 s
->stippled_p
= s
->face
->stipple
!= 0;
2957 if (s
->hl
== DRAW_CURSOR
2958 && !x_stretch_cursor_p
)
2960 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2961 as wide as the stretch glyph. */
2962 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
2965 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
2967 /* Clear rest using the GC of the original non-cursor face. */
2968 if (width
< s
->background_width
)
2970 int x
= s
->x
+ width
, y
= s
->y
;
2971 int w
= s
->background_width
- width
, h
= s
->height
;
2975 if (s
->row
->mouse_face_p
2976 && cursor_in_mouse_face_p (s
->w
))
2978 x_set_mouse_face_gc (s
);
2984 get_glyph_string_clip_rect (s
, &r
);
2985 mac_set_clip_rectangle (s
->display
, s
->window
, &r
);
2987 #if 0 /* MAC_TODO: stipple */
2988 if (s
->face
->stipple
)
2990 /* Fill background with a stipple pattern. */
2991 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
2992 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
2993 XSetFillStyle (s
->display
, gc
, FillSolid
);
2996 #endif /* MAC_TODO */
2999 XGetGCValues (s
->display
, gc
, GCForeground
| GCBackground
, &xgcv
);
3000 XSetForeground (s
->display
, gc
, xgcv
.background
);
3001 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3002 XSetForeground (s
->display
, gc
, xgcv
.foreground
);
3005 mac_reset_clipping (s
->display
, s
->window
);
3008 else if (!s
->background_filled_p
)
3009 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3012 s
->background_filled_p
= 1;
3016 /* Draw glyph string S. */
3019 x_draw_glyph_string (s
)
3020 struct glyph_string
*s
;
3022 int relief_drawn_p
= 0;
3024 /* If S draws into the background of its successor, draw the
3025 background of the successor first so that S can draw into it.
3026 This makes S->next use XDrawString instead of XDrawImageString. */
3027 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps_p
)
3029 xassert (s
->next
->img
== NULL
);
3030 x_set_glyph_string_gc (s
->next
);
3031 x_set_glyph_string_clipping (s
->next
);
3032 x_draw_glyph_string_background (s
->next
, 1);
3035 /* Set up S->gc, set clipping and draw S. */
3036 x_set_glyph_string_gc (s
);
3038 /* Draw relief (if any) in advance for char/composition so that the
3039 glyph string can be drawn over it. */
3040 if (!s
->for_overlaps_p
3041 && s
->face
->box
!= FACE_NO_BOX
3042 && (s
->first_glyph
->type
== CHAR_GLYPH
3043 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3046 x_set_glyph_string_clipping (s
);
3047 x_draw_glyph_string_background (s
, 1);
3048 x_draw_glyph_string_box (s
);
3049 x_set_glyph_string_clipping (s
);
3053 x_set_glyph_string_clipping (s
);
3055 switch (s
->first_glyph
->type
)
3058 x_draw_image_glyph_string (s
);
3062 x_draw_stretch_glyph_string (s
);
3066 if (s
->for_overlaps_p
)
3067 s
->background_filled_p
= 1;
3069 x_draw_glyph_string_background (s
, 0);
3070 x_draw_glyph_string_foreground (s
);
3073 case COMPOSITE_GLYPH
:
3074 if (s
->for_overlaps_p
|| s
->gidx
> 0)
3075 s
->background_filled_p
= 1;
3077 x_draw_glyph_string_background (s
, 1);
3078 x_draw_composite_glyph_string_foreground (s
);
3085 if (!s
->for_overlaps_p
)
3087 /* Draw underline. */
3088 if (s
->face
->underline_p
)
3090 unsigned long h
= 1;
3091 unsigned long dy
= s
->height
- h
;
3093 if (s
->face
->underline_defaulted_p
)
3094 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3099 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3100 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3101 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3103 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3107 /* Draw overline. */
3108 if (s
->face
->overline_p
)
3110 unsigned long dy
= 0, h
= 1;
3112 if (s
->face
->overline_color_defaulted_p
)
3113 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3118 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3119 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3120 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3122 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3126 /* Draw strike-through. */
3127 if (s
->face
->strike_through_p
)
3129 unsigned long h
= 1;
3130 unsigned long dy
= (s
->height
- h
) / 2;
3132 if (s
->face
->strike_through_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
->strike_through_color
);
3140 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3142 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3146 /* Draw relief if not yet drawn. */
3147 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3148 x_draw_glyph_string_box (s
);
3151 /* Reset clipping. */
3152 mac_reset_clipping (s
->display
, s
->window
);
3155 /* Shift display to make room for inserted glyphs. */
3158 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3160 int x
, y
, width
, height
, shift_by
;
3162 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3163 f
->output_data
.mac
->normal_gc
,
3164 x
, y
, width
, height
,
3168 /* Delete N glyphs at the nominal cursor position. Not implemented
3179 /* Clear entire frame. If updating_frame is non-null, clear that
3180 frame. Otherwise clear the selected frame. */
3190 f
= SELECTED_FRAME ();
3192 /* Clearing the frame will erase any cursor, so mark them all as no
3194 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3195 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3196 output_cursor
.x
= -1;
3198 /* We don't set the output cursor here because there will always
3199 follow an explicit cursor_to. */
3201 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3203 #if 0 /* Clearing frame on Mac OS clears scroll bars. */
3204 /* We have to clear the scroll bars, too. If we have changed
3205 colors or something like that, then they should be notified. */
3206 x_scroll_bar_clear (f
);
3209 XFlush (FRAME_MAC_DISPLAY (f
));
3215 /* Invert the middle quarter of the frame for .15 sec. */
3217 /* We use the select system call to do the waiting, so we have to make
3218 sure it's available. If it isn't, we just won't do visual bells. */
3220 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3223 /* Subtract the `struct timeval' values X and Y, storing the result in
3224 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3227 timeval_subtract (result
, x
, y
)
3228 struct timeval
*result
, x
, y
;
3230 /* Perform the carry for the later subtraction by updating y. This
3231 is safer because on some systems the tv_sec member is unsigned. */
3232 if (x
.tv_usec
< y
.tv_usec
)
3234 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3235 y
.tv_usec
-= 1000000 * nsec
;
3239 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3241 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3242 y
.tv_usec
+= 1000000 * nsec
;
3246 /* Compute the time remaining to wait. tv_usec is certainly
3248 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3249 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3251 /* Return indication of whether the result should be considered
3253 return x
.tv_sec
< y
.tv_sec
;
3265 struct timeval wakeup
;
3267 EMACS_GET_TIME (wakeup
);
3269 /* Compute time to wait until, propagating carry from usecs. */
3270 wakeup
.tv_usec
+= 150000;
3271 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3272 wakeup
.tv_usec
%= 1000000;
3274 /* Keep waiting until past the time wakeup. */
3277 struct timeval timeout
;
3279 EMACS_GET_TIME (timeout
);
3281 /* In effect, timeout = wakeup - timeout.
3282 Break if result would be negative. */
3283 if (timeval_subtract (&timeout
, wakeup
, timeout
))
3286 /* Try to wait that long--but we might wake up sooner. */
3287 select (0, NULL
, NULL
, NULL
, &timeout
);
3296 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3299 /* Make audible bell. */
3304 struct frame
*f
= SELECTED_FRAME ();
3306 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3314 XFlush (FRAME_MAC_DISPLAY (f
));
3321 /* Specify how many text lines, from the top of the window,
3322 should be affected by insert-lines and delete-lines operations.
3323 This, and those operations, are used only within an update
3324 that is bounded by calls to x_update_begin and x_update_end. */
3327 XTset_terminal_window (n
)
3330 /* This function intentionally left blank. */
3335 /***********************************************************************
3337 ***********************************************************************/
3339 /* Perform an insert-lines or delete-lines operation, inserting N
3340 lines or deleting -N lines at vertical position VPOS. */
3343 x_ins_del_lines (vpos
, n
)
3350 /* Scroll part of the display as described by RUN. */
3353 x_scroll_run (w
, run
)
3357 struct frame
*f
= XFRAME (w
->frame
);
3358 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3360 /* Get frame-relative bounding box of the text display area of W,
3361 without mode lines. Include in this box the left and right
3363 window_box (w
, -1, &x
, &y
, &width
, &height
);
3365 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3366 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3367 bottom_y
= y
+ height
;
3371 /* Scrolling up. Make sure we don't copy part of the mode
3372 line at the bottom. */
3373 if (from_y
+ run
->height
> bottom_y
)
3374 height
= bottom_y
- from_y
;
3376 height
= run
->height
;
3380 /* Scolling down. Make sure we don't copy over the mode line.
3382 if (to_y
+ run
->height
> bottom_y
)
3383 height
= bottom_y
- to_y
;
3385 height
= run
->height
;
3390 /* Cursor off. Will be switched on again in x_update_window_end. */
3394 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3395 f
->output_data
.mac
->normal_gc
,
3405 /***********************************************************************
3407 ***********************************************************************/
3414 x_update_cursor (f
, 1);
3418 frame_unhighlight (f
)
3421 x_update_cursor (f
, 1);
3424 /* The focus has changed. Update the frames as necessary to reflect
3425 the new situation. Note that we can't change the selected frame
3426 here, because the Lisp code we are interrupting might become confused.
3427 Each event gets marked with the frame in which it occurred, so the
3428 Lisp code can tell when the switch took place by examining the events. */
3431 x_new_focus_frame (dpyinfo
, frame
)
3432 struct x_display_info
*dpyinfo
;
3433 struct frame
*frame
;
3435 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3437 if (frame
!= dpyinfo
->x_focus_frame
)
3439 /* Set this before calling other routines, so that they see
3440 the correct value of x_focus_frame. */
3441 dpyinfo
->x_focus_frame
= frame
;
3443 if (old_focus
&& old_focus
->auto_lower
)
3444 x_lower_frame (old_focus
);
3447 selected_frame
= frame
;
3448 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3450 Fselect_window (selected_frame
->selected_window
, Qnil
);
3451 choose_minibuf_frame ();
3454 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3455 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3457 pending_autoraise_frame
= 0;
3460 x_frame_rehighlight (dpyinfo
);
3463 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3466 x_mouse_leave (dpyinfo
)
3467 struct x_display_info
*dpyinfo
;
3469 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3472 /* The focus has changed, or we have redirected a frame's focus to
3473 another frame (this happens when a frame uses a surrogate
3474 mini-buffer frame). Shift the highlight as appropriate.
3476 The FRAME argument doesn't necessarily have anything to do with which
3477 frame is being highlighted or un-highlighted; we only use it to find
3478 the appropriate X display info. */
3481 XTframe_rehighlight (frame
)
3482 struct frame
*frame
;
3484 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3488 x_frame_rehighlight (dpyinfo
)
3489 struct x_display_info
*dpyinfo
;
3491 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3493 if (dpyinfo
->x_focus_frame
)
3495 dpyinfo
->x_highlight_frame
3496 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3497 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3498 : dpyinfo
->x_focus_frame
);
3499 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3501 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3502 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3506 dpyinfo
->x_highlight_frame
= 0;
3508 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3511 frame_unhighlight (old_highlight
);
3512 if (dpyinfo
->x_highlight_frame
)
3513 frame_highlight (dpyinfo
->x_highlight_frame
);
3519 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3521 #if 0 /* MAC_TODO */
3522 /* Initialize mode_switch_bit and modifier_meaning. */
3524 x_find_modifier_meanings (dpyinfo
)
3525 struct x_display_info
*dpyinfo
;
3527 int min_code
, max_code
;
3530 XModifierKeymap
*mods
;
3532 dpyinfo
->meta_mod_mask
= 0;
3533 dpyinfo
->shift_lock_mask
= 0;
3534 dpyinfo
->alt_mod_mask
= 0;
3535 dpyinfo
->super_mod_mask
= 0;
3536 dpyinfo
->hyper_mod_mask
= 0;
3539 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
3541 min_code
= dpyinfo
->display
->min_keycode
;
3542 max_code
= dpyinfo
->display
->max_keycode
;
3545 syms
= XGetKeyboardMapping (dpyinfo
->display
,
3546 min_code
, max_code
- min_code
+ 1,
3548 mods
= XGetModifierMapping (dpyinfo
->display
);
3550 /* Scan the modifier table to see which modifier bits the Meta and
3551 Alt keysyms are on. */
3553 int row
, col
; /* The row and column in the modifier table. */
3555 for (row
= 3; row
< 8; row
++)
3556 for (col
= 0; col
< mods
->max_keypermod
; col
++)
3559 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
3561 /* Zeroes are used for filler. Skip them. */
3565 /* Are any of this keycode's keysyms a meta key? */
3569 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
3571 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
3577 dpyinfo
->meta_mod_mask
|= (1 << row
);
3582 dpyinfo
->alt_mod_mask
|= (1 << row
);
3587 dpyinfo
->hyper_mod_mask
|= (1 << row
);
3592 dpyinfo
->super_mod_mask
|= (1 << row
);
3596 /* Ignore this if it's not on the lock modifier. */
3597 if ((1 << row
) == LockMask
)
3598 dpyinfo
->shift_lock_mask
= LockMask
;
3606 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
3607 if (! dpyinfo
->meta_mod_mask
)
3609 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
3610 dpyinfo
->alt_mod_mask
= 0;
3613 /* If some keys are both alt and meta,
3614 make them just meta, not alt. */
3615 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
3617 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
3620 XFree ((char *) syms
);
3621 XFreeModifiermap (mods
);
3624 #endif /* MAC_TODO */
3626 /* Convert between the modifier bits X uses and the modifier bits
3630 x_mac_to_emacs_modifiers (dpyinfo
, state
)
3631 struct x_display_info
*dpyinfo
;
3632 unsigned short state
;
3634 return (((state
& shiftKey
) ? shift_modifier
: 0)
3635 | ((state
& controlKey
) ? ctrl_modifier
: 0)
3636 | ((state
& cmdKey
) ? meta_modifier
: 0)
3637 | ((state
& optionKey
) ? alt_modifier
: 0));
3640 #if 0 /* MAC_TODO */
3641 static unsigned short
3642 x_emacs_to_x_modifiers (dpyinfo
, state
)
3643 struct x_display_info
*dpyinfo
;
3646 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
3647 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
3648 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
3649 | ((state
& shift_modifier
) ? ShiftMask
: 0)
3650 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
3651 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
3653 #endif /* MAC_TODO */
3655 /* Convert a keysym to its name. */
3658 x_get_keysym_name (keysym
)
3665 value
= XKeysymToString (keysym
);
3676 /* Mouse clicks and mouse movement. Rah. */
3678 /* Prepare a mouse-event in *RESULT for placement in the input queue.
3680 If the event is a button press, then note that we have grabbed
3684 construct_mouse_click (result
, event
, f
)
3685 struct input_event
*result
;
3691 result
->kind
= MOUSE_CLICK_EVENT
;
3692 result
->code
= 0; /* only one mouse button */
3693 result
->timestamp
= event
->when
;
3694 result
->modifiers
= event
->what
== mouseDown
? down_modifier
: up_modifier
;
3696 mouseLoc
= event
->where
;
3698 #if TARGET_API_MAC_CARBON
3699 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
3701 SetPort (FRAME_MAC_WINDOW (f
));
3704 GlobalToLocal (&mouseLoc
);
3705 XSETINT (result
->x
, mouseLoc
.h
);
3706 XSETINT (result
->y
, mouseLoc
.v
);
3708 XSETFRAME (result
->frame_or_window
, f
);
3715 /* Function to report a mouse movement to the mainstream Emacs code.
3716 The input handler calls this.
3718 We have received a mouse movement event, which is given in *event.
3719 If the mouse is over a different glyph than it was last time, tell
3720 the mainstream emacs code by setting mouse_moved. If not, ask for
3721 another motion event, so we can check again the next time it moves. */
3723 static Point last_mouse_motion_position
;
3724 static Lisp_Object last_mouse_motion_frame
;
3727 note_mouse_movement (frame
, pos
)
3731 #if TARGET_API_MAC_CARBON
3735 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
3736 last_mouse_motion_position
= *pos
;
3737 XSETFRAME (last_mouse_motion_frame
, frame
);
3739 #if TARGET_API_MAC_CARBON
3740 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
3742 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
3745 frame
->mouse_moved
= 1;
3746 last_mouse_scroll_bar
= Qnil
;
3747 note_mouse_highlight (frame
, -1, -1);
3749 /* Has the mouse moved off the glyph it was on at the last sighting? */
3750 else if (pos
->h
< last_mouse_glyph
.left
3751 || pos
->h
>= last_mouse_glyph
.right
3752 || pos
->v
< last_mouse_glyph
.top
3753 || pos
->v
>= last_mouse_glyph
.bottom
)
3755 frame
->mouse_moved
= 1;
3756 last_mouse_scroll_bar
= Qnil
;
3757 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
3761 /* This is used for debugging, to turn off note_mouse_highlight. */
3763 int disable_mouse_highlight
;
3767 /************************************************************************
3769 ************************************************************************/
3771 static struct scroll_bar
*x_window_to_scroll_bar ();
3772 static void x_scroll_bar_report_motion ();
3773 static void x_check_fullscreen
P_ ((struct frame
*));
3774 static void x_check_fullscreen_move
P_ ((struct frame
*));
3775 static int glyph_rect
P_ ((struct frame
*f
, int, int, Rect
*));
3778 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3781 redo_mouse_highlight ()
3783 if (!NILP (last_mouse_motion_frame
)
3784 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
3785 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
3786 last_mouse_motion_position
.h
,
3787 last_mouse_motion_position
.v
);
3791 /* Try to determine frame pixel position and size of the glyph under
3792 frame pixel coordinates X/Y on frame F . Return the position and
3793 size in *RECT. Value is non-zero if we could compute these
3797 glyph_rect (f
, x
, y
, rect
)
3804 window
= window_from_coordinates (f
, x
, y
, 0, &x
, &y
, 0);
3808 struct window
*w
= XWINDOW (window
);
3809 struct glyph_row
*r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
3810 struct glyph_row
*end
= r
+ w
->current_matrix
->nrows
- 1;
3812 for (; r
< end
&& r
->enabled_p
; ++r
)
3813 if (r
->y
<= y
&& r
->y
+ r
->height
> y
)
3815 /* Found the row at y. */
3816 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
3817 struct glyph
*end
= g
+ r
->used
[TEXT_AREA
];
3820 rect
->top
= WINDOW_TO_FRAME_PIXEL_Y (w
, r
->y
);
3821 rect
->bottom
= rect
->top
+ r
->height
;
3825 /* x is to the left of the first glyph in the row. */
3826 /* Shouldn't this be a pixel value?
3827 WINDOW_LEFT_EDGE_X (w) seems to be the right value.
3829 rect
->left
= WINDOW_LEFT_EDGE_COL (w
);
3830 rect
->right
= WINDOW_TO_FRAME_PIXEL_X (w
, r
->x
);
3834 for (gx
= r
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
3835 if (gx
<= x
&& gx
+ g
->pixel_width
> x
)
3837 /* x is on a glyph. */
3838 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3839 rect
->right
= rect
->left
+ g
->pixel_width
;
3843 /* x is to the right of the last glyph in the row. */
3844 rect
->left
= WINDOW_TO_FRAME_PIXEL_X (w
, gx
);
3845 /* Shouldn't this be a pixel value?
3846 WINDOW_RIGHT_EDGE_X (w) seems to be the right value.
3848 rect
->right
= WINDOW_RIGHT_EDGE_COL (w
);
3853 /* The y is not on any row. */
3857 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
3859 /* Record the position of the mouse in last_mouse_glyph. */
3861 remember_mouse_glyph (f1
, gx
, gy
)
3865 if (!glyph_rect (f1
, gx
, gy
, &last_mouse_glyph
))
3867 int width
= FRAME_SMALLEST_CHAR_WIDTH (f1
);
3868 int height
= FRAME_SMALLEST_FONT_HEIGHT (f1
);
3870 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
3871 round down even for negative values. */
3877 /* This was the original code from XTmouse_position, but it seems
3878 to give the position of the glyph diagonally next to the one
3879 the mouse is over. */
3880 gx
= (gx
+ width
- 1) / width
* width
;
3881 gy
= (gy
+ height
- 1) / height
* height
;
3883 gx
= gx
/ width
* width
;
3884 gy
= gy
/ height
* height
;
3887 last_mouse_glyph
.left
= gx
;
3888 last_mouse_glyph
.top
= gy
;
3889 last_mouse_glyph
.right
= gx
+ width
;
3890 last_mouse_glyph
.bottom
= gy
+ height
;
3895 /* Return the current position of the mouse.
3896 *fp should be a frame which indicates which display to ask about.
3898 If the mouse movement started in a scroll bar, set *fp, *bar_window,
3899 and *part to the frame, window, and scroll bar part that the mouse
3900 is over. Set *x and *y to the portion and whole of the mouse's
3901 position on the scroll bar.
3903 If the mouse movement started elsewhere, set *fp to the frame the
3904 mouse is on, *bar_window to nil, and *x and *y to the character cell
3907 Set *time to the server time-stamp for the time at which the mouse
3908 was at this position.
3910 Don't store anything if we don't have a valid set of values to report.
3912 This clears the mouse_moved flag, so we can wait for the next mouse
3916 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
3919 Lisp_Object
*bar_window
;
3920 enum scroll_bar_part
*part
;
3922 unsigned long *time
;
3925 int ignore1
, ignore2
;
3926 WindowPtr wp
= FrontWindow ();
3928 Lisp_Object frame
, tail
;
3930 if (is_emacs_window(wp
))
3931 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
3935 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
3936 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
3939 /* Clear the mouse-moved flag for every frame on this display. */
3940 FOR_EACH_FRAME (tail
, frame
)
3941 XFRAME (frame
)->mouse_moved
= 0;
3943 last_mouse_scroll_bar
= Qnil
;
3945 #if TARGET_API_MAC_CARBON
3946 SetPort (GetWindowPort (wp
));
3951 GetMouse (&mouse_pos
);
3953 pixel_to_glyph_coords (f
, mouse_pos
.h
, mouse_pos
.v
, &ignore1
, &ignore2
,
3954 &last_mouse_glyph
, insist
);
3957 *part
= scroll_bar_handle
;
3959 XSETINT (*x
, mouse_pos
.h
);
3960 XSETINT (*y
, mouse_pos
.v
);
3961 *time
= last_mouse_movement_time
;
3968 /***********************************************************************
3970 ***********************************************************************/
3972 /* Handle mouse button event on the tool-bar of frame F, at
3973 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
3977 mac_handle_tool_bar_click (f
, button_event
)
3979 EventRecord
*button_event
;
3981 int x
= button_event
->where
.h
;
3982 int y
= button_event
->where
.v
;
3984 if (button_event
->what
== mouseDown
)
3985 handle_tool_bar_click (f
, x
, y
, 1, 0);
3987 handle_tool_bar_click (f
, x
, y
, 0,
3988 x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f
),
3989 button_event
->modifiers
));
3993 /************************************************************************
3994 Scroll bars, general
3995 ************************************************************************/
3997 /* Create a scroll bar and return the scroll bar vector for it. W is
3998 the Emacs window on which to create the scroll bar. TOP, LEFT,
3999 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4002 static struct scroll_bar
*
4003 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4005 int top
, left
, width
, height
, disp_top
, disp_height
;
4007 struct frame
*f
= XFRAME (w
->frame
);
4008 struct scroll_bar
*bar
4009 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4017 r
.right
= left
+ width
;
4018 r
.bottom
= disp_top
+ disp_height
;
4020 #ifdef TARGET_API_MAC_CARBON
4021 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0,
4022 kControlScrollBarProc
, 0L);
4024 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", 1, 0, 0, 0, scrollBarProc
,
4027 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4028 SetControlReference (ch
, (long) bar
);
4030 XSETWINDOW (bar
->window
, w
);
4031 XSETINT (bar
->top
, top
);
4032 XSETINT (bar
->left
, left
);
4033 XSETINT (bar
->width
, width
);
4034 XSETINT (bar
->height
, height
);
4035 XSETINT (bar
->start
, 0);
4036 XSETINT (bar
->end
, 0);
4037 bar
->dragging
= Qnil
;
4039 /* Add bar to its frame's list of scroll bars. */
4040 bar
->next
= FRAME_SCROLL_BARS (f
);
4042 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4043 if (!NILP (bar
->next
))
4044 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4051 /* Draw BAR's handle in the proper position.
4053 If the handle is already drawn from START to END, don't bother
4054 redrawing it, unless REBUILD is non-zero; in that case, always
4055 redraw it. (REBUILD is handy for drawing the handle after expose
4058 Normally, we want to constrain the start and end of the handle to
4059 fit inside its rectangle, but if the user is dragging the scroll
4060 bar handle, we want to let them drag it down all the way, so that
4061 the bar's top is as far down as it goes; otherwise, there's no way
4062 to move to the very end of the buffer. */
4065 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4066 struct scroll_bar
*bar
;
4070 int dragging
= ! NILP (bar
->dragging
);
4071 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4072 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4073 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4074 int length
= end
- start
;
4076 /* If the display is already accurate, do nothing. */
4078 && start
== XINT (bar
->start
)
4079 && end
== XINT (bar
->end
))
4084 /* Make sure the values are reasonable, and try to preserve the
4085 distance between start and end. */
4088 else if (start
> top_range
)
4090 end
= start
+ length
;
4094 else if (end
> top_range
&& ! dragging
)
4097 /* Store the adjusted setting in the scroll bar. */
4098 XSETINT (bar
->start
, start
);
4099 XSETINT (bar
->end
, end
);
4101 /* Clip the end position, just for display. */
4102 if (end
> top_range
)
4105 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4106 top positions, to make sure the handle is always at least that
4107 many pixels tall. */
4108 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4110 SetControlMinimum (ch
, 0);
4111 /* Don't inadvertently activate deactivated scroll bars */
4112 if (GetControlMaximum (ch
) != -1)
4113 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4115 SetControlValue (ch
, start
);
4116 #if TARGET_API_MAC_CARBON
4117 SetControlViewSize (ch
, end
- start
);
4124 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4128 x_scroll_bar_remove (bar
)
4129 struct scroll_bar
*bar
;
4131 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4135 /* Destroy the Mac scroll bar control */
4136 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4138 /* Disassociate this scroll bar from its window. */
4139 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4144 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4145 that we are displaying PORTION characters out of a total of WHOLE
4146 characters, starting at POSITION. If WINDOW has no scroll bar,
4149 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4151 int portion
, whole
, position
;
4153 struct frame
*f
= XFRAME (w
->frame
);
4154 struct scroll_bar
*bar
;
4155 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4156 int window_y
, window_height
;
4158 /* Get window dimensions. */
4159 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4164 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4166 height
= window_height
;
4168 /* Compute the left edge of the scroll bar area. */
4169 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4171 /* Compute the width of the scroll bar which might be less than
4172 the width of the area reserved for the scroll bar. */
4173 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4174 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4178 /* Compute the left edge of the scroll bar. */
4179 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4180 sb_left
= left
+ width
- sb_width
- (width
- sb_width
) / 2;
4182 sb_left
= left
+ (width
- sb_width
) / 2;
4184 /* Adjustments according to Inside Macintosh to make it look nice */
4186 disp_height
= height
;
4192 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4198 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4201 /* Does the scroll bar exist yet? */
4202 if (NILP (w
->vertical_scroll_bar
))
4205 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4206 left
, top
, width
, height
, 0);
4208 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4210 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4214 /* It may just need to be moved and resized. */
4217 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4218 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4222 /* If already correctly positioned, do nothing. */
4223 if (XINT (bar
->left
) == sb_left
4224 && XINT (bar
->top
) == top
4225 && XINT (bar
->width
) == sb_width
4226 && XINT (bar
->height
) == height
)
4230 /* Clear areas not covered by the scroll bar because it's not as
4231 wide as the area reserved for it . This makes sure a
4232 previous mode line display is cleared after C-x 2 C-x 1, for
4234 int area_width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
4235 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4236 left
, top
, area_width
, height
, 0);
4239 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4240 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4241 sb_left
- 1, top
, 1, height
, 0);
4245 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4246 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4250 /* Remember new settings. */
4251 XSETINT (bar
->left
, sb_left
);
4252 XSETINT (bar
->top
, top
);
4253 XSETINT (bar
->width
, sb_width
);
4254 XSETINT (bar
->height
, height
);
4260 /* Set the scroll bar's current state, unless we're currently being
4262 if (NILP (bar
->dragging
))
4264 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4267 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4270 int start
= ((double) position
* top_range
) / whole
;
4271 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4272 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4278 /* The following three hooks are used when we're doing a thorough
4279 redisplay of the frame. We don't explicitly know which scroll bars
4280 are going to be deleted, because keeping track of when windows go
4281 away is a real pain - "Can you say set-window-configuration, boys
4282 and girls?" Instead, we just assert at the beginning of redisplay
4283 that *all* scroll bars are to be removed, and then save a scroll bar
4284 from the fiery pit when we actually redisplay its window. */
4286 /* Arrange for all scroll bars on FRAME to be removed at the next call
4287 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4288 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4291 XTcondemn_scroll_bars (frame
)
4294 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4295 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4298 bar
= FRAME_SCROLL_BARS (frame
);
4299 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4300 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4301 XSCROLL_BAR (bar
)->prev
= Qnil
;
4302 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4303 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4304 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4309 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4310 Note that WINDOW isn't necessarily condemned at all. */
4313 XTredeem_scroll_bar (window
)
4314 struct window
*window
;
4316 struct scroll_bar
*bar
;
4318 /* We can't redeem this window's scroll bar if it doesn't have one. */
4319 if (NILP (window
->vertical_scroll_bar
))
4322 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4324 /* Unlink it from the condemned list. */
4326 FRAME_PTR f
= XFRAME (WINDOW_FRAME (window
));
4328 if (NILP (bar
->prev
))
4330 /* If the prev pointer is nil, it must be the first in one of
4332 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4333 /* It's not condemned. Everything's fine. */
4335 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4336 window
->vertical_scroll_bar
))
4337 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4339 /* If its prev pointer is nil, it must be at the front of
4340 one or the other! */
4344 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4346 if (! NILP (bar
->next
))
4347 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4349 bar
->next
= FRAME_SCROLL_BARS (f
);
4351 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4352 if (! NILP (bar
->next
))
4353 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4357 /* Remove all scroll bars on FRAME that haven't been saved since the
4358 last call to `*condemn_scroll_bars_hook'. */
4361 XTjudge_scroll_bars (f
)
4364 Lisp_Object bar
, next
;
4366 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4368 /* Clear out the condemned list now so we won't try to process any
4369 more events on the hapless scroll bars. */
4370 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4372 for (; ! NILP (bar
); bar
= next
)
4374 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4376 x_scroll_bar_remove (b
);
4379 b
->next
= b
->prev
= Qnil
;
4382 /* Now there should be no references to the condemned scroll bars,
4383 and they should get garbage-collected. */
4388 activate_scroll_bars (frame
)
4394 bar
= FRAME_SCROLL_BARS (frame
);
4395 while (! NILP (bar
))
4397 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4398 #ifdef TARGET_API_MAC_CARBON
4399 ActivateControl (ch
);
4401 SetControlMaximum (ch
,
4402 VERTICAL_SCROLL_BAR_TOP_RANGE (frame
,
4403 XINT (XSCROLL_BAR (bar
)
4406 bar
= XSCROLL_BAR (bar
)->next
;
4412 deactivate_scroll_bars (frame
)
4418 bar
= FRAME_SCROLL_BARS (frame
);
4419 while (! NILP (bar
))
4421 ch
= SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (bar
));
4422 #ifdef TARGET_API_MAC_CARBON
4423 DeactivateControl (ch
);
4425 SetControlMaximum (ch
, XINT (-1));
4427 bar
= XSCROLL_BAR (bar
)->next
;
4431 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
4432 is set to something other than NO_EVENT, it is enqueued.
4434 This may be called from a signal handler, so we have to ignore GC
4438 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
4439 struct scroll_bar
*bar
;
4442 struct input_event
*bufp
;
4444 if (! GC_WINDOWP (bar
->window
))
4447 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4448 bufp
->frame_or_window
= bar
->window
;
4451 bar
->dragging
= Qnil
;
4455 case kControlUpButtonPart
:
4456 bufp
->part
= scroll_bar_up_arrow
;
4458 case kControlDownButtonPart
:
4459 bufp
->part
= scroll_bar_down_arrow
;
4461 case kControlPageUpPart
:
4462 bufp
->part
= scroll_bar_above_handle
;
4464 case kControlPageDownPart
:
4465 bufp
->part
= scroll_bar_below_handle
;
4467 #ifdef TARGET_API_MAC_CARBON
4470 case kControlIndicatorPart
:
4472 if (er
->what
== mouseDown
)
4473 bar
->dragging
= make_number (0);
4474 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4475 bufp
->part
= scroll_bar_handle
;
4481 /* Handle some mouse motion while someone is dragging the scroll bar.
4483 This may be called from a signal handler, so we have to ignore GC
4487 x_scroll_bar_note_movement (bar
, y_pos
, t
)
4488 struct scroll_bar
*bar
;
4492 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
4494 last_mouse_movement_time
= t
;
4497 XSETVECTOR (last_mouse_scroll_bar
, bar
);
4499 /* If we're dragging the bar, display it. */
4500 if (! GC_NILP (bar
->dragging
))
4502 /* Where should the handle be now? */
4503 int new_start
= y_pos
- 24;
4505 if (new_start
!= XINT (bar
->start
))
4507 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
4509 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
4515 /* Return information to the user about the current position of the
4516 mouse on the scroll bar. */
4519 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
4521 Lisp_Object
*bar_window
;
4522 enum scroll_bar_part
*part
;
4524 unsigned long *time
;
4526 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
4527 WindowPtr wp
= FrontWindow ();
4529 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
4530 int win_y
, top_range
;
4532 #if TARGET_API_MAC_CARBON
4533 SetPort (GetWindowPort (wp
));
4538 GetMouse (&mouse_pos
);
4540 win_y
= mouse_pos
.v
- XINT (bar
->top
);
4541 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4543 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
4547 if (! NILP (bar
->dragging
))
4548 win_y
-= XINT (bar
->dragging
);
4552 if (win_y
> top_range
)
4556 *bar_window
= bar
->window
;
4558 if (! NILP (bar
->dragging
))
4559 *part
= scroll_bar_handle
;
4560 else if (win_y
< XINT (bar
->start
))
4561 *part
= scroll_bar_above_handle
;
4562 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
4563 *part
= scroll_bar_handle
;
4565 *part
= scroll_bar_below_handle
;
4567 XSETINT (*x
, win_y
);
4568 XSETINT (*y
, top_range
);
4571 last_mouse_scroll_bar
= Qnil
;
4573 *time
= last_mouse_movement_time
;
4576 /***********************************************************************
4578 ***********************************************************************/
4580 /* Set clipping for output in glyph row ROW. W is the window in which
4581 we operate. GC is the graphics context to set clipping in.
4583 ROW may be a text row or, e.g., a mode line. Text rows must be
4584 clipped to the interior of the window dedicated to text display,
4585 mode lines must be clipped to the whole window. */
4588 x_clip_to_row (w
, row
, gc
)
4590 struct glyph_row
*row
;
4593 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4595 int window_y
, window_width
;
4597 window_box (w
, -1, 0, &window_y
, &window_width
, 0);
4599 clip_rect
.left
= WINDOW_TO_FRAME_PIXEL_X (w
, 0);
4600 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
4601 clip_rect
.top
= max (clip_rect
.top
, window_y
);
4602 clip_rect
.right
= clip_rect
.left
+ window_width
;
4603 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
4605 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
), &clip_rect
);
4609 /* Draw a hollow box cursor on window W in glyph row ROW. */
4612 x_draw_hollow_cursor (w
, row
)
4614 struct glyph_row
*row
;
4616 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4617 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
4618 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4621 struct glyph
*cursor_glyph
;
4624 /* Get the glyph the cursor is on. If we can't tell because
4625 the current matrix is invalid or such, give up. */
4626 cursor_glyph
= get_phys_cursor_glyph (w
);
4627 if (cursor_glyph
== NULL
)
4630 /* Compute the width of the rectangle to draw. If on a stretch
4631 glyph, and `x-stretch-block-cursor' is nil, don't draw a
4632 rectangle as wide as the glyph, but use a canonical character
4634 wd
= cursor_glyph
->pixel_width
- 1;
4635 if (cursor_glyph
->type
== STRETCH_GLYPH
4636 && !x_stretch_cursor_p
)
4637 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
4638 w
->phys_cursor_width
= wd
;
4640 /* Compute frame-relative coordinates from window-relative
4642 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
4643 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
);
4645 /* Compute the proper height and ascent of the rectangle, based
4646 on the actual glyph. Using the full height of the row looks
4647 bad when there are tall images on that row. */
4648 h
= max (FRAME_LINE_HEIGHT (f
), cursor_glyph
->ascent
+ cursor_glyph
->descent
);
4649 if (h
< row
->height
)
4650 y
+= row
->ascent
/* - w->phys_cursor_ascent */ + cursor_glyph
->descent
- h
;
4653 /* The foreground of cursor_gc is typically the same as the normal
4654 background color, which can cause the cursor box to be invisible. */
4655 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4656 if (dpyinfo
->scratch_cursor_gc
)
4657 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
4659 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
4660 GCForeground
, &xgcv
);
4661 gc
= dpyinfo
->scratch_cursor_gc
;
4663 /* Set clipping, draw the rectangle, and reset clipping again. */
4664 x_clip_to_row (w
, row
, gc
);
4665 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
4666 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4670 /* Draw a bar cursor on window W in glyph row ROW.
4672 Implementation note: One would like to draw a bar cursor with an
4673 angle equal to the one given by the font property XA_ITALIC_ANGLE.
4674 Unfortunately, I didn't find a font yet that has this property set.
4678 x_draw_bar_cursor (w
, row
, width
, kind
)
4680 struct glyph_row
*row
;
4682 enum text_cursor_kinds kind
;
4684 struct frame
*f
= XFRAME (w
->frame
);
4685 struct glyph
*cursor_glyph
;
4687 /* If cursor is out of bounds, don't draw garbage. This can happen
4688 in mini-buffer windows when switching between echo area glyphs
4690 cursor_glyph
= get_phys_cursor_glyph (w
);
4691 if (cursor_glyph
== NULL
)
4694 /* If on an image, draw like a normal cursor. That's usually better
4695 visible than drawing a bar, esp. if the image is large so that
4696 the bar might not be in the window. */
4697 if (cursor_glyph
->type
== IMAGE_GLYPH
)
4699 struct glyph_row
*row
;
4700 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
4701 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
4705 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
4706 Window window
= FRAME_MAC_WINDOW (f
);
4707 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
4708 unsigned long mask
= GCForeground
| GCBackground
;
4709 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
4712 /* If the glyph's background equals the color we normally draw
4713 the bar cursor in, the bar cursor in its normal color is
4714 invisible. Use the glyph's foreground color instead in this
4715 case, on the assumption that the glyph's colors are chosen so
4716 that the glyph is legible. */
4717 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
4718 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
4720 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
4723 XChangeGC (dpy
, gc
, mask
, &xgcv
);
4726 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
4727 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
4731 width
= FRAME_CURSOR_WIDTH (f
);
4732 width
= min (cursor_glyph
->pixel_width
, width
);
4734 w
->phys_cursor_width
= width
;
4735 x_clip_to_row (w
, row
, gc
);
4737 if (kind
== BAR_CURSOR
)
4738 XFillRectangle (dpy
, window
, gc
,
4739 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4740 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
4741 width
, row
->height
);
4743 XFillRectangle (dpy
, window
, gc
,
4744 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
4745 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
4746 row
->height
- width
),
4747 cursor_glyph
->pixel_width
,
4750 mac_reset_clipping (dpy
, FRAME_MAC_WINDOW (f
));
4755 /* RIF: Define cursor CURSOR on frame F. */
4758 mac_define_frame_cursor (f
, cursor
)
4766 /* RIF: Clear area on frame F. */
4769 mac_clear_frame_area (f
, x
, y
, width
, height
)
4771 int x
, y
, width
, height
;
4773 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4774 x
, y
, width
, height
, 0);
4778 /* RIF: Draw cursor on window W. */
4781 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
4783 struct glyph_row
*glyph_row
;
4785 int cursor_type
, cursor_width
;
4790 w
->phys_cursor_type
= cursor_type
;
4791 w
->phys_cursor_on_p
= 1;
4793 if (glyph_row
->exact_window_width_line_p
4794 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
4796 glyph_row
->cursor_in_fringe_p
= 1;
4797 draw_fringe_bitmap (w
, glyph_row
, 0);
4800 switch (cursor_type
)
4802 case HOLLOW_BOX_CURSOR
:
4803 x_draw_hollow_cursor (w
, glyph_row
);
4806 case FILLED_BOX_CURSOR
:
4807 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
4811 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
4815 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
4819 w
->phys_cursor_width
= 0;
4831 #if 0 /* MAC_TODO: no icon support yet. */
4833 x_bitmap_icon (f
, icon
)
4839 if (FRAME_W32_WINDOW (f
) == 0)
4843 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
4844 else if (STRINGP (icon
))
4845 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
4846 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
4847 else if (SYMBOLP (icon
))
4851 if (EQ (icon
, intern ("application")))
4852 name
= (LPCTSTR
) IDI_APPLICATION
;
4853 else if (EQ (icon
, intern ("hand")))
4854 name
= (LPCTSTR
) IDI_HAND
;
4855 else if (EQ (icon
, intern ("question")))
4856 name
= (LPCTSTR
) IDI_QUESTION
;
4857 else if (EQ (icon
, intern ("exclamation")))
4858 name
= (LPCTSTR
) IDI_EXCLAMATION
;
4859 else if (EQ (icon
, intern ("asterisk")))
4860 name
= (LPCTSTR
) IDI_ASTERISK
;
4861 else if (EQ (icon
, intern ("winlogo")))
4862 name
= (LPCTSTR
) IDI_WINLOGO
;
4866 hicon
= LoadIcon (NULL
, name
);
4874 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
4879 #endif /* MAC_TODO */
4881 /************************************************************************
4883 ************************************************************************/
4885 /* Display Error Handling functions not used on W32. Listing them here
4886 helps diff stay in step when comparing w32term.c with xterm.c.
4888 x_error_catcher (display, error)
4889 x_catch_errors (dpy)
4890 x_catch_errors_unwind (old_val)
4891 x_check_errors (dpy, format)
4892 x_had_errors_p (dpy)
4893 x_clear_errors (dpy)
4894 x_uncatch_errors (dpy, count)
4896 x_connection_signal (signalnum)
4897 x_connection_closed (dpy, error_message)
4898 x_error_quitter (display, error)
4899 x_error_handler (display, error)
4900 x_io_error_quitter (display)
4905 /* Changing the font of the frame. */
4907 /* Give frame F the font named FONTNAME as its default font, and
4908 return the full name of that font. FONTNAME may be a wildcard
4909 pattern; in that case, we choose some font that fits the pattern.
4910 The return value shows which font we chose. */
4913 x_new_font (f
, fontname
)
4915 register char *fontname
;
4917 struct font_info
*fontp
4918 = FS_LOAD_FONT (f
, 0, fontname
, -1);
4923 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
4924 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
4925 FRAME_FONTSET (f
) = -1;
4927 FRAME_COLUMN_WIDTH (f
) = FONT_WIDTH (FRAME_FONT (f
));
4928 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
4930 compute_fringe_widths (f
, 1);
4932 /* Compute the scroll bar width in character columns. */
4933 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
4935 int wid
= FRAME_COLUMN_WIDTH (f
);
4936 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
4937 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
4941 int wid
= FRAME_COLUMN_WIDTH (f
);
4942 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
4945 /* Now make the frame display the given font. */
4946 if (FRAME_MAC_WINDOW (f
) != 0)
4948 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
4950 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
4952 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
4955 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
4956 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
4959 return build_string (fontp
->full_name
);
4962 /* Give frame F the fontset named FONTSETNAME as its default font, and
4963 return the full name of that fontset. FONTSETNAME may be a wildcard
4964 pattern; in that case, we choose some fontset that fits the pattern.
4965 The return value shows which fontset we chose. */
4968 x_new_fontset (f
, fontsetname
)
4972 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
4978 if (FRAME_FONTSET (f
) == fontset
)
4979 /* This fontset is already set in frame F. There's nothing more
4981 return fontset_name (fontset
);
4983 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
4985 if (!STRINGP (result
))
4986 /* Can't load ASCII font. */
4989 /* Since x_new_font doesn't update any fontset information, do it now. */
4990 FRAME_FONTSET(f
) = fontset
;
4992 return build_string (fontsetname
);
4996 /***********************************************************************
4997 TODO: W32 Input Methods
4998 ***********************************************************************/
4999 /* Listing missing functions from xterm.c helps diff stay in step.
5001 xim_destroy_callback (xim, client_data, call_data)
5002 xim_open_dpy (dpyinfo, resource_name)
5004 xim_instantiate_callback (display, client_data, call_data)
5005 xim_initialize (dpyinfo, resource_name)
5006 xim_close_dpy (dpyinfo)
5011 /* Calculate the absolute position in frame F
5012 from its current recorded position values and gravity. */
5015 x_calc_absolute_position (f
)
5019 int flags
= f
->size_hint_flags
;
5023 /* Find the position of the outside upper-left corner of
5024 the inner window, with respect to the outer window. */
5025 if (f
->output_data
.mac
->parent_desc
!= FRAME_MAC_DISPLAY_INFO (f
)->root_window
)
5028 GetPort (&savePort
);
5030 #if TARGET_API_MAC_CARBON
5031 SetPort (GetWindowPort (FRAME_MAC_WINDOW (f
)));
5033 SetPort (FRAME_MAC_WINDOW (f
));
5036 #if TARGET_API_MAC_CARBON
5040 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
5041 SetPt(&pt
, r
.left
, r
.top
);
5043 #else /* not TARGET_API_MAC_CARBON */
5044 SetPt(&pt
, FRAME_MAC_WINDOW (f
)->portRect
.left
, FRAME_MAC_WINDOW (f
)->portRect
.top
);
5045 #endif /* not TARGET_API_MAC_CARBON */
5046 LocalToGlobal (&pt
);
5050 /* Treat negative positions as relative to the leftmost bottommost
5051 position that fits on the screen. */
5052 if (flags
& XNegative
)
5053 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5054 - 2 * f
->border_width
- pt
.h
5055 - FRAME_PIXEL_WIDTH (f
)
5057 /* NTEMACS_TODO: Subtract menubar height? */
5058 if (flags
& YNegative
)
5059 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5060 - 2 * f
->border_width
- pt
.v
5061 - FRAME_PIXEL_HEIGHT (f
)
5063 /* The left_pos and top_pos
5064 are now relative to the top and left screen edges,
5065 so the flags should correspond. */
5066 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5069 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5070 to really change the position, and 0 when calling from
5071 x_make_frame_visible (in that case, XOFF and YOFF are the current
5072 position values). It is -1 when calling from x_set_frame_parameters,
5073 which means, do adjust for borders but don't change the gravity. */
5076 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5078 register int xoff
, yoff
;
5081 int modified_top
, modified_left
;
5083 if (change_gravity
> 0)
5087 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5089 f
->size_hint_flags
|= XNegative
;
5091 f
->size_hint_flags
|= YNegative
;
5092 f
->win_gravity
= NorthWestGravity
;
5094 x_calc_absolute_position (f
);
5097 x_wm_set_size_hint (f
, (long) 0, 0);
5099 modified_left
= f
->left_pos
;
5100 modified_top
= f
->top_pos
;
5102 MoveWindow (f
->output_data
.mac
->mWP
, modified_left
+ 6,
5103 modified_top
+ 42, false);
5108 /* Call this to change the size of frame F's x-window.
5109 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5110 for this size change and subsequent size changes.
5111 Otherwise we leave the window gravity unchanged. */
5114 x_set_window_size (f
, change_gravity
, cols
, rows
)
5119 int pixelwidth
, pixelheight
;
5123 check_frame_size (f
, &rows
, &cols
);
5124 f
->scroll_bar_actual_width
5125 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5127 compute_fringe_widths (f
, 0);
5129 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5130 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5132 f
->win_gravity
= NorthWestGravity
;
5133 x_wm_set_size_hint (f
, (long) 0, 0);
5135 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5137 /* Now, strictly speaking, we can't be sure that this is accurate,
5138 but the window manager will get around to dealing with the size
5139 change request eventually, and we'll hear how it went when the
5140 ConfigureNotify event gets here.
5142 We could just not bother storing any of this information here,
5143 and let the ConfigureNotify event set everything up, but that
5144 might be kind of confusing to the Lisp code, since size changes
5145 wouldn't be reported in the frame parameters until some random
5146 point in the future when the ConfigureNotify event arrives.
5148 We pass 1 for DELAY since we can't run Lisp code inside of
5150 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5151 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5152 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5154 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5155 receive in the ConfigureNotify event; if we get what we asked
5156 for, then the event won't cause the screen to become garbaged, so
5157 we have to make sure to do it here. */
5158 SET_FRAME_GARBAGED (f
);
5160 XFlush (FRAME_X_DISPLAY (f
));
5162 /* If cursor was outside the new size, mark it as off. */
5163 mark_window_cursors_off (XWINDOW (f
->root_window
));
5165 /* Clear out any recollection of where the mouse highlighting was,
5166 since it might be in a place that's outside the new frame size.
5167 Actually checking whether it is outside is a pain in the neck,
5168 so don't try--just let the highlighting be done afresh with new size. */
5169 cancel_mouse_face (f
);
5174 /* Mouse warping. */
5176 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5179 x_set_mouse_position (f
, x
, y
)
5185 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5186 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5188 if (pix_x
< 0) pix_x
= 0;
5189 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5191 if (pix_y
< 0) pix_y
= 0;
5192 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5194 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5198 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5202 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5205 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5206 0, 0, 0, 0, pix_x
, pix_y
);
5212 /* focus shifting, raising and lowering. */
5215 x_focus_on_frame (f
)
5218 #if 0 /* This proves to be unpleasant. */
5222 /* I don't think that the ICCCM allows programs to do things like this
5223 without the interaction of the window manager. Whatever you end up
5224 doing with this code, do it to x_unfocus_frame too. */
5225 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5226 RevertToPointerRoot
, CurrentTime
);
5236 /* Raise frame F. */
5241 if (f
->async_visible
)
5242 SelectWindow (FRAME_MAC_WINDOW (f
));
5245 /* Lower frame F. */
5250 if (f
->async_visible
)
5251 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5255 XTframe_raise_lower (f
, raise_flag
)
5265 /* Change of visibility. */
5267 /* This tries to wait until the frame is really visible.
5268 However, if the window manager asks the user where to position
5269 the frame, this will return before the user finishes doing that.
5270 The frame will not actually be visible at that time,
5271 but it will become visible later when the window manager
5272 finishes with it. */
5275 x_make_frame_visible (f
)
5279 int original_top
, original_left
;
5283 if (! FRAME_VISIBLE_P (f
))
5285 /* We test FRAME_GARBAGED_P here to make sure we don't
5286 call x_set_offset a second time
5287 if we get to x_make_frame_visible a second time
5288 before the window gets really visible. */
5289 if (! FRAME_ICONIFIED_P (f
)
5290 && ! f
->output_data
.mac
->asked_for_visible
)
5291 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5293 f
->output_data
.mac
->asked_for_visible
= 1;
5295 ShowWindow (FRAME_MAC_WINDOW (f
));
5298 XFlush (FRAME_MAC_DISPLAY (f
));
5300 #if 0 /* MAC_TODO */
5301 /* Synchronize to ensure Emacs knows the frame is visible
5302 before we do anything else. We do this loop with input not blocked
5303 so that incoming events are handled. */
5308 /* This must come after we set COUNT. */
5311 XSETFRAME (frame
, f
);
5313 /* Wait until the frame is visible. Process X events until a
5314 MapNotify event has been seen, or until we think we won't get a
5315 MapNotify at all.. */
5316 for (count
= input_signal_count
+ 10;
5317 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5319 /* Force processing of queued events. */
5322 /* Machines that do polling rather than SIGIO have been
5323 observed to go into a busy-wait here. So we'll fake an
5324 alarm signal to let the handler know that there's something
5325 to be read. We used to raise a real alarm, but it seems
5326 that the handler isn't always enabled here. This is
5328 if (input_polling_used ())
5330 /* It could be confusing if a real alarm arrives while
5331 processing the fake one. Turn it off and let the
5332 handler reset it. */
5333 extern void poll_for_input_1
P_ ((void));
5334 int old_poll_suppress_count
= poll_suppress_count
;
5335 poll_suppress_count
= 1;
5336 poll_for_input_1 ();
5337 poll_suppress_count
= old_poll_suppress_count
;
5340 /* See if a MapNotify event has been processed. */
5341 FRAME_SAMPLE_VISIBILITY (f
);
5346 #endif /* MAC_TODO */
5349 /* Change from mapped state to withdrawn state. */
5351 /* Make the frame visible (mapped and not iconified). */
5354 x_make_frame_invisible (f
)
5357 /* Don't keep the highlight on an invisible frame. */
5358 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5359 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5363 HideWindow (FRAME_MAC_WINDOW (f
));
5365 /* We can't distinguish this from iconification
5366 just by the event that we get from the server.
5367 So we can't win using the usual strategy of letting
5368 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5369 and synchronize with the server to make sure we agree. */
5371 FRAME_ICONIFIED_P (f
) = 0;
5372 f
->async_visible
= 0;
5373 f
->async_iconified
= 0;
5378 /* Change window state from mapped to iconified. */
5384 /* Don't keep the highlight on an invisible frame. */
5385 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5386 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5389 /* Review: Since window is still visible in dock, still allow updates? */
5390 if (f
->async_iconified
)
5396 CollapseWindow (FRAME_MAC_WINDOW (f
), true);
5402 /* Free X resources of frame F. */
5405 x_free_frame_resources (f
)
5408 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5412 DisposeWindow (FRAME_MAC_WINDOW (f
));
5414 free_frame_menubar (f
);
5416 if (FRAME_FACE_CACHE (f
))
5417 free_frame_faces (f
);
5421 xfree (f
->output_data
.mac
);
5422 f
->output_data
.mac
= NULL
;
5424 if (f
== dpyinfo
->x_focus_frame
)
5425 dpyinfo
->x_focus_frame
= 0;
5426 if (f
== dpyinfo
->x_focus_event_frame
)
5427 dpyinfo
->x_focus_event_frame
= 0;
5428 if (f
== dpyinfo
->x_highlight_frame
)
5429 dpyinfo
->x_highlight_frame
= 0;
5431 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5433 dpyinfo
->mouse_face_beg_row
5434 = dpyinfo
->mouse_face_beg_col
= -1;
5435 dpyinfo
->mouse_face_end_row
5436 = dpyinfo
->mouse_face_end_col
= -1;
5437 dpyinfo
->mouse_face_window
= Qnil
;
5438 dpyinfo
->mouse_face_deferred_gc
= 0;
5439 dpyinfo
->mouse_face_mouse_frame
= 0;
5446 /* Destroy the X window of frame F. */
5449 x_destroy_window (f
)
5452 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5454 x_free_frame_resources (f
);
5456 dpyinfo
->reference_count
--;
5460 /* Setting window manager hints. */
5462 /* Set the normal size hints for the window manager, for frame F.
5463 FLAGS is the flags word to use--or 0 meaning preserve the flags
5464 that the window now has.
5465 If USER_POSITION is nonzero, we set the USPosition
5466 flag (this is useful when FLAGS is 0). */
5468 x_wm_set_size_hint (f
, flags
, user_position
)
5473 #if 0 /* MAC_TODO: connect this to the Appearance Manager */
5474 XSizeHints size_hints
;
5476 #ifdef USE_X_TOOLKIT
5479 Dimension widget_width
, widget_height
;
5480 Window window
= XtWindow (f
->output_data
.x
->widget
);
5481 #else /* not USE_X_TOOLKIT */
5482 Window window
= FRAME_X_WINDOW (f
);
5483 #endif /* not USE_X_TOOLKIT */
5485 /* Setting PMaxSize caused various problems. */
5486 size_hints
.flags
= PResizeInc
| PMinSize
/* | PMaxSize */;
5488 size_hints
.x
= f
->left_pos
;
5489 size_hints
.y
= f
->top_pos
;
5491 #ifdef USE_X_TOOLKIT
5492 XtSetArg (al
[ac
], XtNwidth
, &widget_width
); ac
++;
5493 XtSetArg (al
[ac
], XtNheight
, &widget_height
); ac
++;
5494 XtGetValues (f
->output_data
.x
->widget
, al
, ac
);
5495 size_hints
.height
= widget_height
;
5496 size_hints
.width
= widget_width
;
5497 #else /* not USE_X_TOOLKIT */
5498 size_hints
.height
= FRAME_PIXEL_HEIGHT (f
);
5499 size_hints
.width
= FRAME_PIXEL_WIDTH (f
);
5500 #endif /* not USE_X_TOOLKIT */
5502 size_hints
.width_inc
= FRAME_COLUMN_WIDTH (f
);
5503 size_hints
.height_inc
= FRAME_LINE_HEIGHT (f
);
5504 size_hints
.max_width
5505 = FRAME_X_DISPLAY_INFO (f
)->width
- FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5506 size_hints
.max_height
5507 = FRAME_X_DISPLAY_INFO (f
)->height
- FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5509 /* Calculate the base and minimum sizes.
5511 (When we use the X toolkit, we don't do it here.
5512 Instead we copy the values that the widgets are using, below.) */
5513 #ifndef USE_X_TOOLKIT
5515 int base_width
, base_height
;
5516 int min_rows
= 0, min_cols
= 0;
5518 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
5519 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
5521 check_frame_size (f
, &min_rows
, &min_cols
);
5523 /* The window manager uses the base width hints to calculate the
5524 current number of rows and columns in the frame while
5525 resizing; min_width and min_height aren't useful for this
5526 purpose, since they might not give the dimensions for a
5527 zero-row, zero-column frame.
5529 We use the base_width and base_height members if we have
5530 them; otherwise, we set the min_width and min_height members
5531 to the size for a zero x zero frame. */
5534 size_hints
.flags
|= PBaseSize
;
5535 size_hints
.base_width
= base_width
;
5536 size_hints
.base_height
= base_height
;
5537 size_hints
.min_width
= base_width
+ min_cols
* size_hints
.width_inc
;
5538 size_hints
.min_height
= base_height
+ min_rows
* size_hints
.height_inc
;
5540 size_hints
.min_width
= base_width
;
5541 size_hints
.min_height
= base_height
;
5545 /* If we don't need the old flags, we don't need the old hint at all. */
5548 size_hints
.flags
|= flags
;
5551 #endif /* not USE_X_TOOLKIT */
5554 XSizeHints hints
; /* Sometimes I hate X Windows... */
5555 long supplied_return
;
5559 value
= XGetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
,
5562 value
= XGetNormalHints (FRAME_X_DISPLAY (f
), window
, &hints
);
5565 #ifdef USE_X_TOOLKIT
5566 size_hints
.base_height
= hints
.base_height
;
5567 size_hints
.base_width
= hints
.base_width
;
5568 size_hints
.min_height
= hints
.min_height
;
5569 size_hints
.min_width
= hints
.min_width
;
5573 size_hints
.flags
|= flags
;
5578 if (hints
.flags
& PSize
)
5579 size_hints
.flags
|= PSize
;
5580 if (hints
.flags
& PPosition
)
5581 size_hints
.flags
|= PPosition
;
5582 if (hints
.flags
& USPosition
)
5583 size_hints
.flags
|= USPosition
;
5584 if (hints
.flags
& USSize
)
5585 size_hints
.flags
|= USSize
;
5589 #ifndef USE_X_TOOLKIT
5594 size_hints
.win_gravity
= f
->win_gravity
;
5595 size_hints
.flags
|= PWinGravity
;
5599 size_hints
.flags
&= ~ PPosition
;
5600 size_hints
.flags
|= USPosition
;
5602 #endif /* PWinGravity */
5605 XSetWMNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5607 XSetNormalHints (FRAME_X_DISPLAY (f
), window
, &size_hints
);
5609 #endif /* MAC_TODO */
5612 #if 0 /* MAC_TODO: hide application instead of iconify? */
5613 /* Used for IconicState or NormalState */
5616 x_wm_set_window_state (f
, state
)
5620 #ifdef USE_X_TOOLKIT
5623 XtSetArg (al
[0], XtNinitialState
, state
);
5624 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5625 #else /* not USE_X_TOOLKIT */
5626 Window window
= FRAME_X_WINDOW (f
);
5628 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
5629 f
->output_data
.x
->wm_hints
.initial_state
= state
;
5631 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5632 #endif /* not USE_X_TOOLKIT */
5636 x_wm_set_icon_pixmap (f
, pixmap_id
)
5642 #ifndef USE_X_TOOLKIT
5643 Window window
= FRAME_X_WINDOW (f
);
5648 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
5649 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
5653 /* It seems there is no way to turn off use of an icon pixmap.
5654 The following line does it, only if no icon has yet been created,
5655 for some window managers. But with mwm it crashes.
5656 Some people say it should clear the IconPixmapHint bit in this case,
5657 but that doesn't work, and the X consortium said it isn't the
5658 right thing at all. Since there is no way to win,
5659 best to explicitly give up. */
5661 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
5667 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
5671 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
5672 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
5675 #else /* not USE_X_TOOLKIT */
5677 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
5678 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5680 #endif /* not USE_X_TOOLKIT */
5683 #endif /* MAC_TODO */
5686 x_wm_set_icon_position (f
, icon_x
, icon_y
)
5690 #if 0 /* MAC_TODO: no icons on Mac */
5691 #ifdef USE_X_TOOLKIT
5692 Window window
= XtWindow (f
->output_data
.x
->widget
);
5694 Window window
= FRAME_X_WINDOW (f
);
5697 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
5698 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
5699 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
5701 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
5702 #endif /* MAC_TODO */
5706 /***********************************************************************
5708 ***********************************************************************/
5710 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5713 x_get_font_info (f
, font_idx
)
5717 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
5720 /* the global font name table */
5721 char **font_name_table
= NULL
;
5722 int font_name_table_size
= 0;
5723 int font_name_count
= 0;
5726 /* compare two strings ignoring case */
5728 stricmp (const char *s
, const char *t
)
5730 for ( ; tolower (*s
) == tolower (*t
); s
++, t
++)
5733 return tolower (*s
) - tolower (*t
);
5736 /* compare two strings ignoring case and handling wildcard */
5738 wildstrieq (char *s1
, char *s2
)
5740 if (strcmp (s1
, "*") == 0 || strcmp (s2
, "*") == 0)
5743 return stricmp (s1
, s2
) == 0;
5746 /* Assume parameter 1 is fully qualified, no wildcards. */
5748 mac_font_pattern_match (fontname
, pattern
)
5752 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
5753 char *font_name_copy
= (char *) alloca (strlen (fontname
) + 1);
5756 /* Copy fontname so we can modify it during comparison. */
5757 strcpy (font_name_copy
, fontname
);
5762 /* Turn pattern into a regexp and do a regexp match. */
5763 for (; *pattern
; pattern
++)
5765 if (*pattern
== '?')
5767 else if (*pattern
== '*')
5778 return (fast_c_string_match_ignore_case (build_string (regex
),
5779 font_name_copy
) >= 0);
5782 /* Two font specs are considered to match if their foundry, family,
5783 weight, slant, and charset match. */
5785 mac_font_match (char *mf
, char *xf
)
5787 char m_foundry
[50], m_family
[50], m_weight
[20], m_slant
[2], m_charset
[20];
5788 char x_foundry
[50], x_family
[50], x_weight
[20], x_slant
[2], x_charset
[20];
5790 if (sscanf (mf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5791 m_foundry
, m_family
, m_weight
, m_slant
, m_charset
) != 5)
5792 return mac_font_pattern_match (mf
, xf
);
5794 if (sscanf (xf
, "-%49[^-]-%49[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%19s",
5795 x_foundry
, x_family
, x_weight
, x_slant
, x_charset
) != 5)
5796 return mac_font_pattern_match (mf
, xf
);
5798 return (wildstrieq (m_foundry
, x_foundry
)
5799 && wildstrieq (m_family
, x_family
)
5800 && wildstrieq (m_weight
, x_weight
)
5801 && wildstrieq (m_slant
, x_slant
)
5802 && wildstrieq (m_charset
, x_charset
))
5803 || mac_font_pattern_match (mf
, xf
);
5807 static Lisp_Object Qbig5
, Qcn_gb
, Qsjis
, Qeuc_kr
;
5810 decode_mac_font_name (char *name
, int size
, short scriptcode
)
5812 Lisp_Object coding_system
;
5813 struct coding_system coding
;
5819 coding_system
= Qbig5
;
5822 coding_system
= Qcn_gb
;
5825 coding_system
= Qsjis
;
5828 coding_system
= Qeuc_kr
;
5834 setup_coding_system (coding_system
, &coding
);
5835 coding
.src_multibyte
= 0;
5836 coding
.dst_multibyte
= 1;
5837 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5838 coding
.composing
= COMPOSITION_DISABLED
;
5839 buf
= (char *) alloca (size
);
5841 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
5842 bcopy (buf
, name
, coding
.produced
);
5843 name
[coding
.produced
] = '\0';
5848 mac_to_x_fontname (char *name
, int size
, Style style
, short scriptcode
)
5850 char foundry
[32], family
[32], cs
[32];
5851 char xf
[256], *result
, *p
;
5853 if (sscanf (name
, "%31[^-]-%31[^-]-%31s", foundry
, family
, cs
) != 3)
5855 strcpy(foundry
, "Apple");
5856 strcpy(family
, name
);
5861 strcpy(cs
, "big5-0");
5864 strcpy(cs
, "gb2312.1980-0");
5867 strcpy(cs
, "jisx0208.1983-sjis");
5870 /* Each Apple Japanese font is entered into the font table
5871 twice: once as a jisx0208.1983-sjis font and once as a
5872 jisx0201.1976-0 font. The latter can be used to display
5873 the ascii charset and katakana-jisx0201 charset. A
5874 negative script code signals that the name of this latter
5875 font is being built. */
5876 strcpy(cs
, "jisx0201.1976-0");
5879 strcpy(cs
, "ksc5601.1989-0");
5882 strcpy(cs
, "mac-roman");
5887 sprintf(xf
, "-%s-%s-%s-%c-normal--%d-%d-75-75-m-%d-%s",
5888 foundry
, family
, style
& bold
? "bold" : "medium",
5889 style
& italic
? 'i' : 'r', size
, size
* 10, size
* 10, cs
);
5891 result
= (char *) xmalloc (strlen (xf
) + 1);
5892 strcpy (result
, xf
);
5893 for (p
= result
; *p
; p
++)
5899 /* Convert an X font spec to the corresponding mac font name, which
5900 can then be passed to GetFNum after conversion to a Pascal string.
5901 For ordinary Mac fonts, this should just be their names, like
5902 "monaco", "Taipei", etc. Fonts converted from the GNU intlfonts
5903 collection contain their charset designation in their names, like
5904 "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both types of font
5905 names are handled accordingly. */
5907 x_font_name_to_mac_font_name (char *xf
, char *mf
)
5909 char foundry
[32], family
[32], weight
[20], slant
[2], cs
[32];
5910 Lisp_Object coding_system
= Qnil
;
5911 struct coding_system coding
;
5915 if (sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5916 foundry
, family
, weight
, slant
, cs
) != 5 &&
5917 sscanf (xf
, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
5918 foundry
, family
, weight
, slant
, cs
) != 5)
5921 if (strcmp (cs
, "big5-0") == 0)
5922 coding_system
= Qbig5
;
5923 else if (strcmp (cs
, "gb2312.1980-0") == 0)
5924 coding_system
= Qcn_gb
;
5925 else if (strcmp (cs
, "jisx0208.1983-sjis") == 0
5926 || strcmp (cs
, "jisx0201.1976-0") == 0)
5927 coding_system
= Qsjis
;
5928 else if (strcmp (cs
, "ksc5601.1989-0") == 0)
5929 coding_system
= Qeuc_kr
;
5930 else if (strcmp (cs
, "mac-roman") == 0)
5931 strcpy (mf
, family
);
5933 sprintf (mf
, "%s-%s-%s", foundry
, family
, cs
);
5935 if (!NILP (coding_system
))
5937 setup_coding_system (coding_system
, &coding
);
5938 coding
.src_multibyte
= 1;
5939 coding
.dst_multibyte
= 1;
5940 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
5941 encode_coding (&coding
, family
, mf
, strlen (family
), sizeof (Str32
) - 1);
5942 mf
[coding
.produced
] = '\0';
5948 add_font_name_table_entry (char *font_name
)
5950 if (font_name_table_size
== 0)
5952 font_name_table_size
= 16;
5953 font_name_table
= (char **)
5954 xmalloc (font_name_table_size
* sizeof (char *));
5956 else if (font_name_count
+ 1 >= font_name_table_size
)
5958 font_name_table_size
+= 16;
5959 font_name_table
= (char **)
5960 xrealloc (font_name_table
,
5961 font_name_table_size
* sizeof (char *));
5964 font_name_table
[font_name_count
++] = font_name
;
5967 /* Sets up the table font_name_table to contain the list of all fonts
5968 in the system the first time the table is used so that the Resource
5969 Manager need not be accessed every time this information is
5973 init_font_name_table ()
5975 #if TARGET_API_MAC_CARBON
5978 if (Gestalt (gestaltSystemVersion
, &sv
) == noErr
&& sv
>= 0x1000)
5980 FMFontFamilyIterator ffi
;
5981 FMFontFamilyInstanceIterator ffii
;
5984 /* Create a dummy instance iterator here to avoid creating and
5985 destroying it in the loop. */
5986 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
5988 /* Create an iterator to enumerate the font families. */
5989 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
5992 FMDisposeFontFamilyInstanceIterator (&ffii
);
5996 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6004 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6010 sc
= FontToScript (ff
);
6011 decode_mac_font_name (name
, sizeof (name
), sc
);
6013 /* Point the instance iterator at the current font family. */
6014 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6017 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
6020 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
6021 contained in Apple Japanese (SJIS) font. */
6025 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6027 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6029 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6031 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6036 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
6038 if (sc
== smJapanese
)
6043 else if (sc
== -smJapanese
)
6048 /* Dispose of the iterators. */
6049 FMDisposeFontFamilyIterator (&ffi
);
6050 FMDisposeFontFamilyInstanceIterator (&ffii
);
6054 #endif /* TARGET_API_MAC_CARBON */
6056 SInt16 fontnum
, old_fontnum
;
6057 int num_mac_fonts
= CountResources('FOND');
6059 Handle font_handle
, font_handle_2
;
6060 short id
, scriptcode
;
6063 struct FontAssoc
*fat
;
6064 struct AsscEntry
*assc_entry
;
6066 GetPort (&port
); /* save the current font number used */
6067 #if TARGET_API_MAC_CARBON
6068 old_fontnum
= GetPortTextFont (port
);
6070 old_fontnum
= port
->txFont
;
6073 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
6075 font_handle
= GetIndResource ('FOND', i
);
6079 GetResInfo (font_handle
, &id
, &type
, name
);
6080 GetFNum (name
, &fontnum
);
6086 scriptcode
= FontToScript (fontnum
);
6087 decode_mac_font_name (name
, sizeof (name
), scriptcode
);
6090 HLock (font_handle
);
6092 if (GetResourceSizeOnDisk (font_handle
)
6093 >= sizeof (struct FamRec
))
6095 fat
= (struct FontAssoc
*) (*font_handle
6096 + sizeof (struct FamRec
));
6098 = (struct AsscEntry
*) (*font_handle
6099 + sizeof (struct FamRec
)
6100 + sizeof (struct FontAssoc
));
6102 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
6104 if (font_name_table_size
== 0)
6106 font_name_table_size
= 16;
6107 font_name_table
= (char **)
6108 xmalloc (font_name_table_size
* sizeof (char *));
6110 else if (font_name_count
>= font_name_table_size
)
6112 font_name_table_size
+= 16;
6113 font_name_table
= (char **)
6114 xrealloc (font_name_table
,
6115 font_name_table_size
* sizeof (char *));
6117 font_name_table
[font_name_count
++]
6118 = mac_to_x_fontname (name
,
6119 assc_entry
->fontSize
,
6120 assc_entry
->fontStyle
,
6122 /* Both jisx0208.1983-sjis and jisx0201.1976-0
6123 parts are contained in Apple Japanese (SJIS)
6125 if (smJapanese
== scriptcode
)
6127 font_name_table
[font_name_count
++]
6128 = mac_to_x_fontname (name
,
6129 assc_entry
->fontSize
,
6130 assc_entry
->fontStyle
,
6136 HUnlock (font_handle
);
6137 font_handle_2
= GetNextFOND (font_handle
);
6138 ReleaseResource (font_handle
);
6139 font_handle
= font_handle_2
;
6141 while (ResError () == noErr
&& font_handle
);
6144 TextFont (old_fontnum
);
6145 #if TARGET_API_MAC_CARBON
6147 #endif /* TARGET_API_MAC_CARBON */
6151 enum xlfd_scalable_field_index
6153 XLFD_SCL_PIXEL_SIZE
,
6154 XLFD_SCL_POINT_SIZE
,
6159 static int xlfd_scalable_fields
[] =
6168 mac_do_list_fonts (pattern
, maxnames
)
6173 Lisp_Object font_list
= Qnil
, pattern_regex
, fontname
;
6174 char *regex
= (char *) alloca (strlen (pattern
) * 2 + 3);
6177 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
6179 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
6182 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6183 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6184 fonts are scaled according to the specified size. */
6187 field
= xlfd_scalable_fields
;
6195 if ('1' <= *ptr
&& *ptr
<= '9')
6197 *val
= *ptr
++ - '0';
6198 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
6199 *val
= *val
* 10 + *ptr
++ - '0';
6206 ptr
= strchr (ptr
, '-');
6209 while (ptr
&& i
< 14);
6211 if (i
== 14 && ptr
== NULL
)
6213 if (scl_val
[XLFD_SCL_POINT_SIZE
] > 0)
6215 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_POINT_SIZE
] / 10;
6216 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_POINT_SIZE
];
6218 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0)
6220 scl_val
[XLFD_SCL_POINT_SIZE
] =
6221 scl_val
[XLFD_SCL_AVGWIDTH
] = scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10;
6223 else if (scl_val
[XLFD_SCL_AVGWIDTH
] > 0)
6225 scl_val
[XLFD_SCL_PIXEL_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
] / 10;
6226 scl_val
[XLFD_SCL_POINT_SIZE
] = scl_val
[XLFD_SCL_AVGWIDTH
];
6230 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
6235 /* Turn pattern into a regexp and do a regexp match. */
6236 for (; *pattern
; pattern
++)
6238 if (*pattern
== '?')
6240 else if (*pattern
== '*')
6246 *ptr
++ = tolower (*pattern
);
6251 pattern_regex
= build_string (regex
);
6253 for (i
= 0; i
< font_name_count
; i
++)
6255 fontname
= build_string (font_name_table
[i
]);
6256 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6258 font_list
= Fcons (fontname
, font_list
);
6261 if (maxnames
> 0 && n_fonts
>= maxnames
)
6264 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
6265 && (ptr
= strstr (font_name_table
[i
], "-0-0-75-75-m-0-")))
6267 int former_len
= ptr
- font_name_table
[i
];
6269 memcpy (scaled
, font_name_table
[i
], former_len
);
6270 sprintf (scaled
+ former_len
,
6271 "-%d-%d-75-75-m-%d-%s",
6272 scl_val
[XLFD_SCL_PIXEL_SIZE
],
6273 scl_val
[XLFD_SCL_POINT_SIZE
],
6274 scl_val
[XLFD_SCL_AVGWIDTH
],
6275 ptr
+ sizeof ("-0-0-75-75-m-0-") - 1);
6276 fontname
= build_string (scaled
);
6277 if (fast_string_match (pattern_regex
, fontname
) >= 0)
6279 font_list
= Fcons (fontname
, font_list
);
6282 if (maxnames
> 0 && n_fonts
>= maxnames
)
6290 /* Return a list of at most MAXNAMES font specs matching the one in
6291 PATTERN. Cache matching fonts for patterns in
6292 dpyinfo->name_list_element to avoid looking them up again by
6293 calling mac_font_pattern_match (slow). Return as many matching
6294 fonts as possible if MAXNAMES = -1. */
6297 x_list_fonts (struct frame
*f
,
6298 Lisp_Object pattern
,
6302 Lisp_Object newlist
= Qnil
, tem
, key
;
6303 struct mac_display_info
*dpyinfo
= f
? FRAME_MAC_DISPLAY_INFO (f
) : NULL
;
6305 if (font_name_table
== NULL
) /* Initialize when first used. */
6306 init_font_name_table ();
6310 tem
= XCDR (dpyinfo
->name_list_element
);
6311 key
= Fcons (pattern
, make_number (maxnames
));
6313 newlist
= Fassoc (key
, tem
);
6314 if (!NILP (newlist
))
6316 newlist
= Fcdr_safe (newlist
);
6321 newlist
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
6323 /* MAC_TODO: add code for matching outline fonts here */
6327 XSETCDR (dpyinfo
->name_list_element
,
6328 Fcons (Fcons (key
, newlist
),
6329 XCDR (dpyinfo
->name_list_element
)));
6339 /* Check that FONT is valid on frame F. It is if it can be found in F's
6343 x_check_font (f
, font
)
6348 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
6350 xassert (font
!= NULL
);
6352 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6353 if (dpyinfo
->font_table
[i
].name
6354 && font
== dpyinfo
->font_table
[i
].font
)
6357 xassert (i
< dpyinfo
->n_fonts
);
6360 #endif /* GLYPH_DEBUG != 0 */
6362 /* Set *W to the minimum width, *H to the minimum font height of FONT.
6363 Note: There are (broken) X fonts out there with invalid XFontStruct
6364 min_bounds contents. For example, handa@etl.go.jp reports that
6365 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
6366 have font->min_bounds.width == 0. */
6369 x_font_min_bounds (font
, w
, h
)
6370 MacFontStruct
*font
;
6374 * TODO: Windows does not appear to offer min bound, only
6375 * average and maximum width, and maximum height.
6377 *h
= FONT_HEIGHT (font
);
6378 *w
= FONT_WIDTH (font
);
6382 /* Compute the smallest character width and smallest font height over
6383 all fonts available on frame F. Set the members smallest_char_width
6384 and smallest_font_height in F's x_display_info structure to
6385 the values computed. Value is non-zero if smallest_font_height or
6386 smallest_char_width become smaller than they were before. */
6389 x_compute_min_glyph_bounds (f
)
6393 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6394 MacFontStruct
*font
;
6395 int old_width
= dpyinfo
->smallest_char_width
;
6396 int old_height
= dpyinfo
->smallest_font_height
;
6398 dpyinfo
->smallest_font_height
= 100000;
6399 dpyinfo
->smallest_char_width
= 100000;
6401 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6402 if (dpyinfo
->font_table
[i
].name
)
6404 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
6407 font
= (MacFontStruct
*) fontp
->font
;
6408 xassert (font
!= (MacFontStruct
*) ~0);
6409 x_font_min_bounds (font
, &w
, &h
);
6411 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
6412 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
6415 xassert (dpyinfo
->smallest_char_width
> 0
6416 && dpyinfo
->smallest_font_height
> 0);
6418 return (dpyinfo
->n_fonts
== 1
6419 || dpyinfo
->smallest_char_width
< old_width
6420 || dpyinfo
->smallest_font_height
< old_height
);
6424 /* Determine whether given string is a fully-specified XLFD: all 14
6425 fields are present, none is '*'. */
6428 is_fully_specified_xlfd (char *p
)
6436 for (i
= 0; i
< 13; i
++)
6438 q
= strchr (p
+ 1, '-');
6441 if (q
- p
== 2 && *(p
+ 1) == '*')
6446 if (strchr (p
+ 1, '-') != NULL
)
6449 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
6456 const int kDefaultFontSize
= 9;
6459 /* XLoadQueryFont creates and returns an internal representation for a
6460 font in a MacFontStruct struct. There is really no concept
6461 corresponding to "loading" a font on the Mac. But we check its
6462 existence and find the font number and all other information for it
6463 and store them in the returned MacFontStruct. */
6465 static MacFontStruct
*
6466 XLoadQueryFont (Display
*dpy
, char *fontname
)
6468 int i
, size
, is_two_byte_font
, char_width
;
6471 SInt16 old_fontnum
, old_fontsize
;
6475 Style fontface
= normal
;
6476 MacFontStruct
*font
;
6477 FontInfo the_fontinfo
;
6478 char s_weight
[7], c_slant
;
6480 if (is_fully_specified_xlfd (fontname
))
6484 Lisp_Object matched_fonts
;
6486 matched_fonts
= mac_do_list_fonts (fontname
, 1);
6487 if (NILP (matched_fonts
))
6489 name
= SDATA (XCAR (matched_fonts
));
6492 GetPort (&port
); /* save the current font number used */
6493 #if TARGET_API_MAC_CARBON
6494 old_fontnum
= GetPortTextFont (port
);
6495 old_fontsize
= GetPortTextSize (port
);
6496 old_fontface
= GetPortTextFace (port
);
6498 old_fontnum
= port
->txFont
;
6499 old_fontsize
= port
->txSize
;
6500 old_fontface
= port
->txFace
;
6503 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%d-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &size
) != 1)
6504 size
= kDefaultFontSize
;
6506 if (sscanf (name
, "-%*[^-]-%*[^-]-%6[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", s_weight
) == 1)
6507 if (strcmp (s_weight
, "bold") == 0)
6510 if (sscanf (name
, "-%*[^-]-%*[^-]-%*[^-]-%c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%*s", &c_slant
) == 1)
6514 x_font_name_to_mac_font_name (name
, mfontname
);
6516 GetFNum (mfontname
, &fontnum
);
6520 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
6522 font
->fontname
= (char *) xmalloc (strlen (name
) + 1);
6523 bcopy (name
, font
->fontname
, strlen (name
) + 1);
6525 font
->mac_fontnum
= fontnum
;
6526 font
->mac_fontsize
= size
;
6527 font
->mac_fontface
= fontface
;
6528 font
->mac_scriptcode
= FontToScript (fontnum
);
6530 /* Apple Japanese (SJIS) font is listed as both
6531 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
6532 (Roman script) in init_font_name_table (). The latter should be
6533 treated as a one-byte font. */
6538 "-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s",
6540 && 0 == strcmp (cs
, "jisx0201.1976-0"))
6541 font
->mac_scriptcode
= smRoman
;
6544 is_two_byte_font
= font
->mac_scriptcode
== smJapanese
||
6545 font
->mac_scriptcode
== smTradChinese
||
6546 font
->mac_scriptcode
== smSimpChinese
||
6547 font
->mac_scriptcode
== smKorean
;
6551 TextFace (fontface
);
6553 GetFontInfo (&the_fontinfo
);
6555 font
->ascent
= the_fontinfo
.ascent
;
6556 font
->descent
= the_fontinfo
.descent
;
6558 font
->min_byte1
= 0;
6559 if (is_two_byte_font
)
6560 font
->max_byte1
= 1;
6562 font
->max_byte1
= 0;
6563 font
->min_char_or_byte2
= 0x20;
6564 font
->max_char_or_byte2
= 0xff;
6566 if (is_two_byte_font
)
6568 /* Use the width of an "ideographic space" of that font because
6569 the_fontinfo.widMax returns the wrong width for some fonts. */
6570 switch (font
->mac_scriptcode
)
6573 char_width
= StringWidth("\p\x81\x40");
6576 char_width
= StringWidth("\p\xa1\x40");
6579 char_width
= StringWidth("\p\xa1\xa1");
6582 char_width
= StringWidth("\p\xa1\xa1");
6587 /* Do this instead of use the_fontinfo.widMax, which incorrectly
6588 returns 15 for 12-point Monaco! */
6589 char_width
= CharWidth ('m');
6591 font
->max_bounds
.rbearing
= char_width
;
6592 font
->max_bounds
.lbearing
= 0;
6593 font
->max_bounds
.width
= char_width
;
6594 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
6595 font
->max_bounds
.descent
= the_fontinfo
.descent
;
6597 font
->min_bounds
= font
->max_bounds
;
6599 if (is_two_byte_font
|| CharWidth ('m') == CharWidth ('i'))
6600 font
->per_char
= NULL
;
6603 font
->per_char
= (XCharStruct
*)
6604 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
6608 for (c
= 0x20; c
<= 0xff; c
++)
6610 font
->per_char
[c
- 0x20] = font
->max_bounds
;
6611 font
->per_char
[c
- 0x20].width
=
6612 font
->per_char
[c
- 0x20].rbearing
= CharWidth (c
);
6617 TextFont (old_fontnum
); /* restore previous font number, size and face */
6618 TextSize (old_fontsize
);
6619 TextFace (old_fontface
);
6625 /* Load font named FONTNAME of the size SIZE for frame F, and return a
6626 pointer to the structure font_info while allocating it dynamically.
6627 If SIZE is 0, load any size of font.
6628 If loading is failed, return NULL. */
6631 x_load_font (f
, fontname
, size
)
6633 register char *fontname
;
6636 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6637 Lisp_Object font_names
;
6639 /* Get a list of all the fonts that match this name. Once we
6640 have a list of matching fonts, we compare them against the fonts
6641 we already have by comparing names. */
6642 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
6644 if (!NILP (font_names
))
6649 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6650 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
6651 if (dpyinfo
->font_table
[i
].name
6652 && (!strcmp (dpyinfo
->font_table
[i
].name
,
6653 SDATA (XCAR (tail
)))
6654 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
6655 SDATA (XCAR (tail
)))))
6656 return (dpyinfo
->font_table
+ i
);
6659 /* Load the font and add it to the table. */
6662 struct MacFontStruct
*font
;
6663 struct font_info
*fontp
;
6664 unsigned long value
;
6667 /* If we have found fonts by x_list_font, load one of them. If
6668 not, we still try to load a font by the name given as FONTNAME
6669 because XListFonts (called in x_list_font) of some X server has
6670 a bug of not finding a font even if the font surely exists and
6671 is loadable by XLoadQueryFont. */
6672 if (size
> 0 && !NILP (font_names
))
6673 fontname
= (char *) SDATA (XCAR (font_names
));
6675 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
6679 /* Find a free slot in the font table. */
6680 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
6681 if (dpyinfo
->font_table
[i
].name
== NULL
)
6684 /* If no free slot found, maybe enlarge the font table. */
6685 if (i
== dpyinfo
->n_fonts
6686 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
6689 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
6690 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
6692 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
6695 fontp
= dpyinfo
->font_table
+ i
;
6696 if (i
== dpyinfo
->n_fonts
)
6699 /* Now fill in the slots of *FONTP. */
6701 bzero (fontp
, sizeof (*fontp
));
6703 fontp
->font_idx
= i
;
6704 fontp
->name
= (char *) xmalloc (strlen (font
->fontname
) + 1);
6705 bcopy (font
->fontname
, fontp
->name
, strlen (font
->fontname
) + 1);
6707 fontp
->full_name
= fontp
->name
;
6709 fontp
->size
= font
->max_bounds
.width
;
6710 fontp
->height
= FONT_HEIGHT (font
);
6712 /* For some font, ascent and descent in max_bounds field is
6713 larger than the above value. */
6714 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
6715 if (max_height
> fontp
->height
)
6716 fontp
->height
= max_height
;
6719 /* The slot `encoding' specifies how to map a character
6720 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
6721 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
6722 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
6723 2:0xA020..0xFF7F). For the moment, we don't know which charset
6724 uses this font. So, we set information in fontp->encoding[1]
6725 which is never used by any charset. If mapping can't be
6726 decided, set FONT_ENCODING_NOT_DECIDED. */
6727 if (font
->mac_scriptcode
== smJapanese
)
6728 fontp
->encoding
[1] = 4;
6732 = (font
->max_byte1
== 0
6734 ? (font
->min_char_or_byte2
< 0x80
6735 ? (font
->max_char_or_byte2
< 0x80
6736 ? 0 /* 0x20..0x7F */
6737 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
6738 : 1) /* 0xA0..0xFF */
6740 : (font
->min_byte1
< 0x80
6741 ? (font
->max_byte1
< 0x80
6742 ? (font
->min_char_or_byte2
< 0x80
6743 ? (font
->max_char_or_byte2
< 0x80
6744 ? 0 /* 0x2020..0x7F7F */
6745 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
6746 : 3) /* 0x20A0..0x7FFF */
6747 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
6748 : (font
->min_char_or_byte2
< 0x80
6749 ? (font
->max_char_or_byte2
< 0x80
6750 ? 2 /* 0xA020..0xFF7F */
6751 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
6752 : 1))); /* 0xA0A0..0xFFFF */
6755 #if 0 /* MAC_TODO: fill these out with more reasonably values */
6756 fontp
->baseline_offset
6757 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
6758 ? (long) value
: 0);
6759 fontp
->relative_compose
6760 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
6761 ? (long) value
: 0);
6762 fontp
->default_ascent
6763 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
6764 ? (long) value
: 0);
6766 fontp
->baseline_offset
= 0;
6767 fontp
->relative_compose
= 0;
6768 fontp
->default_ascent
= 0;
6771 /* Set global flag fonts_changed_p to non-zero if the font loaded
6772 has a character with a smaller width than any other character
6773 before, or if the font loaded has a smalle>r height than any
6774 other font loaded before. If this happens, it will make a
6775 glyph matrix reallocation necessary. */
6776 fonts_changed_p
= x_compute_min_glyph_bounds (f
);
6783 /* Return a pointer to struct font_info of a font named FONTNAME for
6784 frame F. If no such font is loaded, return NULL. */
6787 x_query_font (f
, fontname
)
6789 register char *fontname
;
6791 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6794 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6795 if (dpyinfo
->font_table
[i
].name
6796 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
6797 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
6798 return (dpyinfo
->font_table
+ i
);
6803 /* Find a CCL program for a font specified by FONTP, and set the member
6804 `encoder' of the structure. */
6807 x_find_ccl_program (fontp
)
6808 struct font_info
*fontp
;
6810 Lisp_Object list
, elt
;
6812 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
6816 && STRINGP (XCAR (elt
))
6817 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
6823 struct ccl_program
*ccl
6824 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6826 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
6829 fontp
->font_encoder
= ccl
;
6835 /* The Mac Event loop code */
6839 #include <Quickdraw.h>
6840 #include <Balloons.h>
6841 #include <Devices.h>
6843 #include <Gestalt.h>
6845 #include <Processes.h>
6847 #include <ToolUtils.h>
6848 #include <TextUtils.h>
6849 #include <Dialogs.h>
6852 #include <TextEncodingConverter.h>
6853 #include <Resources.h>
6858 #endif /* ! MAC_OSX */
6863 #define WINDOW_RESOURCE 128
6864 #define TERM_WINDOW_RESOURCE 129
6866 #define DEFAULT_NUM_COLS 80
6868 #define MIN_DOC_SIZE 64
6869 #define MAX_DOC_SIZE 32767
6871 /* sleep time for WaitNextEvent */
6872 #define WNE_SLEEP_AT_SUSPEND 10
6873 #define WNE_SLEEP_AT_RESUME 1
6875 /* true when cannot handle any Mac OS events */
6876 static int handling_window_update
= 0;
6878 /* the flag appl_is_suspended is used both for determining the sleep
6879 time to be passed to WaitNextEvent and whether the cursor should be
6880 drawn when updating the display. The cursor is turned off when
6881 Emacs is suspended. Redrawing it is unnecessary and what needs to
6882 be done depends on whether the cursor lies inside or outside the
6883 redraw region. So we might as well skip drawing it when Emacs is
6885 static Boolean app_is_suspended
= false;
6886 static long app_sleep_time
= WNE_SLEEP_AT_RESUME
;
6888 #define EXTRA_STACK_ALLOC (256 * 1024)
6890 #define ARGV_STRING_LIST_ID 129
6891 #define ABOUT_ALERT_ID 128
6892 #define RAM_TOO_LARGE_ALERT_ID 129
6894 Boolean terminate_flag
= false;
6896 /* Contains the string "reverse", which is a constant for mouse button emu.*/
6897 Lisp_Object Qreverse
;
6899 /* True if using command key as meta key. */
6900 Lisp_Object Vmac_command_key_is_meta
;
6902 /* True if the ctrl and meta keys should be reversed. */
6903 Lisp_Object Vmac_reverse_ctrl_meta
;
6905 /* True if the option and command modifiers should be used to emulate
6906 a three button mouse */
6907 Lisp_Object Vmac_emulate_three_button_mouse
;
6909 #if USE_CARBON_EVENTS
6910 /* True if the mouse wheel button (i.e. button 4) should map to
6911 mouse-2, instead of mouse-3. */
6912 Lisp_Object Vmac_wheel_button_is_mouse_2
;
6914 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
6915 for processing before Emacs sees it. */
6916 Lisp_Object Vmac_pass_command_to_system
;
6918 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
6919 for processing before Emacs sees it. */
6920 Lisp_Object Vmac_pass_control_to_system
;
6923 /* convert input from Mac keyboard (assumed to be in Mac Roman coding)
6924 to this text encoding */
6925 int mac_keyboard_text_encoding
;
6926 int current_mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
6928 /* Set in term/mac-win.el to indicate that event loop can now generate
6929 drag and drop events. */
6930 Lisp_Object Qmac_ready_for_drag_n_drop
;
6932 Lisp_Object drag_and_drop_file_list
;
6934 Point saved_menu_event_location
;
6937 static void init_required_apple_events (void);
6939 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
6941 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
6942 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
6943 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
6946 static OSErr
init_mac_drag_n_drop ();
6947 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
6949 #if USE_CARBON_EVENTS
6950 /* Preliminary Support for the OSX Services Menu */
6951 static OSStatus
mac_handle_service_event (EventHandlerCallRef
,EventRef
,void*);
6952 static void init_service_handler ();
6955 extern void init_emacs_passwd_dir ();
6956 extern int emacs_main (int, char **, char **);
6957 extern void check_alarm ();
6959 extern void initialize_applescript();
6960 extern void terminate_applescript();
6963 #if USE_CARBON_EVENTS
6964 mac_to_emacs_modifiers (UInt32 mods
)
6966 mac_to_emacs_modifiers (EventModifiers mods
)
6969 unsigned int result
= 0;
6970 if (mods
& macShiftKey
)
6971 result
|= shift_modifier
;
6972 if (mods
& macCtrlKey
)
6973 result
|= ctrl_modifier
;
6974 if (mods
& macMetaKey
)
6975 result
|= meta_modifier
;
6976 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
6977 result
|= alt_modifier
;
6982 mac_get_emulated_btn ( UInt32 modifiers
)
6985 if (Vmac_emulate_three_button_mouse
!= Qnil
) {
6986 int cmdIs3
= (Vmac_emulate_three_button_mouse
!= Qreverse
);
6987 if (modifiers
& controlKey
)
6988 result
= cmdIs3
? 2 : 1;
6989 else if (modifiers
& optionKey
)
6990 result
= cmdIs3
? 1 : 2;
6995 #if USE_CARBON_EVENTS
6996 /* Obtains the event modifiers from the event ref and then calls
6997 mac_to_emacs_modifiers. */
6999 mac_event_to_emacs_modifiers (EventRef eventRef
)
7002 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7003 sizeof (UInt32
), NULL
, &mods
);
7004 if (Vmac_emulate_three_button_mouse
!= Qnil
&&
7005 GetEventClass(eventRef
) == kEventClassMouse
)
7007 mods
&= ~(optionKey
& cmdKey
);
7009 return mac_to_emacs_modifiers (mods
);
7012 /* Given an event ref, return the code to use for the mouse button
7013 code in the emacs input_event. */
7015 mac_get_mouse_btn (EventRef ref
)
7017 EventMouseButton result
= kEventMouseButtonPrimary
;
7018 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
7019 sizeof (EventMouseButton
), NULL
, &result
);
7022 case kEventMouseButtonPrimary
:
7023 if (Vmac_emulate_three_button_mouse
== Qnil
)
7027 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
7028 sizeof (UInt32
), NULL
, &mods
);
7029 return mac_get_emulated_btn(mods
);
7031 case kEventMouseButtonSecondary
:
7032 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
7033 case kEventMouseButtonTertiary
:
7034 case 4: /* 4 is the number for the mouse wheel button */
7035 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
7041 /* Normally, ConvertEventRefToEventRecord will correctly handle all
7042 events. However the click of the mouse wheel is not converted to a
7043 mouseDown or mouseUp event. This calls ConvertEventRef, but then
7044 checks to see if it is a mouse up or down carbon event that has not
7045 been converted, and if so, converts it by hand (to be picked up in
7046 the XTread_socket loop). */
7047 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
7049 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
7050 /* Do special case for mouse wheel button. */
7051 if (!result
&& GetEventClass (eventRef
) == kEventClassMouse
)
7053 UInt32 kind
= GetEventKind (eventRef
);
7054 if (kind
== kEventMouseDown
&& !(eventRec
->what
== mouseDown
))
7056 eventRec
->what
= mouseDown
;
7059 if (kind
== kEventMouseUp
&& !(eventRec
->what
== mouseUp
))
7061 eventRec
->what
= mouseUp
;
7066 /* Need where and when. */
7068 GetEventParameter (eventRef
, kEventParamMouseLocation
,
7069 typeQDPoint
, NULL
, sizeof (Point
),
7070 NULL
, &eventRec
->where
);
7071 /* Use two step process because new event modifiers are
7072 32-bit and old are 16-bit. Currently, only loss is
7074 GetEventParameter (eventRef
, kEventParamKeyModifiers
,
7075 typeUInt32
, NULL
, sizeof (UInt32
),
7077 eventRec
->modifiers
= mods
;
7079 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
7090 Handle menubar_handle
;
7091 MenuHandle menu_handle
;
7093 menubar_handle
= GetNewMBar (128);
7094 if(menubar_handle
== NULL
)
7096 SetMenuBar (menubar_handle
);
7099 menu_handle
= GetMenuHandle (M_APPLE
);
7100 if(menu_handle
!= NULL
)
7101 AppendResMenu (menu_handle
,'DRVR');
7108 do_init_managers (void)
7110 #if !TARGET_API_MAC_CARBON
7111 InitGraf (&qd
.thePort
);
7113 FlushEvents (everyEvent
, 0);
7118 #endif /* !TARGET_API_MAC_CARBON */
7121 #if !TARGET_API_MAC_CARBON
7122 /* set up some extra stack space for use by emacs */
7123 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
7125 /* MaxApplZone must be called for AppleScript to execute more
7126 complicated scripts */
7129 #endif /* !TARGET_API_MAC_CARBON */
7133 do_check_ram_size (void)
7135 SInt32 physical_ram_size
, logical_ram_size
;
7137 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
7138 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
7139 || physical_ram_size
> (1 << VALBITS
)
7140 || logical_ram_size
> (1 << VALBITS
))
7142 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
7148 do_window_update (WindowPtr win
)
7150 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (win
);
7151 struct frame
*f
= mwp
->mFP
;
7155 if (f
->async_visible
== 0)
7157 f
->async_visible
= 1;
7158 f
->async_iconified
= 0;
7159 SET_FRAME_GARBAGED (f
);
7161 /* An update event is equivalent to MapNotify on X, so report
7162 visibility changes properly. */
7163 if (! NILP(Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
7164 /* Force a redisplay sooner or later to update the
7165 frame titles in case this is the second frame. */
7166 record_asynch_buffer_change ();
7171 handling_window_update
= 1;
7173 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
7175 expose_frame (f
, 0, 0, 0, 0);
7177 handling_window_update
= 0;
7184 is_emacs_window (WindowPtr win
)
7186 Lisp_Object tail
, frame
;
7191 FOR_EACH_FRAME (tail
, frame
)
7192 if (FRAME_MAC_P (XFRAME (frame
)))
7193 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
7200 do_window_activate (WindowPtr win
)
7205 if (is_emacs_window (win
))
7207 mwp
= (mac_output
*) GetWRefCon (win
);
7212 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7213 activate_scroll_bars (f
);
7219 do_window_deactivate (WindowPtr win
)
7224 if (is_emacs_window (win
))
7226 mwp
= (mac_output
*) GetWRefCon (win
);
7229 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7231 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7232 deactivate_scroll_bars (f
);
7245 if (is_emacs_window (wp
))
7247 mwp
= (mac_output
*) GetWRefCon (wp
);
7252 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), f
);
7253 activate_scroll_bars (f
);
7257 app_is_suspended
= false;
7258 app_sleep_time
= WNE_SLEEP_AT_RESUME
;
7269 if (is_emacs_window (wp
))
7271 mwp
= (mac_output
*) GetWRefCon (wp
);
7274 if (f
== FRAME_MAC_DISPLAY_INFO (f
)->x_focus_frame
)
7276 x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f
), 0);
7277 deactivate_scroll_bars (f
);
7281 app_is_suspended
= true;
7282 app_sleep_time
= WNE_SLEEP_AT_SUSPEND
;
7287 do_mouse_moved (Point mouse_pos
)
7289 WindowPtr wp
= FrontWindow ();
7292 if (is_emacs_window (wp
))
7294 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
7296 #if TARGET_API_MAC_CARBON
7297 SetPort (GetWindowPort (wp
));
7302 GlobalToLocal (&mouse_pos
);
7304 note_mouse_movement (f
, &mouse_pos
);
7310 do_os_event (EventRecord
*erp
)
7312 switch((erp
->message
>> 24) & 0x000000FF)
7314 case suspendResumeMessage
:
7315 if((erp
->message
& resumeFlag
) == 1)
7321 case mouseMovedMessage
:
7322 do_mouse_moved (erp
->where
);
7328 do_events (EventRecord
*erp
)
7333 do_window_update ((WindowPtr
) erp
->message
);
7341 if ((erp
->modifiers
& activeFlag
) != 0)
7342 do_window_activate ((WindowPtr
) erp
->message
);
7344 do_window_deactivate ((WindowPtr
) erp
->message
);
7350 do_apple_menu (SInt16 menu_item
)
7352 #if !TARGET_API_MAC_CARBON
7354 SInt16 da_driver_refnum
;
7356 if (menu_item
== I_ABOUT
)
7357 NoteAlert (ABOUT_ALERT_ID
, NULL
);
7360 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
7361 da_driver_refnum
= OpenDeskAcc (item_name
);
7363 #endif /* !TARGET_API_MAC_CARBON */
7367 do_menu_choice (SInt32 menu_choice
)
7369 SInt16 menu_id
, menu_item
;
7371 menu_id
= HiWord (menu_choice
);
7372 menu_item
= LoWord (menu_choice
);
7380 do_apple_menu (menu_item
);
7385 WindowPtr wp
= FrontWindow ();
7386 struct frame
*f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
7387 MenuHandle menu
= GetMenuHandle (menu_id
);
7392 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
7393 menubar_selection_callback (f
, refcon
);
7402 /* Handle drags in size box. Based on code contributed by Ben
7403 Mesander and IM - Window Manager A. */
7406 do_grow_window (WindowPtr w
, EventRecord
*e
)
7411 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7412 struct frame
*f
= mwp
->mFP
;
7414 SetRect(&limit_rect
, MIN_DOC_SIZE
, MIN_DOC_SIZE
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
7416 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
7418 /* see if it really changed size */
7421 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, HiWord (grow_size
));
7422 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, LoWord (grow_size
));
7424 x_set_window_size (f
, 0, columns
, rows
);
7429 /* Handle clicks in zoom box. Calculation of "standard state" based
7430 on code in IM - Window Manager A and code contributed by Ben
7431 Mesander. The standard state of an Emacs window is 80-characters
7432 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
7435 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
7438 Rect zoom_rect
, port_rect
;
7440 int w_title_height
, columns
, rows
, width
, height
, dummy
, x
, y
;
7441 mac_output
*mwp
= (mac_output
*) GetWRefCon (w
);
7442 struct frame
*f
= mwp
->mFP
;
7444 GetPort (&save_port
);
7446 #if TARGET_API_MAC_CARBON
7447 SetPort (GetWindowPort (w
));
7452 /* Clear window to avoid flicker. */
7453 #if TARGET_API_MAC_CARBON
7458 GetWindowPortBounds (w
, &r
);
7461 if (zoom_in_or_out
== inZoomOut
)
7463 /* calculate height of window's title bar (hard card it for now). */
7464 w_title_height
= 20 + GetMBarHeight ();
7466 /* get maximum height of window into zoom_rect.bottom -
7468 GetQDGlobalsScreenBits (&bm
);
7469 zoom_rect
= bm
.bounds
;
7470 zoom_rect
.top
+= w_title_height
;
7471 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7473 zoom_rect
.right
= zoom_rect
.left
7474 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7476 SetWindowStandardState (w
, &zoom_rect
);
7479 #else /* not TARGET_API_MAC_CARBON */
7480 EraseRect (&(w
->portRect
));
7481 if (zoom_in_or_out
== inZoomOut
)
7483 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
7484 LocalToGlobal (&top_left
);
7486 /* calculate height of window's title bar */
7487 w_title_height
= top_left
.v
- 1
7488 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
7490 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
7491 zoom_rect
= qd
.screenBits
.bounds
;
7492 zoom_rect
.top
+= w_title_height
;
7493 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
7495 zoom_rect
.right
= zoom_rect
.left
7496 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
7498 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
7501 #endif /* not TARGET_API_MAC_CARBON */
7503 ZoomWindow (w
, zoom_in_or_out
, w
== FrontWindow ());
7505 /* retrieve window size and update application values */
7506 #if TARGET_API_MAC_CARBON
7507 GetWindowPortBounds (w
, &port_rect
);
7509 port_rect
= w
->portRect
;
7511 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, port_rect
.bottom
- port_rect
.top
);
7512 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, port_rect
.right
- port_rect
.left
);
7513 x_set_window_size (mwp
->mFP
, 0, columns
, rows
);
7515 SetPort (save_port
);
7518 /* Initialize Drag And Drop to allow files to be dropped onto emacs frames */
7520 init_mac_drag_n_drop ()
7522 OSErr result
= InstallReceiveHandler (mac_do_receive_drag
, 0L, NULL
);
7526 /* Intialize AppleEvent dispatcher table for the required events. */
7528 init_required_apple_events ()
7533 /* Make sure we have apple events before starting. */
7534 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
7538 if (!(result
& (1 << gestaltAppleEventsPresent
)))
7541 #if TARGET_API_MAC_CARBON
7542 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7543 NewAEEventHandlerUPP
7544 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7547 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
7548 NewAEEventHandlerProc
7549 ((AEEventHandlerProcPtr
) do_ae_open_application
),
7555 #if TARGET_API_MAC_CARBON
7556 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7557 NewAEEventHandlerUPP
7558 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7561 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
7562 NewAEEventHandlerProc
7563 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
7569 #if TARGET_API_MAC_CARBON
7570 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7571 NewAEEventHandlerUPP
7572 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7575 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
7576 NewAEEventHandlerProc
7577 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
7583 #if TARGET_API_MAC_CARBON
7584 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7585 NewAEEventHandlerUPP
7586 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7589 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
7590 NewAEEventHandlerProc
7591 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
7598 #if USE_CARBON_EVENTS
7601 init_service_handler ()
7603 EventTypeSpec specs
[] = {{kEventClassService
, kEventServiceGetTypes
},
7604 {kEventClassService
, kEventServiceCopy
},
7605 {kEventClassService
, kEventServicePaste
}};
7606 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event
),
7607 3, specs
, NULL
, NULL
);
7611 MAC_TODO: Check to see if this is called by AEProcessDesc...
7614 mac_handle_service_event (EventHandlerCallRef callRef
,
7615 EventRef event
, void *data
)
7617 OSStatus err
= noErr
;
7618 switch (GetEventKind (event
))
7620 case kEventServiceGetTypes
:
7622 CFMutableArrayRef copyTypes
, pasteTypes
;
7624 Boolean selection
= true;
7626 GetEventParameter(event, kEventParamServicePasteTypes,
7627 typeCFMutableArrayRef, NULL,
7628 sizeof (CFMutableArrayRef), NULL, &pasteTypes);
7630 GetEventParameter(event
, kEventParamServiceCopyTypes
,
7631 typeCFMutableArrayRef
, NULL
,
7632 sizeof (CFMutableArrayRef
), NULL
, ©Types
);
7633 type
= CreateTypeStringWithOSType (kScrapFlavorTypeText
);
7635 CFArrayAppendValue (copyTypes
, type
);
7636 //CFArrayAppendValue (pasteTypes, type);
7640 case kEventServiceCopy
:
7642 ScrapRef currentScrap
, specificScrap
;
7646 GetCurrentScrap (¤tScrap
);
7648 err
= GetScrapFlavorSize (currentScrap
, kScrapFlavorTypeText
, &byteCount
);
7651 void *buffer
= xmalloc (byteCount
);
7654 GetEventParameter (event
, kEventParamScrapRef
, typeScrapRef
, NULL
,
7655 sizeof (ScrapRef
), NULL
, &specificScrap
);
7657 err
= GetScrapFlavorData (currentScrap
, kScrapFlavorTypeText
,
7658 &byteCount
, buffer
);
7660 PutScrapFlavor (specificScrap
, kScrapFlavorTypeText
,
7661 kScrapFlavorMaskNone
, byteCount
, buffer
);
7667 case kEventServicePaste
:
7670 // Get the current location
7672 ScrapRef specificScrap;
7673 GetEventParameter(event, kEventParamScrapRef, typeScrapRef, NULL,
7674 sizeof(ScrapRef), NULL, &specificScrap);
7675 err = GetScrapFlavorSize(specificScrap, kScrapFlavorTypeText, &byteCount);
7677 void * buffer = xmalloc(byteCount);
7678 if (buffer != NULL ) {
7679 err = GetScrapFlavorData(specificScrap, kScrapFlavorTypeText,
7680 &byteCount, buffer);
7682 // Actually place in the buffer
7684 // Get the current "selection" string here
7697 /* Open Application Apple Event */
7699 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
7705 /* Defined in mac.c. */
7707 path_from_vol_dir_name (char *, int, short, long, char *);
7710 /* Called when we receive an AppleEvent with an ID of
7711 "kAEOpenDocuments". This routine gets the direct parameter,
7712 extracts the FSSpecs in it, and puts their names on a list. */
7714 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
7719 DescType actual_type
;
7722 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
7724 goto descriptor_error_exit
;
7726 /* Check to see that we got all of the required parameters from the
7727 event descriptor. For an 'odoc' event this should just be the
7729 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
7730 &actual_type
, (Ptr
) &keyword
,
7731 sizeof (keyword
), &actual_size
);
7732 /* No error means that we found some unused parameters.
7733 errAEDescNotFound means that there are no more parameters. If we
7734 get an error code other than that, flag it. */
7735 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
7737 err
= errAEEventNotHandled
;
7742 /* Got all the parameters we need. Now, go through the direct
7743 object list and parse it up. */
7745 long num_files_to_open
;
7747 err
= AECountItems (&the_desc
, &num_files_to_open
);
7752 /* AE file list is one based so just use that for indexing here. */
7753 for (i
= 1; (err
== noErr
) && (i
<= num_files_to_open
); i
++)
7756 Str255 path_name
, unix_path_name
;
7761 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
7762 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
7763 if (err
!= noErr
) break;
7766 err
= FSpMakeFSRef (&fs
, &fref
);
7767 if (err
!= noErr
) break;
7769 if (FSRefMakePath (&fref
, unix_path_name
, 255) == noErr
)
7771 if (path_from_vol_dir_name (path_name
, 255, fs
.vRefNum
, fs
.parID
,
7773 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7775 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7776 drag_and_drop_file_list
);
7782 /* Nuke the coerced file list in any case */
7783 err2
= AEDisposeDesc(&the_desc
);
7785 descriptor_error_exit
:
7786 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
7792 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
7793 DragReference theDrag
)
7797 FlavorFlags theFlags
;
7800 ItemReference theItem
;
7803 Size size
= sizeof (HFSFlavor
);
7805 drag_and_drop_file_list
= Qnil
;
7806 GetDragMouse (theDrag
, &mouse
, 0L);
7807 CountDragItems (theDrag
, &items
);
7808 for (index
= 1; index
<= items
; index
++)
7810 /* Only handle file references. */
7811 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
7812 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
7813 if (result
== noErr
)
7820 Str255 unix_path_name
;
7821 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
7823 /* Use Carbon routines, otherwise it converts the file name
7824 to /Macintosh HD/..., which is not correct. */
7825 FSpMakeFSRef (&data
.fileSpec
, &fref
);
7826 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
7828 if (path_from_vol_dir_name (path_name
, 255, data
.fileSpec
.vRefNum
,
7829 data
.fileSpec
.parID
, data
.fileSpec
.name
) &&
7830 mac_to_posix_pathname (path_name
, unix_path_name
, 255))
7832 drag_and_drop_file_list
= Fcons (build_string (unix_path_name
),
7833 drag_and_drop_file_list
);
7838 /* If there are items in the list, construct an event and post it to
7839 the queue like an interrupt using kbd_buffer_store_event. */
7840 if (!NILP (drag_and_drop_file_list
))
7842 struct input_event event
;
7844 struct frame
*f
= ((mac_output
*) GetWRefCon(window
))->mFP
;
7845 SetPort (GetWindowPort (window
));
7846 GlobalToLocal (&mouse
);
7848 event
.kind
= DRAG_N_DROP_EVENT
;
7850 event
.modifiers
= 0;
7851 event
.timestamp
= TickCount () * (1000 / 60);
7852 XSETINT (event
.x
, mouse
.h
);
7853 XSETINT (event
.y
, mouse
.v
);
7854 XSETFRAME (frame
, f
);
7855 event
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
7857 /* Post to the interrupt queue */
7858 kbd_buffer_store_event (&event
);
7859 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
7861 ProcessSerialNumber psn
;
7862 GetCurrentProcess (&psn
);
7863 SetFrontProcess (&psn
);
7869 /* Print Document Apple Event */
7871 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
7873 return errAEEventNotHandled
;
7878 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
7880 /* FixMe: Do we need an unwind-protect or something here? And what
7881 do we do about unsaved files. Currently just forces quit rather
7882 than doing recursive callback to get user input. */
7884 terminate_flag
= true;
7886 /* Fkill_emacs doesn't return. We have to return. (TI) */
7893 profiler_exit_proc ()
7895 ProfilerDump ("\pEmacs.prof");
7900 /* These few functions implement Emacs as a normal Mac application
7901 (almost): set up the heap and the Toolbox, handle necessary
7902 system events plus a few simple menu events. They also set up
7903 Emacs's access to functions defined in the rest of this file.
7904 Emacs uses function hooks to perform all its terminal I/O. A
7905 complete list of these functions appear in termhooks.h. For what
7906 they do, read the comments there and see also w32term.c and
7907 xterm.c. What's noticeably missing here is the event loop, which
7908 is normally present in most Mac application. After performing the
7909 necessary Mac initializations, main passes off control to
7910 emacs_main (corresponding to main in emacs.c). Emacs_main calls
7911 mac_read_socket (defined further below) to read input. This is
7912 where WaitNextEvent is called to process Mac events. This is also
7913 where check_alarm in sysdep.c is called to simulate alarm signals.
7914 This makes the cursor jump back to its correct position after
7915 briefly jumping to that of the matching parenthesis, print useful
7916 hints and prompts in the minibuffer after the user stops typing for
7919 #if !TARGET_API_MAC_CARBON
7924 #if __profile__ /* is the profiler on? */
7925 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
7930 /* set creator and type for files created by MSL */
7935 do_init_managers ();
7940 do_check_ram_size ();
7943 init_emacs_passwd_dir ();
7947 initialize_applescript ();
7949 init_required_apple_events ();
7955 /* set up argv array from STR# resource */
7956 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
7960 /* free up AppleScript resources on exit */
7961 atexit (terminate_applescript
);
7963 #if __profile__ /* is the profiler on? */
7964 atexit (profiler_exit_proc
);
7967 /* 3rd param "envp" never used in emacs_main */
7968 (void) emacs_main (argc
, argv
, 0);
7971 /* Never reached - real exit in Fkill_emacs */
7976 /* Table for translating Mac keycode to X keysym values. Contributed
7977 by Sudhir Shenoy. */
7978 static unsigned char keycode_to_xkeysym_table
[] = {
7979 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7980 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7981 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7983 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
7984 /*0x34*/ 0, 0x1b /*escape*/, 0, 0,
7985 /*0x38*/ 0, 0, 0, 0,
7986 /*0x3C*/ 0, 0, 0, 0,
7988 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
7989 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x7f /*kp-clear*/,
7990 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
7991 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
7993 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
7994 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
7995 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
7996 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
7998 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
7999 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8000 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
8001 /*0x6C*/ 0, 0xc7 /*f10*/, 0, 0xc9 /*f12*/,
8003 /*0x70*/ 0, 0xcc /*f15*/, 0x9e /*insert (or 0x6a==help)*/, 0x95 /*home*/,
8004 /*0x74*/ 0x9a /*pgup*/, 0x9f /*delete*/, 0xc1 /*f4*/, 0x9c /*end*/,
8005 /*0x78*/ 0xbf /*f2*/, 0x9b /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8006 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8010 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
8012 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
8013 return *xKeySym
!= 0;
8016 /* Emacs calls this whenever it wants to read an input event from the
8019 XTread_socket (int sd
, int expected
, struct input_event
*hold_quit
)
8021 struct input_event inev
;
8023 #if USE_CARBON_EVENTS
8026 EventMouseButton mouseBtn
;
8030 EventMask event_mask
;
8033 if (interrupt_input_blocked
)
8035 interrupt_input_pending
= 1;
8040 interrupt_input_pending
= 0;
8043 /* So people can tell when we have read the available input. */
8044 input_signal_count
++;
8046 /* Don't poll for events to process (specifically updateEvt) if
8047 window update currently already in progress. A call to redisplay
8048 (in do_window_update) can be preempted by another call to
8049 redisplay, causing blank regions to be left on the screen and the
8050 cursor to be left at strange places. */
8051 if (handling_window_update
)
8058 Fkill_emacs (make_number (1));
8060 /* It is necessary to set this (additional) argument slot of an
8061 event to nil because keyboard.c protects incompletely processed
8062 event from being garbage collected by placing them in the
8063 kbd_buffer_gcpro vector. */
8065 inev
.kind
= NO_EVENT
;
8068 event_mask
= everyEvent
;
8069 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
8070 event_mask
-= highLevelEventMask
;
8072 #if USE_CARBON_EVENTS
8073 rneResult
= ReceiveNextEvent (0, NULL
,
8075 ? TicksToEventTime (app_sleep_time
)
8077 kEventRemoveFromQueue
, &eventRef
);
8080 /* Handle new events */
8081 if (!mac_convert_event_ref (eventRef
, &er
))
8082 switch (GetEventClass (eventRef
))
8084 case kEventClassMouse
:
8085 if (GetEventKind (eventRef
) == kEventMouseWheelMoved
)
8089 WindowPtr window_ptr
= FrontNonFloatingWindow ();
8090 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
8091 if (!IsValidWindowPtr (window_ptr
))
8098 GetEventParameter(eventRef
, kEventParamMouseWheelDelta
,
8099 typeSInt32
, NULL
, sizeof (SInt32
),
8101 GetEventParameter(eventRef
, kEventParamMouseLocation
,
8102 typeQDPoint
, NULL
, sizeof (Point
),
8104 inev
.kind
= WHEEL_EVENT
;
8106 inev
.modifiers
= (mac_event_to_emacs_modifiers(eventRef
)
8107 | ((delta
< 0) ? down_modifier
8109 SetPort (GetWindowPort (window_ptr
));
8110 GlobalToLocal (&point
);
8111 XSETINT (inev
.x
, point
.h
);
8112 XSETINT (inev
.y
, point
.v
);
8113 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8114 inev
.timestamp
= EventTimeToTicks (GetEventTime (eventRef
))*(1000/60);
8117 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
8121 /* Send the event to the appropriate receiver. */
8122 SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ());
8126 if (WaitNextEvent (event_mask
, &er
, (expected
? app_sleep_time
: 0L), NULL
))
8127 #endif /* USE_CARBON_EVENTS */
8133 WindowPtr window_ptr
= FrontWindow ();
8136 #if USE_CARBON_EVENTS
8137 /* This is needed to send mouse events like aqua window buttons
8138 to the correct handler. */
8139 if (eventNotHandledErr
!= SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ())) {
8143 if (!is_emacs_window(window_ptr
))
8147 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8148 && er
.what
== mouseUp
)
8150 struct mac_output
*mwp
= (mac_output
*) GetWRefCon (window_ptr
);
8151 Point mouse_loc
= er
.where
;
8153 /* Convert to local coordinates of new window. */
8154 #if TARGET_API_MAC_CARBON
8155 SetPort (GetWindowPort (window_ptr
));
8157 SetPort (window_ptr
);
8160 GlobalToLocal (&mouse_loc
);
8162 #if USE_CARBON_EVENTS
8163 inev
.code
= mac_get_mouse_btn (eventRef
);
8165 inev
.code
= mac_get_emulate_btn (er
.modifiers
);
8167 inev
.kind
= SCROLL_BAR_CLICK_EVENT
;
8168 inev
.frame_or_window
= tracked_scroll_bar
->window
;
8169 inev
.part
= scroll_bar_handle
;
8170 #if USE_CARBON_EVENTS
8171 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8173 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8175 inev
.modifiers
|= up_modifier
;
8176 inev
.timestamp
= er
.when
* (1000 / 60);
8177 /* ticks to milliseconds */
8179 XSETINT (inev
.x
, tracked_scroll_bar
->left
+ 2);
8180 XSETINT (inev
.y
, mouse_loc
.v
- 24);
8181 tracked_scroll_bar
->dragging
= Qnil
;
8182 mouse_tracking_in_progress
= mouse_tracking_none
;
8183 tracked_scroll_bar
= NULL
;
8187 part_code
= FindWindow (er
.where
, &window_ptr
);
8192 if (er
.what
== mouseDown
)
8194 struct frame
*f
= ((mac_output
*)
8195 GetWRefCon (FrontWindow ()))->mFP
;
8196 saved_menu_event_location
= er
.where
;
8197 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
8198 XSETFRAME (inev
.frame_or_window
, f
);
8203 if (window_ptr
!= FrontWindow ())
8204 SelectWindow (window_ptr
);
8207 SInt16 control_part_code
;
8209 struct mac_output
*mwp
= (mac_output
*)
8210 GetWRefCon (window_ptr
);
8211 Point mouse_loc
= er
.where
;
8213 /* convert to local coordinates of new window */
8214 #if TARGET_API_MAC_CARBON
8215 SetPort (GetWindowPort (window_ptr
));
8217 SetPort (window_ptr
);
8220 GlobalToLocal (&mouse_loc
);
8221 #if TARGET_API_MAC_CARBON
8222 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
8223 &control_part_code
);
8225 control_part_code
= FindControl (mouse_loc
, window_ptr
, &ch
);
8228 #if USE_CARBON_EVENTS
8229 inev
.code
= mac_get_mouse_btn (eventRef
);
8231 inev
.code
= mac_get_emulate_btn (er
.modifiers
);
8233 XSETINT (inev
.x
, mouse_loc
.h
);
8234 XSETINT (inev
.y
, mouse_loc
.v
);
8235 inev
.timestamp
= er
.when
* (1000 / 60);
8236 /* ticks to milliseconds */
8238 #if TARGET_API_MAC_CARBON
8241 if (control_part_code
!= 0)
8244 struct scroll_bar
*bar
= (struct scroll_bar
*)
8245 GetControlReference (ch
);
8246 x_scroll_bar_handle_click (bar
, control_part_code
, &er
,
8248 if (er
.what
== mouseDown
8249 && control_part_code
== kControlIndicatorPart
)
8251 mouse_tracking_in_progress
8252 = mouse_tracking_scroll_bar
;
8253 tracked_scroll_bar
= bar
;
8257 mouse_tracking_in_progress
= mouse_tracking_none
;
8258 tracked_scroll_bar
= NULL
;
8265 inev
.kind
= MOUSE_CLICK_EVENT
;
8266 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8267 if (er
.what
== mouseDown
)
8268 mouse_tracking_in_progress
8269 = mouse_tracking_mouse_movement
;
8271 mouse_tracking_in_progress
= mouse_tracking_none
;
8272 window
= window_from_coordinates (mwp
->mFP
, inev
.x
, inev
.y
, 0, 0, 0, 1);
8274 if (EQ (window
, mwp
->mFP
->tool_bar_window
))
8276 if (er
.what
== mouseDown
)
8277 handle_tool_bar_click (mwp
->mFP
, inev
.x
, inev
.y
, 1, 0);
8279 handle_tool_bar_click (mwp
->mFP
, inev
.x
, inev
.y
, 0,
8280 #if USE_CARBON_EVENTS
8281 mac_event_to_emacs_modifiers (eventRef
)
8290 #if USE_CARBON_EVENTS
8291 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8293 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8299 inev
.modifiers
|= down_modifier
;
8302 inev
.modifiers
|= up_modifier
;
8309 #if TARGET_API_MAC_CARBON
8310 if (er
.what
== mouseDown
)
8314 GetQDGlobalsScreenBits (&bm
);
8315 DragWindow (window_ptr
, er
.where
, &bm
.bounds
);
8317 #else /* not TARGET_API_MAC_CARBON */
8318 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
8319 #endif /* not TARGET_API_MAC_CARBON */
8323 if (TrackGoAway (window_ptr
, er
.where
))
8325 inev
.kind
= DELETE_WINDOW_EVENT
;
8326 XSETFRAME (inev
.frame_or_window
,
8327 ((mac_output
*) GetWRefCon (window_ptr
))->mFP
);
8331 /* window resize handling added --ben */
8333 if (er
.what
== mouseDown
)
8335 do_grow_window(window_ptr
, &er
);
8339 /* window zoom handling added --ben */
8342 if (TrackBox (window_ptr
, er
.where
, part_code
))
8343 do_zoom_window (window_ptr
, part_code
);
8355 #if USE_CARBON_EVENTS
8356 if (eventNotHandledErr
== SendEventToEventTarget (eventRef
, GetEventDispatcherTarget ()))
8364 int keycode
= (er
.message
& keyCodeMask
) >> 8;
8367 #if USE_CARBON_EVENTS
8368 /* When using Carbon Events, we need to pass raw keyboard events
8369 to the TSM ourselves. If TSM handles it, it will pass back
8370 noErr, otherwise it will pass back "eventNotHandledErr" and
8371 we can process it normally. */
8372 if ((!NILP (Vmac_pass_command_to_system
)
8373 || !(er
.modifiers
& cmdKey
))
8374 && (!NILP (Vmac_pass_control_to_system
)
8375 || !(er
.modifiers
& controlKey
)))
8378 err
= SendEventToEventTarget (eventRef
,
8379 GetEventDispatcherTarget ());
8380 if (err
!= eventNotHandledErr
)
8385 if (!IsValidWindowPtr (FrontNonFloatingWindow ()))
8394 if (keycode_to_xkeysym (keycode
, &xkeysym
))
8396 inev
.code
= 0xff00 | xkeysym
;
8397 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
8401 if (er
.modifiers
& (controlKey
|
8402 (NILP (Vmac_command_key_is_meta
) ? optionKey
8405 /* This code comes from Keyboard Resource, Appendix
8406 C of IM - Text. This is necessary since shift is
8407 ignored in KCHR table translation when option or
8408 command is pressed. It also does not translate
8409 correctly control-shift chars like C-% so mask off
8411 int new_modifiers
= er
.modifiers
& 0xe600;
8412 /* mask off option and command */
8413 int new_keycode
= keycode
| new_modifiers
;
8414 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8415 unsigned long some_state
= 0;
8416 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
8417 &some_state
) & 0xff;
8420 inev
.code
= er
.message
& charCodeMask
;
8421 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
8425 /* If variable mac-convert-keyboard-input-to-latin-1 is non-nil,
8426 convert non-ASCII characters typed at the Mac keyboard
8427 (presumed to be in the Mac Roman encoding) to iso-latin-1
8428 encoding before they are passed to Emacs. This enables the
8429 Mac keyboard to be used to enter non-ASCII iso-latin-1
8430 characters directly. */
8431 if (mac_keyboard_text_encoding
!= kTextEncodingMacRoman
8432 && inev
.kind
== ASCII_KEYSTROKE_EVENT
&& inev
.code
>= 128)
8434 static TECObjectRef converter
= NULL
;
8435 OSStatus the_err
= noErr
;
8436 OSStatus convert_status
= noErr
;
8438 if (converter
== NULL
)
8440 the_err
= TECCreateConverter (&converter
,
8441 kTextEncodingMacRoman
,
8442 mac_keyboard_text_encoding
);
8443 current_mac_keyboard_text_encoding
8444 = mac_keyboard_text_encoding
;
8446 else if (mac_keyboard_text_encoding
8447 != current_mac_keyboard_text_encoding
)
8449 /* Free the converter for the current encoding before
8450 creating a new one. */
8451 TECDisposeConverter (converter
);
8452 the_err
= TECCreateConverter (&converter
,
8453 kTextEncodingMacRoman
,
8454 mac_keyboard_text_encoding
);
8455 current_mac_keyboard_text_encoding
8456 = mac_keyboard_text_encoding
;
8459 if (the_err
== noErr
)
8461 unsigned char ch
= inev
.code
;
8462 ByteCount actual_input_length
, actual_output_length
;
8463 unsigned char outch
;
8465 convert_status
= TECConvertText (converter
, &ch
, 1,
8466 &actual_input_length
,
8468 &actual_output_length
);
8469 if (convert_status
== noErr
8470 && actual_input_length
== 1
8471 && actual_output_length
== 1)
8476 #if USE_CARBON_EVENTS
8477 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8479 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8484 = (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8485 XSETFRAME (inev
.frame_or_window
, mwp
->mFP
);
8488 inev
.timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
8491 case kHighLevelEvent
:
8492 drag_and_drop_file_list
= Qnil
;
8494 AEProcessAppleEvent(&er
);
8496 /* Build a DRAG_N_DROP_EVENT type event as is done in
8497 constuct_drag_n_drop in w32term.c. */
8498 if (!NILP (drag_and_drop_file_list
))
8500 struct frame
*f
= NULL
;
8504 wp
= FrontNonFloatingWindow ();
8508 struct frame
*f
= XFRAME (XCAR (Vframe_list
));
8509 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
8510 wp
= FrontNonFloatingWindow ();
8513 if (wp
&& is_emacs_window(wp
))
8514 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8516 inev
.kind
= DRAG_N_DROP_EVENT
;
8518 inev
.timestamp
= er
.when
* (1000 / 60);
8519 /* ticks to milliseconds */
8520 #if USE_CARBON_EVENTS
8521 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
8523 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
8526 XSETINT (inev
.x
, 0);
8527 XSETINT (inev
.y
, 0);
8529 XSETFRAME (frame
, f
);
8530 inev
.frame_or_window
= Fcons (frame
, drag_and_drop_file_list
);
8532 /* Regardless of whether Emacs was suspended or in the
8533 foreground, ask it to redraw its entire screen.
8534 Otherwise parts of the screen can be left in an
8535 inconsistent state. */
8537 #if TARGET_API_MAC_CARBON
8541 GetWindowPortBounds (wp
, &r
);
8542 InvalWindowRect (wp
, &r
);
8544 #else /* not TARGET_API_MAC_CARBON */
8545 InvalRect (&(wp
->portRect
));
8546 #endif /* not TARGET_API_MAC_CARBON */
8551 #if USE_CARBON_EVENTS
8552 ReleaseEvent (eventRef
);
8556 /* If the focus was just given to an autoraising frame,
8558 /* ??? This ought to be able to handle more than one such frame. */
8559 if (pending_autoraise_frame
)
8561 x_raise_frame (pending_autoraise_frame
);
8562 pending_autoraise_frame
= 0;
8565 #if !TARGET_API_MAC_CARBON
8566 check_alarm (); /* simulate the handling of a SIGALRM */
8570 static Point old_mouse_pos
= { -1, -1 };
8572 if (app_is_suspended
)
8574 old_mouse_pos
.h
= -1;
8575 old_mouse_pos
.v
= -1;
8583 struct scroll_bar
*sb
;
8585 wp
= FrontWindow ();
8586 if (is_emacs_window (wp
))
8588 f
= ((mac_output
*) GetWRefCon (wp
))->mFP
;
8590 #if TARGET_API_MAC_CARBON
8591 SetPort (GetWindowPort (wp
));
8596 GetMouse (&mouse_pos
);
8598 if (!EqualPt (mouse_pos
, old_mouse_pos
))
8600 if (mouse_tracking_in_progress
== mouse_tracking_scroll_bar
8601 && tracked_scroll_bar
)
8602 x_scroll_bar_note_movement (tracked_scroll_bar
,
8604 - XINT (tracked_scroll_bar
->top
),
8605 TickCount() * (1000 / 60));
8607 note_mouse_movement (f
, &mouse_pos
);
8609 old_mouse_pos
= mouse_pos
;
8615 if (inev
.kind
!= NO_EVENT
)
8617 kbd_buffer_store_event_hold (&inev
, hold_quit
);
8626 /* Need to override CodeWarrior's input function so no conversion is
8627 done on newlines Otherwise compiled functions in .elc files will be
8628 read incorrectly. Defined in ...:MSL C:MSL
8629 Common:Source:buffer_io.c. */
8632 __convert_to_newlines (unsigned char * p
, size_t * n
)
8638 __convert_from_newlines (unsigned char * p
, size_t * n
)
8645 /* Initialize the struct pointed to by MW to represent a new COLS x
8646 ROWS Macintosh window, using font with name FONTNAME and size
8649 NewMacWindow (FRAME_PTR fp
)
8652 #if TARGET_API_MAC_CARBON
8653 static int making_terminal_window
= 0;
8655 static int making_terminal_window
= 1;
8658 mwp
= fp
->output_data
.mac
;
8660 if (making_terminal_window
)
8662 if (!(mwp
->mWP
= GetNewCWindow (TERM_WINDOW_RESOURCE
, NULL
,
8665 making_terminal_window
= 0;
8668 if (!(mwp
->mWP
= GetNewCWindow (WINDOW_RESOURCE
, NULL
, (WindowPtr
) -1)))
8671 SetWRefCon (mwp
->mWP
, (long) mwp
);
8672 /* so that update events can find this mac_output struct */
8673 mwp
->mFP
= fp
; /* point back to emacs frame */
8675 #if TARGET_API_MAC_CARBON
8676 SetPort (GetWindowPort (mwp
->mWP
));
8683 SizeWindow (mwp
->mWP
, FRAME_PIXEL_WIDTH (fp
), FRAME_PIXEL_HEIGHT (fp
), false);
8684 ShowWindow (mwp
->mWP
);
8690 make_mac_frame (struct frame
*f
)
8692 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8696 f
->output_data
.mac
->cursor_pixel
= 0;
8697 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8698 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
8699 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
8701 FRAME_FONTSET (f
) = -1;
8702 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8703 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8704 f
->output_data
.mac
->explicit_parent
= 0;
8707 f
->border_width
= 0;
8709 f
->internal_border_width
= 0;
8711 f
->output_method
= output_mac
;
8716 f
->new_text_cols
= 0;
8717 f
->new_text_lines
= 0;
8721 make_mac_terminal_frame (struct frame
*f
)
8725 XSETFRAME (frame
, f
);
8727 f
->output_method
= output_mac
;
8728 f
->output_data
.mac
= (struct mac_output
*)
8729 xmalloc (sizeof (struct mac_output
));
8730 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8731 FRAME_FONTSET (f
) = -1;
8732 f
->output_data
.mac
->scroll_bar_foreground_pixel
= -1;
8733 f
->output_data
.mac
->scroll_bar_background_pixel
= -1;
8735 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8737 FRAME_COLS (f
) = 96;
8738 FRAME_LINES (f
) = 4;
8740 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8741 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8747 /* Need to be initialized for unshow_buffer in window.c. */
8748 selected_window
= f
->selected_window
;
8750 Fmodify_frame_parameters (frame
,
8751 Fcons (Fcons (Qfont
,
8752 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
8753 Fmodify_frame_parameters (frame
,
8754 Fcons (Fcons (Qforeground_color
,
8755 build_string ("black")), Qnil
));
8756 Fmodify_frame_parameters (frame
,
8757 Fcons (Fcons (Qbackground_color
,
8758 build_string ("white")), Qnil
));
8762 /***********************************************************************
8764 ***********************************************************************/
8766 int mac_initialized
= 0;
8769 mac_initialize_display_info ()
8771 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
8772 GDHandle main_device_handle
;
8774 bzero (dpyinfo
, sizeof (*dpyinfo
));
8776 /* Put it on x_display_name_list. */
8777 x_display_name_list
= Fcons (Fcons (build_string ("Mac"), Qnil
),
8778 x_display_name_list
);
8779 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
8782 dpyinfo
->mac_id_name
8783 = (char *) xmalloc (SCHARS (Vinvocation_name
)
8784 + SCHARS (Vsystem_name
)
8786 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
8787 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
8789 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
8790 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
8793 main_device_handle
= LMGetMainDevice();
8795 dpyinfo
->reference_count
= 0;
8796 dpyinfo
->resx
= 75.0;
8797 dpyinfo
->resy
= 75.0;
8798 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
8799 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8800 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
8801 gdDevType
, dpyinfo
->color_p
))
8803 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8804 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8805 dpyinfo
->grabbed
= 0;
8806 dpyinfo
->root_window
= NULL
;
8807 dpyinfo
->image_cache
= make_image_cache ();
8809 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
8810 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
8811 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
8812 dpyinfo
->mouse_face_window
= Qnil
;
8815 struct mac_display_info
*
8816 mac_term_init (display_name
, xrm_option
, resource_name
)
8817 Lisp_Object display_name
;
8819 char *resource_name
;
8821 struct mac_display_info
*dpyinfo
;
8822 GDHandle main_device_handle
;
8824 if (!mac_initialized
)
8827 mac_initialized
= 1;
8830 mac_initialize_display_info (display_name
);
8832 dpyinfo
= &one_mac_display_info
;
8834 main_device_handle
= LMGetMainDevice();
8836 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
8837 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
8846 extern int inhibit_window_system
;
8847 extern int noninteractive
;
8848 CFBundleRef appsBundle
;
8851 /* No need to test if already -nw*/
8852 if (inhibit_window_system
|| noninteractive
)
8855 appsBundle
= CFBundleGetMainBundle();
8856 if (appsBundle
!= NULL
)
8858 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
8859 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
8860 /* We found the bundle identifier, now we know we are valid. */
8867 /* MAC_TODO: Have this start the bundled executable */
8869 /* For now, prevent the fatal error by bringing it up in the terminal */
8870 inhibit_window_system
= 1;
8874 MakeMeTheFrontProcess ()
8876 ProcessSerialNumber psn
;
8879 err
= GetCurrentProcess (&psn
);
8881 (void) SetFrontProcess (&psn
);
8884 /***** Code to handle C-g testing *****/
8886 /* Contains the Mac modifier formed from quit_char */
8887 static mac_quit_char_modifiers
= 0;
8888 static mac_quit_char_keycode
;
8889 extern int quit_char
;
8892 mac_determine_quit_char_modifiers()
8894 /* Todo: Determine modifiers from quit_char. */
8895 UInt32 qc_modifiers
= ctrl_modifier
;
8898 mac_quit_char_modifiers
= 0;
8899 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
8900 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
8901 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
8902 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
8906 init_quit_char_handler ()
8908 /* TODO: Let this support keys other the 'g' */
8909 mac_quit_char_keycode
= 5;
8910 /* Look at <architecture/adb_kb_map.h> for details */
8911 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
8913 mac_determine_quit_char_modifiers();
8917 quit_char_comp (EventRef inEvent
, void *inCompData
)
8919 if (GetEventClass(inEvent
) != kEventClassKeyboard
)
8921 if (GetEventKind(inEvent
) != kEventRawKeyDown
)
8925 UInt32 keyModifiers
;
8926 GetEventParameter(inEvent
, kEventParamKeyCode
,
8927 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
8928 if (keyCode
!= mac_quit_char_keycode
)
8930 GetEventParameter(inEvent
, kEventParamKeyModifiers
,
8931 typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyModifiers
);
8932 if (keyModifiers
!= mac_quit_char_modifiers
)
8939 mac_check_for_quit_char ()
8942 static EMACS_TIME last_check_time
= { 0, 0 };
8943 static EMACS_TIME one_second
= { 1, 0 };
8946 /* If windows are not initialized, return immediately (keep it bouncin'). */
8947 if (!mac_quit_char_modifiers
)
8950 /* Don't check if last check is less than a second ago. */
8951 EMACS_GET_TIME (now
);
8952 EMACS_SUB_TIME (t
, now
, last_check_time
);
8953 if (EMACS_TIME_LT (t
, one_second
))
8955 last_check_time
= now
;
8957 /* Redetermine modifiers because they are based on lisp variables */
8958 mac_determine_quit_char_modifiers ();
8960 /* Fill the queue with events */
8961 ReceiveNextEvent (0, NULL
, kEventDurationNoWait
, false, &event
);
8962 event
= FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp
,
8966 struct input_event e
;
8967 struct mac_output
*mwp
=
8968 (mac_output
*) GetWRefCon (FrontNonFloatingWindow ());
8969 /* Use an input_event to emulate what the interrupt handler does. */
8971 e
.kind
= ASCII_KEYSTROKE_EVENT
;
8975 e
.timestamp
= EventTimeToTicks (GetEventTime (event
)) * (1000/60);
8976 XSETFRAME (e
.frame_or_window
, mwp
->mFP
);
8977 /* Remove event from queue to prevent looping. */
8978 RemoveEventFromQueue (GetMainEventQueue (), event
);
8979 ReleaseEvent (event
);
8980 kbd_buffer_store_event (&e
);
8984 #endif /* MAC_OSX */
8986 /* Set up use of X before we make the first connection. */
8988 extern frame_parm_handler mac_frame_parm_handlers
[];
8990 static struct redisplay_interface x_redisplay_interface
=
8992 mac_frame_parm_handlers
,
8996 x_clear_end_of_line
,
8998 x_after_update_window_line
,
8999 x_update_window_begin
,
9000 x_update_window_end
,
9004 x_clear_window_mouse_face
,
9005 x_get_glyph_overhangs
,
9006 x_fix_overlapping_area
,
9007 x_draw_fringe_bitmap
,
9008 0, /* define_fringe_bitmap */
9009 0, /* destroy_fringe_bitmap */
9010 mac_per_char_metric
,
9012 NULL
, /* mac_compute_glyph_string_overhangs */
9013 x_draw_glyph_string
,
9014 mac_define_frame_cursor
,
9015 mac_clear_frame_area
,
9016 mac_draw_window_cursor
,
9017 mac_draw_vertical_window_border
,
9018 mac_shift_glyphs_for_insert
9024 rif
= &x_redisplay_interface
;
9026 clear_frame_hook
= x_clear_frame
;
9027 ins_del_lines_hook
= x_ins_del_lines
;
9028 delete_glyphs_hook
= x_delete_glyphs
;
9029 ring_bell_hook
= XTring_bell
;
9030 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9031 set_terminal_modes_hook
= XTset_terminal_modes
;
9032 update_begin_hook
= x_update_begin
;
9033 update_end_hook
= x_update_end
;
9034 set_terminal_window_hook
= XTset_terminal_window
;
9035 read_socket_hook
= XTread_socket
;
9036 frame_up_to_date_hook
= XTframe_up_to_date
;
9037 mouse_position_hook
= XTmouse_position
;
9038 frame_rehighlight_hook
= XTframe_rehighlight
;
9039 frame_raise_lower_hook
= XTframe_raise_lower
;
9041 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9042 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9043 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9044 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9046 scroll_region_ok
= 1; /* we'll scroll partial frames */
9047 char_ins_del_ok
= 1;
9048 line_ins_del_ok
= 1; /* we'll just blt 'em */
9049 fast_clear_end_of_line
= 1; /* X does this well */
9050 memory_below_frame
= 0; /* we don't remember what scrolls
9055 last_tool_bar_item
= -1;
9056 any_help_event_p
= 0;
9058 /* Try to use interrupt input; if we can't, then start polling. */
9059 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9061 #ifdef USE_X_TOOLKIT
9062 XtToolkitInitialize ();
9063 Xt_app_con
= XtCreateApplicationContext ();
9064 XtAppSetFallbackResources (Xt_app_con
, Xt_default_resources
);
9066 /* Install an asynchronous timer that processes Xt timeout events
9067 every 0.1s. This is necessary because some widget sets use
9068 timeouts internally, for example the LessTif menu bar, or the
9069 Xaw3d scroll bar. When Xt timouts aren't processed, these
9070 widgets don't behave normally. */
9072 EMACS_TIME interval
;
9073 EMACS_SET_SECS_USECS (interval
, 0, 100000);
9074 start_atimer (ATIMER_CONTINUOUS
, interval
, x_process_timeouts
, 0);
9078 #if USE_TOOLKIT_SCROLL_BARS
9079 xaw3d_arrow_scroll
= False
;
9080 xaw3d_pick_top
= True
;
9084 /* Note that there is no real way portable across R3/R4 to get the
9085 original error handler. */
9086 XSetErrorHandler (x_error_handler
);
9087 XSetIOErrorHandler (x_io_error_quitter
);
9089 /* Disable Window Change signals; they are handled by X events. */
9091 signal (SIGWINCH
, SIG_DFL
);
9092 #endif /* ! defined (SIGWINCH) */
9094 signal (SIGPIPE
, x_connection_signal
);
9097 mac_initialize_display_info ();
9099 #if TARGET_API_MAC_CARBON
9100 init_required_apple_events ();
9102 init_mac_drag_n_drop ();
9104 #if USE_CARBON_EVENTS
9105 init_service_handler ();
9107 init_quit_char_handler ();
9110 DisableMenuCommand (NULL
, kHICommandQuit
);
9112 if (!inhibit_window_system
)
9113 MakeMeTheFrontProcess ();
9122 staticpro (&x_error_message_string
);
9123 x_error_message_string
= Qnil
;
9126 Fprovide (intern ("mac-carbon"), Qnil
);
9128 staticpro (&Qreverse
);
9129 Qreverse
= intern ("reverse");
9131 staticpro (&x_display_name_list
);
9132 x_display_name_list
= Qnil
;
9134 staticpro (&last_mouse_scroll_bar
);
9135 last_mouse_scroll_bar
= Qnil
;
9137 staticpro (&Qvendor_specific_keysyms
);
9138 Qvendor_specific_keysyms
= intern ("vendor-specific-keysyms");
9140 staticpro (&last_mouse_press_frame
);
9141 last_mouse_press_frame
= Qnil
;
9143 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
9144 staticpro (&Qmac_ready_for_drag_n_drop
);
9146 Qbig5
= intern ("big5");
9149 Qcn_gb
= intern ("cn-gb");
9150 staticpro (&Qcn_gb
);
9152 Qsjis
= intern ("sjis");
9155 Qeuc_kr
= intern ("euc-kr");
9156 staticpro (&Qeuc_kr
);
9158 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p
,
9159 doc
: /* *Non-nil means autoselect window with mouse pointer. */);
9160 x_autoselect_window_p
= 0;
9162 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9163 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9164 Vx_toolkit_scroll_bars
= Qt
;
9166 DEFVAR_BOOL ("x-use-underline-position-properties",
9167 &x_use_underline_position_properties
,
9168 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9169 nil means ignore them. If you encounter fonts with bogus
9170 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9171 to 4.1, set this to nil. */);
9172 x_use_underline_position_properties
= 0;
9174 staticpro (&last_mouse_motion_frame
);
9175 last_mouse_motion_frame
= Qnil
;
9177 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
9178 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
9179 Otherwise the option key is used. */);
9180 Vmac_command_key_is_meta
= Qt
;
9182 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
9183 doc
: /* Non-nil means that the control and meta keys are reversed. This is
9184 useful for non-standard keyboard layouts. */);
9185 Vmac_reverse_ctrl_meta
= Qnil
;
9187 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9188 &Vmac_emulate_three_button_mouse
,
9189 doc
: /* t means that when the option-key is held down while pressing the
9190 mouse button, the click will register as mouse-2 and while the
9191 command-key is held down, the click will register as mouse-3.
9192 'reverse means that the the option-key will register for mouse-3
9193 and the command-key will register for mouse-2. nil means that
9194 not emulation should be done and the modifiers should be placed
9195 on the mouse-1 event. */);
9196 Vmac_emulate_three_button_mouse
= Qnil
;
9198 #if USE_CARBON_EVENTS
9199 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
9200 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
9201 the right click will be mouse-3.
9202 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
9203 Vmac_wheel_button_is_mouse_2
= Qt
;
9205 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
9206 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
9207 Toolbox for processing before Emacs sees it. */);
9208 Vmac_pass_command_to_system
= Qt
;
9210 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
9211 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
9212 Toolbox for processing before Emacs sees it. */);
9213 Vmac_pass_control_to_system
= Qt
;
9216 DEFVAR_INT ("mac-keyboard-text-encoding", &mac_keyboard_text_encoding
,
9217 doc
: /* One of the Text Encoding Base constant values defined in the
9218 Basic Text Constants section of Inside Macintosh - Text Encoding
9219 Conversion Manager. Its value determines the encoding characters
9220 typed at the Mac keyboard (presumed to be in the MacRoman encoding)
9221 will convert into. E.g., if it is set to kTextEncodingMacRoman (0),
9222 its default value, no conversion takes place. If it is set to
9223 kTextEncodingISOLatin1 (0x201) or kTextEncodingISOLatin2 (0x202),
9224 characters typed on Mac keyboard are first converted into the
9225 ISO Latin-1 or ISO Latin-2 encoding, respectively before being
9226 passed to Emacs. Together with Emacs's set-keyboard-coding-system
9227 command, this enables the Mac keyboard to be used to enter non-ASCII
9228 characters directly. */);
9229 mac_keyboard_text_encoding
= kTextEncodingMacRoman
;
9232 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9233 (do not change this comment) */