diff options
| author | Richard M. Stallman | 1995-02-26 22:31:45 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-02-26 22:31:45 +0000 |
| commit | 6da3dd3a4e1f89eb36a297938ede51e4286e1b70 (patch) | |
| tree | 51de984848cfe13447119117d9164a6a29afc1d3 /src | |
| parent | 30712209665207de3053913ec34b1353b2f884a9 (diff) | |
| download | emacs-6da3dd3a4e1f89eb36a297938ede51e4286e1b70.tar.gz emacs-6da3dd3a4e1f89eb36a297938ede51e4286e1b70.zip | |
(convert_event_type_list): New function.
(lucid_event_type_list_p): New function.
(parse_modifiers_uncached): If MODIFIERS_END is -1,
look for just a modifier. Guts rewritten.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 239 |
1 files changed, 173 insertions, 66 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index c2f8d88553b..c85cffa8783 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1429,7 +1429,8 @@ bind_polling_period (n) | |||
| 1429 | #endif | 1429 | #endif |
| 1430 | } | 1430 | } |
| 1431 | 1431 | ||
| 1432 | /* Applying the control modifier to CHARACTER. */ | 1432 | /* Apply the control modifier to CHARACTER. */ |
| 1433 | |||
| 1433 | int | 1434 | int |
| 1434 | make_ctrl_char (c) | 1435 | make_ctrl_char (c) |
| 1435 | int c; | 1436 | int c; |
| @@ -3161,7 +3162,11 @@ make_lispy_switch_frame (frame) | |||
| 3161 | SYMBOL's name of the end of the modifiers; the string from this | 3162 | SYMBOL's name of the end of the modifiers; the string from this |
| 3162 | position is the unmodified symbol name. | 3163 | position is the unmodified symbol name. |
| 3163 | 3164 | ||
| 3165 | If MODIFIER_END is -1, parse *only* a modifier; expect | ||
| 3166 | the symbol name to be just one modifier, with no dash. | ||
| 3167 | |||
| 3164 | This doesn't use any caches. */ | 3168 | This doesn't use any caches. */ |
| 3169 | |||
| 3165 | static int | 3170 | static int |
| 3166 | parse_modifiers_uncached (symbol, modifier_end) | 3171 | parse_modifiers_uncached (symbol, modifier_end) |
| 3167 | Lisp_Object symbol; | 3172 | Lisp_Object symbol; |
| @@ -3170,87 +3175,117 @@ parse_modifiers_uncached (symbol, modifier_end) | |||
| 3170 | struct Lisp_String *name; | 3175 | struct Lisp_String *name; |
| 3171 | int i; | 3176 | int i; |
| 3172 | int modifiers; | 3177 | int modifiers; |
| 3178 | int just_one = ((int *) (-1) == modifier_end); | ||
| 3173 | 3179 | ||
| 3174 | CHECK_SYMBOL (symbol, 1); | 3180 | CHECK_SYMBOL (symbol, 1); |
| 3175 | 3181 | ||
| 3176 | modifiers = 0; | 3182 | modifiers = 0; |
| 3177 | name = XSYMBOL (symbol)->name; | 3183 | name = XSYMBOL (symbol)->name; |
| 3178 | 3184 | ||
| 3179 | |||
| 3180 | for (i = 0; i+2 <= name->size; ) | 3185 | for (i = 0; i+2 <= name->size; ) |
| 3181 | switch (name->data[i]) | 3186 | { |
| 3182 | { | 3187 | int this_mod_end = 0; |
| 3183 | #define SINGLE_LETTER_MOD(bit) \ | 3188 | int this_mod = 0; |
| 3184 | if (name->data[i+1] != '-') \ | ||
| 3185 | goto no_more_modifiers; \ | ||
| 3186 | modifiers |= bit; \ | ||
| 3187 | i += 2; | ||
| 3188 | |||
| 3189 | case 'A': | ||
| 3190 | SINGLE_LETTER_MOD (alt_modifier); | ||
| 3191 | break; | ||
| 3192 | 3189 | ||
| 3193 | case 'C': | 3190 | /* See if the name continues with a modifier word. |
| 3194 | SINGLE_LETTER_MOD (ctrl_modifier); | 3191 | Check that the word appears, but don't check what follows it. |
| 3195 | break; | 3192 | Set this_mod and this_mod_end to record what we find. */ |
| 3196 | 3193 | ||
| 3197 | case 'H': | 3194 | switch (name->data[i]) |
| 3198 | SINGLE_LETTER_MOD (hyper_modifier); | 3195 | { |
| 3199 | break; | 3196 | #define SINGLE_LETTER_MOD(BIT) \ |
| 3197 | (this_mod_end = i + 1, this_mod = BIT) | ||
| 3198 | |||
| 3199 | #define MULTI_LETTER_MOD(BIT, NAME, LEN) \ | ||
| 3200 | if (i + LEN <= name->size \ | ||
| 3201 | && ! strncmp (name->data + i, NAME, LEN)) \ | ||
| 3202 | { \ | ||
| 3203 | this_mod_end = i + LEN; \ | ||
| 3204 | this_mod = BIT; \ | ||
| 3205 | break; \ | ||
| 3206 | } | ||
| 3200 | 3207 | ||
| 3201 | case 'M': | 3208 | case 'A': |
| 3202 | SINGLE_LETTER_MOD (meta_modifier); | 3209 | SINGLE_LETTER_MOD (alt_modifier); |
| 3203 | break; | 3210 | break; |
| 3204 | 3211 | ||
| 3205 | case 'S': | 3212 | case 'a': |
| 3206 | SINGLE_LETTER_MOD (shift_modifier); | 3213 | MULTI_LETTER_MOD (alt_modifier, "alt", 3); |
| 3207 | break; | 3214 | break; |
| 3208 | 3215 | ||
| 3209 | case 's': | 3216 | case 'C': |
| 3210 | SINGLE_LETTER_MOD (super_modifier); | 3217 | SINGLE_LETTER_MOD (ctrl_modifier); |
| 3211 | break; | 3218 | break; |
| 3212 | 3219 | ||
| 3213 | case 'd': | 3220 | case 'c': |
| 3214 | if (i + 5 > name->size) | 3221 | MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4); |
| 3215 | goto no_more_modifiers; | 3222 | MULTI_LETTER_MOD (ctrl_modifier, "control", 7); |
| 3216 | if (! strncmp (name->data + i, "drag-", 5)) | 3223 | break; |
| 3217 | { | ||
| 3218 | modifiers |= drag_modifier; | ||
| 3219 | i += 5; | ||
| 3220 | } | ||
| 3221 | else if (! strncmp (name->data + i, "down-", 5)) | ||
| 3222 | { | ||
| 3223 | modifiers |= down_modifier; | ||
| 3224 | i += 5; | ||
| 3225 | } | ||
| 3226 | else if (i + 7 <= name->size | ||
| 3227 | && ! strncmp (name->data + i, "double-", 7)) | ||
| 3228 | { | ||
| 3229 | modifiers |= double_modifier; | ||
| 3230 | i += 7; | ||
| 3231 | } | ||
| 3232 | else | ||
| 3233 | goto no_more_modifiers; | ||
| 3234 | break; | ||
| 3235 | 3224 | ||
| 3236 | case 't': | 3225 | case 'H': |
| 3237 | if (i + 7 > name->size) | 3226 | SINGLE_LETTER_MOD (hyper_modifier); |
| 3238 | goto no_more_modifiers; | 3227 | break; |
| 3239 | if (! strncmp (name->data + i, "triple-", 7)) | 3228 | |
| 3240 | { | 3229 | case 'h': |
| 3241 | modifiers |= triple_modifier; | 3230 | MULTI_LETTER_MOD (hyper_modifier, "hyper", 5); |
| 3242 | i += 7; | 3231 | break; |
| 3243 | } | 3232 | |
| 3244 | else | 3233 | case 'M': |
| 3245 | goto no_more_modifiers; | 3234 | SINGLE_LETTER_MOD (meta_modifier); |
| 3246 | break; | 3235 | break; |
| 3236 | |||
| 3237 | case 'm': | ||
| 3238 | MULTI_LETTER_MOD (meta_modifier, "meta", 4); | ||
| 3239 | break; | ||
| 3247 | 3240 | ||
| 3248 | default: | 3241 | case 'S': |
| 3249 | goto no_more_modifiers; | 3242 | SINGLE_LETTER_MOD (shift_modifier); |
| 3243 | break; | ||
| 3244 | |||
| 3245 | case 's': | ||
| 3246 | MULTI_LETTER_MOD (shift_modifier, "shift", 5); | ||
| 3247 | MULTI_LETTER_MOD (super_modifier, "super", 5); | ||
| 3248 | SINGLE_LETTER_MOD (super_modifier); | ||
| 3249 | break; | ||
| 3250 | |||
| 3251 | case 'd': | ||
| 3252 | MULTI_LETTER_MOD (drag_modifier, "drag", 4); | ||
| 3253 | MULTI_LETTER_MOD (down_modifier, "down", 4); | ||
| 3254 | MULTI_LETTER_MOD (double_modifier, "double", 6); | ||
| 3255 | break; | ||
| 3256 | |||
| 3257 | case 't': | ||
| 3258 | MULTI_LETTER_MOD (triple_modifier, "triple", 6); | ||
| 3259 | break; | ||
| 3250 | 3260 | ||
| 3251 | #undef SINGLE_LETTER_MOD | 3261 | #undef SINGLE_LETTER_MOD |
| 3252 | } | 3262 | #undef MULTI_LETTER_MOD |
| 3253 | no_more_modifiers: | 3263 | } |
| 3264 | |||
| 3265 | /* If we are looking for just a modifier, return now. | ||
| 3266 | Return 0 if we didn't find one; return the | ||
| 3267 | modifier bit if we did find one. */ | ||
| 3268 | if (just_one) | ||
| 3269 | { | ||
| 3270 | if (this_mod_end == name->size) | ||
| 3271 | return this_mod; | ||
| 3272 | else | ||
| 3273 | return 0; | ||
| 3274 | } | ||
| 3275 | |||
| 3276 | /* If we found no modifier, stop looking for them. */ | ||
| 3277 | if (this_mod_end == 0) | ||
| 3278 | break; | ||
| 3279 | |||
| 3280 | /* Check there is a dash after the modifier, so that it | ||
| 3281 | really is a modifier. */ | ||
| 3282 | if (this_mod_end >= name->size || name->data[this_mod_end] != '-') | ||
| 3283 | break; | ||
| 3284 | |||
| 3285 | /* This modifier is real; look for another. */ | ||
| 3286 | modifiers |= this_mod; | ||
| 3287 | i = this_mod_end + 1; | ||
| 3288 | } | ||
| 3254 | 3289 | ||
| 3255 | /* Should we include the `click' modifier? */ | 3290 | /* Should we include the `click' modifier? */ |
| 3256 | if (! (modifiers & (down_modifier | drag_modifier | 3291 | if (! (modifiers & (down_modifier | drag_modifier |
| @@ -3266,7 +3301,6 @@ parse_modifiers_uncached (symbol, modifier_end) | |||
| 3266 | return modifiers; | 3301 | return modifiers; |
| 3267 | } | 3302 | } |
| 3268 | 3303 | ||
| 3269 | |||
| 3270 | /* Return a symbol whose name is the modifier prefixes for MODIFIERS | 3304 | /* Return a symbol whose name is the modifier prefixes for MODIFIERS |
| 3271 | prepended to the string BASE[0..BASE_LEN-1]. | 3305 | prepended to the string BASE[0..BASE_LEN-1]. |
| 3272 | This doesn't use any caches. */ | 3306 | This doesn't use any caches. */ |
| @@ -3582,6 +3616,79 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_alist, | |||
| 3582 | /* Apply modifiers to that symbol. */ | 3616 | /* Apply modifiers to that symbol. */ |
| 3583 | return apply_modifiers (modifiers, value); | 3617 | return apply_modifiers (modifiers, value); |
| 3584 | } | 3618 | } |
| 3619 | |||
| 3620 | /* Convert a list that represents an event type, | ||
| 3621 | such as (ctrl meta backspace), into the usual representation of that | ||
| 3622 | event type as a number or a symbol. */ | ||
| 3623 | |||
| 3624 | Lisp_Object | ||
| 3625 | convert_event_type_list (event) | ||
| 3626 | Lisp_Object event; | ||
| 3627 | { | ||
| 3628 | Lisp_Object base; | ||
| 3629 | int modifiers = 0; | ||
| 3630 | Lisp_Object rest; | ||
| 3631 | |||
| 3632 | base = Qnil; | ||
| 3633 | rest = event; | ||
| 3634 | while (CONSP (rest)) | ||
| 3635 | { | ||
| 3636 | Lisp_Object elt; | ||
| 3637 | int this = 0; | ||
| 3638 | |||
| 3639 | elt = XCONS (rest)->car; | ||
| 3640 | |||
| 3641 | if (SYMBOLP (elt)) | ||
| 3642 | this = parse_modifiers_uncached (elt, -1); | ||
| 3643 | |||
| 3644 | if (this != 0) | ||
| 3645 | modifiers |= this; | ||
| 3646 | else if (!NILP (base)) | ||
| 3647 | error ("Two bases given in one event"); | ||
| 3648 | else | ||
| 3649 | base = elt; | ||
| 3650 | |||
| 3651 | rest = XCONS (rest)->cdr; | ||
| 3652 | } | ||
| 3653 | |||
| 3654 | if (INTEGERP (base)) | ||
| 3655 | { | ||
| 3656 | if (modifiers & ctrl_modifier) | ||
| 3657 | return make_number ((modifiers & ~ ctrl_modifier) | ||
| 3658 | | make_ctrl_char (XINT (base))); | ||
| 3659 | else | ||
| 3660 | return make_number (modifiers | XINT (base)); | ||
| 3661 | } | ||
| 3662 | else if (SYMBOLP (base)) | ||
| 3663 | return apply_modifiers (modifiers, base); | ||
| 3664 | else | ||
| 3665 | error ("Invalid base event"); | ||
| 3666 | } | ||
| 3667 | |||
| 3668 | /* Return 1 if EVENT is a list whose elements are all integers or symbols. | ||
| 3669 | Such a list is not valid as an event, | ||
| 3670 | but it can be a Lucid-style event type list. */ | ||
| 3671 | |||
| 3672 | int | ||
| 3673 | lucid_event_type_list_p (object) | ||
| 3674 | Lisp_Object object; | ||
| 3675 | { | ||
| 3676 | Lisp_Object tail; | ||
| 3677 | |||
| 3678 | if (! CONSP (object)) | ||
| 3679 | return 0; | ||
| 3680 | |||
| 3681 | for (tail = object; CONSP (tail); tail = XCONS (tail)->cdr) | ||
| 3682 | { | ||
| 3683 | Lisp_Object elt; | ||
| 3684 | elt = XCONS (tail)->car; | ||
| 3685 | if (! (INTEGERP (elt) || SYMBOLP (elt))) | ||
| 3686 | return 0; | ||
| 3687 | } | ||
| 3688 | |||
| 3689 | return NILP (tail); | ||
| 3690 | } | ||
| 3691 | |||
| 3585 | 3692 | ||
| 3586 | 3693 | ||
| 3587 | /* Store into *addr a value nonzero if terminal input chars are available. | 3694 | /* Store into *addr a value nonzero if terminal input chars are available. |