Mercurial > emacs
comparison src/keyboard.c @ 10844:06d6b2e17987
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 26 Feb 1995 22:31:45 +0000 |
parents | 4dfd3634b155 |
children | 655e3daa560c |
comparison
equal
deleted
inserted
replaced
10843:2f2e5033b3bb | 10844:06d6b2e17987 |
---|---|
1427 /* Start a new alarm with the new period. */ | 1427 /* Start a new alarm with the new period. */ |
1428 start_polling (); | 1428 start_polling (); |
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; |
1436 { | 1437 { |
1437 /* Save the upper bits here. */ | 1438 /* Save the upper bits here. */ |
3159 | 3160 |
3160 If MODIFIER_END is non-zero, set *MODIFIER_END to the position in | 3161 If MODIFIER_END is non-zero, set *MODIFIER_END to the position in |
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; |
3168 int *modifier_end; | 3173 int *modifier_end; |
3169 { | 3174 { |
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] != '-') \ | 3189 |
3185 goto no_more_modifiers; \ | 3190 /* See if the name continues with a modifier word. |
3186 modifiers |= bit; \ | 3191 Check that the word appears, but don't check what follows it. |
3187 i += 2; | 3192 Set this_mod and this_mod_end to record what we find. */ |
3188 | 3193 |
3189 case 'A': | 3194 switch (name->data[i]) |
3190 SINGLE_LETTER_MOD (alt_modifier); | 3195 { |
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 } | |
3207 | |
3208 case 'A': | |
3209 SINGLE_LETTER_MOD (alt_modifier); | |
3210 break; | |
3211 | |
3212 case 'a': | |
3213 MULTI_LETTER_MOD (alt_modifier, "alt", 3); | |
3214 break; | |
3215 | |
3216 case 'C': | |
3217 SINGLE_LETTER_MOD (ctrl_modifier); | |
3218 break; | |
3219 | |
3220 case 'c': | |
3221 MULTI_LETTER_MOD (ctrl_modifier, "ctrl", 4); | |
3222 MULTI_LETTER_MOD (ctrl_modifier, "control", 7); | |
3223 break; | |
3224 | |
3225 case 'H': | |
3226 SINGLE_LETTER_MOD (hyper_modifier); | |
3227 break; | |
3228 | |
3229 case 'h': | |
3230 MULTI_LETTER_MOD (hyper_modifier, "hyper", 5); | |
3231 break; | |
3232 | |
3233 case 'M': | |
3234 SINGLE_LETTER_MOD (meta_modifier); | |
3235 break; | |
3236 | |
3237 case 'm': | |
3238 MULTI_LETTER_MOD (meta_modifier, "meta", 4); | |
3239 break; | |
3240 | |
3241 case 'S': | |
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; | |
3260 | |
3261 #undef SINGLE_LETTER_MOD | |
3262 #undef MULTI_LETTER_MOD | |
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) | |
3191 break; | 3278 break; |
3192 | 3279 |
3193 case 'C': | 3280 /* Check there is a dash after the modifier, so that it |
3194 SINGLE_LETTER_MOD (ctrl_modifier); | 3281 really is a modifier. */ |
3282 if (this_mod_end >= name->size || name->data[this_mod_end] != '-') | |
3195 break; | 3283 break; |
3196 | 3284 |
3197 case 'H': | 3285 /* This modifier is real; look for another. */ |
3198 SINGLE_LETTER_MOD (hyper_modifier); | 3286 modifiers |= this_mod; |
3199 break; | 3287 i = this_mod_end + 1; |
3200 | 3288 } |
3201 case 'M': | |
3202 SINGLE_LETTER_MOD (meta_modifier); | |
3203 break; | |
3204 | |
3205 case 'S': | |
3206 SINGLE_LETTER_MOD (shift_modifier); | |
3207 break; | |
3208 | |
3209 case 's': | |
3210 SINGLE_LETTER_MOD (super_modifier); | |
3211 break; | |
3212 | |
3213 case 'd': | |
3214 if (i + 5 > name->size) | |
3215 goto no_more_modifiers; | |
3216 if (! strncmp (name->data + i, "drag-", 5)) | |
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 | |
3236 case 't': | |
3237 if (i + 7 > name->size) | |
3238 goto no_more_modifiers; | |
3239 if (! strncmp (name->data + i, "triple-", 7)) | |
3240 { | |
3241 modifiers |= triple_modifier; | |
3242 i += 7; | |
3243 } | |
3244 else | |
3245 goto no_more_modifiers; | |
3246 break; | |
3247 | |
3248 default: | |
3249 goto no_more_modifiers; | |
3250 | |
3251 #undef SINGLE_LETTER_MOD | |
3252 } | |
3253 no_more_modifiers: | |
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 |
3257 | double_modifier | triple_modifier)) | 3292 | double_modifier | triple_modifier)) |
3258 && i + 7 == name->size | 3293 && i + 7 == name->size |
3263 if (modifier_end) | 3298 if (modifier_end) |
3264 *modifier_end = i; | 3299 *modifier_end = i; |
3265 | 3300 |
3266 return modifiers; | 3301 return modifiers; |
3267 } | 3302 } |
3268 | |
3269 | 3303 |
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. */ |
3273 static Lisp_Object | 3307 static Lisp_Object |
3580 } | 3614 } |
3581 | 3615 |
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. |
3588 Serves the purpose of ioctl (0, FIONREAD, addr) | 3695 Serves the purpose of ioctl (0, FIONREAD, addr) |
3589 but works even if FIONREAD does not exist. | 3696 but works even if FIONREAD does not exist. |