BRL-CAD
fb_obj.c
Go to the documentation of this file.
1 /* F B _ O B J . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1997-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup fb */
21 /** @{ */
22 /** @file fb_obj.c
23  *
24  * A framebuffer object contains the attributes and
25  * methods for controlling framebuffers.
26  *
27  */
28 /** @} */
29 
30 #include "common.h"
31 
32 #include <stdlib.h>
33 
34 #ifdef HAVE_STRINGS_H
35 # include <strings.h>
36 #endif
37 
38 #include "tcl.h"
39 #include "bu/cmd.h"
40 #include "bu/color.h"
41 #include "bu/getopt.h"
42 #include "bu/malloc.h"
43 #include "bu/str.h"
44 #include "fb_private.h"
45 #include "fb.h"
46 #include "fbserv_obj.h"
47 
48 
49 /* defined in libfb/tcl.c */
50 extern int fb_refresh(fb *ifp, int x, int y, int w, int h);
51 
52 
53 #define FBO_CONSTRAIN(_v, _a, _b) \
54  ((_v > _a) ? (_v < _b ? _v : _b) : _a)
55 
56 struct fb_obj {
57  struct bu_list l;
58  struct bu_vls fbo_name; /* framebuffer object name/cmd */
59  struct fbserv_obj fbo_fbs; /* fbserv object */
60  Tcl_Interp *fbo_interp;
61 };
62 
63 
64 static struct fb_obj HeadFBObj; /* head of display manager object list */
65 
66 
67 HIDDEN int
68 fbo_coords_ok(fb *fbp, int x, int y)
69 {
70  int width;
71  int height;
72  int errors;
73  width = fb_getwidth(fbp);
74  height = fb_getheight(fbp);
75 
76  errors = 0;
77 
78  if (x < 0) {
79  bu_log("fbo_coords_ok: Error!: X value < 0\n");
80  ++errors;
81  }
82 
83  if (y < 0) {
84  bu_log("fbo_coords_ok: Error!: Y value < 0\n");
85  ++errors;
86  }
87 
88  if (x > width - 1) {
89  bu_log("fbo_coords_ok: Error!: X value too large\n");
90  ++errors;
91  }
92 
93  if (y > height - 1) {
94  bu_log("fbo_coords_ok: Error!: Y value too large\n");
95  ++errors;
96  }
97 
98  if (errors) {
99  return 0;
100  } else {
101  return 1;
102  }
103 }
104 
105 
106 /*
107  * Called when the object is destroyed.
108  */
109 HIDDEN void
110 fbo_deleteProc(void *clientData)
111 {
112  struct fb_obj *fbop = (struct fb_obj *)clientData;
113 
114  /* close framebuffer */
115  fb_close(fbop->fbo_fbs.fbs_fbp);
116 
117  bu_vls_free(&fbop->fbo_name);
118  BU_LIST_DEQUEUE(&fbop->l);
119  bu_free((void *)fbop, "fbo_deleteProc: fbop");
120 }
121 
122 
123 /*
124  * Close a framebuffer object.
125  *
126  * Usage:
127  * procname close
128  */
129 HIDDEN int
130 fbo_close_tcl(void *clientData, int argc, const char **UNUSED(argv))
131 {
132  struct fb_obj *fbop = (struct fb_obj *)clientData;
133 
134  if (argc != 2) {
135  bu_log("ERROR: expecting two arguments\n");
136  return BRLCAD_ERROR;
137  }
138 
139  /* Among other things, this will call dmo_deleteProc. */
140  Tcl_DeleteCommand(fbop->fbo_interp, bu_vls_addr(&fbop->fbo_name));
141 
142  return BRLCAD_OK;
143 }
144 
145 
146 HIDDEN int
147 fbo_tcllist2color(const char *str, unsigned char *pixel)
148 {
149  int r, g, b;
150 
151  if (sscanf(str, "%d %d %d", &r, &g, &b) != 3) {
152  bu_log("fb_clear: bad color spec - %s", str);
153  return BRLCAD_ERROR;
154  }
155 
156  pixel[RED] = FBO_CONSTRAIN (r, 0, 255);
157  pixel[GRN] = FBO_CONSTRAIN (g, 0, 255);
158  pixel[BLU] = FBO_CONSTRAIN (b, 0, 255);
159 
160  return BRLCAD_OK;
161 }
162 
163 
164 /*
165  * Clear the framebuffer with the specified color.
166  * Otherwise, clear the framebuffer with black.
167  *
168  * Usage:
169  * procname clear [rgb]
170  */
171 HIDDEN int
172 fbo_clear_tcl(void *clientData, int argc, const char **argv)
173 {
174  struct fb_obj *fbop = (struct fb_obj *)clientData;
175  int status;
176  RGBpixel pixel;
177  unsigned char *ms;
178 
179 
180  if (argc < 2 || 3 < argc) {
181  bu_log("ERROR: expecting only two or three arguments\n");
182  return BRLCAD_ERROR;
183  }
184 
185  if (argc == 3) {
186  /*
187  * Decompose the color list into its constituents.
188  * For now must be in the form of rrr ggg bbb.
189  */
190  if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) {
191  bu_log("fb_cell: invalid color spec: %s.", argv[6]);
192  return BRLCAD_ERROR;
193  }
194 
195  ms = pixel;
196  } else
197  ms = RGBPIXEL_NULL;
198 
199  status = fb_clear(fbop->fbo_fbs.fbs_fbp, ms);
200 
201  if (status < 0)
202  return BRLCAD_ERROR;
203 
204  return BRLCAD_OK;
205 }
206 
207 
208 /*
209  *
210  * Usage:
211  * procname cursor mode x y
212  */
213 HIDDEN int
214 fbo_cursor_tcl(void *clientData, int argc, const char **argv)
215 {
216  struct fb_obj *fbop = (struct fb_obj *)clientData;
217  int mode;
218  int x, y;
219  int status;
220 
221  if (argc != 5) {
222  bu_log("ERROR: expecting five arguments\n");
223  return BRLCAD_ERROR;
224  }
225 
226  if (sscanf(argv[2], "%d", &mode) != 1) {
227  bu_log("fb_cursor: bad mode - %s", argv[2]);
228  return BRLCAD_ERROR;
229  }
230 
231  if (sscanf(argv[3], "%d", &x) != 1) {
232  bu_log("fb_cursor: bad x value - %s", argv[3]);
233  return BRLCAD_ERROR;
234  }
235 
236  if (sscanf(argv[4], "%d", &y) != 1) {
237  bu_log("fb_cursor: bad y value - %s", argv[4]);
238  return BRLCAD_ERROR;
239  }
240 
241  status = fb_cursor(fbop->fbo_fbs.fbs_fbp, mode, x, y);
242  if (status == 0)
243  return BRLCAD_OK;
244 
245  return BRLCAD_ERROR;
246 }
247 
248 
249 /*
250  *
251  * Usage:
252  * procname getcursor
253  */
254 HIDDEN int
255 fbo_getcursor_tcl(void *clientData, int argc, const char **argv)
256 {
257  struct fb_obj *fbop = (struct fb_obj *)clientData;
258  int status;
259  int mode;
260  int x, y;
261  struct bu_vls vls = BU_VLS_INIT_ZERO;
262 
263  if (argc != 2
264  || !BU_STR_EQUIV(argv[1], "getcursor"))
265  {
266  bu_log("ERROR: unexpected argument(s)\n");
267  return BRLCAD_ERROR;
268  }
269 
270  status = fb_getcursor(fbop->fbo_fbs.fbs_fbp, &mode, &x, &y);
271  if (status == 0) {
272  bu_vls_printf(&vls, "%d %d %d", mode, x, y);
273  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
274  bu_vls_free(&vls);
275 
276  return BRLCAD_OK;
277  }
278 
279  return BRLCAD_ERROR;
280 }
281 
282 
283 /*
284  * Refresh the entire framebuffer or that part specified by
285  * a rectangle (i.e. x y width height)
286  * Usage:
287  * procname refresh [rect]
288  */
289 HIDDEN int
290 fbo_refresh_tcl(void *clientData, int argc, const char **argv)
291 {
292  struct fb_obj *fbop = (struct fb_obj *)clientData;
293  int x, y, w, h; /* rectangle to be refreshed */
294 
295  if (argc < 2 || 3 < argc) {
296  bu_log("ERROR: expecting only two or three arguments\n");
297  return BRLCAD_ERROR;
298  }
299 
300  if (argc == 2) {
301  /* refresh the whole display */
302  x = y = 0;
303  w = fbop->fbo_fbs.fbs_fbp->if_width;
304  h = fbop->fbo_fbs.fbs_fbp->if_height;
305  } else if (sscanf(argv[2], "%d %d %d %d", &x, &y, &w, &h) != 4) {
306  /* refresh rectangular area */
307  bu_log("fb_refresh: bad rectangle - %s", argv[2]);
308  return BRLCAD_ERROR;
309  }
310 
311  return fb_refresh(fbop->fbo_fbs.fbs_fbp, x, y, w, h);
312 }
313 
314 
315 /*
316  * Listen for framebuffer clients.
317  *
318  * Usage:
319  * procname listen port
320  *
321  * Returns the port number actually used.
322  *
323  */
324 HIDDEN int
325 fbo_listen_tcl(void *clientData, int argc, const char **argv)
326 {
327  struct fb_obj *fbop = (struct fb_obj *)clientData;
328  struct bu_vls vls = BU_VLS_INIT_ZERO;
329 
330  if (fbop->fbo_fbs.fbs_fbp == FB_NULL) {
331  bu_log("%s listen: framebuffer not open!\n", argv[0]);
332  return BRLCAD_ERROR;
333  }
334 
335  if (argc != 2 && argc != 3) {
336  bu_log("ERROR: expecting only two or three arguments\n");
337  return BRLCAD_ERROR;
338  }
339 
340  if (argc == 3) {
341  int port;
342 
343  if (sscanf(argv[2], "%d", &port) != 1) {
344  bu_log("listen: bad value - %s\n", argv[2]);
345  return BRLCAD_ERROR;
346  }
347 
348  if (port >= 0)
349  fbs_open(&fbop->fbo_fbs, port);
350  else {
351  fbs_close(&fbop->fbo_fbs);
352  }
353  bu_vls_printf(&vls, "%d", fbop->fbo_fbs.fbs_listener.fbsl_port);
354  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
355  bu_vls_free(&vls);
356 
357  return BRLCAD_OK;
358  }
359 
360  /* return the port number */
361  /* argc == 2 */
362  bu_vls_printf(&vls, "%d", fbop->fbo_fbs.fbs_listener.fbsl_port);
363  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
364  bu_vls_free(&vls);
365 
366  return BRLCAD_OK;
367 }
368 
369 
370 /*
371  * Set/get the pixel value at position (x, y).
372  *
373  * Usage:
374  * procname pixel x y [rgb]
375  */
376 HIDDEN int
377 fbo_pixel_tcl(void *clientData, int argc, const char **argv)
378 {
379  struct fb_obj *fbop = (struct fb_obj *)clientData;
380  struct bu_vls vls = BU_VLS_INIT_ZERO;
381  int x, y; /* pixel position */
382  RGBpixel pixel;
383 
384  if (argc != 4 && argc != 5) {
385  bu_log("ERROR: expecting five arguments\n");
386  return BRLCAD_ERROR;
387  }
388 
389  /* get pixel position */
390  if (sscanf(argv[2], "%d", &x) != 1) {
391  bu_log("fb_pixel: bad x value - %s", argv[2]);
392  return BRLCAD_ERROR;
393  }
394 
395  if (sscanf(argv[3], "%d", &y) != 1) {
396  bu_log("fb_pixel: bad y value - %s", argv[3]);
397  return BRLCAD_ERROR;
398  }
399 
400  /* check pixel position */
401  if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, x, y)) {
402  bu_log("fb_pixel: coordinates (%s, %s) are invalid.", argv[2], argv[3]);
403  return BRLCAD_ERROR;
404  }
405 
406  /* get pixel value */
407  if (argc == 4) {
408  fb_rpixel(fbop->fbo_fbs.fbs_fbp, pixel);
409  bu_vls_printf(&vls, "%d %d %d", pixel[RED], pixel[GRN], pixel[BLU]);
410  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
411  bu_vls_free(&vls);
412 
413  return BRLCAD_OK;
414  }
415 
416  /*
417  * Decompose the color list into its constituents.
418  * For now must be in the form of rrr ggg bbb.
419  */
420 
421  /* set pixel value */
422  if (fbo_tcllist2color(argv[4], pixel) == BRLCAD_ERROR) {
423  bu_log("fb_pixel: invalid color spec - %s", argv[4]);
424  return BRLCAD_ERROR;
425  }
426 
427  fb_write(fbop->fbo_fbs.fbs_fbp, x, y, pixel, 1);
428 
429  return BRLCAD_OK;
430 }
431 
432 
433 /*
434  *
435  * Usage:
436  * procname cell xmin ymin width height color
437  */
438 HIDDEN int
439 fbo_cell_tcl(void *clientData, int argc, const char **argv)
440 {
441  struct fb_obj *fbop = (struct fb_obj *)clientData;
442  int xmin, ymin;
443  long width;
444  long height;
445  size_t i;
446  RGBpixel pixel;
447  unsigned char *pp;
448 
449 
450  if (argc != 7) {
451  bu_log("ERROR: expecting seven arguments\n");
452  return BRLCAD_ERROR;
453  }
454 
455  if (sscanf(argv[2], "%d", &xmin) != 1) {
456  bu_log("fb_cell: bad xmin value - %s", argv[2]);
457  return BRLCAD_ERROR;
458  }
459 
460  if (sscanf(argv[3], "%d", &ymin) != 1) {
461  bu_log("fb_cell: bad ymin value - %s", argv[3]);
462  return BRLCAD_ERROR;
463  }
464 
465  /* check coordinates */
466  if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) {
467  bu_log("fb_cell: coordinates (%s, %s) are invalid.", argv[2], argv[3]);
468  return BRLCAD_ERROR;
469  }
470 
471  if (sscanf(argv[4], "%ld", &width) != 1) {
472  bu_log("fb_cell: bad width - %s", argv[4]);
473  return BRLCAD_ERROR;
474  }
475 
476  if (sscanf(argv[5], "%ld", &height) != 1) {
477  bu_log("fb_cell: bad height - %s", argv[5]);
478  return BRLCAD_ERROR;
479  }
480 
481 
482  /* check width and height */
483  if (width <=0 || height <=0) {
484  bu_log("fb_cell: width and height must be > 0");
485  return BRLCAD_ERROR;
486  }
487 
488  /*
489  * Decompose the color list into its constituents.
490  * For now must be in the form of rrr ggg bbb.
491  */
492  if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) {
493  bu_log("fb_cell: invalid color spec: %s", argv[6]);
494  return BRLCAD_ERROR;
495  }
496 
497  pp = (unsigned char *)bu_calloc(width*height, sizeof(RGBpixel), "allocate pixel array");
498  for (i = 0; i < width*height*sizeof(RGBpixel); i+=sizeof(RGBpixel)) {
499  pp[i] = pixel[0];
500  pp[i+1] = pixel[1];
501  pp[i+2] = pixel[2];
502  }
503  fb_writerect(fbop->fbo_fbs.fbs_fbp, xmin, ymin, width, height, pp);
504  bu_free((void *)pp, "free pixel array");
505 
506  return BRLCAD_OK;
507 }
508 
509 
510 /*
511  *
512  * Usage:
513  * procname flush
514  */
515 HIDDEN int
516 fbo_flush_tcl(void *clientData, int argc, const char **argv)
517 {
518  struct fb_obj *fbop = (struct fb_obj *)clientData;
519 
520  if (argc != 2
521  || !BU_STR_EQUIV(argv[1], "flush"))
522  {
523  bu_log("ERROR: expecting two arguments\n");
524  return BRLCAD_ERROR;
525  }
526 
527  fb_flush(fbop->fbo_fbs.fbs_fbp);
528 
529  return BRLCAD_OK;
530 }
531 
532 
533 /*
534  *
535  * Usage:
536  * procname getheight
537  */
538 HIDDEN int
539 fbo_getheight_tcl(void *clientData, int argc, const char **argv)
540 {
541  struct fb_obj *fbop = (struct fb_obj *)clientData;
542  struct bu_vls vls = BU_VLS_INIT_ZERO;
543 
544  if (argc != 2
545  || !BU_STR_EQUIV(argv[1], "getheight"))
546  {
547  bu_log("ERROR: expecting two arguments\n");
548  return BRLCAD_ERROR;
549  }
550 
551  bu_vls_printf(&vls, "%d", fb_getheight(fbop->fbo_fbs.fbs_fbp));
552  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
553  bu_vls_free(&vls);
554 
555  return BRLCAD_OK;
556 }
557 
558 
559 /*
560  *
561  * Usage:
562  * procname getwidth
563  */
564 HIDDEN int
565 fbo_getwidth_tcl(void *clientData, int argc, const char **argv)
566 {
567  struct fb_obj *fbop = (struct fb_obj *)clientData;
568  struct bu_vls vls = BU_VLS_INIT_ZERO;
569 
570  if (argc != 2
571  || !BU_STR_EQUIV(argv[1], "getwidth"))
572  {
573  bu_log("ERROR: expecting two arguments\n");
574  return BRLCAD_ERROR;
575  }
576 
577  bu_vls_printf(&vls, "%d", fb_getwidth(fbop->fbo_fbs.fbs_fbp));
578  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
579  bu_vls_free(&vls);
580 
581  return BRLCAD_OK;
582 }
583 
584 
585 /*
586  *
587  * Usage:
588  * procname getsize
589  */
590 HIDDEN int
591 fbo_getsize_tcl(void *clientData, int argc, const char **argv)
592 {
593  struct fb_obj *fbop = (struct fb_obj *)clientData;
594  struct bu_vls vls = BU_VLS_INIT_ZERO;
595 
596  if (argc != 2
597  || !BU_STR_EQUIV(argv[1], "getsize"))
598  {
599  bu_log("ERROR: expecting two arguments\n");
600  return BRLCAD_ERROR;
601  }
602 
603  bu_vls_printf(&vls, "%d %d",
604  fb_getwidth(fbop->fbo_fbs.fbs_fbp),
605  fb_getheight(fbop->fbo_fbs.fbs_fbp));
606  Tcl_AppendResult(fbop->fbo_interp, bu_vls_addr(&vls), (char *)NULL);
607  bu_vls_free(&vls);
608 
609  return BRLCAD_OK;
610 }
611 
612 
613 /*
614  *
615  * Usage:
616  * procname cell xmin ymin width height color
617  */
618 HIDDEN int
619 fbo_rect_tcl(void *clientData, int argc, const char **argv)
620 {
621  struct fb_obj *fbop = (struct fb_obj *)clientData;
622  int xmin, ymin;
623  int xmax, ymax;
624  int width;
625  int height;
626  int i;
627  RGBpixel pixel;
628 
629  if (argc != 7) {
630  bu_log("ERROR: expecting seven arguments\n");
631  return BRLCAD_ERROR;
632  }
633 
634  if (sscanf(argv[2], "%d", &xmin) != 1) {
635  bu_log("fb_rect: bad xmin value - %s", argv[2]);
636  return BRLCAD_ERROR;
637  }
638 
639  if (sscanf(argv[3], "%d", &ymin) != 1) {
640  bu_log("fb_rect: bad ymin value - %s", argv[3]);
641  return BRLCAD_ERROR;
642  }
643 
644  /* check coordinates */
645  if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) {
646  bu_log("fb_rect: coordinates (%s, %s) are invalid.", argv[2], argv[3]);
647  return BRLCAD_ERROR;
648  }
649 
650  if (sscanf(argv[4], "%d", &width) != 1) {
651  bu_log("fb_rect: bad width - %s", argv[4]);
652  return BRLCAD_ERROR;
653  }
654 
655  if (sscanf(argv[5], "%d", &height) != 1) {
656  bu_log("fb_rect: bad height - %s", argv[5]);
657  return BRLCAD_ERROR;
658  }
659 
660 
661  /* check width and height */
662  if (width <=0 || height <=0) {
663  bu_log("fb_rect: width and height must be > 0");
664  return BRLCAD_ERROR;
665  }
666 
667  /*
668  * Decompose the color list into its constituents.
669  * For now must be in the form of rrr ggg bbb.
670  */
671  if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) {
672  bu_log("fb_rect: invalid color spec: %s", argv[6]);
673  return BRLCAD_ERROR;
674  }
675 
676  xmax = xmin + width;
677  ymax = ymin + height;
678 
679  /* draw horizontal lines */
680  for (i = xmin; i <= xmax; ++i) {
681  /* working on bottom line */
682  fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1);
683 
684  /* working on top line */
685  fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1);
686  }
687 
688  /* draw vertical lines */
689  for (i = ymin; i <= ymax; ++i) {
690  /* working on left line */
691  fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1);
692 
693  /* working on right line */
694  fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1);
695  }
696 
697  return BRLCAD_OK;
698 }
699 
700 
701 /*
702  * Usage:
703  * procname configure width height
704  */
705 HIDDEN int
706 fbo_configure_tcl(void *clientData, int argc, const char **argv)
707 {
708  struct fb_obj *fbop = (struct fb_obj *)clientData;
709  int width, height;
710 
711  if (argc != 4) {
712  bu_log("ERROR: expecting four arguments\n");
713  return BRLCAD_ERROR;
714  }
715 
716  if (sscanf(argv[2], "%d", &width) != 1) {
717  bu_log("fb_configure: bad width - %s", argv[2]);
718  return BRLCAD_ERROR;
719  }
720 
721  if (sscanf(argv[3], "%d", &height) != 1) {
722  bu_log("fb_configure: bad height - %s", argv[3]);
723  return BRLCAD_ERROR;
724  }
725 
726  /* configure the framebuffer window */
727  if (fbop->fbo_fbs.fbs_fbp != FB_NULL)
728  (void)fb_configure_window(fbop->fbo_fbs.fbs_fbp, width, height);
729 
730  return BRLCAD_OK;
731 }
732 
733 
734 /*
735  * Generic interface for framebuffer object routines.
736  * Usage:
737  * procname cmd ?args?
738  *
739  * Returns: result of FB command.
740  */
741 HIDDEN int
742 fbo_cmd(ClientData clientData, Tcl_Interp *UNUSED(interp), int argc, const char **argv)
743 {
744  int ret;
745 
746  static struct bu_cmdtab fbo_cmds[] = {
747  {"cell", fbo_cell_tcl},
748  {"clear", fbo_clear_tcl},
749  {"close", fbo_close_tcl},
750  {"configure", fbo_configure_tcl},
751  {"cursor", fbo_cursor_tcl},
752  {"pixel", fbo_pixel_tcl},
753  {"flush", fbo_flush_tcl},
754  {"getcursor", fbo_getcursor_tcl},
755  {"getheight", fbo_getheight_tcl},
756  {"getsize", fbo_getsize_tcl},
757  {"getwidth", fbo_getwidth_tcl},
758  {"listen", fbo_listen_tcl},
759  {"rect", fbo_rect_tcl},
760  {"refresh", fbo_refresh_tcl},
761  {(const char *)NULL, BU_CMD_NULL}
762  };
763 
764  if (bu_cmd(fbo_cmds, argc, argv, 1, clientData, &ret) == BRLCAD_OK)
765  return ret;
766 
767  bu_log("ERROR: '%s' command not found\n", argv[1]);
768  return BRLCAD_ERROR;
769 }
770 
771 
772 /*
773  * Open/create a framebuffer object.
774  *
775  * Usage:
776  * fb_open [name device [args]]
777  */
778 HIDDEN int
779 fbo_open_tcl(void *UNUSED(clientData), Tcl_Interp *interp, int argc, const char **argv)
780 {
781  struct fb_obj *fbop;
782  fb *ifp;
783  int width = 512;
784  int height = 512;
785  register int c;
786  struct bu_vls vls = BU_VLS_INIT_ZERO;
787 
788  if (argc == 1) {
789  /* get list of framebuffer objects */
790  for (BU_LIST_FOR(fbop, fb_obj, &HeadFBObj.l))
791  Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), " ", (char *)NULL);
792 
793  return BRLCAD_OK;
794  }
795 
796  if (argc < 3) {
797  bu_vls_printf(&vls, "helplib fb_open");
798  Tcl_Eval(interp, bu_vls_addr(&vls));
799  bu_vls_free(&vls);
800  return BRLCAD_ERROR;
801  }
802 
803  /* process args */
804  bu_optind = 3;
805  bu_opterr = 0;
806  while ((c = bu_getopt(argc, (char * const *)argv, "w:W:s:S:n:N:")) != -1) {
807  switch (c) {
808  case 'W':
809  case 'w':
810  width = atoi(bu_optarg);
811  break;
812  case 'N':
813  case 'n':
814  height = atoi(bu_optarg);
815  break;
816  case 'S':
817  case 's':
818  width = atoi(bu_optarg);
819  height = width;
820  break;
821  case '?':
822  default:
823  bu_log("fb_open: bad option - %s", bu_optarg);
824  return BRLCAD_ERROR;
825  }
826  }
827 
828  if ((ifp = fb_open(argv[2], width, height)) == FB_NULL) {
829  bu_log("fb_open: bad device - %s", argv[2]);
830  return BRLCAD_ERROR;
831  }
832 
833  if (fb_ioinit(ifp) != 0) {
834  bu_log("fb_open: fb_ioinit() failed.");
835  return BRLCAD_ERROR;
836  }
837 
838  BU_ALLOC(fbop, struct fb_obj);
839  bu_vls_init(&fbop->fbo_name);
840  bu_vls_strcpy(&fbop->fbo_name, argv[1]);
841  fbop->fbo_fbs.fbs_fbp = ifp;
842  fbop->fbo_fbs.fbs_listener.fbsl_fbsp = &fbop->fbo_fbs;
843  fbop->fbo_fbs.fbs_listener.fbsl_fd = -1;
844  fbop->fbo_fbs.fbs_listener.fbsl_port = -1;
845  fbop->fbo_interp = interp;
846 
847  /* append to list of fb_obj's */
848  BU_LIST_APPEND(&HeadFBObj.l, &fbop->l);
849 
850  (void)Tcl_CreateCommand(interp,
851  bu_vls_addr(&fbop->fbo_name),
852  (Tcl_CmdProc *)fbo_cmd,
853  (ClientData)fbop,
855 
856  /* Return new function name as result */
857  Tcl_ResetResult(interp);
858  Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), (char *)NULL);
859  return BRLCAD_OK;
860 }
861 
862 
863 int
864 Fbo_Init(Tcl_Interp *interp)
865 {
866  BU_LIST_INIT(&HeadFBObj.l);
867  (void)Tcl_CreateCommand(interp, "fb_open", (Tcl_CmdProc *)fbo_open_tcl,
868  (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
869 
870  return BRLCAD_OK;
871 }
872 
873 
874 /*
875  * Local Variables:
876  * mode: C
877  * tab-width: 8
878  * indent-tabs-mode: t
879  * c-file-style: "stroustrup"
880  * End:
881  * ex: shiftwidth=4 tabstop=8
882  */
struct bu_vls fbo_name
Definition: fb_obj.c:58
HIDDEN int fbo_getsize_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:591
Definition: cmd.h:48
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
int fb_refresh(fb *ifp, int x, int y, int w, int h)
Definition: fb_generic.c:156
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
unsigned char RGBpixel[3]
Definition: fb.h:73
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
HIDDEN void fbo_deleteProc(void *clientData)
Definition: fb_obj.c:110
Definition: list.h:118
ustring interp
#define RED
Definition: color.h:39
fb * fb_open(const char *file, int _width, int _height)
Definition: fb_generic.c:384
char * bu_optarg
Definition: globals.c:91
Header file for the BRL-CAD common definitions.
int fbs_close(struct fbserv_obj *fbsp)
Definition: fbserv_obj.c:1073
int bu_optind
Definition: globals.c:89
int fb_getcursor(fb *ifp, int *mode, int *x, int *y)
Definition: fb_generic.c:304
#define BU_CMD_NULL
Definition: cmd.h:37
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
#define BLU
Definition: color.h:41
Definition: fb_obj.c:56
int fb_getheight(fb *ifp)
Definition: fb_generic.c:235
#define FBO_CONSTRAIN(_v, _a, _b)
Definition: fb_obj.c:53
ustring width
int fb_cursor(fb *ifp, int mode, int x, int y)
Definition: fb_generic.c:300
#define HIDDEN
Definition: common.h:86
HIDDEN int fbo_configure_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:706
HIDDEN int fbo_getheight_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:539
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int fb_close(fb *ifp)
Definition: fb_generic.c:478
#define FB_NULL
Definition: fb.h:95
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
HIDDEN int fbo_flush_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:516
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
HIDDEN int fbo_rect_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:619
Tcl_Interp * fbo_interp
Definition: fb_obj.c:60
HIDDEN int fbo_tcllist2color(const char *str, unsigned char *pixel)
Definition: fb_obj.c:147
#define BRLCAD_OK
Definition: defines.h:71
HIDDEN int fbo_clear_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:172
struct fbserv_obj fbo_fbs
Definition: fb_obj.c:59
int fb_getwidth(fb *ifp)
Definition: fb_generic.c:231
#define BU_STR_EQUIV(s1, s2)
Definition: str.h:135
#define UNUSED(parameter)
Definition: common.h:239
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define RGBPIXEL_NULL
Definition: fb.h:90
int fb_configure_window(fb *, int, int)
Definition: fb_generic.c:162
HIDDEN int fbo_cmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
Definition: fb_obj.c:742
int fb_rpixel(fb *ifp, unsigned char *pp)
HIDDEN int fbo_pixel_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:377
#define BU_LIST_INIT(_hp)
Definition: list.h:148
ssize_t fb_write(fb *ifp, int x, int y, const unsigned char *pp, size_t count)
Definition: fb_generic.c:276
HIDDEN int fbo_refresh_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:290
int fb_flush(fb *ifp)
int Fbo_Init(Tcl_Interp *interp)
Definition: fb_obj.c:864
int bu_opterr
Definition: globals.c:88
int fbs_open(struct fbserv_obj *fbsp, int port)
Definition: fbserv_obj.c:983
HIDDEN int fbo_getwidth_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:565
int fb_ioinit(fb *ifp)
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
HIDDEN int fbo_cell_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:439
int fb_clear(fb *ifp, unsigned char *pp)
Definition: fb_generic.c:268
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
HIDDEN int fbo_getcursor_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:255
HIDDEN int fbo_close_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:130
HIDDEN int fbo_open_tcl(void *clientData, Tcl_Interp *interp, int argc, const char **argv)
Definition: fb_obj.c:779
HIDDEN int fbo_cursor_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:214
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
A frame-buffer IO structure.
Definition: fb_private.h:80
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
#define GRN
Definition: color.h:40
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
struct bu_list l
Definition: fb_obj.c:57
HIDDEN int fbo_coords_ok(fb *fbp, int x, int y)
Definition: fb_obj.c:68
HIDDEN int fbo_listen_tcl(void *clientData, int argc, const char **argv)
Definition: fb_obj.c:325
int fb_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: fb_generic.c:312
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)