Heres a patch that should install specctra.c --- On Sun, 7/26/09, Josh Jordan <outerspacema...@yahoo.com> wrote:
From: Josh Jordan <outerspacema...@yahoo.com> Subject: gEDA-user: dsn exporter To: geda-user@moria.seul.org Date: Sunday, July 26, 2009, 3:46 PM This exporter outputs a .dsn file for opening with freeroute.net. It only works on 2 layer designs so far. I did not start writing an importer for it yet, if anyone has suggestions on the architecture of this I will listen. (.cmd file?) I will be out of town for the next 10 days and then I will work on the importer. To install it, make a specctra directory in the hid directory, put this file in it, a copy of hid.conf, make a change to makefile.am in /src, and make install again. -----Inline Attachment Follows----- _______________________________________________ geda-user mailing list [1]geda-u...@moria.seul.org [2]http://www.seul.org/cgi-bin/mailman/listinfo/geda-user References 1. file://localhost/mc/compose?to=geda-u...@moria.seul.org 2. http://www.seul.org/cgi-bin/mailman/listinfo/geda-user
From 86ae4751febed03dd601d96142c5e9051e3e545c Mon Sep 17 00:00:00 2001 From: Josh <jo...@joshq-laptop.(none)> Date: Sun, 26 Jul 2009 16:34:41 -0400 Subject: [PATCH] specctra dsn exporter 2 layers only --- src/hid/specctra/hid.conf | 1 + src/hid/specctra/specctra.c | 837 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 838 insertions(+), 0 deletions(-) create mode 100644 src/hid/specctra/hid.conf create mode 100644 src/hid/specctra/specctra.c diff --git a/src/hid/specctra/hid.conf b/src/hid/specctra/hid.conf new file mode 100644 index 0000000..7be6c4c --- /dev/null +++ b/src/hid/specctra/hid.conf @@ -0,0 +1 @@ +type=export diff --git a/src/hid/specctra/specctra.c b/src/hid/specctra/specctra.c new file mode 100644 index 0000000..1dab7b5 --- /dev/null +++ b/src/hid/specctra/specctra.c @@ -0,0 +1,837 @@ +/* +This program exports specctra .dsn files from geda .pcb files. +By Josh Jordan +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "global.h" +#include "data.h" +#include "error.h" +#include "misc.h" +#include "gts.h" +#include "rats.h" +#include "buffer.h" +#include "parse_l.h" + +#include "hid.h" +#include "../hidint.h" + +#ifdef HAVE_LIBDMALLOC +#include <dmalloc.h> +#endif + +static HID_Attribute specctra_options[] = { + {"specctrafile", "SPECCTRA output file", + HID_String, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_specctrafile 0 + {"trackwidth", "default track width in mils", + HID_Integer, 0, 0, {0, 0, 0}, 0, 0}, +#define HA_trackwidth 1 +}; + +#define NUM_OPTIONS (sizeof(specctra_options)/sizeof(specctra_options[0])) + +static HID_Attr_Val specctra_values[NUM_OPTIONS]; + +static char *specctra_filename; + +typedef struct _StringList +{ + char *str; + struct _StringList *next; +} StringList; + +typedef struct _SpecctraList +{ + char *descr; + char *value; + int num; + StringList *refdes; + struct _SpecctraList *next; +} SpecctraList; + +static HID_Attribute * +specctra_get_export_options (int *n) +{ + static char *last_specctra_filename = 0; + if (PCB) { + derive_default_filename(PCB->Filename, &specctra_options[HA_specctrafile], ".dsn", &last_specctra_filename); + } + + if (n) + *n = NUM_OPTIONS; + return specctra_options; +} + + +static char * +CleanSPECCTRAString (char *in) +{ + char *out; + int i; + + if ((out = malloc ((strlen (in) + 1) * sizeof (char))) == NULL) + { + fprintf (stderr, "Error: CleanSPECCTRAString() malloc() failed\n"); + exit (1); + } + + /* + * copy over in to out with some character conversions. + * Go all the way to then end to get the terminating \0 + */ + for (i = 0; i <= strlen (in); i++) + { + switch (in[i]) + { + case '"': + out[i] = '\''; + break; + default: + out[i] = in[i]; + } + } + + return out; +} + + +static double +xyToAngle (double x, double y) +{ + double theta; + + if ((x > 0.0) && (y >= 0.0)) + theta = 180.0; + else if ((x <= 0.0) && (y > 0.0)) + theta = 90.0; + else if ((x < 0.0) && (y <= 0.0)) + theta = 0.0; + else if ((x >= 0.0) && (y < 0.0)) + theta = 270.0; + else + { + theta = 0.0; + Message ("xyToAngle(): unable to figure out angle of element\n" + " because the pin is at the centroid of the part.\n" + " This is a BUG!!!\n" + " Setting to %g degrees\n", theta); + } + + return (theta); +} + +typedef struct { + double centx; + double centy; + int rot; +} CentroidRotation; + +/* this function is mostly ripped from bom.c + it gives only absolute rotation, it must be + compared to the absolute rotation of the library part*/ +static CentroidRotation +get_rotation_and_centroid (ElementType *element){ + CentroidRotation centrot; + int found_pin1; + int found_pin2; + int pin_cnt; + double x, y, theta = 0.0, user_x, user_y; + double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0; + double pin2x = 0.0, pin2y = 0.0, pin2angle; + double sumx, sumy; + /* initialize our pin count and our totals for finding the centriod */ + pin_cnt = 0; + sumx = 0.0; + sumy = 0.0; + found_pin1 = 0; + found_pin2 = 0; + /* + * iterate over the pins and pads keeping a running count of how + * many pins/pads total and the sum of x and y coordinates + * + * While we're at it, store the location of pin/pad #1 and #2 if + * we can find them + */ + + PIN_LOOP (element); + { + sumx += (double) pin->X; + sumy += (double) pin->Y; + pin_cnt++; + + if (NSTRCMP (pin->Number, "1") == 0) + { + pin1x = (double) pin->X; + pin1y = (double) pin->Y; + pin1angle = 0.0; /* pins have no notion of angle */ + found_pin1 = 1; + } + else if (NSTRCMP (pin->Number, "2") == 0) + { + pin2x = (double) pin->X; + pin2y = (double) pin->Y; + pin2angle = 0.0; /* pins have no notion of angle */ + found_pin2 = 1; + } + } + END_LOOP; + + PAD_LOOP (element); + { + sumx += (pad->Point1.X + pad->Point2.X) / 2.0; + sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0; + pin_cnt++; + + if (NSTRCMP (pad->Number, "1") == 0) + { + pin1x = (double) (pad->Point1.X + pad->Point2.X) / 2.0; + pin1y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0; + /* + * NOTE: We swap the Y points because in PCB, the Y-axis + * is inverted. Increasing Y moves down. We want to deal + * in the usual increasing Y moves up coordinates though. + */ + pin1angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, + pad->Point2.X - pad->Point1.X); + found_pin1 = 1; + } + else if (NSTRCMP (pad->Number, "2") == 0) + { + pin2x = (double) (pad->Point1.X + pad->Point2.X) / 2.0; + pin2y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0; + pin2angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, + pad->Point2.X - pad->Point1.X); + found_pin2 = 1; + } + + } + END_LOOP; + + if (pin_cnt > 0) + { + x = sumx / (double) pin_cnt; + y = sumy / (double) pin_cnt; + + if (found_pin1) + { + /* recenter pin #1 onto the axis which cross at the part + centroid */ + pin1x -= x; + pin1y -= y; + pin1y = -1.0 * pin1y; + + /* if only 1 pin, use pin 1's angle */ + if (pin_cnt == 1) + theta = pin1angle; + else + { + /* if pin #1 is at (0,0) use pin #2 for rotation */ + if ((pin1x == 0.0) && (pin1y == 0.0)) + { + if (found_pin2) + theta = xyToAngle (pin2x, pin2y); + else + { + Message + ("SPECCTRA EXPORTER: unable to figure out angle of element\n" + " %s because pin #1 is at the centroid of the part.\n" + " and I could not find pin #2's location\n" + " Setting to %g degrees\n", + UNKNOWN (NAMEONPCB_NAME (element)), theta); + } + } + else + theta = xyToAngle (pin1x, pin1y); + } + } + /* we did not find pin #1 */ + else + { + theta = 0.0; + Message + ("SPECCTRA EXPORTER: unable to figure out angle because I could\n" + " not find pin #1 of element %s\n" + " Setting to %g degrees\n", + UNKNOWN (NAMEONPCB_NAME (element)), theta); + } + y = PCB->MaxHeight - y; + + /* dimensions in mils */ + user_x = 0.01 * x; + user_y = 0.01 * y; + centrot.centx = user_x; + centrot.centy = user_y; + centrot.rot = theta; + return centrot; + } +} + + +static StringList * +string_insert (char *str, StringList * list) +{ + StringList *new, *cur; + + if ((new = (StringList *) malloc (sizeof (StringList))) == NULL) + { + fprintf (stderr, "malloc() failed in string_insert()\n"); + exit (1); + } + + new->next = NULL; + new->str = strdup (str); + + if (list == NULL) + return (new); + + cur = list; + while (cur->next != NULL) + cur = cur->next; + + cur->next = new; + + return (list); +} + +static SpecctraList * +specctra_insert (char *refdes, char *descr, char *value, SpecctraList * specctra) +{ + SpecctraList *new, *cur, *prev = NULL; + + if (specctra == NULL) + { + /* this is the first element so automatically create an entry */ + if ((new = (SpecctraList *) malloc (sizeof (SpecctraList))) == NULL) + { + fprintf (stderr, "malloc() failed in specctra_insert()\n"); + exit (1); + } + + new->next = NULL; + new->descr = strdup (descr); + new->value = strdup (value); + new->num = 1; + new->refdes = string_insert (refdes, NULL); + return (new); + } + + /* search and see if we already have used one of these + components */ + cur = specctra; + while (cur != NULL) + { + if ((NSTRCMP (descr, cur->descr) == 0) && + (NSTRCMP (value, cur->value) == 0)) + { + cur->num++; + cur->refdes = string_insert (refdes, cur->refdes); + break; + } + prev = cur; + cur = cur->next; + } + + if (cur == NULL) + { + if ((new = (SpecctraList *) malloc (sizeof (SpecctraList))) == NULL) + { + fprintf (stderr, "malloc() failed in specctra_insert()\n"); + exit (1); + } + + prev->next = new; + + new->next = NULL; + new->descr = strdup (descr); + new->value = strdup (value); + new->num = 1; + new->refdes = string_insert (refdes, NULL); + } + + return (specctra); + +} + +/* + * If fp is not NULL then print out the bill of materials contained in + * specctra. Either way, free all memory which has been allocated for specctra. + */ +static void +print_and_free (FILE *fp, SpecctraList *specctra) +{ + SpecctraList *lastb; + StringList *lasts; + char *descr, *value; + + while (specctra != NULL) + { + if (fp) + { + descr = CleanSPECCTRAString (specctra->descr); + value = CleanSPECCTRAString (specctra->value); + fprintf (fp, "%d,\"%s\",\"%s\",", specctra->num, descr, value); + free (descr); + free (value); + } + + while (specctra->refdes != NULL) + { + if (fp) + { + fprintf (fp, "%s ", specctra->refdes->str); + } + free (specctra->refdes->str); + lasts = specctra->refdes; + specctra->refdes = specctra->refdes->next; + free (lasts); + } + if (fp) + { + fprintf (fp, "\n"); + } + lastb = specctra; + specctra = specctra->next; + free (lastb); + } +} + +static void +print_structure (FILE *fp) +{ + fprintf (fp, " (structure\n"); + + /* define layers */ + fprintf (fp, " (layer Component\n"); + fprintf (fp, " (type signal)\n"); + fprintf (fp, " (property\n"); + fprintf (fp, " (index 0)\n )\n )\n"); + fprintf (fp, " (layer Copper\n"); + fprintf (fp, " (type signal)\n"); + fprintf (fp, " (property\n"); + fprintf (fp, " (index 1)\n )\n )\n"); + + /* PCB outline */ + fprintf (fp, " (boundary\n"); + fprintf (fp, " (rect pcb 0.0 0.0 %.2f %.2f)\n", PCB->MaxWidth*0.01, PCB->MaxHeight*0.01); + fprintf (fp, " )\n"); + + fprintf (fp, " (via \"via_45_25_mil\")\n"); + + /* DRC rules */ + fprintf (fp, " (rule\n"); + fprintf (fp, " (width 8)\n"); + fprintf (fp, " (clear 10)\n"); + fprintf (fp, " (clear 10 (type wire_area))\n"); + fprintf (fp, " (clear 10 (type via_smd via_pin))\n"); + fprintf (fp, " (clear 10 (type smd_smd))\n"); + fprintf (fp, " (clear 10 (type default_smd))\n"); + fprintf (fp, " )\n )\n"); +} + +static void +print_placement (FILE *fp) +/* gather all footprint names in a list + gather list of refdes for each footprint in list */ +{ + int i; + GList *footprints; //contain unique footprint names + fprintf (fp, " (placement\n"); + ELEMENT_LOOP (PCB->Data); + { + gconstpointer descript = DESCRIPTION_NAME (element); + if( !g_list_find_custom( footprints, descript, strcmp ) ){ + footprints = g_list_append( footprints, descript ); + } + } + END_LOOP; + for(i=0; i < g_list_length( footprints ); i++){ + int firstrot = -1; //change to the degree of the first element found + fprintf (fp, " (component %s\n", g_list_nth_data( footprints, i )); + ELEMENT_LOOP (PCB->Data); + { + if(!strcmp(DESCRIPTION_NAME (element), g_list_nth_data( footprints, i ) )){ + CentroidRotation crot = get_rotation_and_centroid(element); + if (firstrot == -1) + { + firstrot = crot.rot; + } + char* side = TEST_FLAG (ONSOLDERFLAG, element) ? "back" : "front"; + fprintf (fp, " (place %s %.2f %.2f %s %d (PN %s))\n", NAMEONPCB_NAME (element), crot.centx, crot.centy, side, firstrot-crot.rot, VALUE_NAME (element) ); + } + } + END_LOOP; + fprintf (fp, " )\n"); + } + fprintf (fp, " )\n"); + g_list_free( footprints ); +} + +static void +print_library (FILE *fp) +/* gather all footprint names in a list + print info on each footprint */ +{ + int i; + GList *footprints; //contain unique footprint names + GList *pads; //contain unique pad names + fprintf (fp, " (library\n"); + ELEMENT_LOOP (PCB->Data); + { + if( !g_list_find_custom( footprints, DESCRIPTION_NAME (element), strcmp ) ){ + char *padstack; + int rotation; + int whichside = TEST_FLAG (ONSOLDERFLAG, element) ? -1 : 1; + CentroidRotation crot = get_rotation_and_centroid(element); + footprints = g_list_append( footprints, g_strdup( DESCRIPTION_NAME (element) ) ); + fprintf (fp, " (image %s\n", DESCRIPTION_NAME (element) ); + /* loop thru pins and pads here */ + PIN_LOOP (element); + { + int ty; + float pinthickness; + float lx, ly; //hold local pin coordinates + ty = PCB->MaxHeight - pin->Y; + pinthickness = pin->Thickness*0.01; + padstack = g_strdup_printf ("Th_round_%.0f_mil", pinthickness); + lx = (pin->X*0.01-crot.centx)*whichside; + ly = (crot.centy - ty*0.01)*(-1); + if( !g_list_find_custom( pads, padstack, strcmp ) ) + { + pads = g_list_append( pads, padstack ); + } + if (!pin->Number) //if pin is null just make it a keepout + { + fprintf (fp, " (keepout \"\" (circle Component %.0f %.2f %.2f))\n", pinthickness, lx, ly); + fprintf (fp, " (keepout \"\" (circle Copper %.0f %.2f %.2f))\n", pinthickness, lx, ly); + } + else + { + fprintf (fp, " (pin %s %s %.2f %.2f)\n", padstack, pin->Number, lx, ly); + } + } + END_LOOP; + PAD_LOOP (element); + { + int xlen, ylen, xc, yc, p1y, p2y; + float lx, ly; //store local coordinates for pins + p1y = PCB->MaxHeight - pad->Point1.Y; + p2y = PCB->MaxHeight - pad->Point2.Y; + /* pad dimensions are thickness and point difference plus thickness */ + xlen = (ABS(pad->Point1.X - pad->Point2.X)+50)/100; //round to mil + if (xlen == 0) + { + xlen = (pad->Thickness+50)/100; //round to mil + ylen = (ABS(p1y - p2y)+50)/100 + xlen; //round to mil + } + else + { + ylen = (pad->Thickness+50)/100; + xlen += ylen; + } + xc = (pad->Point1.X + pad->Point2.X)/2; + yc = (p1y + p2y)/2; + lx = (xc*0.01-crot.centx)*whichside; + ly = (crot.centy - yc*0.01)*(-1); + padstack = g_strdup_printf ("Smd_rect_%dx%d_mil", xlen, ylen); + if( !g_list_find_custom( pads, padstack, strcmp ) ) + { + pads = g_list_append( pads, padstack ); + } + if (!pad->Number) //if pad is null just make it a keepout + { + fprintf (fp, " (keepout \"\" (rect %s %.2f %.2f %.2f %.2f))\n", (whichside == 1) ? "Component" : "Copper", lx-xlen/2, ly-ylen/2, lx+xlen/2, ly+ylen/2); + } + else + { + fprintf (fp, " (pin %s %s %.2f %.2f)\n", padstack, pad->Number, lx, ly); + } + } + END_LOOP; + fprintf (fp, " )\n"); + } + } + END_LOOP; + /* loop thru padstacks and define them all */ + for(i=0; i < g_list_length( pads ); i++) + { + int retargs, dim1, dim2; + char * padstring = g_list_nth_data( pads, i ); + fprintf (fp, " (padstack %s\n", padstring); + /* print info about pad here */ + retargs = sscanf (padstring, "Smd_rect_%dx%d_mil", &dim1, &dim2); + if (retargs == 2) //then pad is smd + { + fprintf (fp, " (shape (rect Component %.1f %.1f %.1f %.1f))\n", dim1/(-2.0), dim2/(-2.0), dim1/2.0, dim2/2.0); + } + else ///then pad is th + { + retargs = sscanf (padstring, "Th_round_%d_mil", &dim1); + fprintf (fp, " (shape (circle Component %d))\n", dim1); + fprintf (fp, " (shape (circle Copper %d))\n", dim1); + } + fprintf (fp, " (attach off)\n"); + fprintf (fp, " )\n"); + } + /* add padstack for via */ + fprintf (fp, " (padstack \"via_45_25_mil\"\n (shape (circle Component 45))\n (shape (circle Copper 45))\n (attach off)\n )\n"); + fprintf (fp, " )\n"); + g_list_foreach( footprints, (GFunc)g_free, NULL ); + g_list_free( footprints ); + g_list_foreach( pads, (GFunc)g_free, NULL ); + g_list_free( pads ); +} + +static void +print_network (FILE *fp) +{ + GList *netlistnames; //contain unique strings of netlist names + int i, firstcon; + NetListListType Nets; + Nets = CollectSubnets (False); + fprintf (fp, " (network\n"); + NETLIST_LOOP (&Nets); + { + firstcon = 1; //clear flag after net name is found + NET_LOOP (netlist); + { + CONNECTION_LOOP (net); + { + int ni, nei; + char *ename; + char *pname; + char *n; + char *netname; + /* looking for pins and pads */ + if (connection->type == PIN_TYPE || connection->type == PAD_TYPE) + { + PinTypePtr thispin; + PadTypePtr thispad; + ElementTypePtr thiselem; + if (connection->type == PIN_TYPE) + { + thispin = connection->ptr2; + thiselem = thispin->Element; + pname = thispin->Number; + } + else + { + thispad = connection->ptr2; + thiselem = thispad->Element; + pname = thispad->Number; + } + ename = NAMEONPCB_NAME(thiselem); + n = g_strconcat (ename, "-", pname, NULL); + for (ni = 0; ni < PCB->NetlistLib.MenuN; ni++) //loop thru all nets + for (nei = 0; nei < PCB->NetlistLib.Menu[ni].EntryN; nei++) //loop thru all entries in all nets + { + if (strcmp (PCB->NetlistLib.Menu[ni].Entry[nei].ListEntry, n) == 0) //find the entry that matches this pin or pad + { + netname = g_strdup (PCB->NetlistLib.Menu[ni].Name + 2); //find the net name of this entry + //if( !g_list_find_custom( netlistnames, netname, strcmp ) ) //see if netlist was written down already + if(firstcon == 1) + { + firstcon = 0; + netlistnames = g_list_append( netlistnames, netname ); + fprintf (fp, " (net %s\n (pins", netname); + } + } + } + fprintf (fp, " %s", n); + g_free(n); + } + } + END_LOOP; + } + END_LOOP; + fprintf (fp, ")\n )\n"); + } + END_LOOP; + fprintf (fp, " (class geda_default"); + for(i=0; i < g_list_length( netlistnames ); i++) + { + fprintf (fp, " %s", g_list_nth_data( netlistnames, i ) ); + } + fprintf (fp, "\n (circuit\n (use_via via_45_25_mil)\n )\n"); + fprintf (fp, " (rule (width 8))\n )\n )\n"); + fprintf (fp, " (wiring\n )\n)\n"); + + g_list_foreach( netlistnames, (GFunc)g_free, NULL ); + g_list_free( netlistnames ); +} + +static int +PrintSPECCTRA (void) +{ + char utcTime[64]; + double x, y, theta = 0.0, user_x, user_y; + double sumx, sumy; + double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0; + double pin2x = 0.0, pin2y = 0.0, pin2angle; + int found_pin1; + int found_pin2; + int pin_cnt; + time_t currenttime; + FILE *fp; + SpecctraList *specctra = NULL; + char *name, *descr, *value; + + /* Print out the specctra .dsn file. */ + + fp = fopen (specctra_filename, "w"); + if (!fp) + { + gui->log ("Cannot open file %s for writing\n", specctra_filename); + print_and_free (NULL, specctra); + return 1; + } + + /* pcb [required] */ + fprintf (fp, "(pcb %s\n", ((PCB->Name) && *(PCB->Name) ? (PCB->Name) : "notnamed")); + + /* parser descriptor [optional] */ + fprintf (fp, " (parser\n"); + fprintf (fp, " (string_quote \")\n"); + fprintf (fp, " (space_in_quoted_tokens on)\n"); + fprintf (fp, " (host_cad \"gEDA PCB\")\n"); + fprintf (fp, " (host_version \"(i dunno?)\")\n"); + fprintf (fp, " )\n"); + + /* capacitance resolution descriptor [optional] */ + + /* conductance resolution descriptor [optional] */ + + /* current resolution descriptor [optional] */ + + /* inductance resolution descriptor [optional] */ + + /* resistance resolution descriptor [optional] */ + + /* resolution descriptor [optional] */ + fprintf (fp, " (resolution mil 10)\n"); + + /* time resolution descriptor [optional] */ + + /* voltage resolution descriptor [optional] */ + + /* unit descriptor [optional] */ + fprintf (fp, " (unit mil)\n"); + + /* structure descriptor [required] */ + print_structure (fp); + + /* placement descriptor [optional] */ + print_placement (fp); + + /* library descriptor [required] */ + print_library (fp); + + /* floor plan descriptor [optional] */ + + /* part library descriptor [optional] */ + + /* network descriptor [required] */ + print_network (fp); + + /* wiring descriptor [optional] */ + + /* color descriptor [optional] */ + + print_and_free (fp, specctra); + + fclose (fp); + + return (0); +} + +static void +specctra_do_export (HID_Attr_Val * options) +{ + int i; + + if (!options) + { + specctra_get_export_options (0); + for (i = 0; i < NUM_OPTIONS; i++) + specctra_values[i] = specctra_options[i].default_val; + options = specctra_values; + } + + specctra_filename = options[HA_specctrafile].str_value; + if (!specctra_filename) + specctra_filename = "pcb-out.dsn"; + + PrintSPECCTRA (); +} + +static void +specctra_parse_arguments (int *argc, char ***argv) +{ + hid_register_attributes (specctra_options, + sizeof (specctra_options) / sizeof (specctra_options[0])); + hid_parse_command_line (argc, argv); +} + +HID specctra_hid = { + sizeof (HID), + "specctra", + "Exports a SPECCTRA .dsn file", + 0, 0, 1, 0, 0, 0, + specctra_get_export_options, + specctra_do_export, + specctra_parse_arguments, + 0, /* specctra_invalidate_wh */ + 0, /* specctra_invalidate_lr */ + 0, /* specctra_invalidate_all */ + 0, /* specctra_set_layer */ + 0, /* specctra_make_gc */ + 0, /* specctra_destroy_gc */ + 0, /* specctra_use_mask */ + 0, /* specctra_set_color */ + 0, /* specctra_set_line_cap */ + 0, /* specctra_set_line_width */ + 0, /* specctra_set_draw_xor */ + 0, /* specctra_set_draw_faded */ + 0, /* specctra_set_line_cap_angle */ + 0, /* specctra_draw_line */ + 0, /* specctra_draw_arc */ + 0, /* specctra_draw_rect */ + 0, /* specctra_fill_circle */ + 0, /* specctra_fill_polygon */ + 0, /* specctra_fill_rect */ + 0, /* specctra_calibrate */ + 0, /* specctra_shift_is_pressed */ + 0, /* specctra_control_is_pressed */ + 0, /* specctra_get_coords */ + 0, /* specctra_set_crosshair */ + 0, /* specctra_add_timer */ + 0, /* specctra_stop_timer */ + 0, /* specctra_log */ + 0, /* specctra_logv */ + 0, /* specctra_confirm_dialog */ + 0, /* specctra_close_confirm_dialog */ + 0, /* specctra_report_dialog */ + 0, /* specctra_prompt_for */ + 0, /* specctra_fileselect */ + 0, /* specctra_attribute_dialog */ + 0, /* specctra_show_item */ + 0, /* specctra_beep */ + 0, /* specctra_progress */ +}; + +void +hid_specctra_init () +{ + apply_default_hid (&specctra_hid, 0); + hid_register_hid (&specctra_hid); +} + -- 1.6.0.4
_______________________________________________ geda-user mailing list geda-user@moria.seul.org http://www.seul.org/cgi-bin/mailman/listinfo/geda-user