1 /*--------------------------------------------------------------*/
2 /* keybindings.c: List of key bindings */
3 /* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */
4 /*--------------------------------------------------------------*/
6 /*----------------------------------------------------------------------*/
7 /* written by Tim Edwards, 2/27/01 */
8 /*----------------------------------------------------------------------*/
13 #include <ctype.h> /* for tolower(), toupper() */
17 #include <X11/Intrinsic.h>
18 #include <X11/StringDefs.h>
21 #if !defined(XC_WIN32) || defined(TCL_WRAPPER)
25 #include <X11/keysymdef.h>
28 /*----------------------------------------------------------------------*/
30 /*----------------------------------------------------------------------*/
38 /*----------------------------------------------------------------------*/
39 /* Function prototypes */
40 /*----------------------------------------------------------------------*/
42 #include "prototypes.h"
44 /*----------------------------------------------------------------------*/
45 /* Global variables */
46 /*----------------------------------------------------------------------*/
48 keybinding
*keylist
= NULL
;
51 extern char _STR
[150], _STR2
[250];
53 extern XCWindowData
*areawin
;
55 /*----------------------------------------------------------------------*/
56 /* Key modifiers (convenience definitions) */
57 /* Use Mod5Mask for a "hold" ("press") definition. */
58 /* Why Mod5Mask? Mod2Mask is used by fvwm2 for some obscure purpose, */
59 /* so I went to the other end (Mod5Mask is just below Button1Mask). */
60 /* Thanks to John Heil for reporting the problem and confirming the */
61 /* Mod5Mask solution. */
62 /*----------------------------------------------------------------------*/
64 #define ALT (Mod1Mask << 16)
65 #define CTRL (ControlMask << 16)
66 #define CAPSLOCK (LockMask << 16)
67 #define SHIFT (ShiftMask << 16)
68 #define BUTTON1 (Button1Mask << 16)
69 #define BUTTON2 (Button2Mask << 16)
70 #define BUTTON3 (Button3Mask << 16)
71 #define BUTTON4 (Button4Mask << 16)
72 #define BUTTON5 (Button5Mask << 16)
73 #define HOLD (Mod4Mask << 16)
75 #define ALL_WINDOWS (xcWidget)NULL
77 /*--------------------------------------------------------------*/
78 /* This list declares all the functions which can be bound to */
79 /* keys. It must match the order of the enumeration listed in */
81 /*--------------------------------------------------------------*/
83 static char *function_names
[NUM_FUNCTIONS
+ 1] = {
84 "Page", "Anchor", "Superscript", "Subscript", "Normalscript",
85 "Nextfont", "Boldfont", "Italicfont", "Normalfont", "Underline",
86 "Overline", "ISO Encoding", "Halfspace", "Quarterspace",
87 "Special", "Tab Stop", "Tab Forward", "Tab Backward",
88 "Text Return", "Text Delete", "Text Right", "Text Left",
89 "Text Up", "Text Down", "Text Split",
90 "Text Home", "Text End", "Linebreak", "Parameter",
91 "Parameterize Point", "Change Style", "Delete Point", "Insert Point",
92 "Append Point", "Next Point", "Attach", "Next Library", "Library Directory",
93 "Library Move", "Library Copy", "Library Edit", "Library Delete",
94 "Library Duplicate", "Library Hide", "Library Virtual Copy",
95 "Page Directory", "Library Pop", "Virtual Copy",
96 "Help", "Redraw", "View", "Zoom In", "Zoom Out", "Pan",
97 "Double Snap", "Halve Snap", "Write", "Rotate", "Flip X",
98 "Flip Y", "Snap", "Snap To",
99 "Pop", "Push", "Delete", "Select", "Box", "Arc", "Text",
100 "Exchange", "Copy", "Move", "Join", "Unjoin", "Spline", "Edit",
101 "Undo", "Redo", "Select Save", "Unselect", "Dashed", "Dotted",
102 "Solid", "Prompt", "Dot", "Wire", "Cancel", "Nothing", "Exit",
103 "Netlist", "Swap", "Pin Label", "Pin Global", "Info Label", "Graphic",
104 "Select Box", "Connectivity", "Continue Element", "Finish Element",
105 "Continue Copy", "Finish Copy", "Finish", "Cancel Last", "Sim",
106 "SPICE", "PCB", "SPICE Flat", "Rescale", "Reorder", "Color",
107 "Margin Stop", "Text Delete Param",
111 /*--------------------------------------------------------------*/
112 /* Return TRUE if the indicated key (keysym + bit-shifted state)*/
113 /* is bound to some function. */
114 /*--------------------------------------------------------------*/
116 Boolean
ismacro(xcWidget window
, int keywstate
)
120 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
)
121 if (ksearch
->window
== ALL_WINDOWS
|| ksearch
->window
== window
)
122 if (keywstate
== ksearch
->keywstate
)
128 /*--------------------------------------------------------------*/
129 /* Return the first key binding for the indicated function */
130 /*--------------------------------------------------------------*/
132 int firstbinding(xcWidget window
, int function
)
137 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
) {
138 if (ksearch
->function
== function
) {
139 if (ksearch
->window
== window
)
140 return ksearch
->keywstate
;
141 else if (ksearch
->window
== ALL_WINDOWS
)
142 keywstate
= ksearch
->keywstate
;
148 /*--------------------------------------------------------------*/
149 /* Find the first function bound to the indicated key that is */
150 /* compatible with the current state (eventmode). Window- */
151 /* specific bindings shadow ALL_WINDOWS bindings. Return the */
152 /* function number if found, or -1 if no compatible functions */
153 /* are bound to the key state. */
154 /*--------------------------------------------------------------*/
156 int boundfunction(xcWidget window
, int keywstate
, short *retnum
)
161 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
) {
162 if (keywstate
== ksearch
->keywstate
) {
163 if (compatible_function(ksearch
->function
)) {
164 if (ksearch
->window
== window
) {
165 if (retnum
!= NULL
) *retnum
= (ksearch
->value
);
166 return ksearch
->function
;
168 else if (ksearch
->window
== ALL_WINDOWS
) {
169 if (retnum
!= NULL
) *retnum
= (ksearch
->value
);
170 tempfunc
= ksearch
->function
;
178 /*--------------------------------------------------------------*/
179 /* Check if an entry exists for a given key-function pair */
180 /*--------------------------------------------------------------*/
182 int isbound(xcWidget window
, int keywstate
, int function
, short value
)
186 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
)
187 if (keywstate
== ksearch
->keywstate
&& function
== ksearch
->function
)
188 if (window
== ALL_WINDOWS
|| window
== ksearch
->window
||
189 ksearch
->window
== ALL_WINDOWS
)
190 if (value
== -1 || value
== ksearch
->value
|| ksearch
->value
== -1)
196 /*--------------------------------------------------------------*/
197 /* Return the string associated with a function, or NULL if the */
198 /* function value is out-of-bounds. */
199 /*--------------------------------------------------------------*/
201 char *func_to_string(int function
)
203 if ((function
< 0) || (function
>= NUM_FUNCTIONS
)) return NULL
;
204 return function_names
[function
];
207 /*--------------------------------------------------------------*/
208 /* Identify a function with the string version of its name */
209 /*--------------------------------------------------------------*/
211 int string_to_func(const char *funcstring
, short *value
)
215 for (i
= 0; i
< NUM_FUNCTIONS
; i
++)
217 if (function_names
[i
] == NULL
) {
218 Fprintf(stderr
, "Error: resolve bindings and function strings!\n");
219 return -1; /* should not happen? */
221 if (!strcmp(funcstring
, function_names
[i
]))
225 /* Check if this string might have a value attached */
228 for (i
= 0; i
< NUM_FUNCTIONS
; i
++)
229 if (!strncmp(funcstring
, function_names
[i
], strlen(function_names
[i
]))) {
230 sscanf(funcstring
+ strlen(function_names
[i
]), "%hd", value
);
237 /*--------------------------------------------------------------*/
238 /* Make a key sym from a string representing the key state */
239 /*--------------------------------------------------------------*/
241 int string_to_key(const char *keystring
)
243 int ct
, keywstate
= 0;
244 const char *kptr
= keystring
;
247 if (*kptr
== '\0') return -1;
248 if (!strncmp(kptr
, "XK_", 3))
250 else if (!strncmp(kptr
, "Shift_", 6)) {
254 else if (!strncmp(kptr
, "Capslock_", 9)) {
255 keywstate
|= CAPSLOCK
;
258 else if (!strncmp(kptr
, "Control_", 8)) {
262 else if (!strncmp(kptr
, "Alt_", 4)) {
266 else if (!strncmp(kptr
, "Meta_", 5)) {
270 else if (!strncmp(kptr
, "Hold_", 5)) {
274 else if (*kptr
== '^') {
276 ct
= (int)tolower(*kptr
);
277 keywstate
|= CTRL
| ct
;
280 else if (*(kptr
+ 1) == '\0') {
282 keywstate
|= CTRL
| (int)('A' + (*kptr
) - 1);
284 keywstate
|= (int)(*kptr
);
288 if (!strncmp(kptr
, "Button", 6)) {
289 switch (*(kptr
+ 6)) {
290 case '1': keywstate
= (Button1Mask
<< 16); break;
291 case '2': keywstate
= (Button2Mask
<< 16); break;
292 case '3': keywstate
= (Button3Mask
<< 16); break;
293 case '4': keywstate
= (Button4Mask
<< 16); break;
294 case '5': keywstate
= (Button5Mask
<< 16); break;
298 /* When any modifier keys are used, presence of SHIFT */
299 /* requires that the corresponding key be uppercase, */
300 /* and lack of SHIFT requires lowercase. Enforce it */
301 /* here so that it is not necessary for the user to */
303 if (*(kptr
+ 1) == '\0') {
304 if (keywstate
& SHIFT
)
305 ct
= (int)toupper(*kptr
);
307 ct
= (int)tolower(*kptr
);
311 keywstate
|= XStringToKeysym(kptr
);
319 /*--------------------------------------------------------------*/
320 /* Convert a function into a string representing all of its */
322 /*--------------------------------------------------------------*/
324 char *function_binding_to_string(xcWidget window
, int function
)
327 char *retstr
, *tmpstr
;
330 retstr
= (char *)malloc(1);
332 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
) {
333 if (function
== ksearch
->function
) {
334 if (ksearch
->window
== ALL_WINDOWS
|| ksearch
->window
== window
) {
335 tmpstr
= key_to_string(ksearch
->keywstate
);
336 if (tmpstr
!= NULL
) {
337 retstr
= (char *)realloc(retstr
, strlen(retstr
) + strlen(tmpstr
) +
339 if (!first
) strcat(retstr
, ", ");
340 strcat(retstr
, tmpstr
);
347 if (retstr
[0] == '\0') {
348 retstr
= (char *)realloc(retstr
, 10);
349 strcat(retstr
, "<unbound>");
354 /*--------------------------------------------------------------*/
355 /* Convert a key into a string representing all of its function */
357 /*--------------------------------------------------------------*/
359 char *key_binding_to_string(xcWidget window
, int keywstate
)
362 char *retstr
, *tmpstr
;
365 retstr
= (char *)malloc(1);
367 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
) {
368 if (keywstate
== ksearch
->keywstate
) {
369 if (ksearch
->window
== ALL_WINDOWS
|| ksearch
->window
== window
) {
370 tmpstr
= function_names
[ksearch
->function
];
371 if (tmpstr
!= NULL
) {
372 retstr
= (char *)realloc(retstr
, strlen(retstr
) + strlen(tmpstr
) +
374 if (!first
) strcat(retstr
, ", ");
375 strcat(retstr
, tmpstr
);
381 if (retstr
[0] == '\0') {
382 retstr
= (char *)realloc(retstr
, 10);
383 strcat(retstr
, "<unbound>");
388 /*--------------------------------------------------------------*/
389 /* Return an allocated string name of the function that */
390 /* is bound to the indicated key state for the indicated */
391 /* window and compattible with the current event mode. */
392 /*--------------------------------------------------------------*/
394 char *compat_key_to_string(xcWidget window
, int keywstate
)
396 char *retstr
, *tmpstr
;
399 function
= boundfunction(window
, keywstate
, NULL
);
400 tmpstr
= func_to_string(function
);
402 /* Pass back "Nothing" for unbound key states, since a */
403 /* wrapper script may want to use the result as an action. */
405 if (tmpstr
== NULL
) {
406 retstr
= (char *)malloc(8);
407 strcpy(retstr
, "Nothing");
410 retstr
= strdup(tmpstr
);
415 /*--------------------------------------------------------------*/
416 /* Convert a key sym into a string */
417 /*--------------------------------------------------------------*/
419 char *key_to_string(int keywstate
)
421 static char hex
[17] = "0123456789ABCDEF";
422 char *kptr
, *str
= NULL
;
426 ks
= keywstate
& 0xffff;
427 kmod
= keywstate
>> 16;
428 #if defined(XC_WIN32) && defined(TCL_WRAPPER)
429 if (ks
!= NoSymbol
) str
= XKeysymToString_TkW32(ks
);
431 if (ks
!= NoSymbol
) str
= XKeysymToString(ks
);
434 kptr
= (char *)malloc(32);
436 if (kmod
& Mod1Mask
) strcat(kptr
, "Alt_");
437 if (kmod
& Mod4Mask
) strcat(kptr
, "Hold_");
438 if (kmod
& ControlMask
) strcat(kptr
, "Control_");
439 if (kmod
& LockMask
) strcat(kptr
, "Capslock_");
440 if (kmod
& ShiftMask
) strcat(kptr
, "Shift_");
443 /* 33 is length of all modifiers concatenated + 1 */
444 kptr
= (char *)realloc(kptr
, strlen(str
) + 33);
448 kptr
= (char *)realloc(kptr
, 40);
449 if (kmod
& Button1Mask
) strcat(kptr
, "Button1");
450 else if (kmod
& Button2Mask
) strcat(kptr
, "Button2");
451 else if (kmod
& Button3Mask
) strcat(kptr
, "Button3");
452 else if (kmod
& Button4Mask
) strcat(kptr
, "Button4");
453 else if (kmod
& Button5Mask
) strcat(kptr
, "Button5");
457 kptr
[2] = hex
[(kmod
& 0xf)];
458 kptr
[3] = hex
[(keywstate
& 0xf000) >> 12];
459 kptr
[4] = hex
[(keywstate
& 0x0f00) >> 8];
460 kptr
[5] = hex
[(keywstate
& 0x00f0) >> 4];
461 kptr
[6] = hex
[(keywstate
& 0x000f) ];
468 /*--------------------------------------------------------------*/
469 /* Print the bindings for the (polygon) edit functions */
470 /*--------------------------------------------------------------*/
472 void printeditbindings()
478 tstr
= key_to_string(firstbinding(areawin
->area
, XCF_Edit_Delete
));
481 strcat(_STR2
, func_to_string(XCF_Edit_Delete
));
485 tstr
= key_to_string(firstbinding(areawin
->area
, XCF_Edit_Insert
));
488 strcat(_STR2
, func_to_string(XCF_Edit_Insert
));
492 tstr
= key_to_string(firstbinding(areawin
->area
, XCF_Edit_Param
));
495 strcat(_STR2
, func_to_string(XCF_Edit_Param
));
499 tstr
= key_to_string(firstbinding(areawin
->area
, XCF_Edit_Next
));
502 strcat(_STR2
, func_to_string(XCF_Edit_Next
));
505 /* Use W3printf(). In the Tcl version, this prints to the */
506 /* message window but does not duplicate the output to */
507 /* stdout, where it would be just an annoyance. */
509 W3printf("%s", _STR2
);
512 /*--------------------------------------------------------------*/
513 /* Remove a key binding from the list */
515 /* Note: This routine needs to correctly handle ALL_WINDOWS */
516 /* bindings that shadow specific window bindings. */
517 /*--------------------------------------------------------------*/
519 int remove_binding(xcWidget window
, int keywstate
, int function
)
521 keybinding
*ksearch
, *klast
= NULL
;
523 for (ksearch
= keylist
; ksearch
!= NULL
; ksearch
= ksearch
->nextbinding
) {
524 if (window
== ALL_WINDOWS
|| window
== ksearch
->window
) {
525 if ((function
== ksearch
->function
)
526 && (keywstate
== ksearch
->keywstate
)) {
528 keylist
= ksearch
->nextbinding
;
530 klast
->nextbinding
= ksearch
->nextbinding
;
540 /*--------------------------------------------------------------*/
541 /* Wrapper for remove_binding */
542 /*--------------------------------------------------------------*/
544 void remove_keybinding(xcWidget window
, const char *keystring
, const char *fstring
)
546 int function
= string_to_func(fstring
, NULL
);
547 int keywstate
= string_to_key(keystring
);
549 if ((function
< 0) || (remove_binding(window
, keywstate
, function
) < 0)) {
550 Wprintf("Key binding \'%s\' to \'%s\' does not exist in list.",
555 /*--------------------------------------------------------------*/
556 /* Add a key binding to the list */
557 /*--------------------------------------------------------------*/
559 int add_vbinding(xcWidget window
, int keywstate
, int function
, short value
)
561 keybinding
*newbinding
;
563 /* If key is already bound to the function, ignore it */
565 if (isbound(window
, keywstate
, function
, value
)) return 1;
567 /* Add the new key binding */
569 newbinding
= (keybinding
*)malloc(sizeof(keybinding
));
570 newbinding
->window
= window
;
571 newbinding
->keywstate
= keywstate
;
572 newbinding
->function
= function
;
573 newbinding
->value
= value
;
574 newbinding
->nextbinding
= keylist
;
575 keylist
= newbinding
;
579 /*--------------------------------------------------------------*/
580 /* Wrapper function for key binding without any values */
581 /*--------------------------------------------------------------*/
583 int add_binding(xcWidget window
, int keywstate
, int function
)
585 return add_vbinding(window
, keywstate
, function
, (short)-1);
588 /*--------------------------------------------------------------*/
589 /* Wrapper function for key binding with function as string */
590 /*--------------------------------------------------------------*/
592 int add_keybinding(xcWidget window
, const char *keystring
, const char *fstring
)
595 int function
= string_to_func(fstring
, &value
);
596 int keywstate
= string_to_key(keystring
);
601 return add_vbinding(window
, keywstate
, function
, value
);
604 /*--------------------------------------------------------------*/
605 /* Create list of default key bindings. */
606 /* These are conditional upon any bindings set in the startup */
607 /* file .xcircuitrc. */
608 /*--------------------------------------------------------------*/
610 void default_keybindings()
612 add_vbinding(ALL_WINDOWS
, XK_1
, XCF_Page
, 1);
613 add_vbinding(ALL_WINDOWS
, XK_2
, XCF_Page
, 2);
614 add_vbinding(ALL_WINDOWS
, XK_3
, XCF_Page
, 3);
615 add_vbinding(ALL_WINDOWS
, XK_4
, XCF_Page
, 4);
616 add_vbinding(ALL_WINDOWS
, XK_5
, XCF_Page
, 5);
617 add_vbinding(ALL_WINDOWS
, XK_6
, XCF_Page
, 6);
618 add_vbinding(ALL_WINDOWS
, XK_7
, XCF_Page
, 7);
619 add_vbinding(ALL_WINDOWS
, XK_8
, XCF_Page
, 8);
620 add_vbinding(ALL_WINDOWS
, XK_9
, XCF_Page
, 9);
621 add_vbinding(ALL_WINDOWS
, XK_0
, XCF_Page
, 10);
623 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_1
, XCF_Anchor
, 0);
624 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_2
, XCF_Anchor
, 1);
625 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_3
, XCF_Anchor
, 2);
626 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_4
, XCF_Anchor
, 3);
627 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_5
, XCF_Anchor
, 4);
628 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_6
, XCF_Anchor
, 5);
629 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_7
, XCF_Anchor
, 6);
630 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_8
, XCF_Anchor
, 7);
631 add_vbinding(ALL_WINDOWS
, SHIFT
| XK_KP_9
, XCF_Anchor
, 8);
633 add_vbinding(ALL_WINDOWS
, XK_KP_End
, XCF_Anchor
, 0);
634 add_vbinding(ALL_WINDOWS
, XK_KP_Down
, XCF_Anchor
, 1);
635 add_vbinding(ALL_WINDOWS
, XK_KP_Next
, XCF_Anchor
, 2);
636 add_vbinding(ALL_WINDOWS
, XK_KP_Left
, XCF_Anchor
, 3);
637 add_vbinding(ALL_WINDOWS
, XK_KP_Begin
, XCF_Anchor
, 4);
638 add_vbinding(ALL_WINDOWS
, XK_KP_Right
, XCF_Anchor
, 5);
639 add_vbinding(ALL_WINDOWS
, XK_KP_Home
, XCF_Anchor
, 6);
640 add_vbinding(ALL_WINDOWS
, XK_KP_Up
, XCF_Anchor
, 7);
641 add_vbinding(ALL_WINDOWS
, XK_KP_Prior
, XCF_Anchor
, 8);
643 add_binding(ALL_WINDOWS
, XK_Delete
, XCF_Text_Delete
);
644 add_binding(ALL_WINDOWS
, ALT
| XK_Delete
, XCF_Text_Delete_Param
);
645 add_binding(ALL_WINDOWS
, XK_Return
, XCF_Text_Return
);
646 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Text_Return
);
647 add_binding(ALL_WINDOWS
, XK_BackSpace
, XCF_Text_Delete
);
648 add_binding(ALL_WINDOWS
, XK_Left
, XCF_Text_Left
);
649 add_binding(ALL_WINDOWS
, XK_Right
, XCF_Text_Right
);
650 add_binding(ALL_WINDOWS
, XK_Up
, XCF_Text_Up
);
651 add_binding(ALL_WINDOWS
, XK_Down
, XCF_Text_Down
);
652 add_binding(ALL_WINDOWS
, ALT
| XK_x
, XCF_Text_Split
);
653 add_binding(ALL_WINDOWS
, XK_Home
, XCF_Text_Home
);
654 add_binding(ALL_WINDOWS
, XK_End
, XCF_Text_End
);
655 add_binding(ALL_WINDOWS
, XK_Tab
, XCF_TabForward
);
656 add_binding(ALL_WINDOWS
, SHIFT
| XK_Tab
, XCF_TabBackward
);
657 #ifdef XK_ISO_Left_Tab
658 add_binding(ALL_WINDOWS
, SHIFT
| XK_ISO_Left_Tab
, XCF_TabBackward
);
660 add_binding(ALL_WINDOWS
, ALT
| XK_Tab
, XCF_TabStop
);
661 add_binding(ALL_WINDOWS
, XK_KP_Add
, XCF_Superscript
);
662 add_binding(ALL_WINDOWS
, XK_KP_Subtract
, XCF_Subscript
);
663 add_binding(ALL_WINDOWS
, XK_KP_Enter
, XCF_Normalscript
);
664 add_vbinding(ALL_WINDOWS
, ALT
| XK_f
, XCF_Font
, 1000);
665 add_binding(ALL_WINDOWS
, ALT
| XK_b
, XCF_Boldfont
);
666 add_binding(ALL_WINDOWS
, ALT
| XK_i
, XCF_Italicfont
);
667 add_binding(ALL_WINDOWS
, ALT
| XK_n
, XCF_Normalfont
);
668 add_binding(ALL_WINDOWS
, ALT
| XK_u
, XCF_Underline
);
669 add_binding(ALL_WINDOWS
, ALT
| XK_o
, XCF_Overline
);
670 add_binding(ALL_WINDOWS
, ALT
| XK_e
, XCF_ISO_Encoding
);
671 add_binding(ALL_WINDOWS
, ALT
| XK_Return
, XCF_Linebreak
);
672 add_binding(ALL_WINDOWS
, ALT
| XK_h
, XCF_Halfspace
);
673 add_binding(ALL_WINDOWS
, ALT
| XK_q
, XCF_Quarterspace
);
675 add_binding(ALL_WINDOWS
, ALT
| XK_p
, XCF_Parameter
);
677 add_binding(ALL_WINDOWS
, XK_backslash
, XCF_Special
);
678 add_binding(ALL_WINDOWS
, ALT
| XK_c
, XCF_Special
);
679 add_binding(ALL_WINDOWS
, XK_p
, XCF_Edit_Param
);
680 add_binding(ALL_WINDOWS
, XK_d
, XCF_Edit_Delete
);
681 add_binding(ALL_WINDOWS
, XK_Delete
, XCF_Edit_Delete
);
682 add_binding(ALL_WINDOWS
, XK_i
, XCF_Edit_Insert
);
683 add_binding(ALL_WINDOWS
, XK_Insert
, XCF_Edit_Insert
);
684 add_binding(ALL_WINDOWS
, XK_e
, XCF_Edit_Next
);
685 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Edit_Next
);
686 add_binding(ALL_WINDOWS
, XK_A
, XCF_Attach
);
687 add_binding(ALL_WINDOWS
, XK_V
, XCF_Virtual
);
688 add_binding(ALL_WINDOWS
, XK_l
, XCF_Next_Library
);
689 add_binding(ALL_WINDOWS
, XK_L
, XCF_Library_Directory
);
690 add_binding(ALL_WINDOWS
, XK_c
, XCF_Library_Copy
);
691 add_binding(ALL_WINDOWS
, XK_E
, XCF_Library_Edit
);
692 add_binding(ALL_WINDOWS
, XK_e
, XCF_Library_Edit
);
693 add_binding(ALL_WINDOWS
, XK_D
, XCF_Library_Delete
);
694 add_binding(ALL_WINDOWS
, XK_C
, XCF_Library_Duplicate
);
695 add_binding(ALL_WINDOWS
, XK_H
, XCF_Library_Hide
);
696 add_binding(ALL_WINDOWS
, XK_V
, XCF_Library_Virtual
);
697 add_binding(ALL_WINDOWS
, XK_M
, XCF_Library_Move
);
698 add_binding(ALL_WINDOWS
, XK_m
, XCF_Library_Move
);
699 add_binding(ALL_WINDOWS
, XK_P
, XCF_Page_Directory
);
700 add_binding(ALL_WINDOWS
, XK_less
, XCF_Library_Pop
);
701 add_binding(ALL_WINDOWS
, HOLD
| BUTTON1
, XCF_Library_Pop
);
702 add_binding(ALL_WINDOWS
, XK_h
, XCF_Help
);
703 add_binding(ALL_WINDOWS
, XK_question
, XCF_Help
);
704 add_binding(ALL_WINDOWS
, XK_space
, XCF_Redraw
);
705 add_binding(ALL_WINDOWS
, XK_Redo
, XCF_Redraw
);
706 add_binding(ALL_WINDOWS
, XK_Undo
, XCF_Redraw
);
707 add_binding(ALL_WINDOWS
, XK_Home
, XCF_View
);
708 add_binding(ALL_WINDOWS
, XK_v
, XCF_View
);
709 add_binding(ALL_WINDOWS
, XK_Z
, XCF_Zoom_In
);
710 add_binding(ALL_WINDOWS
, XK_z
, XCF_Zoom_Out
);
711 add_vbinding(ALL_WINDOWS
, XK_p
, XCF_Pan
, 0);
712 add_binding(ALL_WINDOWS
, XK_plus
, XCF_Double_Snap
);
713 add_binding(ALL_WINDOWS
, XK_minus
, XCF_Halve_Snap
);
714 add_vbinding(ALL_WINDOWS
, XK_Left
, XCF_Pan
, 1);
715 add_vbinding(ALL_WINDOWS
, XK_Right
, XCF_Pan
, 2);
716 add_vbinding(ALL_WINDOWS
, XK_Up
, XCF_Pan
, 3);
717 add_vbinding(ALL_WINDOWS
, XK_Down
, XCF_Pan
, 4);
718 add_binding(ALL_WINDOWS
, XK_W
, XCF_Write
);
719 add_vbinding(ALL_WINDOWS
, XK_O
, XCF_Rotate
, -5);
720 add_vbinding(ALL_WINDOWS
, XK_o
, XCF_Rotate
, 5);
721 add_vbinding(ALL_WINDOWS
, XK_R
, XCF_Rotate
, -15);
722 add_vbinding(ALL_WINDOWS
, XK_r
, XCF_Rotate
, 15);
723 add_binding(ALL_WINDOWS
, XK_f
, XCF_Flip_X
);
724 add_binding(ALL_WINDOWS
, XK_F
, XCF_Flip_Y
);
725 add_binding(ALL_WINDOWS
, XK_S
, XCF_Snap
);
726 add_binding(ALL_WINDOWS
, XK_less
, XCF_Pop
);
727 add_binding(ALL_WINDOWS
, XK_greater
, XCF_Push
);
728 add_binding(ALL_WINDOWS
, XK_Delete
, XCF_Delete
);
729 add_binding(ALL_WINDOWS
, XK_d
, XCF_Delete
);
730 add_binding(ALL_WINDOWS
, XK_F19
, XCF_Select
);
731 add_binding(ALL_WINDOWS
, XK_b
, XCF_Box
);
732 add_binding(ALL_WINDOWS
, XK_a
, XCF_Arc
);
733 add_binding(ALL_WINDOWS
, XK_t
, XCF_Text
);
734 add_binding(ALL_WINDOWS
, XK_X
, XCF_Exchange
);
735 add_binding(ALL_WINDOWS
, XK_c
, XCF_Copy
);
736 add_binding(ALL_WINDOWS
, XK_j
, XCF_Join
);
737 add_binding(ALL_WINDOWS
, XK_J
, XCF_Unjoin
);
738 add_binding(ALL_WINDOWS
, XK_s
, XCF_Spline
);
739 add_binding(ALL_WINDOWS
, XK_e
, XCF_Edit
);
740 add_binding(ALL_WINDOWS
, XK_u
, XCF_Undo
);
741 add_binding(ALL_WINDOWS
, XK_U
, XCF_Redo
);
742 add_binding(ALL_WINDOWS
, XK_M
, XCF_Select_Save
);
743 add_binding(ALL_WINDOWS
, XK_m
, XCF_Select_Save
);
744 add_binding(ALL_WINDOWS
, XK_x
, XCF_Unselect
);
745 add_binding(ALL_WINDOWS
, XK_bar
, XCF_Dashed
);
746 add_binding(ALL_WINDOWS
, XK_colon
, XCF_Dotted
);
747 add_binding(ALL_WINDOWS
, XK_underscore
, XCF_Solid
);
748 add_binding(ALL_WINDOWS
, XK_percent
, XCF_Prompt
);
749 add_binding(ALL_WINDOWS
, XK_period
, XCF_Dot
);
751 /* TCL_WRAPPER version req's binding to specific windows */
752 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Wire
);
754 add_binding(ALL_WINDOWS
, XK_w
, XCF_Wire
);
755 add_binding(ALL_WINDOWS
, CTRL
| ALT
| XK_q
, XCF_Exit
);
756 add_binding(ALL_WINDOWS
, HOLD
| BUTTON1
, XCF_Move
);
757 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Continue_Element
);
758 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Continue_Copy
);
759 add_binding(ALL_WINDOWS
, BUTTON1
, XCF_Finish
);
760 add_binding(ALL_WINDOWS
, XK_Escape
, XCF_Cancel
);
761 add_binding(ALL_WINDOWS
, ALT
| XK_r
, XCF_Rescale
);
762 add_binding(ALL_WINDOWS
, ALT
| XK_s
, XCF_SnapTo
);
763 add_binding(ALL_WINDOWS
, ALT
| XK_q
, XCF_Netlist
);
764 add_binding(ALL_WINDOWS
, XK_slash
, XCF_Swap
);
765 add_binding(ALL_WINDOWS
, XK_T
, XCF_Pin_Label
);
766 add_binding(ALL_WINDOWS
, XK_G
, XCF_Pin_Global
);
767 add_binding(ALL_WINDOWS
, XK_I
, XCF_Info_Label
);
768 add_binding(ALL_WINDOWS
, ALT
| XK_w
, XCF_Connectivity
);
770 /* These are for test purposes only. Menu selection is */
773 /* add_binding(ALL_WINDOWS, ALT | XK_d, XCF_Sim); */
774 /* add_binding(ALL_WINDOWS, ALT | XK_a, XCF_SPICE); */
775 /* add_binding(ALL_WINDOWS, ALT | XK_f, XCF_SPICEflat); */
776 /* add_binding(ALL_WINDOWS, ALT | XK_p, XCF_PCB); */
778 /* Avoid spurious Num_Lock messages */
779 add_binding(ALL_WINDOWS
, XK_Num_Lock
, XCF_Nothing
);
781 /* 2-button vs. 3-button mouse bindings (set with -2 */
782 /* commandline option; 3-button bindings default) */
784 if (pressmode
== 1) {
785 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Text_Return
);
786 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Select
);
787 add_binding(ALL_WINDOWS
, HOLD
| BUTTON3
, XCF_SelectBox
);
788 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Finish_Element
);
789 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Finish_Copy
);
791 add_binding(ALL_WINDOWS
, XK_BackSpace
, XCF_Cancel_Last
);
792 add_binding(ALL_WINDOWS
, XK_BackSpace
, XCF_Cancel
);
795 add_binding(ALL_WINDOWS
, BUTTON2
, XCF_Text_Return
);
796 add_binding(ALL_WINDOWS
, SHIFT
| BUTTON1
, XCF_Text_Return
);
797 add_binding(ALL_WINDOWS
, BUTTON2
, XCF_Select
);
798 add_binding(ALL_WINDOWS
, SHIFT
| BUTTON1
, XCF_Select
);
799 add_binding(ALL_WINDOWS
, HOLD
| BUTTON2
, XCF_SelectBox
);
800 add_binding(ALL_WINDOWS
, SHIFT
| HOLD
| BUTTON1
, XCF_Select
);
801 add_binding(ALL_WINDOWS
, BUTTON2
, XCF_Finish_Element
);
802 add_binding(ALL_WINDOWS
, SHIFT
| BUTTON1
, XCF_Finish_Element
);
803 add_binding(ALL_WINDOWS
, BUTTON2
, XCF_Finish_Copy
);
804 add_binding(ALL_WINDOWS
, SHIFT
| BUTTON1
, XCF_Finish_Copy
);
805 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Cancel_Last
);
806 add_binding(ALL_WINDOWS
, BUTTON3
, XCF_Cancel
);
811 /*----------------------------------------------*/
812 /* Mode-setting rebindings (non-Tcl version) */
813 /*----------------------------------------------*/
815 static int button1mode
= XCF_Wire
;
817 /*--------------------------------------------------------------*/
818 /* Re-bind BUTTON1 to the indicated function and optional value */
819 /*--------------------------------------------------------------*/
821 void mode_rebinding(int newmode
, int newvalue
)
823 xcWidget window
= areawin
->area
;
825 remove_binding(window
, BUTTON1
, button1mode
);
826 add_vbinding(window
, BUTTON1
, newmode
, (short)newvalue
);
827 button1mode
= newmode
;
831 /*--------------------------------------------------------------*/
832 /* Execute the function associated with the indicated BUTTON1 */
833 /* mode, but return the keybinding to its previous state. */
834 /*--------------------------------------------------------------*/
836 void mode_tempbinding(int newmode
, int newvalue
)
840 xcWidget window
= areawin
->area
;
842 if (boundfunction(window
, BUTTON1
, &saveval
) == button1mode
) {
843 remove_binding(window
, BUTTON1
, button1mode
);
844 add_vbinding(window
, BUTTON1
, newmode
, (short)newvalue
);
846 eventdispatch(BUTTON1
, (int)cpos
.x
, (int)cpos
.y
);
847 remove_binding(window
, BUTTON1
, newmode
);
848 add_vbinding(window
, BUTTON1
, button1mode
, saveval
);
851 fprintf(stderr
, "Error: No such button1 binding %s\n",
852 func_to_string(button1mode
));
855 #endif /* TCL_WRAPPER */
865 /*--------------------------------------------------------------*/