Mercurial > emacs
comparison src/macterm.c @ 63461:8aa0953a6870
(mac_compute_glyph_string_overhangs): Don't set
overhangs unless the given glyph type is noncomposite CHAR_GLYPH.
[USE_CARBON_EVENTS] (mac_convert_event_ref): Convert dead key down
events.
(XTread_socket): Don't pass keyboard events with the option
modifier to the system when Vmac_command_key_is_meta is nil or
Vmac_option_modifier is non-nil.
[USE_CARBON_EVENTS] (read_socket_inev): New variable.
[USE_CARBON_EVENTS] (init_command_handler): Fix argument.
[USE_CARBON_EVENTS] (mac_handle_mouse_event): New Carbon event
handler function.
(install_window_handler) [USE_CARBON_EVENTS]: Install it.
(XTread_socket) [USE_CARBON_EVENTS]: Move mouse wheel event
handler part to mac_handle_mouse_event.
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
---|---|
date | Wed, 15 Jun 2005 02:29:29 +0000 |
parents | 08adf0b46c71 |
children | 0ddaa52824cd e58cb448e07c a1b34dec1104 |
comparison
equal
deleted
inserted
replaced
63460:645f22f05a9a | 63461:8aa0953a6870 |
---|---|
1994 | 1994 |
1995 static void | 1995 static void |
1996 mac_compute_glyph_string_overhangs (s) | 1996 mac_compute_glyph_string_overhangs (s) |
1997 struct glyph_string *s; | 1997 struct glyph_string *s; |
1998 { | 1998 { |
1999 Rect r; | 1999 if (s->cmp == NULL |
2000 MacFontStruct *font = s->font; | 2000 && s->first_glyph->type == CHAR_GLYPH) |
2001 | 2001 { |
2002 TextFont (font->mac_fontnum); | 2002 Rect r; |
2003 TextSize (font->mac_fontsize); | 2003 MacFontStruct *font = s->font; |
2004 TextFace (font->mac_fontface); | 2004 |
2005 | 2005 TextFont (font->mac_fontnum); |
2006 if (s->two_byte_p) | 2006 TextSize (font->mac_fontsize); |
2007 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); | 2007 TextFace (font->mac_fontface); |
2008 else | 2008 |
2009 { | 2009 if (s->two_byte_p) |
2010 int i; | 2010 QDTextBounds (s->nchars * 2, (char *)s->char2b, &r); |
2011 char *buf = xmalloc (s->nchars); | |
2012 | |
2013 if (buf == NULL) | |
2014 SetRect (&r, 0, 0, 0, 0); | |
2015 else | 2011 else |
2016 { | 2012 { |
2017 for (i = 0; i < s->nchars; ++i) | 2013 int i; |
2018 buf[i] = s->char2b[i].byte2; | 2014 char *buf = xmalloc (s->nchars); |
2019 QDTextBounds (s->nchars, buf, &r); | 2015 |
2020 xfree (buf); | 2016 if (buf == NULL) |
2017 SetRect (&r, 0, 0, 0, 0); | |
2018 else | |
2019 { | |
2020 for (i = 0; i < s->nchars; ++i) | |
2021 buf[i] = s->char2b[i].byte2; | |
2022 QDTextBounds (s->nchars, buf, &r); | |
2023 xfree (buf); | |
2024 } | |
2021 } | 2025 } |
2022 } | 2026 |
2023 | 2027 s->right_overhang = r.right > s->width ? r.right - s->width : 0; |
2024 s->right_overhang = r.right > s->width ? r.right - s->width : 0; | 2028 s->left_overhang = r.left < 0 ? -r.left : 0; |
2025 s->left_overhang = r.left < 0 ? -r.left : 0; | 2029 } |
2026 } | 2030 } |
2027 | 2031 |
2028 | 2032 |
2029 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ | 2033 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ |
2030 | 2034 |
7467 Lisp_Object Vmac_pass_command_to_system; | 7471 Lisp_Object Vmac_pass_command_to_system; |
7468 | 7472 |
7469 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox | 7473 /* If Non-nil, the Mac "Control" key is passed on to the Mac Toolbox |
7470 for processing before Emacs sees it. */ | 7474 for processing before Emacs sees it. */ |
7471 Lisp_Object Vmac_pass_control_to_system; | 7475 Lisp_Object Vmac_pass_control_to_system; |
7476 | |
7477 /* Points to the variable `inev' in the function XTread_socket. It is | |
7478 used for passing an input event to the function back from a Carbon | |
7479 event handler. */ | |
7480 static struct input_event *read_socket_inev = NULL; | |
7472 #endif | 7481 #endif |
7473 | 7482 |
7474 /* Set in term/mac-win.el to indicate that event loop can now generate | 7483 /* Set in term/mac-win.el to indicate that event loop can now generate |
7475 drag and drop events. */ | 7484 drag and drop events. */ |
7476 Lisp_Object Qmac_ready_for_drag_n_drop; | 7485 Lisp_Object Qmac_ready_for_drag_n_drop; |
7599 } | 7608 } |
7600 } | 7609 } |
7601 | 7610 |
7602 /* Normally, ConvertEventRefToEventRecord will correctly handle all | 7611 /* Normally, ConvertEventRefToEventRecord will correctly handle all |
7603 events. However the click of the mouse wheel is not converted to a | 7612 events. However the click of the mouse wheel is not converted to a |
7604 mouseDown or mouseUp event. This calls ConvertEventRef, but then | 7613 mouseDown or mouseUp event. Likewise for dead key down events. |
7605 checks to see if it is a mouse up or down carbon event that has not | 7614 This calls ConvertEventRef, but then checks to see if it is a mouse |
7606 been converted, and if so, converts it by hand (to be picked up in | 7615 up/down, or a dead key down carbon event that has not been |
7607 the XTread_socket loop). */ | 7616 converted, and if so, converts it by hand (to be picked up in the |
7617 XTread_socket loop). */ | |
7608 static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) | 7618 static Boolean mac_convert_event_ref (EventRef eventRef, EventRecord *eventRec) |
7609 { | 7619 { |
7610 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec); | 7620 Boolean result = ConvertEventRefToEventRecord (eventRef, eventRec); |
7611 /* Do special case for mouse wheel button. */ | 7621 |
7612 if (!result && GetEventClass (eventRef) == kEventClassMouse) | 7622 if (result) |
7613 { | 7623 return result; |
7614 UInt32 kind = GetEventKind (eventRef); | 7624 |
7615 if (kind == kEventMouseDown && !(eventRec->what == mouseDown)) | 7625 switch (GetEventClass (eventRef)) |
7626 { | |
7627 case kEventClassMouse: | |
7628 switch (GetEventKind (eventRef)) | |
7616 { | 7629 { |
7630 case kEventMouseDown: | |
7617 eventRec->what = mouseDown; | 7631 eventRec->what = mouseDown; |
7618 result=1; | 7632 result = 1; |
7633 break; | |
7634 | |
7635 case kEventMouseUp: | |
7636 eventRec->what = mouseUp; | |
7637 result = 1; | |
7638 break; | |
7639 | |
7640 default: | |
7641 break; | |
7619 } | 7642 } |
7620 if (kind == kEventMouseUp && !(eventRec->what == mouseUp)) | 7643 |
7644 case kEventClassKeyboard: | |
7645 switch (GetEventKind (eventRef)) | |
7621 { | 7646 { |
7622 eventRec->what = mouseUp; | 7647 case kEventRawKeyDown: |
7623 result=1; | 7648 { |
7649 unsigned char char_codes; | |
7650 UInt32 key_code; | |
7651 | |
7652 eventRec->what = keyDown; | |
7653 GetEventParameter (eventRef, kEventParamKeyMacCharCodes, typeChar, | |
7654 NULL, sizeof (char), NULL, &char_codes); | |
7655 GetEventParameter (eventRef, kEventParamKeyCode, typeUInt32, | |
7656 NULL, sizeof (UInt32), NULL, &key_code); | |
7657 eventRec->message = char_codes | ((key_code & 0xff) << 8); | |
7658 result = 1; | |
7659 } | |
7660 break; | |
7661 | |
7662 default: | |
7663 break; | |
7624 } | 7664 } |
7625 if (result) | 7665 |
7626 { | 7666 default: |
7627 /* Need where and when. */ | 7667 break; |
7628 UInt32 mods; | 7668 } |
7629 GetEventParameter (eventRef, kEventParamMouseLocation, | 7669 |
7630 typeQDPoint, NULL, sizeof (Point), | 7670 if (result) |
7631 NULL, &eventRec->where); | 7671 { |
7632 /* Use two step process because new event modifiers are | 7672 /* Need where and when. */ |
7633 32-bit and old are 16-bit. Currently, only loss is | 7673 UInt32 mods; |
7634 NumLock & Fn. */ | 7674 |
7635 GetEventParameter (eventRef, kEventParamKeyModifiers, | 7675 GetEventParameter (eventRef, kEventParamMouseLocation, typeQDPoint, |
7636 typeUInt32, NULL, sizeof (UInt32), | 7676 NULL, sizeof (Point), NULL, &eventRec->where); |
7637 NULL, &mods); | 7677 /* Use two step process because new event modifiers are 32-bit |
7638 eventRec->modifiers = mods; | 7678 and old are 16-bit. Currently, only loss is NumLock & Fn. */ |
7639 | 7679 GetEventParameter (eventRef, kEventParamKeyModifiers, typeUInt32, |
7640 eventRec->when = EventTimeToTicks (GetEventTime (eventRef)); | 7680 NULL, sizeof (UInt32), NULL, &mods); |
7641 } | 7681 eventRec->modifiers = mods; |
7642 } | 7682 |
7683 eventRec->when = EventTimeToTicks (GetEventTime (eventRef)); | |
7684 } | |
7685 | |
7643 return result; | 7686 return result; |
7644 } | 7687 } |
7645 | 7688 |
7646 #endif | 7689 #endif |
7647 | 7690 |
8207 | 8250 |
8208 return eventNotHandledErr; | 8251 return eventNotHandledErr; |
8209 } | 8252 } |
8210 | 8253 |
8211 static OSErr | 8254 static OSErr |
8212 init_command_handler (window) | 8255 init_command_handler () |
8213 WindowPtr window; | |
8214 { | 8256 { |
8215 OSErr err = noErr; | 8257 OSErr err = noErr; |
8216 EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}}; | 8258 EventTypeSpec specs[] = {{kEventClassCommand, kEventCommandProcess}}; |
8217 static EventHandlerUPP handle_command_eventUPP = NULL; | 8259 static EventHandlerUPP handle_command_eventUPP = NULL; |
8218 | 8260 |
8293 break; | 8335 break; |
8294 } | 8336 } |
8295 | 8337 |
8296 return eventNotHandledErr; | 8338 return eventNotHandledErr; |
8297 } | 8339 } |
8340 | |
8341 static pascal OSStatus | |
8342 mac_handle_mouse_event (next_handler, event, data) | |
8343 EventHandlerCallRef next_handler; | |
8344 EventRef event; | |
8345 void *data; | |
8346 { | |
8347 OSStatus result; | |
8348 | |
8349 switch (GetEventKind (event)) | |
8350 { | |
8351 case kEventMouseWheelMoved: | |
8352 { | |
8353 WindowPtr wp; | |
8354 struct frame *f; | |
8355 EventMouseWheelAxis axis; | |
8356 SInt32 delta; | |
8357 Point point; | |
8358 | |
8359 result = CallNextEventHandler (next_handler, event); | |
8360 if (result != eventNotHandledErr || read_socket_inev == NULL) | |
8361 return result; | |
8362 | |
8363 GetEventParameter (event, kEventParamWindowRef, typeWindowRef, | |
8364 NULL, sizeof (WindowRef), NULL, &wp); | |
8365 f = mac_window_to_frame (wp); | |
8366 if (f != mac_focus_frame (&one_mac_display_info)) | |
8367 break; | |
8368 | |
8369 GetEventParameter (event, kEventParamMouseWheelAxis, | |
8370 typeMouseWheelAxis, NULL, | |
8371 sizeof (EventMouseWheelAxis), NULL, &axis); | |
8372 if (axis != kEventMouseWheelAxisY) | |
8373 break; | |
8374 | |
8375 GetEventParameter (event, kEventParamMouseWheelDelta, typeSInt32, | |
8376 NULL, sizeof (SInt32), NULL, &delta); | |
8377 GetEventParameter (event, kEventParamMouseLocation, typeQDPoint, | |
8378 NULL, sizeof (Point), NULL, &point); | |
8379 read_socket_inev->kind = WHEEL_EVENT; | |
8380 read_socket_inev->code = 0; | |
8381 read_socket_inev->modifiers = | |
8382 (mac_event_to_emacs_modifiers (event) | |
8383 | ((delta < 0) ? down_modifier : up_modifier)); | |
8384 SetPortWindowPort (wp); | |
8385 GlobalToLocal (&point); | |
8386 XSETINT (read_socket_inev->x, point.h); | |
8387 XSETINT (read_socket_inev->y, point.v); | |
8388 XSETFRAME (read_socket_inev->frame_or_window, f); | |
8389 read_socket_inev->timestamp = | |
8390 EventTimeToTicks (GetEventTime (event)) * (1000/60); | |
8391 | |
8392 return noErr; | |
8393 } | |
8394 break; | |
8395 | |
8396 default: | |
8397 break; | |
8398 } | |
8399 | |
8400 return eventNotHandledErr; | |
8401 } | |
8298 #endif /* USE_CARBON_EVENTS */ | 8402 #endif /* USE_CARBON_EVENTS */ |
8299 | 8403 |
8300 | 8404 |
8301 OSErr | 8405 OSErr |
8302 install_window_handler (window) | 8406 install_window_handler (window) |
8303 WindowPtr window; | 8407 WindowPtr window; |
8304 { | 8408 { |
8305 OSErr err = noErr; | 8409 OSErr err = noErr; |
8306 #if USE_CARBON_EVENTS | 8410 #if USE_CARBON_EVENTS |
8307 EventTypeSpec specs[] = {{kEventClassWindow, kEventWindowUpdate}, | 8411 EventTypeSpec specs_window[] = |
8308 {kEventClassWindow, kEventWindowBoundsChanging}}; | 8412 {{kEventClassWindow, kEventWindowUpdate}, |
8309 static EventHandlerUPP handle_window_event_UPP = NULL; | 8413 {kEventClassWindow, kEventWindowBoundsChanging}}; |
8310 | 8414 EventTypeSpec specs_mouse[] = {{kEventClassMouse, kEventMouseWheelMoved}}; |
8311 if (handle_window_event_UPP == NULL) | 8415 static EventHandlerUPP handle_window_eventUPP = NULL; |
8312 handle_window_event_UPP = NewEventHandlerUPP (mac_handle_window_event); | 8416 static EventHandlerUPP handle_mouse_eventUPP = NULL; |
8313 | 8417 |
8314 err = InstallWindowEventHandler (window, handle_window_event_UPP, | 8418 if (handle_window_eventUPP == NULL) |
8315 GetEventTypeCount (specs), specs, | 8419 handle_window_eventUPP = NewEventHandlerUPP (mac_handle_window_event); |
8316 NULL, NULL); | 8420 if (handle_mouse_eventUPP == NULL) |
8421 handle_mouse_eventUPP = NewEventHandlerUPP (mac_handle_mouse_event); | |
8422 err = InstallWindowEventHandler (window, handle_window_eventUPP, | |
8423 GetEventTypeCount (specs_window), | |
8424 specs_window, NULL, NULL); | |
8425 if (err == noErr) | |
8426 err = InstallWindowEventHandler (window, handle_mouse_eventUPP, | |
8427 GetEventTypeCount (specs_mouse), | |
8428 specs_mouse, NULL, NULL); | |
8317 #endif | 8429 #endif |
8318 #if TARGET_API_MAC_CARBON | 8430 #if TARGET_API_MAC_CARBON |
8319 if (mac_do_track_dragUPP == NULL) | 8431 if (mac_do_track_dragUPP == NULL) |
8320 mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag); | 8432 mac_do_track_dragUPP = NewDragTrackingHandlerUPP (mac_do_track_drag); |
8321 if (mac_do_receive_dragUPP == NULL) | 8433 if (mac_do_receive_dragUPP == NULL) |
8863 inev.arg = Qnil; | 8975 inev.arg = Qnil; |
8864 | 8976 |
8865 #if USE_CARBON_EVENTS | 8977 #if USE_CARBON_EVENTS |
8866 /* Handle new events */ | 8978 /* Handle new events */ |
8867 if (!mac_convert_event_ref (eventRef, &er)) | 8979 if (!mac_convert_event_ref (eventRef, &er)) |
8868 switch (GetEventClass (eventRef)) | 8980 { |
8869 { | 8981 /* There used to be a handler for the kEventMouseWheelMoved |
8870 case kEventClassWindow: | 8982 event here. But as of Mac OS X 10.4, this kind of event |
8871 if (GetEventKind (eventRef) == kEventWindowBoundsChanged) | 8983 is not directly posted to the main event queue by |
8872 { | 8984 two-finger scrolling on the trackpad. Instead, some |
8873 WindowPtr window_ptr; | 8985 private event is posted and it is converted to a wheel |
8874 GetEventParameter(eventRef, kEventParamDirectObject, | 8986 event by the default handler for the application target. |
8875 typeWindowRef, NULL, sizeof(WindowPtr), | 8987 The converted one can be received by a Carbon event |
8876 NULL, &window_ptr); | 8988 handler installed on a window target. */ |
8877 f = mac_window_to_frame (window_ptr); | 8989 read_socket_inev = &inev; |
8878 if (f && !f->async_iconified) | 8990 SendEventToEventTarget (eventRef, toolbox_dispatcher); |
8879 x_real_positions (f, &f->left_pos, &f->top_pos); | 8991 read_socket_inev = NULL; |
8880 SendEventToEventTarget (eventRef, toolbox_dispatcher); | 8992 } |
8881 } | |
8882 break; | |
8883 case kEventClassMouse: | |
8884 if (GetEventKind (eventRef) == kEventMouseWheelMoved) | |
8885 { | |
8886 SInt32 delta; | |
8887 Point point; | |
8888 struct frame *f = mac_focus_frame (dpyinfo); | |
8889 WindowPtr window_ptr; | |
8890 | |
8891 #if 0 | |
8892 if (dpyinfo->x_focus_frame == NULL) | |
8893 { | |
8894 /* Beep if wheel move occurs when all the frames | |
8895 are invisible. */ | |
8896 SysBeep(1); | |
8897 break; | |
8898 } | |
8899 #endif | |
8900 | |
8901 GetEventParameter(eventRef, kEventParamMouseWheelDelta, | |
8902 typeSInt32, NULL, sizeof (SInt32), | |
8903 NULL, &delta); | |
8904 GetEventParameter(eventRef, kEventParamMouseLocation, | |
8905 typeQDPoint, NULL, sizeof (Point), | |
8906 NULL, &point); | |
8907 inev.kind = WHEEL_EVENT; | |
8908 inev.code = 0; | |
8909 inev.modifiers = (mac_event_to_emacs_modifiers (eventRef) | |
8910 | ((delta < 0) ? down_modifier | |
8911 : up_modifier)); | |
8912 window_ptr = FRAME_MAC_WINDOW (f); | |
8913 SetPortWindowPort (window_ptr); | |
8914 GlobalToLocal (&point); | |
8915 XSETINT (inev.x, point.h); | |
8916 XSETINT (inev.y, point.v); | |
8917 XSETFRAME (inev.frame_or_window, | |
8918 mac_window_to_frame (window_ptr)); | |
8919 inev.timestamp = EventTimeToTicks (GetEventTime (eventRef))*(1000/60); | |
8920 } | |
8921 else | |
8922 SendEventToEventTarget (eventRef, toolbox_dispatcher); | |
8923 | |
8924 break; | |
8925 | |
8926 default: | |
8927 /* Send the event to the appropriate receiver. */ | |
8928 SendEventToEventTarget (eventRef, toolbox_dispatcher); | |
8929 } | |
8930 else | 8993 else |
8931 #endif /* USE_CARBON_EVENTS */ | 8994 #endif /* USE_CARBON_EVENTS */ |
8932 switch (er.what) | 8995 switch (er.what) |
8933 { | 8996 { |
8934 case mouseDown: | 8997 case mouseDown: |
9360 "eventNotHandledErr" and we can process it | 9423 "eventNotHandledErr" and we can process it |
9361 normally. */ | 9424 normally. */ |
9362 if ((!NILP (Vmac_pass_command_to_system) | 9425 if ((!NILP (Vmac_pass_command_to_system) |
9363 || !(er.modifiers & cmdKey)) | 9426 || !(er.modifiers & cmdKey)) |
9364 && (!NILP (Vmac_pass_control_to_system) | 9427 && (!NILP (Vmac_pass_control_to_system) |
9365 || !(er.modifiers & controlKey))) | 9428 || !(er.modifiers & controlKey)) |
9429 && (!NILP (Vmac_command_key_is_meta) | |
9430 && NILP (Vmac_option_modifier) | |
9431 || !(er.modifiers & optionKey))) | |
9366 if (SendEventToEventTarget (eventRef, toolbox_dispatcher) | 9432 if (SendEventToEventTarget (eventRef, toolbox_dispatcher) |
9367 != eventNotHandledErr) | 9433 != eventNotHandledErr) |
9368 break; | 9434 break; |
9369 #endif | 9435 #endif |
9370 | 9436 |