17 #include "crosshair.h"
27 #include "../hidint.h"
31 #if !GTK_CHECK_VERSION(2,8,0) && defined(HAVE_GDK_GDKX_H)
35 #ifdef HAVE_LIBDMALLOC
46 static void zoom_to (double factor
, int x
, int y
);
47 static void zoom_by (double factor
, int x
, int y
);
49 /* Sets gport->u_gc to the "right" GC to use (wrt mask or window)
51 #define USE_GC(gc) if (!use_gc(gc)) return
53 static int cur_mask
= -1;
54 static int mask_seq
= 0;
56 int ghid_flip_x
= 0, ghid_flip_y
= 0;
58 /* ------------------------------------------------------------ */
60 /* Px converts view->pcb, Vx converts pcb->view */
67 rv
= (PCB
->MaxWidth
- x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
69 rv
= (x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
76 return (x
- gport
->view_x0
) / gport
->zoom
+ 0.5;
84 rv
= (PCB
->MaxHeight
- y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
86 rv
= (y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
93 return (y
- gport
->view_y0
) / gport
->zoom
+ 0.5;
99 return z
/ gport
->zoom
+ 0.5;
105 int rv
= x
* gport
->zoom
+ gport
->view_x0
;
107 rv
= PCB
->MaxWidth
- (x
* gport
->zoom
+ gport
->view_x0
);
114 int rv
= y
* gport
->zoom
+ gport
->view_y0
;
116 rv
= PCB
->MaxHeight
- (y
* gport
->zoom
+ gport
->view_y0
);
123 return (z
* gport
->zoom
);
126 /* ------------------------------------------------------------ */
133 * don't pan so far to the right that we see way past the right
136 if (gport
->view_x0
> PCB
->MaxWidth
- gport
->view_width
)
137 gport
->view_x0
= PCB
->MaxWidth
- gport
->view_width
;
140 * don't pan so far down that we see way past the bottom edge of
143 if (gport
->view_y0
> PCB
->MaxHeight
- gport
->view_height
)
144 gport
->view_y0
= PCB
->MaxHeight
- gport
->view_height
;
146 /* don't view above or to the left of the board... ever */
147 if (gport
->view_x0
< 0)
150 if (gport
->view_y0
< 0)
154 /* if we can see the entire board and some, then zoom to fit */
155 if (gport
->view_width
> PCB
->MaxWidth
&&
156 gport
->view_height
> PCB
->MaxHeight
)
162 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view_x0
);
163 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view_y0
);
165 ghid_invalidate_all ();
169 /* ------------------------------------------------------------ */
171 static const char zoom_syntax
[] =
176 static const char zoom_help
[] =
177 "Various zoom factor changes.";
179 /* %start-doc actions Zoom
180 Changes the zoom (magnification) of the view of the board. If no
181 arguments are passed, the view is scaled such that the board just fits
182 inside the visible window (i.e. ``view all''). Otherwise,
183 @var{factor} specifies a change in zoom factor. It may be prefixed by
184 @code{+}, @code{-}, or @code{=} to change how the zoom factor is
185 modified. The @var{factor} is a floating point number, such as
186 @code{1.5} or @code{0.75}.
191 Values greater than 1.0 cause the board to be drawn smaller; more of
192 the board will be visible. Values between 0.0 and 1.0 cause the board
193 to be drawn bigger; less of the board will be visible.
196 Values greater than 1.0 cause the board to be drawn bigger; less of
197 the board will be visible. Values between 0.0 and 1.0 cause the board
198 to be drawn smaller; more of the board will be visible.
202 The @var{factor} is an absolute zoom factor; the unit for this value
203 is "PCB units per screen pixel". Since PCB units are 0.01 mil, a
204 @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI,
205 about the actual resolution of most screens - resulting in an "actual
206 size" board. Similarly, a @var{factor} of 100 gives you a 10x actual
211 Note that zoom factors of zero are silently ignored.
218 Zoom (int argc
, char **argv
, int x
, int y
)
227 if (x
== 0 && y
== 0)
229 x
= gport
->view_width
/ 2;
230 y
= gport
->view_height
/ 2;
234 /* Px converts view->pcb, Vx converts pcb->view */
241 zoom_to (1000000, 0, 0);
246 if (*vp
== '+' || *vp
== '-' || *vp
== '=')
255 zoom_by (1 / v
, x
, y
);
263 /* this needs to set the scale factor absolutely*/
274 zoom_to (double new_zoom
, int x
, int y
)
276 double max_zoom
, xfrac
, yfrac
;
280 * zoom value is PCB units per screen pixel. Larger numbers mean zooming
281 * out - the largest value means you are looking at the whole board.
283 * PCB units per screen pixel
285 * gport->view_width and gport->view_height are in PCB coordinates
289 printf ("\nzoom_to( %g, %d, %d)\n", new_zoom
, x
, y
);
292 xfrac
= (double) x
/ (double) gport
->view_width
;
293 yfrac
= (double) y
/ (double) gport
->view_height
;
300 /* Find the zoom that would just make the entire board fit */
301 max_zoom
= PCB
->MaxWidth
/ gport
->width
;
302 if (max_zoom
< PCB
->MaxHeight
/ gport
->height
)
303 max_zoom
= PCB
->MaxHeight
/ gport
->height
;
306 printf ("zoom_to(): max_zoom = %g\n", max_zoom
);
310 * clip the zooming so we can never have more than 1 pixel per PCB
311 * unit and never zoom out more than viewing the entire board
316 if (new_zoom
> max_zoom
)
320 printf ("max_zoom = %g, xfrac = %g, yfrac = %g, new_zoom = %g\n",
321 max_zoom
, xfrac
, yfrac
, new_zoom
);
324 /* find center x and y */
325 cx
= gport
->view_x0
+ gport
->view_width
* xfrac
* gport
->zoom
;
326 cy
= gport
->view_y0
+ gport
->view_height
* yfrac
* gport
->zoom
;
329 printf ("zoom_to(): x0 = %d, cx = %d\n", gport
->view_x0
, cx
);
330 printf ("zoom_to(): y0 = %d, cy = %d\n", gport
->view_y0
, cy
);
333 if (gport
->zoom
!= new_zoom
)
338 xtmp
= (gport
->view_x
- gport
->view_x0
) / (gdouble
) gport
->view_width
;
339 ytmp
= (gport
->view_y
- gport
->view_y0
) / (gdouble
) gport
->view_height
;
341 gport
->zoom
= new_zoom
;
342 pixel_slop
= new_zoom
;
343 ghid_port_ranges_scale(FALSE
);
345 x0
= gport
->view_x
- xtmp
* gport
->view_width
;
350 y0
= gport
->view_y
- ytmp
* gport
->view_height
;
355 ghidgui
->adjustment_changed_holdoff
= TRUE
;
356 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view_x0
);
357 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view_y0
);
358 ghidgui
->adjustment_changed_holdoff
= FALSE
;
360 ghid_port_ranges_changed();
364 printf ("zoom_to(): new x0 = %d\n", gport
->view_x0
);
365 printf ("zoom_to(): new y0 = %d\n", gport
->view_y0
);
367 ghid_set_status_line_label ();
371 zoom_by (double factor
, int x
, int y
)
374 printf ("\nzoom_by( %g, %d, %d). old gport->zoom = %g\n",
375 factor
, x
, y
, gport
->zoom
);
377 zoom_to (gport
->zoom
* factor
, x
, y
);
380 /* ------------------------------------------------------------ */
385 static GdkPoint
*points
= 0;
386 static int npoints
= 0;
387 int x1
, y1
, x2
, y2
, n
, i
;
390 if (!Settings
.DrawGrid
)
392 if (Vz (PCB
->Grid
) < MIN_GRID_DISTANCE
)
396 if (gdk_color_parse (Settings
.GridColor
, &gport
->grid_color
))
398 gport
->grid_color
.red
^= gport
->bg_color
.red
;
399 gport
->grid_color
.green
^= gport
->bg_color
.green
;
400 gport
->grid_color
.blue
^= gport
->bg_color
.blue
;
401 gdk_color_alloc (gport
->colormap
, &gport
->grid_color
);
403 gport
->grid_gc
= gdk_gc_new (gport
->drawable
);
404 gdk_gc_set_function (gport
->grid_gc
, GDK_XOR
);
405 gdk_gc_set_foreground (gport
->grid_gc
, &gport
->grid_color
);
407 x1
= GRIDFIT_X (SIDE_X (gport
->view_x0
), PCB
->Grid
);
408 y1
= GRIDFIT_Y (SIDE_Y (gport
->view_y0
), PCB
->Grid
);
409 x2
= GRIDFIT_X (SIDE_X (gport
->view_x0
+ gport
->view_width
- 1), PCB
->Grid
);
410 y2
= GRIDFIT_Y (SIDE_Y (gport
->view_y0
+ gport
->view_height
- 1), PCB
->Grid
);
427 if (Vx (x2
) >= gport
->width
)
429 if (Vy (y2
) >= gport
->height
)
431 n
= (int) ((x2
- x1
) / PCB
->Grid
+ 0.5) + 1;
436 MyRealloc (points
, npoints
* sizeof (GdkPoint
), "gtk_draw_grid");
439 for (x
= x1
; x
<= x2
; x
+= PCB
->Grid
)
441 points
[n
].x
= Vx (x
);
444 for (y
= y1
; y
<= y2
; y
+= PCB
->Grid
)
447 for (i
= 0; i
< n
; i
++)
449 gdk_draw_points (gport
->drawable
, gport
->grid_gc
, points
, n
);
453 /* ------------------------------------------------------------ */
456 ghid_get_export_options (int *n_ret
)
463 ghid_invalidate_wh (int x
, int y
, int width
, int height
, int last
)
465 ghid_invalidate_all ();
469 ghid_invalidate_lr (int left
, int right
, int top
, int bottom
, int last
)
471 ghid_invalidate_all ();
475 ghid_draw_bg_image(void)
477 static GdkPixbuf
*pixbuf
;
478 GdkInterpType interp_type
;
479 gint x
, y
, w
, h
, w_src
, h_src
;
480 static gint w_scaled
, h_scaled
;
482 if (!ghidgui
->bg_pixbuf
)
485 w
= PCB
->MaxWidth
/ gport
->zoom
;
486 h
= PCB
->MaxHeight
/ gport
->zoom
;
487 x
= gport
->view_x0
/ gport
->zoom
;
488 y
= gport
->view_y0
/ gport
->zoom
;
490 if (w_scaled
!= w
|| h_scaled
!= h
)
493 g_object_unref(G_OBJECT(pixbuf
));
495 w_src
= gdk_pixbuf_get_width(ghidgui
->bg_pixbuf
);
496 h_src
= gdk_pixbuf_get_height(ghidgui
->bg_pixbuf
);
497 if (w
> w_src
&& h
> h_src
)
498 interp_type
= GDK_INTERP_NEAREST
;
500 interp_type
= GDK_INTERP_BILINEAR
;
502 pixbuf
= gdk_pixbuf_scale_simple(ghidgui
->bg_pixbuf
, w
, h
, interp_type
);
507 gdk_pixbuf_render_to_drawable(pixbuf
, gport
->drawable
, gport
->bg_gc
,
509 w
- x
, h
- y
, GDK_RGB_DITHER_NORMAL
, 0, 0);
513 ghid_invalidate_all ()
515 int eleft
, eright
, etop
, ebottom
;
521 region
.X1
= MIN(Px(0), Px(gport
->width
+ 1));
522 region
.Y1
= MIN(Py(0), Py(gport
->height
+ 1));
523 region
.X2
= MAX(Px(0), Px(gport
->width
+ 1));
524 region
.Y2
= MAX(Py(0), Py(gport
->height
+ 1));
527 eright
= Vx (PCB
->MaxWidth
);
529 ebottom
= Vy (PCB
->MaxHeight
);
544 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
545 1, 0, 0, eleft
, gport
->height
);
548 if (eright
< gport
->width
)
549 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
550 1, eright
, 0, gport
->width
- eright
, gport
->height
);
552 eright
= gport
->width
;
554 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
555 1, eleft
, 0, eright
- eleft
+ 1, etop
);
558 if (ebottom
< gport
->height
)
559 gdk_draw_rectangle (gport
->drawable
, gport
->offlimits_gc
,
560 1, eleft
, ebottom
, eright
- eleft
+ 1,
561 gport
->height
- ebottom
);
563 ebottom
= gport
->height
;
565 gdk_draw_rectangle (gport
->drawable
, gport
->bg_gc
, 1,
566 eleft
, etop
, eright
- eleft
+ 1, ebottom
- etop
+ 1);
568 ghid_draw_bg_image();
570 hid_expose_callback (&ghid_hid
, ®ion
, 0);
572 if (ghidgui
->need_restore_crosshair
)
573 RestoreCrosshair (FALSE
);
574 ghidgui
->need_restore_crosshair
= FALSE
;
575 ghid_screen_update ();
580 ghid_set_layer (const char *name
, int group
)
582 int idx
= (group
>= 0
584 max_layer
) ? PCB
->LayerGroups
.Entries
[group
][0] : group
;
586 if (idx
>= 0 && idx
< max_layer
+ 2)
587 return /*pinout ? 1 : */ PCB
->Data
->Layer
[idx
].On
;
590 switch (SL_TYPE (idx
))
593 return /* pinout ? 0 : */ PCB
->InvisibleObjectsOn
;
595 if (SL_MYSIDE (idx
) /*&& !pinout */ )
596 return TEST_FLAG (SHOWMASKFLAG
, PCB
);
599 if (SL_MYSIDE (idx
) /*|| pinout */ )
600 return PCB
->ElementOn
;
612 #define WHICH_GC(gc) (cur_mask == HID_MASK_CLEAR ? gport->mask_gc : (gc)->gc)
615 ghid_use_mask (int use_it
)
617 static int mask_seq_id
= 0;
622 if (use_it
== cur_mask
)
627 gport
->drawable
= gport
->pixmap
;
631 case HID_MASK_BEFORE
:
632 printf ("gtk doesn't support mask_before!\n");
637 gport
->mask
= gdk_pixmap_new (0, gport
->width
, gport
->height
, 1);
638 gport
->drawable
= gport
->mask
;
642 gport
->mask_gc
= gdk_gc_new (gport
->drawable
);
645 gdk_gc_set_foreground (gport
->mask_gc
, &color
);
646 gdk_draw_rectangle (gport
->drawable
, gport
->mask_gc
, TRUE
, 0, 0,
647 gport
->width
, gport
->height
);
649 gdk_gc_set_foreground (gport
->mask_gc
, &color
);
656 mask_seq
= mask_seq_id
;
658 gport
->drawable
= gport
->pixmap
;
666 ghid_extents_use_mask (int use_it
)
680 /* Config helper functions for when the user changes color preferences.
681 | set_special colors used in the gtkhid.
684 set_special_grid_color (void)
686 if (!gport
->colormap
)
688 gport
->grid_color
.red
^= gport
->bg_color
.red
;
689 gport
->grid_color
.green
^= gport
->bg_color
.green
;
690 gport
->grid_color
.blue
^= gport
->bg_color
.blue
;
691 gdk_color_alloc (gport
->colormap
, &gport
->grid_color
);
693 gdk_gc_set_foreground (gport
->grid_gc
, &gport
->grid_color
);
697 ghid_set_special_colors (HID_Attribute
* ha
)
699 if (!ha
->name
|| !ha
->value
)
701 if (!strcmp (ha
->name
, "background-color") && gport
->bg_gc
)
703 ghid_map_color_string (*(char **) ha
->value
, &gport
->bg_color
);
704 gdk_gc_set_foreground (gport
->bg_gc
, &gport
->bg_color
);
705 set_special_grid_color ();
707 else if (!strcmp (ha
->name
, "off-limit-color") && gport
->offlimits_gc
)
709 ghid_map_color_string (*(char **) ha
->value
, &gport
->offlimits_color
);
710 gdk_gc_set_foreground (gport
->offlimits_gc
, &gport
->offlimits_color
);
712 else if (!strcmp (ha
->name
, "grid-color") && gport
->grid_gc
)
714 ghid_map_color_string (*(char **) ha
->value
, &gport
->grid_color
);
715 set_special_grid_color ();
720 ghid_set_color (hidGC gc
, const char *name
)
722 static void *cache
= 0;
727 fprintf (stderr
, "%s(): name = NULL, setting to magenta\n",
732 gc
->colorname
= (char *) name
;
735 if (gport
->colormap
== 0)
736 gport
->colormap
= gtk_widget_get_colormap (gport
->top_window
);
738 if (strcmp (name
, "erase") == 0)
740 gdk_gc_set_foreground (gc
->gc
, &gport
->bg_color
);
743 else if (strcmp (name
, "drill") == 0)
745 gdk_gc_set_foreground (gc
->gc
, &gport
->offlimits_color
);
751 if (hid_cache_color (0, name
, &cval
, &cache
))
752 cc
= (ColorCache
*) cval
.ptr
;
755 cc
= (ColorCache
*) malloc (sizeof (ColorCache
));
756 memset (cc
, 0, sizeof (*cc
));
758 hid_cache_color (1, name
, &cval
, &cache
);
763 if (gdk_color_parse (name
, &cc
->color
))
764 gdk_color_alloc (gport
->colormap
, &cc
->color
);
766 gdk_color_white (gport
->colormap
, &cc
->color
);
773 cc
->xor_color
.red
= cc
->color
.red
^ gport
->bg_color
.red
;
774 cc
->xor_color
.green
= cc
->color
.green
^ gport
->bg_color
.green
;
775 cc
->xor_color
.blue
= cc
->color
.blue
^ gport
->bg_color
.blue
;
776 gdk_color_alloc (gport
->colormap
, &cc
->xor_color
);
779 gdk_gc_set_foreground (gc
->gc
, &cc
->xor_color
);
783 gdk_gc_set_foreground (gc
->gc
, &cc
->color
);
791 ghid_set_line_cap (hidGC gc
, EndCapStyle style
)
798 gc
->cap
= GDK_CAP_ROUND
;
799 gc
->join
= GDK_JOIN_ROUND
;
803 gc
->cap
= GDK_CAP_PROJECTING
;
804 gc
->join
= GDK_JOIN_MITER
;
808 gdk_gc_set_line_attributes (WHICH_GC (gc
),
809 Vz (gc
->width
), GDK_LINE_SOLID
,
814 ghid_set_line_width (hidGC gc
, int width
)
819 gdk_gc_set_line_attributes (WHICH_GC (gc
),
820 Vz (gc
->width
), GDK_LINE_SOLID
,
825 ghid_set_draw_xor (hidGC gc
, int xor)
830 gdk_gc_set_function (gc
->gc
, xor ? GDK_XOR
: GDK_COPY
);
831 ghid_set_color (gc
, gc
->colorname
);
835 ghid_set_draw_faded (hidGC gc
, int faded
)
837 printf ("ghid_set_draw_faded(%p,%d) -- not implemented\n", gc
, faded
);
841 ghid_set_line_cap_angle (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
843 printf ("ghid_set_line_cap_angle() -- not implemented\n");
853 gc
->gc
= gdk_gc_new (gport
->top_window
->window
);
854 ghid_set_color (gc
, gc
->colorname
);
855 ghid_set_line_width (gc
, gc
->width
);
856 ghid_set_line_cap (gc
, gc
->cap
);
857 ghid_set_draw_xor (gc
, gc
->xor);
859 if (gc
->mask_seq
!= mask_seq
)
862 gdk_gc_set_clip_mask (gc
->gc
, gport
->mask
);
864 gdk_gc_set_clip_mask (gc
->gc
, NULL
);
865 gc
->mask_seq
= mask_seq
;
867 gport
->u_gc
= WHICH_GC (gc
);
872 ghid_draw_line (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
874 double dx1
, dy1
, dx2
, dy2
;
876 dx1
= Vx ((double)x1
);
877 dy1
= Vy ((double)y1
);
878 dx2
= Vx ((double)x2
);
879 dy2
= Vy ((double)y2
);
881 if (! ClipLine (0, 0, gport
->width
, gport
->height
,
882 &dx1
, &dy1
, &dx2
, &dy2
, gc
->width
/ gport
->zoom
))
886 gdk_draw_line (gport
->drawable
, gport
->u_gc
, dx1
, dy1
, dx2
, dy2
);
890 ghid_draw_arc (hidGC gc
, int cx
, int cy
,
891 int xradius
, int yradius
, int start_angle
, int delta_angle
)
896 w
= gport
->width
* gport
->zoom
;
897 h
= gport
->height
* gport
->zoom
;
898 radius
= (xradius
> yradius
) ? xradius
: yradius
;
899 if (SIDE_X (cx
) < gport
->view_x0
- radius
900 || SIDE_X (cx
) > gport
->view_x0
+ w
+ radius
901 || SIDE_Y (cy
) < gport
->view_y0
- radius
902 || SIDE_Y (cy
) > gport
->view_y0
+ h
+ radius
)
910 /* make sure we fall in the -180 to +180 range */
911 start_angle
= (start_angle
+ 360 + 180) % 360 - 180;
914 start_angle
= 180 - start_angle
;
915 delta_angle
= - delta_angle
;
919 start_angle
= - start_angle
;
920 delta_angle
= - delta_angle
;
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
,
1559 ghid_shift_is_pressed
,
1560 ghid_control_is_pressed
,
1567 ghid_add_block_hook
,
1568 ghid_stop_block_hook
,
1572 ghid_confirm_dialog
,
1573 ghid_close_confirm_dialog
,
1577 ghid_attribute_dialog
,
1583 HID ghid_extents
= {
1586 "used to calculate extents",
1590 0, /* poly before */
1594 0 /* ghid_get_export_options */ ,
1595 0 /* ghid_do_export */ ,
1596 0 /* ghid_parse_arguments */ ,
1598 0 /* ghid_invalidate_wh */ ,
1599 0 /* ghid_invalidate_lr */ ,
1600 0 /* ghid_invalidate_all */ ,
1601 0 /* ghid_set_layer */ ,
1602 0 /* ghid_make_gc */ ,
1603 0 /* ghid_destroy_gc */ ,
1604 ghid_extents_use_mask
,
1605 0 /* ghid_set_color */ ,
1606 0 /* ghid_set_line_cap */ ,
1607 0 /* ghid_set_line_width */ ,
1608 0 /* ghid_set_draw_xor */ ,
1609 0 /* ghid_set_draw_faded */ ,
1610 0 /* ghid_set_line_cap_angle */ ,
1611 ghid_extents_draw_line
,
1612 ghid_extents_draw_arc
,
1613 ghid_extents_draw_rect
,
1614 ghid_extents_fill_circle
,
1615 ghid_extents_fill_polygon
,
1616 ghid_extents_fill_rect
,
1618 0 /* ghid_calibrate */ ,
1619 0 /* ghid_shift_is_pressed */ ,
1620 0 /* ghid_control_is_pressed */ ,
1621 0 /* ghid_get_coords */ ,
1622 0 /* ghid_set_crosshair */ ,
1623 0 /* ghid_add_timer */ ,
1624 0 /* ghid_stop_timer */ ,
1625 0 /* ghid_watch_file */ ,
1626 0 /* ghid_unwatch_file */ ,
1627 0 /* ghid_add_block_hook */ ,
1628 0 /* ghid_stop_block_hook */ ,
1632 0 /* ghid_confirm_dialog */ ,
1633 0 /* ghid_close_confirm_dialog */ ,
1634 0 /* ghid_report_dialog */ ,
1635 0 /* ghid_prompt_for */ ,
1636 0 /* ghid_attribute_dialog */ ,
1637 0 /* ghid_show_item */ ,
1639 0 /* ghid_progress */
1642 /* ------------------------------------------------------------
1644 * Actions specific to the GTK HID follow from here
1649 /* ------------------------------------------------------------ */
1650 static const char about_syntax
[] =
1653 static const char about_help
[] =
1654 "Tell the user about this version of PCB.";
1656 /* %start-doc actions About
1658 This just pops up a dialog telling the user which version of
1659 @code{pcb} they're running.
1665 About (int argc
, char **argv
, int x
, int y
)
1667 ghid_dialog_about ();
1671 /* ------------------------------------------------------------ */
1672 static const char getxy_syntax
[] =
1675 static const char getxy_help
[] =
1676 "Get a coordinate.";
1678 /* %start-doc actions GetXY
1680 Prompts the user for a coordinate, if one is not already selected.
1685 GetXY (int argc
, char **argv
, int x
, int y
)
1690 /* ---------------------------------------------------------------------- */
1692 static int PointCursor (int argc
, char **argv
, int x
, int y
)
1698 ghid_point_cursor ();
1700 ghid_mode_cursor (Settings
.Mode
);
1704 /* ---------------------------------------------------------------------- */
1707 RouteStylesChanged (int argc
, char **argv
, int x
, int y
)
1711 if (PCB
&& PCB
->RouteStyle
[0].Name
)
1712 for (n
= 0; n
< NUM_STYLES
; ++n
)
1713 ghid_route_style_set_button_label ((&PCB
->RouteStyle
[n
])->Name
, n
);
1717 /* ---------------------------------------------------------------------- */
1720 PCBChanged (int argc
, char **argv
, int x
, int y
)
1725 ghid_window_set_name_label (PCB
->Name
);
1729 RouteStylesChanged (0, NULL
, 0, 0);
1730 ghid_port_ranges_scale (TRUE
);
1731 ghid_port_ranges_pan (0, 0, FALSE
);
1732 ghid_port_ranges_zoom (0);
1733 ghid_port_ranges_changed ();
1734 ghid_sync_with_new_layout ();
1738 /* ---------------------------------------------------------------------- */
1741 LayerGroupsChanged (int argc
, char **argv
, int x
, int y
)
1743 printf ("LayerGroupsChanged -- not implemented\n");
1747 /* ---------------------------------------------------------------------- */
1750 LibraryChanged (int argc
, char **argv
, int x
, int y
)
1752 ghid_library_window_show (&ghid_port
, FALSE
);
1756 /* ---------------------------------------------------------------------- */
1759 Command (int argc
, char **argv
, int x
, int y
)
1761 ghid_handle_user_command (TRUE
);
1765 /* ---------------------------------------------------------------------- */
1768 Load (int argc
, char **argv
, int x
, int y
)
1773 static gchar
*current_element_dir
= NULL
;
1774 static gchar
*current_layout_dir
= NULL
;
1775 static gchar
*current_netlist_dir
= NULL
;
1777 /* we've been given the file name */
1779 return hid_actionv ("LoadFrom", argc
, argv
);
1781 function
= argc
? argv
[0] : "Layout";
1783 if (strcasecmp (function
, "Netlist") == 0)
1785 name
= ghid_dialog_file_select_open (_("Load netlist file"),
1786 ¤t_netlist_dir
,
1789 else if (strcasecmp (function
, "ElementToBuffer") == 0)
1791 name
= ghid_dialog_file_select_open (_("Load element to buffer"),
1792 ¤t_element_dir
,
1793 Settings
.LibraryTree
);
1795 else if (strcasecmp (function
, "LayoutToBuffer") == 0)
1797 name
= ghid_dialog_file_select_open (_("Load layout file to buffer"),
1798 ¤t_layout_dir
,
1801 else if (strcasecmp (function
, "Layout") == 0)
1803 name
= ghid_dialog_file_select_open (_("Load layout file"),
1804 ¤t_layout_dir
,
1810 if (Settings
.verbose
)
1811 fprintf (stderr
, "%s: Calling LoadFrom(%s, %s)\n", __FUNCTION__
,
1813 hid_actionl ("LoadFrom", function
, name
, NULL
);
1821 /* ---------------------------------------------------------------------- */
1822 static const char save_syntax
[] =
1824 "Save(Layout|LayoutAs)\n"
1825 "Save(AllConnections|AllUnusedPins|ElementConnections)\n"
1826 "Save(PasteBuffer)";
1828 static const char save_help
[] =
1829 "Save layout and/or element data to a user-selected file.";
1831 /* %start-doc actions Save
1833 This action is a GUI front-end to the core's @code{SaveTo} action
1834 (@pxref{SaveTo Action}). If you happen to pass a filename, like
1835 @code{SaveTo}, then @code{SaveTo} is called directly. Else, the
1836 user is prompted for a filename to save, and then @code{SaveTo} is
1837 called with that filename.
1842 Save (int argc
, char **argv
, int x
, int y
)
1848 static gchar
*current_dir
= NULL
;
1851 return hid_actionv ("SaveTo", argc
, argv
);
1853 function
= argc
? argv
[0] : "Layout";
1855 if (strcasecmp (function
, "Layout") == 0)
1857 return hid_actionl ("SaveTo", "Layout", PCB
->Filename
, NULL
);
1859 if (strcasecmp (function
, "PasteBuffer") == 0)
1860 prompt
= _("Save element as");
1862 prompt
= _("Save layout as");
1864 name
= ghid_dialog_file_select_save (prompt
,
1866 PCB
->Filename
, Settings
.FilePath
);
1871 exist
= fopen (name
, "r");
1875 if (ghid_dialog_confirm (_("File exists! Ok to overwrite?"), NULL
, NULL
))
1877 if (Settings
.verbose
)
1878 fprintf (stderr
, "Overwriting %s\n", name
);
1887 if (Settings
.verbose
)
1888 fprintf (stderr
, "%s: Calling SaveTo(%s, %s)\n",
1889 __FUNCTION__
, function
, name
);
1891 if (strcasecmp (function
, "PasteBuffer") == 0)
1892 hid_actionl ("PasteBuffer", "Save", name
, NULL
);
1896 * if we got this far and the function is Layout, then
1897 * we really needed it to be a LayoutAs. Otherwise
1898 * ActionSaveTo() will ignore the new file name we
1901 if (strcasecmp (function
, "Layout") == 0)
1902 hid_actionl ("SaveTo", "LayoutAs", name
, NULL
);
1904 hid_actionl ("SaveTo", function
, name
, NULL
);
1916 /* ---------------------------------------------------------------------- */
1917 static const char swapsides_syntax
[] =
1918 "SwapSides(|v|h|r)";
1920 static const char swapsides_help
[] =
1921 "Swaps the side of the board you're looking at.";
1923 /* %start-doc actions SwapSides
1925 This action changes the way you view the board.
1930 Flips the board over vertically (up/down).
1933 Flips the board over horizontally (left/right), like flipping pages in
1937 Rotates the board 180 degrees without changing sides.
1941 If no argument is given, the board isn't moved but the opposite side
1944 Normally, this action changes which pads and silk layer are drawn as
1945 true silk, and which are drawn as the "invisible" layer. It also
1946 determines which solder mask you see.
1948 As a special case, if the layer group for the side you're looking at
1949 is visible and currently active, and the layer group for the opposite
1950 is not visible (i.e. disabled), then this action will also swap which
1951 layer group is visible and active, effectively swapping the ``working
1952 side'' of the board.
1958 SwapSides (int argc
, char **argv
, int x
, int y
)
1963 int comp_group
= GetLayerGroupNumberByNumber (max_layer
+ COMPONENT_LAYER
);
1964 int solder_group
= GetLayerGroupNumberByNumber (max_layer
+ SOLDER_LAYER
);
1965 int active_group
= GetLayerGroupNumberByNumber (LayerStack
[0]);
1967 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[comp_group
][0]].On
;
1968 int solder_showing
=
1969 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[solder_group
][0]].On
;
1974 switch (argv
[0][0]) {
1977 ghid_flip_x
= ! ghid_flip_x
;
1982 ghid_flip_y
= ! ghid_flip_y
;
1987 ghid_flip_x
= ! ghid_flip_x
;
1988 ghid_flip_y
= ! ghid_flip_y
;
1995 /* SwapSides will swap this */
1996 Settings
.ShowSolderSide
= (ghid_flip_x
== ghid_flip_y
);
1999 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
;
2000 if (Settings
.ShowSolderSide
)
2002 if (active_group
== comp_group
&& comp_showing
&& !solder_showing
)
2004 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 0,
2006 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 1,
2012 if (active_group
== solder_group
&& solder_showing
&& !comp_showing
)
2014 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 0,
2016 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 1,
2021 /* Update coordinates so that the current location stays where it was on the
2022 other side; we need to do this since the actual flip center is the
2023 center of the board while the user expect the center would be the current
2027 flipd
= PCB
->MaxWidth
/ 2 - gport
->view_x
;
2028 ghid_port_ranges_pan (2 * flipd
, 0, TRUE
);
2032 flipd
= PCB
->MaxHeight
/ 2 - gport
->view_y
;
2033 ghid_port_ranges_pan (0, 2 * flipd
, TRUE
);
2036 ghid_invalidate_all ();
2040 /* ------------------------------------------------------------ */
2042 static const char print_syntax
[] =
2045 static const char print_help
[] =
2046 "Print the layout.";
2048 /* %start-doc actions Print
2050 This will find the default printing HID, prompt the user for its
2051 options, and print the layout.
2056 Print (int argc
, char **argv
, int x
, int y
)
2060 HID
*printer
= NULL
;
2062 hids
= hid_enumerate ();
2063 for (i
= 0; hids
[i
]; i
++)
2065 if (hids
[i
]->printer
)
2069 if (printer
== NULL
)
2071 gui
->log (_("Can't find a suitable printer HID"));
2075 /* check if layout is empty */
2076 if (!IsDataEmpty (PCB
->Data
))
2078 ghid_dialog_print (printer
);
2081 gui
->log (_("Can't print empty layout"));
2087 /* ------------------------------------------------------------ */
2089 static HID_Attribute
2090 printer_calibrate_attrs
[] = {
2091 {"Enter Values here:", "",
2092 HID_Label
, 0, 0, {0, 0, 0}, 0, 0},
2093 {"x-calibration", "X scale for calibrating your printer",
2094 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0},
2095 {"y-calibration", "Y scale for calibrating your printer",
2096 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0}
2098 static HID_Attr_Val printer_calibrate_values
[3];
2100 static const char printcalibrate_syntax
[] =
2103 static const char printcalibrate_help
[] =
2104 "Calibrate the printer.";
2106 /* %start-doc actions PrintCalibrate
2108 This will print a calibration page, which you would measure and type
2109 the measurements in, so that future printouts will be more precise.
2114 PrintCalibrate (int argc
, char **argv
, int x
, int y
)
2116 HID
*printer
= hid_find_printer ();
2117 printer
->calibrate (0.0, 0.0);
2119 if (gui
->attribute_dialog (printer_calibrate_attrs
, 3,
2120 printer_calibrate_values
,
2121 "Printer Calibration Values",
2122 "Enter calibration values for your printer"))
2124 printer
->calibrate (printer_calibrate_values
[1].real_value
,
2125 printer_calibrate_values
[2].real_value
);
2129 /* ------------------------------------------------------------ */
2132 Export (int argc
, char **argv
, int x
, int y
)
2135 /* check if layout is empty */
2136 if (!IsDataEmpty (PCB
->Data
))
2138 ghid_dialog_export ();
2141 gui
->log (_("Can't export empty layout"));
2146 /* ------------------------------------------------------------ */
2149 Benchmark (int argc
, char **argv
, int x
, int y
)
2154 GdkDisplay
*display
;
2156 display
= gdk_drawable_get_display (gport
->drawable
);
2160 region
.X2
= PCB
->MaxWidth
;
2161 region
.Y2
= PCB
->MaxHeight
;
2163 gdk_display_sync (display
);
2167 hid_expose_callback (&ghid_hid
, ®ion
, 0);
2168 gdk_display_sync (display
);
2172 while (end
- start
< 10);
2174 printf ("%g redraws per second\n", i
/ 10.0);
2179 /* ------------------------------------------------------------ */
2181 static const char center_syntax
[] =
2184 static const char center_help
[] =
2185 "Moves the pointer to the center of the window.";
2187 /* %start-doc actions Center
2189 Move the pointer to the center of the window, but only if it's
2190 currently within the window already.
2195 Center(int argc
, char **argv
, int x
, int y
)
2197 int x0
, y0
, w2
, h2
, dx
, dy
;
2202 x
= GRIDFIT_X (SIDE_X (x
), PCB
->Grid
);
2203 y
= GRIDFIT_Y (SIDE_Y (y
), PCB
->Grid
);
2205 w2
= gport
->view_width
/ 2;
2206 h2
= gport
->view_height
/ 2;
2222 dx
= (x0
- gport
->view_x0
) / gport
->zoom
;
2223 dy
= (y0
- gport
->view_y0
) / gport
->zoom
;
2224 gport
->view_x0
= x0
;
2225 gport
->view_y0
= y0
;
2230 /* Move the pointer to the center of the window, but only if it's
2231 currently within the window already. Watch out for edges,
2234 #if GTK_CHECK_VERSION(2,8,0)
2236 GdkDisplay
*display
;
2240 display
= gdk_display_get_default ();
2241 screen
= gdk_display_get_default_screen (display
);
2243 /* figure out where the pointer is and then move it from there by the specified delta */
2244 gdk_display_get_pointer (display
, NULL
, &cx
, &cy
, NULL
);
2245 gdk_display_warp_pointer (display
, screen
, cx
- dx
, cy
- dy
);
2248 * Note that under X11, gdk_display_warp_pointer is just a wrapper around XWarpPointer, but
2249 * hopefully by avoiding the direct call to an X function we might still work under windows
2250 * and other non-X11 based gdk's
2254 # ifdef HAVE_GDK_GDKX_H
2257 Window w_src
, w_dst
;
2258 w_src
= GDK_WINDOW_XID (gport
->drawing_area
->window
);
2261 /* don't warp with the auto drc - that creates auto-scroll chaos */
2262 if (TEST_FLAG (AUTODRCFLAG
, PCB
) && Settings
.Mode
== LINE_MODE
2263 && Crosshair
.AttachedLine
.State
!= STATE_FIRST
)
2266 XWarpPointer (GDK_DRAWABLE_XDISPLAY (gport
->drawing_area
->window
),
2271 /* XWarpPointer creates Motion events normally bound to
2272 * EventMoveCrosshair.
2273 * We don't do any updates when EventMoveCrosshair
2274 * is called the next time to prevent from rounding errors
2277 * IgnoreMotionEvents = ignore;
2286 /* ------------------------------------------------------------ */
2287 static const char cursor_syntax
[] =
2288 "Cursor(Type,DeltaUp,DeltaRight,Units)";
2290 static const char cursor_help
[] =
2293 /* %start-doc actions Cursor
2295 This action moves the mouse cursor. Unlike other actions which take
2296 coordinates, this action's coordinates are always relative to the
2297 user's view of the board. Thus, a positive @var{DeltaUp} may move the
2298 cursor towards the board origin if the board is inverted.
2300 Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the
2301 viewport to move such that the crosshair is under the mouse cursor.
2302 @samp{Warp} causes the mouse cursor to move to be above the crosshair.
2304 @var{Units} can be one of the following:
2310 The cursor is moved by that amount, in board units.
2313 The cursor is moved by that many grid points.
2316 The values are percentages of the viewport's view. Thus, a pan of
2317 @samp{100} would scroll the viewport by exactly the width of the
2321 The values are percentages of the board size. Thus, a move of
2322 @samp{50,50} moves you halfway across the board.
2329 CursorAction(int argc
, char **argv
, int x
, int y
)
2331 int pan_warp
= HID_SC_DO_NOTHING
;
2333 double xu
= 0.0, yu
= 0.0;
2338 if (strcasecmp (argv
[0], "pan") == 0)
2339 pan_warp
= HID_SC_PAN_VIEWPORT
;
2340 else if (strcasecmp (argv
[0], "warp") == 0)
2341 pan_warp
= HID_SC_WARP_POINTER
;
2345 dx
= strtod (argv
[1], 0);
2348 dy
= strtod (argv
[2], 0);
2353 * xu and yu are the scale factors that we multiply dx and dy by to
2354 * come up with PCB internal units.
2356 if (strncasecmp (argv
[3], "mm", 2) == 0)
2357 xu
= yu
= MM_TO_COOR
;
2358 else if (strncasecmp (argv
[3], "mil", 3) == 0)
2360 else if (strncasecmp (argv
[3], "grid", 4) == 0)
2361 xu
= yu
= PCB
->Grid
;
2362 else if (strncasecmp (argv
[3], "view", 4) == 0)
2364 xu
= gport
->view_width
/ 100.0;
2365 yu
= gport
->view_height
/ 100.0;
2367 else if (strncasecmp (argv
[3], "board", 4) == 0)
2369 xu
= PCB
->MaxWidth
/ 100.0;
2370 yu
= PCB
->MaxHeight
/ 100.0;
2373 EventMoveCrosshair (Crosshair
.X
+(int)(dx
*xu
), Crosshair
.Y
+(int)(dy
*yu
));
2374 gui
->set_crosshair (Crosshair
.X
, Crosshair
.Y
, pan_warp
);
2378 /* ------------------------------------------------------------ */
2380 static const char dowindows_syntax
[] =
2381 "DoWindows(1|2|3|4)\n"
2382 "DoWindows(Layout|Library|Log|Netlist|Preferences)";
2384 static const char dowindows_help
[] =
2385 "Open various GUI windows.";
2387 /* %start-doc actions DoWindows
2393 Open the layout window. Since the layout window is always shown
2394 anyway, this has no effect.
2398 Open the library window.
2402 Open the log window.
2406 Open the netlist window.
2410 Open the preferences window.
2417 DoWindows (int argc
, char **argv
, int x
, int y
)
2419 char *a
= argc
== 1 ? argv
[0] : "";
2421 if (strcmp (a
, "1") == 0 || strcasecmp (a
, "Layout") == 0)
2424 else if (strcmp (a
, "2") == 0 || strcasecmp (a
, "Library") == 0)
2426 ghid_library_window_show (gport
, TRUE
);
2428 else if (strcmp (a
, "3") == 0 || strcasecmp (a
, "Log") == 0)
2430 ghid_log_window_show (TRUE
);
2432 else if (strcmp (a
, "4") == 0 || strcasecmp (a
, "Netlist") == 0)
2434 ghid_netlist_window_show (gport
, TRUE
);
2436 else if (strcmp (a
, "5") == 0 || strcasecmp (a
, "Preferences") == 0)
2438 ghid_config_window_show ();
2448 /* ------------------------------------------------------------ */
2449 static const char setunits_syntax
[] =
2452 static const char setunits_help
[] =
2453 "Set the default measurement units.";
2455 /* %start-doc actions SetUnits
2460 Sets the display units to mils (1/1000 inch).
2463 Sets the display units to millimeters.
2470 SetUnits (int argc
, char **argv
, int x
, int y
)
2474 if (strcmp (argv
[0], "mil") == 0)
2475 Settings
.grid_units_mm
= 0;
2476 if (strcmp (argv
[0], "mm") == 0)
2477 Settings
.grid_units_mm
= 1;
2479 ghid_config_handle_units_changed ();
2481 ghid_set_status_line_label ();
2484 * lesstif_sizes_reset ();
2485 * lesstif_styles_update_values ();
2490 /* ------------------------------------------------------------ */
2491 static const char popup_syntax
[] =
2492 "Popup(MenuName, [Button])";
2494 static const char popup_help
[] =
2495 "Bring up the popup menu specified by @code{MenuName}.\n"
2496 "If called by a mouse event then the mouse button number\n"
2497 "must be specified as the optional second argument.";
2499 /* %start-doc actions Popup
2501 This just pops up the specified menu. The menu must have been defined
2502 as a named subresource of the Popups resource in the menu resource
2503 file. If called as a response to a mouse button click, the mouse
2504 button number must be specified as the second argument.
2510 Popup (int argc
, char **argv
, int x
, int y
)
2516 if (argc
!= 1 && argc
!= 2)
2522 button
= atoi (argv
[1]);
2524 if ( (element
= (char *) malloc ( (strlen (argv
[0]) + 2) * sizeof (char))) == NULL
)
2526 fprintf (stderr
, "Popup(): malloc failed\n");
2530 sprintf (element
, "/%s", argv
[0]);
2531 printf ("Loading popup \"%s\". Button = %u\n", element
, button
);
2533 menu
= gtk_ui_manager_get_widget (ghidgui
->ui_manager
, element
);
2536 if (! GTK_IS_MENU (menu
))
2538 Message ("The specified popup menu \"%s\" has not been defined.\n", argv
[0]);
2543 ghidgui
->in_popup
= TRUE
;
2544 gtk_widget_grab_focus (ghid_port
.drawing_area
);
2545 gtk_menu_popup (GTK_MENU (menu
), NULL
, NULL
, NULL
, NULL
, 0,
2546 gtk_get_current_event_time());
2552 Busy (int argc
, char **argv
, int x
, int y
)
2554 ghid_watch_cursor ();
2558 HID_Action ghid_main_action_list
[] = {
2559 {"About", 0, About
, about_help
, about_syntax
},
2560 {"Benchmark", 0, Benchmark
},
2562 {"Center", "Click on a location to center", Center
, center_help
, center_syntax
},
2563 {"Command", 0, Command
},
2564 {"Cursor", 0, CursorAction
, cursor_help
, cursor_syntax
},
2565 {"DoWindows", 0, DoWindows
, dowindows_help
, dowindows_syntax
},
2566 {"Export", 0, Export
},
2567 {"GetXY", "", GetXY
, getxy_help
, getxy_syntax
},
2568 {"LayerGroupsChanged", 0, LayerGroupsChanged
},
2569 {"LibraryChanged", 0, LibraryChanged
},
2571 {"PCBChanged", 0, PCBChanged
},
2572 {"PointCursor", 0, PointCursor
},
2573 {"Popup", 0, Popup
, popup_help
, popup_syntax
},
2575 print_help
, print_syntax
},
2576 {"PrintCalibrate", 0, PrintCalibrate
,
2577 printcalibrate_help
, printcalibrate_syntax
},
2578 {"RouteStylesChanged", 0, RouteStylesChanged
},
2579 {"Save", 0, Save
, save_help
, save_syntax
},
2580 {"SetUnits", 0, SetUnits
, setunits_help
, setunits_syntax
},
2581 {"SwapSides", 0, SwapSides
, swapsides_help
, swapsides_syntax
},
2582 {"Zoom", "Click on zoom focus", Zoom
, zoom_help
, zoom_syntax
}
2585 REGISTER_ACTIONS (ghid_main_action_list
)
2599 HID_Flag ghid_main_flag_list
[] = {
2600 {"flip_x", flag_flipx
, 0},
2601 {"flip_y", flag_flipy
, 0}
2604 REGISTER_FLAGS (ghid_main_flag_list
)
2606 #include "dolists.h"
2609 * We will need these for finding the windows installation
2610 * directory. Without that we can't find our fonts and
2611 * footprint libraries.
2614 #include <windows.h>
2626 tmps
= g_win32_get_package_installation_directory (PACKAGE
"-" VERSION
, NULL
);
2627 #define REST_OF_PATH G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S PACKAGE
2628 share_dir
= (char *) malloc(strlen(tmps
) +
2629 strlen(REST_OF_PATH
) +
2631 sprintf (share_dir
, "%s%s", tmps
, REST_OF_PATH
);
2634 printf ("\"Share\" installation path is \"%s\"\n", share_dir
);
2637 hid_register_hid (&ghid_hid
);
2638 apply_default_hid (&ghid_extents
, &ghid_hid
);
2639 #include "gtk_lists.h"