Mercurial > hg > xemacs-beta
diff src/events.c @ 189:489f57a838ef r20-3b21
Import from CVS: tag r20-3b21
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:57:07 +0200 |
parents | 3d6bfa290dbd |
children | a2f645c6b9f8 |
line wrap: on
line diff
--- a/src/events.c Mon Aug 13 09:56:30 2007 +0200 +++ b/src/events.c Mon Aug 13 09:57:07 2007 +0200 @@ -353,20 +353,25 @@ } -/* #### This should accept a type and props (as returned by - event-properties) to allow creation of any type of event. - This is useful, for example, in Lisp code that might want - to determine if, for a given button-down event, what the - binding for the corresponding button-up event is. */ +DEFUN ("make-event", Fmake_event, 0, 2, 0, /* +Create a new event of type TYPE, with properties stored in PLIST. +TYPE is a symbol, either `empty', `key-press', `button-press', + `button-release', or `motion'. If TYPE is left out, it defaults to + `empty'. +PLIST is a list of properties, as returned by `event-properties'. Not + all properties are allowed for all kinds of events, and some are + required. -DEFUN ("make-event", Fmake_event, 0, 0, 0, /* -Create a new empty event. WARNING, the event object returned may be a reused one; see the function -`deallocate-event'. + `deallocate-event'. */ - ()) + (type, plist)) { - Lisp_Object event; + Lisp_Object event, prop, val; + struct Lisp_Event *e; + + if (NILP (type)) + type = Qempty; if (!NILP (Vevent_resource)) { @@ -377,7 +382,131 @@ { event = allocate_event (); } - zero_event (XEVENT (event)); + e = XEVENT (event); + zero_event (e); + + if (EQ (type, Qkey_press)) + e->event_type = key_press_event; + else if (EQ (type, Qbutton_press)) + e->event_type = button_press_event; + else if (EQ (type, Qbutton_release)) + e->event_type = button_release_event; + else if (EQ (type, Qmotion)) + e->event_type = pointer_motion_event; + else if (EQ (type, Qempty)) + e->event_type = empty_event; + else + /* not allowed: Qmisc_user, Qprocess, Qtimeout, Qmagic, Qmagic_eval */ + signal_simple_error ("Invalid event type", type); + + /* Process the plist. */ + while (!NILP (plist)) + { + prop = Fcar (plist); + plist = Fcdr (plist); + val = Fcar (plist); + plist = Fcdr (plist); + if (EQ (prop, Qchannel)) + { + if (!DEVICEP (val) && !CONSOLEP (val) && !FRAMEP (val) + && !NILP (val)) + signal_simple_error ("Invalid event channel", val); + EVENT_CHANNEL (e) = val; + } + else if (EQ (prop, Qkey)) + { + if (e->event_type != key_press_event) + wrong_type_argument (Qkey_press_event_p, event); + if (!SYMBOLP (val) && !CHARP (val)) + signal_simple_error ("Invalid event key", val); + e->event.key.keysym = val; + } + else if (EQ (prop, Qbutton)) + { + CHECK_NATNUM (val); + check_int_range (XINT(val), 1, 3); + if (e->event_type != button_press_event + && e->event_type != button_release_event) + signal_simple_error ("Invalid event type for `button' property", + type); + e->event.button.button = XINT (val); + } + else if (EQ (prop, Qmodifiers)) + { + Lisp_Object tail, sym; + int modifiers = 0; + + if (e->event_type != key_press_event + && e->event_type != button_press_event + && e->event_type != button_release_event + && e->event_type != pointer_motion_event) + signal_simple_error ("Invalid event type for modifiers", type); + + for (tail = val; !NILP (tail); tail = Fcdr (tail)) + { + sym = Fcar (tail); + if (EQ (sym, Qcontrol)) modifiers |= MOD_CONTROL; + else if (EQ (sym, Qmeta)) modifiers |= MOD_META; + else if (EQ (sym, Qsuper)) modifiers |= MOD_SUPER; + else if (EQ (sym, Qhyper)) modifiers |= MOD_HYPER; + else if (EQ (sym, Qalt)) modifiers |= MOD_ALT; + else if (EQ (sym, Qsymbol)) modifiers |= MOD_ALT; + else if (EQ (sym, Qshift)) modifiers |= MOD_SHIFT; + else + signal_simple_error ("Invalid key modifier", Fcar (tail)); + } + if (e->event_type == key_press_event) + e->event.key.modifiers = modifiers; + else if (e->event_type == button_press_event + || e->event_type == button_release_event) + e->event.button.modifiers = modifiers; + else /* pointer_motion_event */ + e->event.motion.modifiers = modifiers; + } + else if (EQ (prop, Qx)) + { + CHECK_NATNUM (val); + if (e->event_type == pointer_motion_event) + e->event.motion.x = XINT (val); + else if (e->event_type == button_press_event + || e->event_type == button_release_event) + e->event.button.x = XINT (val); + } + else if (EQ (prop, Qy)) + { + CHECK_NATNUM (val); + if (e->event_type == pointer_motion_event) + e->event.motion.y = XINT (val); + else if (e->event_type == button_press_event + || e->event_type == button_release_event) + e->event.button.y = XINT (val); + } + else if (EQ (prop, Qtimestamp)) + { + CHECK_NATNUM (val); + e->timestamp = XINT (val); + } + else + signal_simple_error ("Invalid property", prop); + } /* while */ + + /* Now, let's validate what we got. */ + switch (e->event_type) + { + case key_press_event: + if (!(SYMBOLP (e->event.key.keysym) || CHARP (e->event.key.keysym))) + error ("Undefined key for keypress event"); + break; + case button_press_event: + case button_release_event: + if (!e->event.button.button) + error ("Undefined button for button-press or button-release event"); + if (NILP (EVENT_CHANNEL (e))) + error ("Undefined channel for button-press or button-release event"); + break; + default: + break; + } return event; } @@ -444,7 +573,7 @@ { CHECK_LIVE_EVENT (event1); if (NILP (event2)) - event2 = Fmake_event (); + event2 = Fmake_event (Qnil, Qnil); else CHECK_LIVE_EVENT (event2); if (EQ (event1, event2)) return signal_simple_continuable_error_2 @@ -828,7 +957,7 @@ { struct console *con = decode_console (console); if (NILP (event)) - event = Fmake_event (); + event = Fmake_event (Qnil, Qnil); else CHECK_LIVE_EVENT (event); if (CONSP (ch) || SYMBOLP (ch)) @@ -872,7 +1001,7 @@ for (i = 0; i < len; i++) { - Lisp_Object event = Fmake_event (); + Lisp_Object event = Fmake_event (Qnil, Qnil); nth_of_key_sequence_as_event (seq, i, event); enqueue_event (event, &head, &tail); }