Board outline polygon generation
[geda-pcb/pcjc2.git] / src / vendor.c
blob9391404a01f741d6c1aec9bfb4ae814830c3cdf9
1 /*
2 * COPYRIGHT
4 * PCB, interactive printed circuit board design
5 * Copyright (C) 2004, 2007 Dan McMahill
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include <ctype.h>
28 #include <math.h>
29 #include <stdio.h>
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
41 #endif
43 #ifdef HAVE_REGEX_H
44 #include <regex.h>
45 #else
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 #endif
51 #include "change.h"
52 #include "data.h"
53 #include "draw.h"
54 #include "error.h"
55 #include "global.h"
56 #include "resource.h"
57 #include "set.h"
58 #include "undo.h"
59 #include "vendor.h"
61 #ifdef HAVE_LIBDMALLOC
62 #include <dmalloc.h>
63 #endif
65 static void add_to_drills (char *);
66 static void apply_vendor_map (void);
67 static void process_skips (Resource *);
68 static bool rematch (const char *, const char *);
70 /* list of vendor drills and a count of them */
71 static int *vendor_drills = NULL;
72 static int n_vendor_drills = 0;
74 static int cached_drill = -1;
75 static int cached_map = -1;
77 /* lists of elements to ignore */
78 static char **ignore_refdes = NULL;
79 static int n_refdes = 0;
80 static char **ignore_value = NULL;
81 static int n_value = 0;
82 static char **ignore_descr = NULL;
83 static int n_descr = 0;
85 /* vendor name */
86 static char *vendor_name = NULL;
88 /* resource file to PCB units scale factor */
89 static double sf;
92 /* enable/disable mapping */
93 static bool vendorMapEnable = false;
95 /* type of drill mapping */
96 #define CLOSEST 1
97 #define ROUND_UP 0
98 static int rounding_method = ROUND_UP;
100 #define FREE(x) if((x) != NULL) { free (x) ; (x) = NULL; }
102 /* ************************************************************ */
104 static const char apply_vendor_syntax[] = N_("ApplyVendor()");
106 static const char apply_vendor_help[] =
107 N_("Applies the currently loaded vendor drill table to the current design.");
109 /* %start-doc actions ApplyVendor
110 @cindex vendor map
111 @cindex vendor drill table
112 @findex ApplyVendor()
114 This will modify all of your drill holes to match the list of allowed
115 sizes for your vendor.
116 %end-doc */
119 ActionApplyVendor (int argc, char **argv, Coord x, Coord y)
121 hid_action ("Busy");
122 apply_vendor_map ();
123 return 0;
126 /* ************************************************************ */
128 static const char toggle_vendor_syntax[] = N_("ToggleVendor()");
130 static const char toggle_vendor_help[] =
131 N_("Toggles the state of automatic drill size mapping.");
133 /* %start-doc actions ToggleVendor
135 @cindex vendor map
136 @cindex vendor drill table
137 @findex ToggleVendor()
139 When drill mapping is enabled, new instances of pins and vias will
140 have their drill holes mapped to one of the allowed drill sizes
141 specified in the currently loaded vendor drill table. To enable drill
142 mapping, a vendor resource file containing a drill table must be
143 loaded first.
145 %end-doc */
148 ActionToggleVendor (int argc, char **argv, Coord x, Coord y)
150 if (vendorMapEnable)
151 vendorMapEnable = false;
152 else
153 vendorMapEnable = true;
154 return 0;
157 /* ************************************************************ */
159 static const char enable_vendor_syntax[] = N_("EnableVendor()");
161 static const char enable_vendor_help[] =
162 N_("Enables automatic drill size mapping.");
164 /* %start-doc actions EnableVendor
166 @cindex vendor map
167 @cindex vendor drill table
168 @findex EnableVendor()
170 When drill mapping is enabled, new instances of pins and vias will
171 have their drill holes mapped to one of the allowed drill sizes
172 specified in the currently loaded vendor drill table. To enable drill
173 mapping, a vendor resource file containing a drill table must be
174 loaded first.
176 %end-doc */
179 ActionEnableVendor (int argc, char **argv, Coord x, Coord y)
181 vendorMapEnable = true;
182 return 0;
185 /* ************************************************************ */
187 static const char disable_vendor_syntax[] = N_("DisableVendor()");
189 static const char disable_vendor_help[] =
190 N_("Disables automatic drill size mapping.");
192 /* %start-doc actions DisableVendor
194 @cindex vendor map
195 @cindex vendor drill table
196 @findex DisableVendor()
198 When drill mapping is enabled, new instances of pins and vias will
199 have their drill holes mapped to one of the allowed drill sizes
200 specified in the currently loaded vendor drill table.
202 %end-doc */
205 ActionDisableVendor (int argc, char **argv, Coord x, Coord y)
207 vendorMapEnable = false;
208 return 0;
211 /* ************************************************************ */
213 static const char unload_vendor_syntax[] = N_("UnloadVendor()");
215 static const char unload_vendor_help[] =
216 N_("Unloads the current vendor drill mapping table.");
218 /* %start-doc actions UnloadVendor
220 @cindex vendor map
221 @cindex vendor drill table
222 @findex UnloadVendor()
224 %end-doc */
227 ActionUnloadVendor (int argc, char **argv, Coord x, Coord y)
229 cached_drill = -1;
231 /* Unload any vendor table we may have had */
232 n_vendor_drills = 0;
233 n_refdes = 0;
234 n_value = 0;
235 n_descr = 0;
236 FREE (vendor_drills);
237 FREE (ignore_refdes);
238 FREE (ignore_value);
239 FREE (ignore_descr);
240 return 0;
243 /* ************************************************************ */
245 static const char load_vendor_syntax[] = N_("LoadVendorFrom(filename)");
247 static const char load_vendor_help[] =
248 N_("Loads the specified vendor resource file.");
250 /* %start-doc actions LoadVendorFrom
252 @cindex vendor map
253 @cindex vendor drill table
254 @findex LoadVendorFrom()
256 @table @var
257 @item filename
258 Name of the vendor resource file. If not specified, the user will
259 be prompted to enter one.
260 @end table
262 %end-doc */
265 ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y)
267 int i;
268 char *fname = NULL;
269 static char *default_file = NULL;
270 char *sval;
271 Resource *res, *drcres, *drlres;
272 int type;
273 bool free_fname = false;
275 cached_drill = -1;
277 fname = argc ? argv[0] : 0;
279 if (!fname || !*fname)
281 fname = gui->fileselect (_("Load Vendor Resource File..."),
282 _("Picks a vendor resource file to load.\n"
283 "This file can contain drc settings for a\n"
284 "particular vendor as well as a list of\n"
285 "predefined drills which are allowed."),
286 default_file, ".res", "vendor",
287 HID_FILESELECT_READ);
288 if (fname == NULL)
289 AFAIL (load_vendor);
291 free_fname = true;
293 free (default_file);
294 default_file = NULL;
296 if (fname && *fname)
297 default_file = strdup (fname);
300 /* Unload any vendor table we may have had */
301 n_vendor_drills = 0;
302 n_refdes = 0;
303 n_value = 0;
304 n_descr = 0;
305 FREE (vendor_drills);
306 FREE (ignore_refdes);
307 FREE (ignore_value);
308 FREE (ignore_descr);
311 /* load the resource file */
312 res = resource_parse (fname, NULL);
313 if (res == NULL)
315 Message (_("Could not load vendor resource file \"%s\"\n"), fname);
316 return 1;
319 /* figure out the vendor name, if specified */
320 vendor_name = (char *)UNKNOWN (resource_value (res, "vendor"));
322 /* figure out the units, if specified */
323 sval = resource_value (res, "units");
324 if (sval == NULL)
326 sf = MIL_TO_COORD(1);
328 else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0))
330 sf = MIL_TO_COORD(1);
332 else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0))
334 sf = INCH_TO_COORD(1);
336 else if (NSTRCMP (sval, "mm") == 0)
338 sf = MM_TO_COORD(1);
340 else
342 Message (_("\"%s\" is not a supported units. Defaulting to inch\n"),
343 sval);
344 sf = INCH_TO_COORD(1);
348 /* default to ROUND_UP */
349 rounding_method = ROUND_UP;
351 /* extract the drillmap resource */
352 drlres = resource_subres (res, "drillmap");
353 if (drlres == NULL)
355 Message (_("No drillmap resource found\n"));
357 else
359 sval = resource_value (drlres, "round");
360 if (sval != NULL)
362 if (NSTRCMP (sval, "up") == 0)
364 rounding_method = ROUND_UP;
366 else if (NSTRCMP (sval, "nearest") == 0)
368 rounding_method = CLOSEST;
370 else
372 Message (_("\"%s\" is not a valid rounding type. "
373 "Defaulting to up\n"),
374 sval);
375 rounding_method = ROUND_UP;
379 process_skips (resource_subres (drlres, "skips"));
381 for (i = 0; i < drlres->c; i++)
383 type = resource_type (drlres->v[i]);
384 switch (type)
386 case 10:
387 /* just a number */
388 add_to_drills (drlres->v[i].value);
389 break;
391 default:
392 break;
397 /* Extract the DRC resource */
398 drcres = resource_subres (res, "drc");
400 sval = resource_value (drcres, "copper_space");
401 if (sval != NULL)
403 PCB->Bloat = floor (sf * atof (sval) + 0.5);
404 Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
405 0.01 * PCB->Bloat);
408 sval = resource_value (drcres, "copper_overlap");
409 if (sval != NULL)
411 PCB->Shrink = floor (sf * atof (sval) + 0.5);
412 Message (_("Set DRC minimum copper overlap to %.2f mils\n"),
413 0.01 * PCB->Shrink);
416 sval = resource_value (drcres, "copper_width");
417 if (sval != NULL)
419 PCB->minWid = floor (sf * atof (sval) + 0.5);
420 Message (_("Set DRC minimum copper spacing to %.2f mils\n"),
421 0.01 * PCB->minWid);
424 sval = resource_value (drcres, "silk_width");
425 if (sval != NULL)
427 PCB->minSlk = floor (sf * atof (sval) + 0.5);
428 Message (_("Set DRC minimum silk width to %.2f mils\n"),
429 0.01 * PCB->minSlk);
432 sval = resource_value (drcres, "min_drill");
433 if (sval != NULL)
435 PCB->minDrill = floor (sf * atof (sval) + 0.5);
436 Message (_("Set DRC minimum drill diameter to %.2f mils\n"),
437 0.01 * PCB->minDrill);
440 sval = resource_value (drcres, "min_ring");
441 if (sval != NULL)
443 PCB->minRing = floor (sf * atof (sval) + 0.5);
444 Message (_("Set DRC minimum annular ring to %.2f mils\n"),
445 0.01 * PCB->minRing);
448 Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname);
449 Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"),
450 n_refdes, n_value, n_descr);
452 vendorMapEnable = true;
453 apply_vendor_map ();
454 if (free_fname)
455 free (fname);
456 return 0;
459 static void
460 apply_vendor_map (void)
462 int i;
463 int changed, tot;
464 bool state;
466 state = vendorMapEnable;
468 /* enable mapping */
469 vendorMapEnable = true;
471 /* reset our counts */
472 changed = 0;
473 tot = 0;
475 /* If we have loaded vendor drills, then apply them to the design */
476 if (n_vendor_drills > 0)
479 /* first all the vias */
480 VIA_LOOP (PCB->Data);
482 tot++;
483 if (via->DrillingHole != vendorDrillMap (via->DrillingHole))
485 /* only change unlocked vias */
486 if (!TEST_FLAG (LOCKFLAG, via))
488 if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL,
489 vendorDrillMap (via->DrillingHole),
490 true, false))
491 changed++;
492 else
494 Message (_("Via at %.2f, %.2f not changed. "
495 "Possible reasons:\n"
496 "\t- pad size too small\n"
497 "\t- new size would be too large or too small\n"),
498 0.01 * via->X, 0.01 * via->Y);
501 else
503 Message (_("Locked via at %.2f, %.2f not changed.\n"),
504 0.01 * via->X, 0.01 * via->Y);
508 END_LOOP;
510 /* and now the pins */
511 ELEMENT_LOOP (PCB->Data);
514 * first figure out if this element should be skipped for some
515 * reason
517 if (vendorIsElementMappable (element))
519 /* the element is ok to modify, so iterate over its pins */
520 PIN_LOOP (element);
522 tot++;
523 if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole))
525 if (!TEST_FLAG (LOCKFLAG, pin))
527 if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL,
528 vendorDrillMap (pin->
529 DrillingHole),
530 true, false))
531 changed++;
532 else
534 Message (_("Pin %s (%s) at %.2f, %.2f "
535 "(element %s, %s, %s) not changed.\n"
536 "\tPossible reasons:\n"
537 "\t- pad size too small\n"
538 "\t- new size would be too large or too small\n"),
539 UNKNOWN (pin->Number), UNKNOWN (pin->Name),
540 0.01 * pin->X, 0.01 * pin->Y,
541 UNKNOWN (NAMEONPCB_NAME (element)),
542 UNKNOWN (VALUE_NAME (element)),
543 UNKNOWN (DESCRIPTION_NAME (element)));
546 else
548 Message (_("Locked pin at %-6.2f, %-6.2f not changed.\n"),
549 0.01 * pin->X, 0.01 * pin->Y);
553 END_LOOP;
556 END_LOOP;
558 Message (_("Updated %d drill sizes out of %d total\n"), changed, tot);
560 /* Update the current Via */
561 if (Settings.ViaDrillingHole !=
562 vendorDrillMap (Settings.ViaDrillingHole))
564 changed++;
565 Settings.ViaDrillingHole =
566 vendorDrillMap (Settings.ViaDrillingHole);
567 Message (_("Adjusted active via hole size to be %6.2f mils\n"),
568 0.01 * Settings.ViaDrillingHole);
571 /* and update the vias for the various routing styles */
572 for (i = 0; i < NUM_STYLES; i++)
574 if (PCB->RouteStyle[i].Hole !=
575 vendorDrillMap (PCB->RouteStyle[i].Hole))
577 changed++;
578 PCB->RouteStyle[i].Hole =
579 vendorDrillMap (PCB->RouteStyle[i].Hole);
580 Message (_("Adjusted %s routing style via hole size to be "
581 "%6.2f mils\n"),
582 PCB->RouteStyle[i].Name,
583 0.01 * PCB->RouteStyle[i].Hole);
584 if (PCB->RouteStyle[i].Diameter <
585 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER)
587 PCB->RouteStyle[i].Diameter =
588 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER;
589 Message (_("Increased %s routing style via diameter to "
590 "%6.2f mils\n"),
591 PCB->RouteStyle[i].Name,
592 0.01 * PCB->RouteStyle[i].Diameter);
598 * if we've changed anything, indicate that we need to save the
599 * file, redraw things, and make sure we can undo.
601 if (changed)
603 SetChangedFlag (true);
604 Redraw ();
605 IncrementUndoSerialNumber ();
609 /* restore mapping on/off */
610 vendorMapEnable = state;
613 /* for a given drill size, find the closest vendor drill size */
615 vendorDrillMap (int in)
617 int i, min, max;
619 if (in == cached_drill)
620 return cached_map;
621 cached_drill = in;
623 /* skip the mapping if we don't have a vendor drill table */
624 if ((n_vendor_drills == 0) || (vendor_drills == NULL)
625 || (vendorMapEnable == false))
627 cached_map = in;
628 return in;
631 /* are we smaller than the smallest drill? */
632 if (in <= vendor_drills[0])
634 cached_map = vendor_drills[0];
635 return vendor_drills[0];
638 /* are we larger than the largest drill? */
639 if (in > vendor_drills[n_vendor_drills - 1])
641 Message (_("Vendor drill list does not contain a drill >= %6.2f mil\n"
642 "Using %6.2f mil instead.\n"),
643 0.01 * in, 0.01 * vendor_drills[n_vendor_drills - 1]);
644 cached_map = vendor_drills[n_vendor_drills - 1];
645 return vendor_drills[n_vendor_drills - 1];
648 /* figure out which 2 drills are closest in size */
649 min = 0;
650 max = n_vendor_drills - 1;
651 while (max - min > 1)
653 i = (max+min) / 2;
654 if (in > vendor_drills[i])
655 min = i;
656 else
657 max = i;
659 i = max;
661 /* now round per the rounding mode */
662 if (rounding_method == CLOSEST)
664 /* find the closest drill size */
665 if ((in - vendor_drills[i - 1]) > (vendor_drills[i] - in))
667 cached_map = vendor_drills[i];
668 return vendor_drills[i];
670 else
672 cached_map = vendor_drills[i - 1];
673 return vendor_drills[i - 1];
676 else
678 /* always round up */
679 cached_map = vendor_drills[i];
680 return vendor_drills[i];
685 /* add a drill size to the vendor drill list */
686 static void
687 add_to_drills (char *sval)
689 double tmpd;
690 int val;
691 int k, j;
693 /* increment the count and make sure we have memory */
694 n_vendor_drills++;
695 if ((vendor_drills = (int *)realloc (vendor_drills,
696 n_vendor_drills * sizeof (int))) == NULL)
698 fprintf (stderr, _("realloc() failed to allocate %ld bytes\n"),
699 (unsigned long) n_vendor_drills * sizeof (int));
700 return;
703 /* string to a value with the units scale factor in place */
704 tmpd = atof (sval);
705 val = floor (sf * tmpd + 0.5);
708 * We keep the array of vendor drills sorted to make it easier to
709 * do the rounding later. The algorithm used here is not so efficient,
710 * but we're not dealing with much in the way of data.
713 /* figure out where to insert the value to keep the array sorted. */
714 k = 0;
715 while ((k < n_vendor_drills - 1) && (vendor_drills[k] < val))
716 k++;
718 if (k == n_vendor_drills - 1)
720 vendor_drills[n_vendor_drills - 1] = val;
722 else
724 /* move up the existing drills to make room */
725 for (j = n_vendor_drills - 1; j > k; j--)
727 vendor_drills[j] = vendor_drills[j - 1];
730 vendor_drills[k] = val;
734 /* deal with the "skip" subresource */
735 static void
736 process_skips (Resource * res)
738 int type;
739 int i, k;
740 char *sval;
741 int *cnt;
742 char ***lst = NULL;
744 if (res == NULL)
745 return;
747 for (i = 0; i < res->c; i++)
749 type = resource_type (res->v[i]);
750 switch (type)
752 case 1:
754 * an unnamed sub resource. This is something like
755 * {refdes "J3"}
757 sval = res->v[i].subres->v[0].value;
758 if (sval == NULL)
760 Message (_("Error: null skip value\n"));
762 else
764 if (NSTRCMP (sval, "refdes") == 0)
766 cnt = &n_refdes;
767 lst = &ignore_refdes;
769 else if (NSTRCMP (sval, "value") == 0)
771 cnt = &n_value;
772 lst = &ignore_value;
774 else if (NSTRCMP (sval, "descr") == 0)
776 cnt = &n_descr;
777 lst = &ignore_descr;
779 else
781 cnt = NULL;
784 /* add the entry to the appropriate list */
785 if (cnt != NULL)
787 for (k = 1; k < res->v[i].subres->c; k++)
789 sval = res->v[i].subres->v[k].value;
790 (*cnt)++;
791 if ((*lst =
792 (char **) realloc (*lst,
793 (*cnt) * sizeof (char *))) ==
794 NULL)
796 fprintf (stderr, _("realloc() failed\n"));
797 exit (-1);
799 (*lst)[*cnt - 1] = strdup (sval);
803 break;
805 default:
806 Message (_("Ignored resource type = %d in skips= section\n"), type);
812 bool
813 vendorIsElementMappable (ElementType *element)
815 int i;
816 int noskip;
818 if (vendorMapEnable == false)
819 return false;
821 noskip = 1;
822 for (i = 0; i < n_refdes; i++)
824 if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) ==
826 || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element))))
828 Message (_("Vendor mapping skipped because "
829 "refdes = %s matches %s\n"),
830 UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]);
831 noskip = 0;
834 if (noskip)
835 for (i = 0; i < n_value; i++)
837 if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0)
838 || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element))))
840 Message (_("Vendor mapping skipped because "
841 "value = %s matches %s\n"),
842 UNKNOWN (VALUE_NAME (element)), ignore_value[i]);
843 noskip = 0;
847 if (noskip)
848 for (i = 0; i < n_descr; i++)
850 if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i])
851 == 0)
852 || rematch (ignore_descr[i],
853 UNKNOWN (DESCRIPTION_NAME (element))))
855 Message (_("Vendor mapping skipped because "
856 "descr = %s matches %s\n"),
857 UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]);
858 noskip = 0;
862 if (noskip && TEST_FLAG (LOCKFLAG, element))
864 Message (_("Vendor mapping skipped because element %s is locked\n"),
865 UNKNOWN (NAMEONPCB_NAME (element)));
866 noskip = 0;
869 if (noskip)
870 return true;
871 else
872 return false;
875 static bool
876 rematch (const char *re, const char *s)
879 * If this system has regular expression capability, then
880 * add support for regular expressions in the skip lists.
883 #if defined(HAVE_REGCOMP)
885 int result;
886 regmatch_t match;
887 regex_t compiled;
889 /* compile the regular expression */
890 result = regcomp (&compiled, re, REG_EXTENDED | REG_ICASE | REG_NOSUB);
891 if (result)
893 char errorstring[128];
895 regerror (result, &compiled, errorstring, sizeof (errorstring));
896 Message (_("regexp error: %s\n"), errorstring);
897 regfree (&compiled);
898 return (false);
901 result = regexec (&compiled, s, 1, &match, 0);
902 regfree (&compiled);
904 if (result == 0)
905 return (true);
906 else
907 return (false);
909 #elif defined(HAVE_RE_COMP)
910 int m;
911 char *rslt;
913 /* compile the regular expression */
914 if ((rslt = re_comp (re)) != NULL)
916 Message (_("re_comp error: %s\n"), rslt);
917 return (false);
920 m = re_exec (s);
922 switch m
924 case 1:
925 return (true);
926 break;
928 case 0:
929 return (false);
930 break;
932 default:
933 Message (_("re_exec error\n"));
934 break;
937 #else
938 return (false);
939 #endif
943 HID_Action vendor_action_list[] = {
944 {"ApplyVendor", 0, ActionApplyVendor,
945 apply_vendor_help, apply_vendor_syntax}
947 {"ToggleVendor", 0, ActionToggleVendor,
948 toggle_vendor_help, toggle_vendor_syntax}
950 {"EnableVendor", 0, ActionEnableVendor,
951 enable_vendor_help, enable_vendor_syntax}
953 {"DisableVendor", 0, ActionDisableVendor,
954 disable_vendor_help, disable_vendor_syntax}
956 {"UnloadVendor", 0, ActionUnloadVendor,
957 unload_vendor_help, unload_vendor_syntax}
959 {"LoadVendorFrom", 0, ActionLoadVendorFrom,
960 load_vendor_help, load_vendor_syntax}
963 REGISTER_ACTIONS (vendor_action_list)
965 static int vendor_get_enabled (void *data)
967 return vendorMapEnable;
970 HID_Flag vendor_flag_list[] = {
971 {"VendorMapOn", vendor_get_enabled, NULL}
974 REGISTER_FLAGS (vendor_flag_list)