1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 
5 #include <stdio.h>
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include "global.h"
11 #include "hid.h"
12 #include "hid_draw.h"
13 
14 #ifdef HAVE_LIBDMALLOC
15 #include <dmalloc.h>
16 #endif
17 
18 /* This is the "gui" that is installed at startup, and is used when
19    there is no other real GUI to use.  For the most part, it just
20    stops the application from (1) crashing randomly, and (2) doing
21    gui-specific things when it shouldn't.  */
22 
23 #define CRASH fprintf(stderr, "HID error: pcb called GUI function %s without having a GUI available.\n", __FUNCTION__); abort()
24 
25 typedef struct hid_gc_struct
26 {
27   int nothing_interesting_here;
28 } hid_gc_struct;
29 
30 static HID_Attribute *
nogui_get_export_options(int * n_ret)31 nogui_get_export_options (int *n_ret)
32 {
33   CRASH;
34   return 0;
35 }
36 
37 static void
nogui_do_export(HID_Attr_Val * options)38 nogui_do_export (HID_Attr_Val * options)
39 {
40   CRASH;
41 }
42 
43 static void
nogui_parse_arguments(int * argc,char *** argv)44 nogui_parse_arguments (int *argc, char ***argv)
45 {
46   CRASH;
47 }
48 
49 static void
nogui_invalidate_lr(Coord l,Coord r,Coord t,Coord b)50 nogui_invalidate_lr (Coord l, Coord r, Coord t, Coord b)
51 {
52   printf("pcb: invalidate_lr() called without a GUI\n");
53   printf("This is ok, if you run an action script\n");
54 }
55 
56 static void
nogui_invalidate_all(void)57 nogui_invalidate_all (void)
58 {
59   CRASH;
60 }
61 
62 static int
nogui_set_layer(const char * name,int idx,int empty)63 nogui_set_layer (const char *name, int idx, int empty)
64 {
65   CRASH;
66   return 0;
67 }
68 
69 static void
nogui_end_layer(void)70 nogui_end_layer (void)
71 {
72 }
73 
74 static hidGC
nogui_make_gc(void)75 nogui_make_gc (void)
76 {
77   return 0;
78 }
79 
80 static void
nogui_destroy_gc(hidGC gc)81 nogui_destroy_gc (hidGC gc)
82 {
83 }
84 
85 static void
nogui_use_mask(enum mask_mode mode)86 nogui_use_mask (enum mask_mode mode)
87 {
88   CRASH;
89 }
90 
91 static void
nogui_set_color(hidGC gc,const char * name)92 nogui_set_color (hidGC gc, const char *name)
93 {
94   CRASH;
95 }
96 
97 static void
nogui_set_line_cap(hidGC gc,EndCapStyle style)98 nogui_set_line_cap (hidGC gc, EndCapStyle style)
99 {
100   CRASH;
101 }
102 
103 static void
nogui_set_line_width(hidGC gc,Coord width)104 nogui_set_line_width (hidGC gc, Coord width)
105 {
106   CRASH;
107 }
108 
109 static void
nogui_set_draw_xor(hidGC gc,int xor_)110 nogui_set_draw_xor (hidGC gc, int xor_)
111 {
112   CRASH;
113 }
114 
115 static void
nogui_set_draw_faded(hidGC gc,int faded)116 nogui_set_draw_faded (hidGC gc, int faded)
117 {
118 }
119 
120 static void
nogui_draw_line(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)121 nogui_draw_line (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
122 {
123   CRASH;
124 }
125 
126 static void
nogui_draw_arc(hidGC gc,Coord cx,Coord cy,Coord width,Coord height,Angle start_angle,Angle end_angle)127 nogui_draw_arc (hidGC gc, Coord cx, Coord cy, Coord width, Coord height,
128 		Angle start_angle, Angle end_angle)
129 {
130   CRASH;
131 }
132 
133 static void
nogui_draw_rect(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)134 nogui_draw_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
135 {
136   CRASH;
137 }
138 
139 static void
nogui_fill_circle(hidGC gc,Coord cx,Coord cy,Coord radius)140 nogui_fill_circle (hidGC gc, Coord cx, Coord cy, Coord radius)
141 {
142   CRASH;
143 }
144 
145 static void
nogui_fill_polygon(hidGC gc,int n_coords,Coord * x,Coord * y)146 nogui_fill_polygon (hidGC gc, int n_coords, Coord *x, Coord *y)
147 {
148   CRASH;
149 }
150 
151 static void
nogui_draw_pcb_polygon(hidGC gc,PolygonType * poly,const BoxType * clip_box)152 nogui_draw_pcb_polygon (hidGC gc, PolygonType *poly, const BoxType *clip_box)
153 {
154   CRASH;
155 }
156 
157 static void
nogui_fill_pcb_pad(hidGC gc,PadType * pad,bool clear,bool mask)158 nogui_fill_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
159 {
160   CRASH;
161 }
162 
163 static void
nogui_thindraw_pcb_pad(hidGC gc,PadType * pad,bool clear,bool mask)164 nogui_thindraw_pcb_pad (hidGC gc, PadType *pad, bool clear, bool mask)
165 {
166   CRASH;
167 }
168 
169 static void
nogui_fill_pcb_pv(hidGC fg_gc,hidGC bg_gc,PinType * pad,bool drawHole,bool mask)170 nogui_fill_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pad, bool drawHole, bool mask)
171 {
172   CRASH;
173 }
174 
175 static void
nogui_thindraw_pcb_pv(hidGC fg_gc,hidGC bg_gc,PinType * pad,bool drawHole,bool mask)176 nogui_thindraw_pcb_pv (hidGC fg_gc, hidGC bg_gc, PinType *pad, bool drawHole, bool mask)
177 {
178   CRASH;
179 }
180 
181 static void
nogui_fill_rect(hidGC gc,Coord x1,Coord y1,Coord x2,Coord y2)182 nogui_fill_rect (hidGC gc, Coord x1, Coord y1, Coord x2, Coord y2)
183 {
184   CRASH;
185 }
186 
187 static void
nogui_calibrate(double xval,double yval)188 nogui_calibrate (double xval, double yval)
189 {
190   CRASH;
191 }
192 
193 static int
nogui_shift_is_pressed(void)194 nogui_shift_is_pressed (void)
195 {
196   /* This is called from FitCrosshairIntoGrid() when the board is loaded.  */
197   return 0;
198 }
199 
200 static int
nogui_control_is_pressed(void)201 nogui_control_is_pressed (void)
202 {
203   CRASH;
204   return 0;
205 }
206 
207 static int
nogui_mod1_is_pressed(void)208 nogui_mod1_is_pressed (void)
209 {
210   CRASH;
211   return 0;
212 }
213 
214 static void
nogui_get_coords(const char * msg,Coord * x,Coord * y)215 nogui_get_coords (const char *msg, Coord *x, Coord *y)
216 {
217   CRASH;
218 }
219 
220 static void
nogui_set_crosshair(int x,int y,int action)221 nogui_set_crosshair (int x, int y, int action)
222 {
223 }
224 
225 static hidval
nogui_add_timer(void (* func)(hidval user_data),unsigned long milliseconds,hidval user_data)226 nogui_add_timer (void (*func) (hidval user_data),
227 		 unsigned long milliseconds, hidval user_data)
228 {
229   hidval rv;
230   CRASH;
231   rv.lval = 0;
232   return rv;
233 }
234 
235 static void
nogui_stop_timer(hidval timer)236 nogui_stop_timer (hidval timer)
237 {
238   CRASH;
239 }
240 
241 static hidval
nogui_watch_file(int fd,unsigned int condition,void (* func)(hidval watch,int fd,unsigned int condition,hidval user_data),hidval user_data)242 nogui_watch_file (int fd, unsigned int condition, void (*func) (hidval watch, int fd, unsigned int condition, hidval user_data),
243   hidval user_data)
244 {
245   hidval rv;
246   CRASH;
247   rv.lval = 0;
248   return rv;
249 }
250 
251 static void
nogui_unwatch_file(hidval watch)252 nogui_unwatch_file (hidval watch)
253 {
254   CRASH;
255 }
256 
257 static hidval
nogui_add_block_hook(void (* func)(hidval data),hidval data)258 nogui_add_block_hook (void (*func) (hidval data), hidval data)
259 {
260   hidval rv;
261   CRASH;
262   rv.ptr = NULL;
263   return rv;
264 }
265 
266 static void
nogui_stop_block_hook(hidval block_hook)267 nogui_stop_block_hook (hidval block_hook)
268 {
269   CRASH;
270 }
271 
272 static void
nogui_log(const char * fmt,...)273 nogui_log (const char *fmt, ...)
274 {
275   va_list ap;
276   va_start (ap, fmt);
277   vprintf (fmt, ap);
278   va_end (ap);
279 }
280 
281 static void
nogui_logv(const char * fmt,va_list ap)282 nogui_logv (const char *fmt, va_list ap)
283 {
284   vprintf (fmt, ap);
285 }
286 
287 /* Return a line of user input text, stripped of any newline characters.
288  * Returns NULL if the user simply presses enter, or otherwise gives no input.
289  */
290 #define MAX_LINE_LENGTH 1024
291 static char *
read_stdin_line(void)292 read_stdin_line (void)
293 {
294   static char buf[MAX_LINE_LENGTH];
295   char *s;
296   int i;
297 
298   s = fgets (buf, MAX_LINE_LENGTH, stdin);
299   if (s == NULL)
300     {
301       printf ("\n");
302       return NULL;
303     }
304 
305   /* Strip any trailing newline characters */
306   for (i = strlen (s) - 1; i >= 0; i--)
307     if (s[i] == '\r' || s[i] == '\n')
308       s[i] = '\0';
309 
310   if (s[0] == '\0')
311     return NULL;
312 
313   return strdup (s);
314 }
315 #undef MAX_LINE_LENGTH
316 
317 static int
nogui_confirm_dialog(char * msg,...)318 nogui_confirm_dialog (char *msg, ...)
319 {
320   char *answer;
321   int ret = 0;
322   bool valid_answer = false;
323   va_list args;
324 
325   do
326     {
327       va_start (args, msg);
328       vprintf (msg, args);
329       va_end (args);
330 
331       printf (" ? 0=cancel 1 = ok : ");
332 
333       answer = read_stdin_line ();
334 
335       if (answer == NULL)
336         continue;
337 
338       if (answer[0] == '0' && answer[1] == '\0')
339         {
340           ret = 0;
341           valid_answer = true;
342         }
343 
344       if (answer[0] == '1' && answer[1] == '\0')
345         {
346           ret = 1;
347           valid_answer = true;
348         }
349 
350       free (answer);
351     }
352   while (!valid_answer);
353   return ret;
354 }
355 
356 static int
nogui_close_confirm_dialog()357 nogui_close_confirm_dialog ()
358 {
359   return nogui_confirm_dialog (_("OK to lose data ?"), NULL);
360 }
361 
362 static void
nogui_report_dialog(char * title,char * msg)363 nogui_report_dialog (char *title, char *msg)
364 {
365   printf ("--- %s ---\n%s\n", title, msg);
366 }
367 
368 static char *
nogui_prompt_for(const char * msg,const char * default_string)369 nogui_prompt_for (const char *msg, const char *default_string)
370 {
371   char *answer;
372 
373   if (default_string)
374     printf ("%s [%s] : ", msg, default_string);
375   else
376     printf ("%s : ", msg);
377 
378   answer = read_stdin_line ();
379   if (answer == NULL)
380     return strdup ((default_string != NULL) ? default_string : "");
381   else
382     return answer;
383 }
384 
385 /* FIXME - this could use some enhancement to actually use the other
386    args */
387 static char *
nogui_fileselect(const char * title,const char * descr,char * default_file,char * default_ext,const char * history_tag,int flags)388 nogui_fileselect (const char *title, const char *descr,
389 		  char *default_file, char *default_ext,
390 		  const char *history_tag, int flags)
391 {
392   char *answer;
393 
394   if (default_file)
395     printf ("%s [%s] : ", title, default_file);
396   else
397     printf ("%s : ", title);
398 
399   answer = read_stdin_line ();
400   if (answer == NULL)
401     return (default_file != NULL) ? strdup (default_file) : NULL;
402   else
403     return answer;
404 }
405 
406 static int
nogui_attribute_dialog(HID_Attribute * attrs,int n_attrs,HID_Attr_Val * results,const char * title,const char * descr)407 nogui_attribute_dialog (HID_Attribute * attrs,
408 			int n_attrs, HID_Attr_Val * results,
409 			const char * title, const char * descr)
410 {
411   CRASH;
412 }
413 
414 static void
nogui_show_item(void * item)415 nogui_show_item (void *item)
416 {
417   CRASH;
418 }
419 
420 static void
nogui_beep(void)421 nogui_beep (void)
422 {
423   putchar (7);
424   fflush (stdout);
425 }
426 
427 static int
nogui_progress(int so_far,int total,const char * message)428 nogui_progress (int so_far, int total, const char *message)
429 {
430   return 0;
431 }
432 
433 static HID_DRAW *
nogui_request_debug_draw(void)434 nogui_request_debug_draw (void)
435 {
436   return NULL;
437 }
438 
439 static void
nogui_flush_debug_draw(void)440 nogui_flush_debug_draw (void)
441 {
442 }
443 
444 static void
nogui_finish_debug_draw(void)445 nogui_finish_debug_draw (void)
446 {
447 }
448 
449 void
common_nogui_init(HID * hid)450 common_nogui_init (HID *hid)
451 {
452   hid->get_export_options =   nogui_get_export_options;
453   hid->do_export =            nogui_do_export;
454   hid->parse_arguments =      nogui_parse_arguments;
455   hid->invalidate_lr =        nogui_invalidate_lr;
456   hid->invalidate_all =       nogui_invalidate_all;
457   hid->set_layer =            nogui_set_layer;
458   hid->end_layer =            nogui_end_layer;
459   hid->calibrate =            nogui_calibrate;
460   hid->shift_is_pressed =     nogui_shift_is_pressed;
461   hid->control_is_pressed =   nogui_control_is_pressed;
462   hid->mod1_is_pressed =      nogui_mod1_is_pressed;
463   hid->get_coords =           nogui_get_coords;
464   hid->set_crosshair =        nogui_set_crosshair;
465   hid->add_timer =            nogui_add_timer;
466   hid->stop_timer =           nogui_stop_timer;
467   hid->watch_file =           nogui_watch_file;
468   hid->unwatch_file =         nogui_unwatch_file;
469   hid->add_block_hook =       nogui_add_block_hook;
470   hid->stop_block_hook =      nogui_stop_block_hook;
471   hid->log =                  nogui_log;
472   hid->logv =                 nogui_logv;
473   hid->confirm_dialog =       nogui_confirm_dialog;
474   hid->close_confirm_dialog = nogui_close_confirm_dialog;
475   hid->report_dialog =        nogui_report_dialog;
476   hid->prompt_for =           nogui_prompt_for;
477   hid->fileselect =           nogui_fileselect;
478   hid->attribute_dialog =     nogui_attribute_dialog;
479   hid->show_item =            nogui_show_item;
480   hid->beep =                 nogui_beep;
481   hid->progress =             nogui_progress;
482   hid->request_debug_draw =   nogui_request_debug_draw;
483   hid->flush_debug_draw =     nogui_flush_debug_draw;
484   hid->finish_debug_draw =    nogui_finish_debug_draw;
485 }
486 
487 void
common_nogui_graphics_init(HID_DRAW * graphics)488 common_nogui_graphics_init (HID_DRAW *graphics)
489 {
490   graphics->make_gc =         nogui_make_gc;
491   graphics->destroy_gc =      nogui_destroy_gc;
492   graphics->use_mask =        nogui_use_mask;
493   graphics->set_color =       nogui_set_color;
494   graphics->set_line_cap =    nogui_set_line_cap;
495   graphics->set_line_width =  nogui_set_line_width;
496   graphics->set_draw_xor =    nogui_set_draw_xor;
497   graphics->set_draw_faded =  nogui_set_draw_faded;
498   graphics->draw_line =       nogui_draw_line;
499   graphics->draw_arc =        nogui_draw_arc;
500   graphics->draw_rect =       nogui_draw_rect;
501   graphics->fill_circle =     nogui_fill_circle;
502   graphics->fill_polygon =    nogui_fill_polygon;
503   graphics->fill_rect =       nogui_fill_rect;
504 
505   graphics->draw_pcb_polygon = nogui_draw_pcb_polygon;
506   graphics->fill_pcb_pad =     nogui_fill_pcb_pad;
507   graphics->thindraw_pcb_pad = nogui_thindraw_pcb_pad;
508   graphics->fill_pcb_pv =      nogui_fill_pcb_pv;
509   graphics->thindraw_pcb_pv =  nogui_thindraw_pcb_pv;
510 }
511 
512 static HID nogui_hid;
513 static HID_DRAW nogui_graphics;
514 
515 HID *
hid_nogui_get_hid(void)516 hid_nogui_get_hid (void)
517 {
518   memset (&nogui_hid, 0, sizeof (HID));
519   memset (&nogui_graphics, 0, sizeof (HID_DRAW));
520 
521   nogui_hid.struct_size = sizeof (HID);
522   nogui_hid.name        = "nogui";
523   nogui_hid.description = "Default GUI when no other GUI is present.  "
524                           "Does nothing.";
525   nogui_hid.graphics    = &nogui_graphics;
526 
527   common_nogui_init (&nogui_hid);
528   common_nogui_graphics_init (&nogui_graphics);
529 
530   return &nogui_hid;
531 }
532