Boolean ChangeLayoutName( char *Name ) { int eax; PCB->Name = Name; hid_action( "PCBChanged" ); return 1; }
int ActionApplyVendor (int argc, char **argv, Coord x, Coord y) { hid_action ("Busy"); apply_vendor_map (); return 0; }
void NetlistChanged (int force_unfreeze) { if (force_unfreeze) netlist_frozen = 0; if (netlist_frozen) netlist_needs_update = 1; else { netlist_needs_update = 0; hid_action ("NetlistChanged"); } }
/* DEBUG */ static void DebugPOLYAREA (POLYAREA *s, char *color) { int *x, *y, n, i = 0; PLINE *pl; VNODE *v; POLYAREA *p; #ifndef DEBUG_POLYAREA return; #endif p = s; do { for (pl = p->contours; pl; pl = pl->next) { n = pl->Count; x = (int *) malloc (n * sizeof (int)); y = (int *) malloc (n * sizeof (int)); for (v = &pl->head; i < n; v = v->next) { x[i] = v->point[0]; y[i++] = v->point[1]; } if (1) { gui->graphics->set_color (Output.fgGC, color ? color : PCB->ConnectedColor); gui->graphics->set_line_width (Output.fgGC, 1); for (i = 0; i < n - 1; i++) { gui->graphics->draw_line (Output.fgGC, x[i], y[i], x[i + 1], y[i + 1]); // gui->fill_circle (Output.fgGC, x[i], y[i], 30); } gui->graphics->draw_line (Output.fgGC, x[n - 1], y[n - 1], x[0], y[0]); } free (x); free (y); } } while ((p = p->f) != s); hid_action("Busy"); sleep(3); }
int MoveLayer (int old_index, int new_index) { int groups[MAX_LAYER + 2], l, g; LayerType saved_layer; int saved_group; AddLayerChangeToUndoList (old_index, new_index); IncrementUndoSerialNumber (); if (old_index < -1 || old_index >= max_copper_layer) { Message ("Invalid old layer %d for move: must be -1..%d\n", old_index, max_copper_layer - 1); return 1; } if (new_index < -1 || new_index > max_copper_layer || new_index >= MAX_LAYER) { Message ("Invalid new layer %d for move: must be -1..%d\n", new_index, max_copper_layer); return 1; } if (old_index == new_index) return 0; if (new_index == -1 && LastLayerInComponentGroup (old_index)) { gui->confirm_dialog ("You can't delete the last top-side layer\n", "Ok", NULL); return 1; } if (new_index == -1 && LastLayerInSolderGroup (old_index)) { gui->confirm_dialog ("You can't delete the last bottom-side layer\n", "Ok", NULL); return 1; } for (g = 0; g < MAX_LAYER+2; g++) groups[g] = -1; for (g = 0; g < MAX_LAYER; g++) for (l = 0; l < PCB->LayerGroups.Number[g]; l++) groups[PCB->LayerGroups.Entries[g][l]] = g; if (old_index == -1) { LayerTypePtr lp; if (max_copper_layer == MAX_LAYER) { Message ("No room for new layers\n"); return 1; } /* Create a new layer at new_index. */ lp = &PCB->Data->Layer[new_index]; memmove (&PCB->Data->Layer[new_index + 1], &PCB->Data->Layer[new_index], (max_copper_layer - new_index + 2) * sizeof (LayerType)); memmove (&groups[new_index + 1], &groups[new_index], (max_copper_layer - new_index + 2) * sizeof (int)); max_copper_layer++; memset (lp, 0, sizeof (LayerType)); lp->On = 1; lp->Name = strdup ("New Layer"); lp->Color = Settings.LayerColor[new_index]; lp->SelectedColor = Settings.LayerSelectedColor[new_index]; for (l = 0; l < max_copper_layer; l++) if (LayerStack[l] >= new_index) LayerStack[l]++; LayerStack[max_copper_layer - 1] = new_index; } else if (new_index == -1) { /* Delete the layer at old_index */ memmove (&PCB->Data->Layer[old_index], &PCB->Data->Layer[old_index + 1], (max_copper_layer - old_index + 2 - 1) * sizeof (LayerType)); memset (&PCB->Data->Layer[max_copper_layer + 1], 0, sizeof (LayerType)); memmove (&groups[old_index], &groups[old_index + 1], (max_copper_layer - old_index + 2 - 1) * sizeof (int)); for (l = 0; l < max_copper_layer; l++) if (LayerStack[l] == old_index) memmove (LayerStack + l, LayerStack + l + 1, (max_copper_layer - l - 1) * sizeof (LayerStack[0])); max_copper_layer--; for (l = 0; l < max_copper_layer; l++) if (LayerStack[l] > old_index) LayerStack[l]--; } else { /* Move an existing layer */ memcpy (&saved_layer, &PCB->Data->Layer[old_index], sizeof (LayerType)); saved_group = groups[old_index]; if (old_index < new_index) { memmove (&PCB->Data->Layer[old_index], &PCB->Data->Layer[old_index + 1], (new_index - old_index) * sizeof (LayerType)); memmove (&groups[old_index], &groups[old_index + 1], (new_index - old_index) * sizeof (int)); } else { memmove (&PCB->Data->Layer[new_index + 1], &PCB->Data->Layer[new_index], (old_index - new_index) * sizeof (LayerType)); memmove (&groups[new_index + 1], &groups[new_index], (old_index - new_index) * sizeof (int)); } memcpy (&PCB->Data->Layer[new_index], &saved_layer, sizeof (LayerType)); groups[new_index] = saved_group; } move_all_thermals(old_index, new_index); for (g = 0; g < MAX_LAYER; g++) PCB->LayerGroups.Number[g] = 0; for (l = 0; l < max_copper_layer + 2; l++) { int i; g = groups[l]; if (g >= 0) { i = PCB->LayerGroups.Number[g]++; PCB->LayerGroups.Entries[g][i] = l; } } for (g = 0; g < MAX_LAYER; g++) if (PCB->LayerGroups.Number[g] == 0) { memmove (&PCB->LayerGroups.Number[g], &PCB->LayerGroups.Number[g + 1], (MAX_LAYER - g - 1) * sizeof (PCB->LayerGroups.Number[g])); memmove (&PCB->LayerGroups.Entries[g], &PCB->LayerGroups.Entries[g + 1], (MAX_LAYER - g - 1) * sizeof (PCB->LayerGroups.Entries[g])); } hid_action ("LayersChanged"); gui->invalidate_all (); return 0; }
/* --------------------------------------------------------------------------- * recalculates the passed coordinates to fit the current grid setting */ void FitCrosshairIntoGrid (LocationType X, LocationType Y) { LocationType x2, y2, x0, y0; void *ptr1, *ptr2, *ptr3; float nearest, sq_dist; int ans; x0 = 0; y0 = 0; x2 = PCB->MaxWidth; y2 = PCB->MaxHeight; Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X)); Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y)); if (PCB->RatDraw) { x0 = -600; y0 = -600; } else { /* check if new position is inside the output window * This might not be true after the window has been resized. * In this case we just set it to the center of the window or * with respect to the grid (if possible) */ if (Crosshair.X < x0 || Crosshair.X > x2) { if (x2 + 1 >= PCB->Grid) /* there must be a point that matches the grid * so we just have to look for it with some integer * calculations */ x0 = GRIDFIT_X (PCB->Grid, PCB->Grid); else x0 = (x2) / 2; } else /* check if the new position matches the grid */ x0 = GRIDFIT_X (Crosshair.X, PCB->Grid); /* do the same for the second coordinate */ if (Crosshair.Y < y0 || Crosshair.Y > y2) { if (y2 + 1 >= PCB->Grid) y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid); else y0 = (y2) / 2; } else y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid); if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { int dx = Crosshair.X - Marked.X; int dy = Crosshair.Y - Marked.Y; if (ABS (dx) > ABS (dy)) y0 = Marked.Y; else x0 = Marked.X; } } nearest = -1; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PAD_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid self-snapping when moving */ if (ans && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans && (Settings.Mode == LINE_MODE || (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE))) { PadTypePtr pad = (PadTypePtr) ptr2; LayerType *desired_layer; Cardinal desired_group; Cardinal SLayer, CLayer; int found_our_layer = false; desired_layer = CURRENT; if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE) { desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1; } /* find layer groups of the component side and solder side */ SLayer = GetLayerGroupNumberByNumber (solder_silk_layer); CLayer = GetLayerGroupNumberByNumber (component_silk_layer); desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer; GROUP_LOOP (PCB->Data, desired_group); { if (layer == desired_layer) { found_our_layer = true; break; } } END_LOOP; if (found_our_layer == false) ans = NO_TYPE; } if (ans) { PadTypePtr pad = (PadTypePtr) ptr2; LocationType px, py; px = (pad->Point1.X + pad->Point2.X) / 2; py = (pad->Point1.Y + pad->Point2.Y) / 2; sq_dist = SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y); if (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist) { x0 = px; y0 = py; nearest = sq_dist; } } if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PIN_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid self-snapping when moving */ if (ans && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans) { PinTypePtr pin = (PinTypePtr) ptr2; sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pin->X; y0 = pin->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, VIA_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid snapping vias to any other vias */ if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == VIA_TYPE) { if (ans & PIN_TYPES) ans = NO_TYPE; } if (ans) { PinTypePtr pin = (PinTypePtr) ptr2; sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pin->X; y0 = pin->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans) { PointTypePtr pnt = (PointTypePtr) ptr3; sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pnt->X; y0 = pnt->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans) { PointTypePtr pnt = (PointTypePtr) ptr3; sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pnt->X; y0 = pnt->Y; nearest = sq_dist; } } if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans & ELEMENT_TYPE) { ElementTypePtr el = (ElementTypePtr) ptr1; sq_dist = SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist) { x0 = el->MarkX; y0 = el->MarkY; nearest = sq_dist; } } if (x0 >= 0 && y0 >= 0) { Crosshair.X = x0; Crosshair.Y = y0; } if (Settings.Mode == ARROW_MODE) { ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); }
/* --------------------------------------------------------------------------- * load PCB * parse the file with enabled 'PCB mode' (see parser) * if successful, update some other stuff * * If revert is true, we pass "revert" as a parameter * to the HID's PCBChanged action. */ static int real_load_pcb (char *Filename, bool revert) { const char *unit_suffix, *grid_size; char *new_filename; PCBType *newPCB = CreateNewPCB (false); PCBType *oldPCB; #ifdef DEBUG double elapsed; clock_t start, end; start = clock (); #endif new_filename = strdup (Filename); oldPCB = PCB; PCB = newPCB; /* mark the default font invalid to know if the file has one */ newPCB->Font.Valid = false; /* new data isn't added to the undo list */ if (!ParsePCB (PCB, new_filename)) { RemovePCB (oldPCB); CreateNewPCBPost (PCB, 0); ResetStackAndVisibility (); /* update cursor location */ Crosshair.X = CLAMP (PCB->CursorX, 0, PCB->MaxWidth); Crosshair.Y = CLAMP (PCB->CursorY, 0, PCB->MaxHeight); /* update cursor confinement and output area (scrollbars) */ ChangePCBSize (PCB->MaxWidth, PCB->MaxHeight); /* enable default font if necessary */ if (!PCB->Font.Valid) { Message (_ ("File '%s' has no font information, using default font\n"), new_filename); PCB->Font.Valid = true; } /* clear 'changed flag' */ SetChangedFlag (false); PCB->Filename = new_filename; /* just in case a bad file saved file is loaded */ /* Use attribute PCB::grid::unit as unit, if we can */ unit_suffix = AttributeGet (PCB, "PCB::grid::unit"); if (unit_suffix && *unit_suffix) { const Unit *new_unit = get_unit_struct (unit_suffix); if (new_unit) Settings.grid_unit = new_unit; } AttributePut (PCB, "PCB::grid::unit", Settings.grid_unit->suffix); /* Use attribute PCB::grid::size as size, if we can */ grid_size = AttributeGet (PCB, "PCB::grid::size"); if (grid_size) { PCB->Grid = GetValue (grid_size, NULL, NULL); } sort_netlist (); set_some_route_style (); if (revert) hid_actionl ("PCBChanged", "revert", NULL); else hid_action ("PCBChanged"); #ifdef DEBUG end = clock (); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; gui->log ("Loading file %s took %f seconds of CPU time\n", new_filename, elapsed); #endif return (0); } PCB = oldPCB; hid_action ("PCBChanged"); /* release unused memory */ RemovePCB (newPCB); return (1); }
/* --------------------------------------------------------------------------- * creates a new PCB */ PCBTypePtr CreateNewPCB (bool SetDefaultNames) { PCBTypePtr ptr; int i; /* allocate memory, switch all layers on and copy resources */ ptr = (PCBTypePtr)calloc (1, sizeof (PCBType)); ptr->Data = CreateNewBuffer (); ptr->Data->pcb = (PCBTypePtr) ptr; ptr->ThermStyle = 4; ptr->IsleArea = 2.e8; ptr->SilkActive = false; ptr->RatDraw = false; SET_FLAG (NAMEONPCBFLAG, ptr); if (Settings.ShowNumber) SET_FLAG (SHOWNUMBERFLAG, ptr); if (Settings.AllDirectionLines) SET_FLAG (ALLDIRECTIONFLAG, ptr); ptr->Clipping = 1; /* this is the most useful starting point for now */ if (Settings.RubberBandMode) SET_FLAG (RUBBERBANDFLAG, ptr); if (Settings.SwapStartDirection) SET_FLAG (SWAPSTARTDIRFLAG, ptr); if (Settings.UniqueNames) SET_FLAG (UNIQUENAMEFLAG, ptr); if (Settings.SnapPin) SET_FLAG (SNAPPINFLAG, ptr); if (Settings.ClearLine) SET_FLAG (CLEARNEWFLAG, ptr); if (Settings.FullPoly) SET_FLAG (NEWFULLPOLYFLAG, ptr); if (Settings.OrthogonalMoves) SET_FLAG (ORTHOMOVEFLAG, ptr); if (Settings.liveRouting) SET_FLAG (LIVEROUTEFLAG, ptr); if (Settings.ShowDRC) SET_FLAG (SHOWDRCFLAG, ptr); if (Settings.AutoDRC) SET_FLAG (AUTODRCFLAG, ptr); ptr->Grid = Settings.Grid; ptr->LayerGroups = Settings.LayerGroups; STYLE_LOOP (ptr); { *style = Settings.RouteStyle[n]; style->index = n; } END_LOOP; hid_action ("RouteStylesChanged"); ptr->Zoom = Settings.Zoom; ptr->MaxWidth = Settings.MaxWidth; ptr->MaxHeight = Settings.MaxHeight; ptr->ID = ID++; ptr->ThermScale = 0.5; ptr->Bloat = Settings.Bloat; ptr->Shrink = Settings.Shrink; ptr->minWid = Settings.minWid; ptr->minSlk = Settings.minSlk; ptr->minDrill = Settings.minDrill; ptr->minRing = Settings.minRing; for (i = 0; i < MAX_LAYER; i++) ptr->Data->Layer[i].Name = strdup (Settings.DefaultLayerName[i]); return (ptr); }
/* --------------------------------------------------------------------------- * load PCB * parse the file with enabled 'PCB mode' (see parser) * if successful, update some other stuff */ int LoadPCB (char *Filename) { PCBTypePtr newPCB = CreateNewPCB (false); PCBTypePtr oldPCB; bool units_mm; #ifdef DEBUG double elapsed; clock_t start, end; start = clock (); #endif oldPCB = PCB; PCB = newPCB; /* new data isn't added to the undo list */ if (!ParsePCB (PCB, Filename)) { RemovePCB (oldPCB); CreateNewPCBPost (PCB, 0); ResetStackAndVisibility (); /* update cursor location */ Crosshair.X = MAX (0, MIN (PCB->CursorX, (LocationType) PCB->MaxWidth)); Crosshair.Y = MAX (0, MIN (PCB->CursorY, (LocationType) PCB->MaxHeight)); Xorig = Crosshair.X - TO_PCB (Output.Width / 2); Yorig = Crosshair.Y - TO_PCB (Output.Height / 2); /* update cursor confinement and output area (scrollbars) */ ChangePCBSize (PCB->MaxWidth, PCB->MaxHeight); /* create default font if necessary */ if (!PCB->Font.Valid) { Message (_ ("File '%s' has no font information, using default font\n"), Filename); CreateDefaultFont (); } /* clear 'changed flag' */ SetChangedFlag (false); PCB->Filename = strdup (Filename); /* just in case a bad file saved file is loaded */ units_mm = (PCB->Grid != (int) PCB->Grid) ? true : false; Settings.grid_units_mm = units_mm; sort_netlist (); set_some_route_style (); hid_action ("PCBChanged"); #ifdef DEBUG end = clock (); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; gui->log ("Loading file %s took %f seconds of CPU time\n", Filename, elapsed); #endif return (0); } PCB = oldPCB; hid_action ("PCBChanged"); /* release unused memory */ RemovePCB (newPCB); return (1); }
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); }
/* --------------------------------------------------------------------------- * recalculates the passed coordinates to fit the current grid setting */ void FitCrosshairIntoGrid (LocationType X, LocationType Y) { LocationType x2, y2, x0, y0; void *ptr1, *ptr2, *ptr3; int ans; x0 = 0; y0 = 0; x2 = PCB->MaxWidth; y2 = PCB->MaxHeight; Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X)); Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y)); if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) { ans = SearchScreen (Crosshair.X, Crosshair.Y, PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE && !PCB->RatDraw) ans = SearchScreen (Crosshair.X, Crosshair.Y, VIA_TYPE | LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE && !PCB->RatDraw) ans = SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); } else ans = NO_TYPE; /* avoid self-snapping */ if (Settings.Mode == MOVE_MODE) { switch (Crosshair.AttachedObject.Type) { case ELEMENT_TYPE: if ((ans & (PAD_TYPE | PIN_TYPE)) && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; break; case VIA_TYPE: /* just avoid snapping to any other vias */ if (ans & PIN_TYPES) ans = NO_TYPE; break; } } if (PCB->RatDraw) { x0 = -600; y0 = -600; } else { /* check if new position is inside the output window * This might not be true after the window has been resized. * In this case we just set it to the center of the window or * with respect to the grid (if possible) */ if (Crosshair.X < x0 || Crosshair.X > x2) { if (x2 + 1 >= PCB->Grid) /* there must be a point that matches the grid * so we just have to look for it with some integer * calculations */ x0 = GRIDFIT_X (PCB->Grid, PCB->Grid); else x0 = (x2) / 2; } else /* check if the new position matches the grid */ x0 = GRIDFIT_X (Crosshair.X, PCB->Grid); /* do the same for the second coordinate */ if (Crosshair.Y < y0 || Crosshair.Y > y2) { if (y2 + 1 >= PCB->Grid) y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid); else y0 = (y2) / 2; } else y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid); if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { int dx = Crosshair.X - Marked.X; int dy = Crosshair.Y - Marked.Y; if (ABS (dx) > ABS (dy)) y0 = Marked.Y; else x0 = Marked.X; } } if (ans & PAD_TYPE) { PadTypePtr pad = (PadTypePtr) ptr2; LocationType px, py; px = (pad->Point1.X + pad->Point2.X) / 2; py = (pad->Point1.Y + pad->Point2.Y) / 2; if (!gui->shift_is_pressed() || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y))) { x0 = px; y0 = py; } } else if (ans & (PIN_TYPE | VIA_TYPE)) { PinTypePtr pin = (PinTypePtr) ptr2; if (!gui->shift_is_pressed() || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y))) { x0 = pin->X; y0 = pin->Y; } } else if (ans & LINEPOINT_TYPE) { PointTypePtr pnt = (PointTypePtr) ptr3; if (((x0 - Crosshair.X) * (x0 - Crosshair.X) + (y0 - Crosshair.Y) * (y0 - Crosshair.Y)) > ((pnt->X - Crosshair.X) * (pnt->X - Crosshair.X) + (pnt->Y - Crosshair.Y) * (pnt->Y - Crosshair.Y))) { x0 = pnt->X; y0 = pnt->Y; } } else if (ans & ELEMENT_TYPE) { ElementTypePtr el = (ElementTypePtr) ptr1; if (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y)) { x0 = el->MarkX; y0 = el->MarkY; } } if (x0 >= 0 && y0 >= 0) { Crosshair.X = x0; Crosshair.Y = y0; } if (Settings.Mode == ARROW_MODE) { ans = SearchScreen (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); }
/* --------------------------------------------------------------------------- * recalculates the passed coordinates to fit the current grid setting */ void FitCrosshairIntoGrid (Coord X, Coord Y) { Coord nearest_grid_x, nearest_grid_y; void *ptr1, *ptr2, *ptr3; struct snap_data snap_data; int ans; Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX); Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY); if (PCB->RatDraw) { nearest_grid_x = -MIL_TO_COORD (6); nearest_grid_y = -MIL_TO_COORD (6); } else { nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX); nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY); if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { Coord dx = Crosshair.X - Marked.X; Coord dy = Crosshair.Y - Marked.Y; if (ABS (dx) > ABS (dy)) nearest_grid_y = Marked.Y; else nearest_grid_x = Marked.X; } } snap_data.crosshair = &Crosshair; snap_data.nearest_sq_dist = crosshair_sq_dist (&Crosshair, nearest_grid_x, nearest_grid_y); snap_data.nearest_is_grid = true; snap_data.x = nearest_grid_x; snap_data.y = nearest_grid_y; ans = NO_TYPE; if (!PCB->RatDraw) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); if (ans & ELEMENT_TYPE) { ElementType *el = (ElementType *) ptr1; check_snap_object (&snap_data, el->MarkX, el->MarkY, false); } ans = NO_TYPE; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PAD_TYPE, &ptr1, &ptr2, &ptr3); /* Avoid self-snapping when moving */ if (ans != NO_TYPE && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans != NO_TYPE && ( Settings.Mode == LINE_MODE || (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE))) { PadTypePtr pad = (PadTypePtr) ptr2; LayerType *desired_layer; Cardinal desired_group; Cardinal SLayer, CLayer; int found_our_layer = false; desired_layer = CURRENT; if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE) { desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1; } /* find layer groups of the component side and solder side */ SLayer = GetLayerGroupNumberByNumber (solder_silk_layer); CLayer = GetLayerGroupNumberByNumber (component_silk_layer); desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer; GROUP_LOOP (PCB->Data, desired_group); { if (layer == desired_layer) { found_our_layer = true; break; } } END_LOOP; if (found_our_layer == false) ans = NO_TYPE; } if (ans != NO_TYPE) { PadType *pad = (PadType *)ptr2; check_snap_object (&snap_data, (pad->Point1.X + pad->Point2.X) / 2, (pad->Point1.Y + pad->Point2.Y) / 2, true); } ans = NO_TYPE; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PIN_TYPE, &ptr1, &ptr2, &ptr3); /* Avoid self-snapping when moving */ if (ans != NO_TYPE && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans != NO_TYPE) { PinType *pin = (PinType *)ptr2; check_snap_object (&snap_data, pin->X, pin->Y, true); } ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, VIA_TYPE, &ptr1, &ptr2, &ptr3); /* Avoid snapping vias to any other vias */ if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == VIA_TYPE && (ans & PIN_TYPES)) ans = NO_TYPE; if (ans != NO_TYPE) { PinType *pin = (PinType *)ptr2; check_snap_object (&snap_data, pin->X, pin->Y, true); } ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans != NO_TYPE) { PointType *pnt = (PointType *)ptr3; check_snap_object (&snap_data, pnt->X, pnt->Y, true); } check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y); ans = NO_TYPE; if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans != NO_TYPE) { PointType *pnt = (PointType *)ptr3; check_snap_object (&snap_data, pnt->X, pnt->Y, true); } if (snap_data.x >= 0 && snap_data.y >= 0) { Crosshair.X = snap_data.x; Crosshair.Y = snap_data.y; } if (Settings.Mode == ARROW_MODE) { ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); }
static int FontEdit (int argc, char **argv, Coord Ux, Coord Uy) { FontType *font; SymbolType *symbol; LayerType *lfont, *lorig, *lwidth, *lgrid; int s, l; if (hid_actionl ("New", "Font", 0)) { return 1; } Settings.grid_unit = get_unit_struct("mil"); Settings.Bloat = PCB->Bloat = 1; Settings.Shrink = PCB->Shrink = 1; Settings.minWid = PCB->minWid = 1; Settings.minSlk = PCB->minSlk = 1; MoveLayerToGroup (max_copper_layer + TOP_SILK_LAYER, 0); MoveLayerToGroup (max_copper_layer + BOTTOM_SILK_LAYER, 1); while (PCB->Data->LayerN > 4) { MoveLayer (4, -1); } for (l = 0; l < 4; l++) { MoveLayerToGroup (l, l); } PCB->MaxWidth = CELL_SIZE * 18; PCB->MaxHeight = CELL_SIZE * ((MAX_FONTPOSITION + 15) / 16 + 2); PCB->Grid = MIL_TO_COORD (5); PCB->Data->Layer[0].Name = strdup ("Font"); PCB->Data->Layer[1].Name = strdup ("OrigFont"); PCB->Data->Layer[2].Name = strdup ("Width"); PCB->Data->Layer[3].Name = strdup ("Grid"); hid_action ("PCBChanged"); hid_action ("LayersChanged"); lfont = PCB->Data->Layer + 0; lorig = PCB->Data->Layer + 1; lwidth = PCB->Data->Layer + 2; lgrid = PCB->Data->Layer + 3; font = &PCB->Font; for (s = 0; s <= MAX_FONTPOSITION; s++) { Coord ox = (s % 16 + 1) * CELL_SIZE; Coord oy = (s / 16 + 1) * CELL_SIZE; Coord w, miny, maxy, maxx = 0; symbol = &font->Symbol[s]; miny = MIL_TO_COORD (5); maxy = font->MaxHeight; for (l = 0; l < symbol->LineN; l++) { CreateDrawnLineOnLayer (lfont, symbol->Line[l].Point1.X + ox, symbol->Line[l].Point1.Y + oy, symbol->Line[l].Point2.X + ox, symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, NoFlags ()); CreateDrawnLineOnLayer (lorig, symbol->Line[l].Point1.X + ox, symbol->Line[l].Point1.Y + oy, symbol->Line[l].Point2.X + ox, symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, NoFlags ()); if (maxx < symbol->Line[l].Point1.X) { maxx = symbol->Line[l].Point1.X; } if (maxx < symbol->Line[l].Point2.X) { maxx = symbol->Line[l].Point2.X; } } w = maxx + symbol->Delta + ox; CreateDrawnLineOnLayer (lwidth, w, miny + oy, w, maxy + oy, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ()); } for (l = 0; l < 16; l++) { int x = (l + 1) * CELL_SIZE; CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ()); } for (l = 0; l <= MAX_FONTPOSITION / 16 + 1; l++) { int y = (l + 1) * CELL_SIZE; CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, MIL_TO_COORD (1), MIL_TO_COORD (1), NoFlags ()); } return 0; }
static int FontEdit (int argc, char **argv, int Ux, int Uy) { FontType *font; SymbolType *symbol; LayerTypePtr lfont, lorig, lwidth, lgrid; int s, l; if (hid_actionl ("New", "Font", 0)) return 1; while (PCB->Data->LayerN > 4) MoveLayer (4, -1); for (l = 0; l < 4; l++) { MoveLayerToGroup (l, l); } PCB->MaxWidth = CELL_SIZE * 18; PCB->MaxHeight = CELL_SIZE * ((MAX_FONTPOSITION + 15) / 16 + 2); PCB->Grid = 500.0; PCB->Data->Layer[0].Name = MyStrdup ("Font", "FontEdit"); PCB->Data->Layer[1].Name = MyStrdup ("OrigFont", "FontEdit"); PCB->Data->Layer[2].Name = MyStrdup ("Width", "FontEdit"); PCB->Data->Layer[3].Name = MyStrdup ("Grid", "FontEdit"); hid_action ("PCBChanged"); hid_action ("LayersChanged"); lfont = PCB->Data->Layer + 0; lorig = PCB->Data->Layer + 1; lwidth = PCB->Data->Layer + 2; lgrid = PCB->Data->Layer + 3; font = &PCB->Font; for (s = 0; s <= MAX_FONTPOSITION; s++) { int ox = (s % 16 + 1) * CELL_SIZE; int oy = (s / 16 + 1) * CELL_SIZE; int w, miny, maxy, maxx = 0; symbol = &font->Symbol[s]; miny = 500; maxy = font->MaxHeight; for (l = 0; l < symbol->LineN; l++) { CreateDrawnLineOnLayer (lfont, symbol->Line[l].Point1.X + ox, symbol->Line[l].Point1.Y + oy, symbol->Line[l].Point2.X + ox, symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, NoFlags ()); CreateDrawnLineOnLayer (lorig, symbol->Line[l].Point1.X + ox, symbol->Line[l].Point1.Y + oy, symbol->Line[l].Point2.X + ox, symbol->Line[l].Point2.Y + oy, symbol->Line[l].Thickness, symbol->Line[l].Thickness, NoFlags ()); if (maxx < symbol->Line[l].Point1.X) maxx = symbol->Line[l].Point1.X; if (maxx < symbol->Line[l].Point2.X) maxx = symbol->Line[l].Point2.X; } w = maxx + symbol->Delta + ox; CreateDrawnLineOnLayer (lwidth, w, miny + oy, w, maxy + oy, 100, 100, NoFlags ()); } for (l = 0; l < 16; l++) { int x = (l + 1) * CELL_SIZE; CreateDrawnLineOnLayer (lgrid, x, 0, x, PCB->MaxHeight, 100, 100, NoFlags ()); } for (l = 0; l <= MAX_FONTPOSITION / 16 + 1; l++) { int y = (l + 1) * CELL_SIZE; CreateDrawnLineOnLayer (lgrid, 0, y, PCB->MaxWidth, y, 100, 100, NoFlags ()); } return 0; }
Boolean ChangeLayerName( LayerTypePtr Layer, char *Name ) { int eax; hid_action( "LayersChanged" ); return 1; }