Index: trunk/doc-rnd/TODO =================================================================== --- trunk/doc-rnd/TODO (revision 1444) +++ trunk/doc-rnd/TODO (revision 1445) @@ -1,3 +1,6 @@ +- test vendordrill if it works +- vendordrill: free at exit + Cleanup #4: - reduce - replace hid_load_settings() with lihata @@ -24,8 +27,10 @@ - hid: hid_destroy (pair of hid_create) - cleanup on unload: remove menus - check whether local copy of gts is needed, bisect when toporouter broke -- vendordrill: free at exit +- Message() should have a first param that tells if it is an error, info, etc.; pop up window on error, red + + FEATURES - UI: trace length calculation {small} - UI: be able to manually change text line width {small} Index: trunk/src/hid_resource.h =================================================================== --- trunk/src/hid_resource.h (revision 1444) +++ trunk/src/hid_resource.h (nonexistent) @@ -1,119 +0,0 @@ -/* - * COPYRIGHT - * - * PCB, interactive printed circuit board design - * Copyright (C) 2016 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* Load resources (menus, key and mouse action bindings) from lihata files */ - -#ifndef PCB_HID_RESOURCE_H -#define PCB_HID_RESOURCE_H - -#include -#include - -typedef struct hid_res_s { - lht_doc_t *doc; - struct { - lht_node_t *mouse; - htip_t *mouse_mask; - } cache; -} hid_res_t; - -/* For compatibility; TODO: REMOVE */ -#define M_Mod(n) (1u<<(n+1)) - -#define M_Mod0(n) (1u<<(n)) -typedef enum { - M_Shift = M_Mod0(0), - M_Ctrl = M_Mod0(1), - M_Alt = M_Mod0(2), - M_Multi = M_Mod0(3), - /* M_Mod(3) is M_Mod0(4) */ - /* M_Mod(4) is M_Mod0(5) */ - M_Release = M_Mod0(6), /* there might be a random number of modkeys, but hopefully not this many */ - - MB_LEFT = M_Mod0(7), - MB_MIDDLE = M_Mod0(8), - MB_RIGHT = M_Mod0(9), - MB_UP = M_Mod0(10), /* scroll wheel */ - MB_DOWN = M_Mod0(11) /* scroll wheel */ -} hid_res_mod_t; - -#define MB_ANY (MB_LEFT | MB_MIDDLE | MB_RIGHT | MB_UP | MB_DOWN) -#define M_ANY (M_Release-1) - - - -/* Create a set of resources representing a single menu item */ -lht_node_t *resource_create_menu(hid_res_t *hr, const char *name, const char *action, const char *mnemonic, const char *accel, const char *tip, int flags); - -/* Search and load the menu res for hidname; if not found, and embedded_fallback - is not NULL, parse that string instead. Returns NULL on error */ -hid_res_t *hid_res_load(const char *hidname, const char *embedded_fallback); - -/* Generic, low level lihata loader */ -lht_doc_t *hid_res_load_lht(const char *filename); - -/* Generic, low level lihata text value fetch */ -const char *hid_res_text_value(lht_doc_t *doc, const char *path); - -lht_node_t *hid_res_get_menu(hid_res_t *hr, const char *menu_path); - -/* Fields are retrieved using this enum so that HIDs don't need to hardwire - lihata node names */ -typedef enum { - MF_ACCELERATOR, - MF_MNEMONIC, - MF_SUBMENU, - MF_CHECKED, - MF_SENSITIVE, - MF_TIP, - MF_ACTIVE, - MF_ACTION -} hid_res_menufield_t; - -/* Return a field of a submenu and optionally fill in field_name with the - field name expected in the lihata document (useful for error messages) */ -lht_node_t *hid_res_menu_field(const lht_node_t *submenu, hid_res_menufield_t field, const char **field_name); - -/* Return a text field of a submenu; return NULL and generate a Message() if - the given field is not text */ -const char *hid_res_menu_field_str(const lht_node_t *submenu, hid_res_menufield_t field); - -/* Return non-zero if submenu has further submenus; generate Message() if - there is a submenu field with the wrong lihata type */ -int hid_res_has_submenus(const lht_node_t *submenu); - -void hid_res_mouse_action(hid_res_t *hr, hid_res_mod_t button_and_mask); - -/* Run an action node. The node is either a list of text nodes or a text node */ -void hid_res_action(const lht_node_t *node); - -/* Report an error about a node */ -#define hid_res_error(node, ...) \ -do { \ - extern char hid_res_error_shared[]; \ - char *__end__; \ - __end__ = hid_res_error_shared + sprintf(hid_res_error_shared, "Error in lihata node %s:%d.%d:", node->file_name, node->line, node->col); \ - __end__ += sprintf(__end__, __VA_ARGS__); \ - Message(hid_res_error_shared); \ -} while(0) - -#endif Index: trunk/src/hid_resource.c =================================================================== --- trunk/src/hid_resource.c (revision 1444) +++ trunk/src/hid_resource.c (nonexistent) @@ -1,311 +0,0 @@ -/* - * COPYRIGHT - * - * PCB, interactive printed circuit board design - * Copyright (C) 2016 Tibor 'Igor2' Palinkas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "global.h" -#include "hid.h" -#include "hid_resource.h" -#include "hid_actions.h" -#include "hid_resource.h" -#include "error.h" - -static void hid_res_flush(hid_res_t *hr); - -char hid_res_error_shared[1024]; - -/* split value into a list of '-' separated words; examine each word - and set the bitmask of modifiers */ -static hid_res_mod_t parse_mods(const char *value) -{ - hid_res_mod_t m = 0; - int press = 0; - - for(;;) { - if (strncmp(value, "shift", 5) == 0) m |= M_Shift; - else if (strncmp(value, "ctrl", 4) == 0) m |= M_Ctrl; - else if (strncmp(value, "alt", 3) == 0) m |= M_Alt; - else if (strncmp(value, "release", 7) == 0) m |= M_Release; - else if (strncmp(value, "press", 5) == 0) press = 1; - else - Message("Unkown modifier: %s\n", value); - /* skip to next word */ - value = strchr(value, '-'); - if (value == NULL) - break; - value++; - } - - if (press && (m & M_Release)) - Message("Bogus modifier: both press and release\n"); - - return m; -} - -static hid_res_mod_t button_name2mask(const char *name) -{ - /* All mouse-related resources must be named. The name is the - mouse button number. */ - if (!name) - return 0; - else if (strcasecmp(name, "left") == 0) return MB_LEFT; - else if (strcasecmp(name, "middle") == 0) return MB_MIDDLE; - else if (strcasecmp(name, "right") == 0) return MB_RIGHT; - else if (strcasecmp(name, "up") == 0) return MB_UP; - else if (strcasecmp(name, "down") == 0) return MB_DOWN; - else { - Message("Error: unknown mouse button: %s\n", name); - return 0; - } -} - - -static int keyeq_int(htip_key_t a, htip_key_t b) { return a == b; } -static unsigned int keyhash_int(htip_key_t a) { return murmurhash32(a & 0xFFFF); } - -static void build_mouse_cache(hid_res_t *hr) -{ - lht_node_t *btn, *m; - - if (hr->cache.mouse == NULL) - hr->cache.mouse = hid_res_get_menu(hr, "/mouse"); - - if (hr->cache.mouse == NULL) { - Message("Warning: no /mouse section in the resource file - mouse is disabled\n"); - return; - } - - if (hr->cache.mouse->type != LHT_LIST) { - hid_res_error(hr->cache.mouse, "Warning: should be a list - mouse is disabled\n"); - return; - } - - if (hr->cache.mouse_mask == NULL) - hr->cache.mouse_mask = htip_alloc(keyhash_int, keyeq_int); - else - htip_clear(hr->cache.mouse_mask); - - for(btn = hr->cache.mouse->data.list.first; btn != NULL; btn = btn->next) { - hid_res_mod_t btn_mask = button_name2mask(btn->name); - if (btn_mask == 0) { - hid_res_error(btn, "unknown mouse button"); - continue; - } - if (btn->type != LHT_LIST) { - hid_res_error(btn, "needs to be a list"); - continue; - } - for(m = btn->data.list.first; m != NULL; m = m->next) { - hid_res_mod_t mod_mask = parse_mods(m->name); - htip_set(hr->cache.mouse_mask, btn_mask|mod_mask, m); - } - } -} - -static lht_node_t *find_best_action(hid_res_t *hr, hid_res_mod_t button_and_mask) -{ - lht_node_t *n; - - if (hr->cache.mouse_mask == NULL) - return NULL; - - /* look for exact mod match */ - n = htip_get(hr->cache.mouse_mask, button_and_mask); - if (n != NULL) - return n; - - if (button_and_mask & M_Release) { - /* look for plain release for the given button */ - n = htip_get(hr->cache.mouse_mask, (button_and_mask & M_ANY) | M_Release); - if (n != NULL) - return n; - } - - return NULL; -} - -void hid_res_mouse_action(hid_res_t *hr, hid_res_mod_t button_and_mask) -{ - hid_res_action(find_best_action(hr, button_and_mask)); -} - -lht_node_t *resource_create_menu(hid_res_t *hr, const char *name, const char *action, const char *mnemonic, const char *accel, const char *tip, int flags) -{ - /* TODO */ - abort(); -} - -lht_doc_t *hid_res_load_lht(const char *filename) -{ - FILE *f; - lht_doc_t *doc; - int error = 0; - - f = fopen(filename, "r"); - doc = lht_dom_init(); - lht_dom_loc_newfile(doc, filename); - - while(!(feof(f))) { - lht_err_t err; - int c = fgetc(f); - err = lht_dom_parser_char(doc, c); - if (err != LHTE_SUCCESS) { - if (err != LHTE_STOP) { - const char *fn; - int line, col; - lht_dom_loc_active(doc, &fn, &line, &col); - Message("Resource error: %s (%s:%d.%d)*\n", lht_err_str(err), filename, line+1, col+1); - error = 1; - break; - } - break; /* error or stop, do not read anymore (would get LHTE_STOP without any processing all the time) */ - } - } - - if (error) { - lht_dom_uninit(doc); - doc = NULL; - } - fclose(f); - - return doc; -} - -const char *hid_res_text_value(lht_doc_t *doc, const char *path) -{ - lht_node_t *n = lht_tree_path(doc, "/", path, 1, NULL); - if (n == NULL) - return NULL; - if (n->type != LHT_TEXT) { - hid_res_error(n, "Error: node %s should be a text node\n", path); - return NULL; - } - return n->data.text.value; -} - -hid_res_t *hid_res_load(const char *hidname, const char *embedded_fallback) -{ - lht_doc_t *doc; - hid_res_t *hr; - -//static const char *pcbmenu_paths_in[] = { "gpcb-menu.res", "gpcb-menu.res", PCBSHAREDIR "/gpcb-menu.res", NULL }; - char *hidfn = strdup(hidname); /* TODO: search for the file */ - - doc = hid_res_load_lht(hidfn); - if (doc == NULL) - return NULL; - - hr = calloc(sizeof(hid_res_t), 1); /* make sure the cache is cleared */ - hr->doc = doc; - hid_res_flush(hr); - - return hr; -} - -void hid_res_action(const lht_node_t *node) -{ - if (node == NULL) - return; - switch(node->type) { - case LHT_TEXT: - hid_parse_actions(node->data.text.value); - break; - case LHT_LIST: - for(node = node->data.list.first; node != NULL; node = node->next) - if (node->type == LHT_TEXT) - hid_parse_actions(node->data.text.value); - break; - } -} - -/************* "parsing" **************/ - -lht_node_t *hid_res_get_menu(hid_res_t *hr, const char *menu_path) -{ - lht_err_t err; - return lht_tree_path(hr->doc, "/", menu_path, 1, &err); -} - -lht_node_t *hid_res_menu_field(const lht_node_t *submenu, hid_res_menufield_t field, const char **field_name) -{ - lht_node_t *n; - lht_err_t err; - const char *fieldstr = NULL; - - switch(field) { - case MF_ACCELERATOR: fieldstr = "a"; break; - case MF_MNEMONIC: fieldstr = "m"; break; - case MF_SUBMENU: fieldstr = "submenu"; break; - case MF_CHECKED: fieldstr = "checked"; break; - case MF_SENSITIVE: fieldstr = "sensitive"; break; - case MF_TIP: fieldstr = "tip"; break; - case MF_ACTIVE: fieldstr = "active"; break; - case MF_ACTION: fieldstr = "action"; break; - } - if (field_name != NULL) - *field_name = fieldstr; - - if (fieldstr == NULL) - return NULL; - - return lht_tree_path_(submenu->doc, (lht_node_t *)submenu, fieldstr, 1, 0, &err); -} - -const char *hid_res_menu_field_str(const lht_node_t *submenu, hid_res_menufield_t field) -{ - const char *fldname; - lht_node_t *n = hid_res_menu_field(submenu, field, &fldname); - - if (n == NULL) - return NULL; - if (n->type != LHT_TEXT) { - hid_res_error(submenu, "Error: field %s should be a text node\n", fldname); - return NULL; - } - return n->data.text.value; -} - -int hid_res_has_submenus(const lht_node_t *submenu) -{ - const char *fldname; - lht_node_t *n = hid_res_menu_field(submenu, MF_SUBMENU, &fldname); - if (n == NULL) - return 0; - if (n->type != LHT_LIST) { - hid_res_error(submenu, "Error: field %s should be a list (of submenus)\n", fldname); - return NULL; - } - return 1; -} - -/************* cache **************/ -/* reset the cache of a resource tree; should be called any time the tree - changes */ -static void hid_res_flush(hid_res_t *hr) -{ - build_mouse_cache(hr); -} Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 1444) +++ trunk/src/Makefile.dep (revision 1445) @@ -267,7 +267,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -289,7 +289,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -310,7 +310,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -331,7 +331,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -351,7 +351,7 @@ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h ../src_plugins/hid_gtk/gtkhid.h \ - ../src_plugins/hid_gtk/gui.h hid.h hid_resource.h \ + ../src_plugins/hid_gtk/gui.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -371,7 +371,7 @@ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h clip.h ../src_plugins/hid_gtk/gui.h \ - global.h hid.h hid_resource.h ../src_3rd/liblihata/dom.h \ + global.h hid.h hid_cfg.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/liblihata/genht/htsp.h ../src_3rd/liblihata/genht/ht.h \ ../src_3rd/liblihata/genht/ht_inlines.h data.h misc.h \ @@ -393,7 +393,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h crosshair.h error.h \ - ../src_plugins/hid_gtk/gui.h global.h hid.h hid_resource.h \ + ../src_plugins/hid_gtk/gui.h global.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -415,7 +415,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -435,7 +435,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -457,7 +457,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -478,7 +478,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h ../src_plugins/hid_gtk/gui.h global.h \ - hid.h hid_resource.h ../src_3rd/liblihata/dom.h \ + hid.h hid_cfg.h ../src_3rd/liblihata/dom.h \ ../src_3rd/liblihata/lihata.h ../src_3rd/liblihata/parser.h \ ../src_3rd/liblihata/genht/htsp.h ../src_3rd/liblihata/genht/ht.h \ ../src_3rd/liblihata/genht/ht_inlines.h misc.h \ @@ -500,7 +500,7 @@ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h draw.h pcb-printf.h \ ../src_3rd/genvector/gds_char.h undo.h set.h \ - ../src_plugins/hid_gtk/gui.h global.h hid.h hid_resource.h \ + ../src_plugins/hid_gtk/gui.h global.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -520,7 +520,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -540,7 +540,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -561,7 +561,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -582,7 +582,7 @@ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h crosshair.h global.h data.h misc.h \ ../src_3rd/genvector/gds_char.h mymem.h action_helper.h set.h \ - pcb-printf.h ../src_plugins/hid_gtk/gui.h hid.h hid_resource.h \ + pcb-printf.h ../src_plugins/hid_gtk/gui.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -604,7 +604,7 @@ list_element.h plug_footprint.h create.h global.h data.h draw.h error.h \ find.h misc.h ../src_3rd/genvector/gds_char.h mymem.h mymem.h rats.h \ remove.h search.h select.h set.h undo.h hid_actions.h \ - ../src_plugins/hid_gtk/gui.h hid.h hid_resource.h \ + ../src_plugins/hid_gtk/gui.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -623,7 +623,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -646,7 +646,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h ../src_plugins/hid_gtk/gui.h hid.h \ - hid_resource.h ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + hid_cfg.h ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ data.h global.h misc.h ../src_3rd/genvector/gds_char.h mymem.h \ @@ -667,7 +667,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h ../src_plugins/hid_gtk/gui.h hid.h \ - hid_resource.h ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ + hid_cfg.h ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ data.h global.h misc.h ../src_3rd/genvector/gds_char.h mymem.h \ @@ -689,7 +689,7 @@ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ list_element.h plug_footprint.h ../src_plugins/hid_gtk/gtkhid.h \ - ../src_plugins/hid_gtk/gui.h hid.h hid_resource.h \ + ../src_plugins/hid_gtk/gui.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -713,7 +713,7 @@ list_pad.h list_pin.h list_rat.h vtonpoint.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid.h hid_resource.h \ + list_element.h plug_footprint.h hid.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ @@ -1238,7 +1238,7 @@ list_arc.h list_text.h list_poly.h list_pad.h list_pin.h list_rat.h \ vtonpoint.h ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h hid.h global_element.h \ - list_element.h plug_footprint.h hid_resource.h \ + list_element.h plug_footprint.h hid_cfg.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/liblihata/genht/htsp.h \ ../src_3rd/liblihata/genht/ht.h ../src_3rd/liblihata/genht/ht_inlines.h \ Index: trunk/src/Makefile.in =================================================================== --- trunk/src/Makefile.in (revision 1444) +++ trunk/src/Makefile.in (revision 1445) @@ -2,7 +2,7 @@ put /local/pcb/CFLAGS cc/rdynamic append /local/pcb/CFLAGS cc/cflags append /local/pcb/CFLAGS cc/fpic -append /local/pcb/CFLAGS {-I. -I.. -I../src_3rd -Iicons -DHAVE_CONFIG_H -g -DNDEBUG} +append /local/pcb/CFLAGS {-I. -I.. -I../src_3rd -I../src_3rd/liblihata -Iicons -DHAVE_CONFIG_H -g -DNDEBUG} append /local/pcb/LDFLAGS cc/ldflags append /local/pcb/LDFLAGS cc/rdynamic put /local/pcb/DEPCFLAGS {} @@ -39,6 +39,8 @@ heap.o hid_actions.o hid_attrib.o + hid_cfg.o + hid_cfg_input.o hid_color.o hid_draw_helpers.o hid_extents.o @@ -46,7 +48,6 @@ hid_helper.o hid_init.o hid_nogui.o - hid_resource.o insert.o intersect.o line.o Index: trunk/src/gpcb-menu.h =================================================================== --- trunk/src/gpcb-menu.h (revision 1444) +++ trunk/src/gpcb-menu.h (revision 1445) @@ -201,7 +201,7 @@ "# Settings menu", "#", " {\"Settings\" m=S", -" {\"'All-direction' lines\" checked=alldirection Display(Toggle45Degree) a={\".\" \".\"}}", +" {\"'All-direction' lines\" checked=alldirection Display(ToggleAllDirections) a={\".\" \".\"}}", " {\"Auto swap line start angle\" checked=swapstartdir Display(ToggleStartDirection)}", " {\"Orthogonal moves\" checked=orthomove Display(ToggleOrthoMove)}", " {\"Crosshair snaps to pins and pads\" checked=snappin Display(ToggleSnapPin)}", Index: trunk/src/gui_act.c =================================================================== --- trunk/src/gui_act.c (revision 1444) +++ trunk/src/gui_act.c (revision 1445) @@ -47,7 +47,7 @@ static const char display_syntax[] = "Display(NameOnPCB|Description|Value)\n" "Display(Grid|Redraw)\n" - "Display(CycleClip|CycleCrosshair|Toggle45Degree|ToggleStartDirection)\n" + "Display(CycleClip|CycleCrosshair|ToggleAllDirections|ToggleStartDirection)\n" "Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames)\n" "Display(ToggleMask|ToggleName|ToggleClearLine|ToggleFullPoly)\n" "Display(ToggleSnapPin|ToggleSnapOffGridLine|ToggleHighlightOnPoint)\n" @@ -69,7 +69,7 @@ @item Redraw Redraw the whole board. -@item Toggle45Degree +@item ToggleAllDirections When clear, lines can be drawn at any angle. When set, lines are restricted to multiples of 45 degrees and requested lines may be broken up according to the clip setting. Index: trunk/src/hid_cfg.c =================================================================== --- trunk/src/hid_cfg.c (nonexistent) +++ trunk/src/hid_cfg.c (revision 1445) @@ -0,0 +1,185 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "global.h" +#include "hid.h" +#include "hid_cfg.h" +#include "hid_actions.h" +#include "hid_cfg.h" +#include "error.h" + +char hid_cfg_error_shared[1024]; + +lht_node_t *resource_create_menu(hid_cfg_t *hr, const char *name, const char *action, const char *mnemonic, const char *accel, const char *tip, int flags) +{ + /* TODO */ + abort(); +} + +lht_doc_t *hid_cfg_load_lht(const char *filename) +{ + FILE *f; + lht_doc_t *doc; + int error = 0; + + f = fopen(filename, "r"); + doc = lht_dom_init(); + lht_dom_loc_newfile(doc, filename); + + while(!(feof(f))) { + lht_err_t err; + int c = fgetc(f); + err = lht_dom_parser_char(doc, c); + if (err != LHTE_SUCCESS) { + if (err != LHTE_STOP) { + const char *fn; + int line, col; + lht_dom_loc_active(doc, &fn, &line, &col); + Message("Resource error: %s (%s:%d.%d)*\n", lht_err_str(err), filename, line+1, col+1); + error = 1; + break; + } + break; /* error or stop, do not read anymore (would get LHTE_STOP without any processing all the time) */ + } + } + + if (error) { + lht_dom_uninit(doc); + doc = NULL; + } + fclose(f); + + return doc; +} + +const char *hid_cfg_text_value(lht_doc_t *doc, const char *path) +{ + lht_node_t *n = lht_tree_path(doc, "/", path, 1, NULL); + if (n == NULL) + return NULL; + if (n->type != LHT_TEXT) { + hid_cfg_error(n, "Error: node %s should be a text node\n", path); + return NULL; + } + return n->data.text.value; +} + +hid_cfg_t *hid_cfg_load(const char *hidname, const char *embedded_fallback) +{ + lht_doc_t *doc; + hid_cfg_t *hr; + +//static const char *pcbmenu_paths_in[] = { "gpcb-menu.res", "gpcb-menu.res", PCBSHAREDIR "/gpcb-menu.res", NULL }; + char *hidfn = strdup(hidname); /* TODO: search for the file */ + + doc = hid_cfg_load_lht(hidfn); + if (doc == NULL) + return NULL; + + hr = calloc(sizeof(hid_cfg_t), 1); /* make sure the cache is cleared */ + hr->doc = doc; + + return hr; +} + +void hid_cfg_action(const lht_node_t *node) +{ + if (node == NULL) + return; + switch(node->type) { + case LHT_TEXT: + hid_parse_actions(node->data.text.value); + break; + case LHT_LIST: + for(node = node->data.list.first; node != NULL; node = node->next) + if (node->type == LHT_TEXT) + hid_parse_actions(node->data.text.value); + break; + } +} + +/************* "parsing" **************/ + +lht_node_t *hid_cfg_get_menu(hid_cfg_t *hr, const char *menu_path) +{ + lht_err_t err; + return lht_tree_path(hr->doc, "/", menu_path, 1, &err); +} + +lht_node_t *hid_cfg_menu_field(const lht_node_t *submenu, hid_cfg_menufield_t field, const char **field_name) +{ + lht_node_t *n; + lht_err_t err; + const char *fieldstr = NULL; + + switch(field) { + case MF_ACCELERATOR: fieldstr = "a"; break; + case MF_MNEMONIC: fieldstr = "m"; break; + case MF_SUBMENU: fieldstr = "submenu"; break; + case MF_CHECKED: fieldstr = "checked"; break; + case MF_SENSITIVE: fieldstr = "sensitive"; break; + case MF_TIP: fieldstr = "tip"; break; + case MF_ACTIVE: fieldstr = "active"; break; + case MF_ACTION: fieldstr = "action"; break; + } + if (field_name != NULL) + *field_name = fieldstr; + + if (fieldstr == NULL) + return NULL; + + return lht_tree_path_(submenu->doc, (lht_node_t *)submenu, fieldstr, 1, 0, &err); +} + +const char *hid_cfg_menu_field_str(const lht_node_t *submenu, hid_cfg_menufield_t field) +{ + const char *fldname; + lht_node_t *n = hid_cfg_menu_field(submenu, field, &fldname); + + if (n == NULL) + return NULL; + if (n->type != LHT_TEXT) { + hid_cfg_error(submenu, "Error: field %s should be a text node\n", fldname); + return NULL; + } + return n->data.text.value; +} + +int hid_cfg_has_submenus(const lht_node_t *submenu) +{ + const char *fldname; + lht_node_t *n = hid_cfg_menu_field(submenu, MF_SUBMENU, &fldname); + if (n == NULL) + return 0; + if (n->type != LHT_LIST) { + hid_cfg_error(submenu, "Error: field %s should be a list (of submenus)\n", fldname); + return NULL; + } + return 1; +} + Index: trunk/src/hid_cfg.h =================================================================== --- trunk/src/hid_cfg.h (nonexistent) +++ trunk/src/hid_cfg.h (revision 1445) @@ -0,0 +1,87 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* Helpers for loading and handling lihata HID config files */ + +#ifndef PCB_HID_CFG_H +#define PCB_HID_CFG_H + +#include + +typedef struct hid_cfg_s { + lht_doc_t *doc; +} hid_cfg_t; + +/* Create a set of resources representing a single menu item */ +lht_node_t *resource_create_menu(hid_cfg_t *hr, const char *name, const char *action, const char *mnemonic, const char *accel, const char *tip, int flags); + +/* Search and load the menu res for hidname; if not found, and embedded_fallback + is not NULL, parse that string instead. Returns NULL on error */ +hid_cfg_t *hid_cfg_load(const char *hidname, const char *embedded_fallback); + +/* Generic, low level lihata loader */ +lht_doc_t *hid_cfg_load_lht(const char *filename); + +/* Generic, low level lihata text value fetch */ +const char *hid_cfg_text_value(lht_doc_t *doc, const char *path); + +lht_node_t *hid_cfg_get_menu(hid_cfg_t *hr, const char *menu_path); + +/* Fields are retrieved using this enum so that HIDs don't need to hardwire + lihata node names */ +typedef enum { + MF_ACCELERATOR, + MF_MNEMONIC, + MF_SUBMENU, + MF_CHECKED, + MF_SENSITIVE, + MF_TIP, + MF_ACTIVE, + MF_ACTION +} hid_cfg_menufield_t; + +/* Return a field of a submenu and optionally fill in field_name with the + field name expected in the lihata document (useful for error messages) */ +lht_node_t *hid_cfg_menu_field(const lht_node_t *submenu, hid_cfg_menufield_t field, const char **field_name); + +/* Return a text field of a submenu; return NULL and generate a Message() if + the given field is not text */ +const char *hid_cfg_menu_field_str(const lht_node_t *submenu, hid_cfg_menufield_t field); + +/* Return non-zero if submenu has further submenus; generate Message() if + there is a submenu field with the wrong lihata type */ +int hid_cfg_has_submenus(const lht_node_t *submenu); + +/* Run an action node. The node is either a list of text nodes or a text node */ +void hid_cfg_action(const lht_node_t *node); + +/* Report an error about a node */ +#define hid_cfg_error(node, ...) \ +do { \ + extern char hid_cfg_error_shared[]; \ + char *__end__; \ + __end__ = hid_cfg_error_shared + sprintf(hid_cfg_error_shared, "Error in lihata node %s:%d.%d:", node->file_name, node->line, node->col); \ + __end__ += sprintf(__end__, __VA_ARGS__); \ + Message(hid_cfg_error_shared); \ +} while(0) + +#endif Index: trunk/src/hid_cfg_input.c =================================================================== --- trunk/src/hid_cfg_input.c (nonexistent) +++ trunk/src/hid_cfg_input.c (revision 1445) @@ -0,0 +1,150 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 2016 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "hid.h" +#include "hid_cfg.h" +#include "hid_cfg_input.h" +#include "hid_actions.h" +#include "error.h" + +/* split value into a list of '-' separated words; examine each word + and set the bitmask of modifiers */ +static hid_cfg_mod_t parse_mods(const char *value) +{ + hid_cfg_mod_t m = 0; + int press = 0; + + for(;;) { + if (strncmp(value, "shift", 5) == 0) m |= M_Shift; + else if (strncmp(value, "ctrl", 4) == 0) m |= M_Ctrl; + else if (strncmp(value, "alt", 3) == 0) m |= M_Alt; + else if (strncmp(value, "release", 7) == 0) m |= M_Release; + else if (strncmp(value, "press", 5) == 0) press = 1; + else + Message("Unkown modifier: %s\n", value); + /* skip to next word */ + value = strchr(value, '-'); + if (value == NULL) + break; + value++; + } + + if (press && (m & M_Release)) + Message("Bogus modifier: both press and release\n"); + + return m; +} + +static hid_cfg_mod_t button_name2mask(const char *name) +{ + /* All mouse-related resources must be named. The name is the + mouse button number. */ + if (!name) + return 0; + else if (strcasecmp(name, "left") == 0) return MB_LEFT; + else if (strcasecmp(name, "middle") == 0) return MB_MIDDLE; + else if (strcasecmp(name, "right") == 0) return MB_RIGHT; + else if (strcasecmp(name, "up") == 0) return MB_UP; + else if (strcasecmp(name, "down") == 0) return MB_DOWN; + else { + Message("Error: unknown mouse button: %s\n", name); + return 0; + } +} + + +static int keyeq_int(htip_key_t a, htip_key_t b) { return a == b; } +static unsigned int keyhash_int(htip_key_t a) { return murmurhash32(a & 0xFFFF); } + +int hid_cfg_mouse_init(hid_cfg_t *hr, hid_cfg_mouse_t *mouse) +{ + lht_node_t *btn, *m; + + mouse->mouse = hid_cfg_get_menu(hr, "/mouse"); + + if (mouse->mouse == NULL) { + Message("Warning: no /mouse section in the resource file - mouse is disabled\n"); + return -1; + } + + if (mouse->mouse->type != LHT_LIST) { + hid_cfg_error(mouse->mouse, "Warning: should be a list - mouse is disabled\n"); + return -1; + } + + if (mouse->mouse_mask == NULL) + mouse->mouse_mask = htip_alloc(keyhash_int, keyeq_int); + else + htip_clear(mouse->mouse_mask); + + for(btn = mouse->mouse->data.list.first; btn != NULL; btn = btn->next) { + hid_cfg_mod_t btn_mask = button_name2mask(btn->name); + if (btn_mask == 0) { + hid_cfg_error(btn, "unknown mouse button"); + continue; + } + if (btn->type != LHT_LIST) { + hid_cfg_error(btn, "needs to be a list"); + continue; + } + for(m = btn->data.list.first; m != NULL; m = m->next) { + hid_cfg_mod_t mod_mask = parse_mods(m->name); + htip_set(mouse->mouse_mask, btn_mask|mod_mask, m); + } + } + return 0; +} + +static lht_node_t *find_best_action(hid_cfg_mouse_t *mouse, hid_cfg_mod_t button_and_mask) +{ + lht_node_t *n; + + if (mouse->mouse_mask == NULL) + return NULL; + + /* look for exact mod match */ + n = htip_get(mouse->mouse_mask, button_and_mask); + if (n != NULL) + return n; + + if (button_and_mask & M_Release) { + /* look for plain release for the given button */ + n = htip_get(mouse->mouse_mask, (button_and_mask & M_ANY) | M_Release); + if (n != NULL) + return n; + } + + return NULL; +} + +void hid_cfg_mouse_action(hid_cfg_mouse_t *mouse, hid_cfg_mod_t button_and_mask) +{ + hid_cfg_action(find_best_action(mouse, button_and_mask)); +} Index: trunk/src/hid_cfg_input.h =================================================================== --- trunk/src/hid_cfg_input.h (nonexistent) +++ trunk/src/hid_cfg_input.h (revision 1445) @@ -0,0 +1,38 @@ +#ifndef PCB_HID_CFG_INPUT_H +#define PCB_HID_CFG_INPUT_H + +#include +#include + +typedef struct { + lht_node_t *mouse; + htip_t *mouse_mask; +} hid_cfg_mouse_t; + +/* For compatibility; TODO: REMOVE */ +#define M_Mod(n) (1u<<(n+1)) + +#define M_Mod0(n) (1u<<(n)) +typedef enum { + M_Shift = M_Mod0(0), + M_Ctrl = M_Mod0(1), + M_Alt = M_Mod0(2), + M_Multi = M_Mod0(3), + /* M_Mod(3) is M_Mod0(4) */ + /* M_Mod(4) is M_Mod0(5) */ + M_Release = M_Mod0(6), /* there might be a random number of modkeys, but hopefully not this many */ + + MB_LEFT = M_Mod0(7), + MB_MIDDLE = M_Mod0(8), + MB_RIGHT = M_Mod0(9), + MB_UP = M_Mod0(10), /* scroll wheel */ + MB_DOWN = M_Mod0(11) /* scroll wheel */ +} hid_cfg_mod_t; + +#define MB_ANY (MB_LEFT | MB_MIDDLE | MB_RIGHT | MB_UP | MB_DOWN) +#define M_ANY (M_Release-1) + +int hid_cfg_mouse_init(hid_cfg_t *hr, hid_cfg_mouse_t *mouse); +void hid_cfg_mouse_action(hid_cfg_mouse_t *mouse, hid_cfg_mod_t button_and_mask); + +#endif Index: trunk/src/pcb-menu-gtk.lht =================================================================== --- trunk/src/pcb-menu-gtk.lht (revision 1444) +++ trunk/src/pcb-menu-gtk.lht (revision 1445) @@ -210,7 +210,7 @@ ha:Settings = { m=S li:submenu { - ha:'All-direction' lines = { checked=alldirection; a=.; action=Display(Toggle45Degree) } + ha:'All-direction' lines = { checked=alldirection; a=.; action=Display(ToggleAllDirections) } ha:Auto swap line start angle = { checked=swapstartdir; action=Display(ToggleStartDirection) } ha:Orthogonal moves = { checked=orthomove; action=Display(ToggleOrthoMove) } ha:Crosshair snaps to pins and pads = { checked=snappin; action=Display(ToggleSnapPin) } Index: trunk/src_plugins/hid_gtk/ghid-main-menu.c =================================================================== --- trunk/src_plugins/hid_gtk/ghid-main-menu.c (revision 1444) +++ trunk/src_plugins/hid_gtk/ghid-main-menu.c (revision 1445) @@ -161,15 +161,15 @@ const gchar *accel = NULL; char *menu_label; char *npath; - lht_node_t *n_action = hid_res_menu_field(sub_res, MF_ACTION, NULL); + lht_node_t *n_action = hid_cfg_menu_field(sub_res, MF_ACTION, NULL); /* Resolve accelerator */ - tmp_val = hid_res_menu_field_str(sub_res, MF_ACCELERATOR); + tmp_val = hid_cfg_menu_field_str(sub_res, MF_ACCELERATOR); if (tmp_val) accel = check_unique_accel(translate_accelerator(tmp_val)); /* Resolve the mnemonic */ - tmp_val = hid_res_menu_field_str(sub_res, MF_MNEMONIC); + tmp_val = hid_cfg_menu_field_str(sub_res, MF_MNEMONIC); if (tmp_val) mnemonic = tmp_val[0]; @@ -194,7 +194,7 @@ npath = Concat(path, "/", tmp_val, NULL); - if (hid_res_has_submenus(sub_res)) { + if (hid_cfg_has_submenus(sub_res)) { /* SUBMENU */ GtkWidget *submenu = gtk_menu_new(); GtkWidget *item = gtk_menu_item_new_with_mnemonic(menu_label); @@ -207,18 +207,18 @@ /* add tearoff to menu */ gtk_menu_shell_append(GTK_MENU_SHELL(submenu), tearoff); - /* recurse on the newly-added submenu; hid_res_has_submenus() makes sure + /* recurse on the newly-added submenu; hid_cfg_has_submenus() makes sure the node format is correct; iterate over the list of submenus and create them recursively. */ - n = hid_res_menu_field(sub_res, MF_SUBMENU, NULL); + n = hid_cfg_menu_field(sub_res, MF_SUBMENU, NULL); for(n = n->data.list.first; n != NULL; n = n->next) ghid_main_menu_real_add_resource(menu, GTK_MENU_SHELL(submenu), n, npath); } else { /* NON-SUBMENU: MENU ITEM */ - const char *checked = hid_res_menu_field_str(sub_res, MF_CHECKED); - const char *label = hid_res_menu_field_str(sub_res, MF_SENSITIVE); - const char *tip = hid_res_menu_field_str(sub_res, MF_TIP); + const char *checked = hid_cfg_menu_field_str(sub_res, MF_CHECKED); + const char *label = hid_cfg_menu_field_str(sub_res, MF_SENSITIVE); + const char *tip = hid_cfg_menu_field_str(sub_res, MF_TIP); if (checked) { /* TOGGLE ITEM */ gchar *name = g_strdup_printf("MainMenuAction%d", action_counter++); @@ -276,11 +276,11 @@ if (action) { const char *val; - val = hid_res_menu_field_str(res, MF_CHECKED); + val = hid_cfg_menu_field_str(res, MF_CHECKED); if (val != NULL) g_object_set_data(G_OBJECT(action), "checked-flag", (gpointer *)val); - val = hid_res_menu_field_str(res, MF_ACTIVE); + val = hid_cfg_menu_field_str(res, MF_ACTIVE); if (val != NULL) g_object_set_data(G_OBJECT(action), "active-flag", (gpointer *)val); } @@ -312,11 +312,11 @@ menu->route_style_pos = pos; } else - hid_res_error(res, "Unexpected text node; the only text accepted here is sep, -, @layerview, @layerpick and @routestyles"); + hid_cfg_error(res, "Unexpected text node; the only text accepted here is sep, -, @layerview, @layerpick and @routestyles"); } break; default: - hid_res_error(res, "Unexpected node type; should be hash (submenu) or text (separator or @special)"); + hid_cfg_error(res, "Unexpected node type; should be hash (submenu) or text (separator or @special)"); } } @@ -389,7 +389,7 @@ { lht_node_t *n; if (res->type != LHT_LIST) { - hid_res_error(res, "Menu description shall be a list (li)\n"); + hid_cfg_error(res, "Menu description shall be a list (li)\n"); abort(); } for(n = res->data.list.first; n != NULL; n = n->next) { @@ -405,7 +405,7 @@ submenu = lht_tree_path_(res->doc, (lht_node_t *)res, "submenu", 1, 0, NULL); if (submenu == NULL) { - hid_res_error(res, "can not create popup without submenu list"); + hid_cfg_error(res, "can not create popup without submenu list"); return; } @@ -443,7 +443,7 @@ GList *list; for (list = menu->actions; list; list = list->next) { lht_node_t *res = g_object_get_data(G_OBJECT(list->data), "resource"); - lht_node_t *act = hid_res_menu_field(res, MF_ACTION, NULL); + lht_node_t *act = hid_cfg_menu_field(res, MF_ACTION, NULL); const char *tf = g_object_get_data(G_OBJECT(list->data), "checked-flag"); const char *af = g_object_get_data(G_OBJECT(list->data), Index: trunk/src_plugins/hid_gtk/ghid-main-menu.h =================================================================== --- trunk/src_plugins/hid_gtk/ghid-main-menu.h (revision 1444) +++ trunk/src_plugins/hid_gtk/ghid-main-menu.h (revision 1445) @@ -7,7 +7,7 @@ #include "ghid-layer-selector.h" #include "ghid-route-style-selector.h" -#include "hid_resource.h" +#include "hid_cfg.h" G_BEGIN_DECLS /* keep c++ happy */ #define GHID_MAIN_MENU_TYPE (ghid_main_menu_get_type ()) @@ -34,7 +34,7 @@ void ghid_create_menu(const char *menu[], const char *action, const char *mnemonic, const char *accel, const char *tip); -extern hid_res_t *ghid_res; +extern hid_cfg_t *ghid_cfg; G_END_DECLS /* keep c++ happy */ #endif Index: trunk/src_plugins/hid_gtk/gui-output-events.c =================================================================== --- trunk/src_plugins/hid_gtk/gui-output-events.c (revision 1444) +++ trunk/src_plugins/hid_gtk/gui-output-events.c (revision 1445) @@ -30,7 +30,7 @@ #include "gui.h" #include "gtkhid.h" -#include "hid_resource.h" +#include "hid_cfg.h" #include @@ -268,7 +268,7 @@ return handled; } -static hid_res_mod_t ghid_mouse_button(int ev_button) +static hid_cfg_mod_t ghid_mouse_button(int ev_button) { /* GDK numbers buttons from 1..5, there seem to be no symbolic names */ return (MB_LEFT << (ev_button-1)); @@ -287,7 +287,7 @@ state = (GdkModifierType) (ev->state); mk = ghid_modifier_keys_state(&state); - hid_res_mouse_action(ghid_res, ghid_mouse_button(ev->button) | mk); + hid_cfg_mouse_action(&ghid_mouse, ghid_mouse_button(ev->button) | mk); ghid_invalidate_all(); ghid_window_set_name_label(PCB->Name); @@ -307,7 +307,7 @@ state = (GdkModifierType) (ev->state); mk = ghid_modifier_keys_state(&state); - hid_res_mouse_action(ghid_res, ghid_mouse_button(ev->button) | mk | M_Release); + hid_cfg_mouse_action(&ghid_mouse, ghid_mouse_button(ev->button) | mk | M_Release); AdjustAttachedObjects(); ghid_invalidate_all(); @@ -560,7 +560,7 @@ default: return FALSE; } - hid_res_mouse_action(ghid_res, button | mk); + hid_cfg_mouse_action(&ghid_mouse, button | mk); return TRUE; } Index: trunk/src_plugins/hid_gtk/gui-top-window.c =================================================================== --- trunk/src_plugins/hid_gtk/gui-top-window.c (revision 1444) +++ trunk/src_plugins/hid_gtk/gui-top-window.c (revision 1445) @@ -68,7 +68,7 @@ #include "gtkhid.h" #include "gui.h" #include "hid.h" -#include "hid_resource.h" +#include "hid_cfg.h" #include "action_helper.h" #include "buffer.h" #include "change.h" @@ -100,6 +100,7 @@ #include "paths.h" #include "gui-icons-mode-buttons.data" #include "gui-icons-misc.data" +#include "gui.h" #include "hid_attrib.h" #include "hid_actions.h" #include "hid_flags.h" @@ -114,7 +115,8 @@ GHidPort ghid_port, *gport; -hid_res_t *ghid_res = NULL; +hid_cfg_t *ghid_cfg = NULL; +hid_cfg_mouse_t ghid_mouse; static gchar *bg_image_file; @@ -309,7 +311,7 @@ if (action == NULL || node == NULL) return; - hid_res_action(node); + hid_cfg_action(node); /* Sync gui widgets with pcb state */ ghid_update_toggle_flags(); @@ -1758,19 +1760,19 @@ #warning TODO const char *gpcb_menu_default = NULL; - ghid_res = hid_res_load("gtk", gpcb_menu_default); - if (ghid_res == NULL) { + ghid_cfg = hid_cfg_load("gtk", gpcb_menu_default); + if (ghid_cfg == NULL) { Message("FATAL: can't load the gtk menu res either from file or from hardwired default."); abort(); } - mr = hid_res_get_menu(ghid_res, "/main_menu"); + mr = hid_cfg_get_menu(ghid_cfg, "/main_menu"); if (mr != NULL) { menu_bar = ghid_main_menu_new(G_CALLBACK(ghid_menu_cb), ghid_check_special_key); ghid_main_menu_add_resource(GHID_MAIN_MENU(menu_bar), mr); } - mr = hid_res_get_menu(ghid_res, "/popups"); + mr = hid_cfg_get_menu(ghid_cfg, "/popups"); if (mr != NULL) { if (mr->type == LHT_LIST) { lht_node_t *n; @@ -1778,7 +1780,7 @@ ghid_main_menu_add_popup_resource(GHID_MAIN_MENU(menu_bar), n); } else - hid_res_error(mr, "/popups should be a list"); + hid_cfg_error(mr, "/popups should be a list"); } #ifdef DEBUG_MENUS @@ -1785,9 +1787,9 @@ puts("Finished loading menus."); #endif -#warning TODO: - mr = hid_res_get_menu(ghid_res, "/mouse"); -/* load_mouse_resource(mr);*/ + mr = hid_cfg_get_menu(ghid_cfg, "/mouse"); + if (hid_cfg_mouse_init(ghid_cfg, &ghid_mouse) != 0) + Message("Error: failed to load mouse actions from the hid config lihata - mouse input will not work."); return menu_bar; } Index: trunk/src_plugins/hid_gtk/gui.h =================================================================== --- trunk/src_plugins/hid_gtk/gui.h (revision 1444) +++ trunk/src_plugins/hid_gtk/gui.h (revision 1445) @@ -29,7 +29,8 @@ #include "global.h" #include "hid.h" -#include "hid_resource.h" +#include "hid_cfg.h" +#include "hid_cfg_input.h" #include "data.h" #include "misc.h" @@ -513,5 +514,6 @@ } extern const char *ghid_cookie; +extern hid_cfg_mouse_t ghid_mouse; -#endif /* PCB_HID_GTK_GHID_H */ +#endif /* PCB_HID_GTK_GHID_GUI_H */ Index: trunk/src_plugins/vendordrill/vendor.c =================================================================== --- trunk/src_plugins/vendordrill/vendor.c (revision 1444) +++ trunk/src_plugins/vendordrill/vendor.c (revision 1445) @@ -60,7 +60,7 @@ #include "plugins.h" #include "hid_flags.h" #include "hid_actions.h" -#include "hid_resource.h" +#include "hid_cfg.h" #include #include @@ -298,7 +298,7 @@ FREE(ignore_descr); /* load the resource file */ - doc = hid_res_load_lht(fname); + doc = hid_cfg_load_lht(fname); if (doc == NULL) { Message(_("Could not load vendor resource file \"%s\"\n"), fname); return 1; @@ -305,10 +305,10 @@ } /* figure out the vendor name, if specified */ - vendor_name = (char *) UNKNOWN(hid_res_text_value(doc, "vendor")); + vendor_name = (char *) UNKNOWN(hid_cfg_text_value(doc, "vendor")); /* figure out the units, if specified */ - sval = hid_res_text_value(doc, "/units"); + sval = hid_cfg_text_value(doc, "/units"); if (sval == NULL) { sf = MIL_TO_COORD(1); } @@ -328,7 +328,7 @@ /* default to ROUND_UP */ rounding_method = ROUND_UP; - sval = hid_res_text_value(doc, "/round"); + sval = hid_cfg_text_value(doc, "/round"); if (sval != NULL) { if (NSTRCMP(sval, "up") == 0) { rounding_method = ROUND_UP; @@ -351,7 +351,7 @@ lht_node_t *n; for(n = drlres->data.list.first; n != NULL; n = n->next) { if (n->type != LHT_TEXT) - hid_res_error(n, "Broken drillmap: /drillmap should contain text children only\n"); + hid_cfg_error(n, "Broken drillmap: /drillmap should contain text children only\n"); else add_to_drills(n->data.text.value); } @@ -361,37 +361,37 @@ else Message(_("No drillmap resource found\n")); - sval = hid_res_text_value(doc, "/drc/copper_space"); + sval = hid_cfg_text_value(doc, "/drc/copper_space"); if (sval != NULL) { PCB->Bloat = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum copper spacing to %.2f mils\n"), 0.01 * PCB->Bloat); } - sval = hid_res_text_value(doc, "/drc/copper_overlap"); + sval = hid_cfg_text_value(doc, "/drc/copper_overlap"); if (sval != NULL) { PCB->Shrink = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum copper overlap to %.2f mils\n"), 0.01 * PCB->Shrink); } - sval = hid_res_text_value(doc, "/drc/copper_width"); + sval = hid_cfg_text_value(doc, "/drc/copper_width"); if (sval != NULL) { PCB->minWid = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum copper spacing to %.2f mils\n"), 0.01 * PCB->minWid); } - sval = hid_res_text_value(doc, "/drc/silk_width"); + sval = hid_cfg_text_value(doc, "/drc/silk_width"); if (sval != NULL) { PCB->minSlk = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum silk width to %.2f mils\n"), 0.01 * PCB->minSlk); } - sval = hid_res_text_value(doc, "/drc/min_drill"); + sval = hid_cfg_text_value(doc, "/drc/min_drill"); if (sval != NULL) { PCB->minDrill = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum drill diameter to %.2f mils\n"), 0.01 * PCB->minDrill); } - sval = hid_res_text_value(doc, "/drc/min_ring"); + sval = hid_cfg_text_value(doc, "/drc/min_ring"); if (sval != NULL) { PCB->minRing = floor(sf * atof(sval) + 0.5); Message(_("Set DRC minimum annular ring to %.2f mils\n"), 0.01 * PCB->minRing); @@ -644,7 +644,7 @@ return; if (res->type != LHT_LIST) - hid_res_error(res, "skips must be a list.\n"); + hid_cfg_error(res, "skips must be a list.\n"); for(n = res->data.list.first; n != NULL; n = n->next) { if (n->type == LHT_TEXT) { @@ -661,7 +661,7 @@ lst = &ignore_descr; } else { - hid_res_error(n, "invalid skip name; must be one of refdes, value, descr"); + hid_cfg_error(n, "invalid skip name; must be one of refdes, value, descr"); continue; } /* add the entry to the appropriate list */ @@ -674,7 +674,7 @@ (*lst)[*cnt - 1] = strdup(sval); } else - hid_res_error(n, "invalid skip type; must be text"); + hid_cfg_error(n, "invalid skip type; must be text"); } }