select.c: Remove Draw() call from SelectConnection
[geda-pcb/leaky.git] / src / vendor.c
bloba296aa172bc5ed35d480310195386ab2e67991ee
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 2004, 2007 Dan McMahill
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
29 #include <ctype.h>
30 #include <math.h>
31 #include <stdio.h>
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
45 #ifdef HAVE_REGEX_H
46 #include <regex.h>
47 #else
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51 #endif
53 #include "change.h"
54 #include "data.h"
55 #include "draw.h"
56 #include "error.h"
57 #include "global.h"
58 #include "resource.h"
59 #include "set.h"
60 #include "undo.h"
61 #include "vendor.h"
63 #ifdef HAVE_LIBDMALLOC
64 #include <dmalloc.h>
65 #endif
67 RCSID ("$Id$");
69 static void add_to_drills (char *);
70 static void apply_vendor_map (void);
71 static void process_skips (Resource *);
72 static bool rematch (const char *, const char *);
74 /* list of vendor drills and a count of them */
75 static int *vendor_drills = NULL;
76 static int n_vendor_drills = 0;
78 static int cached_drill = -1;
79 static int cached_map = -1;
81 /* lists of elements to ignore */
82 static char **ignore_refdes = NULL;
83 static int n_refdes = 0;
84 static char **ignore_value = NULL;
85 static int n_value = 0;
86 static char **ignore_descr = NULL;
87 static int n_descr = 0;
89 /* vendor name */
90 static char *vendor_name = NULL;
92 /* resource file to PCB units scale factor */
93 static double sf;
96 /* enable/disable mapping */
97 static bool vendorMapEnable = false;
99 /* type of drill mapping */
100 #define CLOSEST 1
101 #define ROUND_UP 0
102 static int rounding_method = ROUND_UP;
104 #define FREE(x) if((x) != NULL) { free (x) ; (x) = NULL; }
106 /* ************************************************************ */
108 static const char apply_vendor_syntax[] = "ApplyVendor()";
110 static const char apply_vendor_help[] =
111 "Applies the currently loaded vendor drill table to the current design.";
113 /* %start-doc actions ApplyVendor
114 @cindex vendor map
115 @cindex vendor drill table
116 @findex ApplyVendor()
118 This will modify all of your drill holes to match the list of allowed
119 sizes for your vendor.
120 %end-doc */
123 ActionApplyVendor (int argc, char **argv, int x, int y)
125 hid_action ("Busy");
126 apply_vendor_map ();
127 return 0;
130 /* ************************************************************ */
132 static const char toggle_vendor_syntax[] = "ToggleVendor()";
134 static const char toggle_vendor_help[] =
135 "Toggles the state of automatic drill size mapping.";
137 /* %start-doc actions ToggleVendor
139 @cindex vendor map
140 @cindex vendor drill table
141 @findex ToggleVendor()
143 When drill mapping is enabled, new instances of pins and vias will
144 have their drill holes mapped to one of the allowed drill sizes
145 specified in the currently loaded vendor drill table. To enable drill
146 mapping, a vendor resource file containing a drill table must be
147 loaded first.
149 %end-doc */
152 ActionToggleVendor (int argc, char **argv, int x, int y)
154 if (vendorMapEnable)
155 vendorMapEnable = false;
156 else
157 vendorMapEnable = true;
158 return 0;
161 /* ************************************************************ */
163 static const char enable_vendor_syntax[] = "EnableVendor()";
165 static const char enable_vendor_help[] =
166 "Enables automatic drill size mapping.";
168 /* %start-doc actions EnableVendor
170 @cindex vendor map
171 @cindex vendor drill table
172 @findex EnableVendor()
174 When drill mapping is enabled, new instances of pins and vias will
175 have their drill holes mapped to one of the allowed drill sizes
176 specified in the currently loaded vendor drill table. To enable drill
177 mapping, a vendor resource file containing a drill table must be
178 loaded first.
180 %end-doc */
183 ActionEnableVendor (int argc, char **argv, int x, int y)
185 vendorMapEnable = true;
186 return 0;
189 /* ************************************************************ */
191 static const char disable_vendor_syntax[] = "DisableVendor()";
193 static const char disable_vendor_help[] =
194 "Disables automatic drill size mapping.";
196 /* %start-doc actions DisableVendor
198 @cindex vendor map
199 @cindex vendor drill table
200 @findex DisableVendor()
202 When drill mapping is enabled, new instances of pins and vias will
203 have their drill holes mapped to one of the allowed drill sizes
204 specified in the currently loaded vendor drill table.
206 %end-doc */
209 ActionDisableVendor (int argc, char **argv, int x, int y)
211 vendorMapEnable = false;
212 return 0;
215 /* ************************************************************ */
217 static const char unload_vendor_syntax[] = "UnloadVendor()";
219 static const char unload_vendor_help[] =
220 "Unloads the current vendor drill mapping table.";
222 /* %start-doc actions UnloadVendor
224 @cindex vendor map
225 @cindex vendor drill table
226 @findex UnloadVendor()
228 %end-doc */
231 ActionUnloadVendor (int argc, char **argv, int x, int y)
233 cached_drill = -1;
235 /* Unload any vendor table we may have had */
236 n_vendor_drills = 0;
237 n_refdes = 0;
238 n_value = 0;
239 n_descr = 0;
240 FREE (vendor_drills);
241 FREE (ignore_refdes);
242 FREE (ignore_value);
243 FREE (ignore_descr);
244 return 0;
247 /* ************************************************************ */
249 static const char load_vendor_syntax[] = "LoadVendorFrom(filename)";
251 static const char load_vendor_help[] =
252 "Loads the specified vendor resource file.";
254 /* %start-doc actions LoadVendorFrom
256 @cindex vendor map
257 @cindex vendor drill table
258 @findex LoadVendorFrom()
260 @table @var
261 @item filename
262 Name of the vendor resource file. If not specified, the user will
263 be prompted to enter one.
264 @end table
266 %end-doc */
269 ActionLoadVendorFrom (int argc, char **argv, int x, int y)
271 int i;
272 char *fname = NULL;
273 static char *default_file = NULL;
274 char *sval;
275 Resource *res, *drcres, *drlres;
276 int type;
277 bool free_fname = false;
279 cached_drill = -1;
281 fname = argc ? argv[0] : 0;
283 if (!fname || !*fname)
285 fname = gui->fileselect (_("Load Vendor Resource File..."),
286 _("Picks a vendor resource file to load.\n"
287 "This file can contain drc settings for a\n"
288 "particular vendor as well as a list of\n"
289 "predefined drills which are allowed."),
290 default_file, ".res", "vendor",
291 HID_FILESELECT_READ);
292 if (fname == NULL)
293 AFAIL (load_vendor);
295 free_fname = true;
297 free (default_file);
298 default_file = NULL;
300 if (fname && *fname)
301 default_file = strdup (fname);
304 /* Unload any vendor table we may have had */
305 n_vendor_drills = 0;
306 n_refdes = 0;
307 n_value = 0;
308 n_descr = 0;
309 FREE (vendor_drills);
310 FREE (ignore_refdes);
311 FREE (ignore_value);
312 FREE (ignore_descr);
315 /* load the resource file */
316 res = resource_parse (fname, NULL);
317 if (res == NULL)
319 Message (_("Could not load vendor resource file \"%s\"\n"), fname);
320 return 1;
323 /* figure out the vendor name, if specified */
324 vendor_name = UNKNOWN (resource_value (res, "vendor"));
326 /* figure out the units, if specified */
327 sval = resource_value (res, "units");
328 if (sval == NULL)
330 sf = 100;
332 else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0))
334 sf = 100;
336 else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0))
338 sf = 100000;
340 else if (NSTRCMP (sval, "mm") == 0)
343 * divide by .0254 to convert mm to mils. Then multiply by 100
344 * for PCB units
346 sf = (100.0 / 0.0254);
348 else
350 Message ("\"%s\" is not a supported units. Defaulting to inch\n",
351 sval);
352 sf = 100000;
356 /* default to ROUND_UP */
357 rounding_method = ROUND_UP;
359 /* extract the drillmap resource */
360 drlres = resource_subres (res, "drillmap");
361 if (drlres == NULL)
363 Message (_("No drillmap resource found\n"));
365 else
367 sval = resource_value (drlres, "round");
368 if (sval != NULL)
370 if (NSTRCMP (sval, "up") == 0)
372 rounding_method = ROUND_UP;
374 else if (NSTRCMP (sval, "nearest") == 0)
376 rounding_method = CLOSEST;
378 else
380 Message (_
381 ("\"%s\" is not a valid rounding type. Defaulting to up\n"),
382 sval);
383 rounding_method = ROUND_UP;
387 process_skips (resource_subres (drlres, "skips"));
389 for (i = 0; i < drlres->c; i++)
391 type = resource_type (drlres->v[i]);
392 switch (type)
394 case 10:
395 /* just a number */
396 add_to_drills (drlres->v[i].value);
397 break;
399 default:
400 break;
405 /* Extract the DRC resource */
406 drcres = resource_subres (res, "drc");
408 sval = resource_value (drcres, "copper_space");
409 if (sval != NULL)
411 PCB->Bloat = floor (sf * atof (sval) + 0.5);
412 Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
413 0.01 * PCB->Bloat);
416 sval = resource_value (drcres, "copper_overlap");
417 if (sval != NULL)
419 PCB->Shrink = floor (sf * atof (sval) + 0.5);
420 Message (_("Set DRC minimum copper overlap to %.2f mils\n"),
421 0.01 * PCB->Shrink);
424 sval = resource_value (drcres, "copper_width");
425 if (sval != NULL)
427 PCB->minWid = floor (sf * atof (sval) + 0.5);
428 Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
429 0.01 * PCB->minWid);
432 sval = resource_value (drcres, "silk_width");
433 if (sval != NULL)
435 PCB->minSlk = floor (sf * atof (sval) + 0.5);
436 Message (_("Set DRC minimum silk width to %.2f mils\n"),
437 0.01 * PCB->minSlk);
440 sval = resource_value (drcres, "min_drill");
441 if (sval != NULL)
443 PCB->minDrill = floor (sf * atof (sval) + 0.5);
444 Message (_("Set DRC minimum drill diameter to %.2f mils\n"),
445 0.01 * PCB->minDrill);
448 sval = resource_value (drcres, "min_ring");
449 if (sval != NULL)
451 PCB->minRing = floor (sf * atof (sval) + 0.5);
452 Message (_("Set DRC minimum annular ring to %.2f mils\n"),
453 0.01 * PCB->minRing);
456 Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname);
457 Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"),
458 n_refdes, n_value, n_descr);
460 vendorMapEnable = true;
461 apply_vendor_map ();
462 if (free_fname)
463 free (fname);
464 return 0;
467 static void
468 apply_vendor_map (void)
470 int i;
471 int changed, tot;
472 bool state;
474 state = vendorMapEnable;
476 /* enable mapping */
477 vendorMapEnable = true;
479 /* reset our counts */
480 changed = 0;
481 tot = 0;
483 /* If we have loaded vendor drills, then apply them to the design */
484 if (n_vendor_drills > 0)
487 /* first all the vias */
488 VIA_LOOP (PCB->Data);
490 tot++;
491 if (via->DrillingHole != vendorDrillMap (via->DrillingHole))
493 /* only change unlocked vias */
494 if (!TEST_FLAG (LOCKFLAG, via))
496 if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL,
497 vendorDrillMap (via->DrillingHole),
498 true, false))
499 changed++;
500 else
502 Message (_
503 ("Via at %.2f, %.2f not changed. Possible reasons:\n"
504 "\t- pad size too small\n"
505 "\t- new size would be too large or too small\n"),
506 0.01 * via->X, 0.01 * via->Y);
509 else
511 Message (_("Locked via at %.2f, %.2f not changed.\n"),
512 0.01 * via->X, 0.01 * via->Y);
516 END_LOOP;
518 /* and now the pins */
519 ELEMENT_LOOP (PCB->Data);
522 * first figure out if this element should be skipped for some
523 * reason
525 if (vendorIsElementMappable (element))
527 /* the element is ok to modify, so iterate over its pins */
528 PIN_LOOP (element);
530 tot++;
531 if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole))
533 if (!TEST_FLAG (LOCKFLAG, pin))
535 if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL,
536 vendorDrillMap (pin->
537 DrillingHole),
538 true, false))
539 changed++;
540 else
542 Message (_
543 ("Pin %s (%s) at %.2f, %.2f (element %s, %s, %s) not changed.\n"
544 "\tPossible reasons:\n"
545 "\t- pad size too small\n"
546 "\t- new size would be too large or too small\n"),
547 UNKNOWN (pin->Number), UNKNOWN (pin->Name),
548 0.01 * pin->X, 0.01 * pin->Y,
549 UNKNOWN (NAMEONPCB_NAME (element)),
550 UNKNOWN (VALUE_NAME (element)),
551 UNKNOWN (DESCRIPTION_NAME (element)));
554 else
556 Message (_
557 ("Locked pin at %-6.2f, %-6.2f not changed.\n"),
558 0.01 * pin->X, 0.01 * pin->Y);
562 END_LOOP;
565 END_LOOP;
567 Message (_("Updated %d drill sizes out of %d total\n"), changed, tot);
569 /* Update the current Via */
570 if (Settings.ViaDrillingHole !=
571 vendorDrillMap (Settings.ViaDrillingHole))
573 changed++;
574 Settings.ViaDrillingHole =
575 vendorDrillMap (Settings.ViaDrillingHole);
576 Message (_("Adjusted active via hole size to be %6.2f mils\n"),
577 0.01 * Settings.ViaDrillingHole);
580 /* and update the vias for the various routing styles */
581 for (i = 0; i < NUM_STYLES; i++)
583 if (PCB->RouteStyle[i].Hole !=
584 vendorDrillMap (PCB->RouteStyle[i].Hole))
586 changed++;
587 PCB->RouteStyle[i].Hole =
588 vendorDrillMap (PCB->RouteStyle[i].Hole);
589 Message (_
590 ("Adjusted %s routing style via hole size to be %6.2f mils\n"),
591 PCB->RouteStyle[i].Name,
592 0.01 * PCB->RouteStyle[i].Hole);
593 if (PCB->RouteStyle[i].Diameter <
594 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER)
596 PCB->RouteStyle[i].Diameter =
597 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER;
598 Message (_
599 ("Increased %s routing style via diameter to %6.2f mils\n"),
600 PCB->RouteStyle[i].Name,
601 0.01 * PCB->RouteStyle[i].Diameter);
607 * if we've changed anything, indicate that we need to save the
608 * file, redraw things, and make sure we can undo.
610 if (changed)
612 SetChangedFlag (true);
613 ClearAndRedrawOutput ();
614 IncrementUndoSerialNumber ();
618 /* restore mapping on/off */
619 vendorMapEnable = state;
622 /* for a given drill size, find the closest vendor drill size */
624 vendorDrillMap (int in)
626 int i, min, max;
628 if (in == cached_drill)
629 return cached_map;
630 cached_drill = in;
632 /* skip the mapping if we don't have a vendor drill table */
633 if ((n_vendor_drills == 0) || (vendor_drills == NULL)
634 || (vendorMapEnable == false))
636 cached_map = in;
637 return in;
640 /* are we smaller than the smallest drill? */
641 if (in <= vendor_drills[0])
643 cached_map = vendor_drills[0];
644 return vendor_drills[0];
647 /* are we larger than the largest drill? */
648 if (in > vendor_drills[n_vendor_drills - 1])
650 Message (_("Vendor drill list does not contain a drill >= %6.2f mil\n"
651 "Using %6.2f mil instead.\n"),
652 0.01 * in, 0.01 * vendor_drills[n_vendor_drills - 1]);
653 cached_map = vendor_drills[n_vendor_drills - 1];
654 return vendor_drills[n_vendor_drills - 1];
657 /* figure out which 2 drills are closest in size */
658 min = 0;
659 max = n_vendor_drills - 1;
660 while (max - min > 1)
662 i = (max+min) / 2;
663 if (in > vendor_drills[i])
664 min = i;
665 else
666 max = i;
668 i = max;
670 /* now round per the rounding mode */
671 if (rounding_method == CLOSEST)
673 /* find the closest drill size */
674 if ((in - vendor_drills[i - 1]) > (vendor_drills[i] - in))
676 cached_map = vendor_drills[i];
677 return vendor_drills[i];
679 else
681 cached_map = vendor_drills[i - 1];
682 return vendor_drills[i - 1];
685 else
687 /* always round up */
688 cached_map = vendor_drills[i];
689 return vendor_drills[i];
694 /* add a drill size to the vendor drill list */
695 static void
696 add_to_drills (char *sval)
698 double tmpd;
699 int val;
700 int k, j;
702 /* increment the count and make sure we have memory */
703 n_vendor_drills++;
704 if ((vendor_drills = realloc (vendor_drills,
705 n_vendor_drills * sizeof (int))) == NULL)
707 fprintf (stderr, "realloc() failed to allocate %ld bytes\n",
708 (unsigned long) n_vendor_drills * sizeof (int));
709 return;
712 /* string to a value with the units scale factor in place */
713 tmpd = atof (sval);
714 val = floor (sf * tmpd + 0.5);
717 * We keep the array of vendor drills sorted to make it easier to
718 * do the rounding later. The algorithm used here is not so efficient,
719 * but we're not dealing with much in the way of data.
722 /* figure out where to insert the value to keep the array sorted. */
723 k = 0;
724 while ((k < n_vendor_drills - 1) && (vendor_drills[k] < val))
725 k++;
727 if (k == n_vendor_drills - 1)
729 vendor_drills[n_vendor_drills - 1] = val;
731 else
733 /* move up the existing drills to make room */
734 for (j = n_vendor_drills - 1; j > k; j--)
736 vendor_drills[j] = vendor_drills[j - 1];
739 vendor_drills[k] = val;
743 /* deal with the "skip" subresource */
744 static void
745 process_skips (Resource * res)
747 int type;
748 int i, k;
749 char *sval;
750 int *cnt;
751 char ***lst = NULL;
753 if (res == NULL)
754 return;
756 for (i = 0; i < res->c; i++)
758 type = resource_type (res->v[i]);
759 switch (type)
761 case 1:
763 * an unnamed sub resource. This is something like
764 * {refdes "J3"}
766 sval = res->v[i].subres->v[0].value;
767 if (sval == NULL)
769 Message ("Error: null skip value\n");
771 else
773 if (NSTRCMP (sval, "refdes") == 0)
775 cnt = &n_refdes;
776 lst = &ignore_refdes;
778 else if (NSTRCMP (sval, "value") == 0)
780 cnt = &n_value;
781 lst = &ignore_value;
783 else if (NSTRCMP (sval, "descr") == 0)
785 cnt = &n_descr;
786 lst = &ignore_descr;
788 else
790 cnt = NULL;
793 /* add the entry to the appropriate list */
794 if (cnt != NULL)
796 for (k = 1; k < res->v[i].subres->c; k++)
798 sval = res->v[i].subres->v[k].value;
799 (*cnt)++;
800 if ((*lst =
801 (char **) realloc (*lst,
802 (*cnt) * sizeof (char *))) ==
803 NULL)
805 fprintf (stderr, "realloc() failed\n");
806 exit (-1);
808 (*lst)[*cnt - 1] = strdup (sval);
812 break;
814 default:
815 Message (_("Ignored resource type = %d in skips= section\n"), type);
821 bool
822 vendorIsElementMappable (ElementTypePtr element)
824 int i;
825 int noskip;
827 if (vendorMapEnable == false)
828 return false;
830 noskip = 1;
831 for (i = 0; i < n_refdes; i++)
833 if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) ==
835 || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element))))
837 Message (_
838 ("Vendor mapping skipped because refdes = %s matches %s\n"),
839 UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]);
840 noskip = 0;
843 if (noskip)
844 for (i = 0; i < n_value; i++)
846 if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0)
847 || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element))))
849 Message (_
850 ("Vendor mapping skipped because value = %s matches %s\n"),
851 UNKNOWN (VALUE_NAME (element)), ignore_value[i]);
852 noskip = 0;
856 if (noskip)
857 for (i = 0; i < n_descr; i++)
859 if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i])
860 == 0)
861 || rematch (ignore_descr[i],
862 UNKNOWN (DESCRIPTION_NAME (element))))
864 Message (_
865 ("Vendor mapping skipped because descr = %s matches %s\n"),
866 UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]);
867 noskip = 0;
871 if (noskip && TEST_FLAG (LOCKFLAG, element))
873 Message (_("Vendor mapping skipped because element %s is locked\n"),
874 UNKNOWN (NAMEONPCB_NAME (element)));
875 noskip = 0;
878 if (noskip)
879 return true;
880 else
881 return false;
884 static bool
885 rematch (const char *re, const char *s)
888 * If this system has regular expression capability, then
889 * add support for regular expressions in the skip lists.
892 #if defined(HAVE_REGCOMP)
894 int result;
895 regmatch_t match;
896 regex_t compiled;
898 /* compile the regular expression */
899 result = regcomp (&compiled, re, REG_EXTENDED | REG_ICASE | REG_NOSUB);
900 if (result)
902 char errorstring[128];
904 regerror (result, &compiled, errorstring, sizeof (errorstring));
905 Message ("regexp error: %s\n", errorstring);
906 regfree (&compiled);
907 return (false);
910 result = regexec (&compiled, s, 1, &match, 0);
911 regfree (&compiled);
913 if (result == 0)
914 return (true);
915 else
916 return (false);
918 #elif defined(HAVE_RE_COMP)
919 int m;
920 char *rslt;
922 /* compile the regular expression */
923 if ((rslt = re_comp (re)) != NULL)
925 Message ("re_comp error: %s\n", rslt);
926 return (false);
929 m = re_exec (s);
931 switch m
933 case 1:
934 return (true);
935 break;
937 case 0:
938 return (false);
939 break;
941 default:
942 Message ("re_exec error\n");
943 break;
946 #else
947 return (false);
948 #endif
952 HID_Action vendor_action_list[] = {
953 {"ApplyVendor", 0, ActionApplyVendor,
954 apply_vendor_help, apply_vendor_syntax}
956 {"ToggleVendor", 0, ActionToggleVendor,
957 toggle_vendor_help, toggle_vendor_syntax}
959 {"EnableVendor", 0, ActionEnableVendor,
960 enable_vendor_help, enable_vendor_syntax}
962 {"DisableVendor", 0, ActionDisableVendor,
963 disable_vendor_help, disable_vendor_syntax}
965 {"UnloadVendor", 0, ActionUnloadVendor,
966 unload_vendor_help, unload_vendor_syntax}
968 {"LoadVendorFrom", 0, ActionLoadVendorFrom,
969 load_vendor_help, load_vendor_syntax}
972 REGISTER_ACTIONS (vendor_action_list)
973 static int vendor_get_enabled (int unused)
975 return vendorMapEnable;
978 HID_Flag vendor_flag_list[] = {
979 {"VendorMapOn", vendor_get_enabled, 0}
982 REGISTER_FLAGS (vendor_flag_list)