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