18 #include "crosshair.h"
27 #include "../hidint.h"
29 #include "hid/common/draw_helpers.h"
32 #if !GTK_CHECK_VERSION(2,8,0) && defined(HAVE_GDK_GDKX_H)
36 #ifdef HAVE_LIBDMALLOC
47 static void zoom_to (double factor
, int x
, int y
);
48 static void zoom_by (double factor
, int x
, int y
);
50 /* Sets gport->u_gc to the "right" GC to use (wrt mask or window)
52 #define USE_GC(gc) if (!use_gc(gc)) return
54 static int cur_mask
= -1;
55 static int mask_seq
= 0;
57 int ghid_flip_x
= 0, ghid_flip_y
= 0;
59 /* ------------------------------------------------------------ */
61 /* Px converts view->pcb, Vx converts pcb->view */
68 rv
= (PCB
->MaxWidth
- x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
70 rv
= (x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
77 return (x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
85 rv
= (PCB
->MaxHeight
- y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
87 rv
= (y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
94 return (y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
100 return z
/ gport
->zoom
+ 0.5;
106 int rv
= x
* gport
->zoom
+ gport
->view_x0
;
108 rv
= PCB
->MaxWidth
- (x
* gport
->zoom
+ gport
->view_x0
);
115 int rv
= y
* gport
->zoom
+ gport
->view_y0
;
117 rv
= PCB
->MaxHeight
- (y
* gport
->zoom
+ gport
->view_y0
);
124 return (z
* gport
->zoom
);
127 /* ------------------------------------------------------------ */
134 * don't pan so far to the right that we see way past the right
137 if (gport
->view_x0
> PCB
->MaxWidth
- gport
->view_width
)
138 gport
->view_x0
= PCB
->MaxWidth
- gport
->view_width
;
141 * don't pan so far down that we see way past the bottom edge of
144 if (gport
->view_y0
> PCB
->MaxHeight
- gport
->view_height
)
145 gport
->view_y0
= PCB
->MaxHeight
- gport
->view_height
;
147 /* don't view above or to the left of the board... ever */
148 if (gport
->view_x0
< 0)
151 if (gport
->view_y0
< 0)
155 /* if we can see the entire board and some, then zoom to fit */
156 if (gport
->view_width
> PCB
->MaxWidth
&&
157 gport
->view_height
> PCB
->MaxHeight
)
163 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view_x0
);
164 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view_y0
);
166 ghid_invalidate_all ();
170 /* ------------------------------------------------------------ */
172 static const char zoom_syntax
[] =
177 static const char zoom_help
[] =
178 "Various zoom factor changes.";
180 /* %start-doc actions Zoom
181 Changes the zoom (magnification) of the view of the board. If no
182 arguments are passed, the view is scaled such that the board just fits
183 inside the visible window (i.e. ``view all''). Otherwise,
184 @var{factor} specifies a change in zoom factor. It may be prefixed by
185 @code{+}, @code{-}, or @code{=} to change how the zoom factor is
186 modified. The @var{factor} is a floating point number, such as
187 @code{1.5} or @code{0.75}.
192 Values greater than 1.0 cause the board to be drawn smaller; more of
193 the board will be visible. Values between 0.0 and 1.0 cause the board
194 to be drawn bigger; less of the board will be visible.
197 Values greater than 1.0 cause the board to be drawn bigger; less of
198 the board will be visible. Values between 0.0 and 1.0 cause the board
199 to be drawn smaller; more of the board will be visible.
203 The @var{factor} is an absolute zoom factor; the unit for this value
204 is "PCB units per screen pixel". Since PCB units are 0.01 mil, a
205 @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI,
206 about the actual resolution of most screens - resulting in an "actual
207 size" board. Similarly, a @var{factor} of 100 gives you a 10x actual
212 Note that zoom factors of zero are silently ignored.
219 Zoom (int argc
, char **argv
, int x
, int y
)
228 if (x
== 0 && y
== 0)
230 x
= gport
->view_width
/ 2;
231 y
= gport
->view_height
/ 2;
235 /* Px converts view->pcb, Vx converts pcb->view */
242 zoom_to (1000000, 0, 0);
247 if (*vp
== '+' || *vp
== '-' || *vp
== '=')
256 zoom_by (1 / v
, x
, y
);
264 /* this needs to set the scale factor absolutely*/
275 zoom_to (double new_zoom
, int x
, int y
)
277 double max_zoom
, xfrac
, yfrac
;
281 * zoom value is PCB units per screen pixel. Larger numbers mean zooming
282 * out - the largest value means you are looking at the whole board.
284 * PCB units per screen pixel
286 * gport->view_width and gport->view_height are in PCB coordinates
290 printf ("\nzoom_to( %g, %d, %d)\n", new_zoom
, x
, y
);
293 xfrac
= (double) x
/ (double) gport
->view_width
;
294 yfrac
= (double) y
/ (double) gport
->view_height
;
301 /* Find the zoom that would just make the entire board fit */
302 max_zoom
= PCB
->MaxWidth
/ gport
->width
;
303 if (max_zoom
< PCB
->MaxHeight
/ gport
->height
)
304 max_zoom
= PCB
->MaxHeight
/ gport
->height
;
307 printf ("zoom_to(): max_zoom = %g\n", max_zoom
);
311 * clip the zooming so we can never have more than 1 pixel per PCB
312 * unit and never zoom out more than viewing the entire board
317 if (new_zoom
> max_zoom
)
321 printf ("max_zoom = %g, xfrac = %g, yfrac = %g, new_zoom = %g\n",
322 max_zoom
, xfrac
, yfrac
, new_zoom
);
325 /* find center x and y */
326 cx
= gport
->view_x0
+ gport
->view_width
* xfrac
* gport
->zoom
;
327 cy
= gport
->view_y0
+ gport
->view_height
* yfrac
* gport
->zoom
;
330 printf ("zoom_to(): x0 = %d, cx = %d\n", gport
->view_x0
, cx
);
331 printf ("zoom_to(): y0 = %d, cy = %d\n", gport
->view_y0
, cy
);
334 if (gport
->zoom
!= new_zoom
)
339 xtmp
= (gport
->view_x
- gport
->view_x0
) / (gdouble
) gport
->view_width
;
340 ytmp
= (gport
->view_y
- gport
->view_y0
) / (gdouble
) gport
->view_height
;
342 gport
->zoom
= new_zoom
;
343 pixel_slop
= new_zoom
;
344 ghid_port_ranges_scale(FALSE
);
346 x0
= gport
->view_x
- xtmp
* gport
->view_width
;
351 y0
= gport
->view_y
- ytmp
* gport
->view_height
;
356 ghidgui
->adjustment_changed_holdoff
= TRUE
;
357 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view_x0
);
358 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view_y0
);
359 ghidgui
->adjustment_changed_holdoff
= FALSE
;
361 ghid_port_ranges_changed();
365 printf ("zoom_to(): new x0 = %d\n", gport
->view_x0
);
366 printf ("zoom_to(): new y0 = %d\n", gport
->view_y0
);
368 ghid_set_status_line_label ();
372 zoom_by (double factor
, int x
, int y
)
375 printf ("\nzoom_by( %g, %d, %d). old gport->zoom = %g\n",
376 factor
, x
, y
, gport
->zoom
);
378 zoom_to (gport
->zoom
* factor
, x
, y
);
381 /* ------------------------------------------------------------ */
386 static GdkPoint
*points
= 0;
387 static int npoints
= 0;
388 int x1
, y1
, x2
, y2
, n
, i
;
391 if (!Settings
.DrawGrid
)
393 if (Vz (PCB
->Grid
) < MIN_GRID_DISTANCE
)
397 if (gdk_color_parse (Settings
.GridColor
, &gport
->grid_color
))
399 gport
->grid_color
.red
^= gport
->bg_color
.red
;
400 gport
->grid_color
.green
^= gport
->bg_color
.green
;
401 gport
->grid_color
.blue
^= gport
->bg_color
.blue
;
402 gdk_color_alloc (gport
->colormap
, &gport
->grid_color
);
404 gport
->grid_gc
= gdk_gc_new (gport
->drawable
);
405 gdk_gc_set_function (gport
->grid_gc
, GDK_XOR
);
406 gdk_gc_set_foreground (gport
->grid_gc
, &gport
->grid_color
);
408 x1
= GRIDFIT_X (SIDE_X (gport
->view_x0
), PCB
->Grid
);
409 y1
= GRIDFIT_Y (SIDE_Y (gport
->view_y0
), PCB
->Grid
);
410 x2
= GRIDFIT_X (SIDE_X (gport
->view_x0
+ gport
->view_width
- 1), PCB
->Grid
);
411 y2
= GRIDFIT_Y (SIDE_Y (gport
->view_y0
+ gport
->view_height
- 1), PCB
->Grid
);
428 if (Vx (x2
) >= gport
->width
)
430 if (Vy (y2
) >= gport
->height
)
432 n
= (int) ((x2
- x1
) / PCB
->Grid
+ 0.5) + 1;
437 MyRealloc (points
, npoints
* sizeof (GdkPoint
), "gtk_draw_grid");
440 for (x
= x1
; x
<= x2
; x
+= PCB
->Grid
)
442 points
[n
].x
= Vx (x
);
445 for (y
= y1
; y
<= y2
; y
+= PCB
->Grid
)
448 for (i
= 0; i
< n
; i
++)
450 gdk_draw_points (gport
->drawable
, gport
->grid_gc
, points
, n
);
454 /* ------------------------------------------------------------ */
457 ghid_get_export_options (int *n_ret
)
464 ghid_invalidate_wh (int x
, int y
, int width
, int height
, int last
)
466 ghid_invalidate_all ();
470 ghid_invalidate_lr (int left
, int right
, int top
, int bottom
, int last
)
472 ghid_invalidate_all ();
476 ghid_draw_bg_image(void)
478 static GdkPixbuf
*pixbuf
;
479 GdkInterpType interp_type
;
480 gint x
, y
, w
, h
, w_src
, h_src
;
481 static gint w_scaled
, h_scaled
;
483 if (!ghidgui
->bg_pixbuf
)
486 w
= PCB
->MaxWidth
/ gport
->zoom
;
487 h
= PCB
->MaxHeight
/ gport
->zoom
;
488 x
= gport
->view_x0
/ gport
->zoom
;
489 y
= gport
->view_y0
/ gport
->zoom
;
491 if (w_scaled
!= w
|| h_scaled
!= h
)
494 g_object_unref(G_OBJECT(pixbuf
));
496 w_src
= gdk_pixbuf_get_width(ghidgui
->bg_pixbuf
);
497 h_src
= gdk_pixbuf_get_height(ghidgui
->bg_pixbuf
);
498 if (w
> w_src
&& h
> h_src
)
499 interp_type
= GDK_INTERP_NEAREST
;
501 interp_type
= GDK_INTERP_BILINEAR
;
503 pixbuf
= gdk_pixbuf_scale_simple(ghidgui
->bg_pixbuf
, w
, h
, interp_type
);
508 gdk_pixbuf_render_to_drawable(pixbuf
, gport
->drawable
, gport
->bg_gc
,
510 w
- x
, h
- y
, GDK_RGB_DITHER_NORMAL
, 0, 0);
514 ghid_invalidate_all ()
516 int eleft
, eright
, etop
, ebottom
;
522 region
.X1
= MIN(Px(0), Px(gport
->width
+ 1));
523 region
.Y1
= MIN(Py(0), Py(gport
->height
+ 1));
524 region
.X2
= MAX(Px(0), Px(gport
->width
+ 1));
525 region
.Y2
= MAX(Py(0), Py(gport
->height
+ 1));
528 eright
= Vx (PCB
->MaxWidth
);
530 ebottom
= Vy (PCB
->MaxHeight
);
545 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
546 1, 0, 0, eleft
, gport
->height
);
549 if (eright
< gport
->width
)
550 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
551 1, eright
, 0, gport
->width
- eright
, gport
->height
);
553 eright
= gport
->width
;
555 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
556 1, eleft
, 0, eright
- eleft
+ 1, etop
);
559 if (ebottom
< gport
->height
)
560 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
561 1, eleft
, ebottom
, eright
- eleft
+ 1,
562 gport
->height
- ebottom
);
564 ebottom
= gport
->height
;
566 gdk_draw_rectangle (gport
->drawable
, gport
->bg_gc
, 1,
567 eleft
, etop
, eright
- eleft
+ 1, ebottom
- etop
+ 1);
569 ghid_draw_bg_image();
571 hid_expose_callback (&ghid_hid
, ®ion
, 0);
573 if (ghidgui
->need_restore_crosshair
)
574 RestoreCrosshair (FALSE
);
575 ghidgui
->need_restore_crosshair
= FALSE
;
576 ghid_screen_update ();
581 ghid_set_layer (const char *name
, int group
, int empty
)
583 int idx
= (group
>= 0
585 max_layer
) ? PCB
->LayerGroups
.Entries
[group
][0] : group
;
587 if (idx
>= 0 && idx
< max_layer
+ 2)
588 return /*pinout ? 1 : */ PCB
->Data
->Layer
[idx
].On
;
591 switch (SL_TYPE (idx
))
594 return /* pinout ? 0 : */ PCB
->InvisibleObjectsOn
;
596 if (SL_MYSIDE (idx
) /*&& !pinout */ )
597 return TEST_FLAG (SHOWMASKFLAG
, PCB
);
600 if (SL_MYSIDE (idx
) /*|| pinout */ )
601 return PCB
->ElementOn
;
613 #define WHICH_GC(gc) (cur_mask == HID_MASK_CLEAR ? gport->mask_gc : (gc)->gc)
616 ghid_use_mask (int use_it
)
618 static int mask_seq_id
= 0;
623 if (use_it
== cur_mask
)
628 gport
->drawable
= gport
->pixmap
;
632 case HID_MASK_BEFORE
:
633 printf ("gtk doesn't support mask_before!\n");
638 gport
->mask
= gdk_pixmap_new (0, gport
->width
, gport
->height
, 1);
639 gport
->drawable
= gport
->mask
;
643 gport
->mask_gc
= gdk_gc_new (gport
->drawable
);
646 gdk_gc_set_foreground (gport
->mask_gc
, &color
);
647 gdk_draw_rectangle (gport
->drawable
, gport
->mask_gc
, TRUE
, 0, 0,
648 gport
->width
, gport
->height
);
650 gdk_gc_set_foreground (gport
->mask_gc
, &color
);
657 mask_seq
= mask_seq_id
;
659 gport
->drawable
= gport
->pixmap
;
667 ghid_extents_use_mask (int use_it
)
681 /* Config helper functions for when the user changes color preferences.
682 | set_special colors used in the gtkhid.
685 set_special_grid_color (void)
687 if (!gport
->colormap
)
689 gport
->grid_color
.red
^= gport
->bg_color
.red
;
690 gport
->grid_color
.green
^= gport
->bg_color
.green
;
691 gport
->grid_color
.blue
^= gport
->bg_color
.blue
;
692 gdk_color_alloc (gport
->colormap
, &gport
->grid_color
);
694 gdk_gc_set_foreground (gport
->grid_gc
, &gport
->grid_color
);
698 ghid_set_special_colors (HID_Attribute
* ha
)
700 if (!ha
->name
|| !ha
->value
)
702 if (!strcmp (ha
->name
, "background-color") && gport
->bg_gc
)
704 ghid_map_color_string (*(char **) ha
->value
, &gport
->bg_color
);
705 gdk_gc_set_foreground (gport
->bg_gc
, &gport
->bg_color
);
706 set_special_grid_color ();
708 else if (!strcmp (ha
->name
, "off-limit-color") && gport
->offlimits_gc
)
710 ghid_map_color_string (*(char **) ha
->value
, &gport
->offlimits_color
);
711 gdk_gc_set_foreground (gport
->offlimits_gc
, &gport
->offlimits_color
);
713 else if (!strcmp (ha
->name
, "grid-color") && gport
->grid_gc
)
715 ghid_map_color_string (*(char **) ha
->value
, &gport
->grid_color
);
716 set_special_grid_color ();
721 ghid_set_color (hidGC gc
, const char *name
)
723 static void *cache
= 0;
728 fprintf (stderr
, "%s(): name = NULL, setting to magenta\n",
733 gc
->colorname
= (char *) name
;
736 if (gport
->colormap
== 0)
737 gport
->colormap
= gtk_widget_get_colormap (gport
->top_window
);
739 if (strcmp (name
, "erase") == 0)
741 gdk_gc_set_foreground (gc
->gc
, &gport
->bg_color
);
744 else if (strcmp (name
, "drill") == 0)
746 gdk_gc_set_foreground (gc
->gc
, &gport
->offlimits_color
);
752 if (hid_cache_color (0, name
, &cval
, &cache
))
753 cc
= (ColorCache
*) cval
.ptr
;
756 cc
= (ColorCache
*) malloc (sizeof (ColorCache
));
757 memset (cc
, 0, sizeof (*cc
));
759 hid_cache_color (1, name
, &cval
, &cache
);
764 if (gdk_color_parse (name
, &cc
->color
))
765 gdk_color_alloc (gport
->colormap
, &cc
->color
);
767 gdk_color_white (gport
->colormap
, &cc
->color
);
774 cc
->xor_color
.red
= cc
->color
.red
^ gport
->bg_color
.red
;
775 cc
->xor_color
.green
= cc
->color
.green
^ gport
->bg_color
.green
;
776 cc
->xor_color
.blue
= cc
->color
.blue
^ gport
->bg_color
.blue
;
777 gdk_color_alloc (gport
->colormap
, &cc
->xor_color
);
780 gdk_gc_set_foreground (gc
->gc
, &cc
->xor_color
);
784 gdk_gc_set_foreground (gc
->gc
, &cc
->color
);
792 ghid_set_line_cap (hidGC gc
, EndCapStyle style
)
799 gc
->cap
= GDK_CAP_ROUND
;
800 gc
->join
= GDK_JOIN_ROUND
;
804 gc
->cap
= GDK_CAP_PROJECTING
;
805 gc
->join
= GDK_JOIN_MITER
;
809 gdk_gc_set_line_attributes (WHICH_GC (gc
),
810 Vz (gc
->width
), GDK_LINE_SOLID
,
815 ghid_set_line_width (hidGC gc
, int width
)
820 gdk_gc_set_line_attributes (WHICH_GC (gc
),
821 Vz (gc
->width
), GDK_LINE_SOLID
,
826 ghid_set_draw_xor (hidGC gc
, int xor)
831 gdk_gc_set_function (gc
->gc
, xor ? GDK_XOR
: GDK_COPY
);
832 ghid_set_color (gc
, gc
->colorname
);
836 ghid_set_draw_faded (hidGC gc
, int faded
)
838 printf ("ghid_set_draw_faded(%p,%d) -- not implemented\n", gc
, faded
);
842 ghid_set_line_cap_angle (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
844 printf ("ghid_set_line_cap_angle() -- not implemented\n");
854 gc
->gc
= gdk_gc_new (gport
->top_window
->window
);
855 ghid_set_color (gc
, gc
->colorname
);
856 ghid_set_line_width (gc
, gc
->width
);
857 ghid_set_line_cap (gc
, gc
->cap
);
858 ghid_set_draw_xor (gc
, gc
->xor);
860 if (gc
->mask_seq
!= mask_seq
)
863 gdk_gc_set_clip_mask (gc
->gc
, gport
->mask
);
865 gdk_gc_set_clip_mask (gc
->gc
, NULL
);
866 gc
->mask_seq
= mask_seq
;
868 gport
->u_gc
= WHICH_GC (gc
);
873 ghid_draw_line (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
875 double dx1
, dy1
, dx2
, dy2
;
877 dx1
= Vx ((double)x1
);
878 dy1
= Vy ((double)y1
);
879 dx2
= Vx ((double)x2
);
880 dy2
= Vy ((double)y2
);
882 if (! ClipLine (0, 0, gport
->width
, gport
->height
,
883 &dx1
, &dy1
, &dx2
, &dy2
, gc
->width
/ gport
->zoom
))
887 gdk_draw_line (gport
->drawable
, gport
->u_gc
, dx1
, dy1
, dx2
, dy2
);
891 ghid_draw_arc (hidGC gc
, int cx
, int cy
,
892 int xradius
, int yradius
, int start_angle
, int delta_angle
)
897 w
= gport
->width
* gport
->zoom
;
898 h
= gport
->height
* gport
->zoom
;
899 radius
= (xradius
> yradius
) ? xradius
: yradius
;
900 if (SIDE_X (cx
) < gport
->view_x0
- radius
901 || SIDE_X (cx
) > gport
->view_x0
+ w
+ radius
902 || SIDE_Y (cy
) < gport
->view_y0
- radius
903 || SIDE_Y (cy
) > gport
->view_y0
+ h
+ radius
)
912 start_angle
= 180 - start_angle
;
913 delta_angle
= - delta_angle
;
917 start_angle
= - start_angle
;
918 delta_angle
= - delta_angle
;
920 /* make sure we fall in the -180 to +180 range */
921 start_angle
= (start_angle
+ 360 + 180) % 360 - 180;
923 gdk_draw_arc (gport
->drawable
, gport
->u_gc
, 0,
924 Vx (cx
) - vrx
, Vy (cy
) - vry
,
925 vrx
* 2, vry
* 2, (start_angle
+ 180) * 64, delta_angle
* 64);
929 ghid_draw_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
934 w
= gport
->width
* gport
->zoom
;
935 h
= gport
->height
* gport
->zoom
;
937 if ((SIDE_X (x1
) < gport
->view_x0
- lw
938 && SIDE_X (x2
) < gport
->view_x0
- lw
)
939 || (SIDE_X (x1
) > gport
->view_x0
+ w
+ lw
940 && SIDE_X (x2
) > gport
->view_x0
+ w
+ lw
)
941 || (SIDE_Y (y1
) < gport
->view_y0
- lw
942 && SIDE_Y (y2
) < gport
->view_y0
- lw
)
943 || (SIDE_Y (y1
) > gport
->view_y0
+ h
+ lw
944 && SIDE_Y (y2
) > gport
->view_y0
+ h
+ lw
))
952 if (x1
> x2
) { gint xt
= x1
; x1
= x2
; x2
= xt
; }
953 if (y1
> y2
) { gint yt
= y1
; y1
= y2
; y2
= yt
; }
956 gdk_draw_rectangle (gport
->drawable
, gport
->u_gc
, FALSE
,
957 x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1);
962 ghid_fill_circle (hidGC gc
, int cx
, int cy
, int radius
)
966 w
= gport
->width
* gport
->zoom
;
967 h
= gport
->height
* gport
->zoom
;
968 if (SIDE_X (cx
) < gport
->view_x0
- radius
969 || SIDE_X (cx
) > gport
->view_x0
+ w
+ radius
970 || SIDE_Y (cy
) < gport
->view_y0
- radius
971 || SIDE_Y (cy
) > gport
->view_y0
+ h
+ radius
)
976 gdk_draw_arc (gport
->drawable
, gport
->u_gc
, TRUE
,
977 Vx (cx
) - vr
, Vy (cy
) - vr
,
978 vr
* 2, vr
* 2, 0, 360 * 64);
982 ghid_fill_polygon (hidGC gc
, int n_coords
, int *x
, int *y
)
984 static GdkPoint
*points
= 0;
985 static int npoints
= 0;
989 if (npoints
< n_coords
)
991 npoints
= n_coords
+ 1;
992 points
= MyRealloc (points
,
993 npoints
* sizeof (GdkPoint
), (char *) __FUNCTION__
);
995 for (i
= 0; i
< n_coords
; i
++)
997 points
[i
].x
= Vx (x
[i
]);
998 points
[i
].y
= Vy (y
[i
]);
1000 gdk_draw_polygon (gport
->drawable
, gport
->u_gc
, 1, points
, n_coords
);
1004 ghid_fill_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
1006 gint w
, h
, lw
, xx
, yy
;
1009 w
= gport
->width
* gport
->zoom
;
1010 h
= gport
->height
* gport
->zoom
;
1012 if ((SIDE_X (x1
) < gport
->view_x0
- lw
1013 && SIDE_X (x2
) < gport
->view_x0
- lw
)
1014 || (SIDE_X (x1
) > gport
->view_x0
+ w
+ lw
1015 && SIDE_X (x2
) > gport
->view_x0
+ w
+ lw
)
1016 || (SIDE_Y (y1
) < gport
->view_y0
- lw
1017 && SIDE_Y (y2
) < gport
->view_y0
- lw
)
1018 || (SIDE_Y (y1
) > gport
->view_y0
+ h
+ lw
1019 && SIDE_Y (y2
) > gport
->view_y0
+ h
+ lw
))
1039 gdk_draw_rectangle (gport
->drawable
, gport
->u_gc
, TRUE
,
1040 x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1);
1044 ghid_extents_draw_line (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
1046 printf ("ghid_extents_draw_line() -- not implemented\n");
1050 ghid_extents_draw_arc (hidGC gc
, int cx
, int cy
,
1051 int xradius
, int yradius
,
1052 int start_angle
, int delta_angle
)
1054 printf ("ghid_extents_draw_arc() -- not implemented\n");
1058 ghid_extents_draw_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
1060 printf ("ghid_extents_draw_rect() -- not implemented\n");
1064 ghid_extents_fill_circle (hidGC gc
, int cx
, int cy
, int radius
)
1066 printf ("ghid_extents_fill_circle() -- not implemented\n");
1070 ghid_extents_fill_polygon (hidGC gc
, int n_coords
, int *x
, int *y
)
1072 printf ("ghid_extents_fill_polygon() -- not implemented\n");
1076 ghid_extents_fill_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
1078 printf ("ghid_extents_fill_rect() -- not implemented\n");
1082 ghid_calibrate (double xval
, double yval
)
1084 printf ("ghid_calibrate() -- not implemented\n");
1087 static int ghid_gui_is_up
= 0;
1090 ghid_notify_gui_is_up ()
1096 ghid_shift_is_pressed ()
1098 GdkModifierType mask
;
1099 GHidPort
*out
= &ghid_port
;
1101 if( ! ghid_gui_is_up
)
1104 gdk_window_get_pointer (out
->drawing_area
->window
, NULL
, NULL
, &mask
);
1105 return (mask
& GDK_SHIFT_MASK
) ? TRUE
: FALSE
;
1109 ghid_control_is_pressed ()
1111 GdkModifierType mask
;
1112 GHidPort
*out
= &ghid_port
;
1114 if( ! ghid_gui_is_up
)
1117 gdk_window_get_pointer (out
->drawing_area
->window
, NULL
, NULL
, &mask
);
1118 return (mask
& GDK_CONTROL_MASK
) ? TRUE
: FALSE
;
1122 ghid_set_crosshair (int x
, int y
, int action
)
1124 if (gport
->x_crosshair
!= x
|| gport
->y_crosshair
!= y
)
1126 ghid_set_cursor_position_labels ();
1127 gport
->x_crosshair
= x
;
1128 gport
->y_crosshair
= y
;
1131 * FIXME - does this trigger the idle_proc stuff? It is in the
1132 * lesstif HID. Maybe something is needed here?
1134 * need_idle_proc ();
1140 * Pan the viewport so that the crosshair (which is in a fixed
1141 * location relative to the board) lands where the pointer
1142 * is. What happens is the crosshair is moved on the board
1143 * (see above) and then we move the board here to line it up
1144 * again. We do this by figuring out where the pointer is
1145 * in board coordinates and we know where the crosshair is
1146 * in board coordinates. Then we know how far to pan.
1148 if (action
== HID_SC_PAN_VIEWPORT
)
1150 GdkDisplay
*display
;
1152 gint pos_x
, pos_y
, xofs
, yofs
;
1154 display
= gdk_display_get_default ();
1155 screen
= gdk_display_get_default_screen (display
);
1157 /* figure out where the pointer is relative to the display */
1158 gdk_display_get_pointer (display
, NULL
, &pos_x
, &pos_y
, NULL
);
1161 * Figure out where the drawing area is on the screen so we can
1162 * figure out where the pointer is relative to the viewport.
1164 gdk_window_get_origin (gport
->drawing_area
->window
, &xofs
, &yofs
);
1171 * px = gport->view_x0 + pos_x * gport->zoom
1172 * py = gport->view_y0 + pos_y * gport->zoom
1178 * we need to shift x0 by (x - px) and y0 by (y - py)
1179 * x0 = x0 + x - (x0 + pos_x * zoom)
1184 gport
->view_x0
= x
- (gport
->view_width
- pos_x
* gport
->zoom
);
1186 gport
->view_x0
= x
- pos_x
* gport
->zoom
;
1189 gport
->view_y0
= y
- (gport
->view_height
- pos_y
* gport
->zoom
);
1191 gport
->view_y0
= y
- pos_y
* gport
->zoom
;
1195 action
= HID_SC_WARP_POINTER
;
1198 if (action
== HID_SC_WARP_POINTER
)
1200 #if GTK_CHECK_VERSION(2,8,0)
1202 GdkDisplay
*display
;
1205 display
= gdk_display_get_default ();
1206 screen
= gdk_display_get_default_screen (display
);
1209 * Figure out where the drawing area is on the screen because
1210 * gdk_display_warp_pointer will warp relative to the whole display
1211 * but the value we've been given is relative to your drawing area
1213 gdk_window_get_origin (gport
->drawing_area
->window
, &xofs
, &yofs
);
1216 * Note that under X11, gdk_display_warp_pointer is just a wrapper around XWarpPointer, but
1217 * hopefully by avoiding the direct call to an X function we might still work under windows
1218 * and other non-X11 based gdk's
1220 gdk_display_warp_pointer (display
, screen
, xofs
+ Vx2 (x
), yofs
+ Vy2 (y
));
1224 # ifdef HAVE_GDK_GDKX_H
1226 gdk_window_get_origin (gport
->drawing_area
->window
, &xofs
, &yofs
);
1227 XWarpPointer (GDK_DRAWABLE_XDISPLAY (gport
->drawing_area
->window
),
1228 None
, GDK_WINDOW_XID (gport
->drawing_area
->window
),
1230 xofs
+ Vx2 (x
), yofs
+ Vy2 (y
));
1232 # error "sorry. You need gtk+>=2.8.0 unless you are on X windows"
1246 /* We need a wrapper around the hid timer because a gtk timer needs
1247 | to return FALSE else the timer will be restarted.
1250 ghid_timer (GuiTimer
* timer
)
1252 (*timer
->func
) (timer
->user_data
);
1253 ghid_mode_cursor (Settings
.Mode
);
1254 return FALSE
; /* Turns timer off */
1258 ghid_add_timer (void (*func
) (hidval user_data
),
1259 unsigned long milliseconds
, hidval user_data
)
1261 GuiTimer
*timer
= g_new0 (GuiTimer
, 1);
1265 timer
->user_data
= user_data
;
1266 timer
->id
= gtk_timeout_add (milliseconds
, (GtkFunction
) ghid_timer
, timer
);
1267 ret
.ptr
= (void *) timer
;
1272 ghid_stop_timer (hidval timer
)
1274 void *ptr
= timer
.ptr
;
1276 gtk_timeout_remove (((GuiTimer
*) ptr
)->id
);
1282 void (*func
) ( hidval
, int, unsigned int, hidval
);
1285 GIOChannel
*channel
;
1290 /* We need a wrapper around the hid file watch to pass the correct flags
1293 ghid_watch (GIOChannel
*source
, GIOCondition condition
, gpointer data
)
1295 unsigned int pcb_condition
= 0;
1297 GuiWatch
*watch
= (GuiWatch
*)data
;
1299 if (condition
& G_IO_IN
)
1300 pcb_condition
|= PCB_WATCH_READABLE
;
1301 if (condition
& G_IO_OUT
)
1302 pcb_condition
|= PCB_WATCH_WRITABLE
;
1303 if (condition
& G_IO_ERR
)
1304 pcb_condition
|= PCB_WATCH_ERROR
;
1305 if (condition
& G_IO_HUP
)
1306 pcb_condition
|= PCB_WATCH_HANGUP
;
1308 x
.ptr
= (void *) watch
;
1309 watch
->func (x
, watch
->fd
, pcb_condition
, watch
->user_data
);
1310 ghid_mode_cursor (Settings
.Mode
);
1312 return TRUE
; /* Leave watch on */
1316 ghid_watch_file (int fd
, unsigned int condition
, void (*func
) (hidval watch
, int fd
, unsigned int condition
, hidval user_data
),
1319 GuiWatch
*watch
= g_new0 (GuiWatch
, 1);
1321 unsigned int glib_condition
= 0;
1323 if (condition
& PCB_WATCH_READABLE
)
1324 glib_condition
|= G_IO_IN
;
1325 if (condition
& PCB_WATCH_WRITABLE
)
1326 glib_condition
|= G_IO_OUT
;
1327 if (condition
& PCB_WATCH_ERROR
)
1328 glib_condition
|= G_IO_ERR
;
1329 if (condition
& PCB_WATCH_HANGUP
)
1330 glib_condition
|= G_IO_HUP
;
1333 watch
->user_data
= user_data
;
1335 watch
->channel
= g_io_channel_unix_new( fd
);
1336 watch
->id
= g_io_add_watch( watch
->channel
, glib_condition
, ghid_watch
, watch
);
1338 ret
.ptr
= (void *) watch
;
1343 ghid_unwatch_file (hidval data
)
1345 GuiWatch
*watch
= (GuiWatch
*)data
.ptr
;
1347 g_io_channel_shutdown( watch
->channel
, TRUE
, NULL
);
1348 g_io_channel_unref( watch
->channel
);
1355 void (*func
) (hidval user_data
);
1359 static gboolean
ghid_block_hook_prepare (GSource
*source
,
1361 static gboolean
ghid_block_hook_check (GSource
*source
);
1362 static gboolean
ghid_block_hook_dispatch (GSource
*source
,
1363 GSourceFunc callback
,
1364 gpointer user_data
);
1366 static GSourceFuncs ghid_block_hook_funcs
= {
1367 ghid_block_hook_prepare
,
1368 ghid_block_hook_check
,
1369 ghid_block_hook_dispatch
,
1370 NULL
// No destroy notification
1374 ghid_block_hook_prepare (GSource
*source
,
1377 hidval data
= ((BlockHookSource
*)source
)->user_data
;
1378 ((BlockHookSource
*)source
)->func( data
);
1383 ghid_block_hook_check (GSource
*source
)
1389 ghid_block_hook_dispatch (GSource
*source
,
1390 GSourceFunc callback
,
1397 ghid_add_block_hook (void (*func
) (hidval data
),
1401 BlockHookSource
*source
;
1403 source
= (BlockHookSource
*)g_source_new (&ghid_block_hook_funcs
, sizeof( BlockHookSource
));
1405 source
->func
= func
;
1406 source
->user_data
= user_data
;
1408 g_source_attach ((GSource
*)source
, NULL
);
1410 ret
.ptr
= (void *) source
;
1415 ghid_stop_block_hook (hidval mlpoll
)
1417 GSource
*source
= (GSource
*)mlpoll
.ptr
;
1418 g_source_destroy( source
);
1422 ghid_confirm_dialog (char *msg
, ...)
1426 char *cancelmsg
= NULL
, *okmsg
= NULL
;
1429 cancelmsg
= va_arg (ap
, char *);
1430 okmsg
= va_arg (ap
, char *);
1435 cancelmsg
= _("_Cancel");
1443 rv
= ghid_dialog_confirm (msg
, cancelmsg
, okmsg
);
1449 ghid_close_confirm_dialog ()
1451 switch (ghid_dialog_close_confirm ())
1453 case GUI_DIALOG_CLOSE_CONFIRM_SAVE
:
1455 if (hid_actionl ("Save", NULL
))
1457 return 0; /* Cancel */
1459 return 1; /* Close */
1462 case GUI_DIALOG_CLOSE_CONFIRM_NOSAVE
:
1464 return 1; /* Close */
1466 case GUI_DIALOG_CLOSE_CONFIRM_CANCEL
:
1469 return 0; /* Cancel */
1475 ghid_report_dialog (char *title
, char *msg
)
1477 ghid_dialog_report (title
, msg
);
1481 ghid_prompt_for (char *msg
, char *default_string
)
1485 rv
= ghid_dialog_input (msg
, default_string
);
1489 /* FIXME -- implement a proper file select dialog */
1492 ghid_fileselect (const char *title
, const char *descr
,
1493 char *default_file
, char *default_ext
,
1494 const char *history_tag
, int flags
)
1498 rv
= ghid_dialog_input (title
, default_file
);
1504 ghid_show_item (void *item
)
1506 ghid_pinout_window_show (&ghid_port
, (ElementTypePtr
) item
);
1516 ghid_progress (int so_far
, int total
, const char *message
)
1521 /* ---------------------------------------------------------------------- */
1526 "Gtk - The Gimp Toolkit",
1530 0, /* poly before */
1534 ghid_get_export_options
,
1536 ghid_parse_arguments
,
1540 ghid_invalidate_all
,
1547 ghid_set_line_width
,
1549 ghid_set_draw_faded
,
1550 ghid_set_line_cap_angle
,
1556 common_fill_pcb_polygon
,
1557 common_thindraw_pcb_polygon
,
1561 ghid_shift_is_pressed
,
1562 ghid_control_is_pressed
,
1569 ghid_add_block_hook
,
1570 ghid_stop_block_hook
,
1574 ghid_confirm_dialog
,
1575 ghid_close_confirm_dialog
,
1579 ghid_attribute_dialog
,
1585 HID ghid_extents
= {
1588 "used to calculate extents",
1592 0, /* poly before */
1596 0 /* ghid_get_export_options */ ,
1597 0 /* ghid_do_export */ ,
1598 0 /* ghid_parse_arguments */ ,
1600 0 /* ghid_invalidate_wh */ ,
1601 0 /* ghid_invalidate_lr */ ,
1602 0 /* ghid_invalidate_all */ ,
1603 0 /* ghid_set_layer */ ,
1604 0 /* ghid_make_gc */ ,
1605 0 /* ghid_destroy_gc */ ,
1606 ghid_extents_use_mask
,
1607 0 /* ghid_set_color */ ,
1608 0 /* ghid_set_line_cap */ ,
1609 0 /* ghid_set_line_width */ ,
1610 0 /* ghid_set_draw_xor */ ,
1611 0 /* ghid_set_draw_faded */ ,
1612 0 /* ghid_set_line_cap_angle */ ,
1613 ghid_extents_draw_line
,
1614 ghid_extents_draw_arc
,
1615 ghid_extents_draw_rect
,
1616 ghid_extents_fill_circle
,
1617 ghid_extents_fill_polygon
,
1618 common_fill_pcb_polygon
,
1619 0 /* ghid_extents_thindraw_pcb_polygon */ ,
1620 ghid_extents_fill_rect
,
1622 0 /* ghid_calibrate */ ,
1623 0 /* ghid_shift_is_pressed */ ,
1624 0 /* ghid_control_is_pressed */ ,
1625 0 /* ghid_get_coords */ ,
1626 0 /* ghid_set_crosshair */ ,
1627 0 /* ghid_add_timer */ ,
1628 0 /* ghid_stop_timer */ ,
1629 0 /* ghid_watch_file */ ,
1630 0 /* ghid_unwatch_file */ ,
1631 0 /* ghid_add_block_hook */ ,
1632 0 /* ghid_stop_block_hook */ ,
1636 0 /* ghid_confirm_dialog */ ,
1637 0 /* ghid_close_confirm_dialog */ ,
1638 0 /* ghid_report_dialog */ ,
1639 0 /* ghid_prompt_for */ ,
1640 0 /* ghid_attribute_dialog */ ,
1641 0 /* ghid_show_item */ ,
1643 0 /* ghid_progress */
1646 /* ------------------------------------------------------------
1648 * Actions specific to the GTK HID follow from here
1653 /* ------------------------------------------------------------ */
1654 static const char about_syntax
[] =
1657 static const char about_help
[] =
1658 "Tell the user about this version of PCB.";
1660 /* %start-doc actions About
1662 This just pops up a dialog telling the user which version of
1663 @code{pcb} they're running.
1669 About (int argc
, char **argv
, int x
, int y
)
1671 ghid_dialog_about ();
1675 /* ------------------------------------------------------------ */
1676 static const char getxy_syntax
[] =
1679 static const char getxy_help
[] =
1680 "Get a coordinate.";
1682 /* %start-doc actions GetXY
1684 Prompts the user for a coordinate, if one is not already selected.
1689 GetXY (int argc
, char **argv
, int x
, int y
)
1694 /* ---------------------------------------------------------------------- */
1696 static int PointCursor (int argc
, char **argv
, int x
, int y
)
1702 ghid_point_cursor ();
1704 ghid_mode_cursor (Settings
.Mode
);
1708 /* ---------------------------------------------------------------------- */
1711 RouteStylesChanged (int argc
, char **argv
, int x
, int y
)
1715 if (PCB
&& PCB
->RouteStyle
[0].Name
)
1716 for (n
= 0; n
< NUM_STYLES
; ++n
)
1717 ghid_route_style_set_button_label ((&PCB
->RouteStyle
[n
])->Name
, n
);
1721 /* ---------------------------------------------------------------------- */
1724 PCBChanged (int argc
, char **argv
, int x
, int y
)
1729 ghid_window_set_name_label (PCB
->Name
);
1733 RouteStylesChanged (0, NULL
, 0, 0);
1734 ghid_port_ranges_scale (TRUE
);
1735 ghid_port_ranges_pan (0, 0, FALSE
);
1736 ghid_port_ranges_zoom (0);
1737 ghid_port_ranges_changed ();
1738 ghid_sync_with_new_layout ();
1742 /* ---------------------------------------------------------------------- */
1745 LayerGroupsChanged (int argc
, char **argv
, int x
, int y
)
1747 printf ("LayerGroupsChanged -- not implemented\n");
1751 /* ---------------------------------------------------------------------- */
1754 LibraryChanged (int argc
, char **argv
, int x
, int y
)
1756 ghid_library_window_show (&ghid_port
, FALSE
);
1760 /* ---------------------------------------------------------------------- */
1763 Command (int argc
, char **argv
, int x
, int y
)
1765 ghid_handle_user_command (TRUE
);
1769 /* ---------------------------------------------------------------------- */
1772 Load (int argc
, char **argv
, int x
, int y
)
1777 static gchar
*current_element_dir
= NULL
;
1778 static gchar
*current_layout_dir
= NULL
;
1779 static gchar
*current_netlist_dir
= NULL
;
1781 /* we've been given the file name */
1783 return hid_actionv ("LoadFrom", argc
, argv
);
1785 function
= argc
? argv
[0] : "Layout";
1787 if (strcasecmp (function
, "Netlist") == 0)
1789 name
= ghid_dialog_file_select_open (_("Load netlist file"),
1790 ¤t_netlist_dir
,
1793 else if (strcasecmp (function
, "ElementToBuffer") == 0)
1795 name
= ghid_dialog_file_select_open (_("Load element to buffer"),
1796 ¤t_element_dir
,
1797 Settings
.LibraryTree
);
1799 else if (strcasecmp (function
, "LayoutToBuffer") == 0)
1801 name
= ghid_dialog_file_select_open (_("Load layout file to buffer"),
1802 ¤t_layout_dir
,
1805 else if (strcasecmp (function
, "Layout") == 0)
1807 name
= ghid_dialog_file_select_open (_("Load layout file"),
1808 ¤t_layout_dir
,
1814 if (Settings
.verbose
)
1815 fprintf (stderr
, "%s: Calling LoadFrom(%s, %s)\n", __FUNCTION__
,
1817 hid_actionl ("LoadFrom", function
, name
, NULL
);
1825 /* ---------------------------------------------------------------------- */
1826 static const char save_syntax
[] =
1828 "Save(Layout|LayoutAs)\n"
1829 "Save(AllConnections|AllUnusedPins|ElementConnections)\n"
1830 "Save(PasteBuffer)";
1832 static const char save_help
[] =
1833 "Save layout and/or element data to a user-selected file.";
1835 /* %start-doc actions Save
1837 This action is a GUI front-end to the core's @code{SaveTo} action
1838 (@pxref{SaveTo Action}). If you happen to pass a filename, like
1839 @code{SaveTo}, then @code{SaveTo} is called directly. Else, the
1840 user is prompted for a filename to save, and then @code{SaveTo} is
1841 called with that filename.
1846 Save (int argc
, char **argv
, int x
, int y
)
1852 static gchar
*current_dir
= NULL
;
1855 return hid_actionv ("SaveTo", argc
, argv
);
1857 function
= argc
? argv
[0] : "Layout";
1859 if (strcasecmp (function
, "Layout") == 0)
1861 return hid_actionl ("SaveTo", "Layout", PCB
->Filename
, NULL
);
1863 if (strcasecmp (function
, "PasteBuffer") == 0)
1864 prompt
= _("Save element as");
1866 prompt
= _("Save layout as");
1868 name
= ghid_dialog_file_select_save (prompt
,
1870 PCB
->Filename
, Settings
.FilePath
);
1875 exist
= fopen (name
, "r");
1879 if (ghid_dialog_confirm (_("File exists! Ok to overwrite?"), NULL
, NULL
))
1881 if (Settings
.verbose
)
1882 fprintf (stderr
, "Overwriting %s\n", name
);
1891 if (Settings
.verbose
)
1892 fprintf (stderr
, "%s: Calling SaveTo(%s, %s)\n",
1893 __FUNCTION__
, function
, name
);
1895 if (strcasecmp (function
, "PasteBuffer") == 0)
1896 hid_actionl ("PasteBuffer", "Save", name
, NULL
);
1900 * if we got this far and the function is Layout, then
1901 * we really needed it to be a LayoutAs. Otherwise
1902 * ActionSaveTo() will ignore the new file name we
1905 if (strcasecmp (function
, "Layout") == 0)
1906 hid_actionl ("SaveTo", "LayoutAs", name
, NULL
);
1908 hid_actionl ("SaveTo", function
, name
, NULL
);
1920 /* ---------------------------------------------------------------------- */
1921 static const char swapsides_syntax
[] =
1922 "SwapSides(|v|h|r)";
1924 static const char swapsides_help
[] =
1925 "Swaps the side of the board you're looking at.";
1927 /* %start-doc actions SwapSides
1929 This action changes the way you view the board.
1934 Flips the board over vertically (up/down).
1937 Flips the board over horizontally (left/right), like flipping pages in
1941 Rotates the board 180 degrees without changing sides.
1945 If no argument is given, the board isn't moved but the opposite side
1948 Normally, this action changes which pads and silk layer are drawn as
1949 true silk, and which are drawn as the "invisible" layer. It also
1950 determines which solder mask you see.
1952 As a special case, if the layer group for the side you're looking at
1953 is visible and currently active, and the layer group for the opposite
1954 is not visible (i.e. disabled), then this action will also swap which
1955 layer group is visible and active, effectively swapping the ``working
1956 side'' of the board.
1962 SwapSides (int argc
, char **argv
, int x
, int y
)
1967 int comp_group
= GetLayerGroupNumberByNumber (max_layer
+ COMPONENT_LAYER
);
1968 int solder_group
= GetLayerGroupNumberByNumber (max_layer
+ SOLDER_LAYER
);
1969 int active_group
= GetLayerGroupNumberByNumber (LayerStack
[0]);
1971 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[comp_group
][0]].On
;
1972 int solder_showing
=
1973 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[solder_group
][0]].On
;
1978 switch (argv
[0][0]) {
1981 ghid_flip_x
= ! ghid_flip_x
;
1986 ghid_flip_y
= ! ghid_flip_y
;
1991 ghid_flip_x
= ! ghid_flip_x
;
1992 ghid_flip_y
= ! ghid_flip_y
;
1999 /* SwapSides will swap this */
2000 Settings
.ShowSolderSide
= (ghid_flip_x
== ghid_flip_y
);
2003 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
;
2004 if (Settings
.ShowSolderSide
)
2006 if (active_group
== comp_group
&& comp_showing
&& !solder_showing
)
2008 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 0,
2010 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 1,
2016 if (active_group
== solder_group
&& solder_showing
&& !comp_showing
)
2018 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 0,
2020 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 1,
2025 /* Update coordinates so that the current location stays where it was on the
2026 other side; we need to do this since the actual flip center is the
2027 center of the board while the user expect the center would be the current
2031 flipd
= PCB
->MaxWidth
/ 2 - gport
->view_x
;
2032 ghid_port_ranges_pan (2 * flipd
, 0, TRUE
);
2036 flipd
= PCB
->MaxHeight
/ 2 - gport
->view_y
;
2037 ghid_port_ranges_pan (0, 2 * flipd
, TRUE
);
2040 ghid_invalidate_all ();
2044 /* ------------------------------------------------------------ */
2046 static const char print_syntax
[] =
2049 static const char print_help
[] =
2050 "Print the layout.";
2052 /* %start-doc actions Print
2054 This will find the default printing HID, prompt the user for its
2055 options, and print the layout.
2060 Print (int argc
, char **argv
, int x
, int y
)
2064 HID
*printer
= NULL
;
2066 hids
= hid_enumerate ();
2067 for (i
= 0; hids
[i
]; i
++)
2069 if (hids
[i
]->printer
)
2073 if (printer
== NULL
)
2075 gui
->log (_("Can't find a suitable printer HID"));
2079 /* check if layout is empty */
2080 if (!IsDataEmpty (PCB
->Data
))
2082 ghid_dialog_print (printer
);
2085 gui
->log (_("Can't print empty layout"));
2091 /* ------------------------------------------------------------ */
2093 static HID_Attribute
2094 printer_calibrate_attrs
[] = {
2095 {"Enter Values here:", "",
2096 HID_Label
, 0, 0, {0, 0, 0}, 0, 0},
2097 {"x-calibration", "X scale for calibrating your printer",
2098 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0},
2099 {"y-calibration", "Y scale for calibrating your printer",
2100 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0}
2102 static HID_Attr_Val printer_calibrate_values
[3];
2104 static const char printcalibrate_syntax
[] =
2107 static const char printcalibrate_help
[] =
2108 "Calibrate the printer.";
2110 /* %start-doc actions PrintCalibrate
2112 This will print a calibration page, which you would measure and type
2113 the measurements in, so that future printouts will be more precise.
2118 PrintCalibrate (int argc
, char **argv
, int x
, int y
)
2120 HID
*printer
= hid_find_printer ();
2121 printer
->calibrate (0.0, 0.0);
2123 if (gui
->attribute_dialog (printer_calibrate_attrs
, 3,
2124 printer_calibrate_values
,
2125 "Printer Calibration Values",
2126 "Enter calibration values for your printer"))
2128 printer
->calibrate (printer_calibrate_values
[1].real_value
,
2129 printer_calibrate_values
[2].real_value
);
2133 /* ------------------------------------------------------------ */
2136 Export (int argc
, char **argv
, int x
, int y
)
2139 /* check if layout is empty */
2140 if (!IsDataEmpty (PCB
->Data
))
2142 ghid_dialog_export ();
2145 gui
->log (_("Can't export empty layout"));
2150 /* ------------------------------------------------------------ */
2153 Benchmark (int argc
, char **argv
, int x
, int y
)
2158 GdkDisplay
*display
;
2160 display
= gdk_drawable_get_display (gport
->drawable
);
2164 region
.X2
= PCB
->MaxWidth
;
2165 region
.Y2
= PCB
->MaxHeight
;
2167 gdk_display_sync (display
);
2171 hid_expose_callback (&ghid_hid
, ®ion
, 0);
2172 gdk_display_sync (display
);
2176 while (end
- start
< 10);
2178 printf ("%g redraws per second\n", i
/ 10.0);
2183 /* ------------------------------------------------------------ */
2185 static const char center_syntax
[] =
2188 static const char center_help
[] =
2189 "Moves the pointer to the center of the window.";
2191 /* %start-doc actions Center
2193 Move the pointer to the center of the window, but only if it's
2194 currently within the window already.
2199 Center(int argc
, char **argv
, int x
, int y
)
2201 int x0
, y0
, w2
, h2
, dx
, dy
;
2206 x
= GRIDFIT_X (SIDE_X (x
), PCB
->Grid
);
2207 y
= GRIDFIT_Y (SIDE_Y (y
), PCB
->Grid
);
2209 w2
= gport
->view_width
/ 2;
2210 h2
= gport
->view_height
/ 2;
2226 dx
= (x0
- gport
->view_x0
) / gport
->zoom
;
2227 dy
= (y0
- gport
->view_y0
) / gport
->zoom
;
2228 gport
->view_x0
= x0
;
2229 gport
->view_y0
= y0
;
2234 /* Move the pointer to the center of the window, but only if it's
2235 currently within the window already. Watch out for edges,
2238 #if GTK_CHECK_VERSION(2,8,0)
2240 GdkDisplay
*display
;
2244 display
= gdk_display_get_default ();
2245 screen
= gdk_display_get_default_screen (display
);
2247 /* figure out where the pointer is and then move it from there by the specified delta */
2248 gdk_display_get_pointer (display
, NULL
, &cx
, &cy
, NULL
);
2249 gdk_display_warp_pointer (display
, screen
, cx
- dx
, cy
- dy
);
2252 * Note that under X11, gdk_display_warp_pointer is just a wrapper around XWarpPointer, but
2253 * hopefully by avoiding the direct call to an X function we might still work under windows
2254 * and other non-X11 based gdk's
2258 # ifdef HAVE_GDK_GDKX_H
2261 Window w_src
, w_dst
;
2262 w_src
= GDK_WINDOW_XID (gport
->drawing_area
->window
);
2265 /* don't warp with the auto drc - that creates auto-scroll chaos */
2266 if (TEST_FLAG (AUTODRCFLAG
, PCB
) && Settings
.Mode
== LINE_MODE
2267 && Crosshair
.AttachedLine
.State
!= STATE_FIRST
)
2270 XWarpPointer (GDK_DRAWABLE_XDISPLAY (gport
->drawing_area
->window
),
2275 /* XWarpPointer creates Motion events normally bound to
2276 * EventMoveCrosshair.
2277 * We don't do any updates when EventMoveCrosshair
2278 * is called the next time to prevent from rounding errors
2281 * IgnoreMotionEvents = ignore;
2290 /* ------------------------------------------------------------ */
2291 static const char cursor_syntax
[] =
2292 "Cursor(Type,DeltaUp,DeltaRight,Units)";
2294 static const char cursor_help
[] =
2297 /* %start-doc actions Cursor
2299 This action moves the mouse cursor. Unlike other actions which take
2300 coordinates, this action's coordinates are always relative to the
2301 user's view of the board. Thus, a positive @var{DeltaUp} may move the
2302 cursor towards the board origin if the board is inverted.
2304 Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the
2305 viewport to move such that the crosshair is under the mouse cursor.
2306 @samp{Warp} causes the mouse cursor to move to be above the crosshair.
2308 @var{Units} can be one of the following:
2314 The cursor is moved by that amount, in board units.
2317 The cursor is moved by that many grid points.
2320 The values are percentages of the viewport's view. Thus, a pan of
2321 @samp{100} would scroll the viewport by exactly the width of the
2325 The values are percentages of the board size. Thus, a move of
2326 @samp{50,50} moves you halfway across the board.
2333 CursorAction(int argc
, char **argv
, int x
, int y
)
2335 int pan_warp
= HID_SC_DO_NOTHING
;
2337 double xu
= 0.0, yu
= 0.0;
2342 if (strcasecmp (argv
[0], "pan") == 0)
2343 pan_warp
= HID_SC_PAN_VIEWPORT
;
2344 else if (strcasecmp (argv
[0], "warp") == 0)
2345 pan_warp
= HID_SC_WARP_POINTER
;
2349 dx
= strtod (argv
[1], 0);
2352 dy
= strtod (argv
[2], 0);
2357 * xu and yu are the scale factors that we multiply dx and dy by to
2358 * come up with PCB internal units.
2360 if (strncasecmp (argv
[3], "mm", 2) == 0)
2361 xu
= yu
= MM_TO_COOR
;
2362 else if (strncasecmp (argv
[3], "mil", 3) == 0)
2364 else if (strncasecmp (argv
[3], "grid", 4) == 0)
2365 xu
= yu
= PCB
->Grid
;
2366 else if (strncasecmp (argv
[3], "view", 4) == 0)
2368 xu
= gport
->view_width
/ 100.0;
2369 yu
= gport
->view_height
/ 100.0;
2371 else if (strncasecmp (argv
[3], "board", 4) == 0)
2373 xu
= PCB
->MaxWidth
/ 100.0;
2374 yu
= PCB
->MaxHeight
/ 100.0;
2377 EventMoveCrosshair (Crosshair
.X
+(int)(dx
*xu
), Crosshair
.Y
+(int)(dy
*yu
));
2378 gui
->set_crosshair (Crosshair
.X
, Crosshair
.Y
, pan_warp
);
2382 /* ------------------------------------------------------------ */
2384 static const char dowindows_syntax
[] =
2385 "DoWindows(1|2|3|4)\n"
2386 "DoWindows(Layout|Library|Log|Netlist|Preferences)";
2388 static const char dowindows_help
[] =
2389 "Open various GUI windows.";
2391 /* %start-doc actions DoWindows
2397 Open the layout window. Since the layout window is always shown
2398 anyway, this has no effect.
2402 Open the library window.
2406 Open the log window.
2410 Open the netlist window.
2414 Open the preferences window.
2421 DoWindows (int argc
, char **argv
, int x
, int y
)
2423 char *a
= argc
== 1 ? argv
[0] : "";
2425 if (strcmp (a
, "1") == 0 || strcasecmp (a
, "Layout") == 0)
2428 else if (strcmp (a
, "2") == 0 || strcasecmp (a
, "Library") == 0)
2430 ghid_library_window_show (gport
, TRUE
);
2432 else if (strcmp (a
, "3") == 0 || strcasecmp (a
, "Log") == 0)
2434 ghid_log_window_show (TRUE
);
2436 else if (strcmp (a
, "4") == 0 || strcasecmp (a
, "Netlist") == 0)
2438 ghid_netlist_window_show (gport
, TRUE
);
2440 else if (strcmp (a
, "5") == 0 || strcasecmp (a
, "Preferences") == 0)
2442 ghid_config_window_show ();
2452 /* ------------------------------------------------------------ */
2453 static const char setunits_syntax
[] =
2456 static const char setunits_help
[] =
2457 "Set the default measurement units.";
2459 /* %start-doc actions SetUnits
2464 Sets the display units to mils (1/1000 inch).
2467 Sets the display units to millimeters.
2474 SetUnits (int argc
, char **argv
, int x
, int y
)
2478 if (strcmp (argv
[0], "mil") == 0)
2479 Settings
.grid_units_mm
= 0;
2480 if (strcmp (argv
[0], "mm") == 0)
2481 Settings
.grid_units_mm
= 1;
2483 ghid_config_handle_units_changed ();
2485 ghid_set_status_line_label ();
2488 * lesstif_sizes_reset ();
2489 * lesstif_styles_update_values ();
2494 /* ------------------------------------------------------------ */
2495 static const char popup_syntax
[] =
2496 "Popup(MenuName, [Button])";
2498 static const char popup_help
[] =
2499 "Bring up the popup menu specified by @code{MenuName}.\n"
2500 "If called by a mouse event then the mouse button number\n"
2501 "must be specified as the optional second argument.";
2503 /* %start-doc actions Popup
2505 This just pops up the specified menu. The menu must have been defined
2506 as a named subresource of the Popups resource in the menu resource
2507 file. If called as a response to a mouse button click, the mouse
2508 button number must be specified as the second argument.
2514 Popup (int argc
, char **argv
, int x
, int y
)
2520 if (argc
!= 1 && argc
!= 2)
2526 button
= atoi (argv
[1]);
2528 if ( (element
= (char *) malloc ( (strlen (argv
[0]) + 2) * sizeof (char))) == NULL
)
2530 fprintf (stderr
, "Popup(): malloc failed\n");
2534 sprintf (element
, "/%s", argv
[0]);
2535 printf ("Loading popup \"%s\". Button = %u\n", element
, button
);
2537 menu
= gtk_ui_manager_get_widget (ghidgui
->ui_manager
, element
);
2540 if (! GTK_IS_MENU (menu
))
2542 Message ("The specified popup menu \"%s\" has not been defined.\n", argv
[0]);
2547 ghidgui
->in_popup
= TRUE
;
2548 gtk_widget_grab_focus (ghid_port
.drawing_area
);
2549 gtk_menu_popup (GTK_MENU (menu
), NULL
, NULL
, NULL
, NULL
, 0,
2550 gtk_get_current_event_time());
2556 Busy (int argc
, char **argv
, int x
, int y
)
2558 ghid_watch_cursor ();
2562 HID_Action ghid_main_action_list
[] = {
2563 {"About", 0, About
, about_help
, about_syntax
},
2564 {"Benchmark", 0, Benchmark
},
2566 {"Center", "Click on a location to center", Center
, center_help
, center_syntax
},
2567 {"Command", 0, Command
},
2568 {"Cursor", 0, CursorAction
, cursor_help
, cursor_syntax
},
2569 {"DoWindows", 0, DoWindows
, dowindows_help
, dowindows_syntax
},
2570 {"Export", 0, Export
},
2571 {"GetXY", "", GetXY
, getxy_help
, getxy_syntax
},
2572 {"LayerGroupsChanged", 0, LayerGroupsChanged
},
2573 {"LibraryChanged", 0, LibraryChanged
},
2575 {"PCBChanged", 0, PCBChanged
},
2576 {"PointCursor", 0, PointCursor
},
2577 {"Popup", 0, Popup
, popup_help
, popup_syntax
},
2579 print_help
, print_syntax
},
2580 {"PrintCalibrate", 0, PrintCalibrate
,
2581 printcalibrate_help
, printcalibrate_syntax
},
2582 {"RouteStylesChanged", 0, RouteStylesChanged
},
2583 {"Save", 0, Save
, save_help
, save_syntax
},
2584 {"SetUnits", 0, SetUnits
, setunits_help
, setunits_syntax
},
2585 {"SwapSides", 0, SwapSides
, swapsides_help
, swapsides_syntax
},
2586 {"Zoom", "Click on zoom focus", Zoom
, zoom_help
, zoom_syntax
}
2589 REGISTER_ACTIONS (ghid_main_action_list
)
2603 HID_Flag ghid_main_flag_list
[] = {
2604 {"flip_x", flag_flipx
, 0},
2605 {"flip_y", flag_flipy
, 0}
2608 REGISTER_FLAGS (ghid_main_flag_list
)
2610 #include "dolists.h"
2613 * We will need these for finding the windows installation
2614 * directory. Without that we can't find our fonts and
2615 * footprint libraries.
2618 #include <windows.h>
2630 tmps
= g_win32_get_package_installation_directory (PACKAGE
"-" VERSION
, NULL
);
2631 #define REST_OF_PATH G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S PACKAGE
2632 share_dir
= (char *) malloc(strlen(tmps
) +
2633 strlen(REST_OF_PATH
) +
2635 sprintf (share_dir
, "%s%s", tmps
, REST_OF_PATH
);
2638 printf ("\"Share\" installation path is \"%s\"\n", share_dir
);
2641 hid_register_hid (&ghid_hid
);
2642 apply_default_hid (&ghid_extents
, &ghid_hid
);
2643 #include "gtk_lists.h"