~ubuntu-branches/ubuntu/precise/pcb/precise

« back to all changes in this revision

Viewing changes to src/set.c

  • Committer: Bazaar Package Importer
  • Author(s): Hamish Moffatt
  • Date: 2005-02-20 13:14:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050220131400-pfz66g5vhx0azl8f
Tags: 1.99j+20050127-2
* Improved package description: (closes: #295405)
* Fixed dependency: tk84 -> tk8.4 (closes: #295404)
* Updated README.debian (closes: #269578)
* Applied patch to src/djopt.c to allow compilation with gcc-4.0
  (closes: #294319), thanks to Andreas Jochens for the patch.
* Prevent example files from being compressed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: set.c,v 1.24 2005/01/21 22:25:27 danmc Exp $ */
 
2
 
1
3
/*
2
4
 *                            COPYRIGHT
3
5
 *
24
26
 *
25
27
 */
26
28
 
27
 
static  char    *rcsid = "$Id: set.c,v 1.6 1998/02/24 22:54:47 cad Exp $";
28
29
 
29
30
/* routines to update widgets and global settings
30
31
 * (except output window and dialogs)
31
32
 */
32
33
 
 
34
#ifdef HAVE_CONFIG_H
 
35
#include "config.h"
 
36
#endif
 
37
 
33
38
#include <math.h>
34
39
#include <stdio.h>
35
40
#include <stdlib.h>
 
41
#ifdef HAVE_STRING_H
36
42
#include <string.h>
 
43
#endif
37
44
 
38
45
#include "global.h"
39
46
 
40
47
#include "action.h"
41
48
#include "buffer.h"
 
49
#include "compat.h"
42
50
#include "crosshair.h"
43
51
#include "control.h"
44
52
#include "data.h"
45
53
#include "draw.h"
 
54
#include "error.h"
 
55
#include "find.h"
 
56
#include "gui.h"
46
57
#include "menu.h"
47
58
#include "misc.h"
48
59
#include "output.h"
49
60
#include "set.h"
50
 
 
51
 
#include <X11/cursorfont.h>
52
 
#include <X11/Xaw3d/Form.h>
 
61
#include "undo.h"
 
62
 
 
63
#ifdef HAVE_LIBDMALLOC
 
64
#include <dmalloc.h>
 
65
#endif
 
66
 
 
67
RCSID("$Id: set.c,v 1.24 2005/01/21 22:25:27 danmc Exp $");
 
68
 
 
69
 
 
70
 
 
71
 
 
72
static int mode_position = 0;
 
73
static int mode_stack[MAX_MODESTACK_DEPTH];
53
74
 
54
75
/* ---------------------------------------------------------------------------
55
76
 * output of cursor position
56
77
 */
57
 
void SetCursorStatusLine(void)
 
78
void
 
79
SetCursorStatusLine (void)
58
80
{
59
 
        char    text[64];
 
81
  char text[64];
60
82
 
61
 
        if (Marked.status)
62
 
                sprintf(text, "%-i,%-i <%-i,%-i> (%-.1f,%-.1f)",Crosshair.X, Crosshair.Y,
63
 
                        Crosshair.X - Marked.X, Crosshair.Y - Marked.Y,
64
 
                        sqrt(SQUARE(Crosshair.X - Marked.X) + SQUARE(Crosshair.Y - Marked.Y)),
65
 
                        RAD_TO_DEG * atan2(Crosshair.Y - Marked.Y, Marked.X - Crosshair.X));
66
 
        else
67
 
        sprintf(text, "%-i,%-i", Crosshair.X, Crosshair.Y);
68
 
        XtVaSetValues(Output.CursorPosition, XtNlabel, text, NULL);
 
83
  if (Marked.status)
 
84
    sprintf (text,
 
85
             "%-i.%02d, %-i.%02d <%-li.%02d, %-li.%02d> (%-.3fmm, %-.3fmm)",
 
86
             Crosshair.X / 100, abs(Crosshair.X % 100), Crosshair.Y / 100,
 
87
             abs(Crosshair.Y % 100), (Crosshair.X - Marked.X) / 100,
 
88
             abs(Crosshair.X - Marked.X) % 100, (Crosshair.Y - Marked.Y) / 100,
 
89
             abs(Crosshair.Y - Marked.Y) % 100,
 
90
             COOR_TO_MM * (Crosshair.X - Marked.X),
 
91
             COOR_TO_MM * (Crosshair.Y - Marked.Y));
 
92
  else
 
93
    sprintf (text, "%-i.%02d,%-i.%02d (%-.3fmm, %-.3fmm)",
 
94
             Crosshair.X / 100, abs(Crosshair.X % 100),
 
95
             Crosshair.Y / 100, abs(Crosshair.Y % 100),
 
96
             COOR_TO_MM*Crosshair.X,
 
97
             COOR_TO_MM*Crosshair.Y);
 
98
  SetOutputLabel (Output.CursorPosition, text);
69
99
}
70
100
 
71
101
/* ---------------------------------------------------------------------------
72
102
 * output of status line
73
103
 */
74
 
void SetStatusLine(void)
 
104
void
 
105
SetStatusLine (void)
75
106
{
76
 
        char    text[140];
77
 
        int             length;
78
 
 
79
 
        sprintf(text, "%c %s,%s,%s%s, grid=%i:%i, zoom=%-i:%-i, line=%-i, via=%-i(%-i), text=%i%%, buffer=#%-i, name: ",
80
 
                PCB->Changed ? '*' : ' ',
81
 
                Settings.ShowSolderSide ? "solder" : "component",
82
 
                TEST_FLAG(ABSOLUTEFLAG, PCB) ? "abs" : "rel",
83
 
                TEST_FLAG(ALLDIRECTIONFLAG, PCB) ? "all" :
84
 
                 (PCB->Clipping == 0 ? "45" : (PCB->Clipping == 1 ?
85
 
                        "45_/" : "45\\_")),
86
 
                TEST_FLAG(RUBBERBANDFLAG, PCB) ? ",R" : " ",
87
 
                (int) PCB->Grid, (int) Settings.GridFactor,
88
 
                (int) (TO_SCREEN(1) ? TO_SCREEN(1) : 1),
89
 
                (int) (TO_PCB(1) ? TO_PCB(1) : 1),
90
 
                (int) Settings.LineThickness,
91
 
                (int) Settings.ViaThickness, (int) Settings.ViaDrillingHole,
92
 
                (int) Settings.TextScale,
93
 
                Settings.BufferNumber+1);
94
 
 
95
 
                /* append the name of the layout */
96
 
        length = sizeof(text) -1 -strlen(text);
97
 
        strncat(text, UNKNOWN(PCB->Name), length);
98
 
        text[sizeof(text) -1] = '\0';
99
 
        XtVaSetValues(Output.StatusLine, XtNlabel, text, NULL);
 
107
  char text[140];
 
108
  int length;
 
109
 
 
110
  if (PCB->Grid == (int) PCB->Grid)
 
111
    sprintf (text,
 
112
             "%c %s, grid=%i.%02i:%i,%s%sline=%i.%02i, via=%i.%02i(%i.%02i),\n"
 
113
             " clearance=%i.%02i, text=%i%%, buffer=#%li, name: ",
 
114
             PCB->Changed ? '*' : ' ',
 
115
             Settings.ShowSolderSide ? "solder" : "component",
 
116
             (int) PCB->Grid / 100, (int) (PCB->Grid) % 100,
 
117
             (int) Settings.GridFactor,
 
118
             TEST_FLAG (ALLDIRECTIONFLAG,
 
119
                        PCB) ? "all" : (PCB->Clipping ==
 
120
                                        0 ? "45" : (PCB->Clipping ==
 
121
                                                    1 ? "45_/" : "45\\_")),
 
122
             TEST_FLAG (RUBBERBANDFLAG, PCB) ? ",R, " : ", ",
 
123
             Settings.LineThickness / 100, Settings.LineThickness % 100,
 
124
             Settings.ViaThickness / 100, Settings.ViaThickness % 100,
 
125
             Settings.ViaDrillingHole / 100, Settings.ViaDrillingHole % 100,
 
126
             Settings.Keepaway / 100, Settings.Keepaway % 100,
 
127
             Settings.TextScale, Settings.BufferNumber + 1);
 
128
  else
 
129
    sprintf (text,
 
130
             "%c %s, grid=%5.3fmm:%i,%s%sline=%i.%02i, via=%i.%02i(%i.%02i),\n"
 
131
             " clearance=%i.%02i, text=%i%%, buffer=#%li, name: ",
 
132
             PCB->Changed ? '*' : ' ',
 
133
             Settings.ShowSolderSide ? "solder" : "component",
 
134
             PCB->Grid * COOR_TO_MM, (int) Settings.GridFactor,
 
135
             TEST_FLAG (ALLDIRECTIONFLAG,
 
136
                        PCB) ? "all" : (PCB->Clipping ==
 
137
                                        0 ? "45" : (PCB->Clipping ==
 
138
                                                    1 ? "45_/" : "45\\_")),
 
139
             TEST_FLAG (RUBBERBANDFLAG, PCB) ? ",R, " : ", ",
 
140
             Settings.LineThickness / 100, Settings.LineThickness % 100,
 
141
             Settings.ViaThickness / 100, Settings.ViaThickness % 100,
 
142
             Settings.ViaDrillingHole / 100, Settings.ViaDrillingHole % 100,
 
143
             Settings.Keepaway / 100, Settings.Keepaway % 100,
 
144
             Settings.TextScale, Settings.BufferNumber + 1);
 
145
 
 
146
  /* append the name of the layout */
 
147
  length = sizeof (text) - 1 - strlen (text);
 
148
  strncat (text, UNKNOWN (PCB->Name), length);
 
149
  text[sizeof (text) - 1] = '\0';
 
150
  SetOutputLabel (Output.StatusLine, text);
100
151
}
101
152
 
102
153
/* ---------------------------------------------------------------------------
103
154
 * sets cursor grid with respect to grid offset values
104
155
 */
105
 
void SetGrid(int Grid)
 
156
void
 
157
SetGrid (float Grid, Boolean align)
106
158
{
107
 
        if (Grid >= 1 && Grid <= MAX_GRID)
 
159
  if (Grid >= 1 && Grid <= MAX_GRID)
 
160
    {
 
161
      if (align)
108
162
        {
109
 
                        /* set offset relative to current location or absolute
110
 
                         * to (0,0) depending on resource
111
 
                         * DrawGrid() uses XOR mode
112
 
                         */
113
 
                PCB->GridOffsetX= TEST_FLAG(ABSOLUTEFLAG, PCB) ? 0 : Crosshair.X % Grid;
114
 
                PCB->GridOffsetY= TEST_FLAG(ABSOLUTEFLAG, PCB) ? 0 : Crosshair.Y % Grid;
115
 
                PCB->Grid = Grid;
116
 
                if (Settings.DrawGrid)
117
 
                        UpdateAll();
118
 
                SetStatusLine();
 
163
          PCB->GridOffsetX =
 
164
            Crosshair.X - (int) (Crosshair.X / Grid) * Grid + 0.5;
 
165
          PCB->GridOffsetY =
 
166
            Crosshair.Y - (int) (Crosshair.Y / Grid) * Grid + 0.5;
119
167
        }
120
 
 
168
      PCB->Grid = Grid;
 
169
      if (Settings.DrawGrid)
 
170
        UpdateAll ();
 
171
      SetStatusLine ();
 
172
    }
 
173
}
121
174
 
122
175
/* ---------------------------------------------------------------------------
123
176
* sets new zoom factor, adapts size of viewport and centers the cursor
124
177
*/
125
 
void SetZoom(int Zoom)
126
 
{
127
 
        static  String  cmd[] = {"MovePointer", "0", "0"};
128
 
        int             localMin;
129
 
 
130
 
        if (MAX(PCB->MaxWidth, PCB->MaxHeight) > (1 << 14))
131
 
                localMin = MIN_ZOOM;
132
 
        else if (MAX(PCB->MaxWidth, PCB->MaxHeight) > (1 << 13))
133
 
                localMin = MIN_ZOOM - 1;
134
 
        else
135
 
                localMin = MIN_ZOOM - 2;
136
 
        Zoom = MAX(localMin, Zoom);
137
 
        Zoom = MIN(MAX_ZOOM, Zoom);
138
 
 
139
 
                /* redraw only if zoom has changed */
140
 
        if (PCB->Zoom != Zoom)
141
 
        {
142
 
                PCB->Zoom = Zoom;
143
 
                ScaleOutput(Output.Width, Output.Height);
144
 
                Pan(TO_SCREEN_X(Crosshair.X) - Output.Width/2 - Xorig,
145
 
                        TO_SCREEN_Y(Crosshair.Y) - Output.Height/2 - Yorig, False, True);
146
 
 
147
 
                        /* move the pointer to the same relative location */
148
 
                XtCallActionProc(Output.Output, cmd[0], NULL, &cmd[1], 2);
149
 
                UpdateAll();
150
 
        }
151
 
                /* always redraw status line (used for init sequence) */
152
 
        SetStatusLine();
153
 
 
178
void
 
179
SetZoom (float Zoom)
 
180
{
 
181
  int old_x, old_y;
 
182
 
 
183
  /* special argument of 1000 zooms to extents plus 10 percent */
 
184
  if (Zoom == 1000.0)
 
185
    {
 
186
      BoxTypePtr box = GetDataBoundingBox (PCB->Data);
 
187
      if (!box)
 
188
        return;
 
189
      Zoom =
 
190
        logf (0.011 * (float) (box->X2 - box->X1) / Output.Width) / LN_2_OVER_2;
 
191
      Zoom =
 
192
        MAX (Zoom, logf (0.011 * (float) (box->Y2 - box->Y1) / Output.Height) /
 
193
             LN_2_OVER_2);
 
194
      Crosshair.X = (box->X1 + box->X2) / 2;
 
195
      Crosshair.Y = (box->Y1 + box->Y2) / 2;
 
196
      old_x = Output.Width / 2;
 
197
      old_y = Output.Height / 2;
 
198
    }
 
199
  else
 
200
    {
 
201
      old_x = TO_SCREEN_X (Crosshair.X);
 
202
      old_y = TO_SCREEN_Y (Crosshair.Y);
 
203
    }
 
204
  Zoom = MAX (MIN_ZOOM, Zoom);
 
205
  Zoom = MIN (MAX_ZOOM, Zoom);
 
206
  Zoom_Multiplier = 0.01/expf(Zoom * LN_2_OVER_2);
 
207
 
 
208
  /* redraw only if something changed */
 
209
  if (PCB->Zoom != Zoom)
 
210
    {
 
211
      PCB->Zoom = Zoom;
 
212
      RedrawZoom (old_x, old_y);
 
213
    }
 
214
}
 
215
 
 
216
void
 
217
RedrawZoom (Position old_x, Position old_y)
 
218
{
 
219
  ScaleOutput (Output.Width, Output.Height);
 
220
  if (CoalignScreen (old_x, old_y, Crosshair.X, Crosshair.Y))
 
221
    warpNoWhere ();
 
222
 
 
223
  UpdateAll ();
 
224
  /* always redraw status line (used for init sequence) */
 
225
  SetStatusLine ();
 
226
}
154
227
 
155
228
/* ---------------------------------------------------------------------------
156
229
 * sets a new line thickness
157
230
 */
158
 
void SetLineSize(Dimension Size)
 
231
void
 
232
SetLineSize (BDimension Size)
159
233
{
160
 
        if (Size >= MIN_LINESIZE && Size <= MAX_LINESIZE)
161
 
        {
162
 
                Settings.LineThickness = Size;
163
 
                SetStatusLine();
164
 
        }
 
234
  if (Size >= MIN_LINESIZE && Size <= MAX_LINESIZE)
 
235
    {
 
236
      Settings.LineThickness = Size;
 
237
      if (TEST_FLAG (AUTODRCFLAG, PCB))
 
238
        FitCrosshairIntoGrid (Crosshair.X, Crosshair.Y);
 
239
      SetStatusLine ();
 
240
    }
165
241
}
166
242
 
167
243
/* ---------------------------------------------------------------------------
168
244
 * sets a new via thickness
169
245
 */
170
 
void SetViaSize(Dimension Size, Boolean Force)
 
246
void
 
247
SetViaSize (BDimension Size, Boolean Force)
171
248
{
172
 
        if (Force || (Size <= MAX_PINORVIASIZE &&
 
249
  if (Force || (Size <= MAX_PINORVIASIZE &&
173
250
                Size >= MIN_PINORVIASIZE &&
174
 
                Size >= Settings.ViaDrillingHole +MIN_PINORVIACOPPER))
175
 
        {
176
 
                Settings.ViaThickness = Size;
177
 
                SetStatusLine();
178
 
        }
 
251
                Size >= Settings.ViaDrillingHole + MIN_PINORVIACOPPER))
 
252
    {
 
253
      Settings.ViaThickness = Size;
 
254
      SetStatusLine ();
 
255
    }
179
256
}
180
257
 
181
258
/* ---------------------------------------------------------------------------
182
259
 * sets a new via drilling hole
183
260
 */
184
 
void SetViaDrillingHole(Dimension Size, Boolean Force)
 
261
void
 
262
SetViaDrillingHole (BDimension Size, Boolean Force)
185
263
{
186
 
        if (Force || (Size <= MAX_PINORVIASIZE &&
 
264
  if (Force || (Size <= MAX_PINORVIASIZE &&
187
265
                Size >= MIN_PINORVIAHOLE &&
188
 
                Size <= Settings.ViaThickness -MIN_PINORVIACOPPER))
189
 
        {
190
 
                Settings.ViaDrillingHole = Size;
191
 
                SetStatusLine();
192
 
        }
 
266
                Size <= Settings.ViaThickness - MIN_PINORVIACOPPER))
 
267
    {
 
268
      Settings.ViaDrillingHole = Size;
 
269
      SetStatusLine ();
 
270
    }
 
271
}
 
272
 
 
273
/* ---------------------------------------------------------------------------
 
274
 * sets a keepaway width
 
275
 */
 
276
void
 
277
SetKeepawayWidth (BDimension Width)
 
278
{
 
279
  if (Width <= MAX_LINESIZE && Width >= MIN_LINESIZE)
 
280
    {
 
281
      Settings.Keepaway = Width;
 
282
      SetStatusLine ();
 
283
    }
193
284
}
194
285
 
195
286
/* ---------------------------------------------------------------------------
196
287
 * sets a text scaling
197
288
 */
198
 
void SetTextScale(Dimension Scale)
 
289
void
 
290
SetTextScale (Dimension Scale)
199
291
{
200
 
        if (Scale <= MAX_TEXTSCALE && Scale >= MIN_TEXTSCALE)
201
 
        {
202
 
                Settings.TextScale = Scale;
203
 
                SetStatusLine();
204
 
        }
 
292
  if (Scale <= MAX_TEXTSCALE && Scale >= MIN_TEXTSCALE)
 
293
    {
 
294
      Settings.TextScale = Scale;
 
295
      SetStatusLine ();
 
296
    }
205
297
}
206
298
 
207
299
/* ---------------------------------------------------------------------------
208
300
 * sets or resets changed flag and redraws status
209
301
 */
210
 
void SetChangedFlag(Boolean New)
 
302
void
 
303
SetChangedFlag (Boolean New)
211
304
{
212
 
        PCB->Changed = New;
213
 
        SetStatusLine();
 
305
  if (PCB->Changed != New)
 
306
    {
 
307
      PCB->Changed = New;
 
308
      SetStatusLine ();
 
309
    }
214
310
}
215
311
 
216
312
/* ---------------------------------------------------------------------------
217
313
 * sets the crosshair range to the current buffer extents 
218
314
 */
219
 
void SetCrosshairRangeToBuffer(void)
 
315
void
 
316
SetCrosshairRangeToBuffer (void)
220
317
{
221
 
        if (Settings.Mode == PASTEBUFFER_MODE)
222
 
        {
223
 
                SetBufferBoundingBox(PASTEBUFFER);
224
 
                SetCrosshairRange(
225
 
                        PASTEBUFFER->X -PASTEBUFFER->BoundingBox.X1,
226
 
                        PASTEBUFFER->Y -PASTEBUFFER->BoundingBox.Y1,
227
 
                        PCB->MaxWidth-
228
 
                                (PASTEBUFFER->BoundingBox.X2 -PASTEBUFFER->X),
229
 
                        PCB->MaxHeight-
230
 
                                (PASTEBUFFER->BoundingBox.Y2 -PASTEBUFFER->Y));
231
 
        }
 
318
  if (Settings.Mode == PASTEBUFFER_MODE)
 
319
    {
 
320
      SetBufferBoundingBox (PASTEBUFFER);
 
321
      SetCrosshairRange (PASTEBUFFER->X - PASTEBUFFER->BoundingBox.X1,
 
322
                         PASTEBUFFER->Y - PASTEBUFFER->BoundingBox.Y1,
 
323
                         PCB->MaxWidth -
 
324
                         (PASTEBUFFER->BoundingBox.X2 - PASTEBUFFER->X),
 
325
                         PCB->MaxHeight -
 
326
                         (PASTEBUFFER->BoundingBox.Y2 - PASTEBUFFER->Y));
 
327
    }
232
328
}
233
329
 
234
330
/* ---------------------------------------------------------------------------
235
331
 * sets a new buffer number
236
332
 */
237
 
void SetBufferNumber(int Number)
 
333
void
 
334
SetBufferNumber (int Number)
238
335
{
239
 
        if (Number >= 0 && Number < MAX_BUFFER)
240
 
        {
241
 
                Settings.BufferNumber = Number;
 
336
  if (Number >= 0 && Number < MAX_BUFFER)
 
337
    {
 
338
      Settings.BufferNumber = Number;
242
339
 
243
 
                        /* do an update on the crosshair range */
244
 
                SetCrosshairRangeToBuffer();
245
 
                SetStatusLine();
246
 
        }
 
340
      /* do an update on the crosshair range */
 
341
      SetCrosshairRangeToBuffer ();
 
342
      SetStatusLine ();
 
343
    }
247
344
}
248
345
 
249
346
/* ---------------------------------------------------------------------------
250
347
 * updates all widgets like status, cursor position ... on screen
251
348
 */
252
 
void UpdateSettingsOnScreen(void)
253
 
{
254
 
        SetStatusLine();
255
 
        SetCursorStatusLine();
256
 
        UpdateControlPanel();
257
 
        UpdateSizesMenu();
258
 
}
 
349
void
 
350
UpdateSettingsOnScreen (void)
 
351
{
 
352
  SetStatusLine ();
 
353
  SetCursorStatusLine ();
 
354
  UpdateControlPanel ();
 
355
}
 
356
 
 
357
void
 
358
SaveMode (void)
 
359
{
 
360
  mode_stack[mode_position] = Settings.Mode;
 
361
  if (mode_position < MAX_MODESTACK_DEPTH -1)
 
362
    mode_position++;
 
363
}
 
364
 
 
365
void
 
366
RestoreMode (void)
 
367
{
 
368
  if (mode_position == 0)
 
369
    {
 
370
      Message("hace: underflow of restore mode\n");
 
371
      return;
 
372
    }
 
373
  SetMode(mode_stack[--mode_position]);
 
374
}
 
375
 
259
376
 
260
377
/* ---------------------------------------------------------------------------
261
378
 * set a new mode and update X cursor
262
379
 */
263
 
void SetMode(int Mode)
264
 
{
265
 
        static Boolean recursing = False;
266
 
                /* protect the cursor while changing the mode
267
 
                 * perform some additional stuff depending on the new mode
268
 
                 * reset 'state' of attached objects
269
 
                 */
270
 
        if (recursing)
271
 
                return;
272
 
        recursing = True;
273
 
        HideCrosshair(True);
274
 
        addedLines = 0;
275
 
        Crosshair.AttachedObject.Type = NO_TYPE;
276
 
        Crosshair.AttachedObject.State = STATE_FIRST;
277
 
        Crosshair.AttachedPolygon.PointN = 0;
278
 
        if (Settings.Mode == LINE_MODE && Mode == ARC_MODE &&
279
 
                Crosshair.AttachedLine.State != STATE_FIRST)
280
 
        {
281
 
                Crosshair.AttachedLine.State = STATE_FIRST;
282
 
                Crosshair.AttachedBox.State = STATE_SECOND;
283
 
                Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X =
284
 
                        Crosshair.AttachedLine.Point1.X;
285
 
                Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y =
286
 
                        Crosshair.AttachedLine.Point1.Y;
287
 
        }
288
 
        else if (Settings.Mode == ARC_MODE && Mode == LINE_MODE &&
289
 
                Crosshair.AttachedBox.State != STATE_FIRST)
290
 
        {
291
 
                Crosshair.AttachedBox.State = STATE_FIRST;
292
 
                Crosshair.AttachedLine.State = STATE_SECOND;
293
 
                Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X =
294
 
                        Crosshair.AttachedBox.Point1.X;
295
 
                Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y =
296
 
                        Crosshair.AttachedBox.Point1.Y;
297
 
                Settings.Mode = Mode;
298
 
                AdjustAttachedObjects();
299
 
        }
300
 
        else
301
 
        {
302
 
                Crosshair.AttachedBox.State = STATE_FIRST;
303
 
                Crosshair.AttachedLine.State = STATE_FIRST;
304
 
        }
305
 
 
306
 
                /* reset 'valid' cursor area to maximum;
307
 
                 * some modes force a change in the 'case' statement
308
 
                 */
309
 
        SetCrosshairRange(0, 0, PCB->MaxWidth, PCB->MaxHeight);
310
 
 
311
 
        Settings.Mode = Mode;
312
 
        switch(Mode)
313
 
        {
314
 
                case NO_MODE:
315
 
                        SetOutputXCursor(XC_crosshair);
316
 
                        break;
317
 
 
318
 
                case VIA_MODE:
319
 
                        SetOutputXCursor(XC_arrow);
320
 
                        break;
321
 
 
322
 
                case LINE_MODE:
323
 
                        SetOutputXCursor(XC_pencil);
324
 
                        break;
325
 
 
326
 
                case ARC_MODE:
327
 
                        SetOutputXCursor(XC_question_arrow);
328
 
                        break;
329
 
 
330
 
                case ARROW_MODE:
331
 
                        SetOutputXCursor(XC_left_ptr);
332
 
                        break;
333
 
 
334
 
                case POLYGON_MODE:
335
 
                        SetOutputXCursor(XC_sb_up_arrow);
336
 
                        break;
337
 
 
338
 
                case PASTEBUFFER_MODE:
339
 
                        SetOutputXCursor(XC_hand1);
340
 
 
341
 
                                /* do an update on the crosshair range */
342
 
                        SetCrosshairRangeToBuffer();
343
 
                        break;
344
 
 
345
 
                case TEXT_MODE:
346
 
                        SetOutputXCursor(XC_xterm);
347
 
                        break;
348
 
 
349
 
                case RECTANGLE_MODE:
350
 
                        SetOutputXCursor(XC_ul_angle);
351
 
                        break;
352
 
 
353
 
                case THERMAL_MODE:
354
 
                        SetOutputXCursor(XC_iron_cross);
355
 
                        break;
356
 
 
357
 
                case REMOVE_MODE:
358
 
                        SetOutputXCursor(XC_pirate);
359
 
                        break;
360
 
 
361
 
                case ROTATE_MODE:
362
 
                        SetOutputXCursor(XC_exchange);
363
 
                        break;
364
 
 
365
 
                case COPY_MODE:
366
 
                case MOVE_MODE:
367
 
                        SetOutputXCursor(XC_crosshair);
368
 
                        break;
369
 
 
370
 
                case INSERTPOINT_MODE:
371
 
                        SetOutputXCursor(XC_dotbox);
372
 
                        break;
373
 
        }
374
 
        UpdateModeSelection();
375
 
        recursing = False;
376
 
 
377
 
                /* force a crosshair grid update because the valid range
378
 
                 * may have changed
379
 
                 */
380
 
        MoveCrosshairRelative(0, 0);
381
 
        RestoreCrosshair(True);
382
 
}
383
 
 
384
 
void SetRouteStyle(char *name)
385
 
{
386
 
        char    *arg, num[10];
387
 
        Cardinal        i;
388
 
 
389
 
        for (i = 0; i < NUM_STYLES; i++)
390
 
                if (name && strcmp(name, PCB->RouteStyle[i].Name) == 0)
391
 
                {
392
 
                        arg = &num[0];
393
 
                        sprintf(num,"%d", i+1);
394
 
                        XtCallActionProc(Output.Output, "RouteStyle", NULL, &arg, 1);
395
 
                        break;
396
 
                }
 
380
void
 
381
SetMode (int Mode)
 
382
{
 
383
  static Boolean recursing = False;
 
384
  /* protect the cursor while changing the mode
 
385
   * perform some additional stuff depending on the new mode
 
386
   * reset 'state' of attached objects
 
387
   */
 
388
  if (recursing)
 
389
    return;
 
390
  recursing = True;
 
391
  HideCrosshair (True);
 
392
  addedLines = 0;
 
393
  Crosshair.AttachedObject.Type = NO_TYPE;
 
394
  Crosshair.AttachedObject.State = STATE_FIRST;
 
395
  Crosshair.AttachedPolygon.PointN = 0;
 
396
  if (PCB->RatDraw)
 
397
    {
 
398
      if (Mode == ARC_MODE || Mode == RECTANGLE_MODE ||
 
399
          Mode == VIA_MODE || Mode == POLYGON_MODE ||
 
400
          Mode == TEXT_MODE || Mode == INSERTPOINT_MODE ||
 
401
          Mode == THERMAL_MODE)
 
402
        {
 
403
          Message ("That mode is NOT allowed when drawing " "ratlines!\n");
 
404
          Mode = NO_MODE;
 
405
        }
 
406
    }
 
407
  if (Settings.Mode == LINE_MODE && Mode == ARC_MODE &&
 
408
      Crosshair.AttachedLine.State != STATE_FIRST)
 
409
    {
 
410
      Crosshair.AttachedLine.State = STATE_FIRST;
 
411
      Crosshair.AttachedBox.State = STATE_SECOND;
 
412
      Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X =
 
413
        Crosshair.AttachedLine.Point1.X;
 
414
      Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y =
 
415
        Crosshair.AttachedLine.Point1.Y;
 
416
      AdjustAttachedObjects ();
 
417
    }
 
418
  else if (Settings.Mode == ARC_MODE && Mode == LINE_MODE &&
 
419
           Crosshair.AttachedBox.State != STATE_FIRST)
 
420
    {
 
421
      Crosshair.AttachedBox.State = STATE_FIRST;
 
422
      Crosshair.AttachedLine.State = STATE_SECOND;
 
423
      Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X =
 
424
        Crosshair.AttachedBox.Point1.X;
 
425
      Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y =
 
426
        Crosshair.AttachedBox.Point1.Y;
 
427
      Settings.Mode = Mode;
 
428
      AdjustAttachedObjects ();
 
429
    }
 
430
  else
 
431
    {
 
432
      if (Settings.Mode == ARC_MODE || Settings.Mode == LINE_MODE)
 
433
        SetLocalRef(0, 0, False);
 
434
      Crosshair.AttachedBox.State = STATE_FIRST;
 
435
      Crosshair.AttachedLine.State = STATE_FIRST;
 
436
      if (Mode == LINE_MODE && TEST_FLAG (AUTODRCFLAG, PCB))
 
437
        {
 
438
          SaveUndoSerialNumber ();
 
439
          ResetFoundPinsViasAndPads (True);
 
440
          RestoreUndoSerialNumber ();
 
441
          ResetFoundLinesAndPolygons (True);
 
442
          IncrementUndoSerialNumber();
 
443
        }
 
444
    }
 
445
 
 
446
  Settings.Mode = Mode;
 
447
  modeCursor (Mode);
 
448
  if (Mode == PASTEBUFFER_MODE)
 
449
    /* do an update on the crosshair range */
 
450
    SetCrosshairRangeToBuffer ();
 
451
  else
 
452
    SetCrosshairRange (0, 0, PCB->MaxWidth, PCB->MaxHeight);
 
453
 
 
454
  UpdateModeSelection ();
 
455
  recursing = False;
 
456
 
 
457
  /* force a crosshair grid update because the valid range
 
458
   * may have changed
 
459
   */
 
460
  MoveCrosshairRelative (0, 0);
 
461
  RestoreCrosshair (True);
 
462
}
 
463
 
 
464
void
 
465
SetRouteStyle (char *name)
 
466
{
 
467
  char *arg, num[10];
 
468
 
 
469
  STYLE_LOOP (PCB);
 
470
    {
 
471
      if (name && NSTRCMP (name, style->Name) == 0)
 
472
        {
 
473
          arg = &num[0];
 
474
          sprintf (num, "%d", n + 1);
 
475
          CallActionProc (Output.Output, "RouteStyle", NULL, &arg, 1);
 
476
          break;
 
477
        }
 
478
    }
 
479
  END_LOOP;
 
480
}
 
481
 
 
482
void
 
483
SetLocalRef (LocationType X, LocationType Y, Boolean Showing)
 
484
{
 
485
  static MarkType old;
 
486
  static int count = 0;
 
487
 
 
488
  if (Showing)
 
489
    {
 
490
      HideCrosshair (True);
 
491
      if (count == 0)
 
492
        old = Marked;
 
493
      Marked.X = X;
 
494
      Marked.Y = Y;
 
495
      Marked.status = True;
 
496
      count++;
 
497
      RestoreCrosshair (False);
 
498
    }
 
499
  else if (count > 0)
 
500
    {
 
501
      HideCrosshair (False);
 
502
      count = 0;
 
503
      Marked = old;
 
504
      RestoreCrosshair (False);
 
505
    }
397
506
}