summaryrefslogtreecommitdiff
path: root/keybindings.c
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-10-20 17:43:57 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-10-20 17:43:57 +0200
commit04d5d0ea0f65a434e568fe031f6396caec9b3a8d (patch)
treedecc35c37120084c4a55311cb4e801524369ff57 /keybindings.c
Import Upstream version 3.8.78.dfsg
Diffstat (limited to 'keybindings.c')
-rw-r--r--keybindings.c864
1 files changed, 864 insertions, 0 deletions
diff --git a/keybindings.c b/keybindings.c
new file mode 100644
index 0000000..b77d703
--- /dev/null
+++ b/keybindings.c
@@ -0,0 +1,864 @@
+/*--------------------------------------------------------------*/
+/* keybindings.c: List of key bindings */
+/* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */
+/*--------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/* written by Tim Edwards, 2/27/01 */
+/*----------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h> /* for tolower(), toupper() */
+#include <math.h>
+
+#ifndef XC_WIN32
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#endif
+
+#if !defined(XC_WIN32) || defined(TCL_WRAPPER)
+#define XK_MISCELLANY
+#define XK_LATIN1
+#define XK_XKB_KEYS
+#include <X11/keysymdef.h>
+#endif
+
+/*----------------------------------------------------------------------*/
+/* Local includes */
+/*----------------------------------------------------------------------*/
+
+#ifdef TCL_WRAPPER
+#include <tk.h>
+#endif
+
+#include "xcircuit.h"
+
+/*----------------------------------------------------------------------*/
+/* Function prototypes */
+/*----------------------------------------------------------------------*/
+
+#include "prototypes.h"
+
+/*----------------------------------------------------------------------*/
+/* Global variables */
+/*----------------------------------------------------------------------*/
+
+keybinding *keylist = NULL;
+
+extern Display *dpy;
+extern char _STR[150], _STR2[250];
+extern int pressmode;
+extern XCWindowData *areawin;
+
+/*----------------------------------------------------------------------*/
+/* Key modifiers (convenience definitions) */
+/* Use Mod5Mask for a "hold" ("press") definition. */
+/* Why Mod5Mask? Mod2Mask is used by fvwm2 for some obscure purpose, */
+/* so I went to the other end (Mod5Mask is just below Button1Mask). */
+/* Thanks to John Heil for reporting the problem and confirming the */
+/* Mod5Mask solution. */
+/*----------------------------------------------------------------------*/
+
+#define ALT (Mod1Mask << 16)
+#define CTRL (ControlMask << 16)
+#define CAPSLOCK (LockMask << 16)
+#define SHIFT (ShiftMask << 16)
+#define BUTTON1 (Button1Mask << 16)
+#define BUTTON2 (Button2Mask << 16)
+#define BUTTON3 (Button3Mask << 16)
+#define BUTTON4 (Button4Mask << 16)
+#define BUTTON5 (Button5Mask << 16)
+#define HOLD (Mod4Mask << 16)
+
+#define ALL_WINDOWS (xcWidget)NULL
+
+/*--------------------------------------------------------------*/
+/* This list declares all the functions which can be bound to */
+/* keys. It must match the order of the enumeration listed in */
+/* xcircuit.h! */
+/*--------------------------------------------------------------*/
+
+static char *function_names[NUM_FUNCTIONS + 1] = {
+ "Page", "Justify", "Superscript", "Subscript", "Normalscript",
+ "Nextfont", "Boldfont", "Italicfont", "Normalfont", "Underline",
+ "Overline", "ISO Encoding", "Halfspace", "Quarterspace",
+ "Special", "Tab Stop", "Tab Forward", "Tab Backward",
+ "Text Return", "Text Delete", "Text Right", "Text Left",
+ "Text Up", "Text Down", "Text Split",
+ "Text Home", "Text End", "Linebreak", "Parameter",
+ "Parameterize Point", "Change Style", "Delete Point", "Insert Point",
+ "Append Point", "Next Point", "Attach", "Next Library", "Library Directory",
+ "Library Move", "Library Copy", "Library Edit", "Library Delete",
+ "Library Duplicate", "Library Hide", "Library Virtual Copy",
+ "Page Directory", "Library Pop", "Virtual Copy",
+ "Help", "Redraw", "View", "Zoom In", "Zoom Out", "Pan",
+ "Double Snap", "Halve Snap", "Write", "Rotate", "Flip X",
+ "Flip Y", "Snap", "Snap To",
+ "Pop", "Push", "Delete", "Select", "Box", "Arc", "Text",
+ "Exchange", "Copy", "Move", "Join", "Unjoin", "Spline", "Edit",
+ "Undo", "Redo", "Select Save", "Unselect", "Dashed", "Dotted",
+ "Solid", "Prompt", "Dot", "Wire", "Cancel", "Nothing", "Exit",
+ "Netlist", "Swap", "Pin Label", "Pin Global", "Info Label", "Graphic",
+ "Select Box", "Connectivity", "Continue Element", "Finish Element",
+ "Continue Copy", "Finish Copy", "Finish", "Cancel Last", "Sim",
+ "SPICE", "PCB", "SPICE Flat", "Rescale", "Reorder", "Color",
+ "Margin Stop", "Text Delete Param",
+ NULL /* sentinel */
+};
+
+/*--------------------------------------------------------------*/
+/* Return TRUE if the indicated key (keysym + bit-shifted state)*/
+/* is bound to some function. */
+/*--------------------------------------------------------------*/
+
+Boolean ismacro(xcWidget window, int keywstate)
+{
+ keybinding *ksearch;
+
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding)
+ if (ksearch->window == ALL_WINDOWS || ksearch->window == window)
+ if (keywstate == ksearch->keywstate)
+ return True;
+
+ return False;
+}
+
+/*--------------------------------------------------------------*/
+/* Return the first key binding for the indicated function */
+/*--------------------------------------------------------------*/
+
+int firstbinding(xcWidget window, int function)
+{
+ keybinding *ksearch;
+ int keywstate = -1;
+
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding) {
+ if (ksearch->function == function) {
+ if (ksearch->window == window)
+ return ksearch->keywstate;
+ else if (ksearch->window == ALL_WINDOWS)
+ keywstate = ksearch->keywstate;
+ }
+ }
+ return keywstate;
+}
+
+/*--------------------------------------------------------------*/
+/* Find the first function bound to the indicated key that is */
+/* compatible with the current state (eventmode). Window- */
+/* specific bindings shadow ALL_WINDOWS bindings. Return the */
+/* function number if found, or -1 if no compatible functions */
+/* are bound to the key state. */
+/*--------------------------------------------------------------*/
+
+int boundfunction(xcWidget window, int keywstate, short *retnum)
+{
+ keybinding *ksearch;
+ int tempfunc = -1;
+
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding) {
+ if (keywstate == ksearch->keywstate) {
+ if (compatible_function(ksearch->function)) {
+ if (ksearch->window == window) {
+ if (retnum != NULL) *retnum = (ksearch->value);
+ return ksearch->function;
+ }
+ else if (ksearch->window == ALL_WINDOWS) {
+ if (retnum != NULL) *retnum = (ksearch->value);
+ tempfunc = ksearch->function;
+ }
+ }
+ }
+ }
+ return tempfunc;
+}
+
+/*--------------------------------------------------------------*/
+/* Check if an entry exists for a given key-function pair */
+/*--------------------------------------------------------------*/
+
+int isbound(xcWidget window, int keywstate, int function, short value)
+{
+ keybinding *ksearch;
+
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding)
+ if (keywstate == ksearch->keywstate && function == ksearch->function)
+ if (window == ALL_WINDOWS || window == ksearch->window ||
+ ksearch->window == ALL_WINDOWS)
+ if (value == -1 || value == ksearch->value || ksearch->value == -1)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*--------------------------------------------------------------*/
+/* Return the string associated with a function, or NULL if the */
+/* function value is out-of-bounds. */
+/*--------------------------------------------------------------*/
+
+char *func_to_string(int function)
+{
+ if ((function < 0) || (function >= NUM_FUNCTIONS)) return NULL;
+ return function_names[function];
+}
+
+/*--------------------------------------------------------------*/
+/* Identify a function with the string version of its name */
+/*--------------------------------------------------------------*/
+
+int string_to_func(const char *funcstring, short *value)
+{
+ int i;
+
+ for (i = 0; i < NUM_FUNCTIONS; i++)
+ {
+ if (function_names[i] == NULL) {
+ Fprintf(stderr, "Error: resolve bindings and function strings!\n");
+ return -1; /* should not happen? */
+ }
+ if (!strcmp(funcstring, function_names[i]))
+ return i;
+ }
+
+ /* Check if this string might have a value attached */
+
+ if (value != NULL)
+ for (i = 0; i < NUM_FUNCTIONS; i++)
+ if (!strncmp(funcstring, function_names[i], strlen(function_names[i]))) {
+ sscanf(funcstring + strlen(function_names[i]), "%hd", value);
+ return i;
+ }
+
+ return -1;
+}
+
+/*--------------------------------------------------------------*/
+/* Make a key sym from a string representing the key state */
+/*--------------------------------------------------------------*/
+
+int string_to_key(const char *keystring)
+{
+ int ct, keywstate = 0;
+ const char *kptr = keystring;
+
+ while(1) {
+ if (*kptr == '\0') return -1;
+ if (!strncmp(kptr, "XK_", 3))
+ kptr += 3;
+ else if (!strncmp(kptr, "Shift_", 6)) {
+ keywstate |= SHIFT;
+ kptr += 6;
+ }
+ else if (!strncmp(kptr, "Capslock_", 9)) {
+ keywstate |= CAPSLOCK;
+ kptr += 9;
+ }
+ else if (!strncmp(kptr, "Control_", 8)) {
+ keywstate |= CTRL;
+ kptr += 8;
+ }
+ else if (!strncmp(kptr, "Alt_", 4)) {
+ keywstate |= ALT;
+ kptr += 4;
+ }
+ else if (!strncmp(kptr, "Meta_", 5)) {
+ keywstate |= ALT;
+ kptr += 5;
+ }
+ else if (!strncmp(kptr, "Hold_", 5)) {
+ keywstate |= HOLD;
+ kptr += 5;
+ }
+ else if (*kptr == '^') {
+ kptr++;
+ ct = (int)tolower(*kptr);
+ keywstate |= CTRL | ct;
+ break;
+ }
+ else if (*(kptr + 1) == '\0') {
+ if ((*kptr) < 32)
+ keywstate |= CTRL | (int)('A' + (*kptr) - 1);
+ else
+ keywstate |= (int)(*kptr);
+ break;
+ }
+ else {
+ if (!strncmp(kptr, "Button", 6)) {
+ switch (*(kptr + 6)) {
+ case '1': keywstate = (Button1Mask << 16); break;
+ case '2': keywstate = (Button2Mask << 16); break;
+ case '3': keywstate = (Button3Mask << 16); break;
+ case '4': keywstate = (Button4Mask << 16); break;
+ case '5': keywstate = (Button5Mask << 16); break;
+ }
+ }
+ else {
+ /* When any modifier keys are used, presence of SHIFT */
+ /* requires that the corresponding key be uppercase, */
+ /* and lack of SHIFT requires lowercase. Enforce it */
+ /* here so that it is not necessary for the user to */
+ /* do so. */
+ if (*(kptr + 1) == '\0') {
+ if (keywstate & SHIFT)
+ ct = (int)toupper(*kptr);
+ else
+ ct = (int)tolower(*kptr);
+ keywstate |= ct;
+ }
+ else
+ keywstate |= XStringToKeysym(kptr);
+ }
+ break;
+ }
+ }
+ return keywstate;
+}
+
+/*--------------------------------------------------------------*/
+/* Convert a function into a string representing all of its */
+/* key bindings. */
+/*--------------------------------------------------------------*/
+
+char *function_binding_to_string(xcWidget window, int function)
+{
+ keybinding *ksearch;
+ char *retstr, *tmpstr;
+ Bool first = True;
+
+ retstr = (char *)malloc(1);
+ retstr[0] = '\0';
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding) {
+ if (function == ksearch->function) {
+ if (ksearch->window == ALL_WINDOWS || ksearch->window == window) {
+ tmpstr = key_to_string(ksearch->keywstate);
+ if (tmpstr != NULL) {
+ retstr = (char *)realloc(retstr, strlen(retstr) + strlen(tmpstr) +
+ ((first) ? 1 : 3));
+ if (!first) strcat(retstr, ", ");
+ strcat(retstr, tmpstr);
+ free(tmpstr);
+ }
+ first = False;
+ }
+ }
+ }
+ if (retstr[0] == '\0') {
+ retstr = (char *)realloc(retstr, 10);
+ strcat(retstr, "<unbound>");
+ }
+ return(retstr);
+}
+
+/*--------------------------------------------------------------*/
+/* Convert a key into a string representing all of its function */
+/* bindings. */
+/*--------------------------------------------------------------*/
+
+char *key_binding_to_string(xcWidget window, int keywstate)
+{
+ keybinding *ksearch;
+ char *retstr, *tmpstr;
+ Bool first = True;
+
+ retstr = (char *)malloc(1);
+ retstr[0] = '\0';
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding) {
+ if (keywstate == ksearch->keywstate) {
+ if (ksearch->window == ALL_WINDOWS || ksearch->window == window) {
+ tmpstr = function_names[ksearch->function];
+ if (tmpstr != NULL) {
+ retstr = (char *)realloc(retstr, strlen(retstr) + strlen(tmpstr) +
+ ((first) ? 1 : 3));
+ if (!first) strcat(retstr, ", ");
+ strcat(retstr, tmpstr);
+ }
+ first = False;
+ }
+ }
+ }
+ if (retstr[0] == '\0') {
+ retstr = (char *)realloc(retstr, 10);
+ strcat(retstr, "<unbound>");
+ }
+ return(retstr);
+}
+
+/*--------------------------------------------------------------*/
+/* Return an allocated string name of the function that */
+/* is bound to the indicated key state for the indicated */
+/* window and compattible with the current event mode. */
+/*--------------------------------------------------------------*/
+
+char *compat_key_to_string(xcWidget window, int keywstate)
+{
+ char *retstr, *tmpstr;
+ int function;
+
+ function = boundfunction(window, keywstate, NULL);
+ tmpstr = func_to_string(function);
+
+ /* Pass back "Nothing" for unbound key states, since a */
+ /* wrapper script may want to use the result as an action. */
+
+ if (tmpstr == NULL) {
+ retstr = (char *)malloc(8);
+ strcpy(retstr, "Nothing");
+ }
+ else
+ retstr = strdup(tmpstr);
+
+ return(retstr);
+}
+
+/*--------------------------------------------------------------*/
+/* Convert a key sym into a string */
+/*--------------------------------------------------------------*/
+
+char *key_to_string(int keywstate)
+{
+ static char hex[17] = "0123456789ABCDEF";
+ char *kptr, *str = NULL;
+ KeySym ks;
+ int kmod;
+
+ ks = keywstate & 0xffff;
+ kmod = keywstate >> 16;
+#if defined(XC_WIN32) && defined(TCL_WRAPPER)
+ if (ks != NoSymbol) str = XKeysymToString_TkW32(ks);
+#else
+ if (ks != NoSymbol) str = XKeysymToString(ks);
+#endif
+
+ kptr = (char *)malloc(32);
+ kptr[0] = '\0';
+ if (kmod & Mod1Mask) strcat(kptr, "Alt_");
+ if (kmod & Mod4Mask) strcat(kptr, "Hold_");
+ if (kmod & ControlMask) strcat(kptr, "Control_");
+ if (kmod & LockMask) strcat(kptr, "Capslock_");
+ if (kmod & ShiftMask) strcat(kptr, "Shift_");
+
+ if (str != NULL) {
+ /* 33 is length of all modifiers concatenated + 1 */
+ kptr = (char *)realloc(kptr, strlen(str) + 33);
+ strcat(kptr, str);
+ }
+ else {
+ kptr = (char *)realloc(kptr, 40);
+ if (kmod & Button1Mask) strcat(kptr, "Button1");
+ else if (kmod & Button2Mask) strcat(kptr, "Button2");
+ else if (kmod & Button3Mask) strcat(kptr, "Button3");
+ else if (kmod & Button4Mask) strcat(kptr, "Button4");
+ else if (kmod & Button5Mask) strcat(kptr, "Button5");
+ else {
+ kptr[0] = '0';
+ kptr[1] = 'x';
+ kptr[2] = hex[(kmod & 0xf)];
+ kptr[3] = hex[(keywstate & 0xf000) >> 12];
+ kptr[4] = hex[(keywstate & 0x0f00) >> 8];
+ kptr[5] = hex[(keywstate & 0x00f0) >> 4];
+ kptr[6] = hex[(keywstate & 0x000f) ];
+ kptr[7] = '\0';
+ }
+ }
+ return kptr;
+}
+
+/*--------------------------------------------------------------*/
+/* Print the bindings for the (polygon) edit functions */
+/*--------------------------------------------------------------*/
+
+void printeditbindings()
+{
+ char *tstr;
+
+ _STR2[0] = '\0';
+
+ tstr = key_to_string(firstbinding(areawin->area, XCF_Edit_Delete));
+ strcat(_STR2, tstr);
+ strcat(_STR2, "=");
+ strcat(_STR2, func_to_string(XCF_Edit_Delete));
+ strcat(_STR2, ", ");
+ free(tstr);
+
+ tstr = key_to_string(firstbinding(areawin->area, XCF_Edit_Insert));
+ strcat(_STR2, tstr);
+ strcat(_STR2, "=");
+ strcat(_STR2, func_to_string(XCF_Edit_Insert));
+ strcat(_STR2, ", ");
+ free(tstr);
+
+ tstr = key_to_string(firstbinding(areawin->area, XCF_Edit_Param));
+ strcat(_STR2, tstr);
+ strcat(_STR2, "=");
+ strcat(_STR2, func_to_string(XCF_Edit_Param));
+ strcat(_STR2, ", ");
+ free(tstr);
+
+ tstr = key_to_string(firstbinding(areawin->area, XCF_Edit_Next));
+ strcat(_STR2, tstr);
+ strcat(_STR2, "=");
+ strcat(_STR2, func_to_string(XCF_Edit_Next));
+ free(tstr);
+
+ /* Use W3printf(). In the Tcl version, this prints to the */
+ /* message window but does not duplicate the output to */
+ /* stdout, where it would be just an annoyance. */
+
+ W3printf("%s", _STR2);
+}
+
+/*--------------------------------------------------------------*/
+/* Remove a key binding from the list */
+/* */
+/* Note: This routine needs to correctly handle ALL_WINDOWS */
+/* bindings that shadow specific window bindings. */
+/*--------------------------------------------------------------*/
+
+int remove_binding(xcWidget window, int keywstate, int function)
+{
+ keybinding *ksearch, *klast = NULL;
+
+ for (ksearch = keylist; ksearch != NULL; ksearch = ksearch->nextbinding) {
+ if (window == ALL_WINDOWS || window == ksearch->window) {
+ if ((function == ksearch->function)
+ && (keywstate == ksearch->keywstate)) {
+ if (klast == NULL)
+ keylist = ksearch->nextbinding;
+ else
+ klast->nextbinding = ksearch->nextbinding;
+ free(ksearch);
+ return 0;
+ }
+ }
+ klast = ksearch;
+ }
+ return -1;
+}
+
+/*--------------------------------------------------------------*/
+/* Wrapper for remove_binding */
+/*--------------------------------------------------------------*/
+
+void remove_keybinding(xcWidget window, const char *keystring, const char *fstring)
+{
+ int function = string_to_func(fstring, NULL);
+ int keywstate = string_to_key(keystring);
+
+ if ((function < 0) || (remove_binding(window, keywstate, function) < 0)) {
+ Wprintf("Key binding \'%s\' to \'%s\' does not exist in list.",
+ keystring, fstring);
+ }
+}
+
+/*--------------------------------------------------------------*/
+/* Add a key binding to the list */
+/*--------------------------------------------------------------*/
+
+int add_vbinding(xcWidget window, int keywstate, int function, short value)
+{
+ keybinding *newbinding;
+
+ /* If key is already bound to the function, ignore it */
+
+ if (isbound(window, keywstate, function, value)) return 1;
+
+ /* Add the new key binding */
+
+ newbinding = (keybinding *)malloc(sizeof(keybinding));
+ newbinding->window = window;
+ newbinding->keywstate = keywstate;
+ newbinding->function = function;
+ newbinding->value = value;
+ newbinding->nextbinding = keylist;
+ keylist = newbinding;
+ return 0;
+}
+
+/*--------------------------------------------------------------*/
+/* Wrapper function for key binding without any values */
+/*--------------------------------------------------------------*/
+
+int add_binding(xcWidget window, int keywstate, int function)
+{
+ return add_vbinding(window, keywstate, function, (short)-1);
+}
+
+/*--------------------------------------------------------------*/
+/* Wrapper function for key binding with function as string */
+/*--------------------------------------------------------------*/
+
+int add_keybinding(xcWidget window, const char *keystring, const char *fstring)
+{
+ short value = -1;
+ int function = string_to_func(fstring, &value);
+ int keywstate = string_to_key(keystring);
+
+ if (function < 0)
+ return -1;
+ else
+ return add_vbinding(window, keywstate, function, value);
+}
+
+/*--------------------------------------------------------------*/
+/* Create list of default key bindings. */
+/* These are conditional upon any bindings set in the startup */
+/* file .xcircuitrc. */
+/*--------------------------------------------------------------*/
+
+void default_keybindings()
+{
+ add_vbinding(ALL_WINDOWS, XK_1, XCF_Page, 1);
+ add_vbinding(ALL_WINDOWS, XK_2, XCF_Page, 2);
+ add_vbinding(ALL_WINDOWS, XK_3, XCF_Page, 3);
+ add_vbinding(ALL_WINDOWS, XK_4, XCF_Page, 4);
+ add_vbinding(ALL_WINDOWS, XK_5, XCF_Page, 5);
+ add_vbinding(ALL_WINDOWS, XK_6, XCF_Page, 6);
+ add_vbinding(ALL_WINDOWS, XK_7, XCF_Page, 7);
+ add_vbinding(ALL_WINDOWS, XK_8, XCF_Page, 8);
+ add_vbinding(ALL_WINDOWS, XK_9, XCF_Page, 9);
+ add_vbinding(ALL_WINDOWS, XK_0, XCF_Page, 10);
+
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_1, XCF_Justify, 0);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_2, XCF_Justify, 1);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_3, XCF_Justify, 2);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_4, XCF_Justify, 3);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_5, XCF_Justify, 4);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_6, XCF_Justify, 5);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_7, XCF_Justify, 6);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_8, XCF_Justify, 7);
+ add_vbinding(ALL_WINDOWS, SHIFT | XK_KP_9, XCF_Justify, 8);
+
+ add_vbinding(ALL_WINDOWS, XK_KP_End, XCF_Justify, 0);
+ add_vbinding(ALL_WINDOWS, XK_KP_Down, XCF_Justify, 1);
+ add_vbinding(ALL_WINDOWS, XK_KP_Next, XCF_Justify, 2);
+ add_vbinding(ALL_WINDOWS, XK_KP_Left, XCF_Justify, 3);
+ add_vbinding(ALL_WINDOWS, XK_KP_Begin, XCF_Justify, 4);
+ add_vbinding(ALL_WINDOWS, XK_KP_Right, XCF_Justify, 5);
+ add_vbinding(ALL_WINDOWS, XK_KP_Home, XCF_Justify, 6);
+ add_vbinding(ALL_WINDOWS, XK_KP_Up, XCF_Justify, 7);
+ add_vbinding(ALL_WINDOWS, XK_KP_Prior, XCF_Justify, 8);
+
+ add_binding(ALL_WINDOWS, XK_Delete, XCF_Text_Delete);
+ add_binding(ALL_WINDOWS, XK_Return, XCF_Text_Return);
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Text_Return);
+ add_binding(ALL_WINDOWS, XK_BackSpace, XCF_Text_Delete);
+ add_binding(ALL_WINDOWS, XK_Left, XCF_Text_Left);
+ add_binding(ALL_WINDOWS, XK_Right, XCF_Text_Right);
+ add_binding(ALL_WINDOWS, XK_Up, XCF_Text_Up);
+ add_binding(ALL_WINDOWS, XK_Down, XCF_Text_Down);
+ add_binding(ALL_WINDOWS, ALT | XK_x, XCF_Text_Split);
+ add_binding(ALL_WINDOWS, XK_Home, XCF_Text_Home);
+ add_binding(ALL_WINDOWS, XK_End, XCF_Text_End);
+ add_binding(ALL_WINDOWS, XK_Tab, XCF_TabForward);
+ add_binding(ALL_WINDOWS, SHIFT | XK_Tab, XCF_TabBackward);
+#ifdef XK_ISO_Left_Tab
+ add_binding(ALL_WINDOWS, SHIFT | XK_ISO_Left_Tab, XCF_TabBackward);
+#endif
+ add_binding(ALL_WINDOWS, ALT | XK_Tab, XCF_TabStop);
+ add_binding(ALL_WINDOWS, XK_KP_Add, XCF_Superscript);
+ add_binding(ALL_WINDOWS, XK_KP_Subtract, XCF_Subscript);
+ add_binding(ALL_WINDOWS, XK_KP_Enter, XCF_Normalscript);
+ add_vbinding(ALL_WINDOWS, ALT | XK_f, XCF_Font, 1000);
+ add_binding(ALL_WINDOWS, ALT | XK_b, XCF_Boldfont);
+ add_binding(ALL_WINDOWS, ALT | XK_i, XCF_Italicfont);
+ add_binding(ALL_WINDOWS, ALT | XK_n, XCF_Normalfont);
+ add_binding(ALL_WINDOWS, ALT | XK_u, XCF_Underline);
+ add_binding(ALL_WINDOWS, ALT | XK_o, XCF_Overline);
+ add_binding(ALL_WINDOWS, ALT | XK_e, XCF_ISO_Encoding);
+ add_binding(ALL_WINDOWS, ALT | XK_Return, XCF_Linebreak);
+ add_binding(ALL_WINDOWS, ALT | XK_h, XCF_Halfspace);
+ add_binding(ALL_WINDOWS, ALT | XK_q, XCF_Quarterspace);
+#ifndef TCL_WRAPPER
+ add_binding(ALL_WINDOWS, ALT | XK_p, XCF_Parameter);
+#endif
+ add_binding(ALL_WINDOWS, XK_backslash, XCF_Special);
+ add_binding(ALL_WINDOWS, ALT | XK_c, XCF_Special);
+ add_binding(ALL_WINDOWS, XK_p, XCF_Edit_Param);
+ add_binding(ALL_WINDOWS, XK_d, XCF_Edit_Delete);
+ add_binding(ALL_WINDOWS, XK_Delete, XCF_Edit_Delete);
+ add_binding(ALL_WINDOWS, XK_i, XCF_Edit_Insert);
+ add_binding(ALL_WINDOWS, XK_Insert, XCF_Edit_Insert);
+ add_binding(ALL_WINDOWS, XK_e, XCF_Edit_Next);
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Edit_Next);
+ add_binding(ALL_WINDOWS, XK_A, XCF_Attach);
+ add_binding(ALL_WINDOWS, XK_V, XCF_Virtual);
+ add_binding(ALL_WINDOWS, XK_l, XCF_Next_Library);
+ add_binding(ALL_WINDOWS, XK_L, XCF_Library_Directory);
+ add_binding(ALL_WINDOWS, XK_c, XCF_Library_Copy);
+ add_binding(ALL_WINDOWS, XK_E, XCF_Library_Edit);
+ add_binding(ALL_WINDOWS, XK_e, XCF_Library_Edit);
+ add_binding(ALL_WINDOWS, XK_D, XCF_Library_Delete);
+ add_binding(ALL_WINDOWS, XK_C, XCF_Library_Duplicate);
+ add_binding(ALL_WINDOWS, XK_H, XCF_Library_Hide);
+ add_binding(ALL_WINDOWS, XK_V, XCF_Library_Virtual);
+ add_binding(ALL_WINDOWS, XK_M, XCF_Library_Move);
+ add_binding(ALL_WINDOWS, XK_m, XCF_Library_Move);
+ add_binding(ALL_WINDOWS, XK_P, XCF_Page_Directory);
+ add_binding(ALL_WINDOWS, XK_less, XCF_Library_Pop);
+ add_binding(ALL_WINDOWS, HOLD | BUTTON1, XCF_Library_Pop);
+ add_binding(ALL_WINDOWS, XK_h, XCF_Help);
+ add_binding(ALL_WINDOWS, XK_question, XCF_Help);
+ add_binding(ALL_WINDOWS, XK_space, XCF_Redraw);
+ add_binding(ALL_WINDOWS, XK_Redo, XCF_Redraw);
+ add_binding(ALL_WINDOWS, XK_Undo, XCF_Redraw);
+ add_binding(ALL_WINDOWS, XK_Home, XCF_View);
+ add_binding(ALL_WINDOWS, XK_v, XCF_View);
+ add_binding(ALL_WINDOWS, XK_Z, XCF_Zoom_In);
+ add_binding(ALL_WINDOWS, XK_z, XCF_Zoom_Out);
+ add_vbinding(ALL_WINDOWS, XK_p, XCF_Pan, 0);
+ add_binding(ALL_WINDOWS, XK_plus, XCF_Double_Snap);
+ add_binding(ALL_WINDOWS, XK_minus, XCF_Halve_Snap);
+ add_vbinding(ALL_WINDOWS, XK_Left, XCF_Pan, 1);
+ add_vbinding(ALL_WINDOWS, XK_Right, XCF_Pan, 2);
+ add_vbinding(ALL_WINDOWS, XK_Up, XCF_Pan, 3);
+ add_vbinding(ALL_WINDOWS, XK_Down, XCF_Pan, 4);
+ add_binding(ALL_WINDOWS, XK_W, XCF_Write);
+ add_vbinding(ALL_WINDOWS, XK_O, XCF_Rotate, -5);
+ add_vbinding(ALL_WINDOWS, XK_o, XCF_Rotate, 5);
+ add_vbinding(ALL_WINDOWS, XK_R, XCF_Rotate, -15);
+ add_vbinding(ALL_WINDOWS, XK_r, XCF_Rotate, 15);
+ add_binding(ALL_WINDOWS, XK_f, XCF_Flip_X);
+ add_binding(ALL_WINDOWS, XK_F, XCF_Flip_Y);
+ add_binding(ALL_WINDOWS, XK_S, XCF_Snap);
+ add_binding(ALL_WINDOWS, XK_less, XCF_Pop);
+ add_binding(ALL_WINDOWS, XK_greater, XCF_Push);
+ add_binding(ALL_WINDOWS, XK_Delete, XCF_Delete);
+ add_binding(ALL_WINDOWS, XK_d, XCF_Delete);
+ add_binding(ALL_WINDOWS, XK_F19, XCF_Select);
+ add_binding(ALL_WINDOWS, XK_b, XCF_Box);
+ add_binding(ALL_WINDOWS, XK_a, XCF_Arc);
+ add_binding(ALL_WINDOWS, XK_t, XCF_Text);
+ add_binding(ALL_WINDOWS, XK_X, XCF_Exchange);
+ add_binding(ALL_WINDOWS, XK_c, XCF_Copy);
+ add_binding(ALL_WINDOWS, XK_j, XCF_Join);
+ add_binding(ALL_WINDOWS, XK_J, XCF_Unjoin);
+ add_binding(ALL_WINDOWS, XK_s, XCF_Spline);
+ add_binding(ALL_WINDOWS, XK_e, XCF_Edit);
+ add_binding(ALL_WINDOWS, XK_u, XCF_Undo);
+ add_binding(ALL_WINDOWS, XK_U, XCF_Redo);
+ add_binding(ALL_WINDOWS, XK_M, XCF_Select_Save);
+ add_binding(ALL_WINDOWS, XK_m, XCF_Select_Save);
+ add_binding(ALL_WINDOWS, XK_x, XCF_Unselect);
+ add_binding(ALL_WINDOWS, XK_bar, XCF_Dashed);
+ add_binding(ALL_WINDOWS, XK_colon, XCF_Dotted);
+ add_binding(ALL_WINDOWS, XK_underscore, XCF_Solid);
+ add_binding(ALL_WINDOWS, XK_percent, XCF_Prompt);
+ add_binding(ALL_WINDOWS, XK_period, XCF_Dot);
+#ifndef TCL_WRAPPER
+ /* TCL_WRAPPER version req's binding to specific windows */
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Wire);
+#endif
+ add_binding(ALL_WINDOWS, XK_w, XCF_Wire);
+ add_binding(ALL_WINDOWS, CTRL | ALT | XK_q, XCF_Exit);
+ add_binding(ALL_WINDOWS, HOLD | BUTTON1, XCF_Move);
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Continue_Element);
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Continue_Copy);
+ add_binding(ALL_WINDOWS, BUTTON1, XCF_Finish);
+ add_binding(ALL_WINDOWS, XK_Escape, XCF_Cancel);
+ add_binding(ALL_WINDOWS, ALT | XK_r, XCF_Rescale);
+ add_binding(ALL_WINDOWS, ALT | XK_s, XCF_SnapTo);
+ add_binding(ALL_WINDOWS, ALT | XK_q, XCF_Netlist);
+ add_binding(ALL_WINDOWS, XK_slash, XCF_Swap);
+ add_binding(ALL_WINDOWS, XK_T, XCF_Pin_Label);
+ add_binding(ALL_WINDOWS, XK_G, XCF_Pin_Global);
+ add_binding(ALL_WINDOWS, XK_I, XCF_Info_Label);
+ add_binding(ALL_WINDOWS, ALT | XK_w, XCF_Connectivity);
+
+/* These are for test purposes only. Menu selection is */
+/* preferred. */
+
+/* add_binding(ALL_WINDOWS, ALT | XK_d, XCF_Sim); */
+/* add_binding(ALL_WINDOWS, ALT | XK_a, XCF_SPICE); */
+/* add_binding(ALL_WINDOWS, ALT | XK_f, XCF_SPICEflat); */
+/* add_binding(ALL_WINDOWS, ALT | XK_p, XCF_PCB); */
+
+ /* Avoid spurious Num_Lock messages */
+ add_binding(ALL_WINDOWS, XK_Num_Lock, XCF_Nothing);
+
+ /* 2-button vs. 3-button mouse bindings (set with -2 */
+ /* commandline option; 3-button bindings default) */
+
+ if (pressmode == 1) {
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Text_Return);
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Select);
+ add_binding(ALL_WINDOWS, HOLD | BUTTON3, XCF_SelectBox);
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Finish_Element);
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Finish_Copy);
+
+ add_binding(ALL_WINDOWS, XK_BackSpace, XCF_Cancel_Last);
+ add_binding(ALL_WINDOWS, XK_BackSpace, XCF_Cancel);
+ }
+ else {
+ add_binding(ALL_WINDOWS, BUTTON2, XCF_Text_Return);
+ add_binding(ALL_WINDOWS, SHIFT | BUTTON1, XCF_Text_Return);
+ add_binding(ALL_WINDOWS, BUTTON2, XCF_Select);
+ add_binding(ALL_WINDOWS, SHIFT | BUTTON1, XCF_Select);
+ add_binding(ALL_WINDOWS, HOLD | BUTTON2, XCF_SelectBox);
+ add_binding(ALL_WINDOWS, SHIFT | HOLD | BUTTON1, XCF_Select);
+ add_binding(ALL_WINDOWS, BUTTON2, XCF_Finish_Element);
+ add_binding(ALL_WINDOWS, SHIFT | BUTTON1, XCF_Finish_Element);
+ add_binding(ALL_WINDOWS, BUTTON2, XCF_Finish_Copy);
+ add_binding(ALL_WINDOWS, SHIFT | BUTTON1, XCF_Finish_Copy);
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Cancel_Last);
+ add_binding(ALL_WINDOWS, BUTTON3, XCF_Cancel);
+ }
+}
+
+#ifndef TCL_WRAPPER
+/*----------------------------------------------*/
+/* Mode-setting rebindings (non-Tcl version) */
+/*----------------------------------------------*/
+
+static int button1mode = XCF_Wire;
+
+/*--------------------------------------------------------------*/
+/* Re-bind BUTTON1 to the indicated function and optional value */
+/*--------------------------------------------------------------*/
+
+void mode_rebinding(int newmode, int newvalue)
+{
+ xcWidget window = areawin->area;
+
+ remove_binding(window, BUTTON1, button1mode);
+ add_vbinding(window, BUTTON1, newmode, (short)newvalue);
+ button1mode = newmode;
+ toolcursor(newmode);
+}
+
+/*--------------------------------------------------------------*/
+/* Execute the function associated with the indicated BUTTON1 */
+/* mode, but return the keybinding to its previous state. */
+/*--------------------------------------------------------------*/
+
+void mode_tempbinding(int newmode, int newvalue)
+{
+ short saveval;
+ XPoint cpos;
+ xcWidget window = areawin->area;
+
+ if (boundfunction(window, BUTTON1, &saveval) == button1mode) {
+ remove_binding(window, BUTTON1, button1mode);
+ add_vbinding(window, BUTTON1, newmode, (short)newvalue);
+ cpos = UGetCursor();
+ eventdispatch(BUTTON1, (int)cpos.x, (int)cpos.y);
+ remove_binding(window, BUTTON1, newmode);
+ add_vbinding(window, BUTTON1, button1mode, saveval);
+ }
+ else
+ fprintf(stderr, "Error: No such button1 binding %s\n",
+ func_to_string(button1mode));
+}
+
+#endif /* TCL_WRAPPER */
+
+#undef ALT
+#undef CTRL
+#undef CAPSLOCK
+#undef SHIFT
+#undef BUTTON1
+#undef BUTTON2
+#undef BUTTON3
+
+/*--------------------------------------------------------------*/