BRL-CAD
if_stack.c
Go to the documentation of this file.
1 /* I F _ S T A C K . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup if */
21 /** @{ */
22 /** @file if_stack.c
23  *
24  * Allows multiple frame buffers to be ganged together.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "bu/log.h"
36 #include "bu/str.h"
37 #include "fb_private.h"
38 #include "fb.h"
39 
40 
41 /* List of interface struct pointers, one per dev */
42 #define MAXIF 32
43 struct stkinfo {
45 };
46 #define SI(ptr) ((struct stkinfo *)((ptr)->u1.p))
47 #define SIL(ptr) ((ptr)->u1.p) /* left hand side version */
48 
49 HIDDEN int
50 stk_open(fb *ifp, const char *file, int width, int height)
51 {
52  int i;
53  const char *cp;
54  char devbuf[80];
55 
56  FB_CK_FB(ifp);
57 
58  /* Check for /dev/stack */
59  if (bu_strncmp(file, ifp->if_name, strlen("/dev/stack")) != 0) {
60  fb_log("stack_dopen: Bad device %s\n", file);
61  return -1;
62  }
63 
64  if ((SIL(ifp) = (char *)calloc(1, sizeof(struct stkinfo))) == NULL) {
65  fb_log("stack_dopen: stkinfo malloc failed\n");
66  return -1;
67  }
68 
69  cp = &file[strlen("/dev/stack")];
70  while (*cp != '\0' && *cp != ' ' && *cp != '\t')
71  cp++; /* skip suffix */
72 
73  /* special check for a possibly user confusing case */
74  if (*cp == '\0') {
75  fb_log("stack_dopen: No devices specified\n");
76  fb_log("Usage: /dev/stack device_one; device_two; ...\n");
77  return -1;
78  }
79 
80  ifp->if_width = ifp->if_max_width;
81  ifp->if_height = ifp->if_max_height;
82  i = 0;
83  while (i < MAXIF && *cp != '\0') {
84  register char *dp;
85  register fb *fbp;
86 
87  while (*cp != '\0' && (*cp == ' ' || *cp == '\t' || *cp == ';'))
88  cp++; /* skip blanks and separators */
89  if (*cp == '\0')
90  break;
91  dp = devbuf;
92  while (*cp != '\0' && *cp != ';')
93  *dp++ = *cp++;
94  *dp = '\0';
95  if ((fbp = fb_open(devbuf, width, height)) != FB_NULL) {
96  FB_CK_FB(fbp);
97  /* Track the minimum of all the actual sizes */
98  if (fbp->if_width < ifp->if_width)
99  ifp->if_width = fbp->if_width;
100  if (fbp->if_height < ifp->if_height)
101  ifp->if_height = fbp->if_height;
102  if (fbp->if_max_width < ifp->if_max_width)
103  ifp->if_max_width = fbp->if_max_width;
104  if (fbp->if_max_height < ifp->if_max_height)
105  ifp->if_max_height = fbp->if_max_height;
106  SI(ifp)->if_list[i++] = fbp;
107  }
108  }
109  if (i > 0)
110  return 0;
111  else
112  return -1;
113 }
114 
117 {
118  return NULL;
119 }
120 
121 
122 HIDDEN void
124 {
125  return;
126 }
127 
128 HIDDEN int
129 stk_open_existing(fb *UNUSED(ifp), int UNUSED(width), int UNUSED(height), struct fb_platform_specific *UNUSED(fb_p))
130 {
131  return 0;
132 }
133 
134 
135 HIDDEN int
137 {
138  return 0;
139 }
140 
141 HIDDEN int
142 stk_configure_window(fb *UNUSED(ifp), int UNUSED(width), int UNUSED(height))
143 {
144  return 0;
145 }
146 
147 HIDDEN int
148 stk_refresh(fb *UNUSED(ifp), int UNUSED(x), int UNUSED(y), int UNUSED(w), int UNUSED(h))
149 {
150  return 0;
151 }
152 
153 
154 HIDDEN int
156 {
157  register fb **ip = SI(ifp)->if_list;
158 
159  FB_CK_FB(ifp);
160  while (*ip != (fb *)NULL) {
161  FB_CK_FB((*ip));
162  fb_close((*ip));
163  ip++;
164  }
165 
166  return 0;
167 }
168 
169 
170 HIDDEN int
171 stk_clear(fb *ifp, unsigned char *pp)
172 {
173  register fb **ip = SI(ifp)->if_list;
174 
175  while (*ip != (fb *)NULL) {
176  fb_clear((*ip), pp);
177  ip++;
178  }
179 
180  return 0;
181 }
182 
183 
185 stk_read(fb *ifp, int x, int y, unsigned char *pixelp, size_t count)
186 {
187  register fb **ip = SI(ifp)->if_list;
188 
189  if (*ip != (fb *)NULL) {
190  fb_read((*ip), x, y, pixelp, count);
191  }
192 
193  return count;
194 }
195 
196 
198 stk_write(fb *ifp, int x, int y, const unsigned char *pixelp, size_t count)
199 {
200  register fb **ip = SI(ifp)->if_list;
201 
202  while (*ip != (fb *)NULL) {
203  fb_write((*ip), x, y, pixelp, count);
204  ip++;
205  }
206 
207  return count;
208 }
209 
210 
211 /*
212  * Read only from the first source on the stack.
213  */
214 HIDDEN int
215 stk_readrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
216 {
217  register fb **ip = SI(ifp)->if_list;
218 
219  if (*ip != (fb *)NULL) {
220  (void)fb_readrect((*ip), xmin, ymin, width, height, pp);
221  }
222 
223  return width*height;
224 }
225 
226 
227 /*
228  * Write to all destinations on the stack
229  */
230 HIDDEN int
231 stk_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
232 {
233  register fb **ip = SI(ifp)->if_list;
234 
235  while (*ip != (fb *)NULL) {
236  (void)fb_writerect((*ip), xmin, ymin, width, height, pp);
237  ip++;
238  }
239 
240  return width*height;
241 }
242 
243 
244 /*
245  * Read only from the first source on the stack.
246  */
247 HIDDEN int
248 stk_bwreadrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
249 {
250  register fb **ip = SI(ifp)->if_list;
251 
252  if (*ip != (fb *)NULL) {
253  (void)fb_bwreadrect((*ip), xmin, ymin, width, height, pp);
254  }
255 
256  return width*height;
257 }
258 
259 
260 /*
261  * Write to all destinations on the stack
262  */
263 HIDDEN int
264 stk_bwwriterect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
265 {
266  register fb **ip = SI(ifp)->if_list;
267 
268  while (*ip != (fb *)NULL) {
269  (void)fb_bwwriterect((*ip), xmin, ymin, width, height, pp);
270  ip++;
271  }
272 
273  return width*height;
274 }
275 
276 
277 HIDDEN int
278 stk_rmap(fb *ifp, ColorMap *cmp)
279 {
280  register fb **ip = SI(ifp)->if_list;
281 
282  if (*ip != (fb *)NULL) {
283  fb_rmap((*ip), cmp);
284  }
285 
286  return 0;
287 }
288 
289 
290 HIDDEN int
291 stk_wmap(fb *ifp, const ColorMap *cmp)
292 {
293  register fb **ip = SI(ifp)->if_list;
294 
295  while (*ip != (fb *)NULL) {
296  fb_wmap((*ip), cmp);
297  ip++;
298  }
299 
300  return 0;
301 }
302 
303 
304 HIDDEN int
305 stk_view(fb *ifp, int xcenter, int ycenter, int xzoom, int yzoom)
306 {
307  register fb **ip = SI(ifp)->if_list;
308 
309  while (*ip != (fb *)NULL) {
310  fb_view((*ip), xcenter, ycenter, xzoom, yzoom);
311  ip++;
312  }
313 
314  return 0;
315 }
316 
317 
318 HIDDEN int
319 stk_getview(fb *ifp, int *xcenter, int *ycenter, int *xzoom, int *yzoom)
320 {
321  register fb **ip = SI(ifp)->if_list;
322 
323  if (*ip != (fb *)NULL) {
324  fb_getview((*ip), xcenter, ycenter, xzoom, yzoom);
325  }
326 
327  return 0;
328 }
329 
330 
331 HIDDEN int
332 stk_setcursor(fb *ifp, const unsigned char *bits, int xbits, int ybits, int xorig, int yorig)
333 {
334  register fb **ip = SI(ifp)->if_list;
335 
336  while (*ip != (fb *)NULL) {
337  fb_setcursor((*ip), bits, xbits, ybits, xorig, yorig);
338  ip++;
339  }
340 
341  return 0;
342 }
343 
344 
345 HIDDEN int
346 stk_cursor(fb *ifp, int mode, int x, int y)
347 {
348  register fb **ip = SI(ifp)->if_list;
349 
350  while (*ip != (fb *)NULL) {
351  fb_cursor((*ip), mode, x, y);
352  ip++;
353  }
354 
355  return 0;
356 }
357 
358 
359 HIDDEN int
360 stk_getcursor(fb *ifp, int *mode, int *x, int *y)
361 {
362  register fb **ip = SI(ifp)->if_list;
363 
364  if (*ip != (fb *)NULL) {
365  fb_getcursor((*ip), mode, x, y);
366  }
367 
368  return 0;
369 }
370 
371 
372 HIDDEN int
374 {
375  register fb **ip = SI(ifp)->if_list;
376 
377  while (*ip != (fb *)NULL) {
378  fb_poll((*ip));
379  ip++;
380  }
381 
382  return 0;
383 }
384 
385 
386 HIDDEN int
388 {
389  register fb **ip = SI(ifp)->if_list;
390 
391  while (*ip != (fb *)NULL) {
392  fb_flush((*ip));
393  ip++;
394  }
395 
396  return 0;
397 }
398 
399 
400 HIDDEN int
402 {
403  register fb **ip = SI(ifp)->if_list;
404 
405  while (*ip != (fb *)NULL) {
406  fb_free((*ip));
407  ip++;
408  }
409 
410  return 0;
411 }
412 
413 
414 HIDDEN int
416 {
417  register fb **ip = SI(ifp)->if_list;
418  int i;
419 
420  fb_log("Device: /dev/stack\n");
421  fb_log("Usage: /dev/stack device_one; device_two; ...\n");
422 
423  i = 0;
424  while (*ip != (fb *)NULL) {
425  fb_log("=== Current stack device #%d ===\n", i++);
426  fb_help((*ip));
427  ip++;
428  }
429 
430  return 0;
431 }
432 
433 
434 /* This is the ONLY thing that we normally "export" */
436  0,
437  FB_STK_MAGIC,
438  stk_open, /* device_open */
439  stk_open_existing, /* device_open */
441  stk_get_fbps,
442  stk_put_fbps,
443  stk_close, /* device_close */
444  stk_clear, /* device_clear */
445  stk_read, /* buffer_read */
446  stk_write, /* buffer_write */
447  stk_rmap, /* colormap_read */
448  stk_wmap, /* colormap_write */
449  stk_view, /* set view */
450  stk_getview, /* get view */
451  stk_setcursor, /* define cursor */
452  stk_cursor, /* set cursor */
453  stk_getcursor, /* get cursor */
454  stk_readrect, /* read rectangle */
455  stk_writerect, /* write rectangle */
456  stk_bwreadrect, /* read bw rectangle */
457  stk_bwwriterect, /* write bw rectangle */
459  stk_refresh,
460  stk_poll, /* handle events */
461  stk_flush, /* flush output */
462  stk_free, /* free resources */
463  stk_help, /* help function */
464  "Multiple Device Stacker", /* device description */
465  32*1024, /* max width */
466  32*1024, /* max height */
467  "/dev/stack", /* short device name */
468  4, /* default/current width */
469  4, /* default/current height */
470  -1, /* select fd */
471  -1, /* file descriptor */
472  1, 1, /* zoom */
473  2, 2, /* window center */
474  0, 0, 0, /* cursor */
475  PIXEL_NULL, /* page_base */
476  PIXEL_NULL, /* page_curp */
477  PIXEL_NULL, /* page_endp */
478  -1, /* page_no */
479  0, /* page_dirty */
480  0L, /* page_curpos */
481  0L, /* page_pixels */
482  0, /* debug */
483  0, /* refresh rate */
484  {0}, /* u1 */
485  {0}, /* u2 */
486  {0}, /* u3 */
487  {0}, /* u4 */
488  {0}, /* u5 */
489  {0} /* u6 */
490 };
491 
492 
493 /*
494  * Local Variables:
495  * mode: C
496  * tab-width: 8
497  * indent-tabs-mode: t
498  * c-file-style: "stroustrup"
499  * End:
500  * ex: shiftwidth=4 tabstop=8
501  */
ptrdiff_t ssize_t
Definition: common.h:119
HIDDEN int stk_close(fb *ifp)
Definition: if_stack.c:155
void fb_log(const char *fmt,...) _BU_ATTR_PRINTF12
Definition: fb_log.c:42
HIDDEN int stk_readrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
Definition: if_stack.c:215
int fb_help(fb *ifp)
Definition: fb_generic.c:260
HIDDEN int stk_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: if_stack.c:231
HIDDEN int stk_help(fb *ifp)
Definition: if_stack.c:415
HIDDEN int stk_clear(fb *ifp, unsigned char *pp)
Definition: if_stack.c:171
fb * fb_open(const char *file, int _width, int _height)
Definition: fb_generic.c:384
#define PIXEL_NULL
Definition: fb.h:89
Header file for the BRL-CAD common definitions.
int fb_getcursor(fb *ifp, int *mode, int *x, int *y)
Definition: fb_generic.c:304
HIDDEN int stk_bwreadrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
Definition: if_stack.c:248
int if_max_width
max device width
Definition: fb_private.h:111
ustring width
int fb_cursor(fb *ifp, int mode, int x, int y)
Definition: fb_generic.c:300
HIDDEN int stk_rmap(fb *ifp, ColorMap *cmp)
Definition: if_stack.c:278
#define HIDDEN
Definition: common.h:86
int fb_bwwriterect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: fb_generic.c:320
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
HIDDEN struct fb_platform_specific * stk_get_fbps(uint32_t magic)
Definition: if_stack.c:116
HIDDEN int stk_wmap(fb *ifp, const ColorMap *cmp)
Definition: if_stack.c:291
int fb_close(fb *ifp)
Definition: fb_generic.c:478
int fb_free(fb *ifp)
Definition: fb_generic.c:264
HIDDEN ssize_t stk_read(fb *ifp, int x, int y, unsigned char *pixelp, size_t count)
Definition: if_stack.c:185
#define FB_CK_FB(_p)
Definition: fb.h:100
#define FB_NULL
Definition: fb.h:95
HIDDEN void stk_put_fbps(struct fb_platform_specific *fbps)
Definition: if_stack.c:123
int fb_view(fb *ifp, int xcenter, int ycenter, int xzoom, int yzoom)
Definition: fb_generic.c:288
HIDDEN ssize_t stk_write(fb *ifp, int x, int y, const unsigned char *pixelp, size_t count)
Definition: if_stack.c:198
int if_max_height
max device height
Definition: fb_private.h:112
HIDDEN int stk_poll(fb *ifp)
Definition: if_stack.c:373
oldeumate l2 magic
Definition: nmg_mod.c:3843
#define UNUSED(parameter)
Definition: common.h:239
HIDDEN int stk_setcursor(fb *ifp, const unsigned char *bits, int xbits, int ybits, int xorig, int yorig)
Definition: if_stack.c:332
HIDDEN int stk_open_existing(fb *ifp, int width, int height, struct fb_platform_specific *fb_p)
Definition: if_stack.c:129
int fb_readrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
Definition: fb_generic.c:308
fb stk_interface
Definition: if_stack.c:435
Definition: fb.h:82
HIDDEN int stk_close_existing(fb *ifp)
Definition: if_stack.c:136
#define SIL(ptr)
Definition: if_stack.c:47
int fb_rmap(fb *ifp, ColorMap *cmap)
Definition: fb_generic.c:280
HIDDEN int stk_bwwriterect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: if_stack.c:264
int fb_getview(fb *ifp, int *xcenter, int *ycenter, int *xzoom, int *yzoom)
Definition: fb_generic.c:292
ssize_t fb_write(fb *ifp, int x, int y, const unsigned char *pp, size_t count)
Definition: fb_generic.c:276
int fb_wmap(fb *ifp, const ColorMap *cmap)
Definition: fb_generic.c:284
int fb_flush(fb *ifp)
HIDDEN int stk_getview(fb *ifp, int *xcenter, int *ycenter, int *xzoom, int *yzoom)
Definition: if_stack.c:319
HIDDEN int stk_refresh(fb *ifp, int x, int y, int w, int h)
Definition: if_stack.c:148
#define MAXIF
Definition: if_stack.c:42
HIDDEN int stk_flush(fb *ifp)
Definition: if_stack.c:387
fb * if_list[MAXIF]
Definition: if_stack.c:44
int fb_clear(fb *ifp, unsigned char *pp)
Definition: fb_generic.c:268
int fb_bwreadrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
Definition: fb_generic.c:316
HIDDEN int stk_view(fb *ifp, int xcenter, int ycenter, int xzoom, int yzoom)
Definition: if_stack.c:305
HIDDEN int stk_configure_window(fb *ifp, int width, int height)
Definition: if_stack.c:142
HIDDEN int stk_open(fb *ifp, const char *file, int width, int height)
Definition: if_stack.c:50
A frame-buffer IO structure.
Definition: fb_private.h:80
int if_width
current values
Definition: fb_private.h:115
HIDDEN int stk_cursor(fb *ifp, int mode, int x, int y)
Definition: if_stack.c:346
#define SI(ptr)
Definition: if_stack.c:46
char * if_name
what the user called it
Definition: fb_private.h:114
#define FB_STK_MAGIC
Definition: magic.h:188
int fb_setcursor(fb *ifp, const unsigned char *bits, int xb, int yb, int xo, int yo)
Definition: fb_generic.c:296
int fb_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: fb_generic.c:312
ssize_t fb_read(fb *ifp, int x, int y, unsigned char *pp, size_t count)
Definition: fb_generic.c:272
HIDDEN int stk_getcursor(fb *ifp, int *mode, int *x, int *y)
Definition: if_stack.c:360
int fb_poll(fb *ifp)
Definition: fb_generic.c:250
HIDDEN int stk_free(fb *ifp)
Definition: if_stack.c:401