2 /* 15 Oct 2008 Ineiev: add different crosshair shapes */
17 #include "xincludes.h"
22 #include "crosshair.h"
30 #include "../hidint.h"
31 #include "hid/common/draw_helpers.h"
32 #include "hid/common/hid_resource.h"
35 #ifdef HAVE_LIBDMALLOC
44 #define XtRDouble "Double"
47 typedef struct hid_gc_struct
51 const char *colorname
;
58 extern HID lesstif_gui
;
59 extern HID lesstif_extents
;
61 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GUI function %s\n", __FUNCTION__), abort()
63 XtAppContext app_context
;
66 static Window window
= 0;
67 static Cursor my_cursor
= 0;
68 static int old_cursor_mode
= -1;
69 static int over_point
= 0;
71 /* The first is the "current" pixmap. The main_ is the real one we
72 usually use, the mask_ are the ones for doing polygon masks. The
73 pixmap is the saved pixels, the bitmap is for the "erase" color.
74 We set pixmap to point to main_pixmap or mask_pixmap as needed. */
75 static Pixmap pixmap
= 0;
76 static Pixmap main_pixmap
= 0;
77 static Pixmap mask_pixmap
= 0;
78 static Pixmap mask_bitmap
= 0;
79 static int use_mask
= 0;
81 static int use_xrender
= 0;
83 static Picture main_picture
;
84 static Picture mask_picture
;
85 static Pixmap pale_pixmap
;
86 static Picture pale_picture
;
87 #endif /* HAVE_XRENDER */
89 static int pixmap_w
= 0, pixmap_h
= 0;
92 static Colormap colormap
;
93 static GC my_gc
= 0, bg_gc
, clip_gc
= 0, bset_gc
= 0, bclear_gc
= 0, mask_gc
=
95 static Pixel bgcolor
, offlimit_color
, grid_color
;
96 static int bgred
, bggreen
, bgblue
;
98 static GC arc1_gc
, arc2_gc
;
100 /* These are for the pinout windows. */
101 typedef struct PinoutData
103 struct PinoutData
*prev
, *next
;
106 int left
, right
, top
, bottom
; /* PCB extents of item */
107 int x
, y
; /* PCB coordinates of upper right corner of window */
108 double zoom
; /* PCB units per screen pixel */
109 int v_width
, v_height
; /* pixels */
113 /* Linked list of all pinout windows. */
114 static PinoutData
*pinouts
= 0;
115 /* If set, we are currently updating this pinout window. */
116 static PinoutData
*pinout
= 0;
118 static int crosshair_x
= 0, crosshair_y
= 0;
119 static int in_move_event
= 0, crosshair_in_window
= 1;
121 Widget work_area
, messages
, command
, hscroll
, vscroll
;
122 static Widget m_mark
, m_crosshair
, m_grid
, m_zoom
, m_mode
, m_status
;
123 static Widget m_rats
;
124 Widget lesstif_m_layer
;
127 /* This is the size, in pixels, of the viewport. */
128 static int view_width
, view_height
;
129 /* This is the PCB location represented by the upper left corner of
130 the viewport. Note that PCB coordinates put 0,0 in the upper left,
132 static int view_left_x
= 0, view_top_y
= 0;
133 /* Denotes PCB units per screen pixel. Larger numbers mean zooming
134 out - the largest value means you are looking at the whole
136 static double view_zoom
= 1000, prev_view_zoom
= 1000;
137 static int flip_x
= 0, flip_y
= 0;
138 static int autofade
= 0;
151 HID_Flag lesstif_main_flag_list
[] = {
152 {"flip_x", flag_flipx
, 0},
153 {"flip_y", flag_flipy
, 0}
156 REGISTER_FLAGS (lesstif_main_flag_list
)
158 /* This is the size of the current PCB work area. */
159 /* Use PCB->MaxWidth, PCB->MaxHeight. */
160 /* static int pcb_width, pcb_height; */
164 #define stdarg(t,v) XtSetArg(args[n], t, v), n++
167 static int use_private_colormap
= 0;
168 static int stdin_listen
= 0;
169 static char *background_image_file
= 0;
171 HID_Attribute lesstif_attribute_list
[] = {
172 {"install", "Install private colormap",
173 HID_Boolean
, 0, 0, {0, 0, 0}, 0, &use_private_colormap
},
174 #define HA_colormap 0
176 {"listen", "Listen on standard input for actions",
177 HID_Boolean
, 0, 0, {0, 0, 0}, 0, &stdin_listen
},
180 {"bg-image", "Background Image",
181 HID_String
, 0, 0, {0, 0, 0}, 0, &background_image_file
},
182 #define HA_bg_image 1
186 REGISTER_ATTRIBUTES (lesstif_attribute_list
)
188 static void lesstif_use_mask (int use_it
);
189 static void zoom_to (double factor
, int x
, int y
);
190 static void zoom_by (double factor
, int x
, int y
);
191 static void zoom_toggle (int x
, int y
);
192 static void pinout_callback (Widget
, PinoutData
*,
193 XmDrawingAreaCallbackStruct
*);
194 static void pinout_unmap (Widget
, PinoutData
*, void *);
195 static void Pan (int mode
, int x
, int y
);
197 /* Px converts view->pcb, Vx converts pcb->view */
202 int rv
= (x
- view_left_x
) / view_zoom
+ 0.5;
204 rv
= view_width
- rv
;
211 int rv
= (y
- view_top_y
) / view_zoom
+ 0.5;
213 rv
= view_height
- rv
;
220 return z
/ view_zoom
+ 0.5;
228 return x
* view_zoom
+ view_left_x
;
236 return y
* view_zoom
+ view_top_y
;
242 return z
* view_zoom
;
246 lesstif_coords_to_pcb (int vx
, int vy
, int *px
, int *py
)
253 lesstif_parse_color (char *value
)
256 if (XParseColor (display
, colormap
, value
, &color
))
257 if (XAllocColor (display
, colormap
, &color
))
263 do_color (char *value
, char *which
)
266 if (XParseColor (display
, colormap
, value
, &color
))
267 if (XAllocColor (display
, colormap
, &color
))
269 stdarg (which
, color
.pixel
);
273 /* ------------------------------------------------------------ */
278 if (TEST_FLAG (ORTHOMOVEFLAG
, PCB
))
280 if (TEST_FLAG (ALLDIRECTIONFLAG
, PCB
))
282 if (PCB
->Clipping
== 0)
284 if (PCB
->Clipping
== 1)
289 /* Called from the core when it's busy doing something and we need to
290 indicate that to the user. */
292 Busy(int argc
, char **argv
, int x
, int y
)
294 static Cursor busy_cursor
= 0;
295 if (busy_cursor
== 0)
296 busy_cursor
= XCreateFontCursor (display
, XC_watch
);
297 XDefineCursor (display
, window
, busy_cursor
);
299 old_cursor_mode
= -1;
303 /* ---------------------------------------------------------------------- */
308 PointCursor (int argc
, char **argv
, int x
, int y
)
314 old_cursor_mode
= -1;
319 PCBChanged (int argc
, char **argv
, int x
, int y
)
323 /*printf("PCB Changed! %d x %d\n", PCB->MaxWidth, PCB->MaxHeight); */
325 stdarg (XmNminimum
, 0);
326 stdarg (XmNvalue
, 0);
327 stdarg (XmNsliderSize
, PCB
->MaxWidth
? PCB
->MaxWidth
: 1);
328 stdarg (XmNmaximum
, PCB
->MaxWidth
? PCB
->MaxWidth
: 1);
329 XtSetValues (hscroll
, args
, n
);
331 stdarg (XmNminimum
, 0);
332 stdarg (XmNvalue
, 0);
333 stdarg (XmNsliderSize
, PCB
->MaxHeight
? PCB
->MaxHeight
: 1);
334 stdarg (XmNmaximum
, PCB
->MaxHeight
? PCB
->MaxHeight
: 1);
335 XtSetValues (vscroll
, args
, n
);
336 zoom_by (1000000, 0, 0);
338 hid_action ("NetlistChanged");
339 hid_action ("LayersChanged");
340 hid_action ("RouteStylesChanged");
341 lesstif_sizes_reset ();
342 lesstif_update_layer_groups ();
344 pinout_unmap (0, pinouts
, 0);
347 char *cp
= strrchr (PCB
->Filename
, '/');
349 stdarg (XmNtitle
, cp
? cp
+ 1 : PCB
->Filename
);
350 XtSetValues (appwidget
, args
, n
);
356 static const char setunits_syntax
[] =
359 static const char setunits_help
[] =
360 "Set the default measurement units.";
362 /* %start-doc actions SetUnits
367 Sets the display units to mils (1/1000 inch).
370 Sets the display units to millimeters.
377 SetUnits (int argc
, char **argv
, int x
, int y
)
381 if (strcmp (argv
[0], "mil") == 0)
382 Settings
.grid_units_mm
= 0;
383 if (strcmp (argv
[0], "mm") == 0)
384 Settings
.grid_units_mm
= 1;
385 lesstif_sizes_reset ();
386 lesstif_styles_update_values ();
390 static const char zoom_syntax
[] =
394 static const char zoom_help
[] =
395 "Various zoom factor changes.";
397 /* %start-doc actions Zoom
399 Changes the zoom (magnification) of the view of the board. If no
400 arguments are passed, the view is scaled such that the board just fits
401 inside the visible window (i.e. ``view all''). Otherwise,
402 @var{factor} specifies a change in zoom factor. It may be prefixed by
403 @code{+}, @code{-}, or @code{=} to change how the zoom factor is
404 modified. The @var{factor} is a floating point number, such as
405 @code{1.5} or @code{0.75}.
410 Values greater than 1.0 cause the board to be drawn smaller; more of
411 the board will be visible. Values between 0.0 and 1.0 cause the board
412 to be drawn bigger; less of the board will be visible.
415 Values greater than 1.0 cause the board to be drawn bigger; less of
416 the board will be visible. Values between 0.0 and 1.0 cause the board
417 to be drawn smaller; more of the board will be visible.
421 The @var{factor} is an absolute zoom factor; the unit for this value
422 is "PCB units per screen pixel". Since PCB units are 0.01 mil, a
423 @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI,
424 about the actual resolution of most screens - resulting in an "actual
425 size" board. Similarly, a @var{factor} of 100 gives you a 10x actual
430 Note that zoom factors of zero are silently ignored.
435 ZoomAction (int argc
, char **argv
, int x
, int y
)
439 if (x
== 0 && y
== 0)
451 zoom_to (1000000, 0, 0);
455 if (strcasecmp (vp
, "toggle") == 0)
460 if (*vp
== '+' || *vp
== '-' || *vp
== '=')
468 zoom_by (1 / v
, x
, y
);
481 static int pan_thumb_mode
;
484 PanAction (int argc
, char **argv
, int x
, int y
)
490 pan_thumb_mode
= (strcasecmp (argv
[0], "thumb") == 0) ? 1 : 0;
491 mode
= atoi (argv
[1]);
496 mode
= atoi (argv
[0]);
498 Pan (mode
, Vx(x
), Vy(y
));
503 static const char swapsides_syntax
[] =
506 static const char swapsides_help
[] =
507 "Swaps the side of the board you're looking at.";
509 /* %start-doc actions SwapSides
511 This action changes the way you view the board.
516 Flips the board over vertically (up/down).
519 Flips the board over horizontally (left/right), like flipping pages in
523 Rotates the board 180 degrees without changing sides.
527 If no argument is given, the board isn't moved but the opposite side
530 Normally, this action changes which pads and silk layer are drawn as
531 true silk, and which are drawn as the "invisible" layer. It also
532 determines which solder mask you see.
534 As a special case, if the layer group for the side you're looking at
535 is visible and currently active, and the layer group for the opposite
536 is not visible (i.e. disabled), then this action will also swap which
537 layer group is visible and active, effectively swapping the ``working
543 SwapSides (int argc
, char **argv
, int x
, int y
)
545 int old_shown_side
= Settings
.ShowSolderSide
;
546 int comp_group
= GetLayerGroupNumberByNumber (max_layer
+ COMPONENT_LAYER
);
547 int solder_group
= GetLayerGroupNumberByNumber (max_layer
+ SOLDER_LAYER
);
548 int active_group
= GetLayerGroupNumberByNumber (LayerStack
[0]);
550 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[comp_group
][0]].On
;
552 PCB
->Data
->Layer
[PCB
->LayerGroups
.Entries
[solder_group
][0]].On
;
556 switch (argv
[0][0]) {
573 /* SwapSides will swap this */
574 Settings
.ShowSolderSide
= (flip_x
== flip_y
);
579 stdarg (XmNprocessingDirection
, XmMAX_ON_LEFT
);
581 stdarg (XmNprocessingDirection
, XmMAX_ON_RIGHT
);
582 XtSetValues (hscroll
, args
, n
);
586 stdarg (XmNprocessingDirection
, XmMAX_ON_TOP
);
588 stdarg (XmNprocessingDirection
, XmMAX_ON_BOTTOM
);
589 XtSetValues (vscroll
, args
, n
);
591 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
;
593 /* The idea is that if we're looking at the front side and the front
594 layer is active (or visa versa), switching sides should switch
595 layers too. We used to only do this if the other layer wasn't
596 shown, but we now do it always. Change it back if users get
598 if (Settings
.ShowSolderSide
!= old_shown_side
)
600 if (Settings
.ShowSolderSide
)
602 if (active_group
== comp_group
)
604 if (comp_showing
&& !solder_showing
)
605 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 0,
607 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 1,
613 if (active_group
== solder_group
)
615 if (solder_showing
&& !comp_showing
)
616 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0], 0,
618 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0], 1,
623 lesstif_invalidate_all ();
627 static Widget m_cmd
= 0, m_cmd_label
;
630 command_callback (Widget w
, XtPointer uptr
, XmTextVerifyCallbackStruct
* cbs
)
636 s
= XmTextGetString (w
);
637 lesstif_show_crosshair (0);
638 hid_parse_command (s
);
640 XmTextSetString (w
, "");
641 case XmCR_LOSING_FOCUS
:
642 XtUnmanageChild (m_cmd
);
643 XtUnmanageChild (m_cmd_label
);
649 command_event_handler (Widget w
, XtPointer p
, XEvent
* e
, bool * cont
)
658 slen
= XLookupString ((XKeyEvent
*)e
, buf
, sizeof (buf
), &sym
, NULL
);
662 XtUnmanageChild (m_cmd
);
663 XtUnmanageChild (m_cmd_label
);
664 XmTextSetString (w
, "");
672 static const char command_syntax
[] =
675 static const char command_help
[] =
676 "Displays the command line input window.";
678 /* %start-doc actions Command
680 The command window allows the user to manually enter actions to be
681 executed. Action syntax can be done one of two ways:
686 Follow the action name by an open parenthesis, arguments separated by
687 commas, end with a close parenthesis. Example: @code{Abc(1,2,3)}
690 Separate the action name and arguments by spaces. Example: @code{Abc
695 The first option allows you to have arguments with spaces in them,
696 but the second is more ``natural'' to type for most people.
698 Note that action names are not case sensitive, but arguments normally
699 are. However, most actions will check for ``keywords'' in a case
702 There are three ways to finish with the command window. If you press
703 the @code{Enter} key, the command is invoked, the window goes away,
704 and the next time you bring up the command window it's empty. If you
705 press the @code{Esc} key, the window goes away without invoking
706 anything, and the next time you bring up the command window it's
707 empty. If you change focus away from the command window (i.e. click
708 on some other window), the command window goes away but the next time
709 you bring it up it resumes entering the command you were entering
715 Command (int argc
, char **argv
, int x
, int y
)
717 XtManageChild (m_cmd_label
);
718 XtManageChild (m_cmd
);
719 XmProcessTraversal (m_cmd
, XmTRAVERSE_CURRENT
);
723 static const char benchmark_syntax
[] =
726 static const char benchmark_help
[] =
727 "Benchmark the GUI speed.";
729 /* %start-doc actions Benchmark
731 This action is used to speed-test the Lesstif graphics subsystem. It
732 redraws the current screen as many times as possible in ten seconds.
733 It reports the amount of time needed to draw the screen once.
738 Benchmark (int argc
, char **argv
, int x
, int y
)
745 save_main
= main_pixmap
;
746 main_pixmap
= window
;
750 region
.X2
= PCB
->MaxWidth
;
751 region
.Y2
= PCB
->MaxHeight
;
758 XFillRectangle (display
, pixmap
, bg_gc
, 0, 0, view_width
, view_height
);
759 hid_expose_callback (&lesstif_gui
, ®ion
, 0);
764 while (end
- start
< 10);
766 printf ("%g redraws per second\n", i
/ 10.0);
768 main_pixmap
= save_main
;
773 Center(int argc
, char **argv
, int x
, int y
)
775 x
= GRIDFIT_X (x
, PCB
->Grid
);
776 y
= GRIDFIT_Y (y
, PCB
->Grid
);
777 view_left_x
= x
- (view_width
* view_zoom
) / 2;
778 view_top_y
= y
- (view_height
* view_zoom
) / 2;
779 lesstif_pan_fixup ();
780 /* Move the pointer to the center of the window, but only if it's
781 currently within the window already. Watch out for edges,
783 XWarpPointer (display
, window
, window
, 0, 0, view_width
, view_height
,
788 static const char cursor_syntax
[] =
789 "Cursor(Type,DeltaUp,DeltaRight,Units)";
791 static const char cursor_help
[] =
794 /* %start-doc actions Cursor
796 This action moves the mouse cursor. Unlike other actions which take
797 coordinates, this action's coordinates are always relative to the
798 user's view of the board. Thus, a positive @var{DeltaUp} may move the
799 cursor towards the board origin if the board is inverted.
801 Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the
802 viewport to move such that the crosshair is under the mouse cursor.
803 @samp{Warp} causes the mouse cursor to move to be above the crosshair.
805 @var{Units} can be one of the following:
811 The cursor is moved by that amount, in board units.
814 The cursor is moved by that many grid points.
817 The values are percentages of the viewport's view. Thus, a pan of
818 @samp{100} would scroll the viewport by exactly the width of the
822 The values are percentages of the board size. Thus, a move of
823 @samp{50,50} moves you halfway across the board.
830 CursorAction(int argc
, char **argv
, int x
, int y
)
832 int pan_warp
= HID_SC_DO_NOTHING
;
833 double dx
, dy
, xu
, yu
;
838 if (strcasecmp (argv
[0], "pan") == 0)
839 pan_warp
= HID_SC_PAN_VIEWPORT
;
840 else if (strcasecmp (argv
[0], "warp") == 0)
841 pan_warp
= HID_SC_WARP_POINTER
;
845 dx
= strtod (argv
[1], 0);
848 dy
= strtod (argv
[2], 0);
852 if (strncasecmp (argv
[3], "mm", 2) == 0)
853 xu
= yu
= MM_TO_COOR
;
854 else if (strncasecmp (argv
[3], "mil", 3) == 0)
856 else if (strncasecmp (argv
[3], "grid", 4) == 0)
858 else if (strncasecmp (argv
[3], "view", 4) == 0)
860 xu
= Pz(view_width
) / 100.0;
861 yu
= Pz(view_height
) / 100.0;
863 else if (strncasecmp (argv
[3], "board", 4) == 0)
865 xu
= PCB
->MaxWidth
/ 100.0;
866 yu
= PCB
->MaxHeight
/ 100.0;
871 EventMoveCrosshair (Crosshair
.X
+(int)(dx
*xu
), Crosshair
.Y
+(int)(dy
*yu
));
872 gui
->set_crosshair (Crosshair
.X
, Crosshair
.Y
, pan_warp
);
877 HID_Action lesstif_main_action_list
[] = {
878 {"PCBChanged", 0, PCBChanged
,
879 pcbchanged_help
, pcbchanged_syntax
},
880 {"SetUnits", 0, SetUnits
,
881 setunits_help
, setunits_syntax
},
882 {"Zoom", "Click on a place to zoom in", ZoomAction
,
883 zoom_help
, zoom_syntax
},
884 {"Pan", "Click on a place to pan", PanAction
,
885 zoom_help
, zoom_syntax
},
886 {"SwapSides", 0, SwapSides
,
887 swapsides_help
, swapsides_syntax
},
888 {"Command", 0, Command
,
889 command_help
, command_syntax
},
890 {"Benchmark", 0, Benchmark
,
891 benchmark_help
, benchmark_syntax
},
892 {"PointCursor", 0, PointCursor
},
893 {"Center", "Click on a location to center", Center
},
895 {"Cursor", 0, CursorAction
,
896 cursor_help
, cursor_syntax
},
899 REGISTER_ACTIONS (lesstif_main_action_list
)
902 /* ----------------------------------------------------------------------
903 * redraws the background image
906 static int bg_w
, bg_h
, bgi_w
, bgi_h
;
907 static Pixel
**bg
= 0;
908 static XImage
*bgi
= 0;
913 } pixel_type
= PT_unknown
;
916 LoadBackgroundFile (FILE *f
, char *filename
)
918 XVisualInfo vinfot
, *vinfo
;
922 int p
[3], rows
, cols
, maxval
;
926 printf("bgimage: %s signature not P6\n", filename
);
931 printf("bgimage: %s signature not P6\n", filename
);
941 while (!feof(f
) && b
!= '\n')
943 } while (!isdigit(b
));
945 while (isdigit(b
= fgetc(f
)))
946 p
[i
] = p
[i
]*10 + b
- '0';
953 bg
= (Pixel
**) malloc (rows
* sizeof (Pixel
*));
956 printf("Out of memory loading %s\n", filename
);
959 for (i
=0; i
<rows
; i
++)
961 bg
[i
] = (Pixel
*) malloc (cols
* sizeof (Pixel
));
964 printf("Out of memory loading %s\n", filename
);
973 vis
= DefaultVisual (display
, DefaultScreen(display
));
975 vinfot
.visualid
= XVisualIDFromVisual(vis
);
976 vinfo
= XGetVisualInfo (display
, VisualIDMask
, &vinfot
, &nret
);
979 /* If you want to support more visuals below, you'll probably need
981 printf("vinfo: rm %04x gm %04x bm %04x depth %d class %d\n",
982 vinfo
->red_mask
, vinfo
->green_mask
, vinfo
->blue_mask
,
983 vinfo
->depth
, vinfo
->class);
986 if (vinfo
->class == TrueColor
987 && vinfo
->depth
== 16
988 && vinfo
->red_mask
== 0xf800
989 && vinfo
->green_mask
== 0x07e0
990 && vinfo
->blue_mask
== 0x001f)
991 pixel_type
= PT_RGB565
;
993 if (vinfo
->class == TrueColor
994 && vinfo
->depth
== 24
995 && vinfo
->red_mask
== 0xff0000
996 && vinfo
->green_mask
== 0x00ff00
997 && vinfo
->blue_mask
== 0x0000ff)
998 pixel_type
= PT_RGB888
;
1000 for (r
=0; r
<rows
; r
++)
1002 for (c
=0; c
<cols
; c
++)
1005 unsigned int pr
= (unsigned)fgetc(f
);
1006 unsigned int pg
= (unsigned)fgetc(f
);
1007 unsigned int pb
= (unsigned)fgetc(f
);
1012 pix
.red
= pr
* 65535 / maxval
;
1013 pix
.green
= pg
* 65535 / maxval
;
1014 pix
.blue
= pb
* 65535 / maxval
;
1015 pix
.flags
= DoRed
| DoGreen
| DoBlue
;
1016 XAllocColor (display
, colormap
, &pix
);
1017 bg
[r
][c
] = pix
.pixel
;
1020 bg
[r
][c
] = (pr
>>3)<<11 | (pg
>>2)<<5 | (pb
>>3);
1023 bg
[r
][c
] = (pr
<< 16) | (pg
<< 8) | (pb
);
1031 LoadBackgroundImage (char *filename
)
1033 FILE *f
= fopen(filename
, "rb");
1036 if (NSTRCMP (filename
, "pcb-background.ppm"))
1040 LoadBackgroundFile (f
, filename
);
1045 DrawBackgroundImage ()
1048 double xscale
, yscale
;
1049 int pcbwidth
= PCB
->MaxWidth
/ view_zoom
;
1050 int pcbheight
= PCB
->MaxHeight
/ view_zoom
;
1055 if (!bgi
|| view_width
!= bgi_w
|| view_height
!= bgi_h
)
1058 XDestroyImage (bgi
);
1059 /* Cheat - get the image, which sets up the format too. */
1060 bgi
= XGetImage (XtDisplay(work_area
),
1062 0, 0, view_width
, view_height
,
1065 bgi_h
= view_height
;
1068 w
= MIN (view_width
, pcbwidth
);
1069 h
= MIN (view_height
, pcbheight
);
1071 xscale
= (double)bg_w
/ PCB
->MaxWidth
;
1072 yscale
= (double)bg_h
/ PCB
->MaxHeight
;
1077 int ir
= pr
* yscale
;
1081 int ic
= pc
* xscale
;
1082 XPutPixel (bgi
, x
, y
, bg
[ir
][ic
]);
1085 XPutImage(display
, main_pixmap
, bg_gc
,
1089 /* ---------------------------------------------------------------------- */
1091 static HID_Attribute
*
1092 lesstif_get_export_options (int *n
)
1098 set_scroll (Widget s
, int pos
, int view
, int pcb
)
1100 int sz
= view
* view_zoom
;
1104 stdarg (XmNvalue
, pos
);
1105 stdarg (XmNsliderSize
, sz
);
1106 stdarg (XmNincrement
, view_zoom
);
1107 stdarg (XmNpageIncrement
, sz
);
1108 stdarg (XmNmaximum
, pcb
);
1109 XtSetValues (s
, args
, n
);
1113 lesstif_pan_fixup ()
1115 if (view_left_x
> PCB
->MaxWidth
- (view_width
* view_zoom
))
1116 view_left_x
= PCB
->MaxWidth
- (view_width
* view_zoom
);
1117 if (view_top_y
> PCB
->MaxHeight
- (view_height
* view_zoom
))
1118 view_top_y
= PCB
->MaxHeight
- (view_height
* view_zoom
);
1119 if (view_left_x
< 0)
1123 if (view_width
* view_zoom
> PCB
->MaxWidth
1124 && view_height
* view_zoom
> PCB
->MaxHeight
)
1130 set_scroll (hscroll
, view_left_x
, view_width
, PCB
->MaxWidth
);
1131 set_scroll (vscroll
, view_top_y
, view_height
, PCB
->MaxHeight
);
1133 lesstif_invalidate_all ();
1137 zoom_to (double new_zoom
, int x
, int y
)
1139 double max_zoom
, xfrac
, yfrac
;
1142 xfrac
= (double) x
/ (double) view_width
;
1143 yfrac
= (double) y
/ (double) view_height
;
1150 max_zoom
= PCB
->MaxWidth
/ view_width
;
1151 if (max_zoom
< PCB
->MaxHeight
/ view_height
)
1152 max_zoom
= PCB
->MaxHeight
/ view_height
;
1156 if (new_zoom
> max_zoom
)
1157 new_zoom
= max_zoom
;
1159 cx
= view_left_x
+ view_width
* xfrac
* view_zoom
;
1160 cy
= view_top_y
+ view_height
* yfrac
* view_zoom
;
1162 if (view_zoom
!= new_zoom
)
1164 view_zoom
= new_zoom
;
1165 pixel_slop
= view_zoom
;
1167 view_left_x
= cx
- view_width
* xfrac
* view_zoom
;
1168 view_top_y
= cy
- view_height
* yfrac
* view_zoom
;
1170 lesstif_pan_fixup ();
1174 zoom_toggle(int x
, int y
)
1178 tmp
= prev_view_zoom
;
1179 prev_view_zoom
= view_zoom
;
1184 zoom_by (double factor
, int x
, int y
)
1186 zoom_to (view_zoom
* factor
, x
, y
);
1189 static int panning
= 0;
1190 static int shift_pressed
;
1191 static int ctrl_pressed
;
1192 static int alt_pressed
;
1194 /* X and Y are in screen coordinates. */
1196 Pan (int mode
, int x
, int y
)
1199 static int opx
, opy
;
1202 /* This is for ctrl-pan, where the viewport's position is directly
1203 proportional to the cursor position in the window (like the Xaw
1207 opx
= x
* PCB
->MaxWidth
/ view_width
;
1208 opy
= y
* PCB
->MaxHeight
/ view_height
;
1210 opx
= PCB
->MaxWidth
- opx
;
1212 opy
= PCB
->MaxHeight
- opy
;
1213 view_left_x
= opx
- view_width
/ 2 * view_zoom
;
1214 view_top_y
= opy
- view_height
/ 2 * view_zoom
;
1215 lesstif_pan_fixup ();
1217 /* This is the start of a regular pan. On the first click, we
1218 remember the coordinates where we "grabbed" the screen. */
1226 /* continued drag, we calculate how far we've moved the cursor and
1227 set the position accordingly. */
1231 view_left_x
= opx
+ (x
- ox
) * view_zoom
;
1233 view_left_x
= opx
- (x
- ox
) * view_zoom
;
1235 view_top_y
= opy
+ (y
- oy
) * view_zoom
;
1237 view_top_y
= opy
- (y
- oy
) * view_zoom
;
1238 lesstif_pan_fixup ();
1243 mod_changed (XKeyEvent
* e
, int set
)
1245 switch (XKeycodeToKeysym (display
, e
->keycode
, 0))
1249 shift_pressed
= set
;
1256 case XK_Mode_switch
:
1264 // to include the Apple keyboard left and right command keys use XK_Meta_L and XK_Meta_R respectivly.
1270 Pan (2, e
->x
, e
->y
);
1271 EventMoveCrosshair (Px (e
->x
), Py (e
->y
));
1272 AdjustAttachedObjects ();
1273 RestoreCrosshair (1);
1278 work_area_input (Widget w
, XtPointer v
, XEvent
* e
, bool * ctd
)
1280 static int pressed_button
= 0;
1281 static int ignore_release
= 0;
1287 mod_changed (&(e
->xkey
), 1);
1288 if (lesstif_key_event (&(e
->xkey
)))
1293 mod_changed (&(e
->xkey
), 0);
1301 /*printf("click %d\n", e->xbutton.button); */
1302 if (lesstif_button_event (w
, e
))
1309 HideCrosshair (true);
1310 pressed_button
= e
->xbutton
.button
;
1311 mods
= ((e
->xbutton
.state
& ShiftMask
) ? M_Shift
: 0)
1312 + ((e
->xbutton
.state
& ControlMask
) ? M_Ctrl
: 0)
1314 + ((e
->xbutton
.state
& (1<<13)) ? M_Alt
: 0);
1316 + ((e
->xbutton
.state
& Mod1Mask
) ? M_Alt
: 0);
1318 do_mouse_action(e
->xbutton
.button
, mods
);
1319 RestoreCrosshair (true);
1326 if (e
->xbutton
.button
!= pressed_button
)
1328 lesstif_button_event (w
, e
);
1329 HideCrosshair (true);
1331 mods
= ((e
->xbutton
.state
& ShiftMask
) ? M_Shift
: 0)
1332 + ((e
->xbutton
.state
& ControlMask
) ? M_Ctrl
: 0)
1334 + ((e
->xbutton
.state
& (1<<13)) ? M_Alt
: 0)
1336 + ((e
->xbutton
.state
& Mod1Mask
) ? M_Alt
: 0)
1339 do_mouse_action (e
->xbutton
.button
, mods
);
1340 RestoreCrosshair (true);
1347 unsigned int keys_buttons
;
1348 int root_x
, root_y
, pos_x
, pos_y
;
1349 while (XCheckMaskEvent (display
, PointerMotionMask
, e
));
1350 XQueryPointer (display
, e
->xmotion
.window
, &root
, &child
,
1351 &root_x
, &root_y
, &pos_x
, &pos_y
, &keys_buttons
);
1352 shift_pressed
= (keys_buttons
& ShiftMask
);
1353 ctrl_pressed
= (keys_buttons
& ControlMask
);
1355 alt_pressed
= (keys_buttons
& (1<<13));
1357 alt_pressed
= (keys_buttons
& Mod1Mask
);
1359 /*printf("m %d %d\n", Px(e->xmotion.x), Py(e->xmotion.y)); */
1360 crosshair_in_window
= 1;
1363 Pan (2, pos_x
, pos_y
);
1364 EventMoveCrosshair (Px (pos_x
), Py (pos_y
));
1370 crosshair_in_window
= 0;
1376 crosshair_in_window
= 1;
1378 EventMoveCrosshair (Px (e
->xcrossing
.x
), Py (e
->xcrossing
.y
));
1385 printf ("work_area: unknown event %d\n", e
->type
);
1391 draw_right_cross (GC xor_gc
, int x
, int y
,
1392 int view_width
, int view_height
)
1394 XDrawLine (display
, window
, xor_gc
, 0, y
, view_width
, y
);
1395 XDrawLine (display
, window
, xor_gc
, x
, 0, x
, view_height
);
1399 draw_slanted_cross (GC xor_gc
, int x
, int y
,
1400 int view_width
, int view_height
)
1404 x0
= x
+ (view_height
- y
);
1405 x0
= MAX(0, MIN (x0
, view_width
));
1407 x1
= MAX(0, MIN (x1
, view_width
));
1408 y0
= y
+ (view_width
- x
);
1409 y0
= MAX(0, MIN (y0
, view_height
));
1411 y1
= MAX(0, MIN (y1
, view_height
));
1412 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1413 x0
= x
- (view_height
- y
);
1414 x0
= MAX(0, MIN (x0
, view_width
));
1416 x1
= MAX(0, MIN (x1
, view_width
));
1418 y0
= MAX(0, MIN (y0
, view_height
));
1419 y1
= y
- (view_width
- x
);
1420 y1
= MAX(0, MIN (y1
, view_height
));
1421 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1425 draw_dozen_cross (GC xor_gc
, int x
, int y
,
1426 int view_width
, int view_height
)
1429 double tan60
= sqrt (3);
1431 x0
= x
+ (view_height
- y
) / tan60
;
1432 x0
= MAX(0, MIN (x0
, view_width
));
1434 x1
= MAX(0, MIN (x1
, view_width
));
1435 y0
= y
+ (view_width
- x
) * tan60
;
1436 y0
= MAX(0, MIN (y0
, view_height
));
1438 y1
= MAX(0, MIN (y1
, view_height
));
1439 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1441 x0
= x
+ (view_height
- y
) * tan60
;
1442 x0
= MAX(0, MIN (x0
, view_width
));
1444 x1
= MAX(0, MIN (x1
, view_width
));
1445 y0
= y
+ (view_width
- x
) / tan60
;
1446 y0
= MAX(0, MIN (y0
, view_height
));
1448 y1
= MAX(0, MIN (y1
, view_height
));
1449 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1451 x0
= x
- (view_height
- y
) / tan60
;
1452 x0
= MAX(0, MIN (x0
, view_width
));
1454 x1
= MAX(0, MIN (x1
, view_width
));
1456 y0
= MAX(0, MIN (y0
, view_height
));
1457 y1
= y
- (view_width
- x
) * tan60
;
1458 y1
= MAX(0, MIN (y1
, view_height
));
1459 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1461 x0
= x
- (view_height
- y
) * tan60
;
1462 x0
= MAX(0, MIN (x0
, view_width
));
1464 x1
= MAX(0, MIN (x1
, view_width
));
1466 y0
= MAX(0, MIN (y0
, view_height
));
1467 y1
= y
- (view_width
- x
) / tan60
;
1468 y1
= MAX(0, MIN (y1
, view_height
));
1469 XDrawLine (display
, window
, xor_gc
, x0
, y0
, x1
, y1
);
1473 draw_crosshair (GC xor_gc
, int x
, int y
,
1474 int view_width
, int view_height
)
1476 draw_right_cross (xor_gc
, x
, y
, view_width
, view_height
);
1477 if (Crosshair
.shape
== Union_Jack_Crosshair_Shape
)
1478 draw_slanted_cross (xor_gc
, x
, y
, view_width
, view_height
);
1479 if (Crosshair
.shape
== Dozen_Crosshair_Shape
)
1480 draw_dozen_cross (xor_gc
, x
, y
, view_width
, view_height
);
1483 lesstif_show_crosshair (int show
)
1485 static int showing
= 0;
1487 static GC xor_gc
= 0;
1488 Pixel crosshair_color
;
1490 if (!crosshair_in_window
|| !window
)
1494 crosshair_color
= lesstif_parse_color (Settings
.CrosshairColor
) ^ bgcolor
;
1495 xor_gc
= XCreateGC (display
, window
, 0, 0);
1496 XSetFunction (display
, xor_gc
, GXxor
);
1497 XSetForeground (display
, xor_gc
, crosshair_color
);
1499 if (show
== showing
)
1503 sx
= Vx (crosshair_x
);
1504 sy
= Vy (crosshair_y
);
1508 draw_crosshair (xor_gc
, sx
, sy
, view_width
, view_height
);
1513 work_area_expose (Widget work_area
, void *me
,
1514 XmDrawingAreaCallbackStruct
* cbs
)
1519 e
= &(cbs
->event
->xexpose
);
1520 XSetFunction (display
, my_gc
, GXcopy
);
1521 XCopyArea (display
, main_pixmap
, window
, my_gc
,
1522 e
->x
, e
->y
, e
->width
, e
->height
, e
->x
, e
->y
);
1527 scroll_callback (Widget scroll
, int *view_dim
,
1528 XmScrollBarCallbackStruct
* cbs
)
1530 *view_dim
= cbs
->value
;
1531 lesstif_invalidate_all ();
1535 work_area_make_pixmaps (Dimension width
, Dimension height
)
1538 XFreePixmap (display
, main_pixmap
);
1540 XCreatePixmap (display
, window
, width
, height
,
1541 XDefaultDepth (display
, screen
));
1544 XFreePixmap (display
, mask_pixmap
);
1546 XCreatePixmap (display
, window
, width
, height
,
1547 XDefaultDepth (display
, screen
));
1551 XRenderFreePicture (display
, main_picture
);
1556 XRenderFreePicture (display
, mask_picture
);
1561 main_picture
= XRenderCreatePicture (display
, main_pixmap
,
1562 XRenderFindVisualFormat(display
,
1563 DefaultVisual(display
, screen
)), 0, 0);
1564 mask_picture
= XRenderCreatePicture (display
, mask_pixmap
,
1565 XRenderFindVisualFormat(display
,
1566 DefaultVisual(display
, screen
)), 0, 0);
1567 if (!main_picture
|| !mask_picture
)
1570 #endif /* HAVE_XRENDER */
1573 XFreePixmap (display
, mask_bitmap
);
1574 mask_bitmap
= XCreatePixmap (display
, window
, width
, height
, 1);
1576 pixmap
= use_mask
? main_pixmap
: mask_pixmap
;
1582 work_area_resize (Widget work_area
, void *me
,
1583 XmDrawingAreaCallbackStruct
* cbs
)
1586 Dimension width
, height
;
1591 stdarg (XtNwidth
, &width
);
1592 stdarg (XtNheight
, &height
);
1593 stdarg (XmNbackground
, &bgcolor
);
1594 XtGetValues (work_area
, args
, n
);
1596 view_height
= height
;
1598 color
.pixel
= bgcolor
;
1599 XQueryColor (display
, colormap
, &color
);
1601 bggreen
= color
.green
;
1602 bgblue
= color
.blue
;
1607 work_area_make_pixmaps (view_width
, view_height
);
1613 work_area_first_expose (Widget work_area
, void *me
,
1614 XmDrawingAreaCallbackStruct
* cbs
)
1617 Dimension width
, height
;
1618 static char dashes
[] = { 4, 4 };
1620 window
= XtWindow (work_area
);
1621 my_gc
= XCreateGC (display
, window
, 0, 0);
1623 arc1_gc
= XCreateGC (display
, window
, 0, 0);
1624 c
= lesstif_parse_color ("#804000");
1625 XSetForeground (display
, arc1_gc
, c
);
1626 arc2_gc
= XCreateGC (display
, window
, 0, 0);
1627 c
= lesstif_parse_color ("#004080");
1628 XSetForeground (display
, arc2_gc
, c
);
1629 XSetLineAttributes (display
, arc1_gc
, 1, LineOnOffDash
, 0, 0);
1630 XSetLineAttributes (display
, arc2_gc
, 1, LineOnOffDash
, 0, 0);
1631 XSetDashes (display
, arc1_gc
, 0, dashes
, 2);
1632 XSetDashes (display
, arc2_gc
, 0, dashes
, 2);
1635 stdarg (XtNwidth
, &width
);
1636 stdarg (XtNheight
, &height
);
1637 stdarg (XmNbackground
, &bgcolor
);
1638 XtGetValues (work_area
, args
, n
);
1640 view_height
= height
;
1642 offlimit_color
= lesstif_parse_color (Settings
.OffLimitColor
);
1643 grid_color
= lesstif_parse_color (Settings
.GridColor
);
1645 bg_gc
= XCreateGC (display
, window
, 0, 0);
1646 XSetForeground (display
, bg_gc
, bgcolor
);
1648 work_area_make_pixmaps (width
, height
);
1653 XRenderPictureAttributes pa
;
1654 XRenderColor a
= {0, 0, 0, 0x8000};
1656 pale_pixmap
= XCreatePixmap (display
, window
, 1, 1, 8);
1658 pale_picture
= XRenderCreatePicture (display
, pale_pixmap
,
1659 XRenderFindStandardFormat(display
, PictStandardA8
),
1662 XRenderFillRectangle(display
, PictOpSrc
, pale_picture
, &a
, 0, 0, 1, 1);
1666 #endif /* HAVE_XRENDER */
1668 clip_gc
= XCreateGC (display
, window
, 0, 0);
1669 bset_gc
= XCreateGC (display
, mask_bitmap
, 0, 0);
1670 XSetForeground (display
, bset_gc
, 1);
1671 bclear_gc
= XCreateGC (display
, mask_bitmap
, 0, 0);
1672 XSetForeground (display
, bclear_gc
, 0);
1674 XtRemoveCallback (work_area
, XmNexposeCallback
,
1675 (XtCallbackProc
) work_area_first_expose
, 0);
1676 XtAddCallback (work_area
, XmNexposeCallback
,
1677 (XtCallbackProc
) work_area_expose
, 0);
1678 lesstif_invalidate_all ();
1682 make_message (char *name
, Widget left
, int resizeable
)
1688 stdarg (XmNleftAttachment
, XmATTACH_WIDGET
);
1689 stdarg (XmNleftWidget
, XtParent(left
));
1693 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
1695 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
1696 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
1697 stdarg (XmNshadowType
, XmSHADOW_IN
);
1698 stdarg (XmNshadowThickness
, 1);
1699 stdarg (XmNalignment
, XmALIGNMENT_CENTER
);
1700 stdarg (XmNmarginWidth
, 4);
1701 stdarg (XmNmarginHeight
, 1);
1703 stdarg (XmNresizePolicy
, XmRESIZE_GROW
);
1704 f
= XmCreateForm (messages
, name
, args
, n
);
1707 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
1708 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
1709 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
1710 stdarg (XmNrightAttachment
, XmATTACH_FORM
);
1711 w
= XmCreateLabel (f
, name
, args
, n
);
1717 lesstif_do_export (HID_Attr_Val
* options
)
1719 Dimension width
, height
;
1721 Widget work_area_frame
;
1724 stdarg (XtNwidth
, &width
);
1725 stdarg (XtNheight
, &height
);
1726 XtGetValues (appwidget
, args
, n
);
1730 if (width
> XDisplayWidth (display
, screen
))
1731 width
= XDisplayWidth (display
, screen
);
1734 if (height
> XDisplayHeight (display
, screen
))
1735 height
= XDisplayHeight (display
, screen
);
1738 stdarg (XmNwidth
, width
);
1739 stdarg (XmNheight
, height
);
1740 XtSetValues (appwidget
, args
, n
);
1742 stdarg (XmNspacing
, 0);
1743 mainwind
= XmCreateMainWindow (appwidget
, "mainWind", args
, n
);
1744 XtManageChild (mainwind
);
1747 stdarg (XmNmarginWidth
, 0);
1748 stdarg (XmNmarginHeight
, 0);
1749 menu
= lesstif_menu (mainwind
, "menubar", args
, n
);
1750 XtManageChild (menu
);
1753 stdarg (XmNshadowType
, XmSHADOW_IN
);
1755 XmCreateFrame (mainwind
, "work_area_frame", args
, n
);
1756 XtManageChild (work_area_frame
);
1759 do_color (Settings
.BackgroundColor
, XmNbackground
);
1760 work_area
= XmCreateDrawingArea (work_area_frame
, "work_area", args
, n
);
1761 XtManageChild (work_area
);
1762 XtAddCallback (work_area
, XmNexposeCallback
,
1763 (XtCallbackProc
) work_area_first_expose
, 0);
1764 XtAddCallback (work_area
, XmNresizeCallback
,
1765 (XtCallbackProc
) work_area_resize
, 0);
1766 /* A regular callback won't work here, because lesstif swallows any
1767 Ctrl<Button>1 event. */
1768 XtAddEventHandler (work_area
,
1769 ButtonPressMask
| ButtonReleaseMask
1770 | PointerMotionMask
| PointerMotionHintMask
1771 | KeyPressMask
| KeyReleaseMask
1772 | EnterWindowMask
| LeaveWindowMask
,
1773 0, work_area_input
, 0);
1776 stdarg (XmNorientation
, XmVERTICAL
);
1777 stdarg (XmNprocessingDirection
, XmMAX_ON_BOTTOM
);
1778 stdarg (XmNmaximum
, PCB
->MaxHeight
? PCB
->MaxHeight
: 1);
1779 vscroll
= XmCreateScrollBar (mainwind
, "vscroll", args
, n
);
1780 XtAddCallback (vscroll
, XmNvalueChangedCallback
,
1781 (XtCallbackProc
) scroll_callback
, (XtPointer
) & view_top_y
);
1782 XtAddCallback (vscroll
, XmNdragCallback
, (XtCallbackProc
) scroll_callback
,
1783 (XtPointer
) & view_top_y
);
1784 XtManageChild (vscroll
);
1787 stdarg (XmNorientation
, XmHORIZONTAL
);
1788 stdarg (XmNmaximum
, PCB
->MaxWidth
? PCB
->MaxWidth
: 1);
1789 hscroll
= XmCreateScrollBar (mainwind
, "hscroll", args
, n
);
1790 XtAddCallback (hscroll
, XmNvalueChangedCallback
,
1791 (XtCallbackProc
) scroll_callback
, (XtPointer
) & view_left_x
);
1792 XtAddCallback (hscroll
, XmNdragCallback
, (XtCallbackProc
) scroll_callback
,
1793 (XtPointer
) & view_left_x
);
1794 XtManageChild (hscroll
);
1797 stdarg (XmNresize
, true);
1798 stdarg (XmNresizePolicy
, XmRESIZE_ANY
);
1799 messages
= XmCreateForm (mainwind
, "messages", args
, n
);
1800 XtManageChild (messages
);
1803 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
1804 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
1805 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
1806 stdarg (XmNrightAttachment
, XmATTACH_FORM
);
1807 stdarg (XmNalignment
, XmALIGNMENT_CENTER
);
1808 stdarg (XmNshadowThickness
, 2);
1809 m_click
= XmCreateLabel (messages
, "click", args
, n
);
1812 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
1813 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
1814 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
1815 stdarg (XmNlabelString
, XmStringCreateLocalized ("Command: "));
1816 m_cmd_label
= XmCreateLabel (messages
, "command", args
, n
);
1819 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
1820 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
1821 stdarg (XmNleftAttachment
, XmATTACH_WIDGET
);
1822 stdarg (XmNleftWidget
, m_cmd_label
);
1823 stdarg (XmNrightAttachment
, XmATTACH_FORM
);
1824 stdarg (XmNshadowThickness
, 1);
1825 stdarg (XmNhighlightThickness
, 0);
1826 stdarg (XmNmarginWidth
, 2);
1827 stdarg (XmNmarginHeight
, 2);
1828 m_cmd
= XmCreateTextField (messages
, "command", args
, n
);
1829 XtAddCallback (m_cmd
, XmNactivateCallback
,
1830 (XtCallbackProc
) command_callback
, 0);
1831 XtAddCallback (m_cmd
, XmNlosingFocusCallback
,
1832 (XtCallbackProc
) command_callback
, 0);
1833 XtAddEventHandler (m_cmd
, KeyPressMask
, 0, command_event_handler
, 0);
1835 m_mark
= make_message ("m_mark", 0, 0);
1836 m_crosshair
= make_message ("m_crosshair", m_mark
, 0);
1837 m_grid
= make_message ("m_grid", m_crosshair
, 1);
1838 m_zoom
= make_message ("m_zoom", m_grid
, 1);
1839 lesstif_m_layer
= make_message ("m_layer", m_zoom
, 0);
1840 m_mode
= make_message ("m_mode", lesstif_m_layer
, 1);
1841 m_rats
= make_message ("m_rats", m_mode
, 1);
1842 m_status
= make_message ("m_status", m_mode
, 1);
1844 XtUnmanageChild (XtParent (m_mark
));
1845 XtUnmanageChild (XtParent (m_rats
));
1848 stdarg (XmNrightAttachment
, XmATTACH_FORM
);
1849 XtSetValues (XtParent (m_status
), args
, n
);
1851 /* We'll use this later. */
1853 stdarg (XmNleftWidget
, XtParent (m_mark
));
1854 XtSetValues (XtParent (m_crosshair
), args
, n
);
1857 stdarg (XmNmessageWindow
, messages
);
1858 XtSetValues (mainwind
, args
, n
);
1860 if (background_image_file
)
1861 LoadBackgroundImage (background_image_file
);
1863 XtRealizeWidget (appwidget
);
1868 XtAppNextEvent (app_context
, &e
);
1869 XtDispatchEvent (&e
);
1872 PCBChanged (0, 0, 0, 0);
1874 XtAppMainLoop (app_context
);
1878 XrmOptionDescRec lesstif_options
[] = {
1881 XtResource lesstif_resources
[] = {
1893 cvtres_string_to_double (Display
* d
, XrmValue
* args
, Cardinal
* num_args
,
1894 XrmValue
* from
, XrmValue
* to
,
1895 XtPointer
* converter_data
)
1898 rv
= strtod ((char *) from
->addr
, 0);
1900 *(double *) to
->addr
= rv
;
1902 to
->addr
= (XPointer
) & rv
;
1903 to
->size
= sizeof (rv
);
1908 mainwind_delete_cb ()
1910 hid_action ("Quit");
1914 lesstif_listener_cb (XtPointer client_data
, int *fid
, XtInputId
*id
)
1919 if ((nbytes
= read (*fid
, buf
, BUFSIZ
)) == -1)
1920 perror ("lesstif_listener_cb");
1925 hid_parse_actions (buf
);
1931 lesstif_parse_arguments (int *argc
, char ***argv
)
1935 int acount
= 0, amax
;
1936 int rcount
= 0, rmax
;
1938 XrmOptionDescRec
*new_options
;
1939 XtResource
*new_resources
;
1940 val_union
*new_values
;
1941 int render_event
, render_error
;
1943 XtSetTypeConverter (XtRString
,
1945 cvtres_string_to_double
, NULL
, 0, XtCacheAll
, NULL
);
1947 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
1948 for (i
= 0; i
< ha
->n
; i
++)
1950 HID_Attribute
*a
= ha
->attributes
+ i
;
1967 amax
= acount
+ XtNumber (lesstif_options
);
1972 new_options
= malloc ((amax
+ 1) * sizeof (XrmOptionDescRec
));
1975 memcpy (new_options
+ acount
, lesstif_options
, sizeof (lesstif_options
));
1980 rmax
= rcount
+ XtNumber (lesstif_resources
);
1985 new_resources
= malloc ((rmax
+ 1) * sizeof (XtResource
));
1986 new_values
= malloc ((rmax
+ 1) * sizeof (val_union
));
1988 memcpy (new_resources
+ acount
, lesstif_resources
,
1989 sizeof (lesstif_resources
));
1993 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
1994 for (i
= 0; i
< ha
->n
; i
++)
1996 HID_Attribute
*a
= ha
->attributes
+ i
;
1997 XrmOptionDescRec
*o
= new_options
+ acount
;
1998 char *tmpopt
, *tmpres
;
1999 XtResource
*r
= new_resources
+ rcount
;
2001 tmpopt
= (char *) malloc (strlen (a
->name
) + 3);
2002 tmpopt
[0] = tmpopt
[1] = '-';
2003 strcpy (tmpopt
+ 2, a
->name
);
2006 tmpres
= (char *) malloc (strlen (a
->name
) + 2);
2008 strcpy (tmpres
+ 1, a
->name
);
2009 o
->specifier
= tmpres
;
2017 o
->argKind
= XrmoptionSepArg
;
2022 o
->argKind
= XrmoptionNoArg
;
2030 r
->resource_name
= a
->name
;
2031 r
->resource_class
= a
->name
;
2032 r
->resource_offset
= sizeof (val_union
) * rcount
;
2037 r
->resource_type
= XtRInt
;
2038 r
->default_type
= XtRInt
;
2039 r
->resource_size
= sizeof (int);
2040 r
->default_addr
= &(a
->default_val
.int_value
);
2044 r
->resource_type
= XtRDouble
;
2045 r
->default_type
= XtRDouble
;
2046 r
->resource_size
= sizeof (double);
2047 r
->default_addr
= &(a
->default_val
.real_value
);
2052 r
->resource_type
= XtRString
;
2053 r
->default_type
= XtRString
;
2054 r
->resource_size
= sizeof (char *);
2055 r
->default_addr
= a
->default_val
.str_value
;
2059 r
->resource_type
= XtRBoolean
;
2060 r
->default_type
= XtRInt
;
2061 r
->resource_size
= sizeof (int);
2062 r
->default_addr
= &(a
->default_val
.int_value
);
2070 for (i
= 0; i
< XtNumber (lesstif_resources
); i
++)
2072 XtResource
*r
= new_resources
+ rcount
;
2073 r
->resource_offset
= sizeof (val_union
) * rcount
;
2079 stdarg (XmNdeleteResponse
, XmDO_NOTHING
);
2081 appwidget
= XtAppInitialize (&app_context
,
2083 new_options
, amax
, argc
, *argv
, 0, args
, n
);
2085 display
= XtDisplay (appwidget
);
2086 screen_s
= XtScreen (appwidget
);
2087 screen
= XScreenNumberOfScreen (screen_s
);
2088 colormap
= XDefaultColormap (display
, screen
);
2090 close_atom
= XmInternAtom (display
, "WM_DELETE_WINDOW", 0);
2091 XmAddWMProtocolCallback (appwidget
, close_atom
,
2092 (XtCallbackProc
) mainwind_delete_cb
, 0);
2094 /* XSynchronize(display, true); */
2096 XtGetApplicationResources (appwidget
, new_values
, new_resources
,
2100 use_xrender
= XRenderQueryExtension (display
, &render_event
, &render_error
) &&
2101 XRenderFindVisualFormat (display
, DefaultVisual(display
, screen
));
2102 #endif /* HAVE_XRENDER */
2105 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
2106 for (i
= 0; i
< ha
->n
; i
++)
2108 HID_Attribute
*a
= ha
->attributes
+ i
;
2109 val_union
*v
= new_values
+ rcount
;
2114 *(int *) a
->value
= v
->i
;
2116 a
->default_val
.int_value
= v
->i
;
2121 *(char *) a
->value
= v
->i
;
2123 a
->default_val
.int_value
= v
->i
;
2128 *(double *) a
->value
= v
->f
;
2130 a
->default_val
.real_value
= v
->f
;
2136 *(char **) a
->value
= v
->s
;
2138 a
->default_val
.str_value
= v
->s
;
2146 /* redefine colormap, if requested via "-install" */
2147 if (use_private_colormap
)
2149 colormap
= XCopyColormapAndFree (display
, colormap
);
2150 XtVaSetValues (appwidget
, XtNcolormap
, colormap
, NULL
);
2153 /* listen on standard input for actions */
2156 XtAppAddInput (app_context
, fileno (stdin
), (XtPointer
) XtInputReadMask
,
2157 lesstif_listener_cb
, NULL
);
2164 static XPoint
*points
= 0;
2165 static int npoints
= 0;
2166 int x1
, y1
, x2
, y2
, n
, prevx
;
2168 static GC grid_gc
= 0;
2170 if (!Settings
.DrawGrid
)
2172 if (Vz (PCB
->Grid
) < MIN_GRID_DISTANCE
)
2176 grid_gc
= XCreateGC (display
, window
, 0, 0);
2177 XSetFunction (display
, grid_gc
, GXxor
);
2178 XSetForeground (display
, grid_gc
, grid_color
);
2182 x2
= GRIDFIT_X (Px (0), PCB
->Grid
);
2183 x1
= GRIDFIT_X (Px (view_width
), PCB
->Grid
);
2186 if (Vx (x1
) >= view_width
)
2191 x1
= GRIDFIT_X (Px (0), PCB
->Grid
);
2192 x2
= GRIDFIT_X (Px (view_width
), PCB
->Grid
);
2195 if (Vx (x2
) >= view_width
)
2200 y2
= GRIDFIT_Y (Py (0), PCB
->Grid
);
2201 y1
= GRIDFIT_Y (Py (view_height
), PCB
->Grid
);
2204 if (Vy (y1
) >= view_height
)
2209 y1
= GRIDFIT_Y (Py (0), PCB
->Grid
);
2210 y2
= GRIDFIT_Y (Py (view_height
), PCB
->Grid
);
2213 if (Vy (y2
) >= view_height
)
2216 n
= (int) ((x2
- x1
) / PCB
->Grid
+ 0.5) + 1;
2221 MyRealloc (points
, npoints
* sizeof (XPoint
), "lesstif_draw_grid");
2225 for (x
= x1
; x
<= x2
; x
+= PCB
->Grid
)
2231 points
[n
].x
-= prevx
;
2237 for (y
= y1
; y
<= y2
; y
+= PCB
->Grid
)
2241 XDrawPoints (display
, pixmap
, grid_gc
, points
, n
, CoordModePrevious
);
2246 coords_to_widget (int x
, int y
, Widget w
, int prev_state
)
2248 int this_state
= prev_state
;
2249 static char buf
[60];
2254 if (Settings
.grid_units_mm
)
2259 g
= PCB_TO_MM (PCB
->Grid
);
2264 dx
= PCB_TO_MIL (x
);
2265 dy
= PCB_TO_MIL (y
);
2266 g
= PCB_TO_MIL (PCB
->Grid
);
2268 if (x
< 0 && prev_state
>= 0)
2270 else if (((int) (g
* 10000 + 0.5) % 10000) == 0)
2272 const char *fmt
= prev_state
< 0 ? "%+d, %+d" : "%d, %d";
2273 sprintf (buf
, fmt
, (int) (dx
+ 0.5), (int) (dy
+ 0.5));
2274 this_state
= 2 + Settings
.grid_units_mm
;
2277 else if (PCB
->Grid
<= 20 && Settings
.grid_units_mm
)
2279 const char *fmt
= prev_state
< 0 ? "%+.3f, %+.3f" : "%.3f, %.3f";
2280 sprintf (buf
, fmt
, dx
, dy
);
2281 this_state
= 4 + Settings
.grid_units_mm
;
2286 const char *fmt
= prev_state
< 0 ? "%+.2f, %+.2f" : "%.2f, %.2f";
2287 sprintf (buf
, fmt
, dx
, dy
);
2288 this_state
= 4 + Settings
.grid_units_mm
;
2291 if (prev_state
< 0 && (x
|| y
))
2293 int angle
= atan2 (dy
, -dx
) * 180 / M_PI
;
2294 double dist
= sqrt (dx
* dx
+ dy
* dy
);
2296 sprintf (buf
+ strlen (buf
), " (%.2f", dist
);
2298 sprintf (buf
+ strlen (buf
), " (%d", (int) (dist
+ 0.5));
2299 sprintf (buf
+ strlen (buf
), ", %d\260)", angle
);
2301 ms
= XmStringCreateLocalized (buf
);
2303 stdarg (XmNlabelString
, ms
);
2304 XtSetValues (w
, args
, n
);
2309 pcb2str (int pcbval
)
2311 static char buf
[20][20];
2312 static int bufp
= 0;
2315 bufp
= (bufp
+ 1) % 20;
2316 if (Settings
.grid_units_mm
)
2317 d
= PCB_TO_MM (pcbval
);
2319 d
= PCB_TO_MIL (pcbval
);
2321 if ((int) (d
* 100 + 0.5) == (int) (d
+ 0.005) * 100)
2322 sprintf (buf
[bufp
], "%d", (int) d
);
2324 sprintf (buf
[bufp
], "%.2f", d
);
2328 #define u(x) pcb2str(x)
2332 lesstif_update_status_line ()
2335 char *s45
= cur_clip ();
2339 switch (Settings
.Mode
)
2342 sprintf (buf
, "%s/%s \370=%s", u (S
.ViaThickness
),
2343 u (S
.Keepaway
), u (S
.ViaDrillingHole
));
2347 sprintf (buf
, "%s/%s %s", u (S
.LineThickness
), u (S
.Keepaway
), s45
);
2349 case RECTANGLE_MODE
:
2351 sprintf (buf
, "%s %s", u (S
.Keepaway
), s45
);
2354 sprintf (buf
, "%s", u (S
.TextScale
));
2358 case INSERTPOINT_MODE
:
2359 case RUBBERBANDMOVE_MODE
:
2360 sprintf (buf
, "%s", s45
);
2363 case PASTEBUFFER_MODE
:
2372 xs
= XmStringCreateLocalized (buf
);
2374 stdarg (XmNlabelString
, xs
);
2375 XtSetValues (m_status
, args
, n
);
2381 static int idle_proc_set
= 0;
2382 static int need_redraw
= 0;
2385 idle_proc (XtPointer dummy
)
2391 lesstif_use_mask (0);
2393 pixmap
= main_pixmap
;
2398 region
.X2
= Px (view_width
);
2399 region
.Y2
= Py (view_height
);
2402 int tmp
= region
.X1
;
2403 region
.X1
= region
.X2
;
2408 int tmp
= region
.Y1
;
2409 region
.Y1
= region
.Y2
;
2412 XSetForeground (display
, bg_gc
, bgcolor
);
2413 XFillRectangle (display
, main_pixmap
, bg_gc
, 0, 0, mx
, my
);
2414 if (region
.X2
> PCB
->MaxWidth
|| region
.Y2
> PCB
->MaxHeight
)
2416 XSetForeground (display
, bg_gc
, offlimit_color
);
2417 if (region
.X2
> PCB
->MaxWidth
)
2419 mx
= Vx (PCB
->MaxWidth
);
2421 XFillRectangle (display
, main_pixmap
, bg_gc
, 0, 0,
2424 XFillRectangle (display
, main_pixmap
, bg_gc
, mx
+1, 0,
2425 view_width
- mx
+ 1, my
);
2428 if (region
.Y2
> PCB
->MaxHeight
)
2430 my
= Vy (PCB
->MaxHeight
) + 1;
2432 XFillRectangle (display
, main_pixmap
, bg_gc
, 0, 0, mx
,
2435 XFillRectangle (display
, main_pixmap
, bg_gc
, 0, my
, mx
,
2436 view_height
- my
+ 1);
2439 DrawBackgroundImage();
2440 hid_expose_callback (&lesstif_gui
, ®ion
, 0);
2442 lesstif_use_mask (0);
2443 XSetFunction (display
, my_gc
, GXcopy
);
2444 XCopyArea (display
, main_pixmap
, window
, my_gc
, 0, 0, view_width
,
2452 static int c_x
= -2, c_y
= -2;
2453 static MarkType saved_mark
;
2454 if (crosshair_x
!= c_x
|| crosshair_y
!= c_y
2455 || memcmp (&saved_mark
, &Marked
, sizeof (MarkType
)))
2457 static int last_state
= 0;
2458 static int this_state
= 0;
2464 coords_to_widget (crosshair_x
, crosshair_y
, m_crosshair
,
2467 coords_to_widget (crosshair_x
- Marked
.X
, crosshair_y
- Marked
.Y
,
2470 if (Marked
.status
!= saved_mark
.status
)
2474 XtManageChild (XtParent (m_mark
));
2475 XtManageChild (m_mark
);
2477 stdarg (XmNleftAttachment
, XmATTACH_WIDGET
);
2478 stdarg (XmNleftWidget
, XtParent (m_mark
));
2479 XtSetValues (XtParent (m_crosshair
), args
, n
);
2484 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
2485 XtSetValues (XtParent (m_crosshair
), args
, n
);
2486 XtUnmanageChild (XtParent (m_mark
));
2488 last_state
= this_state
+ 100;
2490 memcpy (&saved_mark
, &Marked
, sizeof (MarkType
));
2492 /* This is obtuse. We want to enable XmRESIZE_ANY long enough
2493 to shrink to fit the new format (if any), then switch it
2494 back to XmRESIZE_GROW to prevent it from shrinking due to
2495 changes in the number of actual digits printed. Thus, when
2496 you switch from a small grid and %.2f formats to a large
2497 grid and %d formats, you aren't punished with a wide and
2498 mostly white-space label widget. "this_state" indicates
2499 which of the above formats we're using. "last_state" is
2500 either zero (when resizing) or the same as "this_state"
2501 (when grow-only), or a non-zero but not "this_state" which
2502 means we need to start a resize cycle. */
2503 if (this_state
!= last_state
&& last_state
)
2506 stdarg (XmNresizePolicy
, XmRESIZE_ANY
);
2507 XtSetValues (XtParent (m_mark
), args
, n
);
2508 XtSetValues (XtParent (m_crosshair
), args
, n
);
2511 else if (this_state
!= last_state
)
2514 stdarg (XmNresizePolicy
, XmRESIZE_GROW
);
2515 XtSetValues (XtParent (m_mark
), args
, n
);
2516 XtSetValues (XtParent (m_crosshair
), args
, n
);
2517 last_state
= this_state
;
2523 static double old_grid
= -1;
2524 static int old_gx
, old_gy
, old_mm
;
2526 if (PCB
->Grid
!= old_grid
2527 || PCB
->GridOffsetX
!= old_gx
2528 || PCB
->GridOffsetY
!= old_gy
|| Settings
.grid_units_mm
!= old_mm
)
2530 static char buf
[100];
2533 old_grid
= PCB
->Grid
;
2534 old_gx
= PCB
->GridOffsetX
;
2535 old_gy
= PCB
->GridOffsetY
;
2536 old_mm
= Settings
.grid_units_mm
;
2539 strcpy (buf
, "No Grid");
2543 if (Settings
.grid_units_mm
)
2545 g
= PCB_TO_MM (old_grid
);
2546 x
= PCB_TO_MM (old_gx
);
2547 y
= PCB_TO_MM (old_gy
);
2552 g
= PCB_TO_MIL (old_grid
);
2553 x
= PCB_TO_MIL (old_gx
);
2554 y
= PCB_TO_MIL (old_gy
);
2558 sprintf (buf
, "%g %s @%g,%g", g
, u
, x
, y
);
2560 sprintf (buf
, "%g %s", g
, u
);
2562 ms
= XmStringCreateLocalized (buf
);
2564 stdarg (XmNlabelString
, ms
);
2565 XtSetValues (m_grid
, args
, n
);
2570 static double old_zoom
= -1;
2571 static int old_zoom_units
= -1;
2572 if (view_zoom
!= old_zoom
|| Settings
.grid_units_mm
!= old_zoom_units
)
2574 static char buf
[100];
2579 old_zoom
= view_zoom
;
2580 old_zoom_units
= Settings
.grid_units_mm
;
2582 if (Settings
.grid_units_mm
)
2584 g
= PCB_TO_MM (view_zoom
);
2589 g
= PCB_TO_MIL (view_zoom
);
2592 if ((int) (g
* 100 + 0.5) == (int) (g
+ 0.005) * 100)
2593 sprintf (buf
, "%d %s/pix", (int) (g
+ 0.005), units
);
2595 sprintf (buf
, "%.2f %s/pix", g
, units
);
2596 ms
= XmStringCreateLocalized (buf
);
2598 stdarg (XmNlabelString
, ms
);
2599 XtSetValues (m_zoom
, args
, n
);
2604 if (old_cursor_mode
!= Settings
.Mode
)
2609 static int free_cursor
= 0;
2611 old_cursor_mode
= Settings
.Mode
;
2612 switch (Settings
.Mode
)
2616 cursor
= XC_X_cursor
;
2626 case RECTANGLE_MODE
:
2628 cursor
= XC_ul_angle
;
2632 cursor
= XC_sb_up_arrow
;
2634 case POLYGONHOLE_MODE
:
2636 cursor
= XC_sb_up_arrow
;
2638 case PASTEBUFFER_MODE
:
2648 cursor
= XC_exchange
;
2656 cursor
= XC_crosshair
;
2660 cursor
= XC_crosshair
;
2662 case INSERTPOINT_MODE
:
2666 case RUBBERBANDMOVE_MODE
:
2668 cursor
= XC_top_left_corner
;
2672 cursor
= XC_iron_cross
;
2676 cursor
= XC_question_arrow
;
2681 cursor
= XC_draped_box
;
2683 cursor
= XC_left_ptr
;
2690 ms
= XmStringCreateLocalized (s
);
2692 stdarg (XmNlabelString
, ms
);
2693 XtSetValues (m_mode
, args
, n
);
2697 XFreeCursor (display
, my_cursor
);
2702 static Pixmap nocur_source
= 0;
2703 static Pixmap nocur_mask
= 0;
2704 static Cursor nocursor
= 0;
2705 if (nocur_source
== 0)
2709 XCreateBitmapFromData (display
, window
, "\0", 1, 1);
2711 XCreateBitmapFromData (display
, window
, "\0", 1, 1);
2713 fg
.red
= fg
.green
= fg
.blue
= 65535;
2714 bg
.red
= bg
.green
= bg
.blue
= 0;
2715 fg
.flags
= bg
.flags
= DoRed
| DoGreen
| DoBlue
;
2716 nocursor
= XCreatePixmapCursor (display
, nocur_source
,
2717 nocur_mask
, &fg
, &bg
, 0, 0);
2719 my_cursor
= nocursor
;
2723 my_cursor
= XCreateFontCursor (display
, cursor
);
2726 XDefineCursor (display
, window
, my_cursor
);
2727 lesstif_update_status_line ();
2731 static char *old_clip
= 0;
2732 static int old_tscale
= -1;
2733 char *new_clip
= cur_clip ();
2735 if (new_clip
!= old_clip
|| Settings
.TextScale
!= old_tscale
)
2737 lesstif_update_status_line ();
2738 old_clip
= new_clip
;
2739 old_tscale
= Settings
.TextScale
;
2744 static int old_nrats
= -1;
2745 static char buf
[20];
2747 if (old_nrats
!= PCB
->Data
->RatN
)
2749 old_nrats
= PCB
->Data
->RatN
;
2750 sprintf(buf
, "%d rat%s", PCB
->Data
->RatN
, PCB
->Data
->RatN
== 1 ? "" : "s");
2751 if (PCB
->Data
->RatN
)
2753 XtManageChild(XtParent(m_rats
));
2754 XtManageChild(m_rats
);
2756 stdarg (XmNleftWidget
, m_rats
);
2757 XtSetValues (XtParent (m_status
), args
, n
);
2761 stdarg (XmNlabelString
, XmStringCreateLocalized (buf
));
2762 XtSetValues (m_rats
, args
, n
);
2764 if (!PCB
->Data
->RatN
)
2767 stdarg (XmNleftWidget
, m_mode
);
2768 XtSetValues (XtParent (m_status
), args
, n
);
2769 XtUnmanageChild(XtParent(m_rats
));
2774 lesstif_update_widget_flags ();
2782 lesstif_need_idle_proc ()
2784 if (idle_proc_set
|| window
== 0)
2786 XtAppAddWorkProc (app_context
, idle_proc
, 0);
2791 lesstif_invalidate_lr (int l
, int r
, int t
, int b
)
2801 lesstif_invalidate_all (void)
2803 lesstif_invalidate_lr (0, PCB
->MaxWidth
, 0, PCB
->MaxHeight
);
2807 lesstif_set_layer (const char *name
, int group
, int empty
)
2810 if (idx
>= 0 && idx
< max_layer
)
2812 idx
= PCB
->LayerGroups
.Entries
[idx
][0];
2814 if (idx
== LayerStack
[0]
2815 || GetLayerGroupNumberByNumber (idx
) ==
2816 GetLayerGroupNumberByNumber (LayerStack
[0]))
2826 if (idx
>= 0 && idx
< max_layer
+ 2)
2827 return pinout
? 1 : PCB
->Data
->Layer
[idx
].On
;
2830 switch (SL_TYPE (idx
))
2833 return pinout
? 0 : PCB
->InvisibleObjectsOn
;
2835 if (SL_MYSIDE (idx
) && !pinout
)
2836 return TEST_FLAG (SHOWMASKFLAG
, PCB
);
2839 if (SL_MYSIDE (idx
) || pinout
)
2840 return PCB
->ElementOn
;
2855 lesstif_make_gc (void)
2857 hidGC rv
= malloc (sizeof (hid_gc_struct
));
2858 memset (rv
, 0, sizeof (hid_gc_struct
));
2859 rv
->me_pointer
= &lesstif_gui
;
2864 lesstif_destroy_gc (hidGC gc
)
2870 lesstif_use_mask (int use_it
)
2874 if (use_it
== HID_FLUSH_DRAW_Q
)
2879 else if (use_it
== HID_LIVE_DRAWING
)
2885 else if (use_it
== HID_LIVE_DRAWING_OFF
)
2890 if ((TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
)) &&
2893 if ((use_it
== 0) == (use_mask
== 0))
2900 /* printf("use_mask(%d)\n", use_it); */
2904 XCreatePixmap (display
, window
, pixmap_w
, pixmap_h
,
2905 XDefaultDepth (display
, screen
));
2906 mask_bitmap
= XCreatePixmap (display
, window
, pixmap_w
, pixmap_h
, 1);
2910 pixmap
= mask_pixmap
;
2911 XSetForeground (display
, my_gc
, 0);
2912 XSetFunction (display
, my_gc
, GXcopy
);
2913 XFillRectangle (display
, mask_pixmap
, my_gc
,
2914 0, 0, view_width
, view_height
);
2915 XFillRectangle (display
, mask_bitmap
, bclear_gc
,
2916 0, 0, view_width
, view_height
);
2920 pixmap
= main_pixmap
;
2924 XRenderPictureAttributes pa
;
2926 pa
.clip_mask
= mask_bitmap
;
2927 XRenderChangePicture(display
, main_picture
, CPClipMask
, &pa
);
2928 XRenderComposite(display
, PictOpOver
, mask_picture
, pale_picture
,
2929 main_picture
, 0, 0, 0, 0, 0, 0, view_width
, view_height
);
2932 #endif /* HAVE_XRENDER */
2934 XSetClipMask (display
, clip_gc
, mask_bitmap
);
2935 XCopyArea (display
, mask_pixmap
, main_pixmap
, clip_gc
,
2936 0, 0, view_width
, view_height
, 0, 0);
2942 lesstif_set_color (hidGC gc
, const char *name
)
2944 static void *cache
= 0;
2946 static XColor color
, exact_color
;
2952 gc
->colorname
= name
;
2953 if (strcmp (name
, "erase") == 0)
2955 gc
->color
= bgcolor
;
2958 else if (strcmp (name
, "drill") == 0)
2960 gc
->color
= offlimit_color
;
2963 else if (hid_cache_color (0, name
, &cval
, &cache
))
2965 gc
->color
= cval
.lval
;
2970 if (!XAllocNamedColor (display
, colormap
, name
, &color
, &exact_color
))
2971 color
.pixel
= WhitePixel (display
, screen
);
2973 printf ("lesstif_set_color `%s' %08x rgb/%d/%d/%d\n",
2974 name
, color
.pixel
, color
.red
, color
.green
, color
.blue
);
2976 cval
.lval
= gc
->color
= color
.pixel
;
2977 hid_cache_color (1, name
, &cval
, &cache
);
2982 static int lastcolor
= -1, lastfade
= -1;
2983 if (gc
->color
== lastcolor
)
2984 gc
->color
= lastfade
;
2987 lastcolor
= gc
->color
;
2988 color
.pixel
= gc
->color
;
2990 XQueryColor (display
, colormap
, &color
);
2991 color
.red
= (bgred
+ color
.red
) / 2;
2992 color
.green
= (bggreen
+ color
.green
) / 2;
2993 color
.blue
= (bgblue
+ color
.blue
) / 2;
2994 XAllocColor (display
, colormap
, &color
);
2995 lastfade
= gc
->color
= color
.pixel
;
3003 int cap
, join
, width
;
3004 if (gc
->me_pointer
!= &lesstif_gui
)
3006 fprintf (stderr
, "Fatal: GC from another HID passed to lesstif HID\n");
3010 printf ("set_gc c%s %08lx w%d c%d x%d e%d\n",
3011 gc
->colorname
, gc
->color
, gc
->width
, gc
->cap
, gc
->xor, gc
->erase
);
3016 cap
= CapProjecting
;
3025 cap
= CapProjecting
;
3029 cap
= CapProjecting
;
3035 XSetFunction (display
, my_gc
, GXxor
);
3036 XSetForeground (display
, my_gc
, gc
->color
^ bgcolor
);
3040 XSetFunction (display
, my_gc
, GXcopy
);
3041 XSetForeground (display
, my_gc
, offlimit_color
);
3045 XSetFunction (display
, my_gc
, GXcopy
);
3046 XSetForeground (display
, my_gc
, gc
->color
);
3048 width
= Vz (gc
->width
);
3051 XSetLineAttributes (display
, my_gc
, width
, LineSolid
, cap
,
3056 mask_gc
= bclear_gc
;
3059 XSetLineAttributes (display
, mask_gc
, Vz (gc
->width
), LineSolid
, cap
,
3065 lesstif_set_line_cap (hidGC gc
, EndCapStyle style
)
3071 lesstif_set_line_width (hidGC gc
, int width
)
3077 lesstif_set_draw_xor (hidGC gc
, int xor)
3083 lesstif_set_draw_faded (hidGC gc
, int faded
)
3085 /* We don't use this */
3089 lesstif_set_line_cap_angle (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
3094 #define ISORT(a,b) if (a>b) { a^=b; b^=a; a^=b; }
3097 lesstif_draw_line (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
3099 double dx1
, dy1
, dx2
, dy2
;
3100 int vw
= Vz (gc
->width
);
3101 if ((pinout
|| TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
)) && gc
->erase
)
3104 printf ("draw_line %d,%d %d,%d @%d", x1
, y1
, x2
, y2
, gc
->width
);
3111 printf (" = %d,%d %d,%d %s\n", x1
, y1
, x2
, y2
, gc
->colorname
);
3115 if (! ClipLine (0, 0, view_width
, view_height
,
3116 &dx1
, &dy1
, &dx2
, &dy2
, vw
))
3126 if (gc
->cap
== Square_Cap
&& x1
== x2
&& y1
== y2
)
3128 XFillRectangle (display
, pixmap
, my_gc
, x1
- vw
/ 2, y1
- vw
/ 2, vw
,
3131 XFillRectangle (display
, mask_bitmap
, mask_gc
, x1
- vw
/ 2,
3132 y1
- vw
/ 2, vw
, vw
);
3136 XDrawLine (display
, pixmap
, my_gc
, x1
, y1
, x2
, y2
);
3138 XDrawLine (display
, mask_bitmap
, mask_gc
, x1
, y1
, x2
, y2
);
3143 lesstif_draw_arc (hidGC gc
, int cx
, int cy
, int width
, int height
,
3144 int start_angle
, int delta_angle
)
3146 if ((pinout
|| TEST_FLAG (THINDRAWFLAG
, PCB
)) && gc
->erase
)
3149 printf ("draw_arc %d,%d %dx%d s %d d %d", cx
, cy
, width
, height
, start_angle
, delta_angle
);
3152 height
= Vz (height
);
3153 cx
= Vx (cx
) - width
;
3154 cy
= Vy (cy
) - height
;
3157 start_angle
= 180 - start_angle
;
3158 delta_angle
= - delta_angle
;
3162 start_angle
= - start_angle
;
3163 delta_angle
= - delta_angle
;
3165 start_angle
= (start_angle
+ 360 + 180) % 360 - 180;
3167 printf (" = %d,%d %dx%d %d %s\n", cx
, cy
, width
, height
, gc
->width
,
3171 XDrawArc (display
, pixmap
, my_gc
, cx
, cy
,
3172 width
* 2, height
* 2, (start_angle
+ 180) * 64,
3174 if (use_mask
&& !TEST_FLAG (THINDRAWFLAG
, PCB
))
3175 XDrawArc (display
, mask_bitmap
, mask_gc
, cx
, cy
,
3176 width
* 2, height
* 2, (start_angle
+ 180) * 64,
3179 /* Enable this if you want to see the center and radii of drawn
3180 arcs, for debugging. */
3181 if (TEST_FLAG (THINDRAWFLAG
, PCB
)
3182 && delta_angle
!= 360)
3186 XDrawLine (display
, pixmap
, arc1_gc
, cx
, cy
,
3187 cx
- width
*cos(start_angle
*M_PI
/180),
3188 cy
+ width
*sin(start_angle
*M_PI
/180));
3189 XDrawLine (display
, pixmap
, arc2_gc
, cx
, cy
,
3190 cx
- width
*cos((start_angle
+delta_angle
)*M_PI
/180),
3191 cy
+ width
*sin((start_angle
+delta_angle
)*M_PI
/180));
3197 lesstif_draw_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
3199 int vw
= Vz (gc
->width
);
3200 if ((pinout
|| TEST_FLAG (THINDRAWFLAG
, PCB
)) && gc
->erase
)
3206 if (x1
< -vw
&& x2
< -vw
)
3208 if (y1
< -vw
&& y2
< -vw
)
3210 if (x1
> view_width
+ vw
&& x2
> view_width
+ vw
)
3212 if (y1
> view_height
+ vw
&& y2
> view_height
+ vw
)
3214 if (x1
> x2
) { int xt
= x1
; x1
= x2
; x2
= xt
; }
3215 if (y1
> y2
) { int yt
= y1
; y1
= y2
; y2
= yt
; }
3217 XDrawRectangle (display
, pixmap
, my_gc
, x1
, y1
, x2
- x1
+ 1, y2
- y1
+ 1);
3219 XDrawRectangle (display
, mask_bitmap
, mask_gc
, x1
, y1
, x2
- x1
+ 1,
3224 lesstif_fill_circle (hidGC gc
, int cx
, int cy
, int radius
)
3226 if (pinout
&& use_mask
&& gc
->erase
)
3228 if ((TEST_FLAG (THINDRAWFLAG
, PCB
) || TEST_FLAG(THINDRAWPOLYFLAG
, PCB
)) && gc
->erase
)
3231 printf ("fill_circle %d,%d %d", cx
, cy
, radius
);
3233 radius
= Vz (radius
);
3234 cx
= Vx (cx
) - radius
;
3235 cy
= Vy (cy
) - radius
;
3236 if (cx
< -2 * radius
|| cx
> view_width
)
3238 if (cy
< -2 * radius
|| cy
> view_height
)
3241 printf (" = %d,%d %d %lx %s\n", cx
, cy
, radius
, gc
->color
, gc
->colorname
);
3244 XFillArc (display
, pixmap
, my_gc
, cx
, cy
,
3245 radius
* 2, radius
* 2, 0, 360 * 64);
3247 XFillArc (display
, mask_bitmap
, mask_gc
, cx
, cy
,
3248 radius
* 2, radius
* 2, 0, 360 * 64);
3252 lesstif_fill_polygon (hidGC gc
, int n_coords
, int *x
, int *y
)
3254 static XPoint
*p
= 0;
3255 static int maxp
= 0;
3258 if (maxp
< n_coords
)
3260 maxp
= n_coords
+ 10;
3262 p
= (XPoint
*) realloc (p
, maxp
* sizeof (XPoint
));
3264 p
= (XPoint
*) malloc (maxp
* sizeof (XPoint
));
3267 for (i
= 0; i
< n_coords
; i
++)
3273 printf ("fill_polygon %d pts\n", n_coords
);
3276 XFillPolygon (display
, pixmap
, my_gc
, p
, n_coords
, Complex
,
3279 XFillPolygon (display
, mask_bitmap
, mask_gc
, p
, n_coords
, Complex
,
3284 lesstif_fill_rect (hidGC gc
, int x1
, int y1
, int x2
, int y2
)
3286 int vw
= Vz (gc
->width
);
3287 if ((pinout
|| TEST_FLAG (THINDRAWFLAG
, PCB
)) && gc
->erase
)
3293 if (x1
< -vw
&& x2
< -vw
)
3295 if (y1
< -vw
&& y2
< -vw
)
3297 if (x1
> view_width
+ vw
&& x2
> view_width
+ vw
)
3299 if (y1
> view_height
+ vw
&& y2
> view_height
+ vw
)
3301 if (x1
> x2
) { int xt
= x1
; x1
= x2
; x2
= xt
; }
3302 if (y1
> y2
) { int yt
= y1
; y1
= y2
; y2
= yt
; }
3304 XFillRectangle (display
, pixmap
, my_gc
, x1
, y1
, x2
- x1
+ 1,
3307 XFillRectangle (display
, mask_bitmap
, mask_gc
, x1
, y1
, x2
- x1
+ 1,
3312 lesstif_calibrate (double xval
, double yval
)
3318 lesstif_shift_is_pressed (void)
3320 return shift_pressed
;
3324 lesstif_control_is_pressed (void)
3326 return ctrl_pressed
;
3330 lesstif_mod1_is_pressed (void)
3335 extern void lesstif_get_coords (const char *msg
, int *x
, int *y
);
3338 lesstif_set_crosshair (int x
, int y
, int action
)
3340 if (crosshair_x
!= x
|| crosshair_y
!= y
)
3342 lesstif_show_crosshair(0);
3350 || x
> view_left_x
+ view_width
* view_zoom
3351 || y
< view_top_y
|| y
> view_top_y
+ view_height
* view_zoom
))
3353 view_left_x
= x
- (view_width
* view_zoom
) / 2;
3354 view_top_y
= y
- (view_height
* view_zoom
) / 2;
3355 lesstif_pan_fixup ();
3360 if (action
== HID_SC_PAN_VIEWPORT
)
3363 unsigned int keys_buttons
;
3364 int pos_x
, pos_y
, root_x
, root_y
;
3365 XQueryPointer (display
, window
, &root
, &child
,
3366 &root_x
, &root_y
, &pos_x
, &pos_y
, &keys_buttons
);
3368 view_left_x
= x
- (view_width
-pos_x
) * view_zoom
;
3370 view_left_x
= x
- pos_x
* view_zoom
;
3372 view_top_y
= y
- (view_height
-pos_y
) * view_zoom
;
3374 view_top_y
= y
- pos_y
* view_zoom
;
3375 lesstif_pan_fixup();
3376 action
= HID_SC_WARP_POINTER
;
3378 if (action
== HID_SC_WARP_POINTER
)
3381 XWarpPointer (display
, None
, window
, 0, 0, 0, 0, Vx(x
), Vy(y
));
3388 void (*func
) (hidval
);
3394 lesstif_timer_cb (XtPointer
* p
, XtIntervalId
* id
)
3396 TimerStruct
*ts
= (TimerStruct
*) p
;
3397 ts
->func (ts
->user_data
);
3402 lesstif_add_timer (void (*func
) (hidval user_data
),
3403 unsigned long milliseconds
, hidval user_data
)
3407 t
= (TimerStruct
*) malloc (sizeof (TimerStruct
));
3410 t
->user_data
= user_data
;
3411 t
->id
= XtAppAddTimeOut (app_context
, milliseconds
, (XtTimerCallbackProc
)lesstif_timer_cb
, t
);
3416 lesstif_stop_timer (hidval hv
)
3418 TimerStruct
*ts
= (TimerStruct
*) hv
.ptr
;
3419 XtRemoveTimeOut (ts
->id
);
3426 void (*func
) ( hidval
, int, unsigned int, hidval
);
3433 /* We need a wrapper around the hid file watch because to pass the correct flags
3436 lesstif_watch_cb (XtPointer client_data
, int *fid
, XtInputId
* id
)
3438 unsigned int pcb_condition
= 0;
3442 WatchStruct
*watch
= (WatchStruct
*)client_data
;
3445 fds
.events
= POLLIN
| POLLOUT
;
3447 condition
= fds
.revents
;
3449 // Should we only include those we were asked to watch?
3450 if (condition
& POLLIN
)
3451 pcb_condition
|= PCB_WATCH_READABLE
;
3452 if (condition
& POLLOUT
)
3453 pcb_condition
|= PCB_WATCH_WRITABLE
;
3454 if (condition
& POLLERR
)
3455 pcb_condition
|= PCB_WATCH_ERROR
;
3456 if (condition
& POLLHUP
)
3457 pcb_condition
|= PCB_WATCH_HANGUP
;
3459 x
.ptr
= (void *) watch
;
3460 watch
->func (x
, watch
->fd
, pcb_condition
, watch
->user_data
);
3466 lesstif_watch_file (int fd
, unsigned int condition
, void (*func
) (hidval watch
, int fd
, unsigned int condition
, hidval user_data
),
3469 WatchStruct
*watch
= malloc (sizeof(WatchStruct
));
3471 unsigned int xt_condition
= 0;
3473 if (condition
& PCB_WATCH_READABLE
)
3474 xt_condition
|= XtInputReadMask
;
3475 if (condition
& PCB_WATCH_WRITABLE
)
3476 xt_condition
|= XtInputWriteMask
;
3477 if (condition
& PCB_WATCH_ERROR
)
3478 xt_condition
|= XtInputExceptMask
;
3479 if (condition
& PCB_WATCH_HANGUP
)
3480 xt_condition
|= XtInputExceptMask
;
3483 watch
->user_data
= user_data
;
3485 watch
->id
= XtAppAddInput( app_context
, fd
, (XtPointer
) (size_t) xt_condition
, lesstif_watch_cb
, watch
);
3487 ret
.ptr
= (void *) watch
;
3492 lesstif_unwatch_file (hidval data
)
3494 WatchStruct
*watch
= (WatchStruct
*)data
.ptr
;
3495 XtRemoveInput( watch
->id
);
3502 void (*func
) (hidval user_data
);
3506 static void lesstif_block_hook_cb(XtPointer user_data
);
3509 lesstif_block_hook_cb (XtPointer user_data
)
3511 BlockHookStruct
*block_hook
= (BlockHookStruct
*)user_data
;
3512 block_hook
->func( block_hook
->user_data
);
3516 lesstif_add_block_hook (void (*func
) (hidval data
), hidval user_data
)
3519 BlockHookStruct
*block_hook
= malloc( sizeof( BlockHookStruct
));
3521 block_hook
->func
= func
;
3522 block_hook
->user_data
= user_data
;
3524 block_hook
->id
= XtAppAddBlockHook( app_context
, lesstif_block_hook_cb
, (XtPointer
)block_hook
);
3526 ret
.ptr
= (void *) block_hook
;
3531 lesstif_stop_block_hook (hidval mlpoll
)
3533 BlockHookStruct
*block_hook
= (BlockHookStruct
*)mlpoll
.ptr
;
3534 XtRemoveBlockHook( block_hook
->id
);
3539 extern void lesstif_logv (const char *fmt
, va_list ap
);
3541 extern int lesstif_confirm_dialog (char *msg
, ...);
3543 extern int lesstif_close_confirm_dialog ();
3545 extern void lesstif_report_dialog (char *title
, char *msg
);
3548 lesstif_attribute_dialog (HID_Attribute
* attrs
,
3549 int n_attrs
, HID_Attr_Val
* results
,
3550 const char * title
, const char * descr
);
3553 pinout_callback (Widget da
, PinoutData
* pd
,
3554 XmDrawingAreaCallbackStruct
* cbs
)
3557 int save_vx
, save_vy
, save_vw
, save_vh
;
3558 int save_fx
, save_fy
;
3561 int reason
= cbs
? cbs
->reason
: 0;
3563 if (pd
->window
== 0 && reason
== XmCR_RESIZE
)
3565 if (pd
->window
== 0 || reason
== XmCR_RESIZE
)
3571 stdarg (XmNwidth
, &w
);
3572 stdarg (XmNheight
, &h
);
3573 XtGetValues (da
, args
, n
);
3575 pd
->window
= XtWindow (da
);
3578 pd
->zoom
= (pd
->right
- pd
->left
+ 1) / (double) w
;
3579 z
= (pd
->bottom
- pd
->top
+ 1) / (double) h
;
3583 pd
->x
= (pd
->left
+ pd
->right
) / 2 - pd
->v_width
* pd
->zoom
/ 2;
3584 pd
->y
= (pd
->top
+ pd
->bottom
) / 2 - pd
->v_height
* pd
->zoom
/ 2;
3587 save_vx
= view_left_x
;
3588 save_vy
= view_top_y
;
3589 save_vz
= view_zoom
;
3590 save_vw
= view_width
;
3591 save_vh
= view_height
;
3596 pixmap
= pd
->window
;
3597 view_left_x
= pd
->x
;
3599 view_zoom
= pd
->zoom
;
3600 view_width
= pd
->v_width
;
3601 view_height
= pd
->v_height
;
3603 flip_x
= flip_y
= 0;
3607 region
.X2
= PCB
->MaxWidth
;
3608 region
.Y2
= PCB
->MaxHeight
;
3610 XFillRectangle (display
, pixmap
, bg_gc
, 0, 0, pd
->v_width
, pd
->v_height
);
3611 hid_expose_callback (&lesstif_gui
, ®ion
, pd
->item
);
3614 view_left_x
= save_vx
;
3615 view_top_y
= save_vy
;
3616 view_zoom
= save_vz
;
3617 view_width
= save_vw
;
3618 view_height
= save_vh
;
3625 pinout_unmap (Widget w
, PinoutData
* pd
, void *v
)
3628 pd
->prev
->next
= pd
->next
;
3632 pd
->next
->prev
= pd
->prev
;
3633 XtDestroyWidget (XtParent (pd
->form
));
3638 lesstif_show_item (void *item
)
3645 for (pd
= pinouts
; pd
; pd
= pd
->next
)
3646 if (pd
->item
== item
)
3651 pd
= (PinoutData
*) MyCalloc (1, sizeof (PinoutData
), "lesstif_show_item");
3655 extents
= hid_get_extents (item
);
3656 pd
->left
= extents
->X1
;
3657 pd
->right
= extents
->X2
;
3658 pd
->top
= extents
->Y1
;
3659 pd
->bottom
= extents
->Y2
;
3661 if (pd
->left
> pd
->right
)
3669 pd
->next
->prev
= pd
;
3674 pd
->form
= XmCreateFormDialog (mainwind
, "pinout", args
, n
);
3676 XtAddCallback (pd
->form
, XmNunmapCallback
, (XtCallbackProc
) pinout_unmap
,
3680 sqrt (200.0 * 200.0 /
3681 ((pd
->right
- pd
->left
+ 1.0) * (pd
->bottom
- pd
->top
+ 1.0)));
3684 stdarg (XmNwidth
, (int) (scale
* (pd
->right
- pd
->left
+ 1)));
3685 stdarg (XmNheight
, (int) (scale
* (pd
->bottom
- pd
->top
+ 1)));
3686 stdarg (XmNleftAttachment
, XmATTACH_FORM
);
3687 stdarg (XmNrightAttachment
, XmATTACH_FORM
);
3688 stdarg (XmNtopAttachment
, XmATTACH_FORM
);
3689 stdarg (XmNbottomAttachment
, XmATTACH_FORM
);
3690 da
= XmCreateDrawingArea (pd
->form
, "pinout", args
, n
);
3693 XtAddCallback (da
, XmNexposeCallback
, (XtCallbackProc
) pinout_callback
,
3695 XtAddCallback (da
, XmNresizeCallback
, (XtCallbackProc
) pinout_callback
,
3698 XtManageChild (pd
->form
);
3710 lesstif_progress (int so_far
, int total
, const char *message
)
3718 "LessTif - a Motif clone for X/Unix",
3722 1, /* poly before */
3726 lesstif_get_export_options
,
3728 lesstif_parse_arguments
,
3729 lesstif_invalidate_lr
,
3730 lesstif_invalidate_all
,
3736 lesstif_set_line_cap
,
3737 lesstif_set_line_width
,
3738 lesstif_set_draw_xor
,
3739 lesstif_set_draw_faded
,
3740 lesstif_set_line_cap_angle
,
3744 lesstif_fill_circle
,
3745 lesstif_fill_polygon
,
3746 common_fill_pcb_polygon
,
3747 common_thindraw_pcb_polygon
,
3751 lesstif_shift_is_pressed
,
3752 lesstif_control_is_pressed
,
3753 lesstif_mod1_is_pressed
,
3755 lesstif_set_crosshair
,
3759 lesstif_unwatch_file
,
3760 lesstif_add_block_hook
,
3761 lesstif_stop_block_hook
,
3765 lesstif_confirm_dialog
,
3766 lesstif_close_confirm_dialog
,
3767 lesstif_report_dialog
,
3770 lesstif_attribute_dialog
,
3774 0, /* lesstif_drc_gui */
3775 lesstif_attributes_dialog
3778 #include "dolists.h"
3783 hid_register_hid (&lesstif_gui
);
3784 #include "lesstif_lists.h"