1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* Contributed by Andrew Choi (akochoi@mac.com). */
30 #include "blockinput.h"
38 #if TARGET_API_MAC_CARBON
39 /* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
40 obtain events from the event queue. If set to 0, WaitNextEvent is
42 #define USE_CARBON_EVENTS 1
43 #else /* not TARGET_API_MAC_CARBON */
44 #include <Quickdraw.h>
45 #include <ToolUtils.h>
49 #include <Resources.h>
51 #include <TextUtils.h>
55 #if defined (__MRC__) || (__MSL__ >= 0x6000)
56 #include <ControlDefinitions.h>
62 #endif /* not TARGET_API_MAC_CARBON */
71 #include <sys/param.h>
76 #include "dispextern.h"
78 #include "termhooks.h"
86 #include "intervals.h"
90 /* Set of macros that handle mapping of Mac modifier keys to emacs. */
91 #define macCtrlKey (NILP (Vmac_reverse_ctrl_meta) ? controlKey : \
92 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
93 #define macShiftKey (shiftKey)
94 #define macMetaKey (NILP (Vmac_reverse_ctrl_meta) ? \
95 (NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
97 #define macAltKey (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
100 /* Non-nil means Emacs uses toolkit scroll bars. */
102 Lisp_Object Vx_toolkit_scroll_bars
;
104 /* If Non-nil, the text will be rendered using Core Graphics text rendering which may anti-alias the text. */
105 Lisp_Object Vmac_use_core_graphics
;
108 /* Non-zero means that a HELP_EVENT has been generated since Emacs
111 static int any_help_event_p
;
113 /* Last window where we saw the mouse. Used by mouse-autoselect-window. */
114 static Lisp_Object last_window
;
116 /* This is a chain of structures for all the X displays currently in
119 struct x_display_info
*x_display_list
;
121 /* This is a list of cons cells, each of the form (NAME
122 FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
123 x_display_list and in the same order. NAME is the name of the
124 frame. FONT-LIST-CACHE records previous values returned by
125 x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
126 equivalent, which is implemented with a Lisp object, for the
129 Lisp_Object x_display_name_list
;
131 /* This is display since Mac does not support multiple ones. */
132 struct mac_display_info one_mac_display_info
;
134 /* Frame being updated by update_frame. This is declared in term.c.
135 This is set by update_begin and looked at by all the XT functions.
136 It is zero while not inside an update. In that case, the XT
137 functions assume that `selected_frame' is the frame to apply to. */
139 extern struct frame
*updating_frame
;
141 /* This is a frame waiting to be auto-raised, within XTread_socket. */
143 struct frame
*pending_autoraise_frame
;
147 Formerly, we used PointerMotionHintMask (in standard_event_mask)
148 so that we would have to call XQueryPointer after each MotionNotify
149 event to ask for another such event. However, this made mouse tracking
150 slow, and there was a bug that made it eventually stop.
152 Simply asking for MotionNotify all the time seems to work better.
154 In order to avoid asking for motion events and then throwing most
155 of them away or busy-polling the server for mouse positions, we ask
156 the server for pointer motion hints. This means that we get only
157 one event per group of mouse movements. "Groups" are delimited by
158 other kinds of events (focus changes and button clicks, for
159 example), or by XQueryPointer calls; when one of these happens, we
160 get another MotionNotify event the next time the mouse moves. This
161 is at least as efficient as getting motion events when mouse
162 tracking is on, and I suspect only negligibly worse when tracking
165 /* Where the mouse was last time we reported a mouse event. */
167 static Rect last_mouse_glyph
;
169 /* The scroll bar in which the last X motion event occurred.
171 If the last X motion event occurred in a scroll bar, we set this so
172 XTmouse_position can know whether to report a scroll bar motion or
175 If the last X motion event didn't occur in a scroll bar, we set
176 this to Qnil, to tell XTmouse_position to return an ordinary motion
179 static Lisp_Object last_mouse_scroll_bar
;
181 /* This is a hack. We would really prefer that XTmouse_position would
182 return the time associated with the position it returns, but there
183 doesn't seem to be any way to wrest the time-stamp from the server
184 along with the position query. So, we just keep track of the time
185 of the last movement we received, and return that in hopes that
186 it's somewhat accurate. */
188 static Time last_mouse_movement_time
;
190 struct scroll_bar
*tracked_scroll_bar
= NULL
;
192 /* Incremented by XTread_socket whenever it really tries to read
196 static int volatile input_signal_count
;
198 static int input_signal_count
;
201 extern Lisp_Object Vsystem_name
;
203 /* A mask of extra modifier bits to put into every keyboard char. */
205 extern EMACS_INT extra_keyboard_modifiers
;
207 /* The keysyms to use for the various modifiers. */
209 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qmodifier_value
;
211 extern int inhibit_window_system
;
213 #if __MRC__ && !TARGET_API_MAC_CARBON
214 QDGlobals qd
; /* QuickDraw global information structure. */
217 #define mac_window_to_frame(wp) (((mac_output *) GetWRefCon (wp))->mFP)
219 struct mac_display_info
*mac_display_info_for_display (Display
*);
220 static void x_update_window_end
P_ ((struct window
*, int, int));
221 static int x_io_error_quitter
P_ ((Display
*));
222 int x_catch_errors
P_ ((Display
*));
223 void x_uncatch_errors
P_ ((Display
*, int));
224 void x_lower_frame
P_ ((struct frame
*));
225 void x_scroll_bar_clear
P_ ((struct frame
*));
226 int x_had_errors_p
P_ ((Display
*));
227 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
228 void x_raise_frame
P_ ((struct frame
*));
229 void x_set_window_size
P_ ((struct frame
*, int, int, int));
230 void x_wm_set_window_state
P_ ((struct frame
*, int));
231 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
232 void mac_initialize
P_ ((void));
233 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
234 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
235 static void x_update_end
P_ ((struct frame
*));
236 static void XTframe_up_to_date
P_ ((struct frame
*));
237 static void XTset_terminal_modes
P_ ((void));
238 static void XTreset_terminal_modes
P_ ((void));
239 static void x_clear_frame
P_ ((void));
240 static void frame_highlight
P_ ((struct frame
*));
241 static void frame_unhighlight
P_ ((struct frame
*));
242 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
243 static void mac_focus_changed
P_ ((int, struct mac_display_info
*,
244 struct frame
*, struct input_event
*));
245 static void x_detect_focus_change
P_ ((struct mac_display_info
*,
246 EventRecord
*, struct input_event
*));
247 static void XTframe_rehighlight
P_ ((struct frame
*));
248 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
249 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
250 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
251 enum text_cursor_kinds
));
253 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
254 static void x_flush
P_ ((struct frame
*f
));
255 static void x_update_begin
P_ ((struct frame
*));
256 static void x_update_window_begin
P_ ((struct window
*));
257 static void x_after_update_window_line
P_ ((struct glyph_row
*));
258 static void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
259 enum scroll_bar_part
*,
260 Lisp_Object
*, Lisp_Object
*,
263 static int is_emacs_window
P_ ((WindowPtr
));
265 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
267 /* Defined in macmenu.h. */
268 extern void menubar_selection_callback (FRAME_PTR
, int);
270 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
271 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
272 #define GC_FONT(gc) ((gc)->xgcv.font)
273 #define GC_CLIP_REGION(gc) ((gc)->clip_region)
274 #define MAC_WINDOW_NORMAL_GC(w) (((mac_output *) GetWRefCon (w))->normal_gc)
276 static RgnHandle saved_port_clip_region
= NULL
;
279 mac_begin_clip (region
)
282 static RgnHandle new_region
= NULL
;
284 if (saved_port_clip_region
== NULL
)
285 saved_port_clip_region
= NewRgn ();
286 if (new_region
== NULL
)
287 new_region
= NewRgn ();
291 GetClip (saved_port_clip_region
);
292 SectRgn (saved_port_clip_region
, region
, new_region
);
293 SetClip (new_region
);
298 mac_end_clip (region
)
302 SetClip (saved_port_clip_region
);
306 /* X display function emulation */
309 XFreePixmap (display
, pixmap
)
310 Display
*display
; /* not used */
313 DisposeGWorld (pixmap
);
317 /* Mac version of XDrawLine. */
320 XDrawLine (display
, w
, gc
, x1
, y1
, x2
, y2
)
326 SetPortWindowPort (w
);
328 RGBForeColor (GC_FORE_COLOR (gc
));
330 mac_begin_clip (GC_CLIP_REGION (gc
));
333 mac_end_clip (GC_CLIP_REGION (gc
));
337 mac_draw_line_to_pixmap (display
, p
, gc
, x1
, y1
, x2
, y2
)
346 GetGWorld (&old_port
, &old_gdh
);
349 RGBForeColor (GC_FORE_COLOR (gc
));
351 LockPixels (GetGWorldPixMap (p
));
354 UnlockPixels (GetGWorldPixMap (p
));
356 SetGWorld (old_port
, old_gdh
);
361 mac_erase_rectangle (w
, gc
, x
, y
, width
, height
)
365 unsigned int width
, height
;
369 SetPortWindowPort (w
);
371 RGBBackColor (GC_BACK_COLOR (gc
));
372 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
374 mac_begin_clip (GC_CLIP_REGION (gc
));
376 mac_end_clip (GC_CLIP_REGION (gc
));
378 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
382 /* Mac version of XClearArea. */
385 XClearArea (display
, w
, x
, y
, width
, height
, exposures
)
389 unsigned int width
, height
;
392 mac_erase_rectangle (w
, MAC_WINDOW_NORMAL_GC (w
), x
, y
, width
, height
);
395 /* Mac version of XClearWindow. */
398 XClearWindow (display
, w
)
402 SetPortWindowPort (w
);
404 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
406 #if TARGET_API_MAC_CARBON
410 GetWindowPortBounds (w
, &r
);
413 #else /* not TARGET_API_MAC_CARBON */
414 EraseRect (&(w
->portRect
));
415 #endif /* not TARGET_API_MAC_CARBON */
419 /* Mac replacement for XCopyArea. */
422 mac_draw_bitmap (display
, w
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
426 int x
, y
, width
, height
;
427 unsigned short *bits
;
433 bitmap
.rowBytes
= sizeof(unsigned short);
434 bitmap
.baseAddr
= (char *)bits
;
435 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
437 SetPortWindowPort (w
);
439 RGBForeColor (GC_FORE_COLOR (gc
));
440 RGBBackColor (GC_BACK_COLOR (gc
));
441 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
443 mac_begin_clip (GC_CLIP_REGION (gc
));
444 #if TARGET_API_MAC_CARBON
445 LockPortBits (GetWindowPort (w
));
446 CopyBits (&bitmap
, GetPortBitMapForCopyBits (GetWindowPort (w
)),
447 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
448 UnlockPortBits (GetWindowPort (w
));
449 #else /* not TARGET_API_MAC_CARBON */
450 CopyBits (&bitmap
, &(w
->portBits
), &(bitmap
.bounds
), &r
,
451 overlay_p
? srcOr
: srcCopy
, 0);
452 #endif /* not TARGET_API_MAC_CARBON */
453 mac_end_clip (GC_CLIP_REGION (gc
));
455 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
459 /* Mac replacement for XCreateBitmapFromBitmapData. */
462 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
467 static unsigned char swap_nibble
[16]
468 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
469 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
470 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
471 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
475 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
476 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
477 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
478 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
479 for (i
= 0; i
< h
; i
++)
481 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
482 for (j
= 0; j
< w1
; j
++)
484 /* Bitswap XBM bytes to match how Mac does things. */
485 unsigned char c
= *bits
++;
486 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
487 | (swap_nibble
[(c
>>4) & 0xf]));;
491 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
496 mac_free_bitmap (bitmap
)
499 xfree (bitmap
->baseAddr
);
504 XCreatePixmap (display
, w
, width
, height
, depth
)
505 Display
*display
; /* not used */
507 unsigned int width
, height
;
514 SetPortWindowPort (w
);
516 SetRect (&r
, 0, 0, width
, height
);
517 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
525 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
526 Display
*display
; /* not used */
529 unsigned int width
, height
;
530 unsigned long fg
, bg
;
537 static GC gc
= NULL
; /* not reentrant */
540 gc
= XCreateGC (display
, w
, 0, NULL
);
542 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
546 GetGWorld (&old_port
, &old_gdh
);
547 SetGWorld (pixmap
, NULL
);
548 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
549 XSetForeground (display
, gc
, fg
);
550 XSetBackground (display
, gc
, bg
);
551 RGBForeColor (GC_FORE_COLOR (gc
));
552 RGBBackColor (GC_BACK_COLOR (gc
));
553 LockPixels (GetGWorldPixMap (pixmap
));
554 #if TARGET_API_MAC_CARBON
555 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
556 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
557 #else /* not TARGET_API_MAC_CARBON */
558 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
559 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
560 #endif /* not TARGET_API_MAC_CARBON */
561 UnlockPixels (GetGWorldPixMap (pixmap
));
562 SetGWorld (old_port
, old_gdh
);
563 mac_free_bitmap (&bitmap
);
569 /* Mac replacement for XFillRectangle. */
572 XFillRectangle (display
, w
, gc
, x
, y
, width
, height
)
577 unsigned int width
, height
;
581 SetPortWindowPort (w
);
583 RGBForeColor (GC_FORE_COLOR (gc
));
584 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
586 mac_begin_clip (GC_CLIP_REGION (gc
));
587 PaintRect (&r
); /* using foreground color of gc */
588 mac_end_clip (GC_CLIP_REGION (gc
));
592 #if 0 /* TODO: figure out if we need to do this on Mac. */
594 mac_fill_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
599 unsigned int width
, height
;
605 GetGWorld (&old_port
, &old_gdh
);
607 RGBForeColor (GC_FORE_COLOR (gc
));
608 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
610 LockPixels (GetGWorldPixMap (p
));
611 PaintRect (&r
); /* using foreground color of gc */
612 UnlockPixels (GetGWorldPixMap (p
));
614 SetGWorld (old_port
, old_gdh
);
619 /* Mac replacement for XDrawRectangle: dest is a window. */
622 mac_draw_rectangle (display
, w
, gc
, x
, y
, width
, height
)
627 unsigned int width
, height
;
631 SetPortWindowPort (w
);
633 RGBForeColor (GC_FORE_COLOR (gc
));
634 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
636 mac_begin_clip (GC_CLIP_REGION (gc
));
637 FrameRect (&r
); /* using foreground color of gc */
638 mac_end_clip (GC_CLIP_REGION (gc
));
642 #if 0 /* TODO: figure out if we need to do this on Mac. */
643 /* Mac replacement for XDrawRectangle: dest is a Pixmap. */
646 mac_draw_rectangle_to_pixmap (display
, p
, gc
, x
, y
, width
, height
)
651 unsigned int width
, height
;
657 GetGWorld (&old_port
, &old_gdh
);
659 RGBForeColor (GC_FORE_COLOR (gc
));
660 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
662 LockPixels (GetGWorldPixMap (p
));
663 FrameRect (&r
); /* using foreground color of gc */
664 UnlockPixels (GetGWorldPixMap (p
));
666 SetGWorld (old_port
, old_gdh
);
673 atsu_get_text_layout_with_text_ptr (text
, text_length
, style
, text_layout
)
674 ConstUniCharArrayPtr text
;
675 UniCharCount text_length
;
677 ATSUTextLayout
*text_layout
;
680 static ATSUTextLayout saved_text_layout
= NULL
; /* not reentrant */
682 if (saved_text_layout
== NULL
)
684 UniCharCount lengths
[] = {kATSUToTextEnd
};
685 ATSUAttributeTag tags
[] = {kATSULineLayoutOptionsTag
};
686 ByteCount sizes
[] = {sizeof (ATSLineLayoutOptions
)};
687 static ATSLineLayoutOptions line_layout
=
688 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
689 kATSLineDisableAllLayoutOperations
| kATSLineUseDeviceMetrics
691 kATSLineIsDisplayOnly
| kATSLineFractDisable
694 ATSUAttributeValuePtr values
[] = {&line_layout
};
696 err
= ATSUCreateTextLayoutWithTextPtr (text
,
697 kATSUFromTextBeginning
,
703 err
= ATSUSetLayoutControls (saved_text_layout
,
704 sizeof (tags
) / sizeof (tags
[0]),
705 tags
, sizes
, values
);
706 /* XXX: Should we do this? */
708 err
= ATSUSetTransientFontMatching (saved_text_layout
, true);
712 err
= ATSUSetRunStyle (saved_text_layout
, style
,
713 kATSUFromTextBeginning
, kATSUToTextEnd
);
715 err
= ATSUSetTextPointerLocation (saved_text_layout
, text
,
716 kATSUFromTextBeginning
,
722 *text_layout
= saved_text_layout
;
728 mac_invert_rectangle (display
, w
, x
, y
, width
, height
)
732 unsigned int width
, height
;
736 SetPortWindowPort (w
);
738 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
745 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, mode
,
752 int nchars
, mode
, bytes_per_char
;
754 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
755 UInt32 textFlags
, savedFlags
;
756 if (!NILP(Vmac_use_core_graphics
)) {
757 textFlags
= kQDUseCGTextRendering
;
758 savedFlags
= SwapQDTextFlags(textFlags
);
762 SetPortWindowPort (w
);
764 RGBForeColor (GC_FORE_COLOR (gc
));
766 RGBBackColor (GC_BACK_COLOR (gc
));
769 if (GC_FONT (gc
)->mac_style
)
772 ATSUTextLayout text_layout
;
774 xassert (bytes_per_char
== 2);
776 #ifndef WORDS_BIG_ENDIAN
779 Unichar
*text
= (Unichar
*)buf
;
781 for (i
= 0; i
< nchars
; i
++)
782 text
[i
] = buf
[2*i
] << 8 | buf
[2*i
+1];
785 err
= atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr
)buf
,
787 GC_FONT (gc
)->mac_style
,
792 if (NILP (Vmac_use_core_graphics
))
795 mac_begin_clip (GC_CLIP_REGION (gc
));
797 ATSUDrawText (text_layout
,
798 kATSUFromTextBeginning
, kATSUToTextEnd
,
799 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
800 mac_end_clip (GC_CLIP_REGION (gc
));
806 CGContextRef context
;
809 ATSUAttributeTag tags
[] = {kATSUCGContextTag
};
810 ByteCount sizes
[] = {sizeof (CGContextRef
)};
811 ATSUAttributeValuePtr values
[] = {&context
};
814 QDBeginCGContext (port
, &context
);
815 GetPortBounds (port
, &rect
);
816 port_height
= rect
.bottom
- rect
.top
;
817 if (gc
->n_clip_rects
)
819 CGContextTranslateCTM (context
, 0, port_height
);
820 CGContextScaleCTM (context
, 1, -1);
821 CGContextClipToRects (context
, gc
->clip_rects
,
823 CGContextScaleCTM (context
, 1, -1);
824 CGContextTranslateCTM (context
, 0, -port_height
);
826 CGContextSetRGBFillColor
828 RED_FROM_ULONG (gc
->xgcv
.foreground
) / 255.0,
829 GREEN_FROM_ULONG (gc
->xgcv
.foreground
) / 255.0,
830 BLUE_FROM_ULONG (gc
->xgcv
.foreground
) / 255.0,
832 err
= ATSUSetLayoutControls (text_layout
,
833 sizeof (tags
) / sizeof (tags
[0]),
834 tags
, sizes
, values
);
836 ATSUDrawText (text_layout
,
837 kATSUFromTextBeginning
, kATSUToTextEnd
,
838 Long2Fix (x
), Long2Fix (port_height
- y
));
839 ATSUClearLayoutControls (text_layout
,
840 sizeof (tags
) / sizeof (tags
[0]),
842 CGContextSynchronize (context
);
843 QDEndCGContext (port
, &context
);
851 TextFont (GC_FONT (gc
)->mac_fontnum
);
852 TextSize (GC_FONT (gc
)->mac_fontsize
);
853 TextFace (GC_FONT (gc
)->mac_fontface
);
856 mac_begin_clip (GC_CLIP_REGION (gc
));
858 DrawText (buf
, 0, nchars
* bytes_per_char
);
859 mac_end_clip (GC_CLIP_REGION (gc
));
865 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
866 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
867 if (!NILP(Vmac_use_core_graphics
))
868 SwapQDTextFlags(savedFlags
);
873 /* Mac replacement for XDrawString. */
876 XDrawString (display
, w
, gc
, x
, y
, buf
, nchars
)
884 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcOr
, 1);
888 /* Mac replacement for XDrawString16. */
891 XDrawString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
899 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcOr
,
904 /* Mac replacement for XDrawImageString. */
907 XDrawImageString (display
, w
, gc
, x
, y
, buf
, nchars
)
915 mac_draw_string_common (display
, w
, gc
, x
, y
, buf
, nchars
, srcCopy
, 1);
919 /* Mac replacement for XDrawString16. */
922 XDrawImageString16 (display
, w
, gc
, x
, y
, buf
, nchars
)
930 mac_draw_string_common (display
, w
, gc
, x
, y
, (char *) buf
, nchars
, srcCopy
,
935 /* Mac replacement for XCopyArea: dest must be window. */
938 mac_copy_area (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
, dest_x
,
945 unsigned int width
, height
;
950 SetPortWindowPort (dest
);
952 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
953 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
955 ForeColor (blackColor
);
956 BackColor (whiteColor
);
958 mac_begin_clip (GC_CLIP_REGION (gc
));
959 LockPixels (GetGWorldPixMap (src
));
960 #if TARGET_API_MAC_CARBON
961 LockPortBits (GetWindowPort (dest
));
962 CopyBits (GetPortBitMapForCopyBits (src
),
963 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
964 &src_r
, &dest_r
, srcCopy
, 0);
965 UnlockPortBits (GetWindowPort (dest
));
966 #else /* not TARGET_API_MAC_CARBON */
967 CopyBits (&(((GrafPtr
)src
)->portBits
), &(dest
->portBits
),
968 &src_r
, &dest_r
, srcCopy
, 0);
969 #endif /* not TARGET_API_MAC_CARBON */
970 UnlockPixels (GetGWorldPixMap (src
));
971 mac_end_clip (GC_CLIP_REGION (gc
));
973 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest
)));
978 mac_copy_area_with_mask (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
979 width
, height
, dest_x
, dest_y
)
985 unsigned int width
, height
;
990 SetPortWindowPort (dest
);
992 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
993 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
995 ForeColor (blackColor
);
996 BackColor (whiteColor
);
998 mac_begin_clip (GC_CLIP_REGION (gc
));
999 LockPixels (GetGWorldPixMap (src
));
1000 LockPixels (GetGWorldPixMap (mask
));
1001 #if TARGET_API_MAC_CARBON
1002 LockPortBits (GetWindowPort (dest
));
1003 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1004 GetPortBitMapForCopyBits (GetWindowPort (dest
)),
1005 &src_r
, &src_r
, &dest_r
);
1006 UnlockPortBits (GetWindowPort (dest
));
1007 #else /* not TARGET_API_MAC_CARBON */
1008 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1009 &(dest
->portBits
), &src_r
, &src_r
, &dest_r
);
1010 #endif /* not TARGET_API_MAC_CARBON */
1011 UnlockPixels (GetGWorldPixMap (mask
));
1012 UnlockPixels (GetGWorldPixMap (src
));
1013 mac_end_clip (GC_CLIP_REGION (gc
));
1015 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (dest
)));
1019 /* Mac replacement for XCopyArea: used only for scrolling. */
1022 mac_scroll_area (display
, w
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1027 unsigned int width
, height
;
1030 #if TARGET_API_MAC_CARBON
1032 RgnHandle dummy
= NewRgn (); /* For avoiding update events. */
1034 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1035 ScrollWindowRect (w
, &src_r
, dest_x
- src_x
, dest_y
- src_y
,
1036 kScrollWindowNoOptions
, dummy
);
1038 #else /* not TARGET_API_MAC_CARBON */
1043 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1044 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1046 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1047 color mapping in CopyBits. Otherwise, it will be slow. */
1048 ForeColor (blackColor
);
1049 BackColor (whiteColor
);
1050 mac_begin_clip (GC_CLIP_REGION (gc
));
1051 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1052 mac_end_clip (GC_CLIP_REGION (gc
));
1054 RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w
)));
1055 #endif /* not TARGET_API_MAC_CARBON */
1059 #if 0 /* TODO: figure out if we need to do this on Mac. */
1060 /* Mac replacement for XCopyArea: dest must be Pixmap. */
1063 mac_copy_area_to_pixmap (display
, src
, dest
, gc
, src_x
, src_y
, width
, height
,
1069 unsigned int width
, height
;
1076 GetGWorld (&old_port
, &old_gdh
);
1077 SetGWorld (dest
, NULL
);
1078 ForeColor (blackColor
);
1079 BackColor (whiteColor
);
1081 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1082 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1084 LockPixels (GetGWorldPixMap (src
));
1085 LockPixels (GetGWorldPixMap (dest
));
1086 #if TARGET_API_MAC_CARBON
1087 CopyBits (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (dest
),
1088 &src_r
, &dest_r
, srcCopy
, 0);
1089 #else /* not TARGET_API_MAC_CARBON */
1090 CopyBits (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)dest
)->portBits
),
1091 &src_r
, &dest_r
, srcCopy
, 0);
1092 #endif /* not TARGET_API_MAC_CARBON */
1093 UnlockPixels (GetGWorldPixMap (dest
));
1094 UnlockPixels (GetGWorldPixMap (src
));
1096 SetGWorld (old_port
, old_gdh
);
1101 mac_copy_area_with_mask_to_pixmap (display
, src
, mask
, dest
, gc
, src_x
, src_y
,
1102 width
, height
, dest_x
, dest_y
)
1104 Pixmap src
, mask
, dest
;
1107 unsigned int width
, height
;
1114 GetGWorld (&old_port
, &old_gdh
);
1115 SetGWorld (dest
, NULL
);
1116 ForeColor (blackColor
);
1117 BackColor (whiteColor
);
1119 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1120 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1122 LockPixels (GetGWorldPixMap (src
));
1123 LockPixels (GetGWorldPixMap (mask
));
1124 LockPixels (GetGWorldPixMap (dest
));
1125 #if TARGET_API_MAC_CARBON
1126 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1127 GetPortBitMapForCopyBits (dest
), &src_r
, &src_r
, &dest_r
);
1128 #else /* not TARGET_API_MAC_CARBON */
1129 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1130 &(((GrafPtr
)dest
)->portBits
), &src_r
, &src_r
, &dest_r
);
1131 #endif /* not TARGET_API_MAC_CARBON */
1132 UnlockPixels (GetGWorldPixMap (dest
));
1133 UnlockPixels (GetGWorldPixMap (mask
));
1134 UnlockPixels (GetGWorldPixMap (src
));
1136 SetGWorld (old_port
, old_gdh
);
1141 /* Mac replacement for XChangeGC. */
1144 XChangeGC (display
, gc
, mask
, xgcv
)
1150 if (mask
& GCForeground
)
1151 XSetForeground (display
, gc
, xgcv
->foreground
);
1152 if (mask
& GCBackground
)
1153 XSetBackground (display
, gc
, xgcv
->background
);
1155 XSetFont (display
, gc
, xgcv
->font
);
1159 /* Mac replacement for XCreateGC. */
1162 XCreateGC (display
, window
, mask
, xgcv
)
1168 GC gc
= xmalloc (sizeof (*gc
));
1172 bzero (gc
, sizeof (*gc
));
1173 XChangeGC (display
, gc
, mask
, xgcv
);
1180 /* Used in xfaces.c. */
1183 XFreeGC (display
, gc
)
1187 if (gc
->clip_region
)
1188 DisposeRgn (gc
->clip_region
);
1193 /* Mac replacement for XGetGCValues. */
1196 XGetGCValues (display
, gc
, mask
, xgcv
)
1202 if (mask
& GCForeground
)
1203 xgcv
->foreground
= gc
->xgcv
.foreground
;
1204 if (mask
& GCBackground
)
1205 xgcv
->background
= gc
->xgcv
.background
;
1207 xgcv
->font
= gc
->xgcv
.font
;
1211 /* Mac replacement for XSetForeground. */
1214 XSetForeground (display
, gc
, color
)
1217 unsigned long color
;
1219 if (gc
->xgcv
.foreground
!= color
)
1221 gc
->xgcv
.foreground
= color
;
1222 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1223 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1224 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1229 /* Mac replacement for XSetBackground. */
1232 XSetBackground (display
, gc
, color
)
1235 unsigned long color
;
1237 if (gc
->xgcv
.background
!= color
)
1239 gc
->xgcv
.background
= color
;
1240 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1241 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1242 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1247 /* Mac replacement for XSetFont. */
1250 XSetFont (display
, gc
, font
)
1255 gc
->xgcv
.font
= font
;
1259 /* Mac replacement for XSetClipRectangles. */
1262 mac_set_clip_rectangles (display
, gc
, rectangles
, n
)
1270 if (n
< 0 || n
> MAX_CLIP_RECTS
)
1274 if (gc
->clip_region
)
1276 DisposeRgn (gc
->clip_region
);
1277 gc
->clip_region
= NULL
;
1282 if (gc
->clip_region
== NULL
)
1283 gc
->clip_region
= NewRgn ();
1284 RectRgn (gc
->clip_region
, rectangles
);
1287 RgnHandle region
= NewRgn ();
1289 for (i
= 1; i
< n
; i
++)
1291 RectRgn (region
, rectangles
+ i
);
1292 UnionRgn (gc
->clip_region
, region
, gc
->clip_region
);
1294 DisposeRgn (region
);
1297 #if defined (MAC_OSX) && USE_ATSUI
1298 gc
->n_clip_rects
= n
;
1300 for (i
= 0; i
< n
; i
++)
1302 Rect
*rect
= rectangles
+ i
;
1304 gc
->clip_rects
[i
] = CGRectMake (rect
->left
, rect
->top
,
1305 rect
->right
- rect
->left
,
1306 rect
->bottom
- rect
->top
);
1312 /* Mac replacement for XSetClipMask. */
1315 mac_reset_clip_rectangles (display
, gc
)
1319 mac_set_clip_rectangles (display
, gc
, NULL
, 0);
1323 /* Mac replacement for XSetWindowBackground. */
1326 XSetWindowBackground (display
, w
, color
)
1329 unsigned long color
;
1331 #if !TARGET_API_MAC_CARBON
1332 AuxWinHandle aw_handle
;
1333 CTabHandle ctab_handle
;
1334 ColorSpecPtr ct_table
;
1339 bg_color
.red
= RED16_FROM_ULONG (color
);
1340 bg_color
.green
= GREEN16_FROM_ULONG (color
);
1341 bg_color
.blue
= BLUE16_FROM_ULONG (color
);
1343 #if TARGET_API_MAC_CARBON
1344 SetWindowContentColor (w
, &bg_color
);
1346 if (GetAuxWin (w
, &aw_handle
))
1348 ctab_handle
= (*aw_handle
)->awCTable
;
1349 HandToHand ((Handle
*) &ctab_handle
);
1350 ct_table
= (*ctab_handle
)->ctTable
;
1351 ct_size
= (*ctab_handle
)->ctSize
;
1352 while (ct_size
> -1)
1354 if (ct_table
->value
== 0)
1356 ct_table
->rgb
= bg_color
;
1357 CTabChanged (ctab_handle
);
1358 SetWinColor (w
, (WCTabHandle
) ctab_handle
);
1366 /* x_sync is a no-op on Mac. */
1374 /* Flush display of frame F, or of all frames if F is null. */
1380 #if TARGET_API_MAC_CARBON
1383 QDFlushPortBuffer (GetWindowPort (FRAME_MAC_WINDOW (f
)), NULL
);
1385 QDFlushPortBuffer (GetQDGlobalsThePort (), NULL
);
1391 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1392 Calls to XFlush should be unnecessary because the X output buffer
1393 is flushed automatically as needed by calls to XPending,
1394 XNextEvent, or XWindowEvent according to the XFlush man page.
1395 XTread_socket calls XPending. Removing XFlush improves
1398 #define XFlush(DISPLAY) (void) 0
1401 /* Return the struct mac_display_info corresponding to DPY. There's
1404 struct mac_display_info
*
1405 mac_display_info_for_display (dpy
)
1408 return &one_mac_display_info
;
1413 /***********************************************************************
1414 Starting and ending an update
1415 ***********************************************************************/
1417 /* Start an update of frame F. This function is installed as a hook
1418 for update_begin, i.e. it is called when update_begin is called.
1419 This function is called prior to calls to x_update_window_begin for
1420 each window being updated. */
1426 #if TARGET_API_MAC_CARBON
1427 /* During update of a frame, availability of input events is
1428 periodically checked with ReceiveNextEvent if
1429 redisplay-dont-pause is nil. That normally flushes window buffer
1430 changes for every check, and thus screen update looks waving even
1431 if no input is available. So we disable screen updates during
1432 update of a frame. */
1434 DisableScreenUpdates ();
1440 /* Start update of window W. Set the global variable updated_window
1441 to the window being updated and set output_cursor to the cursor
1445 x_update_window_begin (w
)
1448 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1449 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1452 set_output_cursor (&w
->cursor
);
1456 if (f
== display_info
->mouse_face_mouse_frame
)
1458 /* Don't do highlighting for mouse motion during the update. */
1459 display_info
->mouse_face_defer
= 1;
1461 /* If F needs to be redrawn, simply forget about any prior mouse
1463 if (FRAME_GARBAGED_P (f
))
1464 display_info
->mouse_face_window
= Qnil
;
1466 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1467 their mouse_face_p flag set, which means that they are always
1468 unequal to rows in a desired matrix which never have that
1469 flag set. So, rows containing mouse-face glyphs are never
1470 scrolled, and we don't have to switch the mouse highlight off
1471 here to prevent it from being scrolled. */
1473 /* Can we tell that this update does not affect the window
1474 where the mouse highlight is? If so, no need to turn off.
1475 Likewise, don't do anything if the frame is garbaged;
1476 in that case, the frame's current matrix that we would use
1477 is all wrong, and we will redisplay that line anyway. */
1478 if (!NILP (display_info
->mouse_face_window
)
1479 && w
== XWINDOW (display_info
->mouse_face_window
))
1483 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1484 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1487 if (i
< w
->desired_matrix
->nrows
)
1488 clear_mouse_face (display_info
);
1497 /* Draw a vertical window border from (x,y0) to (x,y1) */
1500 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1504 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1507 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1509 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1512 XDrawLine (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1513 f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1516 /* End update of window W (which is equal to updated_window).
1518 Draw vertical borders between horizontally adjacent windows, and
1519 display W's cursor if CURSOR_ON_P is non-zero.
1521 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1522 glyphs in mouse-face were overwritten. In that case we have to
1523 make sure that the mouse-highlight is properly redrawn.
1525 W may be a menu bar pseudo-window in case we don't have X toolkit
1526 support. Such windows don't have a cursor, so don't display it
1530 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1532 int cursor_on_p
, mouse_face_overwritten_p
;
1534 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1536 if (!w
->pseudo_window_p
)
1541 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1543 output_cursor
.x
, output_cursor
.y
);
1545 if (draw_window_fringes (w
, 1))
1546 x_draw_vertical_border (w
);
1551 /* If a row with mouse-face was overwritten, arrange for
1552 XTframe_up_to_date to redisplay the mouse highlight. */
1553 if (mouse_face_overwritten_p
)
1555 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1556 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1557 dpyinfo
->mouse_face_window
= Qnil
;
1560 updated_window
= NULL
;
1564 /* End update of frame F. This function is installed as a hook in
1571 /* Mouse highlight may be displayed again. */
1572 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1575 #if TARGET_API_MAC_CARBON
1576 EnableScreenUpdates ();
1578 XFlush (FRAME_MAC_DISPLAY (f
));
1583 /* This function is called from various places in xdisp.c whenever a
1584 complete update has been performed. The global variable
1585 updated_window is not available here. */
1588 XTframe_up_to_date (f
)
1591 if (FRAME_MAC_P (f
))
1593 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1595 if (dpyinfo
->mouse_face_deferred_gc
1596 || f
== dpyinfo
->mouse_face_mouse_frame
)
1599 if (dpyinfo
->mouse_face_mouse_frame
)
1600 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1601 dpyinfo
->mouse_face_mouse_x
,
1602 dpyinfo
->mouse_face_mouse_y
);
1603 dpyinfo
->mouse_face_deferred_gc
= 0;
1610 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1611 arrow bitmaps, or clear the fringes if no bitmaps are required
1612 before DESIRED_ROW is made current. The window being updated is
1613 found in updated_window. This function is called from
1614 update_window_line only if it is known that there are differences
1615 between bitmaps to be drawn between current row and DESIRED_ROW. */
1618 x_after_update_window_line (desired_row
)
1619 struct glyph_row
*desired_row
;
1621 struct window
*w
= updated_window
;
1627 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1628 desired_row
->redraw_fringe_bitmaps_p
= 1;
1630 /* When a window has disappeared, make sure that no rest of
1631 full-width rows stays visible in the internal border. Could
1632 check here if updated_window is the leftmost/rightmost window,
1633 but I guess it's not worth doing since vertically split windows
1634 are almost never used, internal border is rarely set, and the
1635 overhead is very small. */
1636 if (windows_or_buffers_changed
1637 && desired_row
->full_width_p
1638 && (f
= XFRAME (w
->frame
),
1639 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1641 && (height
= desired_row
->visible_height
,
1644 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1646 /* Internal border is drawn below the tool bar. */
1647 if (WINDOWP (f
->tool_bar_window
)
1648 && w
== XWINDOW (f
->tool_bar_window
))
1652 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1653 0, y
, width
, height
, 0);
1654 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
1655 FRAME_PIXEL_WIDTH (f
) - width
, y
,
1662 /* Draw the bitmap WHICH in one of the left or right fringes of
1663 window W. ROW is the glyph row for which to display the bitmap; it
1664 determines the vertical position at which the bitmap has to be
1668 x_draw_fringe_bitmap (w
, row
, p
)
1670 struct glyph_row
*row
;
1671 struct draw_fringe_bitmap_params
*p
;
1673 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1674 Display
*display
= FRAME_MAC_DISPLAY (f
);
1675 WindowPtr window
= FRAME_MAC_WINDOW (f
);
1676 GC gc
= f
->output_data
.mac
->normal_gc
;
1677 struct face
*face
= p
->face
;
1680 /* Must clip because of partially visible lines. */
1681 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
1684 /* Adjust position of "bottom aligned" bitmap on partially
1685 visible last row. */
1687 int oldVH
= row
->visible_height
;
1688 row
->visible_height
= p
->h
;
1689 row
->y
-= rowY
- p
->y
;
1690 x_clip_to_row (w
, row
, -1, gc
);
1692 row
->visible_height
= oldVH
;
1695 x_clip_to_row (w
, row
, -1, gc
);
1697 if (p
->bx
>= 0 && !p
->overlay_p
)
1699 #if 0 /* MAC_TODO: stipple */
1700 /* In case the same realized face is used for fringes and
1701 for something displayed in the text (e.g. face `region' on
1702 mono-displays, the fill style may have been changed to
1703 FillSolid in x_draw_glyph_string_background. */
1705 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
1707 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
1710 mac_erase_rectangle (window
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
1712 #if 0 /* MAC_TODO: stipple */
1714 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
1720 unsigned short *bits
= p
->bits
+ p
->dh
;
1723 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
1724 XSetForeground (display
, face
->gc
,
1726 ? (p
->overlay_p
? face
->background
1727 : f
->output_data
.mac
->cursor_pixel
)
1728 : face
->foreground
));
1729 mac_draw_bitmap (display
, window
, face
->gc
, p
->x
, p
->y
,
1730 p
->wd
, p
->h
, bits
, p
->overlay_p
);
1731 XSetForeground (display
, face
->gc
, gcv
.foreground
);
1734 mac_reset_clip_rectangles (display
, gc
);
1739 /* This is called when starting Emacs and when restarting after
1740 suspend. When starting Emacs, no window is mapped. And nothing
1741 must be done to Emacs's own window if it is suspended (though that
1745 XTset_terminal_modes ()
1749 /* This is called when exiting or suspending Emacs. Exiting will make
1750 the windows go away, and suspending requires no action. */
1753 XTreset_terminal_modes ()
1759 /***********************************************************************
1761 ***********************************************************************/
1763 /* Function prototypes of this page. */
1765 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
1766 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
1769 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
1770 is not contained in the font. */
1772 static INLINE XCharStruct
*
1773 x_per_char_metric (font
, char2b
)
1777 /* The result metric information. */
1778 XCharStruct
*pcm
= NULL
;
1780 xassert (font
&& char2b
);
1783 if (font
->mac_style
)
1785 if (char2b
->byte1
>= font
->min_byte1
1786 && char2b
->byte1
<= font
->max_byte1
1787 && char2b
->byte2
>= font
->min_char_or_byte2
1788 && char2b
->byte2
<= font
->max_char_or_byte2
)
1790 pcm
= (font
->per_char
1791 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1792 * (char2b
->byte1
- font
->min_byte1
))
1793 + (char2b
->byte2
- font
->min_char_or_byte2
));
1796 if (pcm
&& !pcm
->valid_p
)
1799 ATSUTextLayout text_layout
;
1802 ATSTrapezoid glyph_bounds
;
1805 c
= (char2b
->byte1
<< 8) + char2b
->byte2
;
1807 err
= atsu_get_text_layout_with_text_ptr (&c
, 1,
1811 err
= ATSUMeasureTextImage (text_layout
,
1812 kATSUFromTextBeginning
, kATSUToTextEnd
,
1813 0, 0, &char_bounds
);
1816 err
= ATSUGetGlyphBounds (text_layout
, 0, 0,
1817 kATSUFromTextBeginning
, kATSUToTextEnd
,
1818 kATSUseFractionalOrigins
, 1,
1819 &glyph_bounds
, NULL
);
1825 xassert (glyph_bounds
.lowerRight
.x
- glyph_bounds
.lowerLeft
.x
1826 == glyph_bounds
.upperRight
.x
- glyph_bounds
.upperLeft
.x
);
1828 char_width
= Fix2Long (glyph_bounds
.upperRight
.x
1829 - glyph_bounds
.upperLeft
.x
);
1830 STORE_XCHARSTRUCT (*pcm
, char_width
, char_bounds
);
1837 if (font
->per_char
!= NULL
)
1839 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
1841 /* min_char_or_byte2 specifies the linear character index
1842 corresponding to the first element of the per_char array,
1843 max_char_or_byte2 is the index of the last character. A
1844 character with non-zero CHAR2B->byte1 is not in the font.
1845 A character with byte2 less than min_char_or_byte2 or
1846 greater max_char_or_byte2 is not in the font. */
1847 if (char2b
->byte1
== 0
1848 && char2b
->byte2
>= font
->min_char_or_byte2
1849 && char2b
->byte2
<= font
->max_char_or_byte2
)
1850 pcm
= font
->per_char
+ char2b
->byte2
- font
->min_char_or_byte2
;
1854 /* If either min_byte1 or max_byte1 are nonzero, both
1855 min_char_or_byte2 and max_char_or_byte2 are less than
1856 256, and the 2-byte character index values corresponding
1857 to the per_char array element N (counting from 0) are:
1859 byte1 = N/D + min_byte1
1860 byte2 = N\D + min_char_or_byte2
1864 D = max_char_or_byte2 - min_char_or_byte2 + 1
1865 / = integer division
1866 \ = integer modulus */
1867 if (char2b
->byte1
>= font
->min_byte1
1868 && char2b
->byte1
<= font
->max_byte1
1869 && char2b
->byte2
>= font
->min_char_or_byte2
1870 && char2b
->byte2
<= font
->max_char_or_byte2
)
1872 pcm
= (font
->per_char
1873 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
1874 * (char2b
->byte1
- font
->min_byte1
))
1875 + (char2b
->byte2
- font
->min_char_or_byte2
));
1881 /* If the per_char pointer is null, all glyphs between the first
1882 and last character indexes inclusive have the same
1883 information, as given by both min_bounds and max_bounds. */
1884 if (char2b
->byte2
>= font
->min_char_or_byte2
1885 && char2b
->byte2
<= font
->max_char_or_byte2
)
1886 pcm
= &font
->max_bounds
;
1892 return ((pcm
== NULL
1893 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
1900 static XCharStruct
*
1901 mac_per_char_metric (font
, char2b
, font_type
)
1906 return x_per_char_metric (font
, char2b
);
1910 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1911 the two-byte form of C. Encoding is returned in *CHAR2B. */
1914 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
1917 struct font_info
*font_info
;
1920 int charset
= CHAR_CHARSET (c
);
1921 XFontStruct
*font
= font_info
->font
;
1923 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1924 This may be either a program in a special encoder language or a
1926 if (font_info
->font_encoder
)
1928 /* It's a program. */
1929 struct ccl_program
*ccl
= font_info
->font_encoder
;
1931 check_ccl_update (ccl
);
1932 if (CHARSET_DIMENSION (charset
) == 1)
1934 ccl
->reg
[0] = charset
;
1935 ccl
->reg
[1] = char2b
->byte2
;
1940 ccl
->reg
[0] = charset
;
1941 ccl
->reg
[1] = char2b
->byte1
;
1942 ccl
->reg
[2] = char2b
->byte2
;
1945 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
1947 /* We assume that MSBs are appropriately set/reset by CCL
1949 if (font
->max_byte1
== 0) /* 1-byte font */
1950 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
1952 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
1954 else if (font_info
->encoding
[charset
])
1956 /* Fixed encoding scheme. See fontset.h for the meaning of the
1957 encoding numbers. */
1958 int enc
= font_info
->encoding
[charset
];
1960 if ((enc
== 1 || enc
== 2)
1961 && CHARSET_DIMENSION (charset
) == 2)
1962 char2b
->byte1
|= 0x80;
1964 if (enc
== 1 || enc
== 3)
1965 char2b
->byte2
|= 0x80;
1971 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
1972 char2b
->byte1
= sjis1
;
1973 char2b
->byte2
= sjis2
;
1978 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
1980 return FONT_TYPE_UNKNOWN
;
1985 /***********************************************************************
1987 ***********************************************************************/
1991 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
1992 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
1993 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
1995 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
1996 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
1997 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
1998 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
1999 static void mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2000 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2001 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2002 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2003 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
2004 unsigned long *, double, int));*/
2005 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2006 double, int, unsigned long));
2007 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2008 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2009 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2010 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2011 static void x_draw_image_foreground_1
P_ ((struct glyph_string
*, Pixmap
));
2012 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2014 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2015 int, int, int, int, int, int,
2017 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2018 int, int, int, Rect
*));
2021 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2025 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2030 struct glyph_string
*s
;
2032 if (s
->font
== FRAME_FONT (s
->f
)
2033 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2034 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2036 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
2039 /* Cursor on non-default face: must merge. */
2043 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
2044 xgcv
.foreground
= s
->face
->background
;
2046 /* If the glyph would be invisible, try a different foreground. */
2047 if (xgcv
.foreground
== xgcv
.background
)
2048 xgcv
.foreground
= s
->face
->foreground
;
2049 if (xgcv
.foreground
== xgcv
.background
)
2050 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
2051 if (xgcv
.foreground
== xgcv
.background
)
2052 xgcv
.foreground
= s
->face
->foreground
;
2054 /* Make sure the cursor is distinct from text in this face. */
2055 if (xgcv
.background
== s
->face
->background
2056 && xgcv
.foreground
== s
->face
->foreground
)
2058 xgcv
.background
= s
->face
->foreground
;
2059 xgcv
.foreground
= s
->face
->background
;
2062 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2063 xgcv
.font
= s
->font
;
2064 mask
= GCForeground
| GCBackground
| GCFont
;
2066 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2067 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2070 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2071 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2073 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2078 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2081 x_set_mouse_face_gc (s
)
2082 struct glyph_string
*s
;
2087 /* What face has to be used last for the mouse face? */
2088 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2089 face
= FACE_FROM_ID (s
->f
, face_id
);
2091 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2093 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2094 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2096 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2097 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2098 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2100 /* If font in this face is same as S->font, use it. */
2101 if (s
->font
== s
->face
->font
)
2102 s
->gc
= s
->face
->gc
;
2105 /* Otherwise construct scratch_cursor_gc with values from FACE
2110 xgcv
.background
= s
->face
->background
;
2111 xgcv
.foreground
= s
->face
->foreground
;
2112 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2113 xgcv
.font
= s
->font
;
2114 mask
= GCForeground
| GCBackground
| GCFont
;
2116 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2117 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2120 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2121 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2123 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2126 xassert (s
->gc
!= 0);
2130 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2131 Faces to use in the mode line have already been computed when the
2132 matrix was built, so there isn't much to do, here. */
2135 x_set_mode_line_face_gc (s
)
2136 struct glyph_string
*s
;
2138 s
->gc
= s
->face
->gc
;
2142 /* Set S->gc of glyph string S for drawing that glyph string. Set
2143 S->stippled_p to a non-zero value if the face of S has a stipple
2147 x_set_glyph_string_gc (s
)
2148 struct glyph_string
*s
;
2150 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2152 if (s
->hl
== DRAW_NORMAL_TEXT
)
2154 s
->gc
= s
->face
->gc
;
2155 s
->stippled_p
= s
->face
->stipple
!= 0;
2157 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2159 x_set_mode_line_face_gc (s
);
2160 s
->stippled_p
= s
->face
->stipple
!= 0;
2162 else if (s
->hl
== DRAW_CURSOR
)
2164 x_set_cursor_gc (s
);
2167 else if (s
->hl
== DRAW_MOUSE_FACE
)
2169 x_set_mouse_face_gc (s
);
2170 s
->stippled_p
= s
->face
->stipple
!= 0;
2172 else if (s
->hl
== DRAW_IMAGE_RAISED
2173 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2175 s
->gc
= s
->face
->gc
;
2176 s
->stippled_p
= s
->face
->stipple
!= 0;
2180 s
->gc
= s
->face
->gc
;
2181 s
->stippled_p
= s
->face
->stipple
!= 0;
2184 /* GC must have been set. */
2185 xassert (s
->gc
!= 0);
2189 /* Set clipping for output of glyph string S. S may be part of a mode
2190 line or menu if we don't have X toolkit support. */
2193 x_set_glyph_string_clipping (s
)
2194 struct glyph_string
*s
;
2196 Rect rects
[MAX_CLIP_RECTS
];
2199 n
= get_glyph_string_clip_rects (s
, rects
, MAX_CLIP_RECTS
);
2200 mac_set_clip_rectangles (s
->display
, s
->gc
, rects
, n
);
2205 Compute left and right overhang of glyph string S. If S is a glyph
2206 string for a composition, assume overhangs don't exist. */
2209 mac_compute_glyph_string_overhangs (s
)
2210 struct glyph_string
*s
;
2213 && s
->first_glyph
->type
== CHAR_GLYPH
)
2216 MacFontStruct
*font
= s
->font
;
2219 if (font
->mac_style
)
2222 ATSUTextLayout text_layout
;
2226 SetRect (&r
, 0, 0, 0, 0);
2227 buf
= xmalloc (sizeof (UniChar
) * s
->nchars
);
2230 for (i
= 0; i
< s
->nchars
; i
++)
2231 buf
[i
] = (s
->char2b
[i
].byte1
<< 8) + s
->char2b
[i
].byte2
;
2233 err
= atsu_get_text_layout_with_text_ptr (buf
, s
->nchars
,
2237 err
= ATSUMeasureTextImage (text_layout
,
2238 kATSUFromTextBeginning
,
2247 TextFont (font
->mac_fontnum
);
2248 TextSize (font
->mac_fontsize
);
2249 TextFace (font
->mac_fontface
);
2252 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
2256 char *buf
= xmalloc (s
->nchars
);
2259 SetRect (&r
, 0, 0, 0, 0);
2262 for (i
= 0; i
< s
->nchars
; ++i
)
2263 buf
[i
] = s
->char2b
[i
].byte2
;
2264 QDTextBounds (s
->nchars
, buf
, &r
);
2272 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
2273 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
2278 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2281 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2282 struct glyph_string
*s
;
2285 mac_erase_rectangle (s
->window
, s
->gc
, x
, y
, w
, h
);
2289 /* We prefer not to use XDrawImageString (srcCopy text transfer mode)
2290 on Mac OS X because:
2291 - Screen is double-buffered. (In srcCopy mode, a text is drawn
2292 into an offscreen graphics world first. So performance gain
2293 cannot be expected.)
2294 - It lowers rendering quality.
2295 - Some fonts leave garbage on cursor movement. */
2297 /* Draw the background of glyph_string S. If S->background_filled_p
2298 is non-zero don't draw it. FORCE_P non-zero means draw the
2299 background even if it wouldn't be drawn normally. This is used
2300 when a string preceding S draws into the background of S, or S
2301 contains the first component of a composition. */
2304 x_draw_glyph_string_background (s
, force_p
)
2305 struct glyph_string
*s
;
2308 /* Nothing to do if background has already been drawn or if it
2309 shouldn't be drawn in the first place. */
2310 if (!s
->background_filled_p
)
2312 int box_line_width
= max (s
->face
->box_line_width
, 0);
2314 #if 0 /* MAC_TODO: stipple */
2317 /* Fill background with a stipple pattern. */
2318 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2319 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2320 s
->y
+ box_line_width
,
2321 s
->background_width
,
2322 s
->height
- 2 * box_line_width
);
2323 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2324 s
->background_filled_p
= 1;
2328 #if defined (MAC_OS8) && !USE_ATSUI
2329 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2330 || s
->font_not_found_p
2331 || s
->extends_to_end_of_line_p
2335 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2336 s
->background_width
,
2337 s
->height
- 2 * box_line_width
);
2338 s
->background_filled_p
= 1;
2344 /* Draw the foreground of glyph string S. */
2347 x_draw_glyph_string_foreground (s
)
2348 struct glyph_string
*s
;
2352 /* If first glyph of S has a left box line, start drawing the text
2353 of S to the right of that box line. */
2354 if (s
->face
->box
!= FACE_NO_BOX
2355 && s
->first_glyph
->left_box_line_p
)
2356 x
= s
->x
+ abs (s
->face
->box_line_width
);
2360 /* Draw characters of S as rectangles if S's font could not be
2362 if (s
->font_not_found_p
)
2364 for (i
= 0; i
< s
->nchars
; ++i
)
2366 struct glyph
*g
= s
->first_glyph
+ i
;
2367 mac_draw_rectangle (s
->display
, s
->window
,
2368 s
->gc
, x
, s
->y
, g
->pixel_width
- 1,
2370 x
+= g
->pixel_width
;
2375 char *char1b
= (char *) s
->char2b
;
2376 int boff
= s
->font_info
->baseline_offset
;
2378 if (s
->font_info
->vertical_centering
)
2379 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2381 /* If we can use 8-bit functions, condense S->char2b. */
2384 && GC_FONT (s
->gc
)->mac_style
== NULL
2387 for (i
= 0; i
< s
->nchars
; ++i
)
2388 char1b
[i
] = s
->char2b
[i
].byte2
;
2390 #if defined (MAC_OS8) && !USE_ATSUI
2391 /* Draw text with XDrawString if background has already been
2392 filled. Otherwise, use XDrawImageString. (Note that
2393 XDrawImageString is usually faster than XDrawString.) Always
2394 use XDrawImageString when drawing the cursor so that there is
2395 no chance that characters under a box cursor are invisible. */
2397 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2400 /* Draw characters with 16-bit or 8-bit functions. */
2403 || GC_FONT (s
->gc
)->mac_style
2406 XDrawString16 (s
->display
, s
->window
, s
->gc
, x
,
2407 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2409 XDrawString (s
->display
, s
->window
, s
->gc
, x
,
2410 s
->ybase
- boff
, char1b
, s
->nchars
);
2412 #if defined (MAC_OS8) && !USE_ATSUI
2416 XDrawImageString16 (s
->display
, s
->window
, s
->gc
, x
,
2417 s
->ybase
- boff
, s
->char2b
, s
->nchars
);
2419 XDrawImageString (s
->display
, s
->window
, s
->gc
, x
,
2420 s
->ybase
- boff
, char1b
, s
->nchars
);
2426 /* Draw the foreground of composite glyph string S. */
2429 x_draw_composite_glyph_string_foreground (s
)
2430 struct glyph_string
*s
;
2434 /* If first glyph of S has a left box line, start drawing the text
2435 of S to the right of that box line. */
2436 if (s
->face
->box
!= FACE_NO_BOX
2437 && s
->first_glyph
->left_box_line_p
)
2438 x
= s
->x
+ abs (s
->face
->box_line_width
);
2442 /* S is a glyph string for a composition. S->gidx is the index of
2443 the first character drawn for glyphs of this composition.
2444 S->gidx == 0 means we are drawing the very first character of
2445 this composition. */
2447 /* Draw a rectangle for the composition if the font for the very
2448 first character of the composition could not be loaded. */
2449 if (s
->font_not_found_p
)
2452 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, s
->y
,
2453 s
->width
- 1, s
->height
- 1);
2457 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2458 XDrawString16 (s
->display
, s
->window
, s
->gc
,
2459 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2460 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2466 #ifdef USE_X_TOOLKIT
2468 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2471 /* Return the frame on which widget WIDGET is used.. Abort if frame
2472 cannot be determined. */
2474 static struct frame
*
2475 x_frame_of_widget (widget
)
2478 struct x_display_info
*dpyinfo
;
2482 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2484 /* Find the top-level shell of the widget. Note that this function
2485 can be called when the widget is not yet realized, so XtWindow
2486 (widget) == 0. That's the reason we can't simply use
2487 x_any_window_to_frame. */
2488 while (!XtIsTopLevelShell (widget
))
2489 widget
= XtParent (widget
);
2491 /* Look for a frame with that top-level widget. Allocate the color
2492 on that frame to get the right gamma correction value. */
2493 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2494 if (GC_FRAMEP (XCAR (tail
))
2495 && (f
= XFRAME (XCAR (tail
)),
2496 (f
->output_data
.nothing
!= 1
2497 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2498 && f
->output_data
.x
->widget
== widget
)
2505 /* Allocate the color COLOR->pixel on the screen and display of
2506 widget WIDGET in colormap CMAP. If an exact match cannot be
2507 allocated, try the nearest color available. Value is non-zero
2508 if successful. This is called from lwlib. */
2511 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2516 struct frame
*f
= x_frame_of_widget (widget
);
2517 return x_alloc_nearest_color (f
, cmap
, color
);
2521 #endif /* USE_X_TOOLKIT */
2523 #if 0 /* MAC_TODO */
2525 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2526 CMAP. If an exact match can't be allocated, try the nearest color
2527 available. Value is non-zero if successful. Set *COLOR to the
2531 x_alloc_nearest_color (f
, cmap
, color
)
2536 Display
*display
= FRAME_X_DISPLAY (f
);
2537 Screen
*screen
= FRAME_X_SCREEN (f
);
2540 gamma_correct (f
, color
);
2541 rc
= XAllocColor (display
, cmap
, color
);
2544 /* If we got to this point, the colormap is full, so we're going
2545 to try to get the next closest color. The algorithm used is
2546 a least-squares matching, which is what X uses for closest
2547 color matching with StaticColor visuals. */
2549 unsigned long nearest_delta
= ~0;
2550 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2551 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2553 for (i
= 0; i
< ncells
; ++i
)
2555 XQueryColors (display
, cmap
, cells
, ncells
);
2557 for (nearest
= i
= 0; i
< ncells
; ++i
)
2559 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2560 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2561 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2562 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2564 if (delta
< nearest_delta
)
2567 nearest_delta
= delta
;
2571 color
->red
= cells
[nearest
].red
;
2572 color
->green
= cells
[nearest
].green
;
2573 color
->blue
= cells
[nearest
].blue
;
2574 rc
= XAllocColor (display
, cmap
, color
);
2577 #ifdef DEBUG_X_COLORS
2579 register_color (color
->pixel
);
2580 #endif /* DEBUG_X_COLORS */
2586 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
2587 It's necessary to do this instead of just using PIXEL directly to
2588 get color reference counts right. */
2591 x_copy_color (f
, pixel
)
2593 unsigned long pixel
;
2597 color
.pixel
= pixel
;
2599 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2600 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
2602 #ifdef DEBUG_X_COLORS
2603 register_color (pixel
);
2609 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
2610 It's necessary to do this instead of just using PIXEL directly to
2611 get color reference counts right. */
2614 x_copy_dpy_color (dpy
, cmap
, pixel
)
2617 unsigned long pixel
;
2621 color
.pixel
= pixel
;
2623 XQueryColor (dpy
, cmap
, &color
);
2624 XAllocColor (dpy
, cmap
, &color
);
2626 #ifdef DEBUG_X_COLORS
2627 register_color (pixel
);
2632 #endif /* MAC_TODO */
2635 /* Brightness beyond which a color won't have its highlight brightness
2638 Nominally, highlight colors for `3d' faces are calculated by
2639 brightening an object's color by a constant scale factor, but this
2640 doesn't yield good results for dark colors, so for colors who's
2641 brightness is less than this value (on a scale of 0-255) have to
2642 use an additional additive factor.
2644 The value here is set so that the default menu-bar/mode-line color
2645 (grey75) will not have its highlights changed at all. */
2646 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2649 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
2650 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2651 If this produces the same color as COLOR, try a color where all RGB
2652 values have DELTA added. Return the allocated color in *COLOR.
2653 DISPLAY is the X display, CMAP is the colormap to operate on.
2654 Value is non-zero if successful. */
2657 mac_alloc_lighter_color (f
, color
, factor
, delta
)
2659 unsigned long *color
;
2666 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2669 /* Change RGB values by specified FACTOR. Avoid overflow! */
2670 xassert (factor
>= 0);
2671 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
2672 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
2673 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
2675 /* Calculate brightness of COLOR. */
2676 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
2677 + BLUE_FROM_ULONG (*color
)) / 6;
2679 /* We only boost colors that are darker than
2680 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2681 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
2682 /* Make an additive adjustment to NEW, because it's dark enough so
2683 that scaling by FACTOR alone isn't enough. */
2685 /* How far below the limit this color is (0 - 1, 1 being darker). */
2686 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
2687 /* The additive adjustment. */
2688 int min_delta
= delta
* dimness
* factor
/ 2;
2691 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
2692 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
2693 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
2695 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
2696 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
2697 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
2701 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
2702 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
2703 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
2705 /* MAC_TODO: Map to palette and retry with delta if same? */
2706 /* MAC_TODO: Free colors (if using palette)? */
2717 /* Set up the foreground color for drawing relief lines of glyph
2718 string S. RELIEF is a pointer to a struct relief containing the GC
2719 with which lines will be drawn. Use a color that is FACTOR or
2720 DELTA lighter or darker than the relief's background which is found
2721 in S->f->output_data.x->relief_background. If such a color cannot
2722 be allocated, use DEFAULT_PIXEL, instead. */
2725 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
2727 struct relief
*relief
;
2730 unsigned long default_pixel
;
2733 struct mac_output
*di
= f
->output_data
.mac
;
2734 unsigned long mask
= GCForeground
;
2735 unsigned long pixel
;
2736 unsigned long background
= di
->relief_background
;
2737 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
2739 /* MAC_TODO: Free colors (if using palette)? */
2741 /* Allocate new color. */
2742 xgcv
.foreground
= default_pixel
;
2744 if (dpyinfo
->n_planes
!= 1
2745 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
2747 relief
->allocated_p
= 1;
2748 xgcv
.foreground
= relief
->pixel
= pixel
;
2751 if (relief
->gc
== 0)
2753 #if 0 /* MAC_TODO: stipple */
2754 xgcv
.stipple
= dpyinfo
->gray
;
2757 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
2760 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
2764 /* Set up colors for the relief lines around glyph string S. */
2767 x_setup_relief_colors (s
)
2768 struct glyph_string
*s
;
2770 struct mac_output
*di
= s
->f
->output_data
.mac
;
2771 unsigned long color
;
2773 if (s
->face
->use_box_color_for_shadows_p
)
2774 color
= s
->face
->box_color
;
2775 else if (s
->first_glyph
->type
== IMAGE_GLYPH
2777 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
2778 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
2783 /* Get the background color of the face. */
2784 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
2785 color
= xgcv
.background
;
2788 if (di
->white_relief
.gc
== 0
2789 || color
!= di
->relief_background
)
2791 di
->relief_background
= color
;
2792 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
2793 WHITE_PIX_DEFAULT (s
->f
));
2794 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
2795 BLACK_PIX_DEFAULT (s
->f
));
2800 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
2801 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
2802 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
2803 relief. LEFT_P non-zero means draw a relief on the left side of
2804 the rectangle. RIGHT_P non-zero means draw a relief on the right
2805 side of the rectangle. CLIP_RECT is the clipping rectangle to use
2809 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
2810 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
2812 int left_x
, top_y
, right_x
, bottom_y
, width
;
2813 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
2816 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
2817 Window window
= FRAME_MAC_WINDOW (f
);
2822 gc
= f
->output_data
.mac
->white_relief
.gc
;
2824 gc
= f
->output_data
.mac
->black_relief
.gc
;
2825 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
2829 for (i
= 0; i
< width
; ++i
)
2830 XDrawLine (dpy
, window
, gc
,
2831 left_x
+ i
* left_p
, top_y
+ i
,
2832 right_x
- i
* right_p
, top_y
+ i
);
2836 for (i
= 0; i
< width
; ++i
)
2837 XDrawLine (dpy
, window
, gc
,
2838 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
);
2840 mac_reset_clip_rectangles (dpy
, gc
);
2842 gc
= f
->output_data
.mac
->black_relief
.gc
;
2844 gc
= f
->output_data
.mac
->white_relief
.gc
;
2845 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
2849 for (i
= 0; i
< width
; ++i
)
2850 XDrawLine (dpy
, window
, gc
,
2851 left_x
+ i
* left_p
, bottom_y
- i
,
2852 right_x
- i
* right_p
, bottom_y
- i
);
2856 for (i
= 0; i
< width
; ++i
)
2857 XDrawLine (dpy
, window
, gc
,
2858 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
- 1);
2860 mac_reset_clip_rectangles (dpy
, gc
);
2864 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
2865 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
2866 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
2867 left side of the rectangle. RIGHT_P non-zero means draw a line
2868 on the right side of the rectangle. CLIP_RECT is the clipping
2869 rectangle to use when drawing. */
2872 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2873 left_p
, right_p
, clip_rect
)
2874 struct glyph_string
*s
;
2875 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
2880 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
2881 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
2882 mac_set_clip_rectangles (s
->display
, s
->gc
, clip_rect
, 1);
2885 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2886 left_x
, top_y
, right_x
- left_x
+ 1, width
);
2890 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2891 left_x
, top_y
, width
, bottom_y
- top_y
+ 1);
2894 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2895 left_x
, bottom_y
- width
+ 1, right_x
- left_x
+ 1, width
);
2899 XFillRectangle (s
->display
, s
->window
, s
->gc
,
2900 right_x
- width
+ 1, top_y
, width
, bottom_y
- top_y
+ 1);
2902 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
2903 mac_reset_clip_rectangles (s
->display
, s
->gc
);
2907 /* Draw a box around glyph string S. */
2910 x_draw_glyph_string_box (s
)
2911 struct glyph_string
*s
;
2913 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
2914 int left_p
, right_p
;
2915 struct glyph
*last_glyph
;
2918 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
2919 ? WINDOW_RIGHT_EDGE_X (s
->w
)
2920 : window_box_right (s
->w
, s
->area
));
2922 /* The glyph that may have a right box line. */
2923 last_glyph
= (s
->cmp
|| s
->img
2925 : s
->first_glyph
+ s
->nchars
- 1);
2927 width
= abs (s
->face
->box_line_width
);
2928 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
2930 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
2932 : min (last_x
, s
->x
+ s
->background_width
) - 1);
2934 bottom_y
= top_y
+ s
->height
- 1;
2936 left_p
= (s
->first_glyph
->left_box_line_p
2937 || (s
->hl
== DRAW_MOUSE_FACE
2939 || s
->prev
->hl
!= s
->hl
)));
2940 right_p
= (last_glyph
->right_box_line_p
2941 || (s
->hl
== DRAW_MOUSE_FACE
2943 || s
->next
->hl
!= s
->hl
)));
2945 get_glyph_string_clip_rect (s
, &clip_rect
);
2947 if (s
->face
->box
== FACE_SIMPLE_BOX
)
2948 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
2949 left_p
, right_p
, &clip_rect
);
2952 x_setup_relief_colors (s
);
2953 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
2954 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
2959 /* Draw foreground of image glyph string S. */
2962 x_draw_image_foreground (s
)
2963 struct glyph_string
*s
;
2966 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
2968 /* If first glyph of S has a left box line, start drawing it to the
2969 right of that line. */
2970 if (s
->face
->box
!= FACE_NO_BOX
2971 && s
->first_glyph
->left_box_line_p
2973 x
+= abs (s
->face
->box_line_width
);
2975 /* If there is a margin around the image, adjust x- and y-position
2977 if (s
->slice
.x
== 0)
2978 x
+= s
->img
->hmargin
;
2979 if (s
->slice
.y
== 0)
2980 y
+= s
->img
->vmargin
;
2984 x_set_glyph_string_clipping (s
);
2987 mac_copy_area_with_mask (s
->display
, s
->img
->pixmap
, s
->img
->mask
,
2988 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2989 s
->slice
.width
, s
->slice
.height
, x
, y
);
2992 mac_copy_area (s
->display
, s
->img
->pixmap
,
2993 s
->window
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
2994 s
->slice
.width
, s
->slice
.height
, x
, y
);
2996 /* When the image has a mask, we can expect that at
2997 least part of a mouse highlight or a block cursor will
2998 be visible. If the image doesn't have a mask, make
2999 a block cursor visible by drawing a rectangle around
3000 the image. I believe it's looking better if we do
3001 nothing here for mouse-face. */
3002 if (s
->hl
== DRAW_CURSOR
)
3004 int r
= s
->img
->relief
;
3006 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
,
3008 s
->slice
.width
+ r
*2 - 1,
3009 s
->slice
.height
+ r
*2 - 1);
3014 /* Draw a rectangle if image could not be loaded. */
3015 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
, y
,
3016 s
->slice
.width
- 1, s
->slice
.height
- 1);
3020 /* Draw a relief around the image glyph string S. */
3023 x_draw_image_relief (s
)
3024 struct glyph_string
*s
;
3026 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3029 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3031 /* If first glyph of S has a left box line, start drawing it to the
3032 right of that line. */
3033 if (s
->face
->box
!= FACE_NO_BOX
3034 && s
->first_glyph
->left_box_line_p
3036 x
+= abs (s
->face
->box_line_width
);
3038 /* If there is a margin around the image, adjust x- and y-position
3040 if (s
->slice
.x
== 0)
3041 x
+= s
->img
->hmargin
;
3042 if (s
->slice
.y
== 0)
3043 y
+= s
->img
->vmargin
;
3045 if (s
->hl
== DRAW_IMAGE_SUNKEN
3046 || s
->hl
== DRAW_IMAGE_RAISED
)
3048 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3049 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3053 thick
= abs (s
->img
->relief
);
3054 raised_p
= s
->img
->relief
> 0;
3059 x1
= x
+ s
->slice
.width
+ thick
- 1;
3060 y1
= y
+ s
->slice
.height
+ thick
- 1;
3062 x_setup_relief_colors (s
);
3063 get_glyph_string_clip_rect (s
, &r
);
3064 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
3066 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
3068 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
3073 #if 0 /* TODO: figure out if we need to do this on Mac. */
3074 /* Draw the foreground of image glyph string S to PIXMAP. */
3077 x_draw_image_foreground_1 (s
, pixmap
)
3078 struct glyph_string
*s
;
3082 int y
= s
->ybase
- s
->y
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3084 /* If first glyph of S has a left box line, start drawing it to the
3085 right of that line. */
3086 if (s
->face
->box
!= FACE_NO_BOX
3087 && s
->first_glyph
->left_box_line_p
3089 x
+= abs (s
->face
->box_line_width
);
3091 /* If there is a margin around the image, adjust x- and y-position
3093 if (s
->slice
.x
== 0)
3094 x
+= s
->img
->hmargin
;
3095 if (s
->slice
.y
== 0)
3096 y
+= s
->img
->vmargin
;
3101 mac_copy_area_with_mask_to_pixmap (s
->display
, s
->img
->pixmap
,
3102 s
->img
->mask
, pixmap
, s
->gc
,
3103 s
->slice
.x
, s
->slice
.y
,
3104 s
->slice
.width
, s
->slice
.height
,
3108 mac_copy_area_to_pixmap (s
->display
, s
->img
->pixmap
, pixmap
, s
->gc
,
3109 s
->slice
.x
, s
->slice
.y
,
3110 s
->slice
.width
, s
->slice
.height
,
3113 /* When the image has a mask, we can expect that at
3114 least part of a mouse highlight or a block cursor will
3115 be visible. If the image doesn't have a mask, make
3116 a block cursor visible by drawing a rectangle around
3117 the image. I believe it's looking better if we do
3118 nothing here for mouse-face. */
3119 if (s
->hl
== DRAW_CURSOR
)
3121 int r
= s
->img
->relief
;
3123 mac_draw_rectangle (s
->display
, s
->window
, s
->gc
, x
- r
, y
- r
,
3124 s
->slice
.width
+ r
*2 - 1,
3125 s
->slice
.height
+ r
*2 - 1);
3130 /* Draw a rectangle if image could not be loaded. */
3131 mac_draw_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
, x
, y
,
3132 s
->slice
.width
- 1, s
->slice
.height
- 1);
3137 /* Draw part of the background of glyph string S. X, Y, W, and H
3138 give the rectangle to draw. */
3141 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3142 struct glyph_string
*s
;
3145 #if 0 /* MAC_TODO: stipple */
3148 /* Fill background with a stipple pattern. */
3149 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3150 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3151 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3154 #endif /* MAC_TODO */
3155 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3159 /* Draw image glyph string S.
3162 s->x +-------------------------
3165 | +-------------------------
3168 | | +-------------------
3174 x_draw_image_glyph_string (s
)
3175 struct glyph_string
*s
;
3178 int box_line_hwidth
= abs (s
->face
->box_line_width
);
3179 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
3183 height
= s
->height
- 2 * box_line_vwidth
;
3186 /* Fill background with face under the image. Do it only if row is
3187 taller than image or if image has a clip mask to reduce
3189 s
->stippled_p
= s
->face
->stipple
!= 0;
3190 if (height
> s
->slice
.height
3194 || s
->img
->pixmap
== 0
3195 || s
->width
!= s
->background_width
)
3198 if (s
->first_glyph
->left_box_line_p
3200 x
+= box_line_hwidth
;
3203 if (s
->slice
.y
== 0)
3204 y
+= box_line_vwidth
;
3206 #if 0 /* TODO: figure out if we need to do this on Mac. */
3209 /* Create a pixmap as large as the glyph string. Fill it
3210 with the background color. Copy the image to it, using
3211 its mask. Copy the temporary pixmap to the display. */
3212 int depth
= one_mac_display_info
.n_planes
;
3214 /* Create a pixmap as large as the glyph string. */
3215 pixmap
= XCreatePixmap (s
->display
, s
->window
,
3216 s
->background_width
,
3219 /* Fill the pixmap with the background color/stipple. */
3220 #if 0 /* TODO: stipple */
3223 /* Fill background with a stipple pattern. */
3224 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3225 XFillRectangle (s
->display
, pixmap
, s
->gc
,
3226 0, 0, s
->background_width
, s
->height
);
3227 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3233 XGetGCValues (s
->display
, s
->gc
, GCForeground
| GCBackground
,
3235 XSetForeground (s
->display
, s
->gc
, xgcv
.background
);
3236 mac_fill_rectangle_to_pixmap (s
->display
, pixmap
, s
->gc
,
3237 0, 0, s
->background_width
,
3239 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3244 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3246 s
->background_filled_p
= 1;
3249 /* Draw the foreground. */
3250 #if 0 /* TODO: figure out if we need to do this on Mac. */
3253 x_draw_image_foreground_1 (s
, pixmap
);
3254 x_set_glyph_string_clipping (s
);
3255 mac_copy_area (s
->display
, pixmap
, s
->window
, s
->gc
,
3256 0, 0, s
->background_width
, s
->height
, s
->x
, s
->y
);
3257 XFreePixmap (s
->display
, pixmap
);
3261 x_draw_image_foreground (s
);
3263 /* If we must draw a relief around the image, do it. */
3265 || s
->hl
== DRAW_IMAGE_RAISED
3266 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3267 x_draw_image_relief (s
);
3271 /* Draw stretch glyph string S. */
3274 x_draw_stretch_glyph_string (s
)
3275 struct glyph_string
*s
;
3277 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3278 s
->stippled_p
= s
->face
->stipple
!= 0;
3280 if (s
->hl
== DRAW_CURSOR
3281 && !x_stretch_cursor_p
)
3283 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3284 as wide as the stretch glyph. */
3285 int width
= min (FRAME_COLUMN_WIDTH (s
->f
), s
->background_width
);
3288 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, width
, s
->height
);
3290 /* Clear rest using the GC of the original non-cursor face. */
3291 if (width
< s
->background_width
)
3293 int x
= s
->x
+ width
, y
= s
->y
;
3294 int w
= s
->background_width
- width
, h
= s
->height
;
3298 if (s
->row
->mouse_face_p
3299 && cursor_in_mouse_face_p (s
->w
))
3301 x_set_mouse_face_gc (s
);
3307 get_glyph_string_clip_rect (s
, &r
);
3308 mac_set_clip_rectangles (s
->display
, gc
, &r
, 1);
3310 #if 0 /* MAC_TODO: stipple */
3311 if (s
->face
->stipple
)
3313 /* Fill background with a stipple pattern. */
3314 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3315 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3316 XSetFillStyle (s
->display
, gc
, FillSolid
);
3319 #endif /* MAC_TODO */
3320 mac_erase_rectangle (s
->window
, gc
, x
, y
, w
, h
);
3323 else if (!s
->background_filled_p
)
3324 x_draw_glyph_string_bg_rect (s
, s
->x
, s
->y
, s
->background_width
,
3327 s
->background_filled_p
= 1;
3331 /* Draw glyph string S. */
3334 x_draw_glyph_string (s
)
3335 struct glyph_string
*s
;
3337 int relief_drawn_p
= 0;
3339 /* If S draws into the background of its successor that does not
3340 draw a cursor, draw the background of the successor first so that
3341 S can draw into it. This makes S->next use XDrawString instead
3342 of XDrawImageString. */
3343 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps
3344 && s
->next
->hl
!= DRAW_CURSOR
)
3346 xassert (s
->next
->img
== NULL
);
3347 x_set_glyph_string_gc (s
->next
);
3348 x_set_glyph_string_clipping (s
->next
);
3349 x_draw_glyph_string_background (s
->next
, 1);
3352 /* Set up S->gc, set clipping and draw S. */
3353 x_set_glyph_string_gc (s
);
3355 /* Draw relief (if any) in advance for char/composition so that the
3356 glyph string can be drawn over it. */
3357 if (!s
->for_overlaps
3358 && s
->face
->box
!= FACE_NO_BOX
3359 && (s
->first_glyph
->type
== CHAR_GLYPH
3360 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3363 x_set_glyph_string_clipping (s
);
3364 x_draw_glyph_string_background (s
, 1);
3365 x_draw_glyph_string_box (s
);
3366 x_set_glyph_string_clipping (s
);
3370 x_set_glyph_string_clipping (s
);
3372 switch (s
->first_glyph
->type
)
3375 x_draw_image_glyph_string (s
);
3379 x_draw_stretch_glyph_string (s
);
3383 if (s
->for_overlaps
)
3384 s
->background_filled_p
= 1;
3386 x_draw_glyph_string_background (s
, 0);
3387 x_draw_glyph_string_foreground (s
);
3390 case COMPOSITE_GLYPH
:
3391 if (s
->for_overlaps
|| s
->gidx
> 0)
3392 s
->background_filled_p
= 1;
3394 x_draw_glyph_string_background (s
, 1);
3395 x_draw_composite_glyph_string_foreground (s
);
3402 if (!s
->for_overlaps
)
3404 /* Draw underline. */
3405 if (s
->face
->underline_p
)
3407 unsigned long h
= 1;
3408 unsigned long dy
= s
->height
- h
;
3410 if (s
->face
->underline_defaulted_p
)
3411 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3416 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3417 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3418 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3420 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3424 /* Draw overline. */
3425 if (s
->face
->overline_p
)
3427 unsigned long dy
= 0, h
= 1;
3429 if (s
->face
->overline_color_defaulted_p
)
3430 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3435 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3436 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3437 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3439 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3443 /* Draw strike-through. */
3444 if (s
->face
->strike_through_p
)
3446 unsigned long h
= 1;
3447 unsigned long dy
= (s
->height
- h
) / 2;
3449 if (s
->face
->strike_through_color_defaulted_p
)
3450 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3455 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3456 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3457 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
, s
->y
+ dy
,
3459 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3463 /* Draw relief if not yet drawn. */
3464 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3465 x_draw_glyph_string_box (s
);
3468 /* Reset clipping. */
3469 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3472 /* Shift display to make room for inserted glyphs. */
3475 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3477 int x
, y
, width
, height
, shift_by
;
3479 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3480 f
->output_data
.mac
->normal_gc
,
3481 x
, y
, width
, height
,
3485 /* Delete N glyphs at the nominal cursor position. Not implemented
3496 /* Clear entire frame. If updating_frame is non-null, clear that
3497 frame. Otherwise clear the selected frame. */
3507 f
= SELECTED_FRAME ();
3509 /* Clearing the frame will erase any cursor, so mark them all as no
3511 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3512 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3513 output_cursor
.x
= -1;
3515 /* We don't set the output cursor here because there will always
3516 follow an explicit cursor_to. */
3518 XClearWindow (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
));
3520 /* We have to clear the scroll bars, too. If we have changed
3521 colors or something like that, then they should be notified. */
3522 x_scroll_bar_clear (f
);
3524 XFlush (FRAME_MAC_DISPLAY (f
));
3530 /* Invert the middle quarter of the frame for .15 sec. */
3532 /* We use the select system call to do the waiting, so we have to make
3533 sure it's available. If it isn't, we just won't do visual bells. */
3535 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3538 /* Subtract the `struct timeval' values X and Y, storing the result in
3539 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3542 timeval_subtract (result
, x
, y
)
3543 struct timeval
*result
, x
, y
;
3545 /* Perform the carry for the later subtraction by updating y. This
3546 is safer because on some systems the tv_sec member is unsigned. */
3547 if (x
.tv_usec
< y
.tv_usec
)
3549 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3550 y
.tv_usec
-= 1000000 * nsec
;
3554 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3556 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3557 y
.tv_usec
+= 1000000 * nsec
;
3561 /* Compute the time remaining to wait. tv_usec is certainly
3563 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3564 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3566 /* Return indication of whether the result should be considered
3568 return x
.tv_sec
< y
.tv_sec
;
3575 /* Get the height not including a menu bar widget. */
3576 int height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, FRAME_LINES (f
));
3577 /* Height of each line to flash. */
3578 int flash_height
= FRAME_LINE_HEIGHT (f
);
3579 /* These will be the left and right margins of the rectangles. */
3580 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
3581 int flash_right
= FRAME_PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
3585 /* Don't flash the area between a scroll bar and the frame
3586 edge it is next to. */
3587 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
3589 case vertical_scroll_bar_left
:
3590 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3593 case vertical_scroll_bar_right
:
3594 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3601 width
= flash_right
- flash_left
;
3605 /* If window is tall, flash top and bottom line. */
3606 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3608 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3610 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3611 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3612 width
, flash_height
);
3613 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3615 (height
- flash_height
3616 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3617 width
, flash_height
);
3620 /* If it is short, flash it all. */
3621 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3622 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3623 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3628 struct timeval wakeup
;
3630 EMACS_GET_TIME (wakeup
);
3632 /* Compute time to wait until, propagating carry from usecs. */
3633 wakeup
.tv_usec
+= 150000;
3634 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3635 wakeup
.tv_usec
%= 1000000;
3637 /* Keep waiting until past the time wakeup or any input gets
3639 while (! detect_input_pending ())
3641 struct timeval current
;
3642 struct timeval timeout
;
3644 EMACS_GET_TIME (current
);
3646 /* Break if result would be negative. */
3647 if (timeval_subtract (¤t
, wakeup
, current
))
3650 /* How long `select' should wait. */
3652 timeout
.tv_usec
= 10000;
3654 /* Try to wait that long--but we might wake up sooner. */
3655 select (0, NULL
, NULL
, NULL
, &timeout
);
3659 /* If window is tall, flash top and bottom line. */
3660 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3662 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3664 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3665 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3666 width
, flash_height
);
3667 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3669 (height
- flash_height
3670 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3671 width
, flash_height
);
3674 /* If it is short, flash it all. */
3675 mac_invert_rectangle (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3676 flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3677 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3684 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
3687 /* Make audible bell. */
3692 struct frame
*f
= SELECTED_FRAME ();
3694 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3702 XFlush (FRAME_MAC_DISPLAY (f
));
3708 /* Specify how many text lines, from the top of the window,
3709 should be affected by insert-lines and delete-lines operations.
3710 This, and those operations, are used only within an update
3711 that is bounded by calls to x_update_begin and x_update_end. */
3714 XTset_terminal_window (n
)
3717 /* This function intentionally left blank. */
3722 /***********************************************************************
3724 ***********************************************************************/
3726 /* Perform an insert-lines or delete-lines operation, inserting N
3727 lines or deleting -N lines at vertical position VPOS. */
3730 x_ins_del_lines (vpos
, n
)
3737 /* Scroll part of the display as described by RUN. */
3740 x_scroll_run (w
, run
)
3744 struct frame
*f
= XFRAME (w
->frame
);
3745 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
3747 /* Get frame-relative bounding box of the text display area of W,
3748 without mode lines. Include in this box the left and right
3750 window_box (w
, -1, &x
, &y
, &width
, &height
);
3752 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
3753 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
3754 bottom_y
= y
+ height
;
3758 /* Scrolling up. Make sure we don't copy part of the mode
3759 line at the bottom. */
3760 if (from_y
+ run
->height
> bottom_y
)
3761 height
= bottom_y
- from_y
;
3763 height
= run
->height
;
3767 /* Scolling down. Make sure we don't copy over the mode line.
3769 if (to_y
+ run
->height
> bottom_y
)
3770 height
= bottom_y
- to_y
;
3772 height
= run
->height
;
3777 /* Cursor off. Will be switched on again in x_update_window_end. */
3781 mac_scroll_area (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
3782 f
->output_data
.mac
->normal_gc
,
3792 /***********************************************************************
3794 ***********************************************************************/
3802 ControlRef root_control
;
3805 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3807 ActivateControl (root_control
);
3809 x_update_cursor (f
, 1);
3813 frame_unhighlight (f
)
3817 ControlRef root_control
;
3820 err
= GetRootControl (FRAME_MAC_WINDOW (f
), &root_control
);
3822 DeactivateControl (root_control
);
3824 x_update_cursor (f
, 1);
3827 /* The focus has changed. Update the frames as necessary to reflect
3828 the new situation. Note that we can't change the selected frame
3829 here, because the Lisp code we are interrupting might become confused.
3830 Each event gets marked with the frame in which it occurred, so the
3831 Lisp code can tell when the switch took place by examining the events. */
3834 x_new_focus_frame (dpyinfo
, frame
)
3835 struct x_display_info
*dpyinfo
;
3836 struct frame
*frame
;
3838 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
3840 if (frame
!= dpyinfo
->x_focus_frame
)
3842 /* Set this before calling other routines, so that they see
3843 the correct value of x_focus_frame. */
3844 dpyinfo
->x_focus_frame
= frame
;
3846 if (old_focus
&& old_focus
->auto_lower
)
3847 x_lower_frame (old_focus
);
3850 selected_frame
= frame
;
3851 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
3853 Fselect_window (selected_frame
->selected_window
, Qnil
);
3854 choose_minibuf_frame ();
3857 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
3858 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
3860 pending_autoraise_frame
= 0;
3863 x_frame_rehighlight (dpyinfo
);
3866 /* Handle FocusIn and FocusOut state changes for FRAME.
3867 If FRAME has focus and there exists more than one frame, puts
3868 a FOCUS_IN_EVENT into *BUFP. */
3871 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
3873 struct mac_display_info
*dpyinfo
;
3874 struct frame
*frame
;
3875 struct input_event
*bufp
;
3877 if (type
== activeFlag
)
3879 if (dpyinfo
->x_focus_event_frame
!= frame
)
3881 x_new_focus_frame (dpyinfo
, frame
);
3882 dpyinfo
->x_focus_event_frame
= frame
;
3884 /* Don't stop displaying the initial startup message
3885 for a switch-frame event we don't need. */
3886 if (GC_NILP (Vterminal_frame
)
3887 && GC_CONSP (Vframe_list
)
3888 && !GC_NILP (XCDR (Vframe_list
)))
3890 bufp
->kind
= FOCUS_IN_EVENT
;
3891 XSETFRAME (bufp
->frame_or_window
, frame
);
3897 if (dpyinfo
->x_focus_event_frame
== frame
)
3899 dpyinfo
->x_focus_event_frame
= 0;
3900 x_new_focus_frame (dpyinfo
, 0);
3905 /* The focus may have changed. Figure out if it is a real focus change,
3906 by checking both FocusIn/Out and Enter/LeaveNotify events.
3908 Returns FOCUS_IN_EVENT event in *BUFP. */
3911 x_detect_focus_change (dpyinfo
, event
, bufp
)
3912 struct mac_display_info
*dpyinfo
;
3914 struct input_event
*bufp
;
3916 struct frame
*frame
;
3918 frame
= mac_window_to_frame ((WindowPtr
) event
->message
);
3922 /* On Mac, this is only called from focus events, so no switch needed. */
3923 mac_focus_changed ((event
->modifiers
& activeFlag
),
3924 dpyinfo
, frame
, bufp
);
3928 /* Handle an event saying the mouse has moved out of an Emacs frame. */
3931 x_mouse_leave (dpyinfo
)
3932 struct x_display_info
*dpyinfo
;
3934 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
3937 /* The focus has changed, or we have redirected a frame's focus to
3938 another frame (this happens when a frame uses a surrogate
3939 mini-buffer frame). Shift the highlight as appropriate.
3941 The FRAME argument doesn't necessarily have anything to do with which
3942 frame is being highlighted or un-highlighted; we only use it to find
3943 the appropriate X display info. */
3946 XTframe_rehighlight (frame
)
3947 struct frame
*frame
;
3949 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
3953 x_frame_rehighlight (dpyinfo
)
3954 struct x_display_info
*dpyinfo
;
3956 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
3958 if (dpyinfo
->x_focus_frame
)
3960 dpyinfo
->x_highlight_frame
3961 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
3962 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
3963 : dpyinfo
->x_focus_frame
);
3964 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
3966 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
3967 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
3971 dpyinfo
->x_highlight_frame
= 0;
3973 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
3976 frame_unhighlight (old_highlight
);
3977 if (dpyinfo
->x_highlight_frame
)
3978 frame_highlight (dpyinfo
->x_highlight_frame
);
3984 /* Keyboard processing - modifier keys, vendor-specific keysyms, etc. */
3986 #if 0 /* MAC_TODO */
3987 /* Initialize mode_switch_bit and modifier_meaning. */
3989 x_find_modifier_meanings (dpyinfo
)
3990 struct x_display_info
*dpyinfo
;
3992 int min_code
, max_code
;
3995 XModifierKeymap
*mods
;
3997 dpyinfo
->meta_mod_mask
= 0;
3998 dpyinfo
->shift_lock_mask
= 0;
3999 dpyinfo
->alt_mod_mask
= 0;
4000 dpyinfo
->super_mod_mask
= 0;
4001 dpyinfo
->hyper_mod_mask
= 0;
4004 XDisplayKeycodes (dpyinfo
->display
, &min_code
, &max_code
);
4006 min_code
= dpyinfo
->display
->min_keycode
;
4007 max_code
= dpyinfo
->display
->max_keycode
;
4010 syms
= XGetKeyboardMapping (dpyinfo
->display
,
4011 min_code
, max_code
- min_code
+ 1,
4013 mods
= XGetModifierMapping (dpyinfo
->display
);
4015 /* Scan the modifier table to see which modifier bits the Meta and
4016 Alt keysyms are on. */
4018 int row
, col
; /* The row and column in the modifier table. */
4020 for (row
= 3; row
< 8; row
++)
4021 for (col
= 0; col
< mods
->max_keypermod
; col
++)
4024 = mods
->modifiermap
[(row
* mods
->max_keypermod
) + col
];
4026 /* Zeroes are used for filler. Skip them. */
4030 /* Are any of this keycode's keysyms a meta key? */
4034 for (code_col
= 0; code_col
< syms_per_code
; code_col
++)
4036 int sym
= syms
[((code
- min_code
) * syms_per_code
) + code_col
];
4042 dpyinfo
->meta_mod_mask
|= (1 << row
);
4047 dpyinfo
->alt_mod_mask
|= (1 << row
);
4052 dpyinfo
->hyper_mod_mask
|= (1 << row
);
4057 dpyinfo
->super_mod_mask
|= (1 << row
);
4061 /* Ignore this if it's not on the lock modifier. */
4062 if ((1 << row
) == LockMask
)
4063 dpyinfo
->shift_lock_mask
= LockMask
;
4071 /* If we couldn't find any meta keys, accept any alt keys as meta keys. */
4072 if (! dpyinfo
->meta_mod_mask
)
4074 dpyinfo
->meta_mod_mask
= dpyinfo
->alt_mod_mask
;
4075 dpyinfo
->alt_mod_mask
= 0;
4078 /* If some keys are both alt and meta,
4079 make them just meta, not alt. */
4080 if (dpyinfo
->alt_mod_mask
& dpyinfo
->meta_mod_mask
)
4082 dpyinfo
->alt_mod_mask
&= ~dpyinfo
->meta_mod_mask
;
4085 XFree ((char *) syms
);
4086 XFreeModifiermap (mods
);
4089 #endif /* MAC_TODO */
4091 /* Convert between the modifier bits X uses and the modifier bits
4095 x_mac_to_emacs_modifiers (dpyinfo
, state
)
4096 struct x_display_info
*dpyinfo
;
4097 unsigned short state
;
4099 return (((state
& shiftKey
) ? shift_modifier
: 0)
4100 | ((state
& controlKey
) ? ctrl_modifier
: 0)
4101 | ((state
& cmdKey
) ? meta_modifier
: 0)
4102 | ((state
& optionKey
) ? alt_modifier
: 0));
4105 #if 0 /* MAC_TODO */
4106 static unsigned short
4107 x_emacs_to_x_modifiers (dpyinfo
, state
)
4108 struct x_display_info
*dpyinfo
;
4111 return ( ((state
& alt_modifier
) ? dpyinfo
->alt_mod_mask
: 0)
4112 | ((state
& super_modifier
) ? dpyinfo
->super_mod_mask
: 0)
4113 | ((state
& hyper_modifier
) ? dpyinfo
->hyper_mod_mask
: 0)
4114 | ((state
& shift_modifier
) ? ShiftMask
: 0)
4115 | ((state
& ctrl_modifier
) ? ControlMask
: 0)
4116 | ((state
& meta_modifier
) ? dpyinfo
->meta_mod_mask
: 0));
4118 #endif /* MAC_TODO */
4120 /* Convert a keysym to its name. */
4123 x_get_keysym_name (keysym
)
4130 value
= XKeysymToString (keysym
);
4141 /* Function to report a mouse movement to the mainstream Emacs code.
4142 The input handler calls this.
4144 We have received a mouse movement event, which is given in *event.
4145 If the mouse is over a different glyph than it was last time, tell
4146 the mainstream emacs code by setting mouse_moved. If not, ask for
4147 another motion event, so we can check again the next time it moves. */
4149 static Point last_mouse_motion_position
;
4150 static Lisp_Object last_mouse_motion_frame
;
4153 note_mouse_movement (frame
, pos
)
4157 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4158 #if TARGET_API_MAC_CARBON
4162 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
4163 last_mouse_motion_position
= *pos
;
4164 XSETFRAME (last_mouse_motion_frame
, frame
);
4166 #if TARGET_API_MAC_CARBON
4167 if (!PtInRect (*pos
, GetWindowPortBounds (FRAME_MAC_WINDOW (frame
), &r
)))
4169 if (!PtInRect (*pos
, &FRAME_MAC_WINDOW (frame
)->portRect
))
4172 if (frame
== dpyinfo
->mouse_face_mouse_frame
)
4173 /* This case corresponds to LeaveNotify in X11. */
4175 /* If we move outside the frame, then we're certainly no
4176 longer on any text in the frame. */
4177 clear_mouse_face (dpyinfo
);
4178 dpyinfo
->mouse_face_mouse_frame
= 0;
4179 if (!dpyinfo
->grabbed
)
4180 rif
->define_frame_cursor (frame
,
4181 frame
->output_data
.mac
->nontext_cursor
);
4184 /* Has the mouse moved off the glyph it was on at the last sighting? */
4185 else if (pos
->h
< last_mouse_glyph
.left
4186 || pos
->h
>= last_mouse_glyph
.right
4187 || pos
->v
< last_mouse_glyph
.top
4188 || pos
->v
>= last_mouse_glyph
.bottom
)
4190 frame
->mouse_moved
= 1;
4191 last_mouse_scroll_bar
= Qnil
;
4192 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
4193 /* Remember which glyph we're now on. */
4194 remember_mouse_glyph (frame
, pos
->h
, pos
->v
, &last_mouse_glyph
);
4197 help_echo_string
= previous_help_echo_string
;
4201 /************************************************************************
4203 ************************************************************************/
4205 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4208 redo_mouse_highlight ()
4210 if (!NILP (last_mouse_motion_frame
)
4211 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
4212 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
4213 last_mouse_motion_position
.h
,
4214 last_mouse_motion_position
.v
);
4218 static struct frame
*
4219 mac_focus_frame (dpyinfo
)
4220 struct mac_display_info
*dpyinfo
;
4222 if (dpyinfo
->x_focus_frame
)
4223 return dpyinfo
->x_focus_frame
;
4225 /* Mac version may get events, such as a menu bar click, even when
4226 all the frames are invisible. In this case, we regard the
4227 event came to the selected frame. */
4228 return SELECTED_FRAME ();
4232 /* Return the current position of the mouse.
4233 *FP should be a frame which indicates which display to ask about.
4235 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4236 and *PART to the frame, window, and scroll bar part that the mouse
4237 is over. Set *X and *Y to the portion and whole of the mouse's
4238 position on the scroll bar.
4240 If the mouse movement started elsewhere, set *FP to the frame the
4241 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
4244 Set *TIME to the server time-stamp for the time at which the mouse
4245 was at this position.
4247 Don't store anything if we don't have a valid set of values to report.
4249 This clears the mouse_moved flag, so we can wait for the next mouse
4253 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
4256 Lisp_Object
*bar_window
;
4257 enum scroll_bar_part
*part
;
4259 unsigned long *time
;
4265 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
4266 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
4269 Lisp_Object frame
, tail
;
4271 /* Clear the mouse-moved flag for every frame on this display. */
4272 FOR_EACH_FRAME (tail
, frame
)
4273 XFRAME (frame
)->mouse_moved
= 0;
4275 last_mouse_scroll_bar
= Qnil
;
4277 if (FRAME_MAC_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
4278 && FRAME_LIVE_P (last_mouse_frame
))
4279 f1
= last_mouse_frame
;
4281 f1
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
4285 /* Ok, we found a frame. Store all the values.
4286 last_mouse_glyph is a rectangle used to reduce the
4287 generation of mouse events. To not miss any motion
4288 events, we must divide the frame into rectangles of the
4289 size of the smallest character that could be displayed
4290 on it, i.e. into the same rectangles that matrices on
4291 the frame are divided into. */
4294 SetPortWindowPort (FRAME_MAC_WINDOW (f1
));
4295 GetMouse (&mouse_pos
);
4296 remember_mouse_glyph (f1
, mouse_pos
.h
, mouse_pos
.v
,
4302 XSETINT (*x
, mouse_pos
.h
);
4303 XSETINT (*y
, mouse_pos
.v
);
4304 *time
= last_mouse_movement_time
;
4312 /************************************************************************
4314 ************************************************************************/
4316 #ifdef USE_TOOLKIT_SCROLL_BARS
4318 static pascal void scroll_bar_timer_callback
P_ ((EventLoopTimerRef
, void *));
4319 static OSStatus install_scroll_bar_timer
P_ ((void));
4320 static OSStatus set_scroll_bar_timer
P_ ((EventTimerInterval
));
4321 static int control_part_code_to_scroll_bar_part
P_ ((ControlPartCode
));
4322 static void construct_scroll_bar_click
P_ ((struct scroll_bar
*, int,
4323 struct input_event
*));
4324 static OSErr get_control_part_bounds
P_ ((ControlHandle
, ControlPartCode
,
4326 static void x_scroll_bar_handle_press
P_ ((struct scroll_bar
*,
4328 struct input_event
*));
4329 static void x_scroll_bar_handle_release
P_ ((struct scroll_bar
*,
4330 struct input_event
*));
4331 static void x_scroll_bar_handle_drag
P_ ((WindowPtr
, struct scroll_bar
*,
4332 Point
, struct input_event
*));
4333 static void x_set_toolkit_scroll_bar_thumb
P_ ((struct scroll_bar
*,
4336 /* Last scroll bar part sent in x_scroll_bar_handle_*. */
4338 static int last_scroll_bar_part
;
4340 static EventLoopTimerRef scroll_bar_timer
;
4342 static int scroll_bar_timer_event_posted_p
;
4344 #define SCROLL_BAR_FIRST_DELAY 0.5
4345 #define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15)
4348 scroll_bar_timer_callback (timer
, data
)
4349 EventLoopTimerRef timer
;
4352 EventRef event
= NULL
;
4355 err
= CreateEvent (NULL
, kEventClassMouse
, kEventMouseMoved
, 0,
4356 kEventAttributeNone
, &event
);
4361 GetMouse (&mouse_pos
);
4362 LocalToGlobal (&mouse_pos
);
4363 err
= SetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
4364 sizeof (Point
), &mouse_pos
);
4368 UInt32 modifiers
= GetCurrentKeyModifiers ();
4370 err
= SetEventParameter (event
, kEventParamKeyModifiers
, typeUInt32
,
4371 sizeof (UInt32
), &modifiers
);
4374 err
= PostEventToQueue (GetCurrentEventQueue (), event
,
4375 kEventPriorityStandard
);
4377 scroll_bar_timer_event_posted_p
= 1;
4380 ReleaseEvent (event
);
4384 install_scroll_bar_timer ()
4386 static EventLoopTimerUPP scroll_bar_timer_callbackUPP
= NULL
;
4388 if (scroll_bar_timer_callbackUPP
== NULL
)
4389 scroll_bar_timer_callbackUPP
=
4390 NewEventLoopTimerUPP (scroll_bar_timer_callback
);
4392 if (scroll_bar_timer
== NULL
)
4393 /* Mac OS X and CarbonLib 1.5 and later allow us to specify
4394 kEventDurationForever as delays. */
4396 InstallEventLoopTimer (GetCurrentEventLoop (),
4397 kEventDurationForever
, kEventDurationForever
,
4398 scroll_bar_timer_callbackUPP
, NULL
,
4403 set_scroll_bar_timer (delay
)
4404 EventTimerInterval delay
;
4406 if (scroll_bar_timer
== NULL
)
4407 install_scroll_bar_timer ();
4409 scroll_bar_timer_event_posted_p
= 0;
4411 return SetEventLoopTimerNextFireTime (scroll_bar_timer
, delay
);
4415 control_part_code_to_scroll_bar_part (part_code
)
4416 ControlPartCode part_code
;
4420 case kControlUpButtonPart
: return scroll_bar_up_arrow
;
4421 case kControlDownButtonPart
: return scroll_bar_down_arrow
;
4422 case kControlPageUpPart
: return scroll_bar_above_handle
;
4423 case kControlPageDownPart
: return scroll_bar_below_handle
;
4424 case kControlIndicatorPart
: return scroll_bar_handle
;
4431 construct_scroll_bar_click (bar
, part
, bufp
)
4432 struct scroll_bar
*bar
;
4434 struct input_event
*bufp
;
4436 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
4437 bufp
->frame_or_window
= bar
->window
;
4441 XSETINT (bufp
->x
, 0);
4442 XSETINT (bufp
->y
, 0);
4443 bufp
->modifiers
= 0;
4447 get_control_part_bounds (ch
, part_code
, rect
)
4449 ControlPartCode part_code
;
4452 RgnHandle region
= NewRgn ();
4455 err
= GetControlRegion (ch
, part_code
, region
);
4457 GetRegionBounds (region
, rect
);
4458 DisposeRgn (region
);
4464 x_scroll_bar_handle_press (bar
, part_code
, bufp
)
4465 struct scroll_bar
*bar
;
4466 ControlPartCode part_code
;
4467 struct input_event
*bufp
;
4469 int part
= control_part_code_to_scroll_bar_part (part_code
);
4474 if (part
!= scroll_bar_handle
)
4476 construct_scroll_bar_click (bar
, part
, bufp
);
4477 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4478 set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY
);
4481 last_scroll_bar_part
= part
;
4482 bar
->dragging
= Qnil
;
4483 tracked_scroll_bar
= bar
;
4487 x_scroll_bar_handle_release (bar
, bufp
)
4488 struct scroll_bar
*bar
;
4489 struct input_event
*bufp
;
4491 if (last_scroll_bar_part
!= scroll_bar_handle
4492 || !GC_NILP (bar
->dragging
))
4493 construct_scroll_bar_click (bar
, scroll_bar_end_scroll
, bufp
);
4495 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4496 set_scroll_bar_timer (kEventDurationForever
);
4498 last_scroll_bar_part
= -1;
4499 bar
->dragging
= Qnil
;
4500 tracked_scroll_bar
= NULL
;
4504 x_scroll_bar_handle_drag (win
, bar
, mouse_pos
, bufp
)
4506 struct scroll_bar
*bar
;
4508 struct input_event
*bufp
;
4510 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4512 if (last_scroll_bar_part
== scroll_bar_handle
)
4517 get_control_part_bounds (SCROLL_BAR_CONTROL_HANDLE (bar
),
4518 kControlIndicatorPart
, &r
);
4520 if (GC_NILP (bar
->dragging
))
4521 XSETINT (bar
->dragging
, mouse_pos
.v
- r
.top
);
4523 top
= mouse_pos
.v
- XINT (bar
->dragging
) - XINT (bar
->track_top
);
4524 top_range
= (XINT (bar
->track_height
) - (r
.bottom
- r
.top
)) *
4525 (1.0 + (float) GetControlViewSize (ch
) / GetControl32BitMaximum (ch
))
4530 if (top
> top_range
)
4533 construct_scroll_bar_click (bar
, scroll_bar_handle
, bufp
);
4534 XSETINT (bufp
->x
, top
);
4535 XSETINT (bufp
->y
, top_range
);
4539 ControlPartCode part_code
;
4540 int unhilite_p
= 0, part
;
4542 if (ch
!= FindControlUnderMouse (mouse_pos
, win
, &part_code
))
4546 part
= control_part_code_to_scroll_bar_part (part_code
);
4548 switch (last_scroll_bar_part
)
4550 case scroll_bar_above_handle
:
4551 case scroll_bar_below_handle
:
4552 if (part
!= scroll_bar_above_handle
4553 && part
!= scroll_bar_below_handle
)
4557 case scroll_bar_up_arrow
:
4558 case scroll_bar_down_arrow
:
4559 if (part
!= scroll_bar_up_arrow
4560 && part
!= scroll_bar_down_arrow
)
4567 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), 0);
4568 else if (part
!= last_scroll_bar_part
4569 || scroll_bar_timer_event_posted_p
)
4571 construct_scroll_bar_click (bar
, part
, bufp
);
4572 last_scroll_bar_part
= part
;
4573 HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar
), part_code
);
4574 set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY
);
4579 /* Set the thumb size and position of scroll bar BAR. We are currently
4580 displaying PORTION out of a whole WHOLE, and our position POSITION. */
4583 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
)
4584 struct scroll_bar
*bar
;
4585 int portion
, position
, whole
;
4587 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4589 int value
, viewsize
, maximum
;
4591 if (whole
== 0 || XINT (bar
->track_height
) == 0)
4592 value
= 0, viewsize
= 1, maximum
= 0;
4597 maximum
= max (0, whole
- portion
);
4602 SetControl32BitMinimum (ch
, 0);
4603 SetControl32BitMaximum (ch
, maximum
);
4604 SetControl32BitValue (ch
, value
);
4605 SetControlViewSize (ch
, viewsize
);
4610 #endif /* USE_TOOLKIT_SCROLL_BARS */
4614 /************************************************************************
4615 Scroll bars, general
4616 ************************************************************************/
4618 /* Create a scroll bar and return the scroll bar vector for it. W is
4619 the Emacs window on which to create the scroll bar. TOP, LEFT,
4620 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4623 static struct scroll_bar
*
4624 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4626 int top
, left
, width
, height
, disp_top
, disp_height
;
4628 struct frame
*f
= XFRAME (w
->frame
);
4629 struct scroll_bar
*bar
4630 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4638 r
.right
= left
+ width
;
4639 r
.bottom
= disp_top
+ disp_height
;
4641 #if TARGET_API_MAC_CARBON
4642 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4643 0, 0, 0, kControlScrollBarProc
, (long) bar
);
4645 ch
= NewControl (FRAME_MAC_WINDOW (f
), &r
, "\p", width
< disp_height
,
4646 0, 0, 0, scrollBarProc
, (long) bar
);
4648 SET_SCROLL_BAR_CONTROL_HANDLE (bar
, ch
);
4650 XSETWINDOW (bar
->window
, w
);
4651 XSETINT (bar
->top
, top
);
4652 XSETINT (bar
->left
, left
);
4653 XSETINT (bar
->width
, width
);
4654 XSETINT (bar
->height
, height
);
4655 XSETINT (bar
->start
, 0);
4656 XSETINT (bar
->end
, 0);
4657 bar
->dragging
= Qnil
;
4658 #ifdef USE_TOOLKIT_SCROLL_BARS
4659 bar
->track_top
= Qnil
;
4660 bar
->track_height
= Qnil
;
4663 /* Add bar to its frame's list of scroll bars. */
4664 bar
->next
= FRAME_SCROLL_BARS (f
);
4666 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4667 if (!NILP (bar
->next
))
4668 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4675 /* Draw BAR's handle in the proper position.
4677 If the handle is already drawn from START to END, don't bother
4678 redrawing it, unless REBUILD is non-zero; in that case, always
4679 redraw it. (REBUILD is handy for drawing the handle after expose
4682 Normally, we want to constrain the start and end of the handle to
4683 fit inside its rectangle, but if the user is dragging the scroll
4684 bar handle, we want to let them drag it down all the way, so that
4685 the bar's top is as far down as it goes; otherwise, there's no way
4686 to move to the very end of the buffer. */
4688 #ifndef USE_TOOLKIT_SCROLL_BARS
4691 x_scroll_bar_set_handle (bar
, start
, end
, rebuild
)
4692 struct scroll_bar
*bar
;
4696 int dragging
= ! NILP (bar
->dragging
);
4697 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4698 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4699 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
4700 int length
= end
- start
;
4702 /* If the display is already accurate, do nothing. */
4704 && start
== XINT (bar
->start
)
4705 && end
== XINT (bar
->end
))
4710 /* Make sure the values are reasonable, and try to preserve the
4711 distance between start and end. */
4714 else if (start
> top_range
)
4716 end
= start
+ length
;
4720 else if (end
> top_range
&& ! dragging
)
4723 /* Store the adjusted setting in the scroll bar. */
4724 XSETINT (bar
->start
, start
);
4725 XSETINT (bar
->end
, end
);
4727 /* Clip the end position, just for display. */
4728 if (end
> top_range
)
4731 /* Draw bottom positions VERTICAL_SCROLL_BAR_MIN_HANDLE pixels below
4732 top positions, to make sure the handle is always at least that
4733 many pixels tall. */
4734 end
+= VERTICAL_SCROLL_BAR_MIN_HANDLE
;
4736 SetControlMinimum (ch
, 0);
4737 /* Don't inadvertently activate deactivated scroll bars */
4738 if (GetControlMaximum (ch
) != -1)
4739 SetControlMaximum (ch
, top_range
+ VERTICAL_SCROLL_BAR_MIN_HANDLE
4741 SetControlValue (ch
, start
);
4742 #if TARGET_API_MAC_CARBON
4743 SetControlViewSize (ch
, end
- start
);
4749 #endif /* !USE_TOOLKIT_SCROLL_BARS */
4751 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4755 x_scroll_bar_remove (bar
)
4756 struct scroll_bar
*bar
;
4758 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (bar
->window
)));
4762 /* Destroy the Mac scroll bar control */
4763 DisposeControl (SCROLL_BAR_CONTROL_HANDLE (bar
));
4765 /* Disassociate this scroll bar from its window. */
4766 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4772 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4773 that we are displaying PORTION characters out of a total of WHOLE
4774 characters, starting at POSITION. If WINDOW has no scroll bar,
4778 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4780 int portion
, whole
, position
;
4782 struct frame
*f
= XFRAME (w
->frame
);
4783 struct scroll_bar
*bar
;
4784 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4785 int window_y
, window_height
;
4787 /* Get window dimensions. */
4788 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4790 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4791 height
= window_height
;
4793 /* Compute the left edge of the scroll bar area. */
4794 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4796 /* Compute the width of the scroll bar which might be less than
4797 the width of the area reserved for the scroll bar. */
4798 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4799 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4803 /* Compute the left edge of the scroll bar. */
4804 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4807 sb_left
= left
+ width
- sb_width
;
4809 /* Adjustments according to Inside Macintosh to make it look nice */
4811 disp_height
= height
;
4817 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4823 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4826 /* Does the scroll bar exist yet? */
4827 if (NILP (w
->vertical_scroll_bar
))
4830 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4831 left
, top
, width
, height
, 0);
4833 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4835 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4839 /* It may just need to be moved and resized. */
4842 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4843 ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4847 /* If already correctly positioned, do nothing. */
4848 if (!(XINT (bar
->left
) == sb_left
4849 && XINT (bar
->top
) == top
4850 && XINT (bar
->width
) == sb_width
4851 && XINT (bar
->height
) == height
))
4853 /* Since toolkit scroll bars are smaller than the space reserved
4854 for them on the frame, we have to clear "under" them. */
4855 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4856 left
, top
, width
, height
, 0);
4859 if (sb_left
+ sb_width
>= FRAME_PIXEL_WIDTH (f
))
4860 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
4861 sb_left
- 1, top
, 1, height
, 0);
4865 MoveControl (ch
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
);
4866 SizeControl (ch
, sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
* 2,
4868 if (sb_width
< disp_height
)
4871 /* Remember new settings. */
4872 XSETINT (bar
->left
, sb_left
);
4873 XSETINT (bar
->top
, top
);
4874 XSETINT (bar
->width
, sb_width
);
4875 XSETINT (bar
->height
, height
);
4876 #ifdef USE_TOOLKIT_SCROLL_BARS
4877 bar
->track_top
= Qnil
;
4878 bar
->track_height
= Qnil
;
4885 #ifdef USE_TOOLKIT_SCROLL_BARS
4886 if (NILP (bar
->track_top
))
4888 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
4893 SetControl32BitMinimum (ch
, 0);
4894 SetControl32BitMaximum (ch
, 1);
4895 SetControlViewSize (ch
, 1);
4897 /* Move the scroll bar thumb to the top. */
4898 SetControl32BitValue (ch
, 0);
4899 get_control_part_bounds (ch
, kControlIndicatorPart
, &r0
);
4901 /* Move the scroll bar thumb to the bottom. */
4902 SetControl32BitValue (ch
, 1);
4903 get_control_part_bounds (ch
, kControlIndicatorPart
, &r1
);
4905 UnionRect (&r0
, &r1
, &r0
);
4906 XSETINT (bar
->track_top
, r0
.top
);
4907 XSETINT (bar
->track_height
, r0
.bottom
- r0
.top
);
4912 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
4913 #else /* not USE_TOOLKIT_SCROLL_BARS */
4914 /* Set the scroll bar's current state, unless we're currently being
4916 if (NILP (bar
->dragging
))
4918 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4921 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4924 int start
= ((double) position
* top_range
) / whole
;
4925 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4926 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4929 #endif /* not USE_TOOLKIT_SCROLL_BARS */
4933 /* The following three hooks are used when we're doing a thorough
4934 redisplay of the frame. We don't explicitly know which scroll bars
4935 are going to be deleted, because keeping track of when windows go
4936 away is a real pain - "Can you say set-window-configuration, boys
4937 and girls?" Instead, we just assert at the beginning of redisplay
4938 that *all* scroll bars are to be removed, and then save a scroll bar
4939 from the fiery pit when we actually redisplay its window. */
4941 /* Arrange for all scroll bars on FRAME to be removed at the next call
4942 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4943 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4946 XTcondemn_scroll_bars (frame
)
4949 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4950 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4953 bar
= FRAME_SCROLL_BARS (frame
);
4954 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4955 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4956 XSCROLL_BAR (bar
)->prev
= Qnil
;
4957 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4958 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4959 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4964 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4965 Note that WINDOW isn't necessarily condemned at all. */
4968 XTredeem_scroll_bar (window
)
4969 struct window
*window
;
4971 struct scroll_bar
*bar
;
4974 /* We can't redeem this window's scroll bar if it doesn't have one. */
4975 if (NILP (window
->vertical_scroll_bar
))
4978 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4980 /* Unlink it from the condemned list. */
4981 f
= XFRAME (WINDOW_FRAME (window
));
4982 if (NILP (bar
->prev
))
4984 /* If the prev pointer is nil, it must be the first in one of
4986 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4987 /* It's not condemned. Everything's fine. */
4989 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4990 window
->vertical_scroll_bar
))
4991 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4993 /* If its prev pointer is nil, it must be at the front of
4994 one or the other! */
4998 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
5000 if (! NILP (bar
->next
))
5001 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
5003 bar
->next
= FRAME_SCROLL_BARS (f
);
5005 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
5006 if (! NILP (bar
->next
))
5007 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
5010 /* Remove all scroll bars on FRAME that haven't been saved since the
5011 last call to `*condemn_scroll_bars_hook'. */
5014 XTjudge_scroll_bars (f
)
5017 Lisp_Object bar
, next
;
5019 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
5021 /* Clear out the condemned list now so we won't try to process any
5022 more events on the hapless scroll bars. */
5023 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
5025 for (; ! NILP (bar
); bar
= next
)
5027 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
5029 x_scroll_bar_remove (b
);
5032 b
->next
= b
->prev
= Qnil
;
5035 /* Now there should be no references to the condemned scroll bars,
5036 and they should get garbage-collected. */
5040 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
5041 is set to something other than NO_EVENT, it is enqueued.
5043 This may be called from a signal handler, so we have to ignore GC
5047 x_scroll_bar_handle_click (bar
, part_code
, er
, bufp
)
5048 struct scroll_bar
*bar
;
5049 ControlPartCode part_code
;
5051 struct input_event
*bufp
;
5053 int win_y
, top_range
;
5055 if (! GC_WINDOWP (bar
->window
))
5058 bufp
->kind
= SCROLL_BAR_CLICK_EVENT
;
5059 bufp
->frame_or_window
= bar
->window
;
5062 bar
->dragging
= Qnil
;
5066 case kControlUpButtonPart
:
5067 bufp
->part
= scroll_bar_up_arrow
;
5069 case kControlDownButtonPart
:
5070 bufp
->part
= scroll_bar_down_arrow
;
5072 case kControlPageUpPart
:
5073 bufp
->part
= scroll_bar_above_handle
;
5075 case kControlPageDownPart
:
5076 bufp
->part
= scroll_bar_below_handle
;
5078 #if TARGET_API_MAC_CARBON
5081 case kControlIndicatorPart
:
5083 if (er
->what
== mouseDown
)
5084 bar
->dragging
= make_number (0);
5085 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5086 bufp
->part
= scroll_bar_handle
;
5090 win_y
= XINT (bufp
->y
) - XINT (bar
->top
);
5091 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (0/*dummy*/, XINT (bar
->height
));
5093 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5097 if (! NILP (bar
->dragging
))
5098 win_y
-= XINT (bar
->dragging
);
5102 if (win_y
> top_range
)
5105 XSETINT (bufp
->x
, win_y
);
5106 XSETINT (bufp
->y
, top_range
);
5109 #ifndef USE_TOOLKIT_SCROLL_BARS
5111 /* Handle some mouse motion while someone is dragging the scroll bar.
5113 This may be called from a signal handler, so we have to ignore GC
5117 x_scroll_bar_note_movement (bar
, y_pos
, t
)
5118 struct scroll_bar
*bar
;
5122 FRAME_PTR f
= XFRAME (XWINDOW (bar
->window
)->frame
);
5124 last_mouse_movement_time
= t
;
5127 XSETVECTOR (last_mouse_scroll_bar
, bar
);
5129 /* If we're dragging the bar, display it. */
5130 if (! GC_NILP (bar
->dragging
))
5132 /* Where should the handle be now? */
5133 int new_start
= y_pos
- 24;
5135 if (new_start
!= XINT (bar
->start
))
5137 int new_end
= new_start
+ (XINT (bar
->end
) - XINT (bar
->start
));
5139 x_scroll_bar_set_handle (bar
, new_start
, new_end
, 0);
5144 #endif /* !USE_TOOLKIT_SCROLL_BARS */
5146 /* Return information to the user about the current position of the mouse
5147 on the scroll bar. */
5150 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
)
5152 Lisp_Object
*bar_window
;
5153 enum scroll_bar_part
*part
;
5155 unsigned long *time
;
5157 struct scroll_bar
*bar
= XSCROLL_BAR (last_mouse_scroll_bar
);
5158 ControlHandle ch
= SCROLL_BAR_CONTROL_HANDLE (bar
);
5159 #if TARGET_API_MAC_CARBON
5160 WindowPtr wp
= GetControlOwner (ch
);
5162 WindowPtr wp
= (*ch
)->contrlOwner
;
5165 struct frame
*f
= mac_window_to_frame (wp
);
5166 int win_y
, top_range
;
5168 SetPortWindowPort (wp
);
5170 GetMouse (&mouse_pos
);
5172 win_y
= mouse_pos
.v
- XINT (bar
->top
);
5173 top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, XINT (bar
->height
));
5175 win_y
-= VERTICAL_SCROLL_BAR_TOP_BORDER
;
5179 if (! NILP (bar
->dragging
))
5180 win_y
-= XINT (bar
->dragging
);
5184 if (win_y
> top_range
)
5188 *bar_window
= bar
->window
;
5190 if (! NILP (bar
->dragging
))
5191 *part
= scroll_bar_handle
;
5192 else if (win_y
< XINT (bar
->start
))
5193 *part
= scroll_bar_above_handle
;
5194 else if (win_y
< XINT (bar
->end
) + VERTICAL_SCROLL_BAR_MIN_HANDLE
)
5195 *part
= scroll_bar_handle
;
5197 *part
= scroll_bar_below_handle
;
5199 XSETINT (*x
, win_y
);
5200 XSETINT (*y
, top_range
);
5203 last_mouse_scroll_bar
= Qnil
;
5205 *time
= last_mouse_movement_time
;
5209 /* The screen has been cleared so we may have changed foreground or
5210 background colors, and the scroll bars may need to be redrawn.
5211 Clear out the scroll bars, and ask for expose events, so we can
5215 x_scroll_bar_clear (f
)
5218 XTcondemn_scroll_bars (f
);
5219 XTjudge_scroll_bars (f
);
5223 /***********************************************************************
5225 ***********************************************************************/
5227 /* Set clipping for output in glyph row ROW. W is the window in which
5228 we operate. GC is the graphics context to set clipping in.
5230 ROW may be a text row or, e.g., a mode line. Text rows must be
5231 clipped to the interior of the window dedicated to text display,
5232 mode lines must be clipped to the whole window. */
5235 x_clip_to_row (w
, row
, area
, gc
)
5237 struct glyph_row
*row
;
5241 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5243 int window_x
, window_y
, window_width
;
5245 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
5247 clip_rect
.left
= window_x
;
5248 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5249 clip_rect
.top
= max (clip_rect
.top
, window_y
);
5250 clip_rect
.right
= clip_rect
.left
+ window_width
;
5251 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
5253 mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f
), gc
, &clip_rect
, 1);
5257 /* Draw a hollow box cursor on window W in glyph row ROW. */
5260 x_draw_hollow_cursor (w
, row
)
5262 struct glyph_row
*row
;
5264 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5265 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5266 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5269 struct glyph
*cursor_glyph
;
5272 /* Get the glyph the cursor is on. If we can't tell because
5273 the current matrix is invalid or such, give up. */
5274 cursor_glyph
= get_phys_cursor_glyph (w
);
5275 if (cursor_glyph
== NULL
)
5278 /* Compute frame-relative coordinates for phys cursor. */
5279 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
);
5280 y
= get_phys_cursor_geometry (w
, row
, cursor_glyph
, &h
);
5281 wd
= w
->phys_cursor_width
;
5283 /* The foreground of cursor_gc is typically the same as the normal
5284 background color, which can cause the cursor box to be invisible. */
5285 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5286 if (dpyinfo
->scratch_cursor_gc
)
5287 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
5289 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
5290 GCForeground
, &xgcv
);
5291 gc
= dpyinfo
->scratch_cursor_gc
;
5293 /* Set clipping, draw the rectangle, and reset clipping again. */
5294 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5295 mac_draw_rectangle (dpy
, FRAME_MAC_WINDOW (f
), gc
, x
, y
, wd
, h
);
5296 mac_reset_clip_rectangles (dpy
, gc
);
5300 /* Draw a bar cursor on window W in glyph row ROW.
5302 Implementation note: One would like to draw a bar cursor with an
5303 angle equal to the one given by the font property XA_ITALIC_ANGLE.
5304 Unfortunately, I didn't find a font yet that has this property set.
5308 x_draw_bar_cursor (w
, row
, width
, kind
)
5310 struct glyph_row
*row
;
5312 enum text_cursor_kinds kind
;
5314 struct frame
*f
= XFRAME (w
->frame
);
5315 struct glyph
*cursor_glyph
;
5317 /* If cursor is out of bounds, don't draw garbage. This can happen
5318 in mini-buffer windows when switching between echo area glyphs
5320 cursor_glyph
= get_phys_cursor_glyph (w
);
5321 if (cursor_glyph
== NULL
)
5324 /* If on an image, draw like a normal cursor. That's usually better
5325 visible than drawing a bar, esp. if the image is large so that
5326 the bar might not be in the window. */
5327 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5329 struct glyph_row
*row
;
5330 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5331 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5335 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5336 Window window
= FRAME_MAC_WINDOW (f
);
5337 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5338 unsigned long mask
= GCForeground
| GCBackground
;
5339 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5342 /* If the glyph's background equals the color we normally draw
5343 the bar cursor in, the bar cursor in its normal color is
5344 invisible. Use the glyph's foreground color instead in this
5345 case, on the assumption that the glyph's colors are chosen so
5346 that the glyph is legible. */
5347 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5348 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5350 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5353 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5356 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5357 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5361 width
= FRAME_CURSOR_WIDTH (f
);
5362 width
= min (cursor_glyph
->pixel_width
, width
);
5364 w
->phys_cursor_width
= width
;
5365 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5367 if (kind
== BAR_CURSOR
)
5368 XFillRectangle (dpy
, window
, gc
,
5369 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5370 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5371 width
, row
->height
);
5373 XFillRectangle (dpy
, window
, gc
,
5374 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5375 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5376 row
->height
- width
),
5377 cursor_glyph
->pixel_width
,
5380 mac_reset_clip_rectangles (dpy
, gc
);
5385 /* RIF: Define cursor CURSOR on frame F. */
5388 mac_define_frame_cursor (f
, cursor
)
5392 SetThemeCursor (cursor
);
5396 /* RIF: Clear area on frame F. */
5399 mac_clear_frame_area (f
, x
, y
, width
, height
)
5401 int x
, y
, width
, height
;
5403 XClearArea (FRAME_MAC_DISPLAY (f
), FRAME_MAC_WINDOW (f
),
5404 x
, y
, width
, height
, 0);
5408 /* RIF: Draw cursor on window W. */
5411 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5413 struct glyph_row
*glyph_row
;
5415 int cursor_type
, cursor_width
;
5420 w
->phys_cursor_type
= cursor_type
;
5421 w
->phys_cursor_on_p
= 1;
5423 if (glyph_row
->exact_window_width_line_p
5424 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5426 glyph_row
->cursor_in_fringe_p
= 1;
5427 draw_fringe_bitmap (w
, glyph_row
, 0);
5430 switch (cursor_type
)
5432 case HOLLOW_BOX_CURSOR
:
5433 x_draw_hollow_cursor (w
, glyph_row
);
5436 case FILLED_BOX_CURSOR
:
5437 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5441 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5445 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5449 w
->phys_cursor_width
= 0;
5461 #if 0 /* MAC_TODO: no icon support yet. */
5463 x_bitmap_icon (f
, icon
)
5469 if (FRAME_W32_WINDOW (f
) == 0)
5473 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5474 else if (STRINGP (icon
))
5475 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5476 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5477 else if (SYMBOLP (icon
))
5481 if (EQ (icon
, intern ("application")))
5482 name
= (LPCTSTR
) IDI_APPLICATION
;
5483 else if (EQ (icon
, intern ("hand")))
5484 name
= (LPCTSTR
) IDI_HAND
;
5485 else if (EQ (icon
, intern ("question")))
5486 name
= (LPCTSTR
) IDI_QUESTION
;
5487 else if (EQ (icon
, intern ("exclamation")))
5488 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5489 else if (EQ (icon
, intern ("asterisk")))
5490 name
= (LPCTSTR
) IDI_ASTERISK
;
5491 else if (EQ (icon
, intern ("winlogo")))
5492 name
= (LPCTSTR
) IDI_WINLOGO
;
5496 hicon
= LoadIcon (NULL
, name
);
5504 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5509 #endif /* MAC_TODO */
5511 /************************************************************************
5513 ************************************************************************/
5515 /* Display Error Handling functions not used on W32. Listing them here
5516 helps diff stay in step when comparing w32term.c with xterm.c.
5518 x_error_catcher (display, error)
5519 x_catch_errors (dpy)
5520 x_catch_errors_unwind (old_val)
5521 x_check_errors (dpy, format)
5522 x_had_errors_p (dpy)
5523 x_clear_errors (dpy)
5524 x_uncatch_errors (dpy, count)
5526 x_connection_signal (signalnum)
5527 x_connection_closed (dpy, error_message)
5528 x_error_quitter (display, error)
5529 x_error_handler (display, error)
5530 x_io_error_quitter (display)
5535 /* Changing the font of the frame. */
5537 /* Give frame F the font named FONTNAME as its default font, and
5538 return the full name of that font. FONTNAME may be a wildcard
5539 pattern; in that case, we choose some font that fits the pattern.
5540 The return value shows which font we chose. */
5543 x_new_font (f
, fontname
)
5545 register char *fontname
;
5547 struct font_info
*fontp
5548 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5553 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5554 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5555 FRAME_FONTSET (f
) = -1;
5557 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5558 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5559 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5561 compute_fringe_widths (f
, 1);
5563 /* Compute the scroll bar width in character columns. */
5564 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5566 int wid
= FRAME_COLUMN_WIDTH (f
);
5567 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5568 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5572 int wid
= FRAME_COLUMN_WIDTH (f
);
5573 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5576 /* Now make the frame display the given font. */
5577 if (FRAME_MAC_WINDOW (f
) != 0)
5579 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5581 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5583 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5586 /* Don't change the size of a tip frame; there's no point in
5587 doing it because it's done in Fx_show_tip, and it leads to
5588 problems because the tip frame has no widget. */
5589 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5590 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5593 return build_string (fontp
->full_name
);
5596 /* Give frame F the fontset named FONTSETNAME as its default font, and
5597 return the full name of that fontset. FONTSETNAME may be a wildcard
5598 pattern; in that case, we choose some fontset that fits the pattern.
5599 The return value shows which fontset we chose. */
5602 x_new_fontset (f
, fontsetname
)
5606 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5612 if (FRAME_FONTSET (f
) == fontset
)
5613 /* This fontset is already set in frame F. There's nothing more
5615 return fontset_name (fontset
);
5617 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5619 if (!STRINGP (result
))
5620 /* Can't load ASCII font. */
5623 /* Since x_new_font doesn't update any fontset information, do it now. */
5624 FRAME_FONTSET (f
) = fontset
;
5626 return build_string (fontsetname
);
5630 /***********************************************************************
5631 TODO: W32 Input Methods
5632 ***********************************************************************/
5633 /* Listing missing functions from xterm.c helps diff stay in step.
5635 xim_destroy_callback (xim, client_data, call_data)
5636 xim_open_dpy (dpyinfo, resource_name)
5638 xim_instantiate_callback (display, client_data, call_data)
5639 xim_initialize (dpyinfo, resource_name)
5640 xim_close_dpy (dpyinfo)
5646 mac_get_window_bounds (f
, inner
, outer
)
5648 Rect
*inner
, *outer
;
5650 #if TARGET_API_MAC_CARBON
5651 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, inner
);
5652 GetWindowBounds (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, outer
);
5653 #else /* not TARGET_API_MAC_CARBON */
5654 RgnHandle region
= NewRgn ();
5656 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowContentRgn
, region
);
5657 *inner
= (*region
)->rgnBBox
;
5658 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowStructureRgn
, region
);
5659 *outer
= (*region
)->rgnBBox
;
5660 DisposeRgn (region
);
5661 #endif /* not TARGET_API_MAC_CARBON */
5666 /* Calculate the absolute position in frame F
5667 from its current recorded position values and gravity. */
5670 x_calc_absolute_position (f
)
5673 int width_diff
= 0, height_diff
= 0;
5674 int flags
= f
->size_hint_flags
;
5677 /* We have nothing to do if the current position
5678 is already for the top-left corner. */
5679 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5682 /* Find the offsets of the outside upper-left corner of
5683 the inner window, with respect to the outer window. */
5684 mac_get_window_bounds (f
, &inner
, &outer
);
5686 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5687 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5689 /* Treat negative positions as relative to the leftmost bottommost
5690 position that fits on the screen. */
5691 if (flags
& XNegative
)
5692 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5694 - FRAME_PIXEL_WIDTH (f
)
5697 if (flags
& YNegative
)
5698 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5700 - FRAME_PIXEL_HEIGHT (f
)
5703 /* The left_pos and top_pos
5704 are now relative to the top and left screen edges,
5705 so the flags should correspond. */
5706 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5709 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5710 to really change the position, and 0 when calling from
5711 x_make_frame_visible (in that case, XOFF and YOFF are the current
5712 position values). It is -1 when calling from x_set_frame_parameters,
5713 which means, do adjust for borders but don't change the gravity. */
5716 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5718 register int xoff
, yoff
;
5721 if (change_gravity
> 0)
5725 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5727 f
->size_hint_flags
|= XNegative
;
5729 f
->size_hint_flags
|= YNegative
;
5730 f
->win_gravity
= NorthWestGravity
;
5732 x_calc_absolute_position (f
);
5735 x_wm_set_size_hint (f
, (long) 0, 0);
5737 #if TARGET_API_MAC_CARBON
5738 MoveWindowStructure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5739 /* If the title bar is completely outside the screen, adjust the
5741 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5742 kWindowConstrainMoveRegardlessOfFit
5743 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5744 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5747 Rect inner
, outer
, screen_rect
, dummy
;
5748 RgnHandle region
= NewRgn ();
5750 mac_get_window_bounds (f
, &inner
, &outer
);
5751 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5752 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5753 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5754 f
->top_pos
+ f
->y_pixels_diff
, false);
5756 /* If the title bar is completely outside the screen, adjust the
5757 position. The variable `outer' holds the title bar rectangle.
5758 The variable `inner' holds slightly smaller one than `outer',
5759 so that the calculation of overlapping may not become too
5761 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5762 outer
= (*region
)->rgnBBox
;
5763 DisposeRgn (region
);
5765 InsetRect (&inner
, 8, 8);
5766 screen_rect
= qd
.screenBits
.bounds
;
5767 screen_rect
.top
+= GetMBarHeight ();
5769 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5771 if (inner
.right
<= screen_rect
.left
)
5772 f
->left_pos
= screen_rect
.left
;
5773 else if (inner
.left
>= screen_rect
.right
)
5774 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5776 if (inner
.bottom
<= screen_rect
.top
)
5777 f
->top_pos
= screen_rect
.top
;
5778 else if (inner
.top
>= screen_rect
.bottom
)
5779 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5781 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5782 f
->top_pos
+ f
->y_pixels_diff
, false);
5790 /* Call this to change the size of frame F's x-window.
5791 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5792 for this size change and subsequent size changes.
5793 Otherwise we leave the window gravity unchanged. */
5796 x_set_window_size (f
, change_gravity
, cols
, rows
)
5801 int pixelwidth
, pixelheight
;
5805 check_frame_size (f
, &rows
, &cols
);
5806 f
->scroll_bar_actual_width
5807 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5809 compute_fringe_widths (f
, 0);
5811 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5812 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5814 f
->win_gravity
= NorthWestGravity
;
5815 x_wm_set_size_hint (f
, (long) 0, 0);
5817 SizeWindow (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5818 #if TARGET_API_MAC_CARBON
5819 if (f
->output_data
.mac
->hourglass_control
)
5820 MoveControl (f
->output_data
.mac
->hourglass_control
,
5821 pixelwidth
- HOURGLASS_WIDTH
, 0);
5824 /* Now, strictly speaking, we can't be sure that this is accurate,
5825 but the window manager will get around to dealing with the size
5826 change request eventually, and we'll hear how it went when the
5827 ConfigureNotify event gets here.
5829 We could just not bother storing any of this information here,
5830 and let the ConfigureNotify event set everything up, but that
5831 might be kind of confusing to the Lisp code, since size changes
5832 wouldn't be reported in the frame parameters until some random
5833 point in the future when the ConfigureNotify event arrives.
5835 We pass 1 for DELAY since we can't run Lisp code inside of
5837 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5838 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5839 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5841 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5842 receive in the ConfigureNotify event; if we get what we asked
5843 for, then the event won't cause the screen to become garbaged, so
5844 we have to make sure to do it here. */
5845 SET_FRAME_GARBAGED (f
);
5847 XFlush (FRAME_X_DISPLAY (f
));
5849 /* If cursor was outside the new size, mark it as off. */
5850 mark_window_cursors_off (XWINDOW (f
->root_window
));
5852 /* Clear out any recollection of where the mouse highlighting was,
5853 since it might be in a place that's outside the new frame size.
5854 Actually checking whether it is outside is a pain in the neck,
5855 so don't try--just let the highlighting be done afresh with new size. */
5856 cancel_mouse_face (f
);
5861 /* Mouse warping. */
5863 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5866 x_set_mouse_position (f
, x
, y
)
5872 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5873 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5875 if (pix_x
< 0) pix_x
= 0;
5876 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5878 if (pix_y
< 0) pix_y
= 0;
5879 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5881 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5885 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5889 #if 0 /* MAC_TODO: CursorDeviceMoveTo is non-Carbon */
5892 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5893 0, 0, 0, 0, pix_x
, pix_y
);
5898 /* focus shifting, raising and lowering. */
5901 x_focus_on_frame (f
)
5904 #if 0 /* This proves to be unpleasant. */
5908 /* I don't think that the ICCCM allows programs to do things like this
5909 without the interaction of the window manager. Whatever you end up
5910 doing with this code, do it to x_unfocus_frame too. */
5911 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5912 RevertToPointerRoot
, CurrentTime
);
5922 /* Raise frame F. */
5928 if (f
->async_visible
)
5931 SelectWindow (FRAME_MAC_WINDOW (f
));
5936 /* Lower frame F. */
5942 if (f
->async_visible
)
5945 SendBehind (FRAME_MAC_WINDOW (f
), nil
);
5951 XTframe_raise_lower (f
, raise_flag
)
5961 /* Change of visibility. */
5964 mac_handle_visibility_change (f
)
5967 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
5968 int visible
= 0, iconified
= 0;
5969 struct input_event buf
;
5971 if (IsWindowVisible (wp
))
5972 if (IsWindowCollapsed (wp
))
5977 if (!f
->async_visible
&& visible
)
5981 /* wait_reading_process_output will notice this and update
5982 the frame's display structures. If we were made
5983 invisible, we should not set garbaged, because that stops
5984 redrawing on Update events. */
5985 SET_FRAME_GARBAGED (f
);
5988 buf
.kind
= DEICONIFY_EVENT
;
5989 XSETFRAME (buf
.frame_or_window
, f
);
5990 kbd_buffer_store_event (&buf
);
5992 else if (! NILP (Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
5993 /* Force a redisplay sooner or later to update the
5994 frame titles in case this is the second frame. */
5995 record_asynch_buffer_change ();
5997 else if (f
->async_visible
&& !visible
)
6001 buf
.kind
= ICONIFY_EVENT
;
6002 XSETFRAME (buf
.frame_or_window
, f
);
6003 kbd_buffer_store_event (&buf
);
6006 f
->async_visible
= visible
;
6007 f
->async_iconified
= iconified
;
6010 /* This tries to wait until the frame is really visible.
6011 However, if the window manager asks the user where to position
6012 the frame, this will return before the user finishes doing that.
6013 The frame will not actually be visible at that time,
6014 but it will become visible later when the window manager
6015 finishes with it. */
6018 x_make_frame_visible (f
)
6022 int original_top
, original_left
;
6026 if (! FRAME_VISIBLE_P (f
))
6028 /* We test FRAME_GARBAGED_P here to make sure we don't
6029 call x_set_offset a second time
6030 if we get to x_make_frame_visible a second time
6031 before the window gets really visible. */
6032 if (! FRAME_ICONIFIED_P (f
)
6033 && ! f
->output_data
.mac
->asked_for_visible
)
6034 #if TARGET_API_MAC_CARBON
6035 if (!(FRAME_SIZE_HINTS (f
)->flags
& (USPosition
| PPosition
)))
6037 struct frame
*sf
= SELECTED_FRAME ();
6038 if (!FRAME_MAC_P (sf
))
6039 RepositionWindow (FRAME_MAC_WINDOW (f
), NULL
,
6040 kWindowCenterOnMainScreen
);
6042 RepositionWindow (FRAME_MAC_WINDOW (f
),
6043 FRAME_MAC_WINDOW (sf
),
6044 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
6045 kWindowCascadeStartAtParentWindowScreen
6047 kWindowCascadeOnParentWindowScreen
6050 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
6054 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
6056 f
->output_data
.mac
->asked_for_visible
= 1;
6058 SelectWindow (FRAME_MAC_WINDOW (f
));
6059 CollapseWindow (FRAME_MAC_WINDOW (f
), false);
6060 ShowWindow (FRAME_MAC_WINDOW (f
));
6063 XFlush (FRAME_MAC_DISPLAY (f
));
6065 /* Synchronize to ensure Emacs knows the frame is visible
6066 before we do anything else. We do this loop with input not blocked
6067 so that incoming events are handled. */
6072 /* This must come after we set COUNT. */
6075 XSETFRAME (frame
, f
);
6077 /* Wait until the frame is visible. Process X events until a
6078 MapNotify event has been seen, or until we think we won't get a
6079 MapNotify at all.. */
6080 for (count
= input_signal_count
+ 10;
6081 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
6083 /* Force processing of queued events. */
6086 /* Machines that do polling rather than SIGIO have been
6087 observed to go into a busy-wait here. So we'll fake an
6088 alarm signal to let the handler know that there's something
6089 to be read. We used to raise a real alarm, but it seems
6090 that the handler isn't always enabled here. This is
6092 if (input_polling_used ())
6094 /* It could be confusing if a real alarm arrives while
6095 processing the fake one. Turn it off and let the
6096 handler reset it. */
6097 extern void poll_for_input_1
P_ ((void));
6098 int old_poll_suppress_count
= poll_suppress_count
;
6099 poll_suppress_count
= 1;
6100 poll_for_input_1 ();
6101 poll_suppress_count
= old_poll_suppress_count
;
6104 /* See if a MapNotify event has been processed. */
6105 FRAME_SAMPLE_VISIBILITY (f
);
6110 /* Change from mapped state to withdrawn state. */
6112 /* Make the frame visible (mapped and not iconified). */
6115 x_make_frame_invisible (f
)
6118 /* A deactivate event does not occur when the last visible frame is
6119 made invisible. So if we clear the highlight here, it will not
6120 be rehighlighted when it is made visible. */
6122 /* Don't keep the highlight on an invisible frame. */
6123 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6124 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6129 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
6130 that the current position of the window is user-specified, rather than
6131 program-specified, so that when the window is mapped again, it will be
6132 placed at the same location, without forcing the user to position it
6133 by hand again (they have already done that once for this window.) */
6134 x_wm_set_size_hint (f
, (long) 0, 1);
6136 HideWindow (FRAME_MAC_WINDOW (f
));
6140 #if !USE_CARBON_EVENTS
6141 mac_handle_visibility_change (f
);
6145 /* Change window state from mapped to iconified. */
6153 /* A deactivate event does not occur when the last visible frame is
6154 iconified. So if we clear the highlight here, it will not be
6155 rehighlighted when it is deiconified. */
6157 /* Don't keep the highlight on an invisible frame. */
6158 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
6159 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
6162 if (f
->async_iconified
)
6167 FRAME_SAMPLE_VISIBILITY (f
);
6169 if (! FRAME_VISIBLE_P (f
))
6170 ShowWindow (FRAME_MAC_WINDOW (f
));
6172 err
= CollapseWindow (FRAME_MAC_WINDOW (f
), true);
6177 error ("Can't notify window manager of iconification");
6179 #if !USE_CARBON_EVENTS
6180 mac_handle_visibility_change (f
);
6185 /* Free X resources of frame F. */
6188 x_free_frame_resources (f
)
6191 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6192 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
6196 if (wp
!= tip_window
)
6197 remove_window_handler (wp
);
6200 if (wp
== tip_window
)
6201 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
6202 closed' event. So we reset tip_window here. */
6205 free_frame_menubar (f
);
6207 if (FRAME_FACE_CACHE (f
))
6208 free_frame_faces (f
);
6212 if (FRAME_SIZE_HINTS (f
))
6213 xfree (FRAME_SIZE_HINTS (f
));
6215 xfree (f
->output_data
.mac
);
6216 f
->output_data
.mac
= NULL
;
6218 if (f
== dpyinfo
->x_focus_frame
)
6219 dpyinfo
->x_focus_frame
= 0;
6220 if (f
== dpyinfo
->x_focus_event_frame
)
6221 dpyinfo
->x_focus_event_frame
= 0;
6222 if (f
== dpyinfo
->x_highlight_frame
)
6223 dpyinfo
->x_highlight_frame
= 0;
6225 if (f
== dpyinfo
->mouse_face_mouse_frame
)
6227 dpyinfo
->mouse_face_beg_row
6228 = dpyinfo
->mouse_face_beg_col
= -1;
6229 dpyinfo
->mouse_face_end_row
6230 = dpyinfo
->mouse_face_end_col
= -1;
6231 dpyinfo
->mouse_face_window
= Qnil
;
6232 dpyinfo
->mouse_face_deferred_gc
= 0;
6233 dpyinfo
->mouse_face_mouse_frame
= 0;
6240 /* Destroy the X window of frame F. */
6243 x_destroy_window (f
)
6246 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6248 x_free_frame_resources (f
);
6250 dpyinfo
->reference_count
--;
6254 /* Setting window manager hints. */
6256 /* Set the normal size hints for the window manager, for frame F.
6257 FLAGS is the flags word to use--or 0 meaning preserve the flags
6258 that the window now has.
6259 If USER_POSITION is nonzero, we set the USPosition
6260 flag (this is useful when FLAGS is 0). */
6262 x_wm_set_size_hint (f
, flags
, user_position
)
6267 int base_width
, base_height
, width_inc
, height_inc
;
6268 int min_rows
= 0, min_cols
= 0;
6269 XSizeHints
*size_hints
;
6271 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
6272 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
6273 width_inc
= FRAME_COLUMN_WIDTH (f
);
6274 height_inc
= FRAME_LINE_HEIGHT (f
);
6276 check_frame_size (f
, &min_rows
, &min_cols
);
6278 size_hints
= FRAME_SIZE_HINTS (f
);
6279 if (size_hints
== NULL
)
6281 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
6282 bzero (size_hints
, sizeof (XSizeHints
));
6285 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
6286 size_hints
->width_inc
= width_inc
;
6287 size_hints
->height_inc
= height_inc
;
6288 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
6289 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
6290 size_hints
->base_width
= base_width
;
6291 size_hints
->base_height
= base_height
;
6294 size_hints
->flags
= flags
;
6295 else if (user_position
)
6297 size_hints
->flags
&= ~ PPosition
;
6298 size_hints
->flags
|= USPosition
;
6302 #if 0 /* MAC_TODO: hide application instead of iconify? */
6303 /* Used for IconicState or NormalState */
6306 x_wm_set_window_state (f
, state
)
6310 #ifdef USE_X_TOOLKIT
6313 XtSetArg (al
[0], XtNinitialState
, state
);
6314 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6315 #else /* not USE_X_TOOLKIT */
6316 Window window
= FRAME_X_WINDOW (f
);
6318 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
6319 f
->output_data
.x
->wm_hints
.initial_state
= state
;
6321 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6322 #endif /* not USE_X_TOOLKIT */
6326 x_wm_set_icon_pixmap (f
, pixmap_id
)
6332 #ifndef USE_X_TOOLKIT
6333 Window window
= FRAME_X_WINDOW (f
);
6338 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
6339 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
6343 /* It seems there is no way to turn off use of an icon pixmap.
6344 The following line does it, only if no icon has yet been created,
6345 for some window managers. But with mwm it crashes.
6346 Some people say it should clear the IconPixmapHint bit in this case,
6347 but that doesn't work, and the X consortium said it isn't the
6348 right thing at all. Since there is no way to win,
6349 best to explicitly give up. */
6351 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
6357 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
6361 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
6362 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6365 #else /* not USE_X_TOOLKIT */
6367 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
6368 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6370 #endif /* not USE_X_TOOLKIT */
6373 #endif /* MAC_TODO */
6376 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6380 #if 0 /* MAC_TODO: no icons on Mac */
6381 #ifdef USE_X_TOOLKIT
6382 Window window
= XtWindow (f
->output_data
.x
->widget
);
6384 Window window
= FRAME_X_WINDOW (f
);
6387 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6388 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6389 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6391 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6392 #endif /* MAC_TODO */
6396 /***********************************************************************
6398 ***********************************************************************/
6400 /* An XLFD pattern is divided into blocks delimited by '*'. This
6401 structure holds information for each block. */
6402 struct xlfdpat_block
6404 /* Length of the pattern string in this block. Non-zero except for
6405 the first and the last blocks. */
6408 /* Pattern string except the last character in this block. The last
6409 character is replaced with NUL in order to use it as a
6411 unsigned char *pattern
;
6413 /* Last character of the pattern string. Must not be '?'. */
6414 unsigned char last_char
;
6416 /* One of the tables for the Boyer-Moore string search. It
6417 specifies the number of positions to proceed for each character
6418 with which the match fails. */
6421 /* The skip value for the last character in the above `skip' is
6422 assigned to `infinity' in order to simplify a loop condition.
6423 The original value is saved here. */
6429 /* Normalized pattern string. "Normalized" means that capital
6430 letters are lowered, blocks are not empty except the first and
6431 the last ones, and trailing '?'s in a block that is not the last
6432 one are moved to the next one. The last character in each block
6433 is replaced with NUL. */
6436 /* Number of characters except '*'s and trailing '?'s in the
6437 normalized pattern string. */
6440 /* Number of trailing '?'s in the normalized pattern string. */
6441 int trailing_anychars
;
6443 /* Number of blocks and information for each block. The latter is
6444 NULL if the pattern is exact (no '*' or '?' in it). */
6446 struct xlfdpat_block
*blocks
;
6450 xlfdpat_destroy (pat
)
6451 struct xlfdpat
*pat
;
6458 xfree (pat
->blocks
);
6465 static struct xlfdpat
*
6466 xlfdpat_create (pattern
)
6469 struct xlfdpat
*pat
;
6470 int nblocks
, i
, skip
;
6471 unsigned char last_char
, *p
, *q
, *anychar_head
;
6472 struct xlfdpat_block
*blk
;
6474 pat
= xmalloc (sizeof (struct xlfdpat
));
6478 pat
->buf
= xmalloc (strlen (pattern
) + 1);
6479 if (pat
->buf
== NULL
)
6482 /* Normalize the pattern string and store it to `pat->buf'. */
6484 anychar_head
= NULL
;
6487 for (p
= pattern
; *p
; p
++)
6489 unsigned char c
= *p
;
6492 if (last_char
== '*')
6493 /* ...a** -> ...a* */
6497 if (last_char
== '?')
6498 if (anychar_head
> pat
->buf
&& *(anychar_head
- 1) == '*')
6499 /* ...*??* -> ...*?? */
6502 /* ...a??* -> ...a*?? */
6504 *anychar_head
++ = '*';
6511 if (last_char
!= '?')
6515 /* On Mac OS X 10.3, tolower also converts non-ASCII
6516 characters for some locales. */
6520 *q
++ = last_char
= c
;
6524 pat
->nblocks
= nblocks
;
6525 if (last_char
!= '?')
6526 pat
->trailing_anychars
= 0;
6529 pat
->trailing_anychars
= q
- anychar_head
;
6532 pat
->nchars
= q
- pat
->buf
- (nblocks
- 1);
6534 if (anychar_head
== NULL
&& nblocks
== 1)
6536 /* The pattern is exact. */
6541 pat
->blocks
= xmalloc (sizeof (struct xlfdpat_block
) * nblocks
);
6542 if (pat
->blocks
== NULL
)
6545 /* Divide the normalized pattern into blocks. */
6547 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
- 1; blk
++)
6552 blk
->len
= p
- blk
->pattern
;
6556 blk
->len
= q
- blk
->pattern
;
6558 /* Setup a table for the Boyer-Moore string search. */
6559 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
; blk
++)
6562 blk
->last_char
= blk
->pattern
[blk
->len
- 1];
6563 blk
->pattern
[blk
->len
- 1] = '\0';
6565 for (skip
= 1; skip
< blk
->len
; skip
++)
6566 if (blk
->pattern
[blk
->len
- skip
- 1] == '?')
6569 for (i
= 0; i
< 256; i
++)
6570 blk
->skip
[i
] = skip
;
6572 p
= blk
->pattern
+ (blk
->len
- skip
);
6574 blk
->skip
[*p
++] = skip
;
6576 blk
->last_char_skip
= blk
->skip
[blk
->last_char
];
6582 xlfdpat_destroy (pat
);
6587 xlfdpat_exact_p (pat
)
6588 struct xlfdpat
*pat
;
6590 return pat
->blocks
== NULL
;
6593 /* Return the first string in STRING + 0, ..., STRING + START_MAX such
6594 that the pattern in *BLK matches with its prefix. Return NULL
6595 there is no such strings. STRING must be lowered in advance. */
6598 xlfdpat_block_match_1 (blk
, string
, start_max
)
6599 struct xlfdpat_block
*blk
;
6600 unsigned char *string
;
6603 int start
, infinity
;
6604 unsigned char *p
, *s
;
6606 xassert (blk
->len
> 0);
6607 xassert (start_max
+ blk
->len
<= strlen (string
));
6608 xassert (blk
->last_char
!= '?');
6610 /* See the comments in the function `boyer_moore' (search.c) for the
6611 use of `infinity'. */
6612 infinity
= start_max
+ blk
->len
+ 1;
6613 blk
->skip
[blk
->last_char
] = infinity
;
6618 /* Check the last character of the pattern. */
6619 s
= string
+ blk
->len
- 1;
6622 start
+= blk
->skip
[*(s
+ start
)];
6624 while (start
<= start_max
);
6626 if (start
< infinity
)
6627 /* Couldn't find the last character. */
6630 /* No less than `infinity' means we could find the last
6631 character at `s[start - infinity]'. */
6634 /* Check the remaining characters. We prefer making no-'?'
6635 cases faster because the use of '?' is really rare. */
6640 while (*p
++ == *s
++)
6643 while (*(p
- 1) == '?');
6645 if (*(p
- 1) == '\0')
6647 return string
+ start
;
6650 start
+= blk
->last_char_skip
;
6652 while (start
<= start_max
);
6657 #define xlfdpat_block_match(b, s, m) \
6658 ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
6659 : xlfdpat_block_match_1 (b, s, m))
6661 /* Check if XLFD pattern PAT, which is generated by `xfldpat_create',
6662 matches with STRING. STRING must be lowered in advance. */
6665 xlfdpat_match (pat
, string
)
6666 struct xlfdpat
*pat
;
6667 unsigned char *string
;
6669 int str_len
, nblocks
, i
, start_max
;
6670 struct xlfdpat_block
*blk
;
6673 xassert (pat
->nblocks
> 0);
6675 if (xlfdpat_exact_p (pat
))
6676 return strcmp (pat
->buf
, string
) == 0;
6678 /* The number of the characters in the string must not be smaller
6679 than that in the pattern. */
6680 str_len
= strlen (string
);
6681 if (str_len
< pat
->nchars
+ pat
->trailing_anychars
)
6684 /* Chop off the trailing '?'s. */
6685 str_len
-= pat
->trailing_anychars
;
6687 /* The last block. When it is non-empty, it must match at the end
6689 nblocks
= pat
->nblocks
;
6690 blk
= pat
->blocks
+ (nblocks
- 1);
6692 /* The last block is also the first one. */
6693 return (str_len
== blk
->len
6694 && (blk
->len
== 0 || xlfdpat_block_match (blk
, string
, 0)));
6695 else if (blk
->len
!= 0)
6696 if (!xlfdpat_block_match (blk
, string
+ (str_len
- blk
->len
), 0))
6699 /* The first block. When it is non-empty, it must match at the
6700 beginning of the string. */
6704 s
= xlfdpat_block_match (blk
, string
, 0);
6707 string
= s
+ blk
->len
;
6710 /* The rest of the blocks. */
6711 start_max
= str_len
- pat
->nchars
;
6712 for (i
= 1, blk
++; i
< nblocks
- 1; i
++, blk
++)
6714 s
= xlfdpat_block_match (blk
, string
, start_max
);
6717 start_max
-= s
- string
;
6718 string
= s
+ blk
->len
;
6725 /***********************************************************************
6727 ***********************************************************************/
6729 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6732 x_get_font_info (f
, font_idx
)
6736 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6739 /* the global font name table */
6740 static char **font_name_table
= NULL
;
6741 static int font_name_table_size
= 0;
6742 static int font_name_count
= 0;
6744 /* Alist linking font family names to Font Manager font family
6745 references (which can also be used as QuickDraw font IDs). We use
6746 an alist because hash tables are not ready when the terminal frame
6747 for Mac OS Classic is created. */
6748 static Lisp_Object fm_font_family_alist
;
6750 /* Hash table linking font family names to ATSU font IDs. */
6751 static Lisp_Object atsu_font_id_hash
;
6754 /* Alist linking character set strings to Mac text encoding and Emacs
6756 static Lisp_Object Vmac_charset_info_alist
;
6759 create_text_encoding_info_alist ()
6761 Lisp_Object result
= Qnil
, rest
;
6763 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
6765 Lisp_Object charset_info
= XCAR (rest
);
6766 Lisp_Object charset
, coding_system
, text_encoding
;
6767 Lisp_Object existing_info
;
6769 if (!(CONSP (charset_info
)
6770 && STRINGP (charset
= XCAR (charset_info
))
6771 && CONSP (XCDR (charset_info
))
6772 && INTEGERP (text_encoding
= XCAR (XCDR (charset_info
)))
6773 && CONSP (XCDR (XCDR (charset_info
)))
6774 && SYMBOLP (coding_system
= XCAR (XCDR (XCDR (charset_info
))))))
6777 existing_info
= assq_no_quit (text_encoding
, result
);
6778 if (NILP (existing_info
))
6779 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
6782 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
6783 XSETCDR (XCDR (existing_info
),
6784 Fcons (charset
, XCDR (XCDR (existing_info
))));
6792 decode_mac_font_name (name
, size
, coding_system
)
6795 Lisp_Object coding_system
;
6797 struct coding_system coding
;
6800 if (!NILP (coding_system
) && !NILP (Fcoding_system_p (coding_system
)))
6802 for (p
= name
; *p
; p
++)
6803 if (!isascii (*p
) || iscntrl (*p
))
6808 setup_coding_system (coding_system
, &coding
);
6809 coding
.src_multibyte
= 0;
6810 coding
.dst_multibyte
= 1;
6811 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6812 coding
.composing
= COMPOSITION_DISABLED
;
6813 buf
= (char *) alloca (size
);
6815 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
6816 bcopy (buf
, name
, coding
.produced
);
6817 name
[coding
.produced
] = '\0';
6821 /* If there's just one occurrence of '-' in the family name, it is
6822 replaced with '_'. (More than one occurrence of '-' means a
6823 "FOUNDRY-FAMILY-CHARSET"-style name.) */
6824 p
= strchr (name
, '-');
6825 if (p
&& strchr (p
+ 1, '-') == NULL
)
6828 for (p
= name
; *p
; p
++)
6829 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6830 for some locales. */
6837 mac_to_x_fontname (name
, size
, style
, charset
)
6845 char xf
[256], *result
;
6848 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
6852 strcpy(foundry
, "Apple");
6853 strcpy(family
, name
);
6856 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
6857 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
6858 size
, size
* 10, size
? 75 : 0, size
? 75 : 0, size
* 10, charset
);
6860 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
6861 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
6862 for (p
= result
; *p
; p
++)
6863 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6864 for some locales. */
6871 /* Parse fully-specified and instantiated X11 font spec XF, and store
6872 the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
6873 parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
6874 caller must allocate at least 256 and 32 bytes respectively. For
6875 ordinary Mac fonts, the value stored to FAMILY should just be their
6876 names, like "monaco", "Taipei", etc. Fonts converted from the GNU
6877 intlfonts collection contain their charset designation in their
6878 names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
6879 types of font names are handled accordingly. */
6881 const int kDefaultFontSize
= 12;
6884 parse_x_font_name (xf
, family
, size
, style
, charset
)
6890 Str31 foundry
, weight
;
6891 int point_size
, avgwidth
;
6894 if (sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6895 foundry
, family
, weight
, slant
, size
,
6896 &point_size
, &avgwidth
, charset
) != 8
6897 && sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6898 foundry
, family
, weight
, slant
, size
,
6899 &point_size
, &avgwidth
, charset
) != 8)
6905 *size
= point_size
/ 10;
6906 else if (avgwidth
> 0)
6907 *size
= avgwidth
/ 10;
6910 *size
= kDefaultFontSize
;
6913 if (strcmp (weight
, "bold") == 0)
6918 if (NILP (Fassoc (build_string (charset
), Vmac_charset_info_alist
)))
6920 int foundry_len
= strlen (foundry
), family_len
= strlen (family
);
6922 if (foundry_len
+ family_len
+ strlen (charset
) + 2 < sizeof (Str255
))
6924 /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
6925 but take overlap into account. */
6926 memmove (family
+ foundry_len
+ 1, family
, family_len
);
6927 memcpy (family
, foundry
, foundry_len
);
6928 family
[foundry_len
] = '-';
6929 family
[foundry_len
+ 1 + family_len
] = '-';
6930 strcpy (family
+ foundry_len
+ 1 + family_len
+ 1, charset
);
6936 for (p
= family
; *p
; p
++)
6937 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6938 for some locales. */
6947 add_font_name_table_entry (char *font_name
)
6949 if (font_name_table_size
== 0)
6951 font_name_table_size
= 256;
6952 font_name_table
= (char **)
6953 xmalloc (font_name_table_size
* sizeof (char *));
6955 else if (font_name_count
+ 1 >= font_name_table_size
)
6957 font_name_table_size
*= 2;
6958 font_name_table
= (char **)
6959 xrealloc (font_name_table
,
6960 font_name_table_size
* sizeof (char *));
6963 font_name_table
[font_name_count
++] = font_name
;
6966 /* Sets up the table font_name_table to contain the list of all fonts
6967 in the system the first time the table is used so that the Resource
6968 Manager need not be accessed every time this information is
6972 init_font_name_table ()
6974 #if TARGET_API_MAC_CARBON
6975 FMFontFamilyIterator ffi
;
6976 FMFontFamilyInstanceIterator ffii
;
6978 Lisp_Object text_encoding_info_alist
;
6979 struct gcpro gcpro1
;
6981 text_encoding_info_alist
= create_text_encoding_info_alist ();
6984 if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode
),
6985 text_encoding_info_alist
)))
6988 ItemCount nfonts
, i
;
6989 ATSUFontID
*font_ids
= NULL
;
6990 Ptr name
, prev_name
= NULL
;
6994 make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
6995 make_float (DEFAULT_REHASH_SIZE
),
6996 make_float (DEFAULT_REHASH_THRESHOLD
),
6998 err
= ATSUFontCount (&nfonts
);
7000 font_ids
= xmalloc (sizeof (ATSUFontID
) * nfonts
);
7002 err
= ATSUGetFontIDs (font_ids
, nfonts
, NULL
);
7004 for (i
= 0; i
< nfonts
; i
++)
7006 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7007 kFontMacintoshPlatform
, kFontNoScript
,
7008 kFontNoLanguage
, 0, NULL
, &name_len
, NULL
);
7011 name
= xmalloc (name_len
+ 1);
7014 name
[name_len
] = '\0';
7015 err
= ATSUFindFontName (font_ids
[i
], kFontFamilyName
,
7016 kFontMacintoshPlatform
, kFontNoScript
,
7017 kFontNoLanguage
, name_len
, name
,
7020 decode_mac_font_name (name
, name_len
+ 1, Qnil
);
7023 && (prev_name
== NULL
7024 || strcmp (name
, prev_name
) != 0))
7026 static char *cs
= "iso10646-1";
7028 add_font_name_table_entry (mac_to_x_fontname (name
, 0,
7030 add_font_name_table_entry (mac_to_x_fontname (name
, 0,
7032 add_font_name_table_entry (mac_to_x_fontname (name
, 0,
7034 add_font_name_table_entry (mac_to_x_fontname (name
, 0,
7035 italic
| bold
, cs
));
7036 Fputhash (make_unibyte_string (name
, name_len
),
7037 long_to_cons (font_ids
[i
]), atsu_font_id_hash
);
7051 /* Create a dummy instance iterator here to avoid creating and
7052 destroying it in the loop. */
7053 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
7055 /* Create an iterator to enumerate the font families. */
7056 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
7059 FMDisposeFontFamilyInstanceIterator (&ffii
);
7063 GCPRO1 (text_encoding_info_alist
);
7065 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
7071 TextEncoding encoding
;
7072 TextEncodingBase sc
;
7073 Lisp_Object text_encoding_info
;
7075 if (FMGetFontFamilyName (ff
, name
) != noErr
)
7081 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
7083 sc
= GetTextEncodingBase (encoding
);
7084 text_encoding_info
= assq_no_quit (make_number (sc
),
7085 text_encoding_info_alist
);
7086 if (NILP (text_encoding_info
))
7087 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
7088 text_encoding_info_alist
);
7089 decode_mac_font_name (name
, sizeof (name
),
7090 XCAR (XCDR (text_encoding_info
)));
7091 fm_font_family_alist
= Fcons (Fcons (build_string (name
),
7093 fm_font_family_alist
);
7095 /* Point the instance iterator at the current font family. */
7096 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
7099 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
7102 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7104 if (size
> 0 || style
== normal
)
7105 for (; !NILP (rest
); rest
= XCDR (rest
))
7107 char *cs
= SDATA (XCAR (rest
));
7111 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
7113 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
7115 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
7117 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
7123 add_font_name_table_entry (mac_to_x_fontname (name
, size
,
7132 /* Dispose of the iterators. */
7133 FMDisposeFontFamilyIterator (&ffi
);
7134 FMDisposeFontFamilyInstanceIterator (&ffii
);
7135 #else /* !TARGET_API_MAC_CARBON */
7137 SInt16 fontnum
, old_fontnum
;
7138 int num_mac_fonts
= CountResources('FOND');
7140 Handle font_handle
, font_handle_2
;
7141 short id
, scriptcode
;
7144 struct FontAssoc
*fat
;
7145 struct AsscEntry
*assc_entry
;
7146 Lisp_Object text_encoding_info_alist
, text_encoding_info
;
7147 struct gcpro gcpro1
;
7149 GetPort (&port
); /* save the current font number used */
7150 old_fontnum
= port
->txFont
;
7152 text_encoding_info_alist
= create_text_encoding_info_alist ();
7154 GCPRO1 (text_encoding_info_alist
);
7156 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
7158 font_handle
= GetIndResource ('FOND', i
);
7162 GetResInfo (font_handle
, &id
, &type
, name
);
7163 GetFNum (name
, &fontnum
);
7169 scriptcode
= FontToScript (fontnum
);
7170 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
7171 text_encoding_info_alist
);
7172 if (NILP (text_encoding_info
))
7173 text_encoding_info
= assq_no_quit (make_number (smRoman
),
7174 text_encoding_info_alist
);
7175 decode_mac_font_name (name
, sizeof (name
),
7176 XCAR (XCDR (text_encoding_info
)));
7177 fm_font_family_alist
= Fcons (Fcons (build_string (name
),
7178 make_number (fontnum
)),
7179 fm_font_family_alist
);
7182 HLock (font_handle
);
7184 if (GetResourceSizeOnDisk (font_handle
)
7185 >= sizeof (struct FamRec
))
7187 fat
= (struct FontAssoc
*) (*font_handle
7188 + sizeof (struct FamRec
));
7190 = (struct AsscEntry
*) (*font_handle
7191 + sizeof (struct FamRec
)
7192 + sizeof (struct FontAssoc
));
7194 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
7196 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7198 for (; !NILP (rest
); rest
= XCDR (rest
))
7200 char *cs
= SDATA (XCAR (rest
));
7202 add_font_name_table_entry (mac_to_x_fontname (name
,
7203 assc_entry
->fontSize
,
7204 assc_entry
->fontStyle
,
7210 HUnlock (font_handle
);
7211 font_handle_2
= GetNextFOND (font_handle
);
7212 ReleaseResource (font_handle
);
7213 font_handle
= font_handle_2
;
7215 while (ResError () == noErr
&& font_handle
);
7220 TextFont (old_fontnum
);
7221 #endif /* !TARGET_API_MAC_CARBON */
7226 mac_clear_font_name_table ()
7230 for (i
= 0; i
< font_name_count
; i
++)
7231 xfree (font_name_table
[i
]);
7232 xfree (font_name_table
);
7233 font_name_table
= NULL
;
7234 font_name_table_size
= font_name_count
= 0;
7235 fm_font_family_alist
= Qnil
;
7239 enum xlfd_scalable_field_index
7241 XLFD_SCL_PIXEL_SIZE
,
7242 XLFD_SCL_POINT_SIZE
,
7247 static int xlfd_scalable_fields
[] =
7256 mac_do_list_fonts (pattern
, maxnames
)
7261 Lisp_Object font_list
= Qnil
;
7262 struct xlfdpat
*pat
;
7264 int scl_val
[XLFD_SCL_LAST
], *field
, *val
;
7267 if (font_name_table
== NULL
) /* Initialize when first used. */
7268 init_font_name_table ();
7270 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
7273 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
7274 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
7275 fonts are scaled according to the specified size. */
7278 field
= xlfd_scalable_fields
;
7286 if ('0' <= *ptr
&& *ptr
<= '9')
7288 *val
= *ptr
++ - '0';
7289 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
7290 *val
= *val
* 10 + *ptr
++ - '0';
7297 ptr
= strchr (ptr
, '-');
7300 while (ptr
&& i
< 14);
7302 if (i
== 14 && ptr
== NULL
)
7304 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
7305 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
7306 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
7307 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
7309 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
7310 scl_val
[XLFD_SCL_POINT_SIZE
] =
7311 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7312 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
7314 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
7315 scl_val
[XLFD_SCL_AVGWIDTH
] =
7316 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7317 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
7321 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
7323 pat
= xlfdpat_create (pattern
);
7327 exact
= xlfdpat_exact_p (pat
);
7329 for (i
= 0; i
< font_name_count
; i
++)
7331 if (xlfdpat_match (pat
, font_name_table
[i
]))
7333 font_list
= Fcons (build_string (font_name_table
[i
]), font_list
);
7334 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
7337 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
7338 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
7340 int former_len
= ptr
- font_name_table
[i
];
7342 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
7345 memcpy (scaled
, font_name_table
[i
], former_len
);
7346 sprintf (scaled
+ former_len
,
7347 "-%d-%d-75-75-m-%d-%s",
7348 scl_val
[XLFD_SCL_PIXEL_SIZE
],
7349 scl_val
[XLFD_SCL_POINT_SIZE
],
7350 scl_val
[XLFD_SCL_AVGWIDTH
],
7351 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
7353 if (xlfdpat_match (pat
, scaled
))
7355 font_list
= Fcons (build_string (scaled
), font_list
);
7357 if (exact
|| maxnames
> 0 && ++n_fonts
>= maxnames
)
7365 xlfdpat_destroy (pat
);
7370 /* Return a list of names of available fonts matching PATTERN on frame F.
7372 Frame F null means we have not yet created any frame on Mac, and
7373 consult the first display in x_display_list. MAXNAMES sets a limit
7374 on how many fonts to match. */
7377 x_list_fonts (f
, pattern
, size
, maxnames
)
7379 Lisp_Object pattern
;
7382 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
7383 struct mac_display_info
*dpyinfo
7384 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
7386 xassert (size
<= 0);
7388 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
7389 if (NILP (patterns
))
7390 patterns
= Fcons (pattern
, Qnil
);
7392 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
7394 pattern
= XCAR (patterns
);
7396 if (!STRINGP (pattern
))
7399 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
7400 key
= Fcons (pattern
, make_number (maxnames
));
7402 list
= Fassoc (key
, tem
);
7405 list
= Fcdr_safe (list
);
7406 /* We have a cashed list. Don't have to get the list again. */
7411 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
7414 /* MAC_TODO: add code for matching outline fonts here */
7416 /* Now store the result in the cache. */
7417 XSETCAR (XCDR (dpyinfo
->name_list_element
),
7418 Fcons (Fcons (key
, list
),
7419 XCAR (XCDR (dpyinfo
->name_list_element
))));
7422 if (NILP (list
)) continue; /* Try the remaining alternatives. */
7431 /* Check that FONT is valid on frame F. It is if it can be found in F's
7435 x_check_font (f
, font
)
7440 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7442 xassert (font
!= NULL
);
7444 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7445 if (dpyinfo
->font_table
[i
].name
7446 && font
== dpyinfo
->font_table
[i
].font
)
7449 xassert (i
< dpyinfo
->n_fonts
);
7452 #endif /* GLYPH_DEBUG != 0 */
7454 /* Set *W to the minimum width, *H to the minimum font height of FONT.
7455 Note: There are (broken) X fonts out there with invalid XFontStruct
7456 min_bounds contents. For example, handa@etl.go.jp reports that
7457 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
7458 have font->min_bounds.width == 0. */
7461 x_font_min_bounds (font
, w
, h
)
7462 MacFontStruct
*font
;
7465 *h
= FONT_HEIGHT (font
);
7466 *w
= font
->min_bounds
.width
;
7470 /* Compute the smallest character width and smallest font height over
7471 all fonts available on frame F. Set the members smallest_char_width
7472 and smallest_font_height in F's x_display_info structure to
7473 the values computed. Value is non-zero if smallest_font_height or
7474 smallest_char_width become smaller than they were before. */
7477 x_compute_min_glyph_bounds (f
)
7481 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7482 MacFontStruct
*font
;
7483 int old_width
= dpyinfo
->smallest_char_width
;
7484 int old_height
= dpyinfo
->smallest_font_height
;
7486 dpyinfo
->smallest_font_height
= 100000;
7487 dpyinfo
->smallest_char_width
= 100000;
7489 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7490 if (dpyinfo
->font_table
[i
].name
)
7492 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
7495 font
= (MacFontStruct
*) fontp
->font
;
7496 xassert (font
!= (MacFontStruct
*) ~0);
7497 x_font_min_bounds (font
, &w
, &h
);
7499 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
7500 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
7503 xassert (dpyinfo
->smallest_char_width
> 0
7504 && dpyinfo
->smallest_font_height
> 0);
7506 return (dpyinfo
->n_fonts
== 1
7507 || dpyinfo
->smallest_char_width
< old_width
7508 || dpyinfo
->smallest_font_height
< old_height
);
7512 /* Determine whether given string is a fully-specified XLFD: all 14
7513 fields are present, none is '*'. */
7516 is_fully_specified_xlfd (char *p
)
7524 for (i
= 0; i
< 13; i
++)
7526 q
= strchr (p
+ 1, '-');
7529 if (q
- p
== 2 && *(p
+ 1) == '*')
7534 if (strchr (p
+ 1, '-') != NULL
)
7537 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
7544 /* XLoadQueryFont creates and returns an internal representation for a
7545 font in a MacFontStruct struct. There is really no concept
7546 corresponding to "loading" a font on the Mac. But we check its
7547 existence and find the font number and all other information for it
7548 and store them in the returned MacFontStruct. */
7550 static MacFontStruct
*
7551 XLoadQueryFont (Display
*dpy
, char *fontname
)
7553 int i
, size
, char_width
;
7559 ATSUStyle mac_style
= NULL
;
7562 #if TARGET_API_MAC_CARBON
7563 TextEncoding encoding
;
7568 MacFontStruct
*font
;
7570 if (is_fully_specified_xlfd (fontname
))
7574 Lisp_Object matched_fonts
;
7576 matched_fonts
= mac_do_list_fonts (fontname
, 1);
7577 if (NILP (matched_fonts
))
7579 name
= SDATA (XCAR (matched_fonts
));
7582 if (parse_x_font_name (name
, family
, &size
, &fontface
, charset
) == 0)
7586 if (strcmp (charset
, "iso10646-1") == 0) /* XXX */
7589 ATSUAttributeTag tags
[] = {kATSUFontTag
, kATSUSizeTag
,
7590 kATSUQDBoldfaceTag
, kATSUQDItalicTag
};
7591 ByteCount sizes
[] = {sizeof (ATSUFontID
), sizeof (Fixed
),
7592 sizeof (Boolean
), sizeof (Boolean
)};
7593 static ATSUFontID font_id
;
7594 static Fixed size_fixed
;
7595 static Boolean bold_p
, italic_p
;
7596 ATSUAttributeValuePtr values
[] = {&font_id
, &size_fixed
,
7597 &bold_p
, &italic_p
};
7598 ATSUFontFeatureType types
[] = {kAllTypographicFeaturesType
};
7599 ATSUFontFeatureSelector selectors
[] = {kAllTypeFeaturesOffSelector
};
7600 Lisp_Object font_id_cons
;
7602 font_id_cons
= Fgethash (make_unibyte_string (family
, strlen (family
)),
7603 atsu_font_id_hash
, Qnil
);
7604 if (NILP (font_id_cons
))
7606 font_id
= cons_to_long (font_id_cons
);
7607 size_fixed
= Long2Fix (size
);
7608 bold_p
= (fontface
& bold
) != 0;
7609 italic_p
= (fontface
& italic
) != 0;
7610 err
= ATSUCreateStyle (&mac_style
);
7613 err
= ATSUSetFontFeatures (mac_style
, sizeof (types
) / sizeof (types
[0]),
7617 err
= ATSUSetAttributes (mac_style
, sizeof (tags
) / sizeof (tags
[0]),
7618 tags
, sizes
, values
);
7620 scriptcode
= kTextEncodingMacUnicode
;
7625 Lisp_Object tmp
= Fassoc (build_string (family
), fm_font_family_alist
);
7629 fontnum
= XINT (XCDR (tmp
));
7630 #if TARGET_API_MAC_CARBON
7631 if (FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
7633 scriptcode
= GetTextEncodingBase (encoding
);
7635 scriptcode
= FontToScript (fontnum
);
7639 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
7641 font
->mac_fontnum
= fontnum
;
7642 font
->mac_fontsize
= size
;
7643 font
->mac_fontface
= fontface
;
7644 font
->mac_scriptcode
= scriptcode
;
7646 font
->mac_style
= mac_style
;
7649 /* Apple Japanese (SJIS) font is listed as both
7650 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
7651 (Roman script) in init_font_name_table (). The latter should be
7652 treated as a one-byte font. */
7653 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
7654 font
->mac_scriptcode
= smRoman
;
7656 font
->full_name
= mac_to_x_fontname (family
, size
, fontface
, charset
);
7659 if (font
->mac_style
)
7662 ATSUTextLayout text_layout
;
7664 Rect char_bounds
, min_bounds
, max_bounds
;
7665 int min_width
, max_width
;
7666 ATSTrapezoid glyph_bounds
;
7668 font
->per_char
= xmalloc (sizeof (XCharStruct
) * 0x10000);
7669 if (font
->per_char
== NULL
)
7671 mac_unload_font (&one_mac_display_info
, font
);
7674 bzero (font
->per_char
, sizeof (XCharStruct
) * 0x10000);
7676 err
= atsu_get_text_layout_with_text_ptr (&c
, 1,
7681 mac_unload_font (&one_mac_display_info
, font
);
7685 for (c
= 0x20; c
<= 0x7e; c
++)
7687 err
= ATSUClearLayoutCache (text_layout
, kATSUFromTextBeginning
);
7689 err
= ATSUMeasureTextImage (text_layout
,
7690 kATSUFromTextBeginning
, kATSUToTextEnd
,
7691 0, 0, &char_bounds
);
7693 err
= ATSUGetGlyphBounds (text_layout
, 0, 0,
7694 kATSUFromTextBeginning
, kATSUToTextEnd
,
7695 kATSUseFractionalOrigins
, 1,
7696 &glyph_bounds
, NULL
);
7699 xassert (glyph_bounds
.lowerRight
.x
- glyph_bounds
.lowerLeft
.x
7700 == glyph_bounds
.upperRight
.x
- glyph_bounds
.upperLeft
.x
);
7702 char_width
= Fix2Long (glyph_bounds
.upperRight
.x
7703 - glyph_bounds
.upperLeft
.x
);
7704 STORE_XCHARSTRUCT (font
->per_char
[c
],
7705 char_width
, char_bounds
);
7708 min_width
= max_width
= char_width
;
7709 min_bounds
= max_bounds
= char_bounds
;
7710 font
->ascent
= -Fix2Long (glyph_bounds
.upperLeft
.y
);
7711 font
->descent
= Fix2Long (glyph_bounds
.lowerLeft
.y
);
7717 min_width
= min (min_width
, char_width
);
7718 max_width
= max (max_width
, char_width
);
7720 if (!EmptyRect (&char_bounds
))
7722 SetRect (&min_bounds
,
7723 max (min_bounds
.left
, char_bounds
.left
),
7724 max (min_bounds
.top
, char_bounds
.top
),
7725 min (min_bounds
.right
, char_bounds
.right
),
7726 min (min_bounds
.bottom
, char_bounds
.bottom
));
7727 UnionRect (&max_bounds
, &char_bounds
, &max_bounds
);
7732 STORE_XCHARSTRUCT (font
->min_bounds
, min_width
, min_bounds
);
7733 STORE_XCHARSTRUCT (font
->max_bounds
, max_width
, max_bounds
);
7735 font
->min_byte1
= 0;
7736 font
->max_byte1
= 0xff;
7737 font
->min_char_or_byte2
= 0;
7738 font
->max_char_or_byte2
= 0xff;
7744 SInt16 old_fontnum
, old_fontsize
;
7746 FontInfo the_fontinfo
;
7747 int is_two_byte_font
;
7749 /* Save the current font number used. */
7751 #if TARGET_API_MAC_CARBON
7752 old_fontnum
= GetPortTextFont (port
);
7753 old_fontsize
= GetPortTextSize (port
);
7754 old_fontface
= GetPortTextFace (port
);
7756 old_fontnum
= port
->txFont
;
7757 old_fontsize
= port
->txSize
;
7758 old_fontface
= port
->txFace
;
7763 TextFace (fontface
);
7765 GetFontInfo (&the_fontinfo
);
7767 font
->ascent
= the_fontinfo
.ascent
;
7768 font
->descent
= the_fontinfo
.descent
;
7770 is_two_byte_font
= (font
->mac_scriptcode
== smJapanese
7771 || font
->mac_scriptcode
== smTradChinese
7772 || font
->mac_scriptcode
== smSimpChinese
7773 || font
->mac_scriptcode
== smKorean
);
7775 if (is_two_byte_font
)
7777 font
->min_byte1
= 0xa1;
7778 font
->max_byte1
= 0xfe;
7779 font
->min_char_or_byte2
= 0xa1;
7780 font
->max_char_or_byte2
= 0xfe;
7782 /* Use the width of an "ideographic space" of that font
7783 because the_fontinfo.widMax returns the wrong width for
7785 switch (font
->mac_scriptcode
)
7788 font
->min_byte1
= 0x81;
7789 font
->max_byte1
= 0xfc;
7790 font
->min_char_or_byte2
= 0x40;
7791 font
->max_char_or_byte2
= 0xfc;
7792 char_width
= StringWidth("\p\x81\x40");
7795 font
->min_char_or_byte2
= 0x40;
7796 char_width
= StringWidth("\p\xa1\x40");
7799 char_width
= StringWidth("\p\xa1\xa1");
7802 char_width
= StringWidth("\p\xa1\xa1");
7808 font
->min_byte1
= font
->max_byte1
= 0;
7809 font
->min_char_or_byte2
= 0x20;
7810 font
->max_char_or_byte2
= 0xff;
7812 /* Do this instead of use the_fontinfo.widMax, which
7813 incorrectly returns 15 for 12-point Monaco! */
7814 char_width
= CharWidth ('m');
7817 if (is_two_byte_font
)
7819 font
->per_char
= NULL
;
7821 if (fontface
& italic
)
7822 font
->max_bounds
.rbearing
= char_width
+ 1;
7824 font
->max_bounds
.rbearing
= char_width
;
7825 font
->max_bounds
.lbearing
= 0;
7826 font
->max_bounds
.width
= char_width
;
7827 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
7828 font
->max_bounds
.descent
= the_fontinfo
.descent
;
7830 font
->min_bounds
= font
->max_bounds
;
7834 int c
, min_width
, max_width
;
7835 Rect char_bounds
, min_bounds
, max_bounds
;
7838 font
->per_char
= xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
7839 bzero (font
->per_char
, sizeof (XCharStruct
) * (0xff - 0x20 + 1));
7841 min_width
= max_width
= char_width
;
7842 SetRect (&min_bounds
, -32767, -32767, 32767, 32767);
7843 SetRect (&max_bounds
, 0, 0, 0, 0);
7844 for (c
= 0x20; c
<= 0xff; c
++)
7847 char_width
= CharWidth (ch
);
7848 QDTextBounds (1, &ch
, &char_bounds
);
7849 STORE_XCHARSTRUCT (font
->per_char
[c
- 0x20],
7850 char_width
, char_bounds
);
7851 /* Some Japanese fonts (in SJIS encoding) return 0 as
7852 the character width of 0x7f. */
7855 min_width
= min (min_width
, char_width
);
7856 max_width
= max (max_width
, char_width
);
7858 if (!EmptyRect (&char_bounds
))
7860 SetRect (&min_bounds
,
7861 max (min_bounds
.left
, char_bounds
.left
),
7862 max (min_bounds
.top
, char_bounds
.top
),
7863 min (min_bounds
.right
, char_bounds
.right
),
7864 min (min_bounds
.bottom
, char_bounds
.bottom
));
7865 UnionRect (&max_bounds
, &char_bounds
, &max_bounds
);
7868 STORE_XCHARSTRUCT (font
->min_bounds
, min_width
, min_bounds
);
7869 STORE_XCHARSTRUCT (font
->max_bounds
, max_width
, max_bounds
);
7870 if (min_width
== max_width
7871 && max_bounds
.left
>= 0 && max_bounds
.right
<= max_width
)
7873 /* Fixed width and no overhangs. */
7874 xfree (font
->per_char
);
7875 font
->per_char
= NULL
;
7879 /* Restore previous font number, size and face. */
7880 TextFont (old_fontnum
);
7881 TextSize (old_fontsize
);
7882 TextFace (old_fontface
);
7890 mac_unload_font (dpyinfo
, font
)
7891 struct mac_display_info
*dpyinfo
;
7894 xfree (font
->full_name
);
7896 xfree (font
->per_char
);
7898 if (font
->mac_style
)
7899 ATSUDisposeStyle (font
->mac_style
);
7905 /* Load font named FONTNAME of the size SIZE for frame F, and return a
7906 pointer to the structure font_info while allocating it dynamically.
7907 If SIZE is 0, load any size of font.
7908 If loading is failed, return NULL. */
7911 x_load_font (f
, fontname
, size
)
7913 register char *fontname
;
7916 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7917 Lisp_Object font_names
;
7919 /* Get a list of all the fonts that match this name. Once we
7920 have a list of matching fonts, we compare them against the fonts
7921 we already have by comparing names. */
7922 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
7924 if (!NILP (font_names
))
7929 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7930 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
7931 if (dpyinfo
->font_table
[i
].name
7932 && (!strcmp (dpyinfo
->font_table
[i
].name
,
7933 SDATA (XCAR (tail
)))
7934 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
7935 SDATA (XCAR (tail
)))))
7936 return (dpyinfo
->font_table
+ i
);
7941 /* Load the font and add it to the table. */
7944 struct MacFontStruct
*font
;
7945 struct font_info
*fontp
;
7946 unsigned long value
;
7949 fontname
= (char *) SDATA (XCAR (font_names
));
7952 font
= (MacFontStruct
*) XLoadQueryFont (FRAME_MAC_DISPLAY (f
), fontname
);
7957 /* Find a free slot in the font table. */
7958 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7959 if (dpyinfo
->font_table
[i
].name
== NULL
)
7962 /* If no free slot found, maybe enlarge the font table. */
7963 if (i
== dpyinfo
->n_fonts
7964 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
7967 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
7968 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
7970 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
7973 fontp
= dpyinfo
->font_table
+ i
;
7974 if (i
== dpyinfo
->n_fonts
)
7977 /* Now fill in the slots of *FONTP. */
7979 bzero (fontp
, sizeof (*fontp
));
7981 fontp
->font_idx
= i
;
7982 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
7983 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
7985 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
7987 /* Fixed width font. */
7988 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
7995 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
7996 pcm
= mac_per_char_metric (font
, &char2b
, 0);
7998 fontp
->space_width
= pcm
->width
;
8000 fontp
->space_width
= FONT_WIDTH (font
);
8004 int width
= pcm
->width
;
8005 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
8006 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
8007 width
+= pcm
->width
;
8008 fontp
->average_width
= width
/ 95;
8011 fontp
->average_width
= FONT_WIDTH (font
);
8014 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
8015 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
8017 fontp
->size
= font
->max_bounds
.width
;
8018 fontp
->height
= FONT_HEIGHT (font
);
8020 /* For some font, ascent and descent in max_bounds field is
8021 larger than the above value. */
8022 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
8023 if (max_height
> fontp
->height
)
8024 fontp
->height
= max_height
;
8027 /* The slot `encoding' specifies how to map a character
8028 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
8029 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
8030 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
8031 2:0xA020..0xFF7F). For the moment, we don't know which charset
8032 uses this font. So, we set information in fontp->encoding[1]
8033 which is never used by any charset. If mapping can't be
8034 decided, set FONT_ENCODING_NOT_DECIDED. */
8035 if (font
->mac_scriptcode
== smJapanese
)
8036 fontp
->encoding
[1] = 4;
8040 = (font
->max_byte1
== 0
8042 ? (font
->min_char_or_byte2
< 0x80
8043 ? (font
->max_char_or_byte2
< 0x80
8044 ? 0 /* 0x20..0x7F */
8045 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
8046 : 1) /* 0xA0..0xFF */
8048 : (font
->min_byte1
< 0x80
8049 ? (font
->max_byte1
< 0x80
8050 ? (font
->min_char_or_byte2
< 0x80
8051 ? (font
->max_char_or_byte2
< 0x80
8052 ? 0 /* 0x2020..0x7F7F */
8053 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
8054 : 3) /* 0x20A0..0x7FFF */
8055 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
8056 : (font
->min_char_or_byte2
< 0x80
8057 ? (font
->max_char_or_byte2
< 0x80
8058 ? 2 /* 0xA020..0xFF7F */
8059 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
8060 : 1))); /* 0xA0A0..0xFFFF */
8063 #if 0 /* MAC_TODO: fill these out with more reasonably values */
8064 fontp
->baseline_offset
8065 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
8066 ? (long) value
: 0);
8067 fontp
->relative_compose
8068 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
8069 ? (long) value
: 0);
8070 fontp
->default_ascent
8071 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
8072 ? (long) value
: 0);
8074 fontp
->baseline_offset
= 0;
8075 fontp
->relative_compose
= 0;
8076 fontp
->default_ascent
= 0;
8079 /* Set global flag fonts_changed_p to non-zero if the font loaded
8080 has a character with a smaller width than any other character
8081 before, or if the font loaded has a smaller height than any
8082 other font loaded before. If this happens, it will make a
8083 glyph matrix reallocation necessary. */
8084 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
8091 /* Return a pointer to struct font_info of a font named FONTNAME for
8092 frame F. If no such font is loaded, return NULL. */
8095 x_query_font (f
, fontname
)
8097 register char *fontname
;
8099 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8102 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8103 if (dpyinfo
->font_table
[i
].name
8104 && (!strcmp (dpyinfo
->font_table
[i
].name
, fontname
)
8105 || !strcmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
8106 return (dpyinfo
->font_table
+ i
);
8111 /* Find a CCL program for a font specified by FONTP, and set the member
8112 `encoder' of the structure. */
8115 x_find_ccl_program (fontp
)
8116 struct font_info
*fontp
;
8118 Lisp_Object list
, elt
;
8120 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
8124 && STRINGP (XCAR (elt
))
8125 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
8131 struct ccl_program
*ccl
8132 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
8134 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
8137 fontp
->font_encoder
= ccl
;
8143 /* The Mac Event loop code */
8145 #if !TARGET_API_MAC_CARBON
8147 #include <Quickdraw.h>
8148 #include <Balloons.h>
8149 #include <Devices.h>
8151 #include <Gestalt.h>
8153 #include <Processes.h>
8155 #include <ToolUtils.h>
8156 #include <TextUtils.h>
8157 #include <Dialogs.h>
8160 #include <Resources.h>
8165 #endif /* ! TARGET_API_MAC_CARBON */
8170 #define WINDOW_RESOURCE 128
8171 #define TERM_WINDOW_RESOURCE 129
8173 #define DEFAULT_NUM_COLS 80
8175 #define MIN_DOC_SIZE 64
8176 #define MAX_DOC_SIZE 32767
8178 #define EXTRA_STACK_ALLOC (256 * 1024)
8180 #define ARGV_STRING_LIST_ID 129
8181 #define ABOUT_ALERT_ID 128
8182 #define RAM_TOO_LARGE_ALERT_ID 129
8184 /* Contains the string "reverse", which is a constant for mouse button emu.*/
8185 Lisp_Object Qreverse
;
8187 /* True if using command key as meta key. */
8188 Lisp_Object Vmac_command_key_is_meta
;
8190 /* Modifier associated with the option key, or nil for normal behavior. */
8191 Lisp_Object Vmac_option_modifier
;
8193 /* True if the ctrl and meta keys should be reversed. */
8194 Lisp_Object Vmac_reverse_ctrl_meta
;
8196 /* True if the option and command modifiers should be used to emulate
8197 a three button mouse */
8198 Lisp_Object Vmac_emulate_three_button_mouse
;
8200 #if USE_CARBON_EVENTS
8201 /* True if the mouse wheel button (i.e. button 4) should map to
8202 mouse-2, instead of mouse-3. */
8203 Lisp_Object Vmac_wheel_button_is_mouse_2
;
8205 /* If Non-nil, the Mac "Command" key is passed on to the Mac Toolbox
8206 for processing before Emacs sees it. */
8207 Lisp_Object Vmac_pass_command_to_system
;
8209 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox
8210 for processing before Emacs sees it. */
8211 Lisp_Object Vmac_pass_control_to_system
;
8214 /* Points to the variable `inev' in the function XTread_socket. It is
8215 used for passing an input event to the function back from
8216 Carbon/Apple event handlers. */
8217 static struct input_event
*read_socket_inev
= NULL
;
8219 /* Set in term/mac-win.el to indicate that event loop can now generate
8220 drag and drop events. */
8221 Lisp_Object Qmac_ready_for_drag_n_drop
;
8223 Point saved_menu_event_location
;
8226 static void init_required_apple_events (void);
8228 do_ae_open_application (const AppleEvent
*, AppleEvent
*, long);
8230 do_ae_print_documents (const AppleEvent
*, AppleEvent
*, long);
8231 static pascal OSErr
do_ae_open_documents (AppleEvent
*, AppleEvent
*, long);
8232 static pascal OSErr
do_ae_quit_application (AppleEvent
*, AppleEvent
*, long);
8234 #if TARGET_API_MAC_CARBON
8236 static pascal OSErr
mac_do_track_drag (DragTrackingMessage
, WindowPtr
, void*, DragReference
);
8237 static pascal OSErr
mac_do_receive_drag (WindowPtr
, void*, DragReference
);
8238 static DragTrackingHandlerUPP mac_do_track_dragUPP
= NULL
;
8239 static DragReceiveHandlerUPP mac_do_receive_dragUPP
= NULL
;
8242 static Lisp_Object Qapplication
, Qabout
;
8243 #if USE_CARBON_EVENTS
8245 extern void init_service_handler ();
8246 static Lisp_Object Qpreferences
, Qservices
, Qpaste
, Qperform
;
8248 /* Window Event Handler */
8249 static pascal OSStatus
mac_handle_window_event (EventHandlerCallRef
,
8252 OSErr
install_window_handler (WindowPtr
);
8254 extern void init_emacs_passwd_dir ();
8255 extern int emacs_main (int, char **, char **);
8257 extern void initialize_applescript();
8258 extern void terminate_applescript();
8261 #if USE_CARBON_EVENTS
8262 mac_to_emacs_modifiers (UInt32 mods
)
8264 mac_to_emacs_modifiers (EventModifiers mods
)
8267 unsigned int result
= 0;
8268 if (mods
& macShiftKey
)
8269 result
|= shift_modifier
;
8270 if (mods
& macCtrlKey
)
8271 result
|= ctrl_modifier
;
8272 if (mods
& macMetaKey
)
8273 result
|= meta_modifier
;
8274 if (NILP (Vmac_command_key_is_meta
) && (mods
& macAltKey
))
8275 result
|= alt_modifier
;
8276 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
8277 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
8279 result
|= XUINT(val
);
8286 mac_get_emulated_btn ( UInt32 modifiers
)
8289 if (!NILP (Vmac_emulate_three_button_mouse
)) {
8290 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
8291 if (modifiers
& cmdKey
)
8292 result
= cmdIs3
? 2 : 1;
8293 else if (modifiers
& optionKey
)
8294 result
= cmdIs3
? 1 : 2;
8299 #if USE_CARBON_EVENTS
8300 /* Obtains the event modifiers from the event ref and then calls
8301 mac_to_emacs_modifiers. */
8303 mac_event_to_emacs_modifiers (EventRef eventRef
)
8306 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8307 sizeof (UInt32
), NULL
, &mods
);
8308 if (!NILP (Vmac_emulate_three_button_mouse
) &&
8309 GetEventClass(eventRef
) == kEventClassMouse
)
8311 mods
&= ~(optionKey
| cmdKey
);
8313 return mac_to_emacs_modifiers (mods
);
8316 /* Given an event ref, return the code to use for the mouse button
8317 code in the emacs input_event. */
8319 mac_get_mouse_btn (EventRef ref
)
8321 EventMouseButton result
= kEventMouseButtonPrimary
;
8322 GetEventParameter (ref
, kEventParamMouseButton
, typeMouseButton
, NULL
,
8323 sizeof (EventMouseButton
), NULL
, &result
);
8326 case kEventMouseButtonPrimary
:
8327 if (NILP (Vmac_emulate_three_button_mouse
))
8331 GetEventParameter (ref
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
8332 sizeof (UInt32
), NULL
, &mods
);
8333 return mac_get_emulated_btn(mods
);
8335 case kEventMouseButtonSecondary
:
8336 return NILP (Vmac_wheel_button_is_mouse_2
) ? 1 : 2;
8337 case kEventMouseButtonTertiary
:
8338 case 4: /* 4 is the number for the mouse wheel button */
8339 return NILP (Vmac_wheel_button_is_mouse_2
) ? 2 : 1;
8345 /* Normally, ConvertEventRefToEventRecord will correctly handle all
8346 events. However the click of the mouse wheel is not converted to a
8347 mouseDown or mouseUp event. Likewise for dead key down events.
8348 This calls ConvertEventRef, but then checks to see if it is a mouse
8349 up/down, or a dead key down carbon event that has not been
8350 converted, and if so, converts it by hand (to be picked up in the
8351 XTread_socket loop). */
8352 static Boolean
mac_convert_event_ref (EventRef eventRef
, EventRecord
*eventRec
)
8354 Boolean result
= ConvertEventRefToEventRecord (eventRef
, eventRec
);
8359 switch (GetEventClass (eventRef
))
8361 case kEventClassMouse
:
8362 switch (GetEventKind (eventRef
))
8364 case kEventMouseDown
:
8365 eventRec
->what
= mouseDown
;
8370 eventRec
->what
= mouseUp
;
8379 case kEventClassKeyboard
:
8380 switch (GetEventKind (eventRef
))
8382 case kEventRawKeyDown
:
8384 unsigned char char_codes
;
8387 eventRec
->what
= keyDown
;
8388 GetEventParameter (eventRef
, kEventParamKeyMacCharCodes
, typeChar
,
8389 NULL
, sizeof (char), NULL
, &char_codes
);
8390 GetEventParameter (eventRef
, kEventParamKeyCode
, typeUInt32
,
8391 NULL
, sizeof (UInt32
), NULL
, &key_code
);
8392 eventRec
->message
= char_codes
| ((key_code
& 0xff) << 8);
8408 /* Need where and when. */
8411 GetEventParameter (eventRef
, kEventParamMouseLocation
, typeQDPoint
,
8412 NULL
, sizeof (Point
), NULL
, &eventRec
->where
);
8413 /* Use two step process because new event modifiers are 32-bit
8414 and old are 16-bit. Currently, only loss is NumLock & Fn. */
8415 GetEventParameter (eventRef
, kEventParamKeyModifiers
, typeUInt32
,
8416 NULL
, sizeof (UInt32
), NULL
, &mods
);
8417 eventRec
->modifiers
= mods
;
8419 eventRec
->when
= EventTimeToTicks (GetEventTime (eventRef
));
8430 Handle menubar_handle
;
8431 MenuHandle menu_handle
;
8433 menubar_handle
= GetNewMBar (128);
8434 if(menubar_handle
== NULL
)
8436 SetMenuBar (menubar_handle
);
8439 #if !TARGET_API_MAC_CARBON
8440 menu_handle
= GetMenuHandle (M_APPLE
);
8441 if(menu_handle
!= NULL
)
8442 AppendResMenu (menu_handle
,'DRVR');
8450 do_init_managers (void)
8452 #if !TARGET_API_MAC_CARBON
8453 InitGraf (&qd
.thePort
);
8455 FlushEvents (everyEvent
, 0);
8460 #endif /* !TARGET_API_MAC_CARBON */
8463 #if !TARGET_API_MAC_CARBON
8464 /* set up some extra stack space for use by emacs */
8465 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
8467 /* MaxApplZone must be called for AppleScript to execute more
8468 complicated scripts */
8471 #endif /* !TARGET_API_MAC_CARBON */
8475 do_check_ram_size (void)
8477 SInt32 physical_ram_size
, logical_ram_size
;
8479 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
8480 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
8481 || physical_ram_size
> (1 << VALBITS
)
8482 || logical_ram_size
> (1 << VALBITS
))
8484 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
8490 do_window_update (WindowPtr win
)
8492 struct frame
*f
= mac_window_to_frame (win
);
8496 /* The tooltip has been drawn already. Avoid the SET_FRAME_GARBAGED
8498 if (win
!= tip_window
)
8500 if (f
->async_visible
== 0)
8502 /* Update events may occur when a frame gets iconified. */
8504 f
->async_visible
= 1;
8505 f
->async_iconified
= 0;
8506 SET_FRAME_GARBAGED (f
);
8512 #if TARGET_API_MAC_CARBON
8513 RgnHandle region
= NewRgn ();
8515 GetPortVisibleRegion (GetWindowPort (win
), region
);
8516 GetRegionBounds (region
, &r
);
8517 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
8518 UpdateControls (win
, region
);
8519 DisposeRgn (region
);
8521 r
= (*win
->visRgn
)->rgnBBox
;
8522 expose_frame (f
, r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
);
8523 UpdateControls (win
, win
->visRgn
);
8532 is_emacs_window (WindowPtr win
)
8534 Lisp_Object tail
, frame
;
8539 FOR_EACH_FRAME (tail
, frame
)
8540 if (FRAME_MAC_P (XFRAME (frame
)))
8541 if (FRAME_MAC_WINDOW (XFRAME (frame
)) == win
)
8550 /* Window-activate events will do the job. */
8556 /* Window-deactivate events will do the job. */
8561 do_apple_menu (SInt16 menu_item
)
8563 #if !TARGET_API_MAC_CARBON
8565 SInt16 da_driver_refnum
;
8567 if (menu_item
== I_ABOUT
)
8568 NoteAlert (ABOUT_ALERT_ID
, NULL
);
8571 GetMenuItemText (GetMenuHandle (M_APPLE
), menu_item
, item_name
);
8572 da_driver_refnum
= OpenDeskAcc (item_name
);
8574 #endif /* !TARGET_API_MAC_CARBON */
8578 do_menu_choice (SInt32 menu_choice
)
8580 SInt16 menu_id
, menu_item
;
8582 menu_id
= HiWord (menu_choice
);
8583 menu_item
= LoWord (menu_choice
);
8591 do_apple_menu (menu_item
);
8596 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
8597 MenuHandle menu
= GetMenuHandle (menu_id
);
8602 GetMenuItemRefCon (menu
, menu_item
, &refcon
);
8603 menubar_selection_callback (f
, refcon
);
8612 /* Handle drags in size box. Based on code contributed by Ben
8613 Mesander and IM - Window Manager A. */
8616 do_grow_window (WindowPtr w
, EventRecord
*e
)
8619 int rows
, columns
, width
, height
;
8620 struct frame
*f
= mac_window_to_frame (w
);
8621 XSizeHints
*size_hints
= FRAME_SIZE_HINTS (f
);
8622 int min_width
= MIN_DOC_SIZE
, min_height
= MIN_DOC_SIZE
;
8623 #if TARGET_API_MAC_CARBON
8629 if (size_hints
->flags
& PMinSize
)
8631 min_width
= size_hints
->min_width
;
8632 min_height
= size_hints
->min_height
;
8634 SetRect (&limit_rect
, min_width
, min_height
, MAX_DOC_SIZE
, MAX_DOC_SIZE
);
8636 #if TARGET_API_MAC_CARBON
8637 if (!ResizeWindow (w
, e
->where
, &limit_rect
, &new_rect
))
8639 height
= new_rect
.bottom
- new_rect
.top
;
8640 width
= new_rect
.right
- new_rect
.left
;
8642 grow_size
= GrowWindow (w
, e
->where
, &limit_rect
);
8643 /* see if it really changed size */
8646 height
= HiWord (grow_size
);
8647 width
= LoWord (grow_size
);
8650 if (width
!= FRAME_PIXEL_WIDTH (f
)
8651 || height
!= FRAME_PIXEL_HEIGHT (f
))
8653 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
8654 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
8656 x_set_window_size (f
, 0, columns
, rows
);
8661 /* Handle clicks in zoom box. Calculation of "standard state" based
8662 on code in IM - Window Manager A and code contributed by Ben
8663 Mesander. The standard state of an Emacs window is 80-characters
8664 wide (DEFAULT_NUM_COLS) and as tall as will fit on the screen. */
8667 do_zoom_window (WindowPtr w
, int zoom_in_or_out
)
8670 Rect zoom_rect
, port_rect
;
8672 int w_title_height
, columns
, rows
, width
, height
;
8673 struct frame
*f
= mac_window_to_frame (w
);
8674 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8676 #if TARGET_API_MAC_CARBON
8678 Point standard_size
;
8680 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
8681 standard_size
.v
= dpyinfo
->height
;
8683 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
))
8684 zoom_in_or_out
= inZoomIn
;
8687 /* Adjust the standard size according to character boundaries. */
8689 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, zoom_rect
.right
- zoom_rect
.left
);
8690 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
8691 standard_size
.h
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, columns
);
8692 standard_size
.v
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
8693 GetWindowBounds (w
, kWindowContentRgn
, &port_rect
);
8694 if (IsWindowInStandardState (w
, &standard_size
, &zoom_rect
)
8695 && port_rect
.left
== zoom_rect
.left
8696 && port_rect
.top
== zoom_rect
.top
)
8697 zoom_in_or_out
= inZoomIn
;
8699 zoom_in_or_out
= inZoomOut
;
8702 ZoomWindowIdeal (w
, zoom_in_or_out
, &standard_size
);
8704 #else /* not TARGET_API_MAC_CARBON */
8705 GetPort (&save_port
);
8707 SetPortWindowPort (w
);
8709 /* Clear window to avoid flicker. */
8710 EraseRect (&(w
->portRect
));
8711 if (zoom_in_or_out
== inZoomOut
)
8713 SetPt (&top_left
, w
->portRect
.left
, w
->portRect
.top
);
8714 LocalToGlobal (&top_left
);
8716 /* calculate height of window's title bar */
8717 w_title_height
= top_left
.v
- 1
8718 - (**((WindowPeek
) w
)->strucRgn
).rgnBBox
.top
+ GetMBarHeight ();
8720 /* get maximum height of window into zoom_rect.bottom - zoom_rect.top */
8721 zoom_rect
= qd
.screenBits
.bounds
;
8722 zoom_rect
.top
+= w_title_height
;
8723 InsetRect (&zoom_rect
, 8, 4); /* not too tight */
8725 zoom_rect
.right
= zoom_rect
.left
8726 + FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, DEFAULT_NUM_COLS
);
8728 /* Adjust the standard size according to character boundaries. */
8729 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, zoom_rect
.bottom
- zoom_rect
.top
);
8731 zoom_rect
.top
+ FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
8733 (**((WStateDataHandle
) ((WindowPeek
) w
)->dataHandle
)).stdState
8737 ZoomWindow (w
, zoom_in_or_out
, f
== mac_focus_frame (dpyinfo
));
8739 SetPort (save_port
);
8740 #endif /* not TARGET_API_MAC_CARBON */
8742 /* retrieve window size and update application values */
8743 #if TARGET_API_MAC_CARBON
8744 GetWindowPortBounds (w
, &port_rect
);
8746 port_rect
= w
->portRect
;
8748 height
= port_rect
.bottom
- port_rect
.top
;
8749 width
= port_rect
.right
- port_rect
.left
;
8751 if (width
!= FRAME_PIXEL_WIDTH (f
)
8752 || height
!= FRAME_PIXEL_HEIGHT (f
))
8754 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, height
);
8755 columns
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, width
);
8757 change_frame_size (f
, rows
, columns
, 0, 1, 0);
8758 SET_FRAME_GARBAGED (f
);
8759 cancel_mouse_face (f
);
8761 FRAME_PIXEL_WIDTH (f
) = width
;
8762 FRAME_PIXEL_HEIGHT (f
) = height
;
8764 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
8767 /* Intialize AppleEvent dispatcher table for the required events. */
8769 init_required_apple_events ()
8774 /* Make sure we have apple events before starting. */
8775 err
= Gestalt (gestaltAppleEventsAttr
, &result
);
8779 if (!(result
& (1 << gestaltAppleEventsPresent
)))
8782 #if TARGET_API_MAC_CARBON
8783 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
8784 NewAEEventHandlerUPP
8785 ((AEEventHandlerProcPtr
) do_ae_open_application
),
8788 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenApplication
,
8789 NewAEEventHandlerProc
8790 ((AEEventHandlerProcPtr
) do_ae_open_application
),
8796 #if TARGET_API_MAC_CARBON
8797 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
8798 NewAEEventHandlerUPP
8799 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
8802 err
= AEInstallEventHandler(kCoreEventClass
, kAEOpenDocuments
,
8803 NewAEEventHandlerProc
8804 ((AEEventHandlerProcPtr
) do_ae_open_documents
),
8810 #if TARGET_API_MAC_CARBON
8811 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
8812 NewAEEventHandlerUPP
8813 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
8816 err
= AEInstallEventHandler(kCoreEventClass
, kAEPrintDocuments
,
8817 NewAEEventHandlerProc
8818 ((AEEventHandlerProcPtr
) do_ae_print_documents
),
8824 #if TARGET_API_MAC_CARBON
8825 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
8826 NewAEEventHandlerUPP
8827 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
8830 err
= AEInstallEventHandler(kCoreEventClass
, kAEQuitApplication
,
8831 NewAEEventHandlerProc
8832 ((AEEventHandlerProcPtr
) do_ae_quit_application
),
8840 mac_store_application_menu_event (event
)
8841 #if USE_CARBON_EVENTS
8847 struct input_event buf
;
8848 Lisp_Object frame
, entry
;
8852 XSETFRAME (frame
, mac_focus_frame (&one_mac_display_info
));
8853 buf
.kind
= MENU_BAR_EVENT
;
8854 buf
.frame_or_window
= frame
;
8856 kbd_buffer_store_event (&buf
);
8858 buf
.arg
= Qapplication
;
8859 kbd_buffer_store_event (&buf
);
8861 #if USE_CARBON_EVENTS
8862 switch (GetEventClass (event
))
8865 case kEventClassService
:
8866 buf
.arg
= Qservices
;
8867 kbd_buffer_store_event (&buf
);
8868 switch (GetEventKind (event
))
8870 case kEventServicePaste
:
8874 case kEventServicePerform
:
8877 CFStringRef message
;
8879 err
= GetEventParameter (event
, kEventParamServiceMessageName
,
8880 typeCFStringRef
, NULL
,
8881 sizeof (CFStringRef
), NULL
, &message
);
8883 kbd_buffer_store_event (&buf
);
8884 if (err
== noErr
&& message
)
8885 entry
= intern (SDATA (cfstring_to_lisp (message
)));
8895 #endif /* MAC_OSX */
8896 case kEventClassCommand
:
8900 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
,
8901 NULL
, sizeof (HICommand
), NULL
, &command
);
8902 switch (command
.commandID
)
8904 case kHICommandAbout
:
8908 case kHICommandPreferences
:
8909 entry
= Qpreferences
;
8911 #endif /* MAC_OSX */
8912 case kHICommandQuit
:
8924 #else /* USE_CARBON_EVENTS */
8927 case kHICommandAbout
:
8930 case kHICommandQuit
:
8939 kbd_buffer_store_event (&buf
);
8942 #if USE_CARBON_EVENTS
8943 static pascal OSStatus
8944 mac_handle_command_event (next_handler
, event
, data
)
8945 EventHandlerCallRef next_handler
;
8952 GetEventParameter(event
, kEventParamDirectObject
, typeHICommand
, NULL
,
8953 sizeof (HICommand
), NULL
, &command
);
8955 switch (command
.commandID
)
8957 case kHICommandAbout
:
8959 case kHICommandPreferences
:
8960 #endif /* MAC_OSX */
8961 result
= CallNextEventHandler (next_handler
, event
);
8962 if (result
!= eventNotHandledErr
)
8965 mac_store_application_menu_event (event
);
8972 return eventNotHandledErr
;
8976 init_command_handler ()
8979 EventTypeSpec specs
[] = {{kEventClassCommand
, kEventCommandProcess
}};
8980 static EventHandlerUPP handle_command_eventUPP
= NULL
;
8982 if (handle_command_eventUPP
== NULL
)
8983 handle_command_eventUPP
= NewEventHandlerUPP (mac_handle_command_event
);
8984 return InstallApplicationEventHandler (handle_command_eventUPP
,
8985 GetEventTypeCount (specs
), specs
,
8989 static pascal OSStatus
8990 mac_handle_window_event (next_handler
, event
, data
)
8991 EventHandlerCallRef next_handler
;
8998 XSizeHints
*size_hints
;
9000 GetEventParameter (event
, kEventParamDirectObject
, typeWindowRef
,
9001 NULL
, sizeof (WindowPtr
), NULL
, &wp
);
9003 switch (GetEventKind (event
))
9005 case kEventWindowUpdate
:
9006 result
= CallNextEventHandler (next_handler
, event
);
9007 if (result
!= eventNotHandledErr
)
9010 do_window_update (wp
);
9013 case kEventWindowBoundsChanging
:
9014 result
= CallNextEventHandler (next_handler
, event
);
9015 if (result
!= eventNotHandledErr
)
9018 GetEventParameter (event
, kEventParamAttributes
, typeUInt32
,
9019 NULL
, sizeof (UInt32
), NULL
, &attributes
);
9020 size_hints
= FRAME_SIZE_HINTS (mac_window_to_frame (wp
));
9021 if ((attributes
& kWindowBoundsChangeUserResize
)
9022 && ((size_hints
->flags
& (PResizeInc
| PBaseSize
| PMinSize
))
9023 == (PResizeInc
| PBaseSize
| PMinSize
)))
9028 GetEventParameter (event
, kEventParamCurrentBounds
,
9030 NULL
, sizeof (Rect
), NULL
, &bounds
);
9031 width
= bounds
.right
- bounds
.left
;
9032 height
= bounds
.bottom
- bounds
.top
;
9034 if (width
< size_hints
->min_width
)
9035 width
= size_hints
->min_width
;
9037 width
= size_hints
->base_width
9038 + (int) ((width
- size_hints
->base_width
)
9039 / (float) size_hints
->width_inc
+ .5)
9040 * size_hints
->width_inc
;
9042 if (height
< size_hints
->min_height
)
9043 height
= size_hints
->min_height
;
9045 height
= size_hints
->base_height
9046 + (int) ((height
- size_hints
->base_height
)
9047 / (float) size_hints
->height_inc
+ .5)
9048 * size_hints
->height_inc
;
9050 bounds
.right
= bounds
.left
+ width
;
9051 bounds
.bottom
= bounds
.top
+ height
;
9052 SetEventParameter (event
, kEventParamCurrentBounds
,
9053 typeQDRectangle
, sizeof (Rect
), &bounds
);
9058 case kEventWindowShown
:
9059 case kEventWindowHidden
:
9060 case kEventWindowExpanded
:
9061 case kEventWindowCollapsed
:
9062 result
= CallNextEventHandler (next_handler
, event
);
9064 mac_handle_visibility_change (mac_window_to_frame (wp
));
9070 return eventNotHandledErr
;
9073 static pascal OSStatus
9074 mac_handle_mouse_event (next_handler
, event
, data
)
9075 EventHandlerCallRef next_handler
;
9081 switch (GetEventKind (event
))
9083 case kEventMouseWheelMoved
:
9087 EventMouseWheelAxis axis
;
9091 result
= CallNextEventHandler (next_handler
, event
);
9092 if (result
!= eventNotHandledErr
|| read_socket_inev
== NULL
)
9095 GetEventParameter (event
, kEventParamWindowRef
, typeWindowRef
,
9096 NULL
, sizeof (WindowRef
), NULL
, &wp
);
9097 f
= mac_window_to_frame (wp
);
9098 if (f
!= mac_focus_frame (&one_mac_display_info
))
9101 GetEventParameter (event
, kEventParamMouseWheelAxis
,
9102 typeMouseWheelAxis
, NULL
,
9103 sizeof (EventMouseWheelAxis
), NULL
, &axis
);
9104 if (axis
!= kEventMouseWheelAxisY
)
9107 GetEventParameter (event
, kEventParamMouseWheelDelta
, typeSInt32
,
9108 NULL
, sizeof (SInt32
), NULL
, &delta
);
9109 GetEventParameter (event
, kEventParamMouseLocation
, typeQDPoint
,
9110 NULL
, sizeof (Point
), NULL
, &point
);
9111 read_socket_inev
->kind
= WHEEL_EVENT
;
9112 read_socket_inev
->code
= 0;
9113 read_socket_inev
->modifiers
=
9114 (mac_event_to_emacs_modifiers (event
)
9115 | ((delta
< 0) ? down_modifier
: up_modifier
));
9116 SetPortWindowPort (wp
);
9117 GlobalToLocal (&point
);
9118 XSETINT (read_socket_inev
->x
, point
.h
);
9119 XSETINT (read_socket_inev
->y
, point
.v
);
9120 XSETFRAME (read_socket_inev
->frame_or_window
, f
);
9130 return eventNotHandledErr
;
9132 #endif /* USE_CARBON_EVENTS */
9136 install_window_handler (window
)
9140 #if USE_CARBON_EVENTS
9141 EventTypeSpec specs_window
[] =
9142 {{kEventClassWindow
, kEventWindowUpdate
},
9143 {kEventClassWindow
, kEventWindowBoundsChanging
},
9144 {kEventClassWindow
, kEventWindowShown
},
9145 {kEventClassWindow
, kEventWindowHidden
},
9146 {kEventClassWindow
, kEventWindowExpanded
},
9147 {kEventClassWindow
, kEventWindowCollapsed
}};
9148 EventTypeSpec specs_mouse
[] = {{kEventClassMouse
, kEventMouseWheelMoved
}};
9149 static EventHandlerUPP handle_window_eventUPP
= NULL
;
9150 static EventHandlerUPP handle_mouse_eventUPP
= NULL
;
9152 if (handle_window_eventUPP
== NULL
)
9153 handle_window_eventUPP
= NewEventHandlerUPP (mac_handle_window_event
);
9154 if (handle_mouse_eventUPP
== NULL
)
9155 handle_mouse_eventUPP
= NewEventHandlerUPP (mac_handle_mouse_event
);
9156 err
= InstallWindowEventHandler (window
, handle_window_eventUPP
,
9157 GetEventTypeCount (specs_window
),
9158 specs_window
, NULL
, NULL
);
9160 err
= InstallWindowEventHandler (window
, handle_mouse_eventUPP
,
9161 GetEventTypeCount (specs_mouse
),
9162 specs_mouse
, NULL
, NULL
);
9164 #if TARGET_API_MAC_CARBON
9165 if (mac_do_track_dragUPP
== NULL
)
9166 mac_do_track_dragUPP
= NewDragTrackingHandlerUPP (mac_do_track_drag
);
9167 if (mac_do_receive_dragUPP
== NULL
)
9168 mac_do_receive_dragUPP
= NewDragReceiveHandlerUPP (mac_do_receive_drag
);
9171 err
= InstallTrackingHandler (mac_do_track_dragUPP
, window
, NULL
);
9173 err
= InstallReceiveHandler (mac_do_receive_dragUPP
, window
, NULL
);
9179 remove_window_handler (window
)
9182 #if TARGET_API_MAC_CARBON
9183 if (mac_do_track_dragUPP
)
9184 RemoveTrackingHandler (mac_do_track_dragUPP
, window
);
9185 if (mac_do_receive_dragUPP
)
9186 RemoveReceiveHandler (mac_do_receive_dragUPP
, window
);
9190 /* Open Application Apple Event */
9192 do_ae_open_application(const AppleEvent
*pae
, AppleEvent
*preply
, long prefcon
)
9198 /* Called when we receive an AppleEvent with an ID of
9199 "kAEOpenDocuments". This routine gets the direct parameter,
9200 extracts the FSSpecs in it, and puts their names on a list. */
9201 #pragma options align=mac68k
9202 typedef struct SelectionRange
{
9203 short unused1
; // 0 (not used)
9204 short lineNum
; // line to select (<0 to specify range)
9205 long startRange
; // start of selection range (if line < 0)
9206 long endRange
; // end of selection range (if line < 0)
9207 long unused2
; // 0 (not used)
9208 long theDate
; // modification date/time
9210 #pragma options align=reset
9213 do_ae_open_documents(AppleEvent
*message
, AppleEvent
*reply
, long refcon
)
9218 DescType actual_type
;
9220 SelectionRange position
;
9221 Lisp_Object file_list
= Qnil
;
9223 xassert (read_socket_inev
);
9225 err
= AEGetParamDesc (message
, keyDirectObject
, typeAEList
, &the_desc
);
9227 goto descriptor_error_exit
;
9229 err
= AEGetParamPtr (message
, keyAEPosition
, typeChar
, &actual_type
, &position
, sizeof(SelectionRange
), &actual_size
);
9231 file_list
= Fcons (list3 (make_number (position
.lineNum
+ 1),
9232 make_number (position
.startRange
+ 1),
9233 make_number (position
.endRange
+ 1)),
9236 /* Check to see that we got all of the required parameters from the
9237 event descriptor. For an 'odoc' event this should just be the
9239 err
= AEGetAttributePtr(message
, keyMissedKeywordAttr
, typeWildCard
,
9240 &actual_type
, (Ptr
) &keyword
,
9241 sizeof (keyword
), &actual_size
);
9242 /* No error means that we found some unused parameters.
9243 errAEDescNotFound means that there are no more parameters. If we
9244 get an error code other than that, flag it. */
9245 if ((err
== noErr
) || (err
!= errAEDescNotFound
))
9247 err
= errAEEventNotHandled
;
9252 /* Got all the parameters we need. Now, go through the direct
9253 object list and parse it up. */
9255 long num_files_to_open
;
9257 err
= AECountItems (&the_desc
, &num_files_to_open
);
9262 /* AE file list is one based so just use that for indexing here. */
9263 for (i
= 1; i
<= num_files_to_open
; i
++)
9265 char unix_path_name
[MAXPATHLEN
];
9269 err
= AEGetNthPtr (&the_desc
, i
, typeFSRef
, &keyword
,
9270 &actual_type
, &fref
, sizeof (FSRef
),
9272 if (err
!= noErr
|| actual_type
!= typeFSRef
)
9275 if (FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
))
9280 err
= AEGetNthPtr(&the_desc
, i
, typeFSS
, &keyword
, &actual_type
,
9281 (Ptr
) &fs
, sizeof (fs
), &actual_size
);
9282 if (err
!= noErr
) continue;
9284 if (fsspec_to_posix_pathname (&fs
, unix_path_name
,
9285 sizeof (unix_path_name
) - 1) == noErr
)
9287 /* x-dnd functions expect undecoded filenames. */
9288 file_list
= Fcons (make_unibyte_string (unix_path_name
,
9289 strlen (unix_path_name
)),
9294 /* Build a DRAG_N_DROP_EVENT type event as is done in
9295 constuct_drag_n_drop in w32term.c. */
9296 if (!NILP (file_list
))
9298 struct frame
*f
= mac_focus_frame (&one_mac_display_info
);
9302 read_socket_inev
->kind
= DRAG_N_DROP_EVENT
;
9303 read_socket_inev
->code
= 0;
9304 read_socket_inev
->modifiers
= 0;
9306 XSETINT (read_socket_inev
->x
, 0);
9307 XSETINT (read_socket_inev
->y
, 0);
9309 XSETFRAME (frame
, f
);
9310 read_socket_inev
->frame_or_window
= Fcons (frame
, file_list
);
9313 /* Regardless of whether Emacs was suspended or in the
9314 foreground, ask it to redraw its entire screen. Otherwise
9315 parts of the screen can be left in an inconsistent
9317 wp
= FRAME_MAC_WINDOW (f
);
9319 #if TARGET_API_MAC_CARBON
9323 GetWindowPortBounds (wp
, &r
);
9324 InvalWindowRect (wp
, &r
);
9326 #else /* not TARGET_API_MAC_CARBON */
9327 InvalRect (&(wp
->portRect
));
9328 #endif /* not TARGET_API_MAC_CARBON */
9334 /* Nuke the coerced file list in any case */
9335 err2
= AEDisposeDesc(&the_desc
);
9337 descriptor_error_exit
:
9338 /* InvalRect(&(gFrontMacWindowP->mWP->portRect)); */
9343 #if TARGET_API_MAC_CARBON
9345 mac_do_track_drag (DragTrackingMessage message
, WindowPtr window
,
9346 void *handlerRefCon
, DragReference theDrag
)
9348 static int can_accept
;
9351 ItemReference theItem
;
9352 FlavorFlags theFlags
;
9355 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
9356 return dragNotAcceptedErr
;
9360 case kDragTrackingEnterHandler
:
9361 CountDragItems (theDrag
, &items
);
9363 for (index
= 1; index
<= items
; index
++)
9365 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
9366 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
9367 if (result
== noErr
)
9375 case kDragTrackingEnterWindow
:
9378 RgnHandle hilite_rgn
= NewRgn ();
9380 struct frame
*f
= mac_window_to_frame (window
);
9382 GetWindowPortBounds (window
, &r
);
9383 OffsetRect (&r
, -r
.left
, -r
.top
);
9384 RectRgn (hilite_rgn
, &r
);
9385 ShowDragHilite (theDrag
, hilite_rgn
, true);
9386 DisposeRgn (hilite_rgn
);
9387 SetThemeCursor (kThemeCopyArrowCursor
);
9391 case kDragTrackingInWindow
:
9394 case kDragTrackingLeaveWindow
:
9397 struct frame
*f
= mac_window_to_frame (window
);
9399 HideDragHilite (theDrag
);
9400 SetThemeCursor (kThemeArrowCursor
);
9404 case kDragTrackingLeaveHandler
:
9412 mac_do_receive_drag (WindowPtr window
, void *handlerRefCon
,
9413 DragReference theDrag
)
9417 FlavorFlags theFlags
;
9420 ItemReference theItem
;
9422 Size size
= sizeof (HFSFlavor
);
9423 Lisp_Object file_list
;
9425 if (GetFrontWindowOfClass (kMovableModalWindowClass
, false))
9426 return dragNotAcceptedErr
;
9429 GetDragMouse (theDrag
, &mouse
, 0L);
9430 CountDragItems (theDrag
, &items
);
9431 for (index
= 1; index
<= items
; index
++)
9433 /* Only handle file references. */
9434 GetDragItemReferenceNumber (theDrag
, index
, &theItem
);
9435 result
= GetFlavorFlags (theDrag
, theItem
, flavorTypeHFS
, &theFlags
);
9436 if (result
== noErr
)
9441 char unix_path_name
[MAXPATHLEN
];
9443 GetFlavorData (theDrag
, theItem
, flavorTypeHFS
, &data
, &size
, 0L);
9445 /* Use Carbon routines, otherwise it converts the file name
9446 to /Macintosh HD/..., which is not correct. */
9447 FSpMakeFSRef (&data
.fileSpec
, &fref
);
9448 if (! FSRefMakePath (&fref
, unix_path_name
, sizeof (unix_path_name
)));
9450 if (fsspec_to_posix_pathname (&data
.fileSpec
, unix_path_name
,
9451 sizeof (unix_path_name
) - 1) == noErr
)
9453 /* x-dnd functions expect undecoded filenames. */
9454 file_list
= Fcons (make_unibyte_string (unix_path_name
,
9455 strlen (unix_path_name
)),
9459 /* If there are items in the list, construct an event and post it to
9460 the queue like an interrupt using kbd_buffer_store_event. */
9461 if (!NILP (file_list
))
9463 struct input_event event
;
9465 struct frame
*f
= mac_window_to_frame (window
);
9468 GlobalToLocal (&mouse
);
9469 GetDragModifiers (theDrag
, NULL
, NULL
, &modifiers
);
9471 event
.kind
= DRAG_N_DROP_EVENT
;
9473 event
.modifiers
= mac_to_emacs_modifiers (modifiers
);
9474 event
.timestamp
= TickCount () * (1000 / 60);
9475 XSETINT (event
.x
, mouse
.h
);
9476 XSETINT (event
.y
, mouse
.v
);
9477 XSETFRAME (frame
, f
);
9478 event
.frame_or_window
= Fcons (frame
, file_list
);
9480 /* Post to the interrupt queue */
9481 kbd_buffer_store_event (&event
);
9482 /* MAC_TODO: Mimic behavior of windows by switching contexts to Emacs */
9484 ProcessSerialNumber psn
;
9485 GetCurrentProcess (&psn
);
9486 SetFrontProcess (&psn
);
9492 return dragNotAcceptedErr
;
9497 /* Print Document Apple Event */
9499 do_ae_print_documents (const AppleEvent
*pAE
, AppleEvent
*reply
, long refcon
)
9501 return errAEEventNotHandled
;
9506 do_ae_quit_application (AppleEvent
* message
, AppleEvent
*reply
, long refcon
)
9508 #if USE_CARBON_EVENTS
9510 EventRef event
= NULL
;
9511 static const HICommand quit_command
= {kEventAttributeNone
, kHICommandQuit
};
9513 err
= CreateEvent (NULL
, kEventClassCommand
, kEventCommandProcess
, 0,
9514 kEventAttributeUserEvent
, &event
);
9516 err
= SetEventParameter (event
, kEventParamDirectObject
, typeHICommand
,
9517 sizeof (HICommand
), &quit_command
);
9519 mac_store_application_menu_event (event
);
9521 ReleaseEvent (event
);
9526 return errAEEventNotHandled
;
9528 mac_store_application_menu_event (kHICommandQuit
);
9537 profiler_exit_proc ()
9539 ProfilerDump ("\pEmacs.prof");
9544 /* These few functions implement Emacs as a normal Mac application
9545 (almost): set up the heap and the Toolbox, handle necessary system
9546 events plus a few simple menu events. They also set up Emacs's
9547 access to functions defined in the rest of this file. Emacs uses
9548 function hooks to perform all its terminal I/O. A complete list of
9549 these functions appear in termhooks.h. For what they do, read the
9550 comments there and see also w32term.c and xterm.c. What's
9551 noticeably missing here is the event loop, which is normally
9552 present in most Mac application. After performing the necessary
9553 Mac initializations, main passes off control to emacs_main
9554 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
9555 (defined further below) to read input. This is where
9556 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
9563 #if __profile__ /* is the profiler on? */
9564 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
9569 /* set creator and type for files created by MSL */
9574 do_init_managers ();
9579 do_check_ram_size ();
9582 init_emacs_passwd_dir ();
9586 initialize_applescript ();
9588 init_required_apple_events ();
9594 /* set up argv array from STR# resource */
9595 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
9599 /* free up AppleScript resources on exit */
9600 atexit (terminate_applescript
);
9602 #if __profile__ /* is the profiler on? */
9603 atexit (profiler_exit_proc
);
9606 /* 3rd param "envp" never used in emacs_main */
9607 (void) emacs_main (argc
, argv
, 0);
9610 /* Never reached - real exit in Fkill_emacs */
9615 /* Table for translating Mac keycode to X keysym values. Contributed
9617 Mapping for special keys is now identical to that in Apple X11
9618 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
9619 on the right of the Cmd key on laptops, and fn + `enter' (->
9621 static unsigned char keycode_to_xkeysym_table
[] = {
9622 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9623 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9624 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9626 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
9627 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
9628 /*0x38*/ 0, 0, 0, 0,
9629 /*0x3C*/ 0, 0, 0, 0,
9631 /*0x40*/ 0, 0xae /*kp-.*/, 0, 0xaa /*kp-**/,
9632 /*0x44*/ 0, 0xab /*kp-+*/, 0, 0x0b /*clear*/,
9633 /*0x48*/ 0, 0, 0, 0xaf /*kp-/*/,
9634 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp--*/, 0,
9636 /*0x50*/ 0, 0xbd /*kp-=*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
9637 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
9638 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
9639 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
9641 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
9642 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
9643 /*0x68*/ 0, 0xca /*f13*/, 0, 0xcb /*f14*/,
9644 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
9646 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
9647 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
9648 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
9649 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
9653 keycode_to_xkeysym (int keyCode
, int *xKeySym
)
9655 *xKeySym
= keycode_to_xkeysym_table
[keyCode
& 0x7f];
9656 return *xKeySym
!= 0;
9659 #if !USE_CARBON_EVENTS
9660 static RgnHandle mouse_region
= NULL
;
9663 mac_wait_next_event (er
, sleep_time
, dequeue
)
9668 static EventRecord er_buf
= {nullEvent
};
9669 UInt32 target_tick
, current_tick
;
9670 EventMask event_mask
;
9672 if (mouse_region
== NULL
)
9673 mouse_region
= NewRgn ();
9675 event_mask
= everyEvent
;
9676 if (NILP (Fboundp (Qmac_ready_for_drag_n_drop
)))
9677 event_mask
-= highLevelEventMask
;
9679 current_tick
= TickCount ();
9680 target_tick
= current_tick
+ sleep_time
;
9682 if (er_buf
.what
== nullEvent
)
9683 while (!WaitNextEvent (event_mask
, &er_buf
,
9684 target_tick
- current_tick
, mouse_region
))
9686 current_tick
= TickCount ();
9687 if (target_tick
<= current_tick
)
9693 er_buf
.what
= nullEvent
;
9696 #endif /* not USE_CARBON_EVENTS */
9698 /* Emacs calls this whenever it wants to read an input event from the
9701 XTread_socket (sd
, expected
, hold_quit
)
9703 struct input_event
*hold_quit
;
9705 struct input_event inev
;
9707 #if USE_CARBON_EVENTS
9709 EventTargetRef toolbox_dispatcher
;
9712 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
9714 if (interrupt_input_blocked
)
9716 interrupt_input_pending
= 1;
9720 interrupt_input_pending
= 0;
9723 /* So people can tell when we have read the available input. */
9724 input_signal_count
++;
9726 #if USE_CARBON_EVENTS
9727 toolbox_dispatcher
= GetEventDispatcherTarget ();
9729 while (!ReceiveNextEvent (0, NULL
, kEventDurationNoWait
,
9730 kEventRemoveFromQueue
, &eventRef
))
9731 #else /* !USE_CARBON_EVENTS */
9732 while (mac_wait_next_event (&er
, 0, true))
9733 #endif /* !USE_CARBON_EVENTS */
9737 unsigned long timestamp
;
9739 /* It is necessary to set this (additional) argument slot of an
9740 event to nil because keyboard.c protects incompletely
9741 processed event from being garbage collected by placing them
9742 in the kbd_buffer_gcpro vector. */
9744 inev
.kind
= NO_EVENT
;
9747 #if USE_CARBON_EVENTS
9748 timestamp
= GetEventTime (eventRef
) / kEventDurationMillisecond
;
9750 timestamp
= er
.when
* (1000 / 60); /* ticks to milliseconds */
9753 #if USE_CARBON_EVENTS
9754 /* Handle new events */
9755 if (!mac_convert_event_ref (eventRef
, &er
))
9757 /* There used to be a handler for the kEventMouseWheelMoved
9758 event here. But as of Mac OS X 10.4, this kind of event
9759 is not directly posted to the main event queue by
9760 two-finger scrolling on the trackpad. Instead, some
9761 private event is posted and it is converted to a wheel
9762 event by the default handler for the application target.
9763 The converted one can be received by a Carbon event
9764 handler installed on a window target. */
9765 read_socket_inev
= &inev
;
9766 SendEventToEventTarget (eventRef
, toolbox_dispatcher
);
9767 read_socket_inev
= NULL
;
9770 #endif /* USE_CARBON_EVENTS */
9776 WindowPtr window_ptr
;
9777 ControlPartCode part_code
;
9780 #if USE_CARBON_EVENTS
9781 /* This is needed to send mouse events like aqua window
9782 buttons to the correct handler. */
9783 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
9784 != eventNotHandledErr
)
9788 if (dpyinfo
->grabbed
&& last_mouse_frame
9789 && FRAME_LIVE_P (last_mouse_frame
))
9791 window_ptr
= FRAME_MAC_WINDOW (last_mouse_frame
);
9792 part_code
= inContent
;
9796 part_code
= FindWindow (er
.where
, &window_ptr
);
9797 if (tip_window
&& window_ptr
== tip_window
)
9799 HideWindow (tip_window
);
9800 part_code
= FindWindow (er
.where
, &window_ptr
);
9804 if (er
.what
!= mouseDown
&& part_code
!= inContent
)
9810 f
= mac_focus_frame (dpyinfo
);
9811 saved_menu_event_location
= er
.where
;
9812 inev
.kind
= MENU_BAR_ACTIVATE_EVENT
;
9813 XSETFRAME (inev
.frame_or_window
, f
);
9817 if (window_ptr
!= FRAME_MAC_WINDOW (mac_focus_frame (dpyinfo
)))
9818 SelectWindow (window_ptr
);
9821 ControlPartCode control_part_code
;
9823 Point mouse_loc
= er
.where
;
9825 ControlKind control_kind
;
9828 f
= mac_window_to_frame (window_ptr
);
9829 /* convert to local coordinates of new window */
9830 SetPortWindowPort (window_ptr
);
9832 GlobalToLocal (&mouse_loc
);
9833 #if TARGET_API_MAC_CARBON
9834 ch
= FindControlUnderMouse (mouse_loc
, window_ptr
,
9835 &control_part_code
);
9838 GetControlKind (ch
, &control_kind
);
9841 control_part_code
= FindControl (mouse_loc
, window_ptr
,
9845 #if USE_CARBON_EVENTS
9846 inev
.code
= mac_get_mouse_btn (eventRef
);
9847 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
9849 inev
.code
= mac_get_emulated_btn (er
.modifiers
);
9850 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
9852 XSETINT (inev
.x
, mouse_loc
.h
);
9853 XSETINT (inev
.y
, mouse_loc
.v
);
9855 if (dpyinfo
->grabbed
&& tracked_scroll_bar
9857 #ifndef USE_TOOLKIT_SCROLL_BARS
9858 /* control_part_code becomes kControlNoPart if
9859 a progress indicator is clicked. */
9860 && control_part_code
!= kControlNoPart
9861 #else /* USE_TOOLKIT_SCROLL_BARS */
9863 && control_kind
.kind
== kControlKindScrollBar
9864 #endif /* MAC_OSX */
9865 #endif /* USE_TOOLKIT_SCROLL_BARS */
9868 struct scroll_bar
*bar
;
9870 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
9872 bar
= tracked_scroll_bar
;
9873 #ifndef USE_TOOLKIT_SCROLL_BARS
9874 control_part_code
= kControlIndicatorPart
;
9878 bar
= (struct scroll_bar
*) GetControlReference (ch
);
9879 #ifdef USE_TOOLKIT_SCROLL_BARS
9880 /* Make the "Ctrl-Mouse-2 splits window" work
9881 for toolkit scroll bars. */
9882 if (er
.modifiers
& controlKey
)
9883 x_scroll_bar_handle_click (bar
, control_part_code
,
9885 else if (er
.what
== mouseDown
)
9886 x_scroll_bar_handle_press (bar
, control_part_code
,
9889 x_scroll_bar_handle_release (bar
, &inev
);
9890 #else /* not USE_TOOLKIT_SCROLL_BARS */
9891 x_scroll_bar_handle_click (bar
, control_part_code
,
9893 if (er
.what
== mouseDown
9894 && control_part_code
== kControlIndicatorPart
)
9895 tracked_scroll_bar
= bar
;
9897 tracked_scroll_bar
= NULL
;
9898 #endif /* not USE_TOOLKIT_SCROLL_BARS */
9903 int x
= mouse_loc
.h
;
9904 int y
= mouse_loc
.v
;
9906 window
= window_from_coordinates (f
, x
, y
, 0, 0, 0, 1);
9907 if (EQ (window
, f
->tool_bar_window
))
9909 if (er
.what
== mouseDown
)
9910 handle_tool_bar_click (f
, x
, y
, 1, 0);
9912 handle_tool_bar_click (f
, x
, y
, 0,
9918 XSETFRAME (inev
.frame_or_window
, f
);
9919 inev
.kind
= MOUSE_CLICK_EVENT
;
9923 if (er
.what
== mouseDown
)
9925 dpyinfo
->grabbed
|= (1 << inev
.code
);
9926 last_mouse_frame
= f
;
9927 /* Ignore any mouse motion that happened
9928 before this event; any subsequent
9929 mouse-movement Emacs events should reflect
9930 only motion after the ButtonPress. */
9935 last_tool_bar_item
= -1;
9939 if ((dpyinfo
->grabbed
& (1 << inev
.code
)) == 0)
9940 /* If a button is released though it was not
9941 previously pressed, that would be because
9942 of multi-button emulation. */
9943 dpyinfo
->grabbed
= 0;
9945 dpyinfo
->grabbed
&= ~(1 << inev
.code
);
9948 #ifdef USE_TOOLKIT_SCROLL_BARS
9949 if (inev
.kind
== MOUSE_CLICK_EVENT
)
9954 inev
.modifiers
|= down_modifier
;
9957 inev
.modifiers
|= up_modifier
;
9964 #if TARGET_API_MAC_CARBON
9965 DragWindow (window_ptr
, er
.where
, NULL
);
9966 #else /* not TARGET_API_MAC_CARBON */
9967 DragWindow (window_ptr
, er
.where
, &qd
.screenBits
.bounds
);
9968 #endif /* not TARGET_API_MAC_CARBON */
9969 /* Update the frame parameters. */
9971 struct frame
*f
= mac_window_to_frame (window_ptr
);
9973 if (f
&& !f
->async_iconified
)
9974 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
9979 if (TrackGoAway (window_ptr
, er
.where
))
9981 inev
.kind
= DELETE_WINDOW_EVENT
;
9982 XSETFRAME (inev
.frame_or_window
,
9983 mac_window_to_frame (window_ptr
));
9987 /* window resize handling added --ben */
9989 do_grow_window (window_ptr
, &er
);
9992 /* window zoom handling added --ben */
9995 if (TrackBox (window_ptr
, er
.where
, part_code
))
9996 do_zoom_window (window_ptr
, part_code
);
10006 #if USE_CARBON_EVENTS
10007 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10008 != eventNotHandledErr
)
10011 do_window_update ((WindowPtr
) er
.message
);
10016 #if USE_CARBON_EVENTS
10017 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10018 != eventNotHandledErr
)
10021 switch ((er
.message
>> 24) & 0x000000FF)
10023 case suspendResumeMessage
:
10024 if ((er
.message
& resumeFlag
) == 1)
10030 case mouseMovedMessage
:
10031 #if !USE_CARBON_EVENTS
10032 SetRectRgn (mouse_region
, er
.where
.h
, er
.where
.v
,
10033 er
.where
.h
+ 1, er
.where
.v
+ 1);
10035 previous_help_echo_string
= help_echo_string
;
10036 help_echo_string
= help_echo_object
= help_echo_window
= Qnil
;
10037 help_echo_pos
= -1;
10039 if (dpyinfo
->grabbed
&& last_mouse_frame
10040 && FRAME_LIVE_P (last_mouse_frame
))
10041 f
= last_mouse_frame
;
10043 f
= dpyinfo
->x_focus_frame
;
10045 if (dpyinfo
->mouse_face_hidden
)
10047 dpyinfo
->mouse_face_hidden
= 0;
10048 clear_mouse_face (dpyinfo
);
10053 WindowPtr wp
= FRAME_MAC_WINDOW (f
);
10054 Point mouse_pos
= er
.where
;
10056 SetPortWindowPort (wp
);
10058 GlobalToLocal (&mouse_pos
);
10060 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10061 #ifdef USE_TOOLKIT_SCROLL_BARS
10062 x_scroll_bar_handle_drag (wp
, tracked_scroll_bar
,
10064 #else /* not USE_TOOLKIT_SCROLL_BARS */
10065 x_scroll_bar_note_movement (tracked_scroll_bar
,
10067 - XINT (tracked_scroll_bar
->top
),
10068 er
.when
* (1000 / 60));
10069 #endif /* not USE_TOOLKIT_SCROLL_BARS */
10072 /* Generate SELECT_WINDOW_EVENTs when needed. */
10073 if (mouse_autoselect_window
)
10075 Lisp_Object window
;
10077 window
= window_from_coordinates (f
,
10082 /* Window will be selected only when it is
10083 not selected now and last mouse movement
10084 event was not in it. Minibuffer window
10085 will be selected iff it is active. */
10086 if (WINDOWP (window
)
10087 && !EQ (window
, last_window
)
10088 && !EQ (window
, selected_window
))
10090 inev
.kind
= SELECT_WINDOW_EVENT
;
10091 inev
.frame_or_window
= window
;
10094 last_window
=window
;
10096 note_mouse_movement (f
, &mouse_pos
);
10100 /* If the contents of the global variable
10101 help_echo_string has changed, generate a
10103 if (!NILP (help_echo_string
) || !NILP (previous_help_echo_string
))
10111 WindowPtr window_ptr
= (WindowPtr
) er
.message
;
10113 #if USE_CARBON_EVENTS
10114 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10115 != eventNotHandledErr
)
10118 if (window_ptr
== tip_window
)
10120 HideWindow (tip_window
);
10124 if (!is_emacs_window (window_ptr
))
10127 if ((er
.modifiers
& activeFlag
) != 0)
10129 /* A window has been activated */
10130 Point mouse_loc
= er
.where
;
10132 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10134 SetPortWindowPort (window_ptr
);
10135 GlobalToLocal (&mouse_loc
);
10136 /* Window-activated event counts as mouse movement,
10137 so update things that depend on mouse position. */
10138 note_mouse_movement (mac_window_to_frame (window_ptr
),
10143 /* A window has been deactivated */
10144 #if USE_TOOLKIT_SCROLL_BARS
10145 if (dpyinfo
->grabbed
&& tracked_scroll_bar
)
10147 struct input_event event
;
10149 EVENT_INIT (event
);
10150 event
.kind
= NO_EVENT
;
10151 x_scroll_bar_handle_release (tracked_scroll_bar
, &event
);
10152 if (event
.kind
!= NO_EVENT
)
10154 event
.timestamp
= timestamp
;
10155 kbd_buffer_store_event_hold (&event
, hold_quit
);
10160 dpyinfo
->grabbed
= 0;
10162 x_detect_focus_change (dpyinfo
, &er
, &inev
);
10164 f
= mac_window_to_frame (window_ptr
);
10165 if (f
== dpyinfo
->mouse_face_mouse_frame
)
10167 /* If we move outside the frame, then we're
10168 certainly no longer on any text in the
10170 clear_mouse_face (dpyinfo
);
10171 dpyinfo
->mouse_face_mouse_frame
= 0;
10174 /* Generate a nil HELP_EVENT to cancel a help-echo.
10175 Do it only if there's something to cancel.
10176 Otherwise, the startup message is cleared when the
10177 mouse leaves the frame. */
10178 if (any_help_event_p
)
10187 int keycode
= (er
.message
& keyCodeMask
) >> 8;
10190 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10191 /* When using Carbon Events, we need to pass raw keyboard
10192 events to the TSM ourselves. If TSM handles it, it
10193 will pass back noErr, otherwise it will pass back
10194 "eventNotHandledErr" and we can process it
10196 if ((!NILP (Vmac_pass_command_to_system
)
10197 || !(er
.modifiers
& cmdKey
))
10198 && (!NILP (Vmac_pass_control_to_system
)
10199 || !(er
.modifiers
& controlKey
))
10200 && (!NILP (Vmac_command_key_is_meta
)
10201 && NILP (Vmac_option_modifier
)
10202 || !(er
.modifiers
& optionKey
)))
10203 if (SendEventToEventTarget (eventRef
, toolbox_dispatcher
)
10204 != eventNotHandledErr
)
10209 if (dpyinfo
->x_focus_frame
== NULL
)
10211 /* Beep if keyboard input occurs when all the frames
10219 static SInt16 last_key_script
= -1;
10220 SInt16 current_key_script
= GetScriptManagerVariable (smKeyScript
);
10222 if (last_key_script
!= current_key_script
)
10224 struct input_event event
;
10226 EVENT_INIT (event
);
10227 event
.kind
= LANGUAGE_CHANGE_EVENT
;
10229 event
.code
= current_key_script
;
10230 event
.timestamp
= timestamp
;
10231 kbd_buffer_store_event (&event
);
10234 last_key_script
= current_key_script
;
10239 if (!dpyinfo
->mouse_face_hidden
&& INTEGERP (Vmouse_highlight
))
10241 clear_mouse_face (dpyinfo
);
10242 dpyinfo
->mouse_face_hidden
= 1;
10245 if (keycode_to_xkeysym (keycode
, &xkeysym
))
10247 inev
.code
= 0xff00 | xkeysym
;
10248 inev
.kind
= NON_ASCII_KEYSTROKE_EVENT
;
10252 if (er
.modifiers
& (controlKey
|
10253 (NILP (Vmac_command_key_is_meta
) ? optionKey
10256 /* This code comes from Keyboard Resource,
10257 Appendix C of IM - Text. This is necessary
10258 since shift is ignored in KCHR table
10259 translation when option or command is pressed.
10260 It also does not translate correctly
10261 control-shift chars like C-% so mask off shift
10263 int new_modifiers
= er
.modifiers
& 0xe600;
10264 /* mask off option and command */
10265 int new_keycode
= keycode
| new_modifiers
;
10266 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
10267 unsigned long some_state
= 0;
10268 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
10269 &some_state
) & 0xff;
10271 else if (!NILP (Vmac_option_modifier
)
10272 && (er
.modifiers
& optionKey
))
10274 /* When using the option key as an emacs modifier,
10275 convert the pressed key code back to one
10276 without the Mac option modifier applied. */
10277 int new_modifiers
= er
.modifiers
& ~optionKey
;
10278 int new_keycode
= keycode
| new_modifiers
;
10279 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
10280 unsigned long some_state
= 0;
10281 inev
.code
= KeyTranslate (kchr_ptr
, new_keycode
,
10282 &some_state
) & 0xff;
10285 inev
.code
= er
.message
& charCodeMask
;
10286 inev
.kind
= ASCII_KEYSTROKE_EVENT
;
10290 #if USE_CARBON_EVENTS
10291 inev
.modifiers
= mac_event_to_emacs_modifiers (eventRef
);
10293 inev
.modifiers
= mac_to_emacs_modifiers (er
.modifiers
);
10295 inev
.modifiers
|= (extra_keyboard_modifiers
10296 & (meta_modifier
| alt_modifier
10297 | hyper_modifier
| super_modifier
));
10298 XSETFRAME (inev
.frame_or_window
, mac_focus_frame (dpyinfo
));
10301 case kHighLevelEvent
:
10302 read_socket_inev
= &inev
;
10303 AEProcessAppleEvent (&er
);
10304 read_socket_inev
= NULL
;
10310 #if USE_CARBON_EVENTS
10311 ReleaseEvent (eventRef
);
10314 if (inev
.kind
!= NO_EVENT
)
10316 inev
.timestamp
= timestamp
;
10317 kbd_buffer_store_event_hold (&inev
, hold_quit
);
10322 && !(hold_quit
&& hold_quit
->kind
!= NO_EVENT
))
10327 XSETFRAME (frame
, f
);
10333 any_help_event_p
= 1;
10334 gen_help_event (help_echo_string
, frame
, help_echo_window
,
10335 help_echo_object
, help_echo_pos
);
10339 help_echo_string
= Qnil
;
10340 gen_help_event (Qnil
, frame
, Qnil
, Qnil
, 0);
10347 /* If the focus was just given to an autoraising frame,
10349 /* ??? This ought to be able to handle more than one such frame. */
10350 if (pending_autoraise_frame
)
10352 x_raise_frame (pending_autoraise_frame
);
10353 pending_autoraise_frame
= 0;
10356 #if !USE_CARBON_EVENTS
10357 /* Check which frames are still visible. We do this here because
10358 there doesn't seem to be any direct notification from the Window
10359 Manager that the visibility of a window has changed (at least,
10360 not in all cases). */
10362 Lisp_Object tail
, frame
;
10364 FOR_EACH_FRAME (tail
, frame
)
10366 struct frame
*f
= XFRAME (frame
);
10368 /* The tooltip has been drawn already. Avoid the
10369 SET_FRAME_GARBAGED in mac_handle_visibility_change. */
10370 if (EQ (frame
, tip_frame
))
10373 if (FRAME_MAC_P (f
))
10374 mac_handle_visibility_change (f
);
10384 /* Need to override CodeWarrior's input function so no conversion is
10385 done on newlines Otherwise compiled functions in .elc files will be
10386 read incorrectly. Defined in ...:MSL C:MSL
10387 Common:Source:buffer_io.c. */
10390 __convert_to_newlines (unsigned char * p
, size_t * n
)
10392 #pragma unused(p,n)
10396 __convert_from_newlines (unsigned char * p
, size_t * n
)
10398 #pragma unused(p,n)
10404 make_mac_terminal_frame (struct frame
*f
)
10409 XSETFRAME (frame
, f
);
10411 f
->output_method
= output_mac
;
10412 f
->output_data
.mac
= (struct mac_output
*)
10413 xmalloc (sizeof (struct mac_output
));
10414 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
10416 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
10418 FRAME_COLS (f
) = 96;
10419 FRAME_LINES (f
) = 4;
10421 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
10422 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
10424 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
10426 f
->output_data
.mac
->cursor_pixel
= 0;
10427 f
->output_data
.mac
->border_pixel
= 0x00ff00;
10428 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
10429 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
10431 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
10432 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
10433 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
10434 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
10435 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
10436 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
10438 FRAME_FONTSET (f
) = -1;
10439 f
->output_data
.mac
->explicit_parent
= 0;
10442 f
->border_width
= 0;
10444 f
->internal_border_width
= 0;
10449 f
->new_text_cols
= 0;
10450 f
->new_text_lines
= 0;
10452 SetRect (&r
, f
->left_pos
, f
->top_pos
,
10453 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
10454 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
10458 if (!(FRAME_MAC_WINDOW (f
) =
10459 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
10460 (WindowPtr
) -1, 1, (long) f
->output_data
.mac
)))
10462 /* so that update events can find this mac_output struct */
10463 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
10469 /* Need to be initialized for unshow_buffer in window.c. */
10470 selected_window
= f
->selected_window
;
10472 Fmodify_frame_parameters (frame
,
10473 Fcons (Fcons (Qfont
,
10474 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
10475 Fmodify_frame_parameters (frame
,
10476 Fcons (Fcons (Qforeground_color
,
10477 build_string ("black")), Qnil
));
10478 Fmodify_frame_parameters (frame
,
10479 Fcons (Fcons (Qbackground_color
,
10480 build_string ("white")), Qnil
));
10485 /***********************************************************************
10487 ***********************************************************************/
10489 int mac_initialized
= 0;
10492 mac_initialize_display_info ()
10494 struct mac_display_info
*dpyinfo
= &one_mac_display_info
;
10495 GDHandle main_device_handle
;
10497 bzero (dpyinfo
, sizeof (*dpyinfo
));
10500 dpyinfo
->mac_id_name
10501 = (char *) xmalloc (SCHARS (Vinvocation_name
)
10502 + SCHARS (Vsystem_name
)
10504 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
10505 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
10507 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
10508 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
10511 main_device_handle
= LMGetMainDevice();
10513 dpyinfo
->reference_count
= 0;
10514 dpyinfo
->resx
= 75.0;
10515 dpyinfo
->resy
= 75.0;
10516 dpyinfo
->color_p
= TestDeviceAttribute (main_device_handle
, gdDevType
);
10518 /* HasDepth returns true if it is possible to have a 32 bit display,
10519 but this may not be what is actually used. Mac OSX can do better.
10520 CGMainDisplayID is only available on OSX 10.2 and higher, but the
10521 header for CGGetActiveDisplayList says that the first display returned
10522 is the active one, so we use that. */
10524 CGDirectDisplayID disp_id
[1];
10525 CGDisplayCount disp_count
;
10526 CGDisplayErr error_code
;
10528 error_code
= CGGetActiveDisplayList (1, disp_id
, &disp_count
);
10529 if (error_code
!= 0)
10530 error ("No display found, CGGetActiveDisplayList error %d", error_code
);
10532 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (disp_id
[0]);
10535 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
10536 if (HasDepth (main_device_handle
, dpyinfo
->n_planes
,
10537 gdDevType
, dpyinfo
->color_p
))
10540 dpyinfo
->height
= (**main_device_handle
).gdRect
.bottom
;
10541 dpyinfo
->width
= (**main_device_handle
).gdRect
.right
;
10542 dpyinfo
->grabbed
= 0;
10543 dpyinfo
->root_window
= NULL
;
10544 dpyinfo
->image_cache
= make_image_cache ();
10546 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
10547 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
10548 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
10549 dpyinfo
->mouse_face_window
= Qnil
;
10550 dpyinfo
->mouse_face_overlay
= Qnil
;
10551 dpyinfo
->mouse_face_hidden
= 0;
10556 mac_make_rdb (xrm_option
)
10559 XrmDatabase database
;
10561 database
= xrm_get_preference_database (NULL
);
10563 xrm_merge_string_database (database
, xrm_option
);
10568 struct mac_display_info
*
10569 mac_term_init (display_name
, xrm_option
, resource_name
)
10570 Lisp_Object display_name
;
10572 char *resource_name
;
10574 struct mac_display_info
*dpyinfo
;
10578 if (!mac_initialized
)
10581 mac_initialized
= 1;
10584 if (x_display_list
)
10585 error ("Sorry, this version can only handle one display");
10587 mac_initialize_display_info ();
10589 dpyinfo
= &one_mac_display_info
;
10591 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
10593 /* Put this display on the chain. */
10594 dpyinfo
->next
= x_display_list
;
10595 x_display_list
= dpyinfo
;
10597 /* Put it on x_display_name_list. */
10598 x_display_name_list
= Fcons (Fcons (display_name
,
10599 Fcons (Qnil
, dpyinfo
->xrdb
)),
10600 x_display_name_list
);
10601 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
10607 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10610 x_delete_display (dpyinfo
)
10611 struct mac_display_info
*dpyinfo
;
10615 /* Discard this display from x_display_name_list and x_display_list.
10616 We can't use Fdelq because that can quit. */
10617 if (! NILP (x_display_name_list
)
10618 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
10619 x_display_name_list
= XCDR (x_display_name_list
);
10624 tail
= x_display_name_list
;
10625 while (CONSP (tail
) && CONSP (XCDR (tail
)))
10627 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
10629 XSETCDR (tail
, XCDR (XCDR (tail
)));
10632 tail
= XCDR (tail
);
10636 if (x_display_list
== dpyinfo
)
10637 x_display_list
= dpyinfo
->next
;
10640 struct x_display_info
*tail
;
10642 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
10643 if (tail
->next
== dpyinfo
)
10644 tail
->next
= tail
->next
->next
;
10647 /* Free the font names in the font table. */
10648 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
10649 if (dpyinfo
->font_table
[i
].name
)
10651 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
10652 xfree (dpyinfo
->font_table
[i
].full_name
);
10653 xfree (dpyinfo
->font_table
[i
].name
);
10656 if (dpyinfo
->font_table
->font_encoder
)
10657 xfree (dpyinfo
->font_table
->font_encoder
);
10659 xfree (dpyinfo
->font_table
);
10660 xfree (dpyinfo
->mac_id_name
);
10662 if (x_display_list
== 0)
10664 mac_clear_font_name_table ();
10665 bzero (dpyinfo
, sizeof (*dpyinfo
));
10674 extern int inhibit_window_system
;
10675 extern int noninteractive
;
10676 CFBundleRef appsBundle
;
10679 /* No need to test if already -nw*/
10680 if (inhibit_window_system
|| noninteractive
)
10683 appsBundle
= CFBundleGetMainBundle();
10684 if (appsBundle
!= NULL
)
10686 CFStringRef cfBI
= CFSTR("CFBundleIdentifier");
10687 CFTypeRef res
= CFBundleGetValueForInfoDictionaryKey(appsBundle
, cfBI
);
10688 /* We found the bundle identifier, now we know we are valid. */
10695 /* MAC_TODO: Have this start the bundled executable */
10697 /* For now, prevent the fatal error by bringing it up in the terminal */
10698 inhibit_window_system
= 1;
10702 MakeMeTheFrontProcess ()
10704 ProcessSerialNumber psn
;
10707 err
= GetCurrentProcess (&psn
);
10709 (void) SetFrontProcess (&psn
);
10712 /***** Code to handle C-g testing *****/
10714 /* Contains the Mac modifier formed from quit_char */
10715 int mac_quit_char_modifiers
= 0;
10716 int mac_quit_char_keycode
;
10717 extern int quit_char
;
10720 mac_determine_quit_char_modifiers()
10722 /* Todo: Determine modifiers from quit_char. */
10723 UInt32 qc_modifiers
= ctrl_modifier
;
10725 /* Map modifiers */
10726 mac_quit_char_modifiers
= 0;
10727 if (qc_modifiers
& ctrl_modifier
) mac_quit_char_modifiers
|= macCtrlKey
;
10728 if (qc_modifiers
& shift_modifier
) mac_quit_char_modifiers
|= macShiftKey
;
10729 if (qc_modifiers
& meta_modifier
) mac_quit_char_modifiers
|= macMetaKey
;
10730 if (qc_modifiers
& alt_modifier
) mac_quit_char_modifiers
|= macAltKey
;
10734 init_quit_char_handler ()
10736 /* TODO: Let this support keys other the 'g' */
10737 mac_quit_char_keycode
= 5;
10738 /* Look at <architecture/adb_kb_map.h> for details */
10739 /* http://gemma.apple.com/techpubs/mac/Toolbox/Toolbox-40.html#MARKER-9-184*/
10741 mac_determine_quit_char_modifiers();
10743 #endif /* MAC_OSX */
10751 MenuItemIndex menu_index
;
10753 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandQuit
, 1,
10754 &menu
, &menu_index
);
10756 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
10757 #if USE_CARBON_EVENTS
10758 EnableMenuCommand (NULL
, kHICommandPreferences
);
10759 err
= GetIndMenuItemWithCommandID (NULL
, kHICommandPreferences
, 1,
10760 &menu
, &menu_index
);
10763 SetMenuItemCommandKey (menu
, menu_index
, false, 0);
10764 InsertMenuItemTextWithCFString (menu
, NULL
,
10765 0, kMenuItemAttrSeparator
, 0);
10766 InsertMenuItemTextWithCFString (menu
, CFSTR ("About Emacs"),
10767 0, 0, kHICommandAbout
);
10769 #endif /* USE_CARBON_EVENTS */
10770 #else /* !MAC_OSX */
10771 #if USE_CARBON_EVENTS
10772 SetMenuItemCommandID (GetMenuHandle (M_APPLE
), I_ABOUT
, kHICommandAbout
);
10778 /* Set up use of X before we make the first connection. */
10780 extern frame_parm_handler mac_frame_parm_handlers
[];
10782 static struct redisplay_interface x_redisplay_interface
=
10784 mac_frame_parm_handlers
,
10788 x_clear_end_of_line
,
10790 x_after_update_window_line
,
10791 x_update_window_begin
,
10792 x_update_window_end
,
10795 0, /* flush_display_optional */
10796 x_clear_window_mouse_face
,
10797 x_get_glyph_overhangs
,
10798 x_fix_overlapping_area
,
10799 x_draw_fringe_bitmap
,
10800 0, /* define_fringe_bitmap */
10801 0, /* destroy_fringe_bitmap */
10802 mac_per_char_metric
,
10804 mac_compute_glyph_string_overhangs
,
10805 x_draw_glyph_string
,
10806 mac_define_frame_cursor
,
10807 mac_clear_frame_area
,
10808 mac_draw_window_cursor
,
10809 mac_draw_vertical_window_border
,
10810 mac_shift_glyphs_for_insert
10816 rif
= &x_redisplay_interface
;
10818 clear_frame_hook
= x_clear_frame
;
10819 ins_del_lines_hook
= x_ins_del_lines
;
10820 delete_glyphs_hook
= x_delete_glyphs
;
10821 ring_bell_hook
= XTring_bell
;
10822 reset_terminal_modes_hook
= XTreset_terminal_modes
;
10823 set_terminal_modes_hook
= XTset_terminal_modes
;
10824 update_begin_hook
= x_update_begin
;
10825 update_end_hook
= x_update_end
;
10826 set_terminal_window_hook
= XTset_terminal_window
;
10827 read_socket_hook
= XTread_socket
;
10828 frame_up_to_date_hook
= XTframe_up_to_date
;
10829 mouse_position_hook
= XTmouse_position
;
10830 frame_rehighlight_hook
= XTframe_rehighlight
;
10831 frame_raise_lower_hook
= XTframe_raise_lower
;
10833 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
10834 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
10835 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
10836 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
10838 scroll_region_ok
= 1; /* we'll scroll partial frames */
10839 char_ins_del_ok
= 1;
10840 line_ins_del_ok
= 1; /* we'll just blt 'em */
10841 fast_clear_end_of_line
= 1; /* X does this well */
10842 memory_below_frame
= 0; /* we don't remember what scrolls
10846 last_tool_bar_item
= -1;
10847 any_help_event_p
= 0;
10849 /* Try to use interrupt input; if we can't, then start polling. */
10850 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
10854 #if TARGET_API_MAC_CARBON
10855 init_required_apple_events ();
10857 #if USE_CARBON_EVENTS
10859 init_service_handler ();
10861 init_quit_char_handler ();
10862 #endif /* MAC_OSX */
10864 init_command_handler ();
10867 #endif /* USE_CARBON_EVENTS */
10870 if (!inhibit_window_system
)
10871 MakeMeTheFrontProcess ();
10882 staticpro (&x_error_message_string
);
10883 x_error_message_string
= Qnil
;
10886 Qmodifier_value
= intern ("modifier-value");
10887 Qalt
= intern ("alt");
10888 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
10889 Qhyper
= intern ("hyper");
10890 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
10891 Qsuper
= intern ("super");
10892 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
10894 Qapplication
= intern ("application"); staticpro (&Qapplication
);
10895 Qabout
= intern ("about"); staticpro (&Qabout
);
10897 #if USE_CARBON_EVENTS && defined (MAC_OSX)
10898 Qpreferences
= intern ("preferences"); staticpro (&Qpreferences
);
10899 Qservices
= intern ("services"); staticpro (&Qservices
);
10900 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
10901 Qperform
= intern ("perform"); staticpro (&Qperform
);
10905 Fprovide (intern ("mac-carbon"), Qnil
);
10908 staticpro (&Qreverse
);
10909 Qreverse
= intern ("reverse");
10911 staticpro (&Qmac_ready_for_drag_n_drop
);
10912 Qmac_ready_for_drag_n_drop
= intern ("mac-ready-for-drag-n-drop");
10914 staticpro (&x_display_name_list
);
10915 x_display_name_list
= Qnil
;
10917 staticpro (&last_mouse_scroll_bar
);
10918 last_mouse_scroll_bar
= Qnil
;
10920 staticpro (&fm_font_family_alist
);
10921 fm_font_family_alist
= Qnil
;
10924 staticpro (&atsu_font_id_hash
);
10925 atsu_font_id_hash
= Qnil
;
10928 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
10929 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
10930 #ifdef USE_TOOLKIT_SCROLL_BARS
10931 Vx_toolkit_scroll_bars
= Qt
;
10933 Vx_toolkit_scroll_bars
= Qnil
;
10936 staticpro (&last_mouse_motion_frame
);
10937 last_mouse_motion_frame
= Qnil
;
10939 DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta
,
10940 doc
: /* Non-nil means that the command key is used as the Emacs meta key.
10941 Otherwise the option key is used. */);
10942 Vmac_command_key_is_meta
= Qt
;
10944 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
10945 doc
: /* Modifier to use for the Mac alt/option key. The value can
10946 be alt, hyper, or super for the respective modifier. If the value is
10947 nil then the key will act as the normal Mac option modifier. */);
10948 Vmac_option_modifier
= Qnil
;
10950 DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta
,
10951 doc
: /* Non-nil means that the control and meta keys are reversed. This is
10952 useful for non-standard keyboard layouts. */);
10953 Vmac_reverse_ctrl_meta
= Qnil
;
10955 DEFVAR_LISP ("mac-emulate-three-button-mouse",
10956 &Vmac_emulate_three_button_mouse
,
10957 doc
: /* t means that when the option-key is held down while pressing the
10958 mouse button, the click will register as mouse-2 and while the
10959 command-key is held down, the click will register as mouse-3.
10960 'reverse means that the option-key will register for mouse-3
10961 and the command-key will register for mouse-2. nil means that
10962 no emulation should be done and the modifiers should be placed
10963 on the mouse-1 event. */);
10964 Vmac_emulate_three_button_mouse
= Qnil
;
10966 #if USE_CARBON_EVENTS
10967 DEFVAR_LISP ("mac-wheel-button-is-mouse-2", &Vmac_wheel_button_is_mouse_2
,
10968 doc
: /* Non-nil means that the wheel button will be treated as mouse-2 and
10969 the right click will be mouse-3.
10970 Otherwise, the right click will be mouse-2 and the wheel button mouse-3.*/);
10971 Vmac_wheel_button_is_mouse_2
= Qt
;
10973 DEFVAR_LISP ("mac-pass-command-to-system", &Vmac_pass_command_to_system
,
10974 doc
: /* If non-nil, the Mac \"Command\" key is passed on to the Mac
10975 Toolbox for processing before Emacs sees it. */);
10976 Vmac_pass_command_to_system
= Qt
;
10978 DEFVAR_LISP ("mac-pass-control-to-system", &Vmac_pass_control_to_system
,
10979 doc
: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
10980 Toolbox for processing before Emacs sees it. */);
10981 Vmac_pass_control_to_system
= Qt
;
10985 DEFVAR_LISP ("mac-allow-anti-aliasing", &Vmac_use_core_graphics
,
10986 doc
: /* If non-nil, allow anti-aliasing.
10987 The text will be rendered using Core Graphics text rendering which
10988 may anti-alias the text. */);
10989 Vmac_use_core_graphics
= Qnil
;
10991 /* Register an entry for `mac-roman' so that it can be used when
10992 creating the terminal frame on Mac OS 9 before loading
10993 term/mac-win.elc. */
10994 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
10995 doc
: /* Alist linking Emacs character sets to Mac text encoding and Emacs coding system.
10996 Each entry should be of the form:
10998 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
11000 where CHARSET-NAME is a string used in font names to identify the
11001 charset, TEXT-ENCODING is a TextEncodingBase value, and CODING_SYSTEM
11002 is a coding system corresponding to TEXT-ENCODING. */);
11003 Vmac_charset_info_alist
=
11004 Fcons (list3 (build_string ("mac-roman"),
11005 make_number (smRoman
), Qnil
), Qnil
);
11008 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
11009 (do not change this comment) */