BRL-CAD
dm_obj.c
Go to the documentation of this file.
1 /* D M _ 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 /** @file libdm/dm_obj.c
21  *
22  * A display manager object contains the attributes and
23  * methods for controlling display managers.
24  *
25  */
26 
27 #include "common.h"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
32 
33 #include <zlib.h>
34 #include <png.h>
35 
36 #include "tcl.h"
37 
38 #include "bu/cmd.h"
39 #include "bu/endian.h"
40 #include "vmath.h"
41 #include "bn.h"
42 #include "db.h"
43 #include "mater.h"
44 #include "nmg.h"
45 #include "rtgeom.h"
46 #include "nurb.h"
47 #include "solid.h"
48 #include "dm.h"
49 #include "dm_private.h"
50 
51 #ifdef DM_X
52 # include "dm/dm_xvars.h"
53 # include <X11/Xutil.h>
54 # include "dm-X.h"
55 #endif /* DM_X */
56 
57 #ifdef DM_TK
58 # include "dm/dm_xvars.h"
59 # include "tk.h"
60 # include "dm-tk.h"
61 #endif /* DM_TK */
62 
63 #ifdef DM_OGL
64 # include "dm/dm_xvars.h"
65 # include "dm-ogl.h"
66 #endif /* DM_OGL */
67 
68 #ifdef DM_WGL
69 # include "dm/dm_xvars.h"
70 # include <tkwinport.h>
71 # include "dm-wgl.h"
72 #endif /* DM_WGL */
73 
74 #ifdef USE_FBSERV
75 # include "fb.h"
76 #endif
77 
78 /**
79  *@brief
80  * A display manager object is used for interacting with a display manager.
81  */
82 struct dm_obj {
83  struct bu_list l;
84  struct bu_vls dmo_name; /**< @brief display manager object name/cmd */
85  dm *dmo_dmp; /**< @brief display manager pointer */
86 #ifdef USE_FBSERV
87  struct fbserv_obj dmo_fbs; /**< @brief fbserv object */
88 #endif
89  struct bu_observer dmo_observers; /**< @brief fbserv observers */
90  mat_t viewMat;
91  int (*dmo_drawLabelsHook)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData);
93  Tcl_Interp *interp;
94 };
95 
96 
97 static struct dm_obj HeadDMObj; /* head of display manager object list */
98 
99 
100 #ifdef USE_FBSERV
101 /*
102  * Open/activate the display managers framebuffer.
103  */
104 HIDDEN int
105 dmo_openFb(struct dm_obj *dmop)
106 {
107  if (!dmop || !dmop->interp)
108  return TCL_ERROR;
109 
110  /* already open */
111  if (dmop->dmo_fbs.fbs_fbp != FB_NULL)
112  return TCL_OK;
113 
114  dmop->dmo_fbs.fbs_fbp = dm_get_fb(dmop->dmo_dmp);
115 
116  if (dmop->dmo_fbs.fbs_fbp == FB_NULL) {
117  Tcl_Obj *obj;
118 
119  obj = Tcl_GetObjResult(dmop->interp);
120  if (Tcl_IsShared(obj))
121  obj = Tcl_DuplicateObj(obj);
122 
123  Tcl_AppendStringsToObj(obj, "openfb: failed to allocate framebuffer memory\n", (char *)NULL);
124 
125  Tcl_SetObjResult(dmop->interp, obj);
126  return TCL_ERROR;
127  }
128 
129  return TCL_OK;
130 }
131 
132 
133 /*
134  * Draw the point.
135  *
136  * Usage:
137  * objname drawPoint x y
138  *
139  */
140 HIDDEN int
141 dmo_closeFb(struct dm_obj *dmop)
142 {
143  if (dmop->dmo_fbs.fbs_fbp == FB_NULL)
144  return TCL_OK;
145 
146  fb_flush(dmop->dmo_fbs.fbs_fbp);
147  fb_close_existing(dmop->dmo_fbs.fbs_fbp);
148 
149  dmop->dmo_fbs.fbs_fbp = FB_NULL;
150 
151  return TCL_OK;
152 }
153 
154 
155 /*
156  * Set/get the port used to listen for framebuffer clients.
157  *
158  * Usage:
159  * objname listen [port]
160  *
161  * Returns the port number actually used.
162  *
163  */
164 HIDDEN int
165 dmo_listen_tcl(void *clientData, int argc, const char **argv)
166 {
167  struct dm_obj *dmop = (struct dm_obj *)clientData;
168  struct bu_vls vls = BU_VLS_INIT_ZERO;
169  Tcl_Obj *obj;
170 
171  if (!dmop || !dmop->interp)
172  return TCL_ERROR;
173 
174  obj = Tcl_GetObjResult(dmop->interp);
175  if (Tcl_IsShared(obj))
176  obj = Tcl_DuplicateObj(obj);
177 
178  if (dmop->dmo_fbs.fbs_fbp == FB_NULL) {
179  bu_vls_printf(&vls, "%s listen: framebuffer not open!\n", argv[0]);
180  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
181  bu_vls_free(&vls);
182 
183  Tcl_SetObjResult(dmop->interp, obj);
184  return TCL_ERROR;
185  }
186 
187  /* return the port number */
188  if (argc == 2) {
189  bu_vls_printf(&vls, "%d", dmop->dmo_fbs.fbs_listener.fbsl_port);
190  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
191  bu_vls_free(&vls);
192 
193  Tcl_SetObjResult(dmop->interp, obj);
194  return TCL_OK;
195  }
196 
197  if (argc == 3) {
198  int port;
199 
200  if (sscanf(argv[2], "%d", &port) != 1) {
201  Tcl_AppendStringsToObj(obj, "listen: bad value - ", argv[2], "\n", (char *)NULL);
202  Tcl_SetObjResult(dmop->interp, obj);
203  return TCL_ERROR;
204  }
205 
206  if (port >= 0)
207  fbs_open(&dmop->dmo_fbs, port);
208  else {
209  fbs_close(&dmop->dmo_fbs);
210  }
211  bu_vls_printf(&vls, "%d", dmop->dmo_fbs.fbs_listener.fbsl_port);
212  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
213  bu_vls_free(&vls);
214 
215  Tcl_SetObjResult(dmop->interp, obj);
216  return TCL_OK;
217  }
218 
219  bu_vls_printf(&vls, "helplib_alias dm_listen %s", argv[1]);
220  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
221  bu_vls_free(&vls);
222 
223  return TCL_ERROR;
224 }
225 
226 
227 /*
228  * Refresh the display managers framebuffer.
229  *
230  * Usage:
231  * objname refresh
232  *
233  */
234 HIDDEN int
235 dmo_refreshFb_tcl(void *clientData, int argc, const char **argv)
236 {
237  struct dm_obj *dmop = (struct dm_obj *)clientData;
238  struct bu_vls vls = BU_VLS_INIT_ZERO;
239 
240  if (!dmop || !dmop->interp || argc < 1 || !argv)
241  return TCL_ERROR;
242 
243  if (dmop->dmo_fbs.fbs_fbp == FB_NULL) {
244  Tcl_Obj *obj;
245 
246  obj = Tcl_GetObjResult(dmop->interp);
247  if (Tcl_IsShared(obj))
248  obj = Tcl_DuplicateObj(obj);
249 
250  bu_vls_printf(&vls, "%s refresh: framebuffer not open!\n", argv[0]);
251  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
252  bu_vls_free(&vls);
253 
254  Tcl_SetObjResult(dmop->interp, obj);
255  return TCL_ERROR;
256  }
257 
258  fb_refresh(dmop->dmo_fbs.fbs_fbp, 0, 0,
259  dmop->dmo_dmp->dm_width, dmop->dmo_dmp->dm_height);
260 
261  return TCL_OK;
262 }
263 #endif
264 
265 
266 HIDDEN int
268  const char **argv,
269  fastf_t *viewSize,
270  mat_t rmat,
271  point_t axesPos,
272  fastf_t *axesSize,
273  int *axesColor,
274  int *labelColor,
275  int *lineWidth,
276  int *posOnly,
277  int *tripleColor,
278  struct bu_vls *vlsp)
279 {
280  double scan;
281 
282  if (argc < 3 || sscanf(argv[2], "%lf", &scan) != 1) {
283  bu_vls_printf(vlsp, "parseAxesArgs: bad view size - %s\n", argv[2]);
284  return TCL_ERROR;
285  }
286  /* convert double to fastf_t */
287  *viewSize = scan;
288 
289  if (argc < 4 || bn_decode_mat(rmat, argv[3]) != 16) {
290  bu_vls_printf(vlsp, "parseAxesArgs: bad rmat - %s\n", argv[3]);
291  return TCL_ERROR;
292  }
293 
294  if (argc < 5 || bn_decode_vect(axesPos, argv[4]) != 3) {
295  bu_vls_printf(vlsp, "parseAxesArgs: bad axes position - %s\n", argv[4]);
296  return TCL_ERROR;
297  }
298 
299  if (argc < 6 || sscanf(argv[5], "%lf", &scan) != 1) {
300  bu_vls_printf(vlsp, "parseAxesArgs: bad axes size - %s\n", argv[5]);
301  return TCL_ERROR;
302  }
303  /* convert double to fastf_t */
304  *axesSize = scan;
305 
306  if (argc < 7 || sscanf(argv[6], "%d %d %d",
307  &axesColor[0],
308  &axesColor[1],
309  &axesColor[2]) != 3) {
310 
311  bu_vls_printf(vlsp, "parseAxesArgs: bad axes color - %s\n", argv[6]);
312  return TCL_ERROR;
313  }
314 
315  /* validate color */
316  if (axesColor[0] < 0 || 255 < axesColor[0] ||
317  axesColor[1] < 0 || 255 < axesColor[1] ||
318  axesColor[2] < 0 || 255 < axesColor[2]) {
319 
320  bu_vls_printf(vlsp, "parseAxesArgs: bad axes color - %s\n", argv[6]);
321  return TCL_ERROR;
322  }
323 
324  if (sscanf(argv[7], "%d %d %d",
325  &labelColor[0],
326  &labelColor[1],
327  &labelColor[2]) != 3) {
328 
329  bu_vls_printf(vlsp, "parseAxesArgs: bad label color - %s\n", argv[7]);
330  return TCL_ERROR;
331  }
332 
333  /* validate color */
334  if (labelColor[0] < 0 || 255 < labelColor[0] ||
335  labelColor[1] < 0 || 255 < labelColor[1] ||
336  labelColor[2] < 0 || 255 < labelColor[2]) {
337 
338  bu_vls_printf(vlsp, "parseAxesArgs: bad label color - %s\n", argv[7]);
339  return TCL_ERROR;
340  }
341 
342  if (sscanf(argv[8], "%d", lineWidth) != 1) {
343  bu_vls_printf(vlsp, "parseAxesArgs: bad line width - %s\n", argv[8]);
344  return TCL_ERROR;
345  }
346 
347  /* validate lineWidth */
348  if (*lineWidth < 0) {
349  bu_vls_printf(vlsp, "parseAxesArgs: line width must be greater than 0\n");
350  return TCL_ERROR;
351  }
352 
353  /* parse positive only flag */
354  if (sscanf(argv[9], "%d", posOnly) != 1) {
355  bu_vls_printf(vlsp, "parseAxesArgs: bad positive only flag - %s\n", argv[9]);
356  return TCL_ERROR;
357  }
358 
359  /* validate tick enable flag */
360  if (*posOnly < 0) {
361  bu_vls_printf(vlsp, "parseAxesArgs: positive only flag must be >= 0\n");
362  return TCL_ERROR;
363  }
364 
365  /* parse three color flag */
366  if (sscanf(argv[10], "%d", tripleColor) != 1) {
367  bu_vls_printf(vlsp, "parseAxesArgs: bad three color flag - %s\n", argv[10]);
368  return TCL_ERROR;
369  }
370 
371  /* validate tick enable flag */
372  if (*tripleColor < 0) {
373  bu_vls_printf(vlsp, "parseAxesArgs: three color flag must be >= 0\n");
374  return TCL_ERROR;
375  }
376 
377  return TCL_OK;
378 }
379 
380 
381 /*
382  * Draw the view axes.
383  *
384  * Usage:
385  * objname drawViewAxes args
386  *
387  */
388 HIDDEN int
389 dmo_drawViewAxes_tcl(void *clientData, int argc, const char **argv)
390 {
391  point_t axesPos;
392  fastf_t viewSize;
393  mat_t rmat;
394  fastf_t axesSize;
395  int axesColor[3];
396  int labelColor[3];
397  int lineWidth;
398  int posOnly;
399  int tripleColor;
400  struct bview_axes_state bnas;
401  struct bu_vls vls = BU_VLS_INIT_ZERO;
402  struct dm_obj *dmop = (struct dm_obj *)clientData;
403 
404  if (!dmop || !dmop->interp)
405  return TCL_ERROR;
406 
407  if (argc != 11) {
408  /* return help message */
409  bu_vls_printf(&vls, "helplib_alias dm_drawViewAxes %s", argv[1]);
410  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
411  bu_vls_free(&vls);
412  return TCL_ERROR;
413  }
414 
415  memset(&bnas, 0, sizeof(struct bview_axes_state));
416 
417  if (dmo_parseAxesArgs(argc, argv, &viewSize, rmat, axesPos, &axesSize,
418  axesColor, labelColor, &lineWidth,
419  &posOnly, &tripleColor, &vls) == TCL_ERROR) {
420  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
421  bu_vls_free(&vls);
422  return TCL_ERROR;
423  }
424 
425  VMOVE(bnas.axes_pos, axesPos);
426  bnas.axes_size = axesSize;
427  VMOVE(bnas.axes_color, axesColor);
428  VMOVE(bnas.label_color, labelColor);
429  bnas.line_width = lineWidth;
430  bnas.pos_only = posOnly;
431  bnas.triple_color = tripleColor;
432 
433  dm_draw_axes(dmop->dmo_dmp, viewSize, rmat, &bnas);
434 
435  bu_vls_free(&vls);
436  return TCL_OK;
437 }
438 
439 
440 /*
441  * Draw the center dot.
442  *
443  * Usage:
444  * drawCenterDot color
445  *
446  */
447 HIDDEN int
449  int argc,
450  const char **argv)
451 {
452  int color[3];
453 
454  if (!dmop || !dmop->interp)
455  return TCL_ERROR;
456 
457  if (argc != 2) {
458  struct bu_vls vls = BU_VLS_INIT_ZERO;
459 
460  bu_vls_printf(&vls, "helplib_alias dm_drawCenterDot %s", argv[1]);
461  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
462  bu_vls_free(&vls);
463  return TCL_ERROR;
464  }
465 
466  if (sscanf(argv[1], "%d %d %d",
467  &color[0],
468  &color[1],
469  &color[2]) != 3) {
470  struct bu_vls vls = BU_VLS_INIT_ZERO;
471 
472  bu_vls_printf(&vls, "drawCenterDot: bad color - %s\n", argv[1]);
473  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
474  bu_vls_free(&vls);
475 
476  return TCL_ERROR;
477  }
478 
479  /* validate color */
480  if (color[0] < 0 || 255 < color[0] ||
481  color[1] < 0 || 255 < color[1] ||
482  color[2] < 0 || 255 < color[2]) {
483  struct bu_vls vls = BU_VLS_INIT_ZERO;
484 
485  bu_vls_printf(&vls, "drawCenterDot: bad color - %s\n", argv[1]);
486  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
487  bu_vls_free(&vls);
488 
489  return TCL_ERROR;
490  }
491 
492  dm_set_fg(dmop->dmo_dmp,
493  (unsigned char)color[0],
494  (unsigned char)color[1],
495  (unsigned char)color[2], 1, 1.0);
496 
497  dm_draw_point_2d(dmop->dmo_dmp, 0.0, 0.0);
498 
499  return TCL_OK;
500 }
501 
502 
503 /*
504  * Draw the center dot.
505  *
506  * Usage:
507  * objname drawCenterDot color
508  *
509  */
510 HIDDEN int
511 dmo_drawCenterDot_tcl(void *clientData, int argc, const char **argv)
512 {
513  struct dm_obj *dmop = (struct dm_obj *)clientData;
514 
515  if (!dmop || !dmop->interp)
516  return TCL_ERROR;
517 
518  return dmo_drawCenterDot_cmd(dmop, argc-1, argv+1);
519 }
520 
521 
522 HIDDEN int
524  const char **argv,
525  fastf_t *viewSize,
526  mat_t rmat,
527  mat_t model2view,
528  point_t axesPos,
529  fastf_t *axesSize,
530  int *axesColor,
531  int *lineWidth,
532  struct bu_vls *vlsp)
533 {
534  double scan;
535 
536  if (argc < 3 || sscanf(argv[2], "%lf", &scan) != 1) {
537  bu_vls_printf(vlsp, "parseDataAxesArgs: bad view size - %s\n", argv[2]);
538  return TCL_ERROR;
539  }
540  /* convert double to fastf_t */
541  *viewSize = scan;
542 
543  if (argc < 4 || bn_decode_mat(rmat, argv[3]) != 16) {
544  bu_vls_printf(vlsp, "parseDataAxesArgs: bad rmat - %s\n", argv[3]);
545  return TCL_ERROR;
546  }
547 
548  /* parse model to view matrix */
549  if (argc < 5 || bn_decode_mat(model2view, argv[4]) != 16) {
550  bu_vls_printf(vlsp, "parseDataAxesArgs: bad model2view - %s\n", argv[4]);
551  return TCL_ERROR;
552  }
553 
554  if (argc < 6 || bn_decode_vect(axesPos, argv[5]) != 3) {
555  bu_vls_printf(vlsp, "parseDataAxesArgs: bad axes position - %s\n", argv[5]);
556  return TCL_ERROR;
557  }
558 
559  if (argc < 7 || sscanf(argv[6], "%lf", &scan) != 1) {
560  bu_vls_printf(vlsp, "parseDataAxesArgs: bad axes size - %s\n", argv[6]);
561  return TCL_ERROR;
562  }
563  /* convert double to fastf_t */
564  *axesSize = scan;
565 
566  if (argc < 8 || sscanf(argv[7], "%d %d %d",
567  &axesColor[0],
568  &axesColor[1],
569  &axesColor[2]) != 3) {
570  bu_vls_printf(vlsp, "parseDataAxesArgs: bad axes color - %s\n", argv[7]);
571  return TCL_ERROR;
572  }
573 
574  /* validate color */
575  if (axesColor[0] < 0 || 255 < axesColor[0] ||
576  axesColor[1] < 0 || 255 < axesColor[1] ||
577  axesColor[2] < 0 || 255 < axesColor[2]) {
578 
579  bu_vls_printf(vlsp, "parseDataAxesArgs: bad axes color - %s\n", argv[7]);
580  return TCL_ERROR;
581  }
582 
583  if (sscanf(argv[8], "%d", lineWidth) != 1) {
584  bu_vls_printf(vlsp, "parseDataAxesArgs: bad line width - %s\n", argv[8]);
585  return TCL_ERROR;
586  }
587 
588  /* validate lineWidth */
589  if (*lineWidth < 0) {
590  bu_vls_printf(vlsp, "parseDataAxesArgs: line width must be greater than 0\n");
591  return TCL_ERROR;
592  }
593 
594  return TCL_OK;
595 }
596 
597 
598 /*
599  * Draw the data axes.
600  *
601  * Usage:
602  * objname drawDataAxes args
603  *
604  *XXX This needs to be modified to handle an array/list of data points
605  */
606 HIDDEN int
607 dmo_drawDataAxes_tcl(void *clientData, int argc, const char **argv)
608 {
609  point_t modelAxesPos;
610  fastf_t viewSize;
611  mat_t rmat;
612  mat_t model2view;
613  fastf_t axesSize;
614  int axesColor[3];
615  int lineWidth;
616  struct bview_data_axes_state bndas;
617  struct bu_vls vls = BU_VLS_INIT_ZERO;
618  struct dm_obj *dmop = (struct dm_obj *)clientData;
619 
620  if (!dmop || !dmop->interp)
621  return TCL_ERROR;
622 
623  if (argc != 9) {
624  /* return help message */
625  bu_vls_printf(&vls, "helplib_alias dm_drawDataAxes %s", argv[1]);
626  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
627  bu_vls_free(&vls);
628  return TCL_ERROR;
629  }
630 
631  if (dmo_parseDataAxesArgs(argc,
632  argv,
633  &viewSize,
634  rmat,
635  model2view,
636  modelAxesPos,
637  &axesSize,
638  axesColor,
639  &lineWidth,
640  &vls) == TCL_ERROR) {
641  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
642  bu_vls_free(&vls);
643  return TCL_ERROR;
644  }
645 
646  memset(&bndas, 0, sizeof(struct bview_data_axes_state));
647  VMOVE(bndas.points[0], modelAxesPos);
648  bndas.size = axesSize;
649  VMOVE(bndas.color, axesColor);
650  bndas.line_width = lineWidth;
651 
653  viewSize,
654  &bndas);
655 
656  bu_vls_free(&vls);
657  return TCL_OK;
658 }
659 
660 
661 HIDDEN int
663  const char **argv,
664  fastf_t *viewSize,
665  mat_t rmat,
666  point_t axesPos,
667  fastf_t *axesSize,
668  int *axesColor,
669  int *labelColor,
670  int *lineWidth,
671  int *posOnly,
672  int *tripleColor,
673  mat_t model2view,
674  int *tickEnable,
675  int *tickLength,
676  int *majorTickLength,
677  fastf_t *tickInterval,
678  int *ticksPerMajor,
679  int *tickColor,
680  int *majorTickColor,
681  int *tickThreshold,
682  struct bu_vls *vlsp)
683 {
684  double scan;
685 
686  if (dmo_parseAxesArgs(argc, argv, viewSize, rmat, axesPos, axesSize,
687  axesColor, labelColor, lineWidth,
688  posOnly, tripleColor, vlsp) == TCL_ERROR)
689  return TCL_ERROR;
690 
691  /* parse model to view matrix */
692  if (bn_decode_mat(model2view, argv[11]) != 16) {
693  bu_vls_printf(vlsp, "parseModelAxesArgs: bad model2view - %s\n", argv[11]);
694  return TCL_ERROR;
695  }
696 
697 /* parse tick enable flag */
698  if (sscanf(argv[12], "%d", tickEnable) != 1) {
699  bu_vls_printf(vlsp, "parseModelAxesArgs: bad tick enable flag - %s\n", argv[12]);
700  return TCL_ERROR;
701  }
702 
703 /* validate tick enable flag */
704  if (*tickEnable < 0) {
705  bu_vls_printf(vlsp, "parseModelAxesArgs: tick enable flag must be >= 0\n");
706  return TCL_ERROR;
707  }
708 
709 /* parse tick length */
710  if (sscanf(argv[13], "%d", tickLength) != 1) {
711  bu_vls_printf(vlsp, "parseModelAxesArgs: bad tick length - %s\n", argv[13]);
712  return TCL_ERROR;
713  }
714 
715 /* validate tick length */
716  if (*tickLength < 1) {
717  bu_vls_printf(vlsp, "parseModelAxesArgs: tick length must be >= 1\n");
718  return TCL_ERROR;
719  }
720 
721 /* parse major tick length */
722  if (sscanf(argv[14], "%d", majorTickLength) != 1) {
723  bu_vls_printf(vlsp, "parseModelAxesArgs: bad major tick length - %s\n", argv[14]);
724  return TCL_ERROR;
725  }
726 
727 /* validate major tick length */
728  if (*majorTickLength < 1) {
729  bu_vls_printf(vlsp, "parseModelAxesArgs: major tick length must be >= 1\n");
730  return TCL_ERROR;
731  }
732 
733 /* parse tick interval */
734  if (sscanf(argv[15], "%lf", &scan) != 1) {
735  bu_vls_printf(vlsp, "parseModelAxesArgs: tick interval must be > 0");
736  return TCL_ERROR;
737  }
738  /* convert double to fastf_t */
739  *tickInterval = scan;
740 
741 /* validate tick interval */
742  if (*tickInterval <= 0) {
743  bu_vls_printf(vlsp, "parseModelAxesArgs: tick interval must be > 0");
744  return TCL_ERROR;
745  }
746 
747 /* parse ticks per major */
748  if (sscanf(argv[16], "%d", ticksPerMajor) != 1) {
749  bu_vls_printf(vlsp, "parseModelAxesArgs: bad ticks per major - %s\n", argv[16]);
750  return TCL_ERROR;
751  }
752 
753 /* validate ticks per major */
754  if (*ticksPerMajor < 0) {
755  bu_vls_printf(vlsp, "parseModelAxesArgs: ticks per major must be >= 0\n");
756  return TCL_ERROR;
757  }
758 
759 /* parse tick color */
760  if (sscanf(argv[17], "%d %d %d",
761  &tickColor[0],
762  &tickColor[1],
763  &tickColor[2]) != 3) {
764 
765  bu_vls_printf(vlsp, "parseModelAxesArgs: bad tick color - %s\n", argv[17]);
766  return TCL_ERROR;
767  }
768 
769 /* validate tick color */
770  if (tickColor[0] < 0 || 255 < tickColor[0] ||
771  tickColor[1] < 0 || 255 < tickColor[1] ||
772  tickColor[2] < 0 || 255 < tickColor[2]) {
773 
774  bu_vls_printf(vlsp, "parseModelAxesArgs: bad tick color - %s\n", argv[17]);
775  return TCL_ERROR;
776  }
777 
778 /* parse major tick color */
779  if (sscanf(argv[18], "%d %d %d",
780  &majorTickColor[0],
781  &majorTickColor[1],
782  &majorTickColor[2]) != 3) {
783 
784  bu_vls_printf(vlsp, "parseModelAxesArgs: bad major tick color - %s\n", argv[18]);
785  return TCL_ERROR;
786  }
787 
788 /* validate tick color */
789  if (majorTickColor[0] < 0 || 255 < majorTickColor[0] ||
790  majorTickColor[1] < 0 || 255 < majorTickColor[1] ||
791  majorTickColor[2] < 0 || 255 < majorTickColor[2]) {
792 
793  bu_vls_printf(vlsp, "parseModelAxesArgs: bad major tick color - %s\n", argv[18]);
794  return TCL_ERROR;
795  }
796 
797 /* parse tick threshold */
798  if (sscanf(argv[19], "%d", tickThreshold) != 1) {
799  bu_vls_printf(vlsp, "parseModelAxesArgs: bad tick threshold - %s\n", argv[19]);
800  return TCL_ERROR;
801  }
802 
803 /* validate tick threshold */
804  if (*tickThreshold <= 0) {
805  bu_vls_printf(vlsp, "parseModelAxesArgs: tick threshold must be > 0\n");
806  return TCL_ERROR;
807  }
808 
809  return TCL_OK;
810 }
811 
812 
813 /*
814  * Draw the model axes.
815  *
816  * Usage:
817  * objname drawModelAxes args
818  *
819  */
820 HIDDEN int
821 dmo_drawModelAxes_tcl(void *clientData, int argc, const char **argv)
822 {
823  point_t modelAxesPos;
824  point_t viewAxesPos;
825  fastf_t viewSize;
826  mat_t rmat;
827  mat_t model2view;
828  fastf_t axesSize;
829  int axesColor[3];
830  int labelColor[3];
831  int lineWidth;
832  int posOnly;
833  int tripleColor;
834  int tickEnable;
835  int tickLength;
836  int majorTickLength;
837  fastf_t tickInterval;
838  int ticksPerMajor;
839  int tickColor[3];
840  int majorTickColor[3];
841  int tickThreshold;
842  struct bview_axes_state bnas;
843  struct bu_vls vls = BU_VLS_INIT_ZERO;
844  struct dm_obj *dmop = (struct dm_obj *)clientData;
845 
846  if (!dmop || !dmop->interp)
847  return TCL_ERROR;
848 
849  if (argc != 20) {
850  /* return help message */
851  bu_vls_printf(&vls, "helplib_alias dm_drawModelAxes %s", argv[1]);
852  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
853  bu_vls_free(&vls);
854  return TCL_ERROR;
855  }
856 
857  if (dmo_parseModelAxesArgs(argc, argv,
858  &viewSize, rmat, modelAxesPos,
859  &axesSize, axesColor,
860  labelColor, &lineWidth,
861  &posOnly, &tripleColor,
862  model2view, &tickEnable,
863  &tickLength, &majorTickLength,
864  &tickInterval, &ticksPerMajor,
865  tickColor, majorTickColor,
866  &tickThreshold, &vls) == TCL_ERROR) {
867  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
868  bu_vls_free(&vls);
869  return TCL_ERROR;
870  }
871 
872  MAT4X3PNT(viewAxesPos, model2view, modelAxesPos);
873 
874  memset(&bnas, 0, sizeof(struct bview_axes_state));
875  VMOVE(bnas.axes_pos, viewAxesPos);
876  bnas.axes_size = axesSize;
877  VMOVE(bnas.axes_color, axesColor);
878  VMOVE(bnas.label_color, labelColor);
879  bnas.line_width = lineWidth;
880  bnas.pos_only = posOnly;
881  bnas.triple_color = tripleColor;
882  bnas.tick_enabled = tickEnable;
883  bnas.tick_length = tickLength;
884  bnas.tick_major_length = majorTickLength;
885  bnas.tick_interval = tickInterval;
886  bnas.ticks_per_major = ticksPerMajor;
887  VMOVE(bnas.tick_color, tickColor);
888  VMOVE(bnas.tick_major_color, majorTickColor);
889  bnas.tick_threshold = tickThreshold;
890 
891  dm_draw_axes(dmop->dmo_dmp, viewSize, rmat, &bnas);
892 
893  bu_vls_free(&vls);
894  return TCL_OK;
895 }
896 
897 
898 /*
899  * Begin the draw cycle.
900  *
901  * Usage:
902  * objname drawBegin
903  *
904  */
905 HIDDEN int
906 dmo_drawBegin_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
907 {
908  struct dm_obj *dmop = (struct dm_obj *)clientData;
909 
910  if (!dmop || !dmop->interp)
911  return TCL_ERROR;
912 
913  return dm_draw_begin(dmop->dmo_dmp);
914 }
915 
916 
917 HIDDEN int
918 dmo_drawEnd_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
919 {
920  struct dm_obj *dmop = (struct dm_obj *)clientData;
921 
922  if (!dmop || !dmop->interp)
923  return TCL_ERROR;
924 
925  return dm_draw_end(dmop->dmo_dmp);
926 }
927 
928 
929 /*
930  * End the draw cycle.
931  *
932  * Usage:
933  * objname drawEnd
934  *
935  */
936 HIDDEN int
937 dmo_clear_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
938 {
939  struct dm_obj *dmop = (struct dm_obj *)clientData;
940  int status;
941 
942  if (!dmop || !dmop->interp)
943  return TCL_ERROR;
944 
945  if ((status = dm_draw_begin(dmop->dmo_dmp)) != TCL_OK)
946  return status;
947 
948  return dm_draw_end(dmop->dmo_dmp);
949 }
950 
951 
952 /*
953  * Clear the display.
954  *
955  * Usage:
956  * objname clear
957  *
958  */
959 HIDDEN int
960 dmo_normal_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
961 {
962  struct dm_obj *dmop = (struct dm_obj *)clientData;
963 
964  if (!dmop || !dmop->interp)
965  return TCL_ERROR;
966 
967  return dm_normal(dmop->dmo_dmp);
968 }
969 
970 
971 /*
972  * Reset the viewing transform.
973  *
974  * Usage:
975  * objname normal
976  *
977  */
978 HIDDEN int
979 dmo_loadmat_tcl(void *clientData, int argc, const char **argv)
980 {
981  struct dm_obj *dmop = (struct dm_obj *)clientData;
982  mat_t mat;
983  int which_eye;
984 
985  if (!dmop || !dmop->interp)
986  return TCL_ERROR;
987 
988  if (argc != 4) {
989  struct bu_vls vls = BU_VLS_INIT_ZERO;
990 
991  bu_vls_printf(&vls, "helplib_alias dm_loadmat %s", argv[1]);
992  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
993  bu_vls_free(&vls);
994  return TCL_ERROR;
995  }
996 
997 
998  if (bn_decode_mat(mat, argv[2]) != 16)
999  return TCL_ERROR;
1000 
1001  if (sscanf(argv[3], "%d", &which_eye) != 1) {
1002  Tcl_Obj *obj;
1003 
1004  obj = Tcl_GetObjResult(dmop->interp);
1005  if (Tcl_IsShared(obj))
1006  obj = Tcl_DuplicateObj(obj);
1007 
1008  Tcl_AppendStringsToObj(obj, "bad eye value - ", argv[3], (char *)NULL);
1009  Tcl_SetObjResult(dmop->interp, obj);
1010  return TCL_ERROR;
1011  }
1012 
1013  MAT_COPY(dmop->viewMat, mat);
1014 
1015  return dm_loadmatrix(dmop->dmo_dmp, mat, which_eye);
1016 }
1017 
1018 
1019 /*
1020  * Draw a string on the display.
1021  *
1022  * Usage:
1023  * objname drawString args
1024  *
1025  */
1026 HIDDEN int
1027 dmo_drawString_tcl(void *clientData, int argc, const char **argv)
1028 {
1029  struct dm_obj *dmop = (struct dm_obj *)clientData;
1030  fastf_t x, y;
1031  int size;
1032  int use_aspect;
1033 
1034  if (!dmop || !dmop->interp)
1035  return TCL_ERROR;
1036 
1037  if (argc != 7) {
1038  struct bu_vls vls = BU_VLS_INIT_ZERO;
1039 
1040  bu_vls_printf(&vls, "helplib_alias dm_drawString %s", argv[1]);
1041  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1042  bu_vls_free(&vls);
1043  return TCL_ERROR;
1044  }
1045 
1046  /*XXX use sscanf */
1047  x = atof(argv[3]);
1048  y = atof(argv[4]);
1049  size = atoi(argv[5]);
1050  use_aspect = atoi(argv[6]);
1051 
1052  return dm_draw_string_2d(dmop->dmo_dmp, argv[2], x, y, size, use_aspect);
1053 }
1054 
1055 
1056 HIDDEN int
1057 dmo_drawPoint_tcl(void *clientData, int argc, const char **argv)
1058 {
1059  struct dm_obj *dmop = (struct dm_obj *)clientData;
1060  fastf_t x, y;
1061 
1062  if (!dmop || !dmop->interp)
1063  return TCL_ERROR;
1064 
1065  if (argc != 4) {
1066  struct bu_vls vls = BU_VLS_INIT_ZERO;
1067 
1068  bu_vls_printf(&vls, "helplib_alias dm_drawPoint %s", argv[1]);
1069  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1070  bu_vls_free(&vls);
1071  return TCL_ERROR;
1072  }
1073 
1074  /*XXX use sscanf */
1075  x = atof(argv[2]);
1076  y = atof(argv[3]);
1077 
1078  return dm_draw_point_2d(dmop->dmo_dmp, x, y);
1079 }
1080 
1081 
1082 /*
1083  * Draw the line.
1084  *
1085  * Usage:
1086  * objname drawLine x1 y1 x2 y2
1087  *
1088  */
1089 HIDDEN int
1090 dmo_drawLine_tcl(void *clientData, int argc, const char **argv)
1091 {
1092  struct dm_obj *dmop = (struct dm_obj *)clientData;
1093  fastf_t xpos1, ypos1, xpos2, ypos2;
1094 
1095  if (!dmop || !dmop->interp)
1096  return TCL_ERROR;
1097 
1098  if (argc != 6) {
1099  struct bu_vls vls = BU_VLS_INIT_ZERO;
1100 
1101  bu_vls_printf(&vls, "helplib_alias dm_drawLine %s", argv[1]);
1102  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1103  bu_vls_free(&vls);
1104  return TCL_ERROR;
1105  }
1106 
1107  /*XXX use sscanf */
1108  xpos1 = atof(argv[2]);
1109  ypos1 = atof(argv[3]);
1110  xpos2 = atof(argv[4]);
1111  ypos2 = atof(argv[5]);
1112 
1113  return dm_draw_line_2d(dmop->dmo_dmp, xpos1, ypos1, xpos2, ypos2);
1114 }
1115 
1116 
1117 /*
1118  * Draw the vlist.
1119  *
1120  * Usage:
1121  * objname drawVList vid
1122  */
1123 HIDDEN int
1124 dmo_drawVList_tcl(void *clientData, int argc, const char **argv)
1125 {
1126  struct dm_obj *dmop = (struct dm_obj *)clientData;
1127  struct bn_vlist *vp;
1128 
1129  if (!dmop || !dmop->interp)
1130  return TCL_ERROR;
1131 
1132  if (argc != 3) {
1133  struct bu_vls vls = BU_VLS_INIT_ZERO;
1134 
1135  bu_vls_printf(&vls, "helplib_alias dm_drawVList %s", argv[1]);
1136  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1137  bu_vls_free(&vls);
1138  return TCL_ERROR;
1139  }
1140 
1141  if (sscanf(argv[2], "%lu", (unsigned long *)&vp) != 1) {
1142  Tcl_Obj *obj;
1143 
1144  obj = Tcl_GetObjResult(dmop->interp);
1145  if (Tcl_IsShared(obj))
1146  obj = Tcl_DuplicateObj(obj);
1147 
1148  Tcl_AppendStringsToObj(obj, "invalid vlist pointer - ", argv[2], (char *)NULL);
1149  Tcl_SetObjResult(dmop->interp, obj);
1150  return TCL_ERROR;
1151  }
1152 
1153  BN_CK_VLIST(vp);
1154 
1155  return dm_draw_vlist(dmop->dmo_dmp, vp);
1156 }
1157 
1158 
1159 HIDDEN void
1160 dmo_drawSolid(struct dm_obj *dmop,
1161  struct solid *sp)
1162 {
1163  if (sp->s_iflag == UP)
1164  dm_set_fg(dmop->dmo_dmp, 255, 255, 255, 0, sp->s_transparency);
1165  else
1166  dm_set_fg(dmop->dmo_dmp,
1167  (unsigned char)sp->s_color[0],
1168  (unsigned char)sp->s_color[1],
1169  (unsigned char)sp->s_color[2], 0, sp->s_transparency);
1170  dm_draw_vlist(dmop->dmo_dmp, (struct bn_vlist *)&sp->s_vlist);
1171 }
1172 
1173 
1174 /*
1175  * Draw a scale.
1176  *
1177  * Usage:
1178  * drawScale vsize color
1179  *
1180  */
1181 int
1183  int argc,
1184  const char **argv)
1185 {
1186  int color[3];
1187  double scan;
1188  fastf_t viewSize;
1189  struct bu_vls vls = BU_VLS_INIT_ZERO;
1190 
1191  if (argc != 3) {
1192  bu_vls_printf(&vls, "helplib_alias dm_drawScale %s", argv[0]);
1193  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1194  bu_vls_free(&vls);
1195  return TCL_ERROR;
1196  }
1197 
1198  if (sscanf(argv[1], "%lf", &scan) != 1) {
1199  bu_vls_printf(&vls, "drawScale: bad view size - %s\n", argv[1]);
1200  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
1201  bu_vls_free(&vls);
1202 
1203  return TCL_ERROR;
1204  }
1205  /* convert double to fastf_t */
1206  viewSize = scan;
1207 
1208  if (sscanf(argv[2], "%d %d %d",
1209  &color[0],
1210  &color[1],
1211  &color[2]) != 3) {
1212  bu_vls_printf(&vls, "drawScale: bad color - %s\n", argv[2]);
1213  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
1214  bu_vls_free(&vls);
1215 
1216  return TCL_ERROR;
1217  }
1218 
1219  /* validate color */
1220  if (color[0] < 0 || 255 < color[0]
1221  || color[1] < 0 || 255 < color[1]
1222  || color[2] < 0 || 255 < color[2])
1223  {
1224 
1225  bu_vls_printf(&vls, "drawScale: bad color - %s\n", argv[2]);
1226  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
1227  bu_vls_free(&vls);
1228 
1229  return TCL_ERROR;
1230  }
1231 
1232  dm_draw_scale(dmop->dmo_dmp, viewSize, color, color);
1233 
1234  return TCL_OK;
1235 }
1236 
1237 
1238 /*
1239  * Usage:
1240  * objname drawScale vsize color
1241  */
1242 HIDDEN int
1243 dmo_drawScale_tcl(void *clientData, int argc, const char **argv)
1244 {
1245  struct dm_obj *dmop = (struct dm_obj *)clientData;
1246 
1247  if (!dmop || !dmop->interp)
1248  return TCL_ERROR;
1249 
1250  return dmo_drawScale_cmd(dmop, argc-1, argv+1);
1251 }
1252 
1253 
1254 /*
1255  * Usage:
1256  * objname drawSList hsp
1257  */
1258 HIDDEN int
1259 dmo_drawSList(struct dm_obj *dmop,
1260  struct bu_list *hsp)
1261 {
1262  struct solid *sp;
1263  int linestyle = -1;
1264 
1265  if (!dmop)
1266  return TCL_ERROR;
1267 
1268  if (dmop->dmo_dmp->dm_transparency) {
1269  /* First, draw opaque stuff */
1270  FOR_ALL_SOLIDS(sp, hsp) {
1271  if (sp->s_transparency < 1.0)
1272  continue;
1273 
1274  if (linestyle != sp->s_soldash) {
1275  linestyle = sp->s_soldash;
1276  dm_set_line_attr(dmop->dmo_dmp, dmop->dmo_dmp->dm_lineWidth, linestyle);
1277  }
1278 
1279  dmo_drawSolid(dmop, sp);
1280  }
1281 
1282  /* disable write to depth buffer */
1283  dm_set_depth_mask(dmop->dmo_dmp, 0);
1284 
1285  /* Second, draw transparent stuff */
1286  FOR_ALL_SOLIDS(sp, hsp) {
1287  /* already drawn above */
1288  if (ZERO(sp->s_transparency - 1.0))
1289  continue;
1290 
1291  if (linestyle != sp->s_soldash) {
1292  linestyle = sp->s_soldash;
1293  dm_set_line_attr(dmop->dmo_dmp, dmop->dmo_dmp->dm_lineWidth, linestyle);
1294  }
1295 
1296  dmo_drawSolid(dmop, sp);
1297  }
1298 
1299  /* re-enable write to depth buffer */
1300  dm_set_depth_mask(dmop->dmo_dmp, 1);
1301  } else {
1302 
1303  FOR_ALL_SOLIDS(sp, hsp) {
1304  if (linestyle != sp->s_soldash) {
1305  linestyle = sp->s_soldash;
1306  dm_set_line_attr(dmop->dmo_dmp, dmop->dmo_dmp->dm_lineWidth, linestyle);
1307  }
1308 
1309  dmo_drawSolid(dmop, sp);
1310  }
1311  }
1312 
1313  return TCL_OK;
1314 }
1315 
1316 
1317 /*
1318  * Usage:
1319  * objname drawSList sid
1320  */
1321 HIDDEN int
1322 dmo_drawSList_tcl(void *clientData, int argc, const char **argv)
1323 {
1324  struct dm_obj *dmop = (struct dm_obj *)clientData;
1325  struct bu_list *hsp;
1326 
1327  if (!dmop || !dmop->interp)
1328  return TCL_ERROR;
1329 
1330  if (argc != 3) {
1331  struct bu_vls vls = BU_VLS_INIT_ZERO;
1332 
1333  bu_vls_printf(&vls, "helplib_alias dm_drawSList %s", argv[1]);
1334  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1335  bu_vls_free(&vls);
1336  return TCL_ERROR;
1337  }
1338 
1339  if (sscanf(argv[2], "%lu", (unsigned long *)&hsp) != 1) {
1340  Tcl_Obj *obj;
1341 
1342  obj = Tcl_GetObjResult(dmop->interp);
1343  if (Tcl_IsShared(obj))
1344  obj = Tcl_DuplicateObj(obj);
1345 
1346  Tcl_AppendStringsToObj(obj, "invalid solid list pointer - ",
1347  argv[2], "\n", (char *)NULL);
1348 
1349  Tcl_SetObjResult(dmop->interp, obj);
1350  return TCL_ERROR;
1351  }
1352  dmo_drawSList(dmop, hsp);
1353 
1354  return TCL_OK;
1355 }
1356 
1357 
1358 /*
1359  * Get/set the display manager's foreground color.
1360  *
1361  * Usage:
1362  * objname fg [rgb]
1363  */
1364 HIDDEN int
1365 dmo_fg_tcl(void *clientData, int argc, const char **argv)
1366 {
1367  struct dm_obj *dmop = (struct dm_obj *)clientData;
1368  struct bu_vls vls = BU_VLS_INIT_ZERO;
1369  int r, g, b;
1370  Tcl_Obj *obj;
1371 
1372  if (!dmop || !dmop->interp)
1373  return TCL_ERROR;
1374 
1375  obj = Tcl_GetObjResult(dmop->interp);
1376  if (Tcl_IsShared(obj))
1377  obj = Tcl_DuplicateObj(obj);
1378 
1379  /* get foreground color */
1380  if (argc == 2) {
1381  bu_vls_printf(&vls, "%d %d %d",
1382  dmop->dmo_dmp->dm_fg[0],
1383  dmop->dmo_dmp->dm_fg[1],
1384  dmop->dmo_dmp->dm_fg[2]);
1385  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1386  bu_vls_free(&vls);
1387 
1388  Tcl_SetObjResult(dmop->interp, obj);
1389  return TCL_OK;
1390  }
1391 
1392  /* set foreground color */
1393  if (argc == 3) {
1394  if (sscanf(argv[2], "%d %d %d", &r, &g, &b) != 3)
1395  goto bad_color;
1396 
1397  /* validate color */
1398  if (r < 0 || 255 < r ||
1399  g < 0 || 255 < g ||
1400  b < 0 || 255 < b)
1401  goto bad_color;
1402 
1403  bu_vls_free(&vls);
1404  return dm_set_fg(dmop->dmo_dmp,
1405  (unsigned char)r,
1406  (unsigned char)g,
1407  (unsigned char)b,
1408  1, 1.0);
1409  }
1410 
1411  /* wrong number of arguments */
1412  bu_vls_printf(&vls, "helplib_alias dm_fg %s", argv[1]);
1413  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1414  bu_vls_free(&vls);
1415  return TCL_ERROR;
1416 
1417 bad_color:
1418  bu_vls_printf(&vls, "bad rgb color - %s\n", argv[2]);
1419  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1420  bu_vls_free(&vls);
1421 
1422  Tcl_SetObjResult(dmop->interp, obj);
1423  return TCL_ERROR;
1424 }
1425 
1426 
1427 /*
1428  * Get/set the display manager's background color.
1429  *
1430  * Usage:
1431  * objname bg [rgb]
1432  */
1433 HIDDEN int
1434 dmo_bg_tcl(void *clientData, int argc, const char **argv)
1435 {
1436  struct dm_obj *dmop = (struct dm_obj *)clientData;
1437  struct bu_vls vls = BU_VLS_INIT_ZERO;
1438  int r, g, b;
1439  Tcl_Obj *obj;
1440 
1441  if (!dmop || !dmop->interp)
1442  return TCL_ERROR;
1443 
1444  obj = Tcl_GetObjResult(dmop->interp);
1445  if (Tcl_IsShared(obj))
1446  obj = Tcl_DuplicateObj(obj);
1447 
1448  /* get background color */
1449  if (argc == 2) {
1450  bu_vls_printf(&vls, "%d %d %d",
1451  dmop->dmo_dmp->dm_bg[0],
1452  dmop->dmo_dmp->dm_bg[1],
1453  dmop->dmo_dmp->dm_bg[2]);
1454  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1455  bu_vls_free(&vls);
1456 
1457  Tcl_SetObjResult(dmop->interp, obj);
1458  return TCL_OK;
1459  }
1460 
1461  /* set background color */
1462  if (argc == 3) {
1463  if (sscanf(argv[2], "%d %d %d", &r, &g, &b) != 3)
1464  goto bad_color;
1465 
1466  /* validate color */
1467  if (r < 0 || 255 < r ||
1468  g < 0 || 255 < g ||
1469  b < 0 || 255 < b)
1470  goto bad_color;
1471 
1472  bu_vls_free(&vls);
1473  return dm_set_bg(dmop->dmo_dmp, (unsigned char)r, (unsigned char)g, (unsigned char)b);
1474  }
1475 
1476  /* wrong number of arguments */
1477  bu_vls_printf(&vls, "helplib_alias dm_bg %s", argv[1]);
1478  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1479  bu_vls_free(&vls);
1480  return TCL_ERROR;
1481 
1482 bad_color:
1483  bu_vls_printf(&vls, "bad rgb color - %s\n", argv[2]);
1484  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1485  bu_vls_free(&vls);
1486 
1487  Tcl_SetObjResult(dmop->interp, obj);
1488  return TCL_ERROR;
1489 }
1490 
1491 
1492 /*
1493  * Get/set the display manager's linewidth.
1494  *
1495  * Usage:
1496  * objname linewidth [n]
1497  */
1498 HIDDEN int
1499 dmo_lineWidth_tcl(void *clientData, int argc, const char **argv)
1500 {
1501  struct dm_obj *dmop = (struct dm_obj *)clientData;
1502  struct bu_vls vls = BU_VLS_INIT_ZERO;
1503  int lineWidth;
1504  Tcl_Obj *obj;
1505 
1506  if (!dmop || !dmop->interp)
1507  return TCL_ERROR;
1508 
1509  obj = Tcl_GetObjResult(dmop->interp);
1510  if (Tcl_IsShared(obj))
1511  obj = Tcl_DuplicateObj(obj);
1512 
1513  /* get linewidth */
1514  if (argc == 2) {
1515  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_lineWidth);
1516  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1517  bu_vls_free(&vls);
1518 
1519  Tcl_SetObjResult(dmop->interp, obj);
1520  return TCL_OK;
1521  }
1522 
1523  /* set lineWidth */
1524  if (argc == 3) {
1525  if (sscanf(argv[2], "%d", &lineWidth) != 1)
1526  goto bad_lineWidth;
1527 
1528  /* validate lineWidth */
1529  if (lineWidth < 0 || 20 < lineWidth)
1530  goto bad_lineWidth;
1531 
1532  bu_vls_free(&vls);
1533  return dm_set_line_attr(dmop->dmo_dmp, lineWidth, dmop->dmo_dmp->dm_lineStyle);
1534  }
1535 
1536  /* wrong number of arguments */
1537  bu_vls_printf(&vls, "helplib_alias dm_linewidth %s", argv[1]);
1538  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1539  bu_vls_free(&vls);
1540  return TCL_ERROR;
1541 
1542 bad_lineWidth:
1543  bu_vls_printf(&vls, "bad linewidth - %s\n", argv[2]);
1544  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1545  bu_vls_free(&vls);
1546 
1547  Tcl_SetObjResult(dmop->interp, obj);
1548  return TCL_ERROR;
1549 }
1550 
1551 
1552 /*
1553  * Get/set the display manager's linestyle.
1554  *
1555  * Usage:
1556  * objname linestyle [0|1]
1557  */
1558 HIDDEN int
1559 dmo_lineStyle_tcl(void *clientData, int argc, const char **argv)
1560 {
1561  struct dm_obj *dmop = (struct dm_obj *)clientData;
1562  struct bu_vls vls = BU_VLS_INIT_ZERO;
1563  int linestyle;
1564  Tcl_Obj *obj;
1565 
1566  if (!dmop || !dmop->interp)
1567  return TCL_ERROR;
1568 
1569  obj = Tcl_GetObjResult(dmop->interp);
1570  if (Tcl_IsShared(obj))
1571  obj = Tcl_DuplicateObj(obj);
1572 
1573  /* get linestyle */
1574  if (argc == 2) {
1575  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_lineStyle);
1576  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1577  bu_vls_free(&vls);
1578 
1579  Tcl_SetObjResult(dmop->interp, obj);
1580  return TCL_OK;
1581  }
1582 
1583  /* set linestyle */
1584  if (argc == 3) {
1585  if (sscanf(argv[2], "%d", &linestyle) != 1)
1586  goto bad_linestyle;
1587 
1588  /* validate linestyle */
1589  if (linestyle < 0 || 1 < linestyle)
1590  goto bad_linestyle;
1591 
1592  bu_vls_free(&vls);
1593  return dm_set_line_attr(dmop->dmo_dmp, dmop->dmo_dmp->dm_lineWidth, linestyle);
1594  }
1595 
1596  /* wrong number of arguments */
1597  bu_vls_printf(&vls, "helplib_alias dm_linestyle %s", argv[1]);
1598  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1599  bu_vls_free(&vls);
1600  return TCL_ERROR;
1601 
1602 bad_linestyle:
1603  bu_vls_printf(&vls, "bad linestyle - %s\n", argv[2]);
1604  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1605  bu_vls_free(&vls);
1606 
1607  Tcl_SetObjResult(dmop->interp, obj);
1608  return TCL_ERROR;
1609 }
1610 
1611 
1612 /*
1613  * Configure the display manager window. This is typically
1614  * called as a result of a ConfigureNotify event.
1615  *
1616  * Usage:
1617  * objname configure
1618  */
1619 HIDDEN int
1620 dmo_configure_tcl(void *clientData, int argc, const char **argv)
1621 {
1622  struct dm_obj *dmop = (struct dm_obj *)clientData;
1623  int status;
1624 
1625  if (!dmop || !dmop->interp)
1626  return TCL_ERROR;
1627 
1628  if (argc != 2) {
1629  struct bu_vls vls = BU_VLS_INIT_ZERO;
1630 
1631  bu_vls_printf(&vls, "helplib_alias dm_configure %s", argv[1]);
1632  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1633  bu_vls_free(&vls);
1634  return TCL_ERROR;
1635  }
1636 
1637  /* configure the display manager window */
1638  status = dm_configure_win(dmop->dmo_dmp, 0);
1639 
1640 #ifdef USE_FBSERV
1641  /* configure the framebuffer window */
1642  if (dmop->dmo_fbs.fbs_fbp != FB_NULL)
1643  (void)fb_configure_window(dmop->dmo_fbs.fbs_fbp,
1644  dmop->dmo_dmp->dm_width,
1645  dmop->dmo_dmp->dm_height);
1646 #endif
1647 
1648  return status;
1649 }
1650 
1651 
1652 /*
1653  * Get/set the display manager's zclip flag.
1654  *
1655  * Usage:
1656  * objname zclip [0|1]
1657  */
1658 HIDDEN int
1659 dmo_zclip_tcl(void *clientData, int argc, const char **argv)
1660 {
1661  struct dm_obj *dmop = (struct dm_obj *)clientData;
1662  struct bu_vls vls = BU_VLS_INIT_ZERO;
1663  int zclip;
1664  Tcl_Obj *obj;
1665 
1666  if (!dmop || !dmop->interp)
1667  return TCL_ERROR;
1668 
1669  obj = Tcl_GetObjResult(dmop->interp);
1670  if (Tcl_IsShared(obj))
1671  obj = Tcl_DuplicateObj(obj);
1672 
1673  /* get zclip flag */
1674  if (argc == 2) {
1675  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_zclip);
1676  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1677  bu_vls_free(&vls);
1678 
1679  Tcl_SetObjResult(dmop->interp, obj);
1680  return TCL_OK;
1681  }
1682 
1683  /* set zclip flag */
1684  if (argc == 3) {
1685  if (sscanf(argv[2], "%d", &zclip) != 1) {
1686  Tcl_AppendStringsToObj(obj, "dmo_zclip: invalid zclip value - ",
1687  argv[2], "\n", (char *)NULL);
1688  Tcl_SetObjResult(dmop->interp, obj);
1689  return TCL_ERROR;
1690  }
1691 
1692  dmop->dmo_dmp->dm_zclip = zclip;
1693  return TCL_OK;
1694  }
1695 
1696  bu_vls_printf(&vls, "helplib_alias dm_zclip %s", argv[1]);
1697  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1698  bu_vls_free(&vls);
1699  return TCL_ERROR;
1700 }
1701 
1702 
1703 /*
1704  * Get/set the display manager's zbuffer flag.
1705  *
1706  * Usage:
1707  * objname zbuffer [0|1]
1708  */
1709 HIDDEN int
1710 dmo_zbuffer_tcl(void *clientData, int argc, const char **argv)
1711 {
1712  struct dm_obj *dmop = (struct dm_obj *)clientData;
1713  struct bu_vls vls = BU_VLS_INIT_ZERO;
1714  int zbuffer;
1715  Tcl_Obj *obj;
1716 
1717  if (!dmop || !dmop->interp)
1718  return TCL_ERROR;
1719 
1720  obj = Tcl_GetObjResult(dmop->interp);
1721  if (Tcl_IsShared(obj))
1722  obj = Tcl_DuplicateObj(obj);
1723 
1724  /* get zbuffer flag */
1725  if (argc == 2) {
1726  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_zbuffer);
1727  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1728  bu_vls_free(&vls);
1729 
1730  Tcl_SetObjResult(dmop->interp, obj);
1731  return TCL_OK;
1732  }
1733 
1734  /* set zbuffer flag */
1735  if (argc == 3) {
1736  if (sscanf(argv[2], "%d", &zbuffer) != 1) {
1737  Tcl_AppendStringsToObj(obj, "dmo_zbuffer: invalid zbuffer value - ",
1738  argv[2], "\n", (char *)NULL);
1739  Tcl_SetObjResult(dmop->interp, obj);
1740  return TCL_ERROR;
1741  }
1742 
1743  dm_set_zbuffer(dmop->dmo_dmp, zbuffer);
1744  return TCL_OK;
1745  }
1746 
1747  bu_vls_printf(&vls, "helplib_alias dm_zbuffer %s", argv[1]);
1748  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1749  bu_vls_free(&vls);
1750  return TCL_ERROR;
1751 }
1752 
1753 
1754 /*
1755  * Get/set the display manager's light flag.
1756  *
1757  * Usage:
1758  * objname light [0|1]
1759  */
1760 HIDDEN int
1761 dmo_light_tcl(void *clientData, int argc, const char **argv)
1762 {
1763  struct dm_obj *dmop = (struct dm_obj *)clientData;
1764  struct bu_vls vls = BU_VLS_INIT_ZERO;
1765  int light;
1766  Tcl_Obj *obj;
1767 
1768  if (!dmop || !dmop->interp)
1769  return TCL_ERROR;
1770 
1771  obj = Tcl_GetObjResult(dmop->interp);
1772  if (Tcl_IsShared(obj))
1773  obj = Tcl_DuplicateObj(obj);
1774 
1775  /* get light flag */
1776  if (argc == 2) {
1777  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_light);
1778  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1779  bu_vls_free(&vls);
1780 
1781  Tcl_SetObjResult(dmop->interp, obj);
1782  return TCL_OK;
1783  }
1784 
1785  /* set light flag */
1786  if (argc == 3) {
1787  if (sscanf(argv[2], "%d", &light) != 1) {
1788  Tcl_AppendStringsToObj(obj, "dmo_light: invalid light value - ",
1789  argv[2], "\n", (char *)NULL);
1790 
1791  Tcl_SetObjResult(dmop->interp, obj);
1792  return TCL_ERROR;
1793  }
1794 
1795  (void)dm_set_light(dmop->dmo_dmp, light);
1796  return TCL_OK;
1797  }
1798 
1799  bu_vls_printf(&vls, "helplib_alias dm_light %s", argv[1]);
1800  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1801  bu_vls_free(&vls);
1802  return TCL_ERROR;
1803 }
1804 
1805 
1806 /*
1807  * Get/set the display manager's transparency flag.
1808  *
1809  * Usage:
1810  * objname transparency [0|1]
1811  */
1812 HIDDEN int
1813 dmo_transparency_tcl(void *clientData, int argc, const char **argv)
1814 {
1815  struct dm_obj *dmop = (struct dm_obj *)clientData;
1816  struct bu_vls vls = BU_VLS_INIT_ZERO;
1817  int transparency;
1818  Tcl_Obj *obj;
1819 
1820  if (!dmop || !dmop->interp)
1821  return TCL_ERROR;
1822 
1823  obj = Tcl_GetObjResult(dmop->interp);
1824  if (Tcl_IsShared(obj))
1825  obj = Tcl_DuplicateObj(obj);
1826 
1827  /* get transparency flag */
1828  if (argc == 2) {
1829  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_transparency);
1830  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1831  bu_vls_free(&vls);
1832 
1833  Tcl_SetObjResult(dmop->interp, obj);
1834  return TCL_OK;
1835  }
1836 
1837  /* set transparency flag */
1838  if (argc == 3) {
1839  if (sscanf(argv[2], "%d", &transparency) != 1) {
1840  Tcl_AppendStringsToObj(obj, "dmo_transparency: invalid transparency value - ",
1841  argv[2], "\n", (char *)NULL);
1842 
1843  Tcl_SetObjResult(dmop->interp, obj);
1844  return TCL_ERROR;
1845  }
1846 
1847  (void)dm_set_transparency(dmop->dmo_dmp, transparency);
1848  return TCL_OK;
1849  }
1850 
1851  bu_vls_printf(&vls, "helplib_alias dm_transparency %s", argv[1]);
1852  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1853  bu_vls_free(&vls);
1854  return TCL_ERROR;
1855 }
1856 
1857 
1858 /*
1859  * Get/set the display manager's depth mask flag.
1860  *
1861  * Usage:
1862  * objname depthMask [0|1]
1863  */
1864 HIDDEN int
1865 dmo_depthMask_tcl(void *clientData, int argc, const char **argv)
1866 {
1867  struct dm_obj *dmop = (struct dm_obj *)clientData;
1868  struct bu_vls vls = BU_VLS_INIT_ZERO;
1869  int depthMask;
1870  Tcl_Obj *obj;
1871 
1872  if (!dmop || !dmop->interp)
1873  return TCL_ERROR;
1874 
1875  obj = Tcl_GetObjResult(dmop->interp);
1876  if (Tcl_IsShared(obj))
1877  obj = Tcl_DuplicateObj(obj);
1878 
1879  /* get depthMask flag */
1880  if (argc == 2) {
1881  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_depthMask);
1882  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1883  bu_vls_free(&vls);
1884 
1885  Tcl_SetObjResult(dmop->interp, obj);
1886  return TCL_OK;
1887  }
1888 
1889  /* set depthMask flag */
1890  if (argc == 3) {
1891  if (sscanf(argv[2], "%d", &depthMask) != 1) {
1892  Tcl_AppendStringsToObj(obj, "dmo_depthMask: invalid depthMask value - ",
1893  argv[2], "\n", (char *)NULL);
1894 
1895  Tcl_SetObjResult(dmop->interp, obj);
1896  return TCL_ERROR;
1897  }
1898 
1899  dm_set_depth_mask(dmop->dmo_dmp, depthMask);
1900  return TCL_OK;
1901  }
1902 
1903  bu_vls_printf(&vls, "helplib_alias dm_depthMask %s", argv[1]);
1904  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1905  bu_vls_free(&vls);
1906  return TCL_ERROR;
1907 }
1908 
1909 
1910 /*
1911  * Get/set the display manager's window bounds.
1912  *
1913  * Usage:
1914  * objname bounds ["xmin xmax ymin ymax zmin zmax"]
1915  */
1916 HIDDEN int
1917 dmo_bounds_tcl(void *clientData, int argc, const char **argv)
1918 {
1919  struct dm_obj *dmop = (struct dm_obj *)clientData;
1920  struct bu_vls vls = BU_VLS_INIT_ZERO;
1921  Tcl_Obj *obj;
1922 
1923  /* intentionally double for scan */
1924  double clipmin[3];
1925  double clipmax[3];
1926 
1927  if (!dmop || !dmop->interp)
1928  return TCL_ERROR;
1929 
1930  obj = Tcl_GetObjResult(dmop->interp);
1931  if (Tcl_IsShared(obj))
1932  obj = Tcl_DuplicateObj(obj);
1933 
1934  /* get window bounds */
1935  if (argc == 2) {
1936  bu_vls_printf(&vls, "%g %g %g %g %g %g",
1937  dmop->dmo_dmp->dm_clipmin[X],
1938  dmop->dmo_dmp->dm_clipmax[X],
1939  dmop->dmo_dmp->dm_clipmin[Y],
1940  dmop->dmo_dmp->dm_clipmax[Y],
1941  dmop->dmo_dmp->dm_clipmin[Z],
1942  dmop->dmo_dmp->dm_clipmax[Z]);
1943  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
1944  bu_vls_free(&vls);
1945 
1946  Tcl_SetObjResult(dmop->interp, obj);
1947  return TCL_OK;
1948  }
1949 
1950  /* set window bounds */
1951  if (argc == 3) {
1952  if (sscanf(argv[2], "%lf %lf %lf %lf %lf %lf",
1953  &clipmin[X], &clipmax[X],
1954  &clipmin[Y], &clipmax[Y],
1955  &clipmin[Z], &clipmax[Z]) != 6) {
1956  Tcl_AppendStringsToObj(obj, "dmo_bounds: invalid bounds - ",
1957  argv[2], "\n", (char *)NULL);
1958 
1959  Tcl_SetObjResult(dmop->interp, obj);
1960  return TCL_ERROR;
1961  }
1962 
1963  VMOVE(dmop->dmo_dmp->dm_clipmin, clipmin);
1964  VMOVE(dmop->dmo_dmp->dm_clipmax, clipmax);
1965 
1966  /*
1967  * Since dm_bound doesn't appear to be used anywhere,
1968  * I'm going to use it for controlling the location
1969  * of the zclipping plane in dm-ogl.c. dm-X.c uses
1970  * dm_clipmin and dm_clipmax.
1971  */
1972  if (dmop->dmo_dmp->dm_clipmax[2] <= GED_MAX)
1973  dmop->dmo_dmp->dm_bound = 1.0;
1974  else
1975  dmop->dmo_dmp->dm_bound = GED_MAX / dmop->dmo_dmp->dm_clipmax[2];
1976 
1977  return TCL_OK;
1978  }
1979 
1980  bu_vls_printf(&vls, "helplib_alias dm_bounds %s", argv[1]);
1981  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
1982  bu_vls_free(&vls);
1983 
1984  return TCL_ERROR;
1985 }
1986 
1987 
1988 /*
1989  * Get/set the display manager's perspective mode.
1990  *
1991  * Usage:
1992  * objname perspective [n]
1993  */
1994 HIDDEN int
1995 dmo_perspective_tcl(void *clientData, int argc, const char **argv)
1996 {
1997  struct dm_obj *dmop = (struct dm_obj *)clientData;
1998  struct bu_vls vls = BU_VLS_INIT_ZERO;
1999  int perspective;
2000  Tcl_Obj *obj;
2001 
2002  if (!dmop || !dmop->interp)
2003  return TCL_ERROR;
2004 
2005  obj = Tcl_GetObjResult(dmop->interp);
2006  if (Tcl_IsShared(obj))
2007  obj = Tcl_DuplicateObj(obj);
2008 
2009  /* get perspective mode */
2010  if (argc == 2) {
2011  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_perspective);
2012  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2013  bu_vls_free(&vls);
2014 
2015  Tcl_SetObjResult(dmop->interp, obj);
2016  return TCL_OK;
2017  }
2018 
2019  /* set perspective mode */
2020  if (argc == 3) {
2021  if (sscanf(argv[2], "%d", &perspective) != 1) {
2022  Tcl_AppendStringsToObj(obj,
2023  "dmo_perspective: invalid perspective mode - ",
2024  argv[2], "\n", (char *)NULL);
2025 
2026  Tcl_SetObjResult(dmop->interp, obj);
2027  return TCL_ERROR;
2028  }
2029 
2030  dmop->dmo_dmp->dm_perspective = perspective;
2031  return TCL_OK;
2032  }
2033 
2034  bu_vls_printf(&vls, "helplib_alias dm_perspective %s", argv[1]);
2035  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2036  bu_vls_free(&vls);
2037  return TCL_ERROR;
2038 }
2039 
2040 
2041 #if defined(DM_X) || defined(DM_OGL)
2042 
2043 HIDDEN int
2044 dmo_png_cmd(struct dm_obj *dmop,
2045  int argc,
2046  const char **argv)
2047 {
2048  FILE *fp;
2049  png_structp png_p;
2050  png_infop info_p;
2051  XImage *ximage_p;
2052  unsigned char **rows;
2053  unsigned char *idata;
2054  unsigned char *irow;
2055  int bytes_per_pixel;
2056  int bits_per_channel = 8; /* bits per color channel */
2057  int i, j, k;
2058  unsigned char *dbyte0, *dbyte1, *dbyte2, *dbyte3;
2059  int red_shift;
2060  int green_shift;
2061  int blue_shift;
2062  int red_bits;
2063  int green_bits;
2064  int blue_bits;
2065 
2066  if (argc != 2) {
2067  struct bu_vls vls = BU_VLS_INIT_ZERO;
2068 
2069  bu_vls_printf(&vls, "helplib_alias dm_png %s", argv[0]);
2070  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2071  bu_vls_free(&vls);
2072  return TCL_ERROR;
2073  }
2074 
2075  if ((fp = fopen(argv[1], "wb")) == NULL) {
2076  Tcl_AppendResult(dmop->interp, "png: cannot open \"", argv[1], " for writing\n", (char *)NULL);
2077  return TCL_ERROR;
2078  }
2079 
2080  png_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
2081  if (!png_p) {
2082  Tcl_AppendResult(dmop->interp, "png: could not create PNG write structure\n", (char *)NULL);
2083  fclose(fp);
2084  return TCL_ERROR;
2085  }
2086 
2087  info_p = png_create_info_struct(png_p);
2088  if (!info_p) {
2089  Tcl_AppendResult(dmop->interp, "png: could not create PNG info structure\n", (char *)NULL);
2090  fclose(fp);
2091  return TCL_ERROR;
2092  }
2093 
2094  ximage_p = XGetImage(((struct dm_xvars *)dmop->dmo_dmp->dm_vars.pub_vars)->dpy,
2095  ((struct dm_xvars *)dmop->dmo_dmp->dm_vars.pub_vars)->win,
2096  0, 0,
2097  dmop->dmo_dmp->dm_width,
2098  dmop->dmo_dmp->dm_height,
2099  ~0, ZPixmap);
2100  if (!ximage_p) {
2101  Tcl_AppendResult(dmop->interp, "png: could not get XImage\n", (char *)NULL);
2102  fclose(fp);
2103  return TCL_ERROR;
2104  }
2105 
2106  bytes_per_pixel = ximage_p->bytes_per_line / ximage_p->width;
2107 
2108  if (bytes_per_pixel == 4) {
2109  unsigned long mask;
2110  unsigned long tmask;
2111 
2112  /* This section assumes 8 bits per channel */
2113 
2114  mask = ximage_p->red_mask;
2115  tmask = 1;
2116  for (red_shift = 0; red_shift < 32; red_shift++) {
2117  if (tmask & mask)
2118  break;
2119  tmask = tmask << 1;
2120  }
2121 
2122  mask = ximage_p->green_mask;
2123  tmask = 1;
2124  for (green_shift = 0; green_shift < 32; green_shift++) {
2125  if (tmask & mask)
2126  break;
2127  tmask = tmask << 1;
2128  }
2129 
2130  mask = ximage_p->blue_mask;
2131  tmask = 1;
2132  for (blue_shift = 0; blue_shift < 32; blue_shift++) {
2133  if (tmask & mask)
2134  break;
2135  tmask = tmask << 1;
2136  }
2137 
2138  /*
2139  * We need to reverse things if the image byte order
2140  * is different from the system's byte order.
2141  */
2142  if (((bu_byteorder() == BU_BIG_ENDIAN) && (ximage_p->byte_order == LSBFirst)) ||
2143  ((bu_byteorder() == BU_LITTLE_ENDIAN) && (ximage_p->byte_order == MSBFirst))) {
2144  DM_REVERSE_COLOR_BYTE_ORDER(red_shift, ximage_p->red_mask);
2145  DM_REVERSE_COLOR_BYTE_ORDER(green_shift, ximage_p->green_mask);
2146  DM_REVERSE_COLOR_BYTE_ORDER(blue_shift, ximage_p->blue_mask);
2147  }
2148 
2149  } else if (bytes_per_pixel == 2) {
2150  unsigned long mask;
2151  unsigned long tmask;
2152  int bpb = 8; /* bits per byte */
2153 
2154  /*XXX
2155  * This section probably needs logic similar
2156  * to the previous section (i.e. bytes_per_pixel == 4).
2157  * That is we may need to reverse things depending on
2158  * the image byte order and the system's byte order.
2159  */
2160 
2161  mask = ximage_p->red_mask;
2162  tmask = 1;
2163  for (red_shift = 0; red_shift < 16; red_shift++) {
2164  if (tmask & mask)
2165  break;
2166  tmask = tmask << 1;
2167  }
2168  for (red_bits = red_shift; red_bits < 16; red_bits++) {
2169  if (!(tmask & mask))
2170  break;
2171  tmask = tmask << 1;
2172  }
2173 
2174  red_bits = red_bits - red_shift;
2175  if (red_shift == 0)
2176  red_shift = red_bits - bpb;
2177  else
2178  red_shift = red_shift - (bpb - red_bits);
2179 
2180  mask = ximage_p->green_mask;
2181  tmask = 1;
2182  for (green_shift = 0; green_shift < 16; green_shift++) {
2183  if (tmask & mask)
2184  break;
2185  tmask = tmask << 1;
2186  }
2187  for (green_bits = green_shift; green_bits < 16; green_bits++) {
2188  if (!(tmask & mask))
2189  break;
2190  tmask = tmask << 1;
2191  }
2192 
2193  green_bits = green_bits - green_shift;
2194  green_shift = green_shift - (bpb - green_bits);
2195 
2196  mask = ximage_p->blue_mask;
2197  tmask = 1;
2198  for (blue_shift = 0; blue_shift < 16; blue_shift++) {
2199  if (tmask & mask)
2200  break;
2201  tmask = tmask << 1;
2202  }
2203  for (blue_bits = blue_shift; blue_bits < 16; blue_bits++) {
2204  if (!(tmask & mask))
2205  break;
2206  tmask = tmask << 1;
2207  }
2208  blue_bits = blue_bits - blue_shift;
2209 
2210  if (blue_shift == 0)
2211  blue_shift = blue_bits - bpb;
2212  else
2213  blue_shift = blue_shift - (bpb - blue_bits);
2214  } else {
2215  struct bu_vls vls = BU_VLS_INIT_ZERO;
2216 
2217  bu_vls_printf(&vls, "png: %d bytes per pixel is not yet supported\n", bytes_per_pixel);
2218  Tcl_AppendResult(dmop->interp, bu_vls_addr(&vls), (char *)NULL);
2219  fclose(fp);
2220  bu_vls_free(&vls);
2221 
2222  return TCL_ERROR;
2223  }
2224 
2225  rows = (unsigned char **)bu_calloc(ximage_p->height, sizeof(unsigned char *), "rows");
2226  idata = (unsigned char *)bu_calloc(ximage_p->height * ximage_p->width, 4, "png data");
2227 
2228  /* for each scanline */
2229  for (i = ximage_p->height - 1, j = 0; 0 <= i; --i, ++j) {
2230  /* irow points to the current scanline in ximage_p */
2231  irow = (unsigned char *)(ximage_p->data + ((ximage_p->height-i-1)*ximage_p->bytes_per_line));
2232 
2233  if (bytes_per_pixel == 4) {
2234  unsigned int pixel;
2235 
2236  /* rows[j] points to the current scanline in idata */
2237  rows[j] = (unsigned char *)(idata + ((ximage_p->height-i-1)*ximage_p->bytes_per_line));
2238 
2239  /* for each pixel in current scanline of ximage_p */
2240  for (k = 0; k < ximage_p->bytes_per_line; k += bytes_per_pixel) {
2241  pixel = *((unsigned int *)(irow + k));
2242 
2243  dbyte0 = rows[j] + k;
2244  dbyte1 = dbyte0 + 1;
2245  dbyte2 = dbyte0 + 2;
2246  dbyte3 = dbyte0 + 3;
2247 
2248  *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
2249  *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
2250  *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
2251  *dbyte3 = 255;
2252  }
2253  } else if (bytes_per_pixel == 2) {
2254  unsigned short spixel;
2255  unsigned long pixel;
2256 
2257  /* rows[j] points to the current scanline in idata */
2258  rows[j] = (unsigned char *)(idata + ((ximage_p->height-i-1)*ximage_p->bytes_per_line*2));
2259 
2260  /* for each pixel in current scanline of ximage_p */
2261  for (k = 0; k < ximage_p->bytes_per_line; k += bytes_per_pixel) {
2262  spixel = *((unsigned short *)(irow + k));
2263  pixel = spixel;
2264 
2265  dbyte0 = rows[j] + k*2;
2266  dbyte1 = dbyte0 + 1;
2267  dbyte2 = dbyte0 + 2;
2268  dbyte3 = dbyte0 + 3;
2269 
2270  if (0 <= red_shift)
2271  *dbyte0 = (pixel & ximage_p->red_mask) >> red_shift;
2272  else
2273  *dbyte0 = (pixel & ximage_p->red_mask) << -red_shift;
2274 
2275  *dbyte1 = (pixel & ximage_p->green_mask) >> green_shift;
2276 
2277  if (0 <= blue_shift)
2278  *dbyte2 = (pixel & ximage_p->blue_mask) >> blue_shift;
2279  else
2280  *dbyte2 = (pixel & ximage_p->blue_mask) << -blue_shift;
2281 
2282  *dbyte3 = 255;
2283  }
2284  } else {
2285  bu_free(rows, "rows");
2286  bu_free(idata, "image data");
2287  fclose(fp);
2288 
2289  Tcl_AppendResult(dmop->interp, "png: not supported for this platform\n", (char *)NULL);
2290  return TCL_ERROR;
2291  }
2292  }
2293 
2294  png_init_io(png_p, fp);
2295  png_set_filter(png_p, 0, PNG_FILTER_NONE);
2296  png_set_compression_level(png_p, Z_BEST_COMPRESSION);
2297  png_set_IHDR(png_p, info_p, ximage_p->width, ximage_p->height, bits_per_channel,
2298  PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
2299  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
2300  png_set_gAMA(png_p, info_p, 0.77);
2301  png_write_info(png_p, info_p);
2302  png_write_image(png_p, rows);
2303  png_write_end(png_p, NULL);
2304 
2305  bu_free(rows, "rows");
2306  bu_free(idata, "image data");
2307  fclose(fp);
2308 
2309  return TCL_OK;
2310 }
2311 
2312 
2313 #endif /* defined(DM_X) || defined(DM_OGL) */
2314 
2315 
2316 /*
2317  * Write the pixels to a file in png format.
2318  *
2319  * Usage:
2320  * objname png args
2321  *
2322  */
2323 HIDDEN int
2324 #if defined(DM_X) || defined(DM_OGL)
2325 dmo_png_tcl(void *clientData, int argc, const char **argv)
2326 #else
2327 dmo_png_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
2328 #endif
2329 {
2330  struct dm_obj *dmop = (struct dm_obj *)clientData;
2331 
2332  if (!dmop || !dmop->interp)
2333  return TCL_ERROR;
2334 
2335 #if defined(DM_X) || defined(DM_OGL)
2336  return dmo_png_cmd(dmop, argc-1, argv+1);
2337 #else
2338  bu_log("Sorry, support for the 'png' command is unavailable.\n");
2339  return 0;
2340 #endif
2341 }
2342 
2343 
2344 /*
2345  * Get/set the clearBufferAfter flag.
2346  *
2347  * Usage:
2348  * objname clearBufferAfter [flag]
2349  *
2350  */
2351 HIDDEN int
2352 dmo_clearBufferAfter_tcl(void *clientData, int argc, const char **argv)
2353 {
2354  struct dm_obj *dmop = (struct dm_obj *)clientData;
2355  struct bu_vls vls = BU_VLS_INIT_ZERO;
2356  int clearBufferAfter;
2357  Tcl_Obj *obj;
2358 
2359  if (!dmop || !dmop->interp)
2360  return TCL_ERROR;
2361 
2362  obj = Tcl_GetObjResult(dmop->interp);
2363  if (Tcl_IsShared(obj))
2364  obj = Tcl_DuplicateObj(obj);
2365 
2366  /* get clearBufferAfter flag */
2367  if (argc == 2) {
2368  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_clearBufferAfter);
2369  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2370  bu_vls_free(&vls);
2371 
2372  Tcl_SetObjResult(dmop->interp, obj);
2373  return TCL_OK;
2374  }
2375 
2376  /* set clearBufferAfter flag */
2377  if (argc == 3) {
2378  if (sscanf(argv[2], "%d", &clearBufferAfter) != 1) {
2379  Tcl_AppendStringsToObj(obj, "dmo_clearBufferAfter: invalid clearBufferAfter value - ",
2380  argv[2], "\n", (char *)NULL);
2381  Tcl_SetObjResult(dmop->interp, obj);
2382  return TCL_ERROR;
2383  }
2384 
2385  dmop->dmo_dmp->dm_clearBufferAfter = clearBufferAfter;
2386  return TCL_OK;
2387  }
2388 
2389  bu_vls_printf(&vls, "helplib_alias dm_clearBufferAfter %s", argv[1]);
2390  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2391  bu_vls_free(&vls);
2392  return TCL_ERROR;
2393 }
2394 
2395 
2396 /*
2397  * Get/set the display manager's debug level.
2398  *
2399  * Usage:
2400  * objname debug [n]
2401  */
2402 HIDDEN int
2403 dmo_debug_tcl(void *clientData, int argc, const char **argv)
2404 {
2405  struct dm_obj *dmop = (struct dm_obj *)clientData;
2406  struct bu_vls vls = BU_VLS_INIT_ZERO;
2407  int level;
2408  Tcl_Obj *obj;
2409 
2410  if (!dmop || !dmop->interp)
2411  return TCL_ERROR;
2412 
2413  obj = Tcl_GetObjResult(dmop->interp);
2414  if (Tcl_IsShared(obj))
2415  obj = Tcl_DuplicateObj(obj);
2416 
2417  /* get debug level */
2418  if (argc == 2) {
2419  bu_vls_printf(&vls, "%d", dmop->dmo_dmp->dm_debugLevel);
2420  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2421  bu_vls_free(&vls);
2422 
2423  Tcl_SetObjResult(dmop->interp, obj);
2424  return TCL_OK;
2425  }
2426 
2427  /* set debug level */
2428  if (argc == 3) {
2429  if (sscanf(argv[2], "%d", &level) != 1) {
2430  Tcl_AppendStringsToObj(obj, "dmo_debug: invalid debug level - ",
2431  argv[2], "\n", (char *)NULL);
2432 
2433  Tcl_SetObjResult(dmop->interp, obj);
2434  return TCL_ERROR;
2435  }
2436 
2437  return dm_debug(dmop->dmo_dmp, level);
2438  }
2439 
2440  bu_vls_printf(&vls, "helplib_alias dm_debug %s", argv[1]);
2441  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2442  bu_vls_free(&vls);
2443  return TCL_ERROR;
2444 }
2445 
2446 /*
2447  * Get/set the display manager's log file.
2448  *
2449  * Usage:
2450  * objname logfile [filename]
2451  */
2452 HIDDEN int
2453 dmo_logfile_tcl(void *clientData, int argc, const char **argv)
2454 {
2455  struct dm_obj *dmop = (struct dm_obj *)clientData;
2456  struct bu_vls vls = BU_VLS_INIT_ZERO;
2457  Tcl_Obj *obj;
2458 
2459  if (!dmop || !dmop->interp)
2460  return TCL_ERROR;
2461 
2462  obj = Tcl_GetObjResult(dmop->interp);
2463  if (Tcl_IsShared(obj))
2464  obj = Tcl_DuplicateObj(obj);
2465 
2466  /* get log file */
2467  if (argc == 2) {
2468  bu_vls_printf(&vls, "%d", bu_vls_addr(&(dmop->dmo_dmp->dm_log)));
2469  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2470  bu_vls_free(&vls);
2471 
2472  Tcl_SetObjResult(dmop->interp, obj);
2473  return TCL_OK;
2474  }
2475 
2476  /* set log file */
2477  if (argc == 3) {
2478  return dm_logfile(dmop->dmo_dmp, argv[3]);
2479  }
2480 
2481  bu_vls_printf(&vls, "helplib_alias dm_debug %s", argv[1]);
2482  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2483  bu_vls_free(&vls);
2484  return TCL_ERROR;
2485 }
2486 
2487 
2488 
2489 /*
2490  * Flush the output buffer.
2491  *
2492  * Usage:
2493  * objname flush
2494  *
2495  */
2496 HIDDEN int
2497 #ifdef DM_X
2498 dmo_flush_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
2499 #else
2500 dmo_flush_tcl(void *UNUSED(clientData), int UNUSED(argc), const char **UNUSED(argv))
2501 #endif
2502 {
2503 #ifdef DM_X
2504  struct dm_obj *dmop = (struct dm_obj *)clientData;
2505 
2506  if (!dmop)
2507  return TCL_ERROR;
2508 
2509  XFlush(((struct dm_xvars *)dmop->dmo_dmp->dm_vars.pub_vars)->dpy);
2510 #endif
2511 
2512  return TCL_OK;
2513 }
2514 
2515 
2516 /*
2517  * Flush the output buffer and process all events.
2518  *
2519  * Usage:
2520  * objname sync
2521  *
2522  */
2523 HIDDEN int
2524 #ifdef DM_X
2525 dmo_sync_tcl(void *clientData, int UNUSED(argc), const char **UNUSED(argv))
2526 #else
2527 dmo_sync_tcl(void *UNUSED(clientData), int UNUSED(argc), const char **UNUSED(argv))
2528 #endif
2529 {
2530 #ifdef DM_X
2531  struct dm_obj *dmop = (struct dm_obj *)clientData;
2532 
2533  if (!dmop)
2534  return TCL_ERROR;
2535 
2536  XSync(((struct dm_xvars *)dmop->dmo_dmp->dm_vars.pub_vars)->dpy, 0);
2537 #endif
2538 
2539  return TCL_OK;
2540 }
2541 
2542 
2543 /*
2544  * Set/get window size.
2545  *
2546  * Usage:
2547  * objname size [width [height]]
2548  *
2549  */
2550 HIDDEN int
2551 dmo_size_tcl(void *clientData, int argc, const char **argv)
2552 {
2553  struct dm_obj *dmop = (struct dm_obj *)clientData;
2554  struct bu_vls vls = BU_VLS_INIT_ZERO;
2555  Tcl_Obj *obj;
2556 
2557  if (!dmop || !dmop->interp)
2558  return TCL_ERROR;
2559 
2560  obj = Tcl_GetObjResult(dmop->interp);
2561  if (Tcl_IsShared(obj))
2562  obj = Tcl_DuplicateObj(obj);
2563 
2564  if (argc == 2) {
2565  bu_vls_printf(&vls, "%d %d", dmop->dmo_dmp->dm_width, dmop->dmo_dmp->dm_height);
2566  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2567  bu_vls_free(&vls);
2568 
2569  Tcl_SetObjResult(dmop->interp, obj);
2570  return TCL_OK;
2571  }
2572 
2573  if (argc == 3 || argc == 4) {
2574  int width, height;
2575 
2576  if (sscanf(argv[2], "%d", &width) != 1) {
2577  Tcl_AppendStringsToObj(obj, "size: bad width - ", argv[2], "\n", (char *)NULL);
2578 
2579  Tcl_SetObjResult(dmop->interp, obj);
2580  return TCL_ERROR;
2581  }
2582 
2583  if (argc == 3)
2584  height = width;
2585  else {
2586  if (sscanf(argv[3], "%d", &height) != 1) {
2587  Tcl_AppendStringsToObj(obj, "size: bad height - ", argv[3], "\n", (char *)NULL);
2588  Tcl_SetObjResult(dmop->interp, obj);
2589  return TCL_ERROR;
2590  }
2591  }
2592 
2593 #if defined(DM_X) || defined(DM_OGL) || defined(DM_OGL) || defined(DM_WGL)
2594  Tk_GeometryRequest(((struct dm_xvars *)dmop->dmo_dmp->dm_vars.pub_vars)->xtkwin,
2595  width, height);
2596  return TCL_OK;
2597 #else
2598  bu_log("Sorry, support for 'size' command is unavailable.\n");
2599  return TCL_ERROR;
2600 #endif
2601  }
2602 
2603  bu_vls_printf(&vls, "helplib_alias dm_size %s", argv[1]);
2604  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2605  bu_vls_free(&vls);
2606  return TCL_ERROR;
2607 }
2608 
2609 
2610 /*
2611  * Get window aspect ratio (i.e. width / height)
2612  *
2613  * Usage:
2614  * objname get_aspect
2615  *
2616  */
2617 HIDDEN int
2618 dmo_get_aspect_tcl(void *clientData, int argc, const char **argv)
2619 {
2620  struct dm_obj *dmop = (struct dm_obj *)clientData;
2621  struct bu_vls vls = BU_VLS_INIT_ZERO;
2622  Tcl_Obj *obj;
2623 
2624  if (!dmop || !dmop->interp)
2625  return TCL_ERROR;
2626 
2627  if (argc != 2) {
2628  bu_vls_printf(&vls, "helplib_alias dm_getaspect %s", argv[1]);
2629  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2630  bu_vls_free(&vls);
2631  return TCL_ERROR;
2632  }
2633 
2634  obj = Tcl_GetObjResult(dmop->interp);
2635  if (Tcl_IsShared(obj))
2636  obj = Tcl_DuplicateObj(obj);
2637 
2638  bu_vls_printf(&vls, "%g", dmop->dmo_dmp->dm_aspect);
2639  Tcl_AppendStringsToObj(obj, bu_vls_addr(&vls), (char *)NULL);
2640  bu_vls_free(&vls);
2641 
2642  Tcl_SetObjResult(dmop->interp, obj);
2643  return TCL_OK;
2644 }
2645 
2646 
2647 /*
2648  * Attach/detach observers to/from list.
2649  *
2650  * Usage:
2651  * objname observer cmd [args]
2652  *
2653  */
2654 HIDDEN int
2655 dmo_observer_tcl(void *clientData, int argc, const char **argv)
2656 {
2657  struct dm_obj *dmop = (struct dm_obj *)clientData;
2658 
2659  if (!dmop || !dmop->interp)
2660  return TCL_ERROR;
2661 
2662  if (argc < 3) {
2663  struct bu_vls vls = BU_VLS_INIT_ZERO;
2664 
2665  /* return help message */
2666  bu_vls_printf(&vls, "helplib_alias dm_observer %s", argv[1]);
2667  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2668  bu_vls_free(&vls);
2669  return TCL_ERROR;
2670  }
2671 
2672  return bu_observer_cmd((ClientData)&dmop->dmo_observers, argc-2, (const char **)argv+2);
2673 }
2674 
2675 
2676 #ifdef USE_FBSERV
2677 HIDDEN void
2678 dmo_fbs_callback(void *clientData)
2679 {
2680  struct dm_obj *dmop = (struct dm_obj *)clientData;
2681 
2682  if (!dmop)
2683  return;
2684 
2686 }
2687 #endif
2688 
2689 
2690 HIDDEN int
2691 dmo_getDrawLabelsHook_cmd(struct dm_obj *dmop, int argc, const char **argv)
2692 {
2693  char buf[64];
2694  Tcl_DString ds;
2695 
2696  if (!dmop || !dmop->interp)
2697  return TCL_ERROR;
2698 
2699  if (argc != 1) {
2700  struct bu_vls vls = BU_VLS_INIT_ZERO;
2701 
2702  bu_vls_printf(&vls, "helplib_alias dm_getDrawLabelsHook %s", argv[0]);
2703  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2704  bu_vls_free(&vls);
2705  return TCL_ERROR;
2706  }
2707 
2708  /* FIXME: the standard forbids this kind of crap. candidate for removal. */
2709  sprintf(buf, "%p %p",
2710  (void *)(uintptr_t)dmop->dmo_drawLabelsHook,
2711  (void *)(uintptr_t)dmop->dmo_drawLabelsHookClientData);
2712  Tcl_DStringInit(&ds);
2713  Tcl_DStringAppend(&ds, buf, -1);
2714  Tcl_DStringResult(dmop->interp, &ds);
2715 
2716  return TCL_OK;
2717 }
2718 
2719 
2720 HIDDEN int
2721 dmo_getDrawLabelsHook_tcl(void *clientData, int argc, const char **argv)
2722 {
2723  struct dm_obj *dmop = (struct dm_obj *)clientData;
2724 
2725  return dmo_getDrawLabelsHook_cmd(dmop, argc-1, argv+1);
2726 }
2727 
2728 
2729 HIDDEN int
2730 dmo_setDrawLabelsHook_cmd(struct dm_obj *dmop, int argc, const char **argv)
2731 {
2732  int (*hook)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData);
2733  void *clientData;
2734 
2735  if (!dmop || !dmop->interp)
2736  return TCL_ERROR;
2737 
2738  if (argc != 3) {
2739  struct bu_vls vls = BU_VLS_INIT_ZERO;
2740 
2741  bu_vls_printf(&vls, "helplib_alias dm_setDrawLabelsHook %s", argv[0]);
2742  Tcl_Eval(dmop->interp, bu_vls_addr(&vls));
2743  bu_vls_free(&vls);
2744  return TCL_ERROR;
2745  }
2746 
2747  if (sscanf(argv[1], "%p", (void **)((unsigned char *)&hook)) != 1) {
2748  Tcl_DString ds;
2749 
2750  Tcl_DStringInit(&ds);
2751  Tcl_DStringAppend(&ds, argv[0], -1);
2752  Tcl_DStringAppend(&ds, ": failed to set the drawLabels hook", -1);
2753  Tcl_DStringResult(dmop->interp, &ds);
2754 
2755  dmop->dmo_drawLabelsHook = (int (*)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData))0;
2756 
2757  return TCL_ERROR;
2758  }
2759 
2760  if (sscanf(argv[2], "%p", &clientData) != 1) {
2761  Tcl_DString ds;
2762 
2763  Tcl_DStringInit(&ds);
2764  Tcl_DStringAppend(&ds, argv[0], -1);
2765  Tcl_DStringAppend(&ds, ": failed to set the drawLabels hook", -1);
2766  Tcl_DStringResult(dmop->interp, &ds);
2767 
2768  dmop->dmo_drawLabelsHook = (int (*)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData))0;
2769 
2770  return TCL_ERROR;
2771  }
2772 
2773  /* FIXME: standard prohibits casting between function pointers and
2774  * void *. find a better way.
2775  */
2776  dmop->dmo_drawLabelsHook = hook;
2777  dmop->dmo_drawLabelsHookClientData = clientData;
2778 
2779  return TCL_OK;
2780 }
2781 
2782 
2783 HIDDEN int
2784 dmo_setDrawLabelsHook_tcl(void *clientData, int argc, const char **argv)
2785 {
2786  struct dm_obj *dmop = (struct dm_obj *)clientData;
2787 
2788  return dmo_setDrawLabelsHook_cmd(dmop, argc-1, argv+1);
2789 }
2790 
2791 
2792 /*
2793  * Called by Tcl when the object is destroyed.
2794  */
2795 HIDDEN void
2796 dmo_deleteProc(ClientData clientData)
2797 {
2798  struct dm_obj *dmop = (struct dm_obj *)clientData;
2799 
2800  /* free observers */
2802 
2803 #ifdef USE_FBSERV
2804  /* close framebuffer */
2805  dmo_closeFb(dmop);
2806 #endif
2807 
2808  bu_vls_free(&dmop->dmo_name);
2809  (void)dm_close(dmop->dmo_dmp);
2810  BU_LIST_DEQUEUE(&dmop->l);
2811  bu_free((void *)dmop, "dmo_deleteProc: dmop");
2812 
2813 }
2814 
2815 
2816 /*
2817  * Generic interface for display manager object routines.
2818  * Usage:
2819  * objname cmd ?args?
2820  *
2821  * Returns: result of DM command.
2822  */
2823 HIDDEN int
2824 dmo_cmd(ClientData clientData, Tcl_Interp *UNUSED(interp), int argc, const char **argv)
2825 {
2826  int ret;
2827 
2828  static struct bu_cmdtab dmo_cmds[] = {
2829  {"bg", dmo_bg_tcl},
2830  {"bounds", dmo_bounds_tcl},
2831  {"clear", dmo_clear_tcl},
2832  {"configure", dmo_configure_tcl},
2833  {"debug", dmo_debug_tcl},
2834  {"depthMask", dmo_depthMask_tcl},
2835  {"drawBegin", dmo_drawBegin_tcl},
2836  {"drawEnd", dmo_drawEnd_tcl},
2837  {"drawGeom", BU_CMD_NULL},
2838  {"drawLabels", BU_CMD_NULL},
2839  {"drawLine", dmo_drawLine_tcl},
2840  {"drawPoint", dmo_drawPoint_tcl},
2841  {"drawScale", dmo_drawScale_tcl},
2842  {"drawSList", dmo_drawSList_tcl},
2843  {"drawString", dmo_drawString_tcl},
2844  {"drawVList", dmo_drawVList_tcl},
2845  {"drawDataAxes", dmo_drawDataAxes_tcl},
2846  {"drawModelAxes", dmo_drawModelAxes_tcl},
2847  {"drawViewAxes", dmo_drawViewAxes_tcl},
2848  {"drawCenterDot", dmo_drawCenterDot_tcl},
2849  {"fg", dmo_fg_tcl},
2850  {"flush", dmo_flush_tcl},
2851  {"get_aspect", dmo_get_aspect_tcl},
2852  {"getDrawLabelsHook", dmo_getDrawLabelsHook_tcl},
2853  {"light", dmo_light_tcl},
2854  {"linestyle", dmo_lineStyle_tcl},
2855  {"linewidth", dmo_lineWidth_tcl},
2856 #ifdef USE_FBSERV
2857  {"listen", dmo_listen_tcl},
2858 #endif
2859  {"loadmat", dmo_loadmat_tcl},
2860  {"logfile", dmo_logfile_tcl},
2861  {"normal", dmo_normal_tcl},
2862  {"observer", dmo_observer_tcl},
2863  {"perspective", dmo_perspective_tcl},
2864  {"png", dmo_png_tcl},
2865 #ifdef USE_FBSERV
2866  {"refreshfb", dmo_refreshFb_tcl},
2867 #endif
2868  {"clearBufferAfter", dmo_clearBufferAfter_tcl},
2869  {"setDrawLabelsHook", dmo_setDrawLabelsHook_tcl},
2870  {"size", dmo_size_tcl},
2871  {"sync", dmo_sync_tcl},
2872  {"transparency", dmo_transparency_tcl},
2873  {"zbuffer", dmo_zbuffer_tcl},
2874  {"zclip", dmo_zclip_tcl},
2875  {(const char *)NULL, BU_CMD_NULL}
2876  };
2877 
2878  if (bu_cmd(dmo_cmds, argc, argv, 1, clientData, &ret) == BRLCAD_OK)
2879  return ret;
2880 
2881  bu_log("ERROR: '%s' command not found\n", argv[1]);
2882  return BRLCAD_ERROR;
2883 }
2884 
2885 
2886 /*
2887  * Open/create a display manager object.
2888  *
2889  * Usage:
2890  * dm_open [name type [args]]
2891  */
2892 HIDDEN int
2893 dmo_open_tcl(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv)
2894 {
2895  struct dm_obj *dmop;
2896  dm *dmp;
2897  struct bu_vls vls = BU_VLS_INIT_ZERO;
2898  int name_index = 1;
2899  int type = DM_TYPE_BAD;
2900  Tcl_Obj *obj;
2901 
2902  obj = Tcl_GetObjResult(interp);
2903  if (Tcl_IsShared(obj))
2904  obj = Tcl_DuplicateObj(obj);
2905 
2906  if (argc == 1) {
2907  /* get list of display manager objects */
2908  for (BU_LIST_FOR(dmop, dm_obj, &HeadDMObj.l))
2909  Tcl_AppendStringsToObj(obj, bu_vls_addr(&dmop->dmo_name), " ", (char *)NULL);
2910 
2911  Tcl_SetObjResult(interp, obj);
2912  return TCL_OK;
2913  }
2914 
2915  if (argc < 3) {
2916  bu_vls_printf(&vls, "helplib_alias dm_open %s", argv[1]);
2917  Tcl_Eval(interp, bu_vls_addr(&vls));
2918  bu_vls_free(&vls);
2919  return TCL_ERROR;
2920  }
2921 
2922  /* check to see if display manager object exists */
2923  for (BU_LIST_FOR(dmop, dm_obj, &HeadDMObj.l)) {
2924  if (BU_STR_EQUAL(argv[name_index], bu_vls_addr(&dmop->dmo_name))) {
2925  Tcl_AppendStringsToObj(obj, "dmo_open: ", argv[name_index],
2926  " exists.", (char *)NULL);
2927  Tcl_SetObjResult(interp, obj);
2928  return TCL_ERROR;
2929  }
2930  }
2931 
2932  /* find display manager type */
2933 #ifdef DM_X
2934  if (argv[2][0] == 'X' || argv[2][0] == 'x')
2935  type = DM_TYPE_X;
2936 #endif /* DM_X */
2937 
2938 #ifdef DM_TK
2939  if (BU_STR_EQUAL(argv[2], "tk"))
2940  type = DM_TYPE_TK;
2941 #endif /* DM_TK */
2942 
2943 #ifdef DM_OGL
2944  if (BU_STR_EQUAL(argv[2], "ogl"))
2945  type = DM_TYPE_OGL;
2946 #endif /* DM_OGL */
2947 
2948 #ifdef DM_WGL
2949  if (BU_STR_EQUAL(argv[2], "wgl"))
2950  type = DM_TYPE_WGL;
2951 #endif /* DM_WGL */
2952 
2953  if (type == DM_TYPE_BAD) {
2954  Tcl_AppendStringsToObj(obj,
2955  "Unsupported display manager type - ",
2956  argv[2], "\n",
2957  "The supported types are: X, ogl, wgl, and nu",
2958  (char *)NULL);
2959  Tcl_SetObjResult(interp, obj);
2960  return TCL_ERROR;
2961  }
2962 
2963  {
2964  int i;
2965  int arg_start = 3;
2966  int newargs = 2;
2967  int ac;
2968  const char **av;
2969 
2970  ac = argc + newargs;
2971  av = (const char **)bu_malloc(sizeof(char *) * (ac+1), "dmo_open_tcl: av");
2972  av[0] = argv[0];
2973 
2974  /* Insert new args (i.e. arrange to call init_dm_obj from dm_open()) */
2975  av[1] = "-i";
2976  av[2] = "init_dm_obj";
2977 
2978  /*
2979  * Stuff name into argument list.
2980  */
2981  av[3] = "-n";
2982  av[4] = argv[name_index];
2983 
2984  /* copy the rest */
2985  for (i = arg_start; i < argc; ++i)
2986  av[i+newargs] = argv[i];
2987  av[i+newargs] = (const char *)NULL;
2988 
2989  if ((dmp = dm_open(interp, type, ac, av)) == DM_NULL) {
2990  if (Tcl_IsShared(obj))
2991  obj = Tcl_DuplicateObj(obj);
2992 
2993  Tcl_AppendStringsToObj(obj,
2994  "dmo_open_tcl: Failed to open - ",
2995  argv[name_index],
2996  "\n",
2997  (char *)NULL);
2998  bu_free((void *)av, "dmo_open_tcl: av");
2999 
3000  Tcl_SetObjResult(interp, obj);
3001  return TCL_ERROR;
3002  }
3003 
3004  bu_free((void *)av, "dmo_open_tcl: av");
3005  }
3006 
3007  /* acquire dm_obj struct */
3008  BU_ALLOC(dmop, struct dm_obj);
3009 
3010  /* initialize dm_obj */
3011  bu_vls_init(&dmop->dmo_name);
3012  bu_vls_strcpy(&dmop->dmo_name, argv[name_index]);
3013  dmop->dmo_dmp = dmp;
3014  VSETALL(dmop->dmo_dmp->dm_clipmin, -2048.0);
3015  VSETALL(dmop->dmo_dmp->dm_clipmax, 2047.0);
3016  dmop->dmo_drawLabelsHook = (int (*)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData))0;
3017 
3018 #ifdef USE_FBSERV
3019  dmop->dmo_fbs.fbs_listener.fbsl_fbsp = &dmop->dmo_fbs;
3020  dmop->dmo_fbs.fbs_listener.fbsl_fd = -1;
3021  dmop->dmo_fbs.fbs_listener.fbsl_port = -1;
3022  dmop->dmo_fbs.fbs_fbp = FB_NULL;
3023  dmop->dmo_fbs.fbs_callback = dmo_fbs_callback;
3024  dmop->dmo_fbs.fbs_clientData = dmop;
3025  dmop->dmo_fbs.fbs_interp = interp;
3026 #endif
3027  dmop->interp = interp;
3028 
3029  BU_LIST_INIT(&dmop->dmo_observers.l);
3030 
3031  /* append to list of dm_obj's */
3032  BU_LIST_APPEND(&HeadDMObj.l, &dmop->l);
3033 
3034  (void)Tcl_CreateCommand(interp,
3035  bu_vls_addr(&dmop->dmo_name),
3036  (Tcl_CmdProc *)dmo_cmd,
3037  (ClientData)dmop,
3038  dmo_deleteProc);
3039 
3040  /* send Configure event */
3041  bu_vls_printf(&vls, "event generate %s <Configure>; update", bu_vls_addr(&dmop->dmo_name));
3042  Tcl_Eval(interp, bu_vls_addr(&vls));
3043  bu_vls_free(&vls);
3044 
3045 #ifdef USE_FBSERV
3046  /* open the framebuffer */
3047  dmo_openFb(dmop);
3048 #endif
3049 
3050  /* Return new function name as result */
3051  Tcl_SetResult(interp, bu_vls_addr(&dmop->dmo_name), TCL_VOLATILE);
3052  return TCL_OK;
3053 }
3054 
3055 
3056 int
3057 Dmo_Init(Tcl_Interp *interp)
3058 {
3059  BU_LIST_INIT(&HeadDMObj.l);
3060  BU_VLS_INIT(&HeadDMObj.dmo_name);
3061  (void)Tcl_CreateCommand(interp, "dm_open", (Tcl_CmdProc *)dmo_open_tcl, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
3062 
3063  return TCL_OK;
3064 }
3065 
3066 
3067 /*
3068  * Local Variables:
3069  * mode: C
3070  * tab-width: 8
3071  * indent-tabs-mode: t
3072  * c-file-style: "stroustrup"
3073  * End:
3074  * ex: shiftwidth=4 tabstop=8
3075  */
Definition: cmd.h:48
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
int dm_loadmatrix(dm *dmp, fastf_t *mat, int eye)
Definition: dm-generic.c:723
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
#define GED_MAX
Definition: ged.h:253
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
char * UP
int dm_set_light(dm *dmp, int light)
Definition: dm-generic.c:540
int dm_width
Definition: dm_private.h:91
fastf_t axes_size
Definition: bview.h:81
HIDDEN int dmo_lineWidth_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1499
int bu_observer_cmd(void *clientData, int argc, const char *argv[])
Definition: list.h:118
void * pub_vars
Definition: dm_private.h:35
ustring interp
int ticks_per_major
Definition: bview.h:91
int dm_zclip
!0 means zclipping
Definition: dm_private.h:116
HIDDEN int dmo_drawEnd_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:918
HIDDEN int dmo_flush_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2500
HIDDEN int dmo_png_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2327
HIDDEN int dmo_bg_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1434
int tick_threshold
Definition: bview.h:92
HIDDEN void dmo_drawSolid(struct dm_obj *dmop, struct solid *sp)
Definition: dm_obj.c:1160
int dm_normal(dm *dmp)
Definition: dm-generic.c:717
fastf_t tick_interval
Definition: bview.h:90
#define VSETALL(a, s)
Definition: color.c:54
#define DM_TYPE_WGL
Definition: dm.h:99
HIDDEN int dmo_logfile_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2453
vect_t dm_clipmax
maximum clipping vector
Definition: dm_private.h:108
int fb_close_existing(fb *ifp)
Definition: fb_generic.c:498
HIDDEN int dmo_drawModelAxes_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:821
HIDDEN int dmo_bounds_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1917
unsigned char dm_fg[3]
foreground color
Definition: dm_private.h:106
HIDDEN int dmo_drawVList_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1124
#define DM_TYPE_BAD
Definition: dm.h:91
int tick_length
Definition: bview.h:88
HIDDEN int dmo_get_aspect_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2618
int dm_draw_string_2d(dm *dmp, const char *str, fastf_t x, fastf_t y, int size, int use_aspect)
Definition: dm-generic.c:735
bu_endian_t bu_byteorder(void)
Definition: endian.c:27
int axes_color[3]
Definition: bview.h:84
int dm_logfile(dm *dmp, const char *filename)
Definition: dm-generic.c:802
Header file for the BRL-CAD common definitions.
struct bu_list l
Definition: dm_obj.c:83
int fbs_close(struct fbserv_obj *fbsp)
Definition: fbserv_obj.c:1073
#define BU_CMD_NULL
Definition: cmd.h:37
HIDDEN int dmo_setDrawLabelsHook_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2784
int line_width
Definition: bview.h:82
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
HIDDEN int dmo_zbuffer_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1710
HIDDEN int dmo_transparency_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1813
struct bu_list l
Definition: bu_tcl.h:48
int dm_light
!0 means lighting on
Definition: dm_private.h:112
ustring width
fastf_t dm_aspect
Definition: dm_private.h:97
#define HIDDEN
Definition: common.h:86
void dm_draw_axes(dm *dmp, fastf_t viewSize, const mat_t rmat, struct bview_axes_state *bnasp)
Definition: axes.c:121
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
int dm_configure_win(dm *dmp, int force)
Definition: dm-generic.c:497
int dm_clearBufferAfter
1 means clear back buffer after drawing and swap
Definition: dm_private.h:117
int tick_major_length
Definition: bview.h:89
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define DM_TYPE_TK
Definition: dm.h:100
Definition: color.c:49
#define DM_NULL
Definition: dm.h:43
void * memset(void *s, int c, size_t n)
HIDDEN int dmo_zclip_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1659
HIDDEN int dmo_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
Definition: dm_obj.c:2893
int label_color[3]
Definition: bview.h:85
HIDDEN int dmo_getDrawLabelsHook_cmd(struct dm_obj *dmop, int argc, const char **argv)
Definition: dm_obj.c:2691
HIDDEN void dmo_deleteProc(ClientData clientData)
Definition: dm_obj.c:2796
#define FB_NULL
Definition: fb.h:95
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
int dm_perspective
!0 means perspective on
Definition: dm_private.h:111
int tick_major_color[3]
Definition: bview.h:94
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
point_t * points
Definition: bview.h:103
struct bu_vls dm_log
!NULL && !empty means log debug output to the file
Definition: dm_private.h:110
#define DM_TYPE_X
Definition: dm.h:95
HIDDEN int dmo_parseAxesArgs(int argc, const char **argv, fastf_t *viewSize, mat_t rmat, point_t axesPos, fastf_t *axesSize, int *axesColor, int *labelColor, int *lineWidth, int *posOnly, int *tripleColor, struct bu_vls *vlsp)
Definition: dm_obj.c:267
int dm_draw_end(dm *dmp)
Definition: dm-generic.c:711
HIDDEN int dmo_loadmat_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:979
HIDDEN int dmo_cmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
Definition: dm_obj.c:2824
#define BRLCAD_OK
Definition: defines.h:71
int dm_draw_begin(dm *dmp)
Definition: dm-generic.c:705
int dm_set_fg(dm *dmp, unsigned char r, unsigned char g, unsigned char b, int strict, fastf_t transparency)
Definition: dm-generic.c:441
HIDDEN int dmo_parseModelAxesArgs(int argc, const char **argv, fastf_t *viewSize, mat_t rmat, point_t axesPos, fastf_t *axesSize, int *axesColor, int *labelColor, int *lineWidth, int *posOnly, int *tripleColor, mat_t model2view, int *tickEnable, int *tickLength, int *majorTickLength, fastf_t *tickInterval, int *ticksPerMajor, int *tickColor, int *majorTickColor, int *tickThreshold, struct bu_vls *vlsp)
Definition: dm_obj.c:662
int dm_draw_point_2d(dm *dmp, fastf_t x, fastf_t y)
Definition: dm-generic.c:760
HIDDEN int dmo_drawCenterDot_cmd(struct dm_obj *dmop, int argc, const char **argv)
Definition: dm_obj.c:448
HIDDEN int dmo_light_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1761
HIDDEN int dmo_getDrawLabelsHook_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2721
#define UNUSED(parameter)
Definition: common.h:239
int bn_decode_vect(vect_t v, const char *str)
HIDDEN int dmo_sync_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2527
fb * dm_get_fb(dm *dmp)
Definition: dm-generic.c:305
int dm_set_depth_mask(dm *dmp, int d_on)
Definition: dm-generic.c:790
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
HIDDEN int dmo_drawScale_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1243
int fb_configure_window(fb *, int, int)
Definition: fb_generic.c:162
int dm_lineWidth
Definition: dm_private.h:95
int dm_debug(dm *dmp, int lvl)
Definition: dm-generic.c:796
point_t axes_pos
Definition: bview.h:80
struct bu_vls dmo_name
display manager object name/cmd
Definition: dm_obj.c:84
int triple_color
Definition: bview.h:86
HIDDEN int dmo_observer_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2655
int tick_color[3]
Definition: bview.h:93
HIDDEN int dmo_drawSList(struct dm_obj *dmop, struct bu_list *hsp)
Definition: dm_obj.c:1259
int tick_enabled
Definition: bview.h:87
int(* dmo_drawLabelsHook)(dm *, struct rt_wdb *, const char *, mat_t, int *, ClientData)
Definition: dm_obj.c:91
HIDDEN int dmo_drawBegin_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:906
int bn_decode_mat(mat_t m, const char *str)
Support routines for the math functions.
HIDDEN int dmo_lineStyle_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1559
HIDDEN int dmo_clearBufferAfter_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2352
HIDDEN int dmo_clear_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:937
#define ZERO(val)
Definition: units.c:38
#define BU_LIST_INIT(_hp)
Definition: list.h:148
#define BN_CK_VLIST(_p)
Definition: vlist.h:78
void dm_draw_scale(dm *dmp, fastf_t viewSize, int *lineColor, int *textColor)
Definition: scale.c:39
dm * dm_open(Tcl_Interp *interp, int type, int argc, const char *argv[])
Definition: dm-generic.c:107
vect_t dm_clipmin
minimum clipping vector
Definition: dm_private.h:107
HIDDEN int dmo_drawLine_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1090
Definition: vlist.h:71
HIDDEN int dmo_fg_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1365
struct bu_observer dmo_observers
fbserv observers
Definition: dm_obj.c:89
struct dm_vars dm_vars
display manager dependent variables
Definition: dm_private.h:99
int fb_flush(fb *ifp)
int dm_height
Definition: dm_private.h:92
int dm_zbuffer
!0 means zbuffer on
Definition: dm_private.h:115
int dm_set_bg(dm *dmp, unsigned char r, unsigned char g, unsigned char b)
Definition: dm-generic.c:427
int fbs_open(struct fbserv_obj *fbsp, int port)
Definition: fbserv_obj.c:983
HIDDEN int dmo_drawSList_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1322
void bu_observer_free(struct bu_observer *)
Definition: observer.c:162
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
HIDDEN int dmo_drawString_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1027
int pos_only
Definition: bview.h:83
double dm_bound
zoom-in limit
Definition: dm_private.h:85
A display manager object is used for interacting with a display manager.
Definition: dm_obj.c:82
unsigned char dm_bg[3]
background color
Definition: dm_private.h:105
Definition: color.c:51
void * dmo_drawLabelsHookClientData
Definition: dm_obj.c:92
int dm_set_line_attr(dm *dmp, int width, int style)
Definition: dm-generic.c:617
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
dm * dmo_dmp
display manager pointer
Definition: dm_obj.c:85
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
HIDDEN int dmo_configure_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1620
HIDDEN int dmo_drawCenterDot_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:511
int dm_transparency
!0 means transparency on
Definition: dm_private.h:113
HIDDEN int dmo_normal_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:960
int Dmo_Init(Tcl_Interp *interp)
Definition: dm_obj.c:3057
int dmo_drawScale_cmd(struct dm_obj *dmop, int argc, const char **argv)
Definition: dm_obj.c:1182
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define DM_REVERSE_COLOR_BYTE_ORDER(_shift, _mask)
Definition: dm.h:191
mat_t viewMat
Definition: dm_obj.c:90
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
HIDDEN int dmo_drawViewAxes_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:389
HIDDEN int dmo_perspective_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1995
HIDDEN int dmo_drawDataAxes_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:607
Tcl_Interp * interp
Definition: dm_obj.c:93
int dm_draw_line_2d(dm *dmp, fastf_t x1, fastf_t y1_2d, fastf_t x2, fastf_t y2)
Definition: dm-generic.c:741
int dm_debugLevel
!0 means debugging
Definition: dm_private.h:109
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
HIDDEN int dmo_size_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2551
double fastf_t
Definition: defines.h:300
int dm_draw_vlist(dm *dmp, struct bn_vlist *vp)
Definition: dm-generic.c:692
void dm_draw_data_axes(dm *dmp, fastf_t viewSize, struct bview_data_axes_state *bndasp)
Definition: axes.c:46
HIDDEN int dmo_parseDataAxesArgs(int argc, const char **argv, fastf_t *viewSize, mat_t rmat, mat_t model2view, point_t axesPos, fastf_t *axesSize, int *axesColor, int *lineWidth, struct bu_vls *vlsp)
Definition: dm_obj.c:523
HIDDEN int dmo_debug_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:2403
int dm_lineStyle
Definition: dm_private.h:96
int dm_close(dm *dmp)
Definition: dm-generic.c:413
HIDDEN int dmo_depthMask_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1865
int dm_set_zbuffer(dm *dmp, int zbuffer)
Definition: dm-generic.c:582
Definition: color.c:50
HIDDEN int dmo_setDrawLabelsHook_cmd(struct dm_obj *dmop, int argc, const char **argv)
Definition: dm_obj.c:2730
int dm_depthMask
!0 means depth buffer is writable
Definition: dm_private.h:114
HIDDEN int dmo_drawPoint_tcl(void *clientData, int argc, const char **argv)
Definition: dm_obj.c:1057
int dm_set_transparency(dm *dmp, int transparency)
Definition: dm-generic.c:568
#define DM_TYPE_OGL
Definition: dm.h:96
int bu_cmd(const struct bu_cmdtab *cmds, int argc, const char *argv[], int cmd_index, void *data, int *result)
void bu_observer_notify(Tcl_Interp *interp, struct bu_observer *headp, char *self)
Definition: observer.c:140
#define BU_VLS_INIT(_vp)
Definition: vls.h:74
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126