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.