pcb 4.1.1
An interactive printed circuit board layout editor.

change.c

Go to the documentation of this file.
00001 
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036 
00037 #include <stdlib.h>
00038 #include <stdio.h>
00039 
00040 #include "global.h"
00041 
00042 #include "change.h"
00043 #include "create.h"
00044 #include "crosshair.h"
00045 #include "data.h"
00046 #include "draw.h"
00047 #include "error.h"
00048 #include "mymem.h"
00049 #include "misc.h"
00050 #include "mirror.h"
00051 #include "polygon.h"
00052 #include "rats.h"
00053 #include "remove.h"
00054 #include "rtree.h"
00055 #include "search.h"
00056 #include "select.h"
00057 #include "set.h"
00058 #include "thermal.h"
00059 #include "undo.h"
00060 
00061 #ifdef HAVE_LIBDMALLOC
00062 #include <dmalloc.h>
00063 #endif
00064 
00065 /* ---------------------------------------------------------------------------
00066  * some local prototypes
00067  */
00068 static void *ChangePinSize (ElementType *, PinType *);
00069 static void *ChangePinClearSize (ElementType *, PinType *);
00070 static void *ChangePinMaskSize (ElementType *, PinType *);
00071 static void *ChangePadSize (ElementType *, PadType *);
00072 static void *ChangePadClearSize (ElementType *, PadType *);
00073 static void *ChangePadMaskSize (ElementType *, PadType *);
00074 static void *ChangePin2ndSize (ElementType *, PinType *);
00075 static void *ChangeElement2ndSize (ElementType *);
00076 static void *ChangeViaSize (PinType *);
00077 static void *ChangeVia2ndSize (PinType *);
00078 static void *ChangeViaClearSize (PinType *);
00079 static void *ChangeViaMaskSize (PinType *);
00080 static void *ChangeLineSize (LayerType *, LineType *);
00081 static void *ChangeLineClearSize (LayerType *, LineType *);
00082 static void *ChangePolygonClearSize (LayerType *, PolygonType *);
00083 static void *ChangeArcSize (LayerType *, ArcType *);
00084 static void *ChangeArcClearSize (LayerType *, ArcType *);
00085 static void *ChangeTextSize (LayerType *, TextType *);
00086 static void *ChangeElementSize (ElementType *);
00087 static void *ChangeElementNameSize (ElementType *);
00088 static void *ChangePinName (ElementType *, PinType *);
00089 static void *ChangePadName (ElementType *, PadType *);
00090 static void *ChangeViaName (PinType *);
00091 static void *ChangeLineName (LayerType *, LineType *);
00092 static void *ChangeElementName (ElementType *);
00093 static void *ChangeTextName (LayerType *, TextType *);
00094 static void *ChangeElementSquare (ElementType *);
00095 static void *SetElementSquare (ElementType *);
00096 static void *ClrElementSquare (ElementType *);
00097 static void *ChangeElementOctagon (ElementType *);
00098 static void *SetElementOctagon (ElementType *);
00099 static void *ClrElementOctagon (ElementType *);
00100 static void *ChangePinSquare (ElementType *, PinType *);
00101 static void *SetPinSquare (ElementType *, PinType *);
00102 static void *ClrPinSquare (ElementType *, PinType *);
00103 static void *ChangePinOctagon (ElementType *, PinType *);
00104 static void *SetPinOctagon (ElementType *, PinType *);
00105 static void *ClrPinOctagon (ElementType *, PinType *);
00106 static void *ChangeViaOctagon (PinType *);
00107 static void *SetViaOctagon (PinType *);
00108 static void *ClrViaOctagon (PinType *);
00109 static void *ChangePadSquare (ElementType *, PadType *);
00110 static void *SetPadSquare (ElementType *, PadType *);
00111 static void *ClrPadSquare (ElementType *, PadType *);
00112 static void *ChangeViaThermal (PinType *);
00113 static void *ChangePinThermal (ElementType *, PinType *);
00114 static void *ChangeLineJoin (LayerType *, LineType *);
00115 static void *SetLineJoin (LayerType *, LineType *);
00116 static void *ClrLineJoin (LayerType *, LineType *);
00117 static void *ChangeArcJoin (LayerType *, ArcType *);
00118 static void *SetArcJoin (LayerType *, ArcType *);
00119 static void *ClrArcJoin (LayerType *, ArcType *);
00120 static void *ChangeTextJoin (LayerType *, TextType *);
00121 static void *SetTextJoin (LayerType *, TextType *);
00122 static void *ClrTextJoin (LayerType *, TextType *);
00123 static void *ChangePolyClear (LayerType *, PolygonType *);
00124 
00125 /* ---------------------------------------------------------------------------
00126  * some local identifiers
00127  */
00128 static int Delta;               /* change of size */
00129 static int Absolute;            /* Absolute size */
00130 static char *NewName;           /* new name */
00131 static ObjectFunctionType ChangeSizeFunctions = {
00132   ChangeLineSize,
00133   ChangeTextSize,
00134   ChangePolyClear,
00135   ChangeViaSize,
00136   ChangeElementSize,            /* changes silk screen line width */
00137   ChangeElementNameSize,
00138   ChangePinSize,
00139   ChangePadSize,
00140   NULL,
00141   NULL,
00142   ChangeArcSize,
00143   NULL
00144 };
00145 static ObjectFunctionType Change2ndSizeFunctions = {
00146   NULL,
00147   NULL,
00148   NULL,
00149   ChangeVia2ndSize,
00150   ChangeElement2ndSize,
00151   NULL,
00152   ChangePin2ndSize,
00153   NULL,
00154   NULL,
00155   NULL,
00156   NULL,
00157   NULL
00158 };
00159 static ObjectFunctionType ChangeThermalFunctions = {
00160   NULL,
00161   NULL,
00162   NULL,
00163   ChangeViaThermal,
00164   NULL,
00165   NULL,
00166   ChangePinThermal,
00167   NULL,
00168   NULL,
00169   NULL,
00170   NULL,
00171   NULL
00172 };
00173 static ObjectFunctionType ChangeClearSizeFunctions = {
00174   ChangeLineClearSize,
00175   NULL,
00176   ChangePolygonClearSize, /* just to tell the user not to :-) */
00177   ChangeViaClearSize,
00178   NULL,
00179   NULL,
00180   ChangePinClearSize,
00181   ChangePadClearSize,
00182   NULL,
00183   NULL,
00184   ChangeArcClearSize,
00185   NULL
00186 };
00187 static ObjectFunctionType ChangeNameFunctions = {
00188   ChangeLineName,
00189   ChangeTextName,
00190   NULL,
00191   ChangeViaName,
00192   ChangeElementName,
00193   NULL,
00194   ChangePinName,
00195   ChangePadName,
00196   NULL,
00197   NULL,
00198   NULL,
00199   NULL
00200 };
00201 static ObjectFunctionType ChangeSquareFunctions = {
00202   NULL,
00203   NULL,
00204   NULL,
00205   NULL,
00206   ChangeElementSquare,
00207   NULL,
00208   ChangePinSquare,
00209   ChangePadSquare,
00210   NULL,
00211   NULL,
00212   NULL,
00213   NULL
00214 };
00215 static ObjectFunctionType ChangeJoinFunctions = {
00216   ChangeLineJoin,
00217   ChangeTextJoin,
00218   NULL,
00219   NULL,
00220   NULL,
00221   NULL,
00222   NULL,
00223   NULL,
00224   NULL,
00225   NULL,
00226   ChangeArcJoin,
00227   NULL
00228 };
00229 static ObjectFunctionType ChangeOctagonFunctions = {
00230   NULL,
00231   NULL,
00232   NULL,
00233   ChangeViaOctagon,
00234   ChangeElementOctagon,
00235   NULL,
00236   ChangePinOctagon,
00237   NULL,
00238   NULL,
00239   NULL,
00240   NULL,
00241   NULL
00242 };
00243 static ObjectFunctionType ChangeMaskSizeFunctions = {
00244   NULL,
00245   NULL,
00246   NULL,
00247   ChangeViaMaskSize,
00248 #if 0
00249   ChangeElementMaskSize,
00250 #else
00251   NULL,
00252 #endif
00253   NULL,
00254   ChangePinMaskSize,
00255   ChangePadMaskSize,
00256   NULL,
00257   NULL,
00258   NULL,
00259   NULL
00260 };
00261 static ObjectFunctionType SetSquareFunctions = {
00262   NULL,
00263   NULL,
00264   NULL,
00265   NULL,
00266   SetElementSquare,
00267   NULL,
00268   SetPinSquare,
00269   SetPadSquare,
00270   NULL,
00271   NULL,
00272   NULL,
00273   NULL
00274 };
00275 static ObjectFunctionType SetJoinFunctions = {
00276   SetLineJoin,
00277   SetTextJoin,
00278   NULL,
00279   NULL,
00280   NULL,
00281   NULL,
00282   NULL,
00283   NULL,
00284   NULL,
00285   NULL,
00286   SetArcJoin,
00287   NULL
00288 };
00289 static ObjectFunctionType SetOctagonFunctions = {
00290   NULL,
00291   NULL,
00292   NULL,
00293   SetViaOctagon,
00294   SetElementOctagon,
00295   NULL,
00296   SetPinOctagon,
00297   NULL,
00298   NULL,
00299   NULL,
00300   NULL,
00301   NULL
00302 };
00303 static ObjectFunctionType ClrSquareFunctions = {
00304   NULL,
00305   NULL,
00306   NULL,
00307   NULL,
00308   ClrElementSquare,
00309   NULL,
00310   ClrPinSquare,
00311   ClrPadSquare,
00312   NULL,
00313   NULL,
00314   NULL,
00315   NULL
00316 };
00317 static ObjectFunctionType ClrJoinFunctions = {
00318   ClrLineJoin,
00319   ClrTextJoin,
00320   NULL,
00321   NULL,
00322   NULL,
00323   NULL,
00324   NULL,
00325   NULL,
00326   NULL,
00327   NULL,
00328   ClrArcJoin,
00329   NULL
00330 };
00331 static ObjectFunctionType ClrOctagonFunctions = {
00332   NULL,
00333   NULL,
00334   NULL,
00335   ClrViaOctagon,
00336   ClrElementOctagon,
00337   NULL,
00338   ClrPinOctagon,
00339   NULL,
00340   NULL,
00341   NULL,
00342   NULL,
00343   NULL
00344 };
00345 
00351 static void *
00352 ChangeViaThermal (PinType *Via)
00353 {
00354   AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, false);
00355   RestoreToPolygon (PCB->Data, VIA_TYPE, CURRENT, Via);
00356   AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
00357   if (!Delta)                   /* remove the thermals */
00358     CLEAR_THERM (INDEXOFCURRENT, Via);
00359   else
00360     ASSIGN_THERM (INDEXOFCURRENT, Delta, Via);
00361   AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, true);
00362   ClearFromPolygon (PCB->Data, VIA_TYPE, CURRENT, Via);
00363   DrawVia (Via);
00364   return Via;
00365 }
00366 
00372 static void *
00373 ChangePinThermal (ElementType *element, PinType *Pin)
00374 {
00375   AddObjectToClearPolyUndoList (PIN_TYPE, element, Pin, Pin, false);
00376   RestoreToPolygon (PCB->Data, VIA_TYPE, CURRENT, Pin);
00377   AddObjectToFlagUndoList (PIN_TYPE, element, Pin, Pin);
00378   if (!Delta)                   /* remove the thermals */
00379     CLEAR_THERM (INDEXOFCURRENT, Pin);
00380   else
00381     ASSIGN_THERM (INDEXOFCURRENT, Delta, Pin);
00382   AddObjectToClearPolyUndoList (PIN_TYPE, element, Pin, Pin, true);
00383   ClearFromPolygon (PCB->Data, VIA_TYPE, CURRENT, Pin);
00384   DrawPin (Pin);
00385   return Pin;
00386 }
00387 
00393 static void *
00394 ChangeViaSize (PinType *Via)
00395 {
00396   Coord value = Absolute ? Absolute : Via->Thickness + Delta;
00397 
00398   if (TEST_FLAG (LOCKFLAG, Via))
00399     return (NULL);
00400   if (!TEST_FLAG (HOLEFLAG, Via) && value <= MAX_PINORVIASIZE &&
00401       value >= MIN_PINORVIASIZE &&
00402       value >= Via->DrillingHole + MIN_PINORVIACOPPER &&
00403       value != Via->Thickness)
00404     {
00405       AddObjectToSizeUndoList (VIA_TYPE, Via, Via, Via);
00406       EraseVia (Via);
00407       r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
00408       RestoreToPolygon (PCB->Data, PIN_TYPE, Via, Via);
00409       if (Via->Mask)
00410         {
00411           AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
00412           Via->Mask += value - Via->Thickness;
00413         }
00414       Via->Thickness = value;
00415       SetPinBoundingBox (Via);
00416       r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
00417       ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
00418       DrawVia (Via);
00419       return (Via);
00420     }
00421   return (NULL);
00422 }
00423 
00429 static void *
00430 ChangeVia2ndSize (PinType *Via)
00431 {
00432   Coord value = (Absolute) ? Absolute : Via->DrillingHole + Delta;
00433 
00434   if (TEST_FLAG (LOCKFLAG, Via))
00435     return (NULL);
00436   if (value <= MAX_PINORVIASIZE &&
00437       value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, Via) ||
00438                                     value <=
00439                                     Via->Thickness - MIN_PINORVIACOPPER)
00440       && value != Via->DrillingHole)
00441     {
00442       AddObjectTo2ndSizeUndoList (VIA_TYPE, Via, Via, Via);
00443       EraseVia (Via);
00444       RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
00445       Via->DrillingHole = value;
00446       if (TEST_FLAG (HOLEFLAG, Via))
00447         {
00448           AddObjectToSizeUndoList (VIA_TYPE, Via, Via, Via);
00449           Via->Thickness = value;
00450         }
00451       ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
00452       DrawVia (Via);
00453       return (Via);
00454     }
00455   return (NULL);
00456 }
00457 
00463 static void *
00464 ChangeViaClearSize (PinType *Via)
00465 {
00466   Coord value = (Absolute) ? Absolute : Via->Clearance + Delta;
00467 
00468   if (TEST_FLAG (LOCKFLAG, Via))
00469     return (NULL);
00470   value = MIN (MAX_LINESIZE, value);
00471   if (value < 0)
00472     value = 0;
00473   if (Delta < 0 && value < PCB->Bloat * 2)
00474     value = 0;
00475   if ((Delta > 0 || Absolute) && value < PCB->Bloat * 2)
00476     value = PCB->Bloat * 2 + 2;
00477   if (Via->Clearance == value)
00478     return NULL;
00479   RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
00480   AddObjectToClearSizeUndoList (VIA_TYPE, Via, Via, Via);
00481   EraseVia (Via);
00482   r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
00483   Via->Clearance = value;
00484   SetPinBoundingBox (Via);
00485   r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
00486   ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
00487   DrawVia (Via);
00488   Via->Element = NULL;
00489   return (Via);
00490 }
00491 
00492 
00498 static void *
00499 ChangePinSize (ElementType *Element, PinType *Pin)
00500 {
00501   Coord value = (Absolute) ? Absolute : Pin->Thickness + Delta;
00502 
00503   if (TEST_FLAG (LOCKFLAG, Pin))
00504     return (NULL);
00505   if (!TEST_FLAG (HOLEFLAG, Pin) && value <= MAX_PINORVIASIZE &&
00506       value >= MIN_PINORVIASIZE &&
00507       value >= Pin->DrillingHole + MIN_PINORVIACOPPER &&
00508       value != Pin->Thickness)
00509     {
00510       AddObjectToSizeUndoList (PIN_TYPE, Element, Pin, Pin);
00511       AddObjectToMaskSizeUndoList (PIN_TYPE, Element, Pin, Pin);
00512       ErasePin (Pin);
00513       r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
00514       RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00515       Pin->Mask += value - Pin->Thickness;
00516       Pin->Thickness = value;
00517       /* SetElementBB updates all associated rtrees */
00518       SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
00519       ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00520       DrawPin (Pin);
00521       return (Pin);
00522     }
00523   return (NULL);
00524 }
00525 
00531 static void *
00532 ChangePinClearSize (ElementType *Element, PinType *Pin)
00533 {
00534   Coord value = (Absolute) ? Absolute : Pin->Clearance + Delta;
00535 
00536   if (TEST_FLAG (LOCKFLAG, Pin))
00537     return (NULL);
00538   value = MIN (MAX_LINESIZE, value);
00539   if (value < 0)
00540     value = 0;
00541   if (Delta < 0 && value < PCB->Bloat * 2)
00542     value = 0;
00543   if ((Delta > 0 || Absolute) && value < PCB->Bloat * 2)
00544     value = PCB->Bloat * 2 + 2;
00545   if (Pin->Clearance == value)
00546     return NULL;
00547   RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00548   AddObjectToClearSizeUndoList (PIN_TYPE, Element, Pin, Pin);
00549   ErasePin (Pin);
00550   r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
00551   Pin->Clearance = value;
00552   /* SetElementBB updates all associated rtrees */
00553   SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
00554   ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00555   DrawPin (Pin);
00556   return (Pin);
00557 }
00558 
00564 static void *
00565 ChangePadSize (ElementType *Element, PadType *Pad)
00566 {
00567   Coord value = (Absolute) ? Absolute : Pad->Thickness + Delta;
00568 
00569   if (TEST_FLAG (LOCKFLAG, Pad))
00570     return (NULL);
00571   if (value <= MAX_PADSIZE && value >= MIN_PADSIZE && value != Pad->Thickness)
00572     {
00573       AddObjectToSizeUndoList (PAD_TYPE, Element, Pad, Pad);
00574       AddObjectToMaskSizeUndoList (PAD_TYPE, Element, Pad, Pad);
00575       RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
00576       ErasePad (Pad);
00577       r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
00578       Pad->Mask += value - Pad->Thickness;
00579       Pad->Thickness = value;
00580       /* SetElementBB updates all associated rtrees */
00581       SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
00582       ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
00583       DrawPad (Pad);
00584       return (Pad);
00585     }
00586   return (NULL);
00587 }
00588 
00594 static void *
00595 ChangePadClearSize (ElementType *Element, PadType *Pad)
00596 {
00597   Coord value = (Absolute) ? Absolute : Pad->Clearance + Delta;
00598 
00599   if (TEST_FLAG (LOCKFLAG, Pad))
00600     return (NULL);
00601   value = MIN (MAX_LINESIZE, value);
00602   if (value < 0)
00603     value = 0;
00604   if (Delta < 0 && value < PCB->Bloat * 2)
00605     value = 0;
00606   if ((Delta > 0 || Absolute) && value < PCB->Bloat * 2)
00607     value = PCB->Bloat * 2 + 2;
00608   if (value == Pad->Clearance)
00609     return NULL;
00610   AddObjectToClearSizeUndoList (PAD_TYPE, Element, Pad, Pad);
00611   RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
00612   ErasePad (Pad);
00613   r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
00614   Pad->Clearance = value;
00615   /* SetElementBB updates all associated rtrees */
00616   SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
00617   ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
00618   DrawPad (Pad);
00619   return Pad;
00620 }
00621 
00627 static void *
00628 ChangeElement2ndSize (ElementType *Element)
00629 {
00630   bool changed = false;
00631   Coord value;
00632 
00633   if (TEST_FLAG (LOCKFLAG, Element))
00634     return (NULL);
00635   PIN_LOOP (Element);
00636   {
00637     value = (Absolute) ? Absolute : pin->DrillingHole + Delta;
00638     if (value <= MAX_PINORVIASIZE &&
00639         value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, pin) ||
00640                                       value <=
00641                                       pin->Thickness -
00642                                       MIN_PINORVIACOPPER)
00643         && value != pin->DrillingHole)
00644       {
00645         changed = true;
00646         AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, pin, pin);
00647         ErasePin (pin);
00648         RestoreToPolygon (PCB->Data, PIN_TYPE, Element, pin);
00649         pin->DrillingHole = value;
00650         if (TEST_FLAG (HOLEFLAG, pin))
00651           {
00652             AddObjectToSizeUndoList (PIN_TYPE, Element, pin, pin);
00653             pin->Thickness = value;
00654           }
00655         ClearFromPolygon (PCB->Data, PIN_TYPE, Element, pin);
00656         DrawPin (pin);
00657       }
00658   }
00659   END_LOOP;
00660   if (changed)
00661     return (Element);
00662   else
00663     return (NULL);
00664 }
00665 
00671 static void *
00672 ChangePin2ndSize (ElementType *Element, PinType *Pin)
00673 {
00674   Coord value = (Absolute) ? Absolute : Pin->DrillingHole + Delta;
00675 
00676   if (TEST_FLAG (LOCKFLAG, Pin))
00677     return (NULL);
00678   if (value <= MAX_PINORVIASIZE &&
00679       value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, Pin) ||
00680                                     value <=
00681                                     Pin->Thickness - MIN_PINORVIACOPPER)
00682       && value != Pin->DrillingHole)
00683     {
00684       AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, Pin, Pin);
00685       ErasePin (Pin);
00686       RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00687       Pin->DrillingHole = value;
00688       if (TEST_FLAG (HOLEFLAG, Pin))
00689         {
00690           AddObjectToSizeUndoList (PIN_TYPE, Element, Pin, Pin);
00691           Pin->Thickness = value;
00692         }
00693       ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
00694       DrawPin (Pin);
00695       return (Pin);
00696     }
00697   return (NULL);
00698 }
00699 
00705 static void *
00706 ChangeLineSize (LayerType *Layer, LineType *Line)
00707 {
00708   Coord value = (Absolute) ? Absolute : Line->Thickness + Delta;
00709 
00710   if (TEST_FLAG (LOCKFLAG, Line))
00711     return (NULL);
00712   if (value <= MAX_LINESIZE && value >= MIN_LINESIZE &&
00713       value != Line->Thickness)
00714     {
00715       AddObjectToSizeUndoList (LINE_TYPE, Layer, Line, Line);
00716       EraseLine (Line);
00717       r_delete_entry (Layer->line_tree, (BoxType *) Line);
00718       RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
00719       Line->Thickness = value;
00720       SetLineBoundingBox (Line);
00721       r_insert_entry (Layer->line_tree, (BoxType *) Line, 0);
00722       ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
00723       DrawLine (Layer, Line);
00724       return (Line);
00725     }
00726   return (NULL);
00727 }
00728 
00734 static void *
00735 ChangeLineClearSize (LayerType *Layer, LineType *Line)
00736 {
00737   Coord value = (Absolute) ? Absolute : Line->Clearance + Delta;
00738 
00739   if (TEST_FLAG (LOCKFLAG, Line) || !TEST_FLAG (CLEARLINEFLAG, Line))
00740     return (NULL);
00741   value = MIN (MAX_LINESIZE, MAX (value, PCB->Bloat * 2 + 2));
00742   if (value != Line->Clearance)
00743     {
00744       AddObjectToClearSizeUndoList (LINE_TYPE, Layer, Line, Line);
00745       RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
00746       EraseLine (Line);
00747       r_delete_entry (Layer->line_tree, (BoxType *) Line);
00748       Line->Clearance = value;
00749       if (Line->Clearance == 0)
00750         {
00751           CLEAR_FLAG (CLEARLINEFLAG, Line);
00752           Line->Clearance = MIL_TO_COORD(10);
00753         }
00754       SetLineBoundingBox (Line);
00755       r_insert_entry (Layer->line_tree, (BoxType *) Line, 0);
00756       ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
00757       DrawLine (Layer, Line);
00758       return (Line);
00759     }
00760   return (NULL);
00761 }
00762 
00766 static void *
00767 ChangePolygonClearSize (LayerType *Layer, PolygonType *poly)
00768 {
00769   static int shown_this_message = 0;
00770   if (!shown_this_message)
00771     {
00772       gui->confirm_dialog (_("To change the clearance of objects in a polygon, "
00773                            "change the objects, not the polygon.\n"
00774                            "Hint: To set a minimum clearance for a group of objects, "
00775                            "select them all then :MinClearGap(Selected,=10,mil)"),
00776                            "Ok", NULL);
00777       shown_this_message = 1;
00778     }
00779 
00780   return (NULL);
00781 }
00782 
00788 static void *
00789 ChangeArcSize (LayerType *Layer, ArcType *Arc)
00790 {
00791   Coord value = (Absolute) ? Absolute : Arc->Thickness + Delta;
00792 
00793   if (TEST_FLAG (LOCKFLAG, Arc))
00794     return (NULL);
00795   if (value <= MAX_LINESIZE && value >= MIN_LINESIZE &&
00796       value != Arc->Thickness)
00797     {
00798       AddObjectToSizeUndoList (ARC_TYPE, Layer, Arc, Arc);
00799       EraseArc (Arc);
00800       r_delete_entry (Layer->arc_tree, (BoxType *) Arc);
00801       RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
00802       Arc->Thickness = value;
00803       SetArcBoundingBox (Arc);
00804       r_insert_entry (Layer->arc_tree, (BoxType *) Arc, 0);
00805       ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
00806       DrawArc (Layer, Arc);
00807       return (Arc);
00808     }
00809   return (NULL);
00810 }
00811 
00817 static void *
00818 ChangeArcClearSize (LayerType *Layer, ArcType *Arc)
00819 {
00820   Coord value = (Absolute) ? Absolute : Arc->Clearance + Delta;
00821 
00822   if (TEST_FLAG (LOCKFLAG, Arc) || !TEST_FLAG (CLEARLINEFLAG, Arc))
00823     return (NULL);
00824   value = MIN (MAX_LINESIZE, MAX (value, PCB->Bloat * 2 + 2));
00825   if (value != Arc->Clearance)
00826     {
00827       AddObjectToClearSizeUndoList (ARC_TYPE, Layer, Arc, Arc);
00828       EraseArc (Arc);
00829       r_delete_entry (Layer->arc_tree, (BoxType *) Arc);
00830       RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
00831       Arc->Clearance = value;
00832       if (Arc->Clearance == 0)
00833         {
00834           CLEAR_FLAG (CLEARLINEFLAG, Arc);
00835           Arc->Clearance = MIL_TO_COORD(10);
00836         }
00837       SetArcBoundingBox (Arc);
00838       r_insert_entry (Layer->arc_tree, (BoxType *) Arc, 0);
00839       ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
00840       DrawArc (Layer, Arc);
00841       return (Arc);
00842     }
00843   return (NULL);
00844 }
00845 
00851 static void *
00852 ChangeTextSize (LayerType *Layer, TextType *Text)
00853 {
00854   int value = (Absolute != 0 ? 0 : Text->Scale) +
00855               (double)(Absolute != 0 ? Absolute : Delta)
00856                 / (double)FONT_CAPHEIGHT * 100.;
00857 
00858   if (TEST_FLAG (LOCKFLAG, Text))
00859     return (NULL);
00860   if (value <= MAX_TEXTSCALE && value >= MIN_TEXTSCALE &&
00861       value != Text->Scale)
00862     {
00863       AddObjectToSizeUndoList (TEXT_TYPE, Layer, Text, Text);
00864       EraseText (Layer, Text);
00865       r_delete_entry (Layer->text_tree, (BoxType *) Text);
00866       RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
00867       Text->Scale = value;
00868       SetTextBoundingBox (&PCB->Font, Text);
00869       r_insert_entry (Layer->text_tree, (BoxType *) Text, 0);
00870       ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
00871       DrawText (Layer, Text);
00872       return (Text);
00873     }
00874   return (NULL);
00875 }
00876 
00882 static void *
00883 ChangeElementSize (ElementType *Element)
00884 {
00885   Coord value;
00886   bool changed = false;
00887 
00888   if (TEST_FLAG (LOCKFLAG, Element))
00889     return (NULL);
00890   if (PCB->ElementOn)
00891     EraseElement (Element);
00892   ELEMENTLINE_LOOP (Element);
00893   {
00894     value = (Absolute) ? Absolute : line->Thickness + Delta;
00895     if (value <= MAX_LINESIZE && value >= MIN_LINESIZE &&
00896         value != line->Thickness)
00897       {
00898         AddObjectToSizeUndoList (ELEMENTLINE_TYPE, Element, line, line);
00899         line->Thickness = value;
00900         changed = true;
00901       }
00902   }
00903   END_LOOP;
00904   ARC_LOOP (Element);
00905   {
00906     value = (Absolute) ? Absolute : arc->Thickness + Delta;
00907     if (value <= MAX_LINESIZE && value >= MIN_LINESIZE &&
00908         value != arc->Thickness)
00909       {
00910         AddObjectToSizeUndoList (ELEMENTARC_TYPE, Element, arc, arc);
00911         arc->Thickness = value;
00912         changed = true;
00913       }
00914   }
00915   END_LOOP;
00916   if (PCB->ElementOn)
00917     {
00918       DrawElement (Element);
00919     }
00920   if (changed)
00921     return (Element);
00922   return (NULL);
00923 }
00924 
00930 static void *
00931 ChangeElementNameSize (ElementType *Element)
00932 {
00933   int value = (Absolute != 0 ? 0 : DESCRIPTION_TEXT (Element).Scale) +
00934               (double)(Absolute != 0 ? Absolute : Delta)
00935                 / (double)FONT_CAPHEIGHT * 100.;
00936 
00937   if (TEST_FLAG (LOCKFLAG, &Element->Name[0]))
00938     return (NULL);
00939   if (value <= MAX_TEXTSCALE && value >= MIN_TEXTSCALE)
00940     {
00941       EraseElementName (Element);
00942       ELEMENTTEXT_LOOP (Element);
00943       {
00944         AddObjectToSizeUndoList (ELEMENTNAME_TYPE, Element, text, text);
00945         r_delete_entry (PCB->Data->name_tree[n], (BoxType *) text);
00946         text->Scale = value;
00947         SetTextBoundingBox (&PCB->Font, text);
00948         r_insert_entry (PCB->Data->name_tree[n], (BoxType *) text, 0);
00949       }
00950       END_LOOP;
00951       DrawElementName (Element);
00952       return (Element);
00953     }
00954   return (NULL);
00955 }
00956 
00960 static void *
00961 ChangeViaName (PinType *Via)
00962 {
00963   char *old = Via->Name;
00964 
00965   if (TEST_FLAG (DISPLAYNAMEFLAG, Via))
00966     {
00967       ErasePinName (Via);
00968       Via->Name = NewName;
00969       DrawPinName (Via);
00970     }
00971   else
00972     Via->Name = NewName;
00973   return (old);
00974 }
00975 
00979 static void *
00980 ChangePinName (ElementType *Element, PinType *Pin)
00981 {
00982   char *old = Pin->Name;
00983 
00984   (void) Element;               /* get rid of 'unused...' warnings */
00985   if (TEST_FLAG (DISPLAYNAMEFLAG, Pin))
00986     {
00987       ErasePinName (Pin);
00988       Pin->Name = NewName;
00989       DrawPinName (Pin);
00990     }
00991   else
00992     Pin->Name = NewName;
00993   return (old);
00994 }
00995 
00999 static void *
01000 ChangePadName (ElementType *Element, PadType *Pad)
01001 {
01002   char *old = Pad->Name;
01003 
01004   (void) Element;               /* get rid of 'unused...' warnings */
01005   if (TEST_FLAG (DISPLAYNAMEFLAG, Pad))
01006     {
01007       ErasePadName (Pad);
01008       Pad->Name = NewName;
01009       DrawPadName (Pad);
01010     }
01011   else
01012     Pad->Name = NewName;
01013   return (old);
01014 }
01015 
01019 static void *
01020 ChangeLineName (LayerType *Layer, LineType *Line)
01021 {
01022   char *old = Line->Number;
01023 
01024   (void) Layer;
01025   Line->Number = NewName;
01026   return (old);
01027 }
01028 
01038 char *
01039 ChangeElementText (PCBType *pcb, DataType *data, ElementType *Element, int which, char *new_name)
01040 {
01041   char *old = Element->Name[which].TextString;
01042 
01043 #ifdef DEBUG
01044   printf("In ChangeElementText, updating old TextString %s to %s\n", old, new_name);
01045 #endif
01046 
01047   if (pcb && which == NAME_INDEX (pcb))
01048     EraseElementName (Element);
01049 
01050   r_delete_entry (data->name_tree[which],
01051                   & Element->Name[which].BoundingBox);
01052 
01053   Element->Name[which].TextString = new_name;
01054   SetTextBoundingBox (&PCB->Font, &Element->Name[which]);
01055 
01056   r_insert_entry (data->name_tree[which],
01057                   & Element->Name[which].BoundingBox, 0);
01058 
01059   if (pcb && which == NAME_INDEX (pcb))
01060     DrawElementName (Element);
01061 
01062   return old;
01063 }
01064 
01065 static void *
01066 ChangeElementName (ElementType *Element)
01067 {
01068   if (TEST_FLAG (LOCKFLAG, &Element->Name[0]))
01069     return (NULL);
01070   if (NAME_INDEX (PCB) == NAMEONPCB_INDEX)
01071     {
01072       if (TEST_FLAG (UNIQUENAMEFLAG, PCB) &&
01073           UniqueElementName (PCB->Data, NewName) != NewName)
01074         {
01075           Message (_("Error: The name \"%s\" is not unique!\n"), NewName);
01076           return ((char *) -1);
01077         }
01078     }
01079 
01080   return ChangeElementText (PCB, PCB->Data, Element, NAME_INDEX (PCB), NewName);
01081 }
01082 
01091 static void *
01092 ChangeTextName (LayerType *Layer, TextType *Text)
01093 {
01094   char *old = Text->TextString;
01095 
01096   if (TEST_FLAG (LOCKFLAG, Text))
01097     return (NULL);
01098   EraseText (Layer, Text);
01099   r_delete_entry (Layer->text_tree, (BoxType *) Text);
01100   RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
01101   Text->TextString = NewName;
01102 
01103   /* calculate size of the bounding box */
01104   SetTextBoundingBox (&PCB->Font, Text);
01105   r_insert_entry(Layer->text_tree, (BoxType *) Text, 0);
01106   ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
01107   DrawText (Layer, Text);
01108   return (old);
01109 }
01110 
01115 bool
01116 ChangeLayoutName (char *Name)
01117 {
01118   free (PCB->Name);
01119   PCB->Name = Name;
01120   hid_action ("PCBChanged");
01121   return (true);
01122 }
01123 
01129 bool
01130 ChangeElementSide (ElementType *Element, Coord yoff)
01131 {
01132   if (TEST_FLAG (LOCKFLAG, Element))
01133     return (false);
01134   EraseElement (Element);
01135   AddObjectToMirrorUndoList (ELEMENT_TYPE, Element, Element, Element, yoff);
01136   MirrorElementCoordinates (PCB->Data, Element, yoff);
01137   DrawElement (Element);
01138   return (true);
01139 }
01140 
01145 bool
01146 ChangeLayerName (LayerType *Layer, char *Name)
01147 {
01148   free (CURRENT->Name);
01149   CURRENT->Name = Name;
01150   hid_action ("LayersChanged");
01151   return (true);
01152 }
01153 
01157 static void *
01158 ChangeLineJoin (LayerType *Layer, LineType *Line)
01159 {
01160   if (TEST_FLAG (LOCKFLAG, Line))
01161     return (NULL);
01162   EraseLine (Line);
01163   if (TEST_FLAG(CLEARLINEFLAG, Line))
01164   {
01165   AddObjectToClearPolyUndoList (LINE_TYPE, Layer, Line, Line, false);
01166   RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
01167   }
01168   AddObjectToFlagUndoList (LINE_TYPE, Layer, Line, Line);
01169   TOGGLE_FLAG (CLEARLINEFLAG, Line);
01170   if (TEST_FLAG(CLEARLINEFLAG, Line))
01171   {
01172   AddObjectToClearPolyUndoList (LINE_TYPE, Layer, Line, Line, true);
01173   ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
01174   }
01175   DrawLine (Layer, Line);
01176   return (Line);
01177 }
01178 
01182 static void *
01183 SetLineJoin (LayerType *Layer, LineType *Line)
01184 {
01185   if (TEST_FLAG (LOCKFLAG, Line) || TEST_FLAG (CLEARLINEFLAG, Line))
01186     return (NULL);
01187   return ChangeLineJoin (Layer, Line);
01188 }
01189 
01193 static void *
01194 ClrLineJoin (LayerType *Layer, LineType *Line)
01195 {
01196   if (TEST_FLAG (LOCKFLAG, Line) || !TEST_FLAG (CLEARLINEFLAG, Line))
01197     return (NULL);
01198   return ChangeLineJoin (Layer, Line);
01199 }
01200 
01204 static void *
01205 ChangeArcJoin (LayerType *Layer, ArcType *Arc)
01206 {
01207   if (TEST_FLAG (LOCKFLAG, Arc))
01208     return (NULL);
01209   EraseArc (Arc);
01210   if (TEST_FLAG (CLEARLINEFLAG, Arc))
01211   {
01212     RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
01213     AddObjectToClearPolyUndoList (ARC_TYPE, Layer, Arc, Arc, false);
01214     }
01215   AddObjectToFlagUndoList (ARC_TYPE, Layer, Arc, Arc);
01216   TOGGLE_FLAG (CLEARLINEFLAG, Arc);
01217   if (TEST_FLAG (CLEARLINEFLAG, Arc))
01218   {
01219     ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
01220   AddObjectToClearPolyUndoList (ARC_TYPE, Layer, Arc, Arc, true);
01221   }
01222   DrawArc (Layer, Arc);
01223   return (Arc);
01224 }
01225 
01229 static void *
01230 SetArcJoin (LayerType *Layer, ArcType *Arc)
01231 {
01232   if (TEST_FLAG (LOCKFLAG, Arc) || TEST_FLAG (CLEARLINEFLAG, Arc))
01233     return (NULL);
01234   return ChangeArcJoin (Layer, Arc);
01235 }
01236 
01240 static void *
01241 ClrArcJoin (LayerType *Layer, ArcType *Arc)
01242 {
01243   if (TEST_FLAG (LOCKFLAG, Arc) || !TEST_FLAG (CLEARLINEFLAG, Arc))
01244     return (NULL);
01245   return ChangeArcJoin (Layer, Arc);
01246 }
01247 
01251 static void *
01252 ChangeTextJoin (LayerType *Layer, TextType *Text)
01253 {
01254   if (TEST_FLAG (LOCKFLAG, Text))
01255     return (NULL);
01256   EraseText (Layer, Text);
01257   if (TEST_FLAG(CLEARLINEFLAG, Text))
01258   {
01259   AddObjectToClearPolyUndoList (TEXT_TYPE, Layer, Text, Text, false);
01260   RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
01261   }
01262   AddObjectToFlagUndoList (TEXT_TYPE, Layer, Text, Text);
01263   TOGGLE_FLAG (CLEARLINEFLAG, Text);
01264   if (TEST_FLAG(CLEARLINEFLAG, Text))
01265   {
01266   AddObjectToClearPolyUndoList (TEXT_TYPE, Layer, Text, Text, true);
01267   ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
01268   }
01269   DrawText (Layer, Text);
01270   return (Text);
01271 }
01272 
01276 static void *
01277 SetTextJoin (LayerType *Layer, TextType *Text)
01278 {
01279   if (TEST_FLAG (LOCKFLAG, Text) || TEST_FLAG (CLEARLINEFLAG, Text))
01280     return (NULL);
01281   return ChangeTextJoin (Layer, Text);
01282 }
01283 
01287 static void *
01288 ClrTextJoin (LayerType *Layer, TextType *Text)
01289 {
01290   if (TEST_FLAG (LOCKFLAG, Text) || !TEST_FLAG (CLEARLINEFLAG, Text))
01291     return (NULL);
01292   return ChangeTextJoin (Layer, Text);
01293 }
01294 
01298 static void *
01299 ChangeElementSquare (ElementType *Element)
01300 {
01301   void *ans = NULL;
01302 
01303   if (TEST_FLAG (LOCKFLAG, Element))
01304     return (NULL);
01305   PIN_LOOP (Element);
01306   {
01307     ans = ChangePinSquare (Element, pin);
01308   }
01309   END_LOOP;
01310   PAD_LOOP (Element);
01311   {
01312     ans = ChangePadSquare (Element, pad);
01313   }
01314   END_LOOP;
01315   return (ans);
01316 }
01317 
01321 static void *
01322 SetElementSquare (ElementType *Element)
01323 {
01324   void *ans = NULL;
01325 
01326   if (TEST_FLAG (LOCKFLAG, Element))
01327     return (NULL);
01328   PIN_LOOP (Element);
01329   {
01330     ans = SetPinSquare (Element, pin);
01331   }
01332   END_LOOP;
01333   PAD_LOOP (Element);
01334   {
01335     ans = SetPadSquare (Element, pad);
01336   }
01337   END_LOOP;
01338   return (ans);
01339 }
01340 
01344 static void *
01345 ClrElementSquare (ElementType *Element)
01346 {
01347   void *ans = NULL;
01348 
01349   if (TEST_FLAG (LOCKFLAG, Element))
01350     return (NULL);
01351   PIN_LOOP (Element);
01352   {
01353     ans = ClrPinSquare (Element, pin);
01354   }
01355   END_LOOP;
01356   PAD_LOOP (Element);
01357   {
01358     ans = ClrPadSquare (Element, pad);
01359   }
01360   END_LOOP;
01361   return (ans);
01362 }
01363 
01367 static void *
01368 ChangeElementOctagon (ElementType *Element)
01369 {
01370   void *result = NULL;
01371 
01372   if (TEST_FLAG (LOCKFLAG, Element))
01373     return (NULL);
01374   PIN_LOOP (Element);
01375   {
01376     ChangePinOctagon (Element, pin);
01377     result = Element;
01378   }
01379   END_LOOP;
01380   return (result);
01381 }
01382 
01386 static void *
01387 SetElementOctagon (ElementType *Element)
01388 {
01389   void *result = NULL;
01390 
01391   if (TEST_FLAG (LOCKFLAG, Element))
01392     return (NULL);
01393   PIN_LOOP (Element);
01394   {
01395     SetPinOctagon (Element, pin);
01396     result = Element;
01397   }
01398   END_LOOP;
01399   return (result);
01400 }
01401 
01405 static void *
01406 ClrElementOctagon (ElementType *Element)
01407 {
01408   void *result = NULL;
01409 
01410   if (TEST_FLAG (LOCKFLAG, Element))
01411     return (NULL);
01412   PIN_LOOP (Element);
01413   {
01414     ClrPinOctagon (Element, pin);
01415     result = Element;
01416   }
01417   END_LOOP;
01418   return (result);
01419 }
01420 
01424 static void *
01425 ChangePadSquare (ElementType *Element, PadType *Pad)
01426 {
01427   if (TEST_FLAG (LOCKFLAG, Pad))
01428     return (NULL);
01429   ErasePad (Pad);
01430   AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, false);
01431   RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
01432   AddObjectToFlagUndoList (PAD_TYPE, Element, Pad, Pad);
01433   TOGGLE_FLAG (SQUAREFLAG, Pad);
01434   AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, true);
01435   ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
01436   DrawPad (Pad);
01437   return (Pad);
01438 }
01439 
01443 static void *
01444 SetPadSquare (ElementType *Element, PadType *Pad)
01445 {
01446 
01447   if (TEST_FLAG (LOCKFLAG, Pad) || TEST_FLAG (SQUAREFLAG, Pad))
01448     return (NULL);
01449 
01450   return (ChangePadSquare (Element, Pad));
01451 }
01452 
01453 
01457 static void *
01458 ClrPadSquare (ElementType *Element, PadType *Pad)
01459 {
01460 
01461   if (TEST_FLAG (LOCKFLAG, Pad) || !TEST_FLAG (SQUAREFLAG, Pad))
01462     return (NULL);
01463 
01464   return (ChangePadSquare (Element, Pad));
01465 }
01466 
01467 
01471 static void *
01472 ChangePinSquare (ElementType *Element, PinType *Pin)
01473 {
01474   if (TEST_FLAG (LOCKFLAG, Pin))
01475     return (NULL);
01476   ErasePin (Pin);
01477   AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, false);
01478   RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
01479   AddObjectToFlagUndoList (PIN_TYPE, Element, Pin, Pin);
01480   TOGGLE_FLAG (SQUAREFLAG, Pin);
01481   AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, true);
01482   ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
01483   DrawPin (Pin);
01484   return (Pin);
01485 }
01486 
01490 static void *
01491 SetPinSquare (ElementType *Element, PinType *Pin)
01492 {
01493   if (TEST_FLAG (LOCKFLAG, Pin) || TEST_FLAG (SQUAREFLAG, Pin))
01494     return (NULL);
01495 
01496   return (ChangePinSquare (Element, Pin));
01497 }
01498 
01502 static void *
01503 ClrPinSquare (ElementType *Element, PinType *Pin)
01504 {
01505   if (TEST_FLAG (LOCKFLAG, Pin) || !TEST_FLAG (SQUAREFLAG, Pin))
01506     return (NULL);
01507 
01508   return (ChangePinSquare (Element, Pin));
01509 }
01510 
01514 static void *
01515 ChangeViaOctagon (PinType *Via)
01516 {
01517   if (TEST_FLAG (LOCKFLAG, Via))
01518     return (NULL);
01519   EraseVia (Via);
01520   AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, false);
01521   RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
01522   AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
01523   TOGGLE_FLAG (OCTAGONFLAG, Via);
01524   AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, true);
01525   ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
01526   DrawVia (Via);
01527   return (Via);
01528 }
01529 
01533 static void *
01534 SetViaOctagon (PinType *Via)
01535 {
01536   if (TEST_FLAG (LOCKFLAG, Via) || TEST_FLAG (OCTAGONFLAG, Via))
01537     return (NULL);
01538 
01539   return (ChangeViaOctagon (Via));
01540 }
01541 
01545 static void *
01546 ClrViaOctagon (PinType *Via)
01547 {
01548   if (TEST_FLAG (LOCKFLAG, Via) || !TEST_FLAG (OCTAGONFLAG, Via))
01549     return (NULL);
01550 
01551   return (ChangeViaOctagon (Via));
01552 }
01553 
01557 static void *
01558 ChangePinOctagon (ElementType *Element, PinType *Pin)
01559 {
01560   if (TEST_FLAG (LOCKFLAG, Pin))
01561     return (NULL);
01562   ErasePin (Pin);
01563   AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, false);
01564   RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
01565   AddObjectToFlagUndoList (PIN_TYPE, Element, Pin, Pin);
01566   TOGGLE_FLAG (OCTAGONFLAG, Pin);
01567   AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, true);
01568   ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
01569   DrawPin (Pin);
01570   return (Pin);
01571 }
01572 
01576 static void *
01577 SetPinOctagon (ElementType *Element, PinType *Pin)
01578 {
01579   if (TEST_FLAG (LOCKFLAG, Pin) || TEST_FLAG (OCTAGONFLAG, Pin))
01580     return (NULL);
01581 
01582   return (ChangePinOctagon (Element, Pin));
01583 }
01584 
01588 static void *
01589 ClrPinOctagon (ElementType *Element, PinType *Pin)
01590 {
01591   if (TEST_FLAG (LOCKFLAG, Pin) || !TEST_FLAG (OCTAGONFLAG, Pin))
01592     return (NULL);
01593 
01594   return (ChangePinOctagon (Element, Pin));
01595 }
01596 
01600 bool
01601 ChangeHole (PinType *Via)
01602 {
01603   if (TEST_FLAG (LOCKFLAG, Via))
01604     return (false);
01605   EraseVia (Via);
01606   AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
01607   AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
01608   r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
01609   RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
01610   TOGGLE_FLAG (HOLEFLAG, Via);
01611 
01612   if (TEST_FLAG (HOLEFLAG, Via))
01613     {
01614       /* A tented via becomes an minimally untented hole.  An untented
01615          via retains its mask clearance.  */
01616       if (Via->Mask > Via->Thickness)
01617         {
01618           Via->Mask = (Via->DrillingHole
01619                        + (Via->Mask - Via->Thickness));
01620         }
01621       else if (Via->Mask < Via->DrillingHole)
01622         {
01623           Via->Mask = Via->DrillingHole + 2 * MASKFRAME;
01624         }
01625     }
01626   else
01627     {
01628       Via->Mask = (Via->Thickness
01629                    + (Via->Mask - Via->DrillingHole));
01630     }
01631 
01632   SetPinBoundingBox (Via);
01633   r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
01634   ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
01635   DrawVia (Via);
01636   Draw ();
01637   return (true);
01638 }
01639 
01643 bool
01644 ChangePaste (PadType *Pad)
01645 {
01646   if (TEST_FLAG (LOCKFLAG, Pad))
01647     return (false);
01648   ErasePad (Pad);
01649   AddObjectToFlagUndoList (PAD_TYPE, Pad, Pad, Pad);
01650   TOGGLE_FLAG (NOPASTEFLAG, Pad);
01651   DrawPad (Pad);
01652   Draw ();
01653   return (true);
01654 }
01655 
01659 static void *
01660 ChangePolyClear (LayerType *Layer, PolygonType *Polygon)
01661 {
01662   if (TEST_FLAG (LOCKFLAG, Polygon))
01663     return (NULL);
01664   AddObjectToClearPolyUndoList (POLYGON_TYPE, Layer, Polygon, Polygon, true);
01665   AddObjectToFlagUndoList (POLYGON_TYPE, Layer, Polygon, Polygon);
01666   TOGGLE_FLAG (CLEARPOLYFLAG, Polygon);
01667   InitClip (PCB->Data, Layer, Polygon);
01668   DrawPolygon (Layer, Polygon);
01669   return (Polygon);
01670 }
01671 
01677 bool
01678 ChangeSelectedElementSide (void)
01679 {
01680   bool change = false;
01681 
01682   /* setup identifiers */
01683   if (PCB->PinOn && PCB->ElementOn)
01684     ELEMENT_LOOP (PCB->Data);
01685   {
01686     if (TEST_FLAG (SELECTEDFLAG, element))
01687       {
01688         change |= ChangeElementSide (element, 0);
01689       }
01690   }
01691   END_LOOP;
01692   if (change)
01693     {
01694       Draw ();
01695       IncrementUndoSerialNumber ();
01696     }
01697   return (change);
01698 }
01699 
01706 bool
01707 ChangeSelectedThermals (int types, int therm_style)
01708 {
01709   bool change = false;
01710 
01711   Delta = therm_style;
01712   change = SelectedOperation (&ChangeThermalFunctions, false, types);
01713   if (change)
01714     {
01715       Draw ();
01716       IncrementUndoSerialNumber ();
01717     }
01718   return (change);
01719 }
01720 
01721 
01728 bool
01729 ChangeSelectedViaLayers (int from, int to)
01730 {
01731   bool change = false;
01732   int new_from;
01733   int new_to;
01734   int i;
01735 
01736   VIA_LOOP (PCB->Data);
01737     {
01738       if (TEST_FLAG (LOCKFLAG, via))
01739         continue;
01740       if (TEST_FLAG (SELECTEDFLAG, via))
01741         {
01742 
01743           new_from = (from != -1)?from:via->BuriedFrom;
01744           new_to = (to != -1)?to:via->BuriedTo;
01745 
01746           if (new_from == new_to)
01747             continue;
01748 
01749           /* special case - changing TH via "from" layer sets "to" layer to bottom layer */
01750           if (!VIA_IS_BURIED (via)
01751                && (to == -1))
01752              new_to = GetMaxBottomLayer ();
01753 
01754           for (i=0; i < max_copper_layer; i++)
01755             {
01756               /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, false); not needed? */
01757               RestoreToPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
01758             }
01759 
01760             AddObjectToSetViaLayersUndoList (via, via, via);
01761             via->BuriedFrom = new_from;
01762             via->BuriedTo = new_to;
01763 
01764             if (VIA_IS_BURIED (via))
01765               {
01766                 SanitizeBuriedVia (via);
01767                 for (i=0; i < max_copper_layer; i++)
01768                   {
01769                     /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, true);  not needed? */
01770                     ClearFromPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
01771                   }
01772                 DrawVia (via);
01773               }
01774             change = true;
01775         }
01776     }
01777   END_LOOP;
01778   if (change)
01779     {
01780       Draw ();
01781       IncrementUndoSerialNumber ();
01782     }
01783   return (change);
01784 }
01785 
01791 bool
01792 ChangeSelectedSize (int types, Coord Difference, bool fixIt)
01793 {
01794   bool change = false;
01795 
01796   /* setup identifiers */
01797   Absolute = (fixIt) ? Difference : 0;
01798   Delta = Difference;
01799 
01800   change = SelectedOperation (&ChangeSizeFunctions, false, types);
01801   if (change)
01802     {
01803       Draw ();
01804       IncrementUndoSerialNumber ();
01805     }
01806   return (change);
01807 }
01808 
01814 bool
01815 ChangeSelectedClearSize (int types, Coord Difference, bool fixIt)
01816 {
01817   bool change = false;
01818 
01819   /* setup identifiers */
01820   Absolute = (fixIt) ? Difference : 0;
01821   Delta = Difference;
01822   if (TEST_FLAG (SHOWMASKFLAG, PCB))
01823     change = SelectedOperation (&ChangeMaskSizeFunctions, false, types);
01824   else
01825     change = SelectedOperation (&ChangeClearSizeFunctions, false, types);
01826   if (change)
01827     {
01828       Draw ();
01829       IncrementUndoSerialNumber ();
01830     }
01831   return (change);
01832 }
01833 
01840 bool
01841 ChangeSelected2ndSize (int types, Coord Difference, bool fixIt)
01842 {
01843   bool change = false;
01844 
01845   /* setup identifiers */
01846   Absolute = (fixIt) ? Difference : 0;
01847   Delta = Difference;
01848   change = SelectedOperation (&Change2ndSizeFunctions, false, types);
01849   if (change)
01850     {
01851       Draw ();
01852       IncrementUndoSerialNumber ();
01853     }
01854   return (change);
01855 }
01856 
01863 bool
01864 ChangeSelectedJoin (int types)
01865 {
01866   bool change = false;
01867 
01868   change = SelectedOperation (&ChangeJoinFunctions, false, types);
01869   if (change)
01870     {
01871       Draw ();
01872       IncrementUndoSerialNumber ();
01873     }
01874   return (change);
01875 }
01876 
01883 bool
01884 SetSelectedJoin (int types)
01885 {
01886   bool change = false;
01887 
01888   change = SelectedOperation (&SetJoinFunctions, false, types);
01889   if (change)
01890     {
01891       Draw ();
01892       IncrementUndoSerialNumber ();
01893     }
01894   return (change);
01895 }
01896 
01903 bool
01904 ClrSelectedJoin (int types)
01905 {
01906   bool change = false;
01907 
01908   change = SelectedOperation (&ClrJoinFunctions, false, types);
01909   if (change)
01910     {
01911       Draw ();
01912       IncrementUndoSerialNumber ();
01913     }
01914   return (change);
01915 }
01916 
01923 bool
01924 ChangeSelectedSquare (int types)
01925 {
01926   bool change = false;
01927 
01928   change = SelectedOperation (&ChangeSquareFunctions, false, types);
01929   if (change)
01930     {
01931       Draw ();
01932       IncrementUndoSerialNumber ();
01933     }
01934   return (change);
01935 }
01936 
01942 bool
01943 SetSelectedSquare (int types)
01944 {
01945   bool change = false;
01946 
01947   change = SelectedOperation (&SetSquareFunctions, false, types);
01948   if (change)
01949     {
01950       Draw ();
01951       IncrementUndoSerialNumber ();
01952     }
01953   return (change);
01954 }
01955 
01962 bool
01963 ClrSelectedSquare (int types)
01964 {
01965   bool change = false;
01966 
01967   change = SelectedOperation (&ClrSquareFunctions, false, types);
01968   if (change)
01969     {
01970       Draw ();
01971       IncrementUndoSerialNumber ();
01972     }
01973   return (change);
01974 }
01975 
01982 bool
01983 ChangeSelectedOctagon (int types)
01984 {
01985   bool change = false;
01986 
01987   change = SelectedOperation (&ChangeOctagonFunctions, false, types);
01988   if (change)
01989     {
01990       Draw ();
01991       IncrementUndoSerialNumber ();
01992     }
01993   return (change);
01994 }
01995 
02002 bool
02003 SetSelectedOctagon (int types)
02004 {
02005   bool change = false;
02006 
02007   change = SelectedOperation (&SetOctagonFunctions, false, types);
02008   if (change)
02009     {
02010       Draw ();
02011       IncrementUndoSerialNumber ();
02012     }
02013   return (change);
02014 }
02015 
02022 bool
02023 ClrSelectedOctagon (int types)
02024 {
02025   bool change = false;
02026 
02027   change = SelectedOperation (&ClrOctagonFunctions, false, types);
02028   if (change)
02029     {
02030       Draw ();
02031       IncrementUndoSerialNumber ();
02032     }
02033   return (change);
02034 }
02035 
02041 bool
02042 ChangeSelectedHole (void)
02043 {
02044   bool change = false;
02045 
02046   if (PCB->ViaOn)
02047     VIA_LOOP (PCB->Data);
02048   {
02049     if (TEST_FLAG (SELECTEDFLAG, via))
02050       change |= ChangeHole (via);
02051   }
02052   END_LOOP;
02053   if (change)
02054     {
02055       Draw ();
02056       IncrementUndoSerialNumber ();
02057     }
02058   return (change);
02059 }
02060 
02066 bool
02067 ChangeSelectedPaste (void)
02068 {
02069   bool change = false;
02070 
02071   ALLPAD_LOOP (PCB->Data);
02072   {
02073     if (TEST_FLAG (SELECTEDFLAG, pad))
02074       change |= ChangePaste (pad);
02075   }
02076   ENDALL_LOOP;
02077   if (change)
02078     {
02079       Draw ();
02080       IncrementUndoSerialNumber ();
02081     }
02082   return (change);
02083 }
02084 
02085 
02091 bool
02092 ChangeObjectSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
02093                   Coord Difference, bool fixIt)
02094 {
02095   bool change;
02096 
02097   /* setup identifier */
02098   Absolute = (fixIt) ? Difference : 0;
02099   Delta = Difference;
02100   change =
02101     (ObjectOperation (&ChangeSizeFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL);
02102   if (change)
02103     {
02104       Draw ();
02105       IncrementUndoSerialNumber ();
02106     }
02107   return (change);
02108 }
02109 
02115 bool
02116 ChangeObjectClearSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
02117                        Coord Difference, bool fixIt)
02118 {
02119   bool change;
02120 
02121   /* setup identifier */
02122   Absolute = (fixIt) ? Difference : 0;
02123   Delta = Difference;
02124   if (TEST_FLAG (SHOWMASKFLAG, PCB))
02125     change =
02126       (ObjectOperation (&ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02127        NULL);
02128   else
02129     change =
02130       (ObjectOperation (&ChangeClearSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02131        NULL);
02132   if (change)
02133     {
02134       Draw ();
02135       IncrementUndoSerialNumber ();
02136     }
02137   return (change);
02138 }
02139 
02146 bool
02147 ChangeObjectThermal (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
02148                      int therm_type)
02149 {
02150   bool change;
02151 
02152   Delta = Absolute = therm_type;
02153   change =
02154     (ObjectOperation (&ChangeThermalFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02155      NULL);
02156   if (change)
02157     {
02158       Draw ();
02159       IncrementUndoSerialNumber ();
02160     }
02161   return (change);
02162 }
02163 
02170 bool
02171 ChangeObjectViaLayers (void *Ptr1, void *Ptr2, void *Ptr3,
02172                      int from, int to)
02173 {
02174   bool change = false;
02175   PinType *via = (PinType *) Ptr1;
02176   int new_from = (from != -1)?from:via->BuriedFrom;
02177   int new_to = (to != -1)?to:via->BuriedTo;
02178   int i;
02179 
02180   if (TEST_FLAG (LOCKFLAG, via))
02181     return (NULL);
02182 
02183   if ((new_from == new_to)
02184       && new_from != 0)
02185     return false;
02186 
02187   /* special case - changing TH via "from" layer sets "to" layer to bottom layer */
02188   if (!VIA_IS_BURIED (via)
02189        && (to == -1))
02190      new_to = GetMaxBottomLayer ();
02191 
02192   for (i=0; i < max_copper_layer; i++)
02193     {
02194       /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, false);  not needed? */
02195       RestoreToPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
02196     }
02197 
02198   if (from != -1 || to != -1)
02199     {
02200       AddObjectToSetViaLayersUndoList (via, via, via);
02201       change = true;
02202     }
02203 
02204   via->BuriedFrom = new_from;
02205   via->BuriedTo = new_to;
02206 
02207   if (VIA_IS_BURIED (via))
02208     {
02209       SanitizeBuriedVia (via);
02210       for (i=0; i < max_copper_layer; i++)
02211         {
02212           /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, true);  not needed? */
02213           ClearFromPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
02214         }
02215       DrawVia (via);
02216     }
02217 
02218   if (change)
02219     {
02220       Draw ();
02221       IncrementUndoSerialNumber ();
02222     }
02223   return (change);
02224 }
02225 
02231 bool
02232 ChangeObject2ndSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
02233                      Coord Difference, bool fixIt, bool incundo)
02234 {
02235   bool change;
02236 
02237   /* setup identifier */
02238   Absolute = (fixIt) ? Difference : 0;
02239   Delta = Difference;
02240   change =
02241     (ObjectOperation (&Change2ndSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02242      NULL);
02243   if (change)
02244     {
02245       Draw ();
02246       if (incundo)
02247         IncrementUndoSerialNumber ();
02248     }
02249   return (change);
02250 }
02251 
02257 bool
02258 ChangeObjectMaskSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
02259                       Coord Difference, bool fixIt)
02260 {
02261   bool change;
02262 
02263   /* setup identifier */
02264   Absolute = (fixIt) ? Difference : 0;
02265   Delta = Difference;
02266   change =
02267     (ObjectOperation (&ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02268      NULL);
02269   if (change)
02270     {
02271       Draw ();
02272       IncrementUndoSerialNumber ();
02273     }
02274   return (change);
02275 }
02276 
02285 void *
02286 ChangeObjectName (int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *Name)
02287 {
02288   void *result;
02289   /* setup identifier */
02290   NewName = Name;
02291   result = ObjectOperation (&ChangeNameFunctions, Type, Ptr1, Ptr2, Ptr3);
02292   Draw ();
02293   return (result);
02294 }
02295 
02301 bool
02302 ChangeObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02303 {
02304   if (ObjectOperation (&ChangeJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02305     {
02306       Draw ();
02307       IncrementUndoSerialNumber ();
02308       return (true);
02309     }
02310   return (false);
02311 }
02312 
02318 bool
02319 SetObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02320 {
02321   if (ObjectOperation (&SetJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02322     {
02323       Draw ();
02324       IncrementUndoSerialNumber ();
02325       return (true);
02326     }
02327   return (false);
02328 }
02329 
02335 bool
02336 ClrObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02337 {
02338   if (ObjectOperation (&ClrJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02339     {
02340       Draw ();
02341       IncrementUndoSerialNumber ();
02342       return (true);
02343     }
02344   return (false);
02345 }
02346 
02352 bool
02353 ChangeObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02354 {
02355   if (ObjectOperation (&ChangeSquareFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02356       NULL)
02357     {
02358       Draw ();
02359       IncrementUndoSerialNumber ();
02360       return (true);
02361     }
02362   return (false);
02363 }
02364 
02370 bool
02371 SetObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02372 {
02373   if (ObjectOperation (&SetSquareFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02374     {
02375       Draw ();
02376       IncrementUndoSerialNumber ();
02377       return (true);
02378     }
02379   return (false);
02380 }
02381 
02387 bool
02388 ClrObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02389 {
02390   if (ObjectOperation (&ClrSquareFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02391     {
02392       Draw ();
02393       IncrementUndoSerialNumber ();
02394       return (true);
02395     }
02396   return (false);
02397 }
02398 
02404 bool
02405 ChangeObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02406 {
02407   if (ObjectOperation (&ChangeOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) !=
02408       NULL)
02409     {
02410       Draw ();
02411       IncrementUndoSerialNumber ();
02412       return (true);
02413     }
02414   return (false);
02415 }
02416 
02422 bool
02423 SetObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02424 {
02425   if (ObjectOperation (&SetOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02426     {
02427       Draw ();
02428       IncrementUndoSerialNumber ();
02429       return (true);
02430     }
02431   return (false);
02432 }
02433 
02439 bool
02440 ClrObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02441 {
02442   if (ObjectOperation (&ClrOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
02443     {
02444       Draw ();
02445       IncrementUndoSerialNumber ();
02446       return (true);
02447     }
02448   return (false);
02449 }
02450 
02457 void *
02458 QueryInputAndChangeObjectName (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
02459 {
02460   char *name = NULL;
02461   char msg[513];
02462 
02463   /* if passed an element name, make it an element reference instead */
02464   if (Type == ELEMENTNAME_TYPE)
02465     {
02466       Type = ELEMENT_TYPE;
02467       Ptr2 = Ptr1;
02468       Ptr3 = Ptr1;
02469     }
02470   switch (Type)
02471     {
02472     case LINE_TYPE:
02473       name = gui->prompt_for (_("Linename:"),
02474                               EMPTY (((LineType *) Ptr2)->Number));
02475       break;
02476 
02477     case VIA_TYPE:
02478       name = gui->prompt_for (_("Vianame:"),
02479                               EMPTY (((PinType *) Ptr2)->Name));
02480       break;
02481 
02482     case PIN_TYPE:
02483       sprintf (msg, _("%s Pin Name:"), EMPTY (((PinType *) Ptr2)->Number));
02484       name = gui->prompt_for (msg, EMPTY (((PinType *) Ptr2)->Name));
02485       break;
02486 
02487     case PAD_TYPE:
02488       sprintf (msg, _("%s Pad Name:"), EMPTY (((PadType *) Ptr2)->Number));
02489       name = gui->prompt_for (msg, EMPTY (((PadType *) Ptr2)->Name));
02490       break;
02491 
02492     case TEXT_TYPE:
02493       name = gui->prompt_for (_("Enter text:"),
02494                               EMPTY (((TextType *) Ptr2)->TextString));
02495       break;
02496 
02497     case ELEMENT_TYPE:
02498       name = gui->prompt_for (_("Elementname:"),
02499                               EMPTY (ELEMENT_NAME
02500                                      (PCB, (ElementType *) Ptr2)));
02501       break;
02502     }
02503   if (name)
02504     {
02505       /* NB: ChangeObjectName takes ownership of the passed memory */
02506       char *old = (char *)ChangeObjectName (Type, Ptr1, Ptr2, Ptr3, name);
02507       if (old != (char *) -1)
02508         {
02509           AddObjectToChangeNameUndoList (Type, Ptr1, Ptr2, Ptr3, old);
02510           IncrementUndoSerialNumber ();
02511         }
02512       Draw ();
02513       return (Ptr3);
02514     }
02515   return (NULL);
02516 }
02517 
02523 void
02524 ChangePCBSize (Coord Width, Coord Height)
02525 {
02526   PCB->MaxWidth = Width;
02527   PCB->MaxHeight = Height;
02528   hid_action ("PCBChanged");
02529 }
02530 
02536 static void *
02537 ChangePadMaskSize (ElementType *Element, PadType *Pad)
02538 {
02539   Coord value = (Absolute) ? Absolute : Pad->Mask + Delta;
02540 
02541   value = MAX (value, 0);
02542   if (value == Pad->Mask && Absolute == 0)
02543     value = Pad->Thickness;
02544   if (value != Pad->Mask)
02545     {
02546       AddObjectToMaskSizeUndoList (PAD_TYPE, Element, Pad, Pad);
02547       ErasePad (Pad);
02548       r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
02549       Pad->Mask = value;
02550       SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
02551       DrawPad (Pad);
02552       return (Pad);
02553     }
02554   return (NULL);
02555 }
02556 
02562 static void *
02563 ChangePinMaskSize (ElementType *Element, PinType *Pin)
02564 {
02565   Coord value = (Absolute) ? Absolute : Pin->Mask + Delta;
02566 
02567   value = MAX (value, 0);
02568   if (value == Pin->Mask && Absolute == 0)
02569     value = Pin->Thickness;
02570   if (value != Pin->Mask)
02571     {
02572       AddObjectToMaskSizeUndoList (PIN_TYPE, Element, Pin, Pin);
02573       ErasePin (Pin);
02574       r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
02575       Pin->Mask = value;
02576       SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
02577       DrawPin (Pin);
02578       return (Pin);
02579     }
02580   return (NULL);
02581 }
02582 
02588 static void *
02589 ChangeViaMaskSize (PinType *Via)
02590 {
02591   Coord value;
02592 
02593   value = (Absolute) ? Absolute : Via->Mask + Delta;
02594   value = MAX (value, 0);
02595   if (value != Via->Mask)
02596     {
02597       AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
02598       EraseVia (Via);
02599       r_delete_entry (PCB->Data->via_tree, &Via->BoundingBox);
02600       Via->Mask = value;
02601       SetPinBoundingBox (Via);
02602       r_insert_entry (PCB->Data->via_tree, &Via->BoundingBox, 0);
02603       DrawVia (Via);
02604       return (Via);
02605     }
02606   return (NULL);
02607 }