static void btsco_sco_disconnected(void *arg, int err) { struct btsco_softc *sc = arg; DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state); KASSERT(sc->sc_sco != NULL); sc->sc_err = err; sco_detach_pcb(&sc->sc_sco); switch (sc->sc_state) { case BTSCO_CLOSED: /* dont think this can happen */ break; case BTSCO_WAIT_CONNECT: /* connect failed */ cv_broadcast(&sc->sc_connect); break; case BTSCO_OPEN: /* link lost */ /* * If IO is in progress, tell the audio driver that it * has completed so that when it tries to send more, we * can indicate an error. */ mutex_enter(&sc->sc_intr_lock); if (sc->sc_tx_pending > 0) { sc->sc_tx_pending = 0; (*sc->sc_tx_intr)(sc->sc_tx_intrarg); } if (sc->sc_rx_want > 0) { sc->sc_rx_want = 0; (*sc->sc_rx_intr)(sc->sc_rx_intrarg); } mutex_exit(&sc->sc_intr_lock); break; default: UNKNOWN(sc->sc_state); } sc->sc_state = BTSCO_CLOSED; }
/* --------------------------------------------------------------------------- * creates a new pin in an element */ PinTypePtr CreateNewPin (ElementTypePtr Element, LocationType X, LocationType Y, BDimension Thickness, BDimension Clearance, BDimension Mask, BDimension DrillingHole, char *Name, char *Number, FlagType Flags) { PinTypePtr pin = GetPinMemory (Element); /* copy values */ pin->X = X; pin->Y = Y; pin->Thickness = Thickness; pin->Clearance = Clearance; pin->Mask = Mask; pin->Name = STRDUP (Name); pin->Number = STRDUP (Number); pin->Flags = Flags; CLEAR_FLAG (WARNFLAG, pin); SET_FLAG (PINFLAG, pin); pin->ID = ID++; pin->Element = Element; /* * If there is no vendor drill map installed, this will simply * return DrillingHole. */ pin->DrillingHole = vendorDrillMap (DrillingHole); /* Unless we should not map drills on this element, map them! */ if (vendorIsElementMappable (Element)) { if (pin->DrillingHole < MIN_PINORVIASIZE) { Message (_ ("Did not map pin #%s (%s) drill hole because %6.2f mil is below the minimum allowed size\n"), UNKNOWN (Number), UNKNOWN (Name), 0.01 * pin->DrillingHole); pin->DrillingHole = DrillingHole; } else if (pin->DrillingHole > MAX_PINORVIASIZE) { Message (_ ("Did not map pin #%s (%s) drill hole because %6.2f mil is above the maximum allowed size\n"), UNKNOWN (Number), UNKNOWN (Name), 0.01 * pin->DrillingHole); pin->DrillingHole = DrillingHole; } else if (!TEST_FLAG (HOLEFLAG, pin) && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER)) { Message (_ ("Did not map pin #%s (%s) drill hole because %6.2f mil does not leave enough copper\n"), UNKNOWN (Number), UNKNOWN (Name), 0.01 * pin->DrillingHole); pin->DrillingHole = DrillingHole; } } else { pin->DrillingHole = DrillingHole; } if (pin->DrillingHole != DrillingHole) { Message (_ ("Mapped pin drill hole to %.2f mils from %.2f mils per vendor table\n"), 0.01 * pin->DrillingHole, 0.01 * DrillingHole); } return (pin); }
static int PrintBOM (void) { char utcTime[64]; Coord x, y; double theta = 0.0; double sumx, sumy; int pinfound[MAXREFPINS]; double pinx[MAXREFPINS]; double piny[MAXREFPINS]; double pinangle[MAXREFPINS]; double padcentrex, padcentrey; double centroidx, centroidy; double pin1x, pin1y; int pin_cnt; int found_any_not_at_centroid; int found_any; time_t currenttime; FILE *fp; BomList *bom = NULL; char *name, *descr, *value,*fixed_rotation; int rpindex; fp = fopen (xy_filename, "w"); if (!fp) { gui->log ("Cannot open file %s for writing\n", xy_filename); return 1; } /* Create a portable timestamp. */ currenttime = time (NULL); { /* avoid gcc complaints */ const char *fmt = "%c UTC"; strftime (utcTime, sizeof (utcTime), fmt, gmtime (¤ttime)); } fprintf (fp, "# PcbXY Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name)); fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n"); /* don't use localized xy_unit->in_suffix here since */ /* the line itself is not localized and not for GUI */ fprintf (fp, "# X,Y in %s. rotation in degrees.\n", xy_unit->suffix); fprintf (fp, "# --------------------------------------------\n"); /* * For each element we calculate the centroid of the footprint. * In addition, we need to extract some notion of rotation. * While here generate the BOM list */ ELEMENT_LOOP (PCB->Data); { /* Initialize our pin count and our totals for finding the centroid. */ pin_cnt = 0; sumx = 0.0; sumy = 0.0; for (rpindex = 0; rpindex < MAXREFPINS; rpindex++) pinfound[rpindex] = 0; /* Insert this component into the bill of materials list. */ bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)), (char *)UNKNOWN (DESCRIPTION_NAME (element)), (char *)UNKNOWN (VALUE_NAME (element)), bom); /* * 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++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pin->Number, reference_pin_names[rpindex]) == 0) { pinx[rpindex] = (double) pin->X; piny[rpindex] = (double) pin->Y; pinangle[rpindex] = 0.0; /* pins have no notion of angle */ pinfound[rpindex] = 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++; for (rpindex = 0; reference_pin_names[rpindex]; rpindex++) { if (NSTRCMP (pad->Number, reference_pin_names[rpindex]) == 0) { padcentrex = (double) (pad->Point1.X + pad->Point2.X) / 2.0; padcentrey = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0; pinx[rpindex] = padcentrex; piny[rpindex] = padcentrey; /* * 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. */ pinangle[rpindex] = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y, pad->Point2.X - pad->Point1.X); pinfound[rpindex]=1; } } } END_LOOP; if (pin_cnt > 0) { centroidx = sumx / (double) pin_cnt; centroidy = sumy / (double) pin_cnt; if (NSTRCMP( AttributeGetFromList (&element->Attributes,"xy-centre"), "origin") == 0 ) { x = element->MarkX; y = element->MarkY; } else { x = centroidx; y = centroidy; } fixed_rotation = AttributeGetFromList (&element->Attributes, "xy-fixed-rotation"); if (fixed_rotation) { /* The user specified a fixed rotation */ theta = atof (fixed_rotation); found_any_not_at_centroid = 1; found_any = 1; } else { /* Find first reference pin not at the centroid */ found_any_not_at_centroid = 0; found_any = 0; theta = 0.0; for (rpindex = 0; reference_pin_names[rpindex] && !found_any_not_at_centroid; rpindex++) { if (pinfound[rpindex]) { found_any = 1; /* Recenter pin "#1" onto the axis which cross at the part centroid */ pin1x = pinx[rpindex] - x; pin1y = piny[rpindex] - y; /* flip x, to reverse rotation for elements on back */ if (FRONT (element) != 1) pin1x = -pin1x; /* if only 1 pin, use pin 1's angle */ if (pin_cnt == 1) { theta = pinangle[rpindex]; found_any_not_at_centroid = 1; } else if ((pin1x != 0.0) || (pin1y != 0.0)) { theta = xyToAngle (pin1x, pin1y, pin_cnt > 2); found_any_not_at_centroid = 1; } } } if (!found_any) { Message ("PrintBOM(): unable to figure out angle because I could\n" " not find a suitable reference pin of element %s\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } else if (!found_any_not_at_centroid) { Message ("PrintBOM(): unable to figure out angle of element\n" " %s because the reference pin(s) are at the centroid of the part.\n" " Setting to %g degrees\n", UNKNOWN (NAMEONPCB_NAME (element)), theta); } } name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element))); descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element))); value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element))); y = PCB->MaxHeight - y; pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%.2mS,%.2mS,%g,%s\n", xy_unit->allow, name, descr, value, x, y, theta, FRONT (element) == 1 ? "top" : "bottom"); free (name); free (descr); free (value); } } END_LOOP; fclose (fp); /* Now print out a Bill of Materials file */ fp = fopen (bom_filename, "w"); if (!fp) { gui->log ("Cannot open file %s for writing\n", bom_filename); print_and_free (NULL, bom); return 1; } fprintf (fp, "# PcbBOM Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name)); fprintf (fp, "# Quantity, Description, Value, RefDes\n"); fprintf (fp, "# --------------------------------------------\n"); print_and_free (fp, bom); fclose (fp); return (0); }
/*! * \brief Creates a new pin in an element. */ PinType * CreateNewPin (ElementType *Element, Coord X, Coord Y, Coord Thickness, Coord Clearance, Coord Mask, Coord DrillingHole, char *Name, char *Number, FlagType Flags) { PinType *pin = GetPinMemory (Element); /* copy values */ pin->X = X; pin->Y = Y; pin->Thickness = Thickness; pin->Clearance = Clearance; pin->Mask = Mask; pin->Name = STRDUP (Name); pin->Number = STRDUP (Number); pin->Flags = Flags; CLEAR_FLAG (WARNFLAG, pin); SET_FLAG (PINFLAG, pin); pin->ID = ID++; pin->Element = Element; /* * If there is no vendor drill map installed, this will simply * return DrillingHole. */ pin->DrillingHole = vendorDrillMap (DrillingHole); /* Unless we should not map drills on this element, map them! */ if (vendorIsElementMappable (Element)) { if (pin->DrillingHole < MIN_PINORVIASIZE) { Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is below the minimum allowed size\n"), Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole); pin->DrillingHole = DrillingHole; } else if (pin->DrillingHole > MAX_PINORVIASIZE) { Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS is above the maximum allowed size\n"), Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole); pin->DrillingHole = DrillingHole; } else if (!TEST_FLAG (HOLEFLAG, pin) && (pin->DrillingHole > pin->Thickness - MIN_PINORVIACOPPER)) { Message (_("%m+Did not map pin #%s (%s) drill hole because %$mS does not leave enough copper\n"), Settings.grid_unit->allow, UNKNOWN (Number), UNKNOWN (Name), pin->DrillingHole); pin->DrillingHole = DrillingHole; } } else { pin->DrillingHole = DrillingHole; } if (pin->DrillingHole != DrillingHole) { Message (_("%m+Mapped pin drill hole to %$mS from %$mS per vendor table\n"), Settings.grid_unit->allow, pin->DrillingHole, DrillingHole); } return (pin); }
int main (int argc, char *argv[]) { int i; /* init application: * - make program name available for error handlers * - evaluate special options * - initialize toplevel shell and resources * - create an empty PCB with default symbols * - initialize all other widgets * - update screen and get size of drawing area * - evaluate command-line arguments * - register 'call on exit()' function */ setbuf (stdout, 0); InitPaths (argv[0]); #ifdef LOCALEDIR bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); textdomain(GETTEXT_PACKAGE); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); setlocale(LC_ALL,""); #endif srand ( time(NULL) ); /* Set seed for rand() */ initialize_units(); polygon_init (); hid_init (); hid_load_settings (); program_name = argv[0]; program_basename = strrchr (program_name, PCB_DIR_SEPARATOR_C); if (program_basename) { program_directory = strdup (program_name); *strrchr (program_directory, PCB_DIR_SEPARATOR_C) = 0; program_basename++; } else { program_directory = "."; program_basename = program_name; } Progname = program_basename; /* Print usage or version if requested. Then exit. */ if (argc > 1 && (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "-?") == 0 || strcmp (argv[1], "--help") == 0)) usage (); if (argc > 1 && strcmp (argv[1], "-V") == 0) print_version (); /* Export pcb from command line if requested. */ if (argc > 1 && strcmp (argv[1], "-p") == 0) { exporter = gui = hid_find_printer (); argc--; argv++; } else if (argc > 2 && strcmp (argv[1], "-x") == 0) { exporter = gui = hid_find_exporter (argv[2]); argc -= 2; argv += 2; } /* Otherwise start GUI. */ else if (argc > 2 && strcmp (argv[1], "--gui") == 0) { gui = hid_find_gui (argv[2]); if (gui == NULL) { Message("Can't find the gui requested.\n"); exit(1); } argc -= 2; argv += 2; } else { const char **g; gui = NULL; for(g = try_gui_hids; (*g != NULL) && (gui == NULL); g++) { gui = hid_find_gui (*g); } /* try anything */ if (gui == NULL) { Message("Warning: can't find any of the preferred GUIs, falling back to anything available...\n"); gui = hid_find_gui (NULL); } } /* Exit with error if GUI failed to start. */ if (!gui) exit (1); /* Initialize actions only when the gui is already known so only the right one is registered (there can be only one GUI). */ #include "action_list.h" /* Set up layers. */ for (i = 0; i < MAX_LAYER; i++) { char buf[20]; sprintf (buf, "signal%d", i + 1); Settings.DefaultLayerName[i] = strdup (buf); Settings.LayerColor[i] = "#c49350"; Settings.LayerSelectedColor[i] = "#00ffff"; } gui->parse_arguments (&argc, &argv); if (show_help || (argc > 1 && argv[1][0] == '-')) usage (); if (show_version) print_version (); if (show_defaults) print_defaults (); if (show_copyright) copyright (); settings_post_process (); if (show_actions) { print_actions (); exit (0); } if (do_dump_actions) { extern void dump_actions (void); dump_actions (); exit (0); } set_fontfile(); /* Create a new PCB object in memory */ PCB = CreateNewPCB (); if (PCB == NULL) { Message("Can't load the default pcb (%s) for creating an empty layout\n", Settings.DefaultPcbFile); exit(1); } /* Add silk layers to newly created PCB */ CreateNewPCBPost (PCB, 1); if (argc > 1) command_line_pcb = argv[1]; ResetStackAndVisibility (); if (gui->gui) InitCrosshair (); InitHandler (); InitBuffers (); SetMode (ARROW_MODE); if (command_line_pcb) { /* keep filename even if initial load command failed; * file might not exist */ if (LoadPCB (command_line_pcb)) PCB->Filename = strdup (command_line_pcb); } if (Settings.InitialLayerStack && Settings.InitialLayerStack[0]) { LayerStringToLayerStack (Settings.InitialLayerStack); } /* This must be called before any other atexit functions * are registered, as it configures an atexit function to * clean up and free various items of allocated memory, * and must be the last last atexit function to run. */ leaky_init (); /* Register a function to be called when the program terminates. * This makes sure that data is saved even if LEX/YACC routines * abort the program. * If the OS doesn't have at least one of them, * the critical sections will be handled by parse_l.l */ atexit (EmergencySave); /* read the library file and display it if it's not empty */ if (!ReadLibraryContents () && Library.MenuN) hid_action ("LibraryChanged"); #ifdef HAVE_LIBSTROKE stroke_init (); #endif if (Settings.ScriptFilename) { Message (_("Executing startup script file %s\n"), Settings.ScriptFilename); hid_actionl ("ExecuteFile", Settings.ScriptFilename, NULL); } if (Settings.ActionString) { Message (_("Executing startup action %s\n"), Settings.ActionString); hid_parse_actions (Settings.ActionString); } if (gui->printer || gui->exporter) { // Workaround to fix batch output for non-C locales setlocale(LC_NUMERIC,"C"); gui->do_export (0); exit (0); } #if HAVE_DBUS pcb_dbus_setup(); #endif EnableAutosave (); #ifdef DEBUG printf ("Settings.FontPath = \"%s\"\n", Settings.FontPath); printf ("Settings.ElementPath = \"%s\"\n", Settings.ElementPath); printf ("Settings.LibrarySearchPaths = \"%s\"\n", Settings.LibrarySearchPaths); printf ("Settings.LibraryShell = \"%s\"\n", Settings.LibraryShell); printf ("Settings.MakeProgram = \"%s\"\n", UNKNOWN (Settings.MakeProgram)); printf ("Settings.GnetlistProgram = \"%s\"\n", UNKNOWN (Settings.GnetlistProgram)); #endif buildin_init(); gui->do_export (0); #if HAVE_DBUS pcb_dbus_finish(); #endif return (0); }
/* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int rfcomm_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct rfcomm_dlc *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (up->so_lock == NULL) { mutex_obj_hold(bt_lock); up->so_lock = bt_lock; solock(up); } KASSERT(solocked(up)); if (pcb != NULL) return EINVAL; /* * Since we have nothing to add, we attach the DLC * structure directly to our PCB pointer. */ err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace); if (err) return err; err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb, &rfcomm_proto, up); if (err) return err; err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv)); if (err) { rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb); return err; } return 0; } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return rfcomm_disconnect(pcb, up->so_linger); case PRU_ABORT: rfcomm_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb); case PRU_BIND: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return rfcomm_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return rfcomm_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m != NULL); if (ctl) /* no use for that */ m_freem(ctl); m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) return ENOMEM; sbappendstream(&up->so_snd, m); return rfcomm_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: return rfcomm_rcvd(pcb, sbspace(&up->so_rcv)); case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return rfcomm_listen(pcb); case PRU_ACCEPT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; }
/* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * ctl is optional mbuf chain containing socket options * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ static int sco_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); KASSERT(req != PRU_ATTACH); KASSERT(req != PRU_DETACH); switch(req) { case PRU_CONTROL: return EOPNOTSUPP; case PRU_PURGEIF: return EOPNOTSUPP; } /* anything after here *requires* a pcb */ if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return sco_disconnect(pcb, up->so_linger); case PRU_ABORT: sco_disconnect(pcb, 0); soisdisconnected(up); sco_detach(up); return 0; case PRU_BIND: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return sco_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return sco_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return sco_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return sco_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m != NULL); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->sp_mtu) { err = EMSGSIZE; break; } m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return sco_send(pcb, m0); case PRU_SENSE: return 0; /* (no sense - Doh!) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return sco_listen(pcb); case PRU_ACCEPT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return sco_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; }
static int ReportDialog (int argc, char **argv, Coord x, Coord y) { void *ptr1, *ptr2, *ptr3; int type; char report[2048]; type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3); if (type == NO_TYPE) type = SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3); switch (type) { case VIA_TYPE: { PinType *via; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->via_tree->root, 0); return 0; } #endif via = (PinType *) ptr2; if (TEST_FLAG (HOLEFLAG, via)) pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "It is a pure hole of diameter %$mS.\n" "Name = \"%s\"." "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE), via->X, via->Y, via->DrillingHole, EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? _("It is LOCKED.\n") : ""); else pcb_snprintf (report, sizeof (report), _("%m+VIA ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "Copper width = %$mS. Drill width = %$mS.\n" "Clearance width in polygons = %$mS.\n" "Annulus = %$mS.\n" "Solder mask hole = %$mS (gap = %$mS).\n" "Name = \"%s\"." "%s"), USER_UNITMASK, via->ID, flags_to_string (via->Flags, VIA_TYPE), via->X, via->Y, via->Thickness, via->DrillingHole, via->Clearance / 2, (via->Thickness - via->DrillingHole) / 2, via->Mask, (via->Mask - via->Thickness) / 2, EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? _("It is LOCKED.\n") : ""); break; } case PIN_TYPE: { PinType *Pin; ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pin_tree->root, 0); return 0; } #endif Pin = (PinType *) ptr2; element = (ElementType *) ptr1; PIN_LOOP (element); { if (pin == Pin) break; } END_LOOP; if (TEST_FLAG (HOLEFLAG, Pin)) pcb_snprintf (report, sizeof (report), _("%m+PIN ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "It is a mounting hole. Drill width = %$mS.\n" "It is owned by element %$mS.\n" "%s"), USER_UNITMASK, Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), Pin->X, Pin->Y, Pin->DrillingHole, EMPTY (element->Name[1].TextString), TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : ""); else pcb_snprintf (report, sizeof (report), _("%m+PIN ID# %ld; Flags:%s\n" "(X,Y) = %$mD.\n" "Copper width = %$mS. Drill width = %$mS.\n" "Clearance width to Polygon = %$mS.\n" "Annulus = %$mS.\n" "Solder mask hole = %$mS (gap = %$mS).\n" "Name = \"%s\".\n" "It is owned by element %s\n as pin number %s.\n" "%s"), USER_UNITMASK, Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), Pin->X, Pin->Y, Pin->Thickness, Pin->DrillingHole, Pin->Clearance / 2, (Pin->Thickness - Pin->DrillingHole) / 2, Pin->Mask, (Pin->Mask - Pin->Thickness) / 2, EMPTY (Pin->Name), EMPTY (element->Name[1].TextString), EMPTY (Pin->Number), TEST_FLAG (LOCKFLAG, Pin) ? _("It is LOCKED.\n") : ""); break; } case LINE_TYPE: { LineType *line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->line_tree->root, 0); return 0; } #endif line = (LineType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD, ID = %ld.\n" "SecondPoint(X,Y) = %$mD, ID = %ld.\n" "Width = %$mS.\nClearance width in polygons = %$mS.\n" "It is on layer %d\n" "and has name \"%s\".\n" "%s"), USER_UNITMASK, line->ID, flags_to_string (line->Flags, LINE_TYPE), line->Point1.X, line->Point1.Y, line->Point1.ID, line->Point2.X, line->Point2.Y, line->Point2.ID, line->Thickness, line->Clearance / 2, GetLayerNumber (PCB->Data, (LayerType *) ptr1), UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG, line) ? _("It is LOCKED.\n") : ""); break; } case RATLINE_TYPE: { RatType *line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->rat_tree->root, 0); return 0; } #endif line = (RatType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+RAT-LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD; ID = %ld; " "connects to layer group %d.\n" "SecondPoint(X,Y) = %$mD; ID = %ld; " "connects to layer group %d.\n"), USER_UNITMASK, line->ID, flags_to_string (line->Flags, LINE_TYPE), line->Point1.X, line->Point1.Y, line->Point1.ID, line->group1, line->Point2.X, line->Point2.Y, line->Point2.ID, line->group2); break; } case ARC_TYPE: { ArcType *Arc; BoxType *box; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->arc_tree->root, 0); return 0; } #endif Arc = (ArcType *) ptr2; box = GetArcEnds (Arc); pcb_snprintf (report, sizeof (report), _("%m+ARC ID# %ld; Flags:%s\n" "CenterPoint(X,Y) = %$mD.\n" "Radius = %$mS, Thickness = %$mS.\n" "Clearance width in polygons = %$mS.\n" "StartAngle = %ma degrees, DeltaAngle = %ma degrees.\n" "Bounding Box is %$mD, %$mD.\n" "That makes the end points at %$mD and %$mD.\n" "It is on layer %d.\n" "%s"), USER_UNITMASK, Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE), Arc->X, Arc->Y, Arc->Width, Arc->Thickness, Arc->Clearance / 2, Arc->StartAngle, Arc->Delta, Arc->BoundingBox.X1, Arc->BoundingBox.Y1, Arc->BoundingBox.X2, Arc->BoundingBox.Y2, box->X1, box->Y1, box->X2, box->Y2, GetLayerNumber (PCB->Data, (LayerType *) ptr1), TEST_FLAG (LOCKFLAG, Arc) ? _("It is LOCKED.\n") : ""); break; } case POLYGON_TYPE: { PolygonType *Polygon; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->polygon_tree->root, 0); return 0; } #endif Polygon = (PolygonType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+POLYGON ID# %ld; Flags:%s\n" "Its bounding box is %$mD %$mD.\n" "It has %d points and could store %d more\n" " without using more memory.\n" "It has %d holes and resides on layer %d.\n" "%s"), USER_UNITMASK, Polygon->ID, flags_to_string (Polygon->Flags, POLYGON_TYPE), Polygon->BoundingBox.X1, Polygon->BoundingBox.Y1, Polygon->BoundingBox.X2, Polygon->BoundingBox.Y2, Polygon->PointN, Polygon->PointMax - Polygon->PointN, Polygon->HoleIndexN, GetLayerNumber (PCB->Data, (LayerType *) ptr1), TEST_FLAG (LOCKFLAG, Polygon) ? _("It is LOCKED.\n") : ""); break; } case PAD_TYPE: { Coord len; PadType *Pad; ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pad_tree->root, 0); return 0; } #endif Pad = (PadType *) ptr2; element = (ElementType *) ptr1; PAD_LOOP (element); { { if (pad == Pad) break; } } END_LOOP; len = Distance (Pad->Point1.X, Pad->Point1.Y, Pad->Point2.X, Pad->Point2.Y); pcb_snprintf (report, sizeof (report), _("%m+PAD ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = %$mD; ID = %ld.\n" "SecondPoint(X,Y) = %$mD; ID = %ld.\n" "Width = %$mS. Length = %$mS.\n" "Clearance width in polygons = %$mS.\n" "Solder mask = %$mS x %$mS (gap = %$mS).\n" "Name = \"%s\".\n" "It is owned by SMD element %s\n" " as pin number %s and is on the %s\n" "side of the board.\n" "%s"), USER_UNITMASK, Pad->ID, flags_to_string (Pad->Flags, PAD_TYPE), Pad->Point1.X, Pad->Point1.Y, Pad->Point1.ID, Pad->Point2.X, Pad->Point2.Y, Pad->Point2.ID, Pad->Thickness, len + Pad->Thickness, Pad->Clearance / 2, Pad->Mask, len + Pad->Mask, (Pad->Mask - Pad->Thickness) / 2, EMPTY (Pad->Name), EMPTY (element->Name[1].TextString), EMPTY (Pad->Number), TEST_FLAG (ONSOLDERFLAG, Pad) ? _("solder (bottom)") : _("component"), TEST_FLAG (LOCKFLAG, Pad) ? _("It is LOCKED.\n") : ""); break; } case ELEMENT_TYPE: { ElementType *element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->element_tree->root, 0); return 0; } #endif element = (ElementType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+ELEMENT ID# %ld; Flags:%s\n" "BoundingBox %$mD %$mD.\n" "Descriptive Name \"%s\".\n" "Name on board \"%s\".\n" "Part number name \"%s\".\n" "It is %$mS tall and is located at (X,Y) = %$mD %s.\n" "Mark located at point (X,Y) = %$mD.\n" "It is on the %s side of the board.\n" "%s"), USER_UNITMASK, element->ID, flags_to_string (element->Flags, ELEMENT_TYPE), element->BoundingBox.X1, element->BoundingBox.Y1, element->BoundingBox.X2, element->BoundingBox.Y2, EMPTY (element->Name[0].TextString), EMPTY (element->Name[1].TextString), EMPTY (element->Name[2].TextString), SCALE_TEXT (FONT_CAPHEIGHT, element->Name[1].Scale), element->Name[1].X, element->Name[1].Y, TEST_FLAG (HIDENAMEFLAG, element) ? _(",\n but it's hidden") : "", element->MarkX, element->MarkY, TEST_FLAG (ONSOLDERFLAG, element) ? _("solder (bottom)") : _("component"), TEST_FLAG (LOCKFLAG, element) ? _("It is LOCKED.\n") : ""); break; } case TEXT_TYPE: #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerType *layer = (LayerType *) ptr1; __r_dump_tree (layer->text_tree->root, 0); return 0; } #endif case ELEMENTNAME_TYPE: { char laynum[32]; TextType *text; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0); return 0; } #endif text = (TextType *) ptr2; if (type == TEXT_TYPE) sprintf (laynum, _("It is on layer %d."), GetLayerNumber (PCB->Data, (LayerType *) ptr1)); pcb_snprintf (report, sizeof (report), _("%m+TEXT ID# %ld; Flags:%s\n" "Located at (X,Y) = %$mD.\n" "Characters are %$mS tall.\n" "Value is \"%s\".\n" "Direction is %d.\n" "The bounding box is %$mD %$mD.\n" "%s\n" "%s"), USER_UNITMASK, text->ID, flags_to_string (text->Flags, TEXT_TYPE), text->X, text->Y, SCALE_TEXT (FONT_CAPHEIGHT, text->Scale), text->TextString, text->Direction, text->BoundingBox.X1, text->BoundingBox.Y1, text->BoundingBox.X2, text->BoundingBox.Y2, (type == TEXT_TYPE) ? laynum : _("It is an element name."), TEST_FLAG (LOCKFLAG, text) ? _("It is LOCKED.\n") : ""); break; } case LINEPOINT_TYPE: case POLYGONPOINT_TYPE: { PointType *point = (PointType *) ptr2; pcb_snprintf (report, sizeof (report), _("%m+POINT ID# %ld.\n" "Located at (X,Y) = %$mD.\n" "It belongs to a %s on layer %d.\n"), USER_UNITMASK, point->ID, point->X, point->Y, (type == LINEPOINT_TYPE) ? C_("report", "line") : C_("report", "polygon"), GetLayerNumber (PCB->Data, (LayerType *) ptr1)); break; } case NO_TYPE: report[0] = '\0'; break; default: sprintf (report, _("Unknown\n")); break; } if (report[0] == '\0') { Message (_("Nothing found to report on\n")); return 1; } /* create dialog box */ gui->report_dialog (_("Report"), report); return 0; }
static void apply_vendor_map (void) { int i; int changed, tot; bool state; state = vendorMapEnable; /* enable mapping */ vendorMapEnable = true; /* reset our counts */ changed = 0; tot = 0; /* If we have loaded vendor drills, then apply them to the design */ if (n_vendor_drills > 0) { /* first all the vias */ VIA_LOOP (PCB->Data); { tot++; if (via->DrillingHole != vendorDrillMap (via->DrillingHole)) { /* only change unlocked vias */ if (!TEST_FLAG (LOCKFLAG, via)) { if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL, vendorDrillMap (via->DrillingHole), true, false)) changed++; else { Message (_ ("Via at %.2f, %.2f not changed. Possible reasons:\n" "\t- pad size too small\n" "\t- new size would be too large or too small\n"), 0.01 * via->X, 0.01 * via->Y); } } else { Message (_("Locked via at %.2f, %.2f not changed.\n"), 0.01 * via->X, 0.01 * via->Y); } } } END_LOOP; /* and now the pins */ ELEMENT_LOOP (PCB->Data); { /* * first figure out if this element should be skipped for some * reason */ if (vendorIsElementMappable (element)) { /* the element is ok to modify, so iterate over its pins */ PIN_LOOP (element); { tot++; if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole)) { if (!TEST_FLAG (LOCKFLAG, pin)) { if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL, vendorDrillMap (pin-> DrillingHole), true, false)) changed++; else { Message (_ ("Pin %s (%s) at %.2f, %.2f (element %s, %s, %s) not changed.\n" "\tPossible reasons:\n" "\t- pad size too small\n" "\t- new size would be too large or too small\n"), UNKNOWN (pin->Number), UNKNOWN (pin->Name), 0.01 * pin->X, 0.01 * pin->Y, UNKNOWN (NAMEONPCB_NAME (element)), UNKNOWN (VALUE_NAME (element)), UNKNOWN (DESCRIPTION_NAME (element))); } } else { Message (_ ("Locked pin at %-6.2f, %-6.2f not changed.\n"), 0.01 * pin->X, 0.01 * pin->Y); } } } END_LOOP; } } END_LOOP; Message (_("Updated %d drill sizes out of %d total\n"), changed, tot); /* Update the current Via */ if (Settings.ViaDrillingHole != vendorDrillMap (Settings.ViaDrillingHole)) { changed++; Settings.ViaDrillingHole = vendorDrillMap (Settings.ViaDrillingHole); Message (_("Adjusted active via hole size to be %6.2f mils\n"), 0.01 * Settings.ViaDrillingHole); } /* and update the vias for the various routing styles */ for (i = 0; i < NUM_STYLES; i++) { if (PCB->RouteStyle[i].Hole != vendorDrillMap (PCB->RouteStyle[i].Hole)) { changed++; PCB->RouteStyle[i].Hole = vendorDrillMap (PCB->RouteStyle[i].Hole); Message (_ ("Adjusted %s routing style via hole size to be %6.2f mils\n"), PCB->RouteStyle[i].Name, 0.01 * PCB->RouteStyle[i].Hole); if (PCB->RouteStyle[i].Diameter < PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER) { PCB->RouteStyle[i].Diameter = PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER; Message (_ ("Increased %s routing style via diameter to %6.2f mils\n"), PCB->RouteStyle[i].Name, 0.01 * PCB->RouteStyle[i].Diameter); } } } /* * if we've changed anything, indicate that we need to save the * file, redraw things, and make sure we can undo. */ if (changed) { SetChangedFlag (true); Redraw (); IncrementUndoSerialNumber (); } } /* restore mapping on/off */ vendorMapEnable = state; }
int ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y) { int i; char *fname = NULL; static char *default_file = NULL; char *sval; Resource *res, *drcres, *drlres; int type; bool free_fname = false; cached_drill = -1; fname = argc ? argv[0] : 0; if (!fname || !*fname) { fname = gui->fileselect (_("Load Vendor Resource File..."), _("Picks a vendor resource file to load.\n" "This file can contain drc settings for a\n" "particular vendor as well as a list of\n" "predefined drills which are allowed."), default_file, ".res", "vendor", HID_FILESELECT_READ); if (fname == NULL) AFAIL (load_vendor); free_fname = true; free (default_file); default_file = NULL; if (fname && *fname) default_file = strdup (fname); } /* Unload any vendor table we may have had */ n_vendor_drills = 0; n_refdes = 0; n_value = 0; n_descr = 0; FREE (vendor_drills); FREE (ignore_refdes); FREE (ignore_value); FREE (ignore_descr); /* load the resource file */ res = resource_parse (fname, NULL); if (res == NULL) { Message (_("Could not load vendor resource file \"%s\"\n"), fname); return 1; } /* figure out the vendor name, if specified */ vendor_name = (char *)UNKNOWN (resource_value (res, "vendor")); /* figure out the units, if specified */ sval = resource_value (res, "units"); if (sval == NULL) { sf = MIL_TO_COORD(1); } else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0)) { sf = MIL_TO_COORD(1); } else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0)) { sf = INCH_TO_COORD(1); } else if (NSTRCMP (sval, "mm") == 0) { sf = MM_TO_COORD(1); } else { Message ("\"%s\" is not a supported units. Defaulting to inch\n", sval); sf = INCH_TO_COORD(1); } /* default to ROUND_UP */ rounding_method = ROUND_UP; /* extract the drillmap resource */ drlres = resource_subres (res, "drillmap"); if (drlres == NULL) { Message (_("No drillmap resource found\n")); } else { sval = resource_value (drlres, "round"); if (sval != NULL) { if (NSTRCMP (sval, "up") == 0) { rounding_method = ROUND_UP; } else if (NSTRCMP (sval, "nearest") == 0) { rounding_method = CLOSEST; } else { Message (_ ("\"%s\" is not a valid rounding type. Defaulting to up\n"), sval); rounding_method = ROUND_UP; } } process_skips (resource_subres (drlres, "skips")); for (i = 0; i < drlres->c; i++) { type = resource_type (drlres->v[i]); switch (type) { case 10: /* just a number */ add_to_drills (drlres->v[i].value); break; default: break; } } } /* Extract the DRC resource */ drcres = resource_subres (res, "drc"); sval = resource_value (drcres, "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 = resource_value (drcres, "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 = resource_value (drcres, "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 = resource_value (drcres, "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 = resource_value (drcres, "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 = resource_value (drcres, "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); } Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname); Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"), n_refdes, n_value, n_descr); vendorMapEnable = true; apply_vendor_map (); if (free_fname) free (fname); return 0; }
static int btsco_open(void *hdl, int flags) { struct sockaddr_bt sa; struct btsco_softc *sc = hdl; struct sockopt sopt; int err, timo; DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); /* flags FREAD & FWRITE? */ if (sc->sc_sco != NULL || sc->sc_sco_l != NULL) return EIO; KASSERT(mutex_owned(bt_lock)); memset(&sa, 0, sizeof(sa)); sa.bt_len = sizeof(sa); sa.bt_family = AF_BLUETOOTH; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); if (sc->sc_flags & BTSCO_LISTEN) { err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc); if (err) goto done; err = sco_bind_pcb(sc->sc_sco_l, &sa); if (err) { sco_detach_pcb(&sc->sc_sco_l); goto done; } err = sco_listen_pcb(sc->sc_sco_l); if (err) { sco_detach_pcb(&sc->sc_sco_l); goto done; } timo = 0; /* no timeout */ } else { err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc); if (err) goto done; err = sco_bind_pcb(sc->sc_sco, &sa); if (err) { sco_detach_pcb(&sc->sc_sco); goto done; } bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); err = sco_connect_pcb(sc->sc_sco, &sa); if (err) { sco_detach_pcb(&sc->sc_sco); goto done; } timo = BTSCO_TIMEOUT; } sc->sc_state = BTSCO_WAIT_CONNECT; while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT) err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo); switch (sc->sc_state) { case BTSCO_CLOSED: /* disconnected */ err = sc->sc_err; /* fall through to */ case BTSCO_WAIT_CONNECT: /* error */ if (sc->sc_sco != NULL) sco_detach_pcb(&sc->sc_sco); if (sc->sc_sco_l != NULL) sco_detach_pcb(&sc->sc_sco_l); break; case BTSCO_OPEN: /* hurrah */ sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0); (void)sco_getopt(sc->sc_sco, &sopt); (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu)); sockopt_destroy(&sopt); break; default: UNKNOWN(sc->sc_state); break; } done: DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n", err, sc->sc_state, sc->sc_mtu); return err; }
static int PrintBOM (void) { char utcTime[64]; Coord x, y; double theta = 0.0; double sumx, sumy; double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0; double pin2x = 0.0, pin2y = 0.0; int found_pin1; int found_pin2; int pin_cnt; time_t currenttime; FILE *fp; BomList *bom = NULL; char *name, *descr, *value; fp = fopen (xy_filename, "w"); if (!fp) { gui->log ("Cannot open file %s for writing\n", xy_filename); return 1; } /* Create a portable timestamp. */ currenttime = time (NULL); { /* avoid gcc complaints */ const char *fmt = "%c UTC"; strftime (utcTime, sizeof (utcTime), fmt, gmtime (¤ttime)); } fprintf (fp, "# PcbXY Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name)); fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n"); fprintf (fp, "# X,Y in %s. rotation in degrees.\n", xy_unit->in_suffix); fprintf (fp, "# --------------------------------------------\n"); /* * For each element we calculate the centroid of the footprint. * In addition, we need to extract some notion of rotation. * While here generate the BOM list */ ELEMENT_LOOP (PCB->Data); { /* 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; /* insert this component into the bill of materials list */ bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)), (char *)UNKNOWN (DESCRIPTION_NAME (element)), (char *)UNKNOWN (VALUE_NAME (element)), bom); /* * 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; 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; 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 ("PrintBOM(): 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 ("PrintBOM(): 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); } name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element))); descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element))); value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element))); y = PCB->MaxHeight - y; pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%mS,%.2mS,%g,%s\n", xy_unit->allow, name, descr, value, x, y, theta, FRONT (element) == 1 ? "top" : "bottom"); free (name); free (descr); free (value); } } END_LOOP; fclose (fp); /* Now print out a Bill of Materials file */ fp = fopen (bom_filename, "w"); if (!fp) { gui->log ("Cannot open file %s for writing\n", bom_filename); print_and_free (NULL, bom); return 1; } fprintf (fp, "# PcbBOM Version 1.0\n"); fprintf (fp, "# Date: %s\n", utcTime); fprintf (fp, "# Author: %s\n", pcb_author ()); fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name)); fprintf (fp, "# Quantity, Description, Value, RefDes\n"); fprintf (fp, "# --------------------------------------------\n"); print_and_free (fp, bom); fclose (fp); return (0); }
/* * User Request. * up is socket * m is either * optional mbuf chain containing message * ioctl command (PRU_CONTROL) * nam is either * optional mbuf chain containing an address * ioctl data (PRU_CONTROL) * optionally protocol number (PRU_ATTACH) * message flags (PRU_RCVD) * ctl is either * optional mbuf chain containing socket options * optional interface pointer (PRU_CONTROL, PRU_PURGEIF) * l is pointer to process requesting action (if any) * * we are responsible for disposing of m and ctl if * they are mbuf chains */ int l2cap_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct proc *p) { struct l2cap_channel *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; #ifdef notyet /* XXX */ DPRINTFN(2, "%s\n", prurequests[req]); #endif switch (req) { case PRU_CONTROL: return EPASSTHROUGH; #ifdef notyet /* XXX */ case PRU_PURGEIF: return EOPNOTSUPP; #endif case PRU_ATTACH: /* XXX solock() and bt_lock fiddling in NetBSD */ if (pcb != NULL) return EINVAL; /* * For L2CAP socket PCB we just use an l2cap_channel structure * since we have nothing to add.. */ err = soreserve(up, l2cap_sendspace, l2cap_recvspace); if (err) return err; return l2cap_attach((struct l2cap_channel **)&up->so_pcb, &l2cap_proto, up); } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return l2cap_disconnect(pcb, up->so_linger); case PRU_ABORT: l2cap_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return l2cap_detach((struct l2cap_channel **)&up->so_pcb); case PRU_BIND: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; return l2cap_bind(pcb, sa); case PRU_CONNECT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); if (sa->bt_len != sizeof(struct sockaddr_bt)) return EINVAL; if (sa->bt_family != AF_BLUETOOTH) return EAFNOSUPPORT; soisconnecting(up); return l2cap_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m != NULL); if (m->m_pkthdr.len == 0) break; if (m->m_pkthdr.len > pcb->lc_omtu) { err = EMSGSIZE; break; } m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT); if (m0 == NULL) { err = ENOMEM; break; } if (ctl) /* no use for that */ m_freem(ctl); sbappendrecord(&up->so_snd, m); return l2cap_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return l2cap_listen(pcb); case PRU_ACCEPT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return l2cap_peeraddr(pcb, sa); case PRU_CONNECT2: case PRU_SENDOOB: case PRU_FASTTIMO: case PRU_SLOWTIMO: case PRU_PROTORCV: case PRU_PROTOSEND: err = EOPNOTSUPP; break; default: UNKNOWN(req); err = EOPNOTSUPP; break; } release: if (m) m_freem(m); if (ctl) m_freem(ctl); return err; }
/* --------------------------------------------------------------------------- * Read contents of the library description file (for M4) * and then read in M4 libs. Then call a fcn to read the newlib * footprints. */ int ReadLibraryContents (void) { static char *command = NULL; char inputline[MAX_LIBRARY_LINE_LENGTH + 1]; FILE *resultFP = NULL; LibraryMenuType *menu = NULL; LibraryEntryType *entry; /* If we don't have a command to execute to find the library contents, * skip this. This is used by default on Windows builds (set in main.c), * as we can't normally run shell scripts or expect to have m4 present. */ if (Settings.LibraryContentsCommand != NULL && Settings.LibraryContentsCommand[0] != '\0') { /* First load the M4 stuff. The variable Settings.LibraryPath * points to it. */ free (command); command = EvaluateFilename (Settings.LibraryContentsCommand, Settings.LibraryPath, Settings.LibraryFilename, NULL); #ifdef DEBUG printf("In ReadLibraryContents, about to execute command %s\n", command); #endif /* This uses a pipe to execute a shell script which provides the names of * all M4 libs and footprints. The results are placed in resultFP. */ if (command && *command && (resultFP = popen (command, "r")) == NULL) { PopenErrorMessage (command); } /* the M4 library contents are separated by colons; * template : package : name : description */ while (resultFP != NULL && fgets (inputline, MAX_LIBRARY_LINE_LENGTH, resultFP)) { size_t len = strlen (inputline); /* check for maximum linelength */ if (len) { len--; if (inputline[len] != '\n') Message ("linelength (%i) exceeded; following characters will be ignored\n", MAX_LIBRARY_LINE_LENGTH); else inputline[len] = '\0'; } /* if the line defines a menu */ if (!strncmp (inputline, "TYPE=", 5)) { menu = GetLibraryMenuMemory (&Library); menu->Name = strdup (UNKNOWN (&inputline[5])); menu->directory = strdup (Settings.LibraryFilename); } else { /* allocate a new menu entry if not already done */ if (!menu) { menu = GetLibraryMenuMemory (&Library); menu->Name = strdup (UNKNOWN ((char *) NULL)); menu->directory = strdup (Settings.LibraryFilename); } entry = GetLibraryEntryMemory (menu); entry->AllocatedMemory = strdup (inputline); /* now break the line into pieces separated by colons */ if ((entry->Template = strtok (entry->AllocatedMemory, ":")) != NULL) if ((entry->Package = strtok (NULL, ":")) != NULL) if ((entry->Value = strtok (NULL, ":")) != NULL) entry->Description = strtok (NULL, ":"); /* create the list entry */ len = strlen (EMPTY (entry->Value)) + strlen (EMPTY (entry->Description)) + 4; entry->ListEntry = (char *)calloc (len, sizeof (char)); sprintf (entry->ListEntry, "%s, %s", EMPTY (entry->Value), EMPTY (entry->Description)); } } if (resultFP != NULL) pclose (resultFP); } /* Now after reading in the M4 libs, call a function to * read the newlib footprint libraries. Then sort the whole * library. */ if (ParseLibraryTree () > 0 || resultFP != NULL) { sort_library (&Library); return 0; } return (1); }
bool vendorIsElementMappable (ElementType *element) { int i; int noskip; if (vendorMapEnable == false) return false; noskip = 1; for (i = 0; i < n_refdes; i++) { if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) == 0) || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element)))) { Message (_ ("Vendor mapping skipped because refdes = %s matches %s\n"), UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]); noskip = 0; } } if (noskip) for (i = 0; i < n_value; i++) { if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0) || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element)))) { Message (_ ("Vendor mapping skipped because value = %s matches %s\n"), UNKNOWN (VALUE_NAME (element)), ignore_value[i]); noskip = 0; } } if (noskip) for (i = 0; i < n_descr; i++) { if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]) == 0) || rematch (ignore_descr[i], UNKNOWN (DESCRIPTION_NAME (element)))) { Message (_ ("Vendor mapping skipped because descr = %s matches %s\n"), UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]); noskip = 0; } } if (noskip && TEST_FLAG (LOCKFLAG, element)) { Message (_("Vendor mapping skipped because element %s is locked\n"), UNKNOWN (NAMEONPCB_NAME (element))); noskip = 0; } if (noskip) return true; else return false; }
static int ReportDialog (int argc, char **argv, int x, int y) { void *ptr1, *ptr2, *ptr3; int type, prec = Settings.grid_units_mm? 4: 2; char report[2048]; type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3); if (type == NO_TYPE) type = SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3); switch (type) { case VIA_TYPE: { PinTypePtr via; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->via_tree->root, 0); return 0; } #endif via = (PinTypePtr) ptr2; if (TEST_FLAG (HOLEFLAG, via)) sprintf (&report[0], "VIA ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "It is a pure hole of diameter %.*f %s.\n" "Name = \"%s\"." "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE), prec, units (via->X), prec, UNIT (via->Y), prec, UNIT (via->DrillingHole), EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? "It is LOCKED.\n" : ""); else sprintf (&report[0], "VIA ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "Copper width = %0.*f %s. Drill width = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "Annulus = %0.*f %s.\n" "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\"." "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE), prec, units (via->X), prec, UNIT (via->Y), prec, UNIT (via->Thickness), prec, UNIT (via->DrillingHole), prec, UNIT (via->Clearance / 2.), prec, UNIT ((via->Thickness - via->DrillingHole)/2), prec, UNIT (via->Mask), prec, UNIT ((via->Mask - via->Thickness)/2), EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ? "It is LOCKED.\n" : ""); break; } case PIN_TYPE: { PinTypePtr Pin; ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pin_tree->root, 0); return 0; } #endif Pin = (PinTypePtr) ptr2; element = (ElementTypePtr) ptr1; PIN_LOOP (element); { if (pin == Pin) break; } END_LOOP; if (TEST_FLAG (HOLEFLAG, Pin)) sprintf (&report[0], "PIN ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "It is a mounting hole. Drill width = %0.*f %s.\n" "It is owned by element %s.\n" "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), prec, units (Pin->X), prec, UNIT (Pin->Y), prec, UNIT (Pin->DrillingHole), EMPTY (element->Name[1].TextString), TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : ""); else sprintf (&report[0], "PIN ID# %ld; Flags:%s\n" "(X,Y) = (%.*f, %.*f) %s.\n" "Copper width = %0.*f %s. Drill width = %0.*f %s.\n" "Clearance width to Polygon = %0.*f %s.\n" "Annulus = %0.*f %s.\n" "Solder mask hole = %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\".\n" "It is owned by element %s\n as pin number %s.\n" "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE), prec, units(Pin->X), prec, UNIT(Pin->Y), prec, UNIT (Pin->Thickness), prec, UNIT (Pin->DrillingHole), prec, UNIT (Pin->Clearance / 2.), prec, UNIT ((Pin->Thickness - Pin->DrillingHole)/2), prec, UNIT (Pin->Mask), prec, UNIT ((Pin->Mask - Pin->Thickness)/2), EMPTY (Pin->Name), EMPTY (element->Name[1].TextString), EMPTY (Pin->Number), TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED.\n" : ""); break; } case LINE_TYPE: { LineTypePtr line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->line_tree->root, 0); return 0; } #endif line = (LineTypePtr) ptr2; sprintf (&report[0], "LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s, ID = %ld.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s, ID = %ld.\n" "Width = %0.*f %s.\nClearance width in polygons = %0.*f %s.\n" "It is on layer %d\n" "and has name \"%s\".\n" "%s", line->ID, flags_to_string (line->Flags, LINE_TYPE), prec, units (line->Point1.X), prec, UNIT (line->Point1.Y), line->Point1.ID, prec, units (line->Point2.X), prec, UNIT (line->Point2.Y), line->Point2.ID, prec, UNIT (line->Thickness), prec, UNIT (line->Clearance / 2.), GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG, line) ? "It is LOCKED.\n" : ""); break; } case RATLINE_TYPE: { RatTypePtr line; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->rat_tree->root, 0); return 0; } #endif line = (RatTypePtr) ptr2; sprintf (&report[0], "RAT-LINE ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld; " "connects to layer group %d.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld; " "connects to layer group %d.\n", line->ID, flags_to_string (line->Flags, LINE_TYPE), prec, units (line->Point1.X), prec, UNIT (line->Point1.Y), line->Point1.ID, line->group1, prec, units (line->Point2.X), prec, UNIT (line->Point2.Y), line->Point2.ID, line->group2); break; } case ARC_TYPE: { ArcTypePtr Arc; BoxTypePtr box; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->arc_tree->root, 0); return 0; } #endif Arc = (ArcTypePtr) ptr2; box = GetArcEnds (Arc); sprintf (&report[0], "ARC ID# %ld; Flags:%s\n" "CenterPoint(X,Y) = (%.*f, %.*f) %s.\n" "Radius = %0.*f %s, Thickness = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "StartAngle = %ld degrees, DeltaAngle = %ld degrees.\n" "Bounding Box is (%.*f,%.*f), (%.*f,%.*f) %s.\n" "That makes the end points at (%.*f,%.*f) %s and (%.*f,%.*f) %s.\n" "It is on layer %d.\n" "%s", Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE), prec, units(Arc->X), prec, UNIT(Arc->Y), prec, UNIT (Arc->Width), prec, UNIT (Arc->Thickness), prec, UNIT (Arc->Clearance / 2.), Arc->StartAngle, Arc->Delta, prec, units (Arc->BoundingBox.X1), prec, units (Arc->BoundingBox.Y1), prec, units (Arc->BoundingBox.X2), prec, UNIT (Arc->BoundingBox.Y2), prec, units (box->X1), prec, UNIT (box->Y1), prec, units (box->X2), prec, UNIT (box->Y2), GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), TEST_FLAG (LOCKFLAG, Arc) ? "It is LOCKED.\n" : ""); break; } case POLYGON_TYPE: { PolygonTypePtr Polygon; #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->polygon_tree->root, 0); return 0; } #endif Polygon = (PolygonTypePtr) ptr2; sprintf (&report[0], "POLYGON ID# %ld; Flags:%s\n" "Its bounding box is (%.*f,%.*f) (%.*f,%.*f) %s.\n" "It has %d points and could store %d more\n" " without using more memory.\n" "It has %d holes and resides on layer %d.\n" "%s", Polygon->ID, flags_to_string (Polygon->Flags, POLYGON_TYPE), prec, units(Polygon->BoundingBox.X1), prec, units(Polygon->BoundingBox.Y1), prec, units(Polygon->BoundingBox.X2), prec, UNIT(Polygon->BoundingBox.Y2), Polygon->PointN, Polygon->PointMax - Polygon->PointN, Polygon->HoleIndexN, GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1), TEST_FLAG (LOCKFLAG, Polygon) ? "It is LOCKED.\n" : ""); break; } case PAD_TYPE: { int len, dx, dy, mgap; PadTypePtr Pad; ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->pad_tree->root, 0); return 0; } #endif Pad = (PadTypePtr) ptr2; element = (ElementTypePtr) ptr1; PAD_LOOP (element); { { if (pad == Pad) break; } } END_LOOP; dx = Pad->Point1.X - Pad->Point2.X; dy = Pad->Point1.Y - Pad->Point2.Y; len = sqrt (dx*dx+dy*dy); mgap = (Pad->Mask - Pad->Thickness)/2; sprintf (&report[0], "PAD ID# %ld; Flags:%s\n" "FirstPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld.\n" "SecondPoint(X,Y) = (%.*f, %.*f) %s; ID = %ld.\n" "Width = %0.*f %s. Length = %0.*f %s.\n" "Clearance width in polygons = %0.*f %s.\n" "Solder mask = %0.*f x %0.*f %s (gap = %0.*f %s).\n" "Name = \"%s\".\n" "It is owned by SMD element %s\n" " as pin number %s and is on the %s\n" "side of the board.\n" "%s", Pad->ID, flags_to_string (Pad->Flags, PAD_TYPE), prec, units (Pad->Point1.X), prec, UNIT (Pad->Point1.Y), Pad->Point1.ID, prec, units (Pad->Point2.X), prec, UNIT (Pad->Point2.Y), Pad->Point2.ID, prec, UNIT (Pad->Thickness), prec, UNIT (len + Pad->Thickness), prec, UNIT (Pad->Clearance / 2.), prec, units (Pad->Mask), prec, UNIT (Pad->Mask + len), prec, UNIT (mgap), EMPTY (Pad->Name), EMPTY (element->Name[1].TextString), EMPTY (Pad->Number), TEST_FLAG (ONSOLDERFLAG, Pad) ? "solder (bottom)" : "component", TEST_FLAG (LOCKFLAG, Pad) ? "It is LOCKED.\n" : ""); break; } case ELEMENT_TYPE: { ElementTypePtr element; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->element_tree->root, 0); return 0; } #endif element = (ElementTypePtr) ptr2; sprintf (&report[0], "ELEMENT ID# %ld; Flags:%s\n" "BoundingBox (%.*f,%.*f) (%.*f,%.*f) %s.\n" "Descriptive Name \"%s\".\n" "Name on board \"%s\".\n" "Part number name \"%s\".\n" "It is %.*f %s tall and is located at (X,Y) = (%.*f,%.*f)%s.\n" "Mark located at point (X,Y) = (%.*f,%.*f).\n" "It is on the %s side of the board.\n" "%s", element->ID, flags_to_string (element->Flags, ELEMENT_TYPE), prec, units(element->BoundingBox.X1), prec, units (element->BoundingBox.Y1), prec, units(element->BoundingBox.X2), prec, UNIT (element->BoundingBox.Y2), EMPTY (element->Name[0].TextString), EMPTY (element->Name[1].TextString), EMPTY (element->Name[2].TextString), prec, UNIT (0.45 * element->Name[1].Scale * 100.), prec, units(element->Name[1].X), prec, units(element->Name[1].Y), TEST_FLAG (HIDENAMEFLAG, element) ? ",\n but it's hidden" : "", prec, units(element->MarkX), prec, units(element->MarkY), TEST_FLAG (ONSOLDERFLAG, element) ? "solder (bottom)" : "component", TEST_FLAG (LOCKFLAG, element) ? "It is LOCKED.\n" : ""); break; } case TEXT_TYPE: #ifndef NDEBUG if (gui->shift_is_pressed ()) { LayerTypePtr layer = (LayerTypePtr) ptr1; __r_dump_tree (layer->text_tree->root, 0); return 0; } #endif case ELEMENTNAME_TYPE: { char laynum[32]; TextTypePtr text; #ifndef NDEBUG if (gui->shift_is_pressed ()) { __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0); return 0; } #endif text = (TextTypePtr) ptr2; if (type == TEXT_TYPE) sprintf (laynum, "It is on layer %d.", GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1)); sprintf (&report[0], "TEXT ID# %ld; Flags:%s\n" "Located at (X,Y) = (%.*f,%.*f) %s.\n" "Characters are %0.*f %s tall.\n" "Value is \"%s\".\n" "Direction is %d.\n" "The bounding box is (%.*f,%.*f) (%.*f, %.*f) %s.\n" "%s\n" "%s", text->ID, flags_to_string (text->Flags, TEXT_TYPE), prec, units(text->X), prec, UNIT (text->Y), prec, UNIT (0.45 * text->Scale * 100.), text->TextString, text->Direction, prec, units(text->BoundingBox.X1), prec, units(text->BoundingBox.Y1), prec, units(text->BoundingBox.X2), prec, UNIT (text->BoundingBox.Y2), (type == TEXT_TYPE) ? laynum : "It is an element name.", TEST_FLAG (LOCKFLAG, text) ? "It is LOCKED.\n" : ""); break; } case LINEPOINT_TYPE: case POLYGONPOINT_TYPE: { PointTypePtr point = (PointTypePtr) ptr2; sprintf (&report[0], "POINT ID# %ld.\n" "Located at (X,Y) = (%.*f,%.*f) %s.\n" "It belongs to a %s on layer %d.\n", point->ID, prec, units (point->X), prec, UNIT (point->Y), (type == LINEPOINT_TYPE) ? "line" : "polygon", GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1)); break; } case NO_TYPE: report[0] = '\0'; break; default: sprintf (&report[0], "Unknown\n"); break; } if (report[0] == '\0') { Message (_("Nothing found to report on\n")); return 1; } HideCrosshair (false); /* create dialog box */ gui->report_dialog ("Report", &report[0]); RestoreCrosshair (false); return 0; }
static bool CheckShorts (LibraryMenuType *theNet) { bool newone, warn = false; PointerListType *generic = (PointerListType *)calloc (1, sizeof (PointerListType)); /* the first connection was starting point so * the menu is always non-null */ void **menu = GetPointerMemory (generic); *menu = theNet; ALLPIN_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, pin)) { warn = true; if (!pin->Spare) { Message (_("Warning! Net \"%s\" is shorted to %s pin %s\n"), &theNet->Name[2], UNKNOWN (NAMEONPCB_NAME (element)), UNKNOWN (pin->Number)); SET_FLAG (WARNFLAG, pin); continue; } newone = true; POINTER_LOOP (generic); { if (*ptr == pin->Spare) { newone = false; break; } } END_LOOP; if (newone) { menu = GetPointerMemory (generic); *menu = pin->Spare; Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"), &theNet->Name[2], &((LibraryMenuType *) (pin->Spare))->Name[2]); SET_FLAG (WARNFLAG, pin); } } } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, pad)) { warn = true; if (!pad->Spare) { Message (_("Warning! Net \"%s\" is shorted to %s pad %s\n"), &theNet->Name[2], UNKNOWN (NAMEONPCB_NAME (element)), UNKNOWN (pad->Number)); SET_FLAG (WARNFLAG, pad); continue; } newone = true; POINTER_LOOP (generic); { if (*ptr == pad->Spare) { newone = false; break; } } END_LOOP; if (newone) { menu = GetPointerMemory (generic); *menu = pad->Spare; Message (_("Warning! Net \"%s\" is shorted to net \"%s\"\n"), &theNet->Name[2], &((LibraryMenuType *) (pad->Spare))->Name[2]); SET_FLAG (WARNFLAG, pad); } } } ENDALL_LOOP; FreePointerListMemory (generic); free (generic); return (warn); }
static char * describe_location (Coord X, Coord Y) { void *ptr1, *ptr2, *ptr3; int type; int Range = 0; char *elename = ""; char *pinname; char *netname = NULL; char *description; /* check if there are any pins or pads at that position */ type = SearchObjectByLocation (PIN_TYPE | PAD_TYPE, &ptr1, &ptr2, &ptr3, X, Y, Range); if (type == NO_TYPE) return NULL; /* don't mess with silk objects! */ if (type & SILK_TYPE && GetLayerNumber (PCB->Data, (LayerType *) ptr1) >= max_copper_layer) return NULL; if (type == PIN_TYPE || type == PAD_TYPE) elename = (char *)UNKNOWN (NAMEONPCB_NAME ((ElementType *) ptr1)); pinname = ConnectionName (type, ptr1, ptr2); if (pinname == NULL) return NULL; /* Find netlist entry */ MENU_LOOP (&PCB->NetlistLib); { if (!menu->Name) continue; ENTRY_LOOP (menu); { if (!entry->ListEntry) continue; if (strcmp (entry->ListEntry, pinname) == 0) { netname = g_strdup (menu->Name); /* For some reason, the netname has spaces in front of it, strip them */ g_strstrip (netname); break; } } END_LOOP; if (netname != NULL) break; } END_LOOP; description = g_strdup_printf ("Element name: %s\n" "Pinname : %s\n" "Netname : %s", elename, (pinname != NULL) ? pinname : "--", (netname != NULL) ? netname : "--"); g_free (netname); return description; }
static int gerber_set_layer (const char *name, int group, int empty) { int want_outline; char *cp; int idx = (group >= 0 && group < max_group) ? PCB->LayerGroups.Entries[group][0] : group; if (name == NULL) name = PCB->Data->Layer[idx].Name; if (idx >= 0 && idx < max_copper_layer && !print_layer[idx]) return 0; if (strcmp (name, "invisible") == 0) return 0; if (SL_TYPE (idx) == SL_ASSY) return 0; flash_drills = 0; if (strcmp (name, "outline") == 0 || strcmp (name, "route") == 0) flash_drills = 1; if (is_drill && n_pending_drills) { int i; /* dump pending drills in sequence */ qsort (pending_drills, n_pending_drills, sizeof (pending_drills[0]), drill_sort); for (i = 0; i < n_pending_drills; i++) { if (i == 0 || pending_drills[i].diam != pending_drills[i - 1].diam) { Aperture *ap = findAperture (curr_aptr_list, pending_drills[i].diam, ROUND); fprintf (f, "T%02d\r\n", ap->dCode); } /* Notice the last zeroes are literal zeroes here, a x10 scale factor. * * v v */ pcb_fprintf (f, metric ? "X%06.0muY%06.0mu\r\n" : "X%06.0ml0Y%06.0ml0\r\n", gerberDrX (PCB, pending_drills[i].x), gerberDrY (PCB, pending_drills[i].y)); } free (pending_drills); n_pending_drills = max_pending_drills = 0; pending_drills = NULL; } is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL); is_mask = (SL_TYPE (idx) == SL_MASK); current_mask = 0; #if 0 printf ("Layer %s group %d drill %d mask %d\n", name, group, is_drill, is_mask); #endif if (group < 0 || group != lastgroup) { time_t currenttime; char utcTime[64]; #ifdef HAVE_GETPWUID struct passwd *pwentry; #endif ApertureList *aptr_list; Aperture *search; lastgroup = group; lastX = -1; lastY = -1; linewidth = -1; lastcap = -1; aptr_list = setLayerApertureList (layer_list_idx++); if (finding_apertures) goto emit_outline; if (aptr_list->count == 0 && !all_layers) return 0; maybe_close_f (f); f = NULL; pagecount++; assign_file_suffix (filesuff, idx); f = fopen (filename, "wb"); /* Binary needed to force CR-LF */ if (f == NULL) { Message ( "Error: Could not open %s for writing.\n", filename); return 1; } was_drill = is_drill; if (verbose) { int c = aptr_list->count; printf ("Gerber: %d aperture%s in %s\n", c, c == 1 ? "" : "s", filename); } if (is_drill) { /* We omit the ,TZ here because we are not omitting trailing zeros. Our format is always six-digit 0.1 mil or µm resolution (i.e. 001100 = 0.11" or 1.1mm)*/ fprintf (f, "M48\r\n"); fprintf (f, metric ? "METRIC,000.000\r\n" : "INCH\r\n"); for (search = aptr_list->data; search; search = search->next) pcb_fprintf (f, metric ? "T%02dC%.3`mm\r\n" : "T%02dC%.3`mi\r\n", search->dCode, search->width); fprintf (f, "%%\r\n"); /* FIXME */ return 1; } fprintf (f, "G04 start of page %d for group %d idx %d *\r\n", pagecount, group, idx); /* Create a portable timestamp. */ currenttime = time (NULL); { /* avoid gcc complaints */ const char *fmt = "%c UTC"; strftime (utcTime, sizeof utcTime, fmt, gmtime (¤ttime)); } /* Print a cute file header at the beginning of each file. */ fprintf (f, "G04 Title: %s, %s *\r\n", UNKNOWN (PCB->Name), UNKNOWN (name)); fprintf (f, "G04 Creator: %s " VERSION " *\r\n", Progname); fprintf (f, "G04 CreationDate: %s *\r\n", utcTime); #ifdef HAVE_GETPWUID /* ID the user. */ pwentry = getpwuid (getuid ()); fprintf (f, "G04 For: %s *\r\n", pwentry->pw_name); #endif fprintf (f, "G04 Format: Gerber/RS-274X *\r\n"); pcb_fprintf (f, metric ? "G04 PCB-Dimensions (mm): %.2mm %.2mm *\r\n" : "G04 PCB-Dimensions (mil): %.2ml %.2ml *\r\n", PCB->MaxWidth, PCB->MaxHeight); fprintf (f, "G04 PCB-Coordinate-Origin: lower left *\r\n"); /* Signal data in inches. */ fprintf (f, metric ? "%%MOMM*%%\r\n" : "%%MOIN*%%\r\n"); /* Signal Leading zero suppression, Absolute Data, 2.5 format in inch, 4.3 in mm */ fprintf (f, metric ? "%%FSLAX43Y43*%%\r\n" : "%%FSLAX25Y25*%%\r\n"); /* build a legal identifier. */ if (layername) free (layername); layername = strdup (filesuff); if (strrchr (layername, '.')) * strrchr (layername, '.') = 0; for (cp=layername; *cp; cp++) { if (isalnum((int) *cp)) *cp = toupper((int) *cp); else *cp = '_'; } fprintf (f, "%%LN%s*%%\r\n", layername); lncount = 1; for (search = aptr_list->data; search; search = search->next) fprintAperture(f, search); if (aptr_list->count == 0) /* We need to put *something* in the file to make it be parsed as RS-274X instead of RS-274D. */ fprintf (f, "%%ADD11C,0.0100*%%\r\n"); } emit_outline: /* If we're printing a copper layer other than the outline layer, and we want to "print outlines", and we have an outline layer, print the outline layer on this layer also. */ want_outline = 0; if (copy_outline_mode == COPY_OUTLINE_MASK && SL_TYPE (idx) == SL_MASK) want_outline = 1; if (copy_outline_mode == COPY_OUTLINE_SILK && SL_TYPE (idx) == SL_SILK) want_outline = 1; if (copy_outline_mode == COPY_OUTLINE_ALL && (SL_TYPE (idx) == SL_SILK || SL_TYPE (idx) == SL_MASK || SL_TYPE (idx) == SL_FAB || SL_TYPE (idx) == SL_ASSY || SL_TYPE (idx) == 0)) want_outline = 1; if (want_outline && strcmp (name, "outline") && strcmp (name, "route")) { if (outline_layer && outline_layer != PCB->Data->Layer+idx) DrawLayer (outline_layer, ®ion); else if (!outline_layer) { hidGC gc = gui->make_gc (); printf("name %s idx %d\n", name, idx); if (SL_TYPE (idx) == SL_SILK) gui->set_line_width (gc, PCB->minSlk); else if (group >= 0) gui->set_line_width (gc, PCB->minWid); else gui->set_line_width (gc, AUTO_OUTLINE_WIDTH); gui->draw_line (gc, 0, 0, PCB->MaxWidth, 0); gui->draw_line (gc, 0, 0, 0, PCB->MaxHeight); gui->draw_line (gc, PCB->MaxWidth, 0, PCB->MaxWidth, PCB->MaxHeight); gui->draw_line (gc, 0, PCB->MaxHeight, PCB->MaxWidth, PCB->MaxHeight); gui->destroy_gc (gc); } } return 1; }