BRL-CAD
if_qt.cpp
Go to the documentation of this file.
1 /* I F _ Q T . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 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_qt.cpp
23  *
24  * A Qt Frame Buffer.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <ctype.h>
36 
37 #include "fb.h"
38 #include "fb/fb_qt.h"
39 #include "bu/malloc.h"
40 #include "bu/file.h"
41 #include "bu/str.h"
42 
43 class QMainWindow: public QWindow {
44 
45 public:
46  QMainWindow(fb *ifp, QImage *image, QWindow *parent = 0);
47  ~QMainWindow();
48 
49  virtual void render(QPainter *painter);
50 public slots:
51  void renderNow();
52 
53 protected:
54  bool event(QEvent *event);
55 
56  void resizeEvent(QResizeEvent *event);
57  void exposeEvent(QExposeEvent *event);
58 
59 private:
60  fb *ifp;
61  QImage *image;
62  QBackingStore *m_backingStore;
63  bool m_update_pending;
64 };
65 
66 struct qtinfo {
67  QApplication *qapp;
68  QWindow *win;
69  QImage *qi_image;
70  void **qi_parent_img;
71  QPainter *qi_painter;
72 
73  int alive;
74  int *drawFb;
75 
76  unsigned long qi_mode;
77  unsigned long qi_flags;
78 
79  unsigned char *qi_mem;
80  unsigned char *qi_pix;
81 
82  int qi_iwidth;
84 
85  int qi_ilf; /* Image coordinate of LLHC image */
86  int qi_ibt; /* pixel */
87  int qi_irt; /* Image coordinate of URHC image */
88  int qi_itp; /* pixel */
89 
90  int qi_ilf_w; /* Width of leftmost image pixels */
91  int qi_irt_w; /* Width of rightmost image pixels */
92  int qi_ibt_h; /* Height of bottommost image pixels */
93  int qi_itp_h; /* Height of topmost image pixels */
94 
95  int qi_qwidth; /* Width of Qwindow */
96  int qi_qheight; /* Height of Qwindow */
97 
98  int qi_xlf; /* X-coord of leftmost pixels */
99  int qi_xrt; /* X-coord of rightmost pixels */
100  int qi_xtp; /* Y-coord of topmost pixels */
101  int qi_xbt; /* Y-coord of bottommost pixels */
102 
103  ColorMap *qi_rgb_cmap; /* User's libfb colormap */
104  unsigned char *qi_redmap;
105  unsigned char *qi_blumap;
106  unsigned char *qi_grnmap;
107 };
108 
109 #define QI(ptr) ((struct qtinfo *)((ptr)->u1.p))
110 #define QI_SET(ptr, val) ((ptr)->u1.p) = (char *) val;
111 
112 /* Flags in qi_flags */
113 #define FLG_LINCMAP 0x10 /* We're using a linear colormap */
114 #define FLG_INIT 0x40 /* Display is fully initialized */
115 
116 /* Mode flags for open */
117 #define MODE1_MASK (1<<1)
118 #define MODE1_TRANSIENT (0<<1)
119 #define MODE1_LINGERING (1<<1)
120 
121 #define MODEV_MASK (7<<1)
122 
123 #define MODE10_MASK (1<<10)
124 #define MODE10_MALLOC (0<<10)
125 #define MODE10_SHARED (1<<10)
126 
127 #define MODE11_MASK (1<<11)
128 #define MODE11_NORMAL (0<<11)
129 #define MODE11_ZAP (1<<11)
130 
131 static struct modeflags {
132  char c;
133  unsigned long mask;
134  unsigned long value;
135  const char *help;
136 } modeflags[] = {
137  { 'l', MODE1_MASK, MODE1_LINGERING,
138  "Lingering window" },
139  { 't', MODE1_MASK, MODE1_TRANSIENT,
140  "Transient window" },
141  { 's', MODE10_MASK, MODE10_SHARED,
142  "Use shared memory backing store" },
143  { '\0', 0, 0, "" },
144 };
145 
146 
147 HIDDEN void
149 {
150  struct qtinfo *qi = QI(ifp);
151 
152  int xwp, ywp; /* Size of Qt window in image pixels */
153  int xrp, yrp; /* Leftover Qt pixels */
154 
155  int tp_h, bt_h; /* Height of top/bottom image pixel slots */
156  int lf_w, rt_w; /* Width of left/right image pixel slots */
157 
158  int want, avail; /* Wanted/available image pixels */
159 
160  FB_CK_FB(ifp);
161 
162  /*
163  * Set ?wp to the number of whole zoomed image pixels we could display
164  * in the window.
165  */
166  xwp = qi->qi_qwidth / ifp->if_xzoom;
167  ywp = qi->qi_qheight / ifp->if_yzoom;
168 
169  /*
170  * Set ?rp to the number of leftover pixels we have, after displaying
171  * wp whole zoomed image pixels.
172  */
173  xrp = qi->qi_qwidth % ifp->if_xzoom;
174  yrp = qi->qi_qheight % ifp->if_yzoom;
175 
176  /*
177  * Force ?wp to be the same as the window width (mod 2). This
178  * keeps the image from jumping around when using large zoom
179  * factors.
180  */
181  if (xwp && (xwp ^ qi->qi_qwidth) & 1) {
182  xwp--;
183  xrp += ifp->if_xzoom;
184  }
185 
186  if (ywp && (ywp ^ qi->qi_qheight) & 1) {
187  ywp--;
188  yrp += ifp->if_yzoom;
189  }
190 
191  /*
192  * Now we calculate the height/width of the outermost image pixel
193  * slots. If we've got any leftover pixels, we'll make
194  * truncated slots out of them; if not, the outermost ones end up
195  * full size. We'll adjust ?wp to be the number of full and
196  * truncated slots available.
197  */
198  switch (xrp) {
199  case 0:
200  lf_w = ifp->if_xzoom;
201  rt_w = ifp->if_xzoom;
202  break;
203 
204  case 1:
205  lf_w = 1;
206  rt_w = ifp->if_xzoom;
207  xwp += 1;
208  break;
209 
210  default:
211  lf_w = xrp / 2;
212  rt_w = xrp - lf_w;
213  xwp += 2;
214  break;
215  }
216 
217  switch (yrp) {
218  case 0:
219  tp_h = ifp->if_yzoom;
220  bt_h = ifp->if_yzoom;
221  break;
222 
223  case 1:
224  tp_h = 1;
225  bt_h = ifp->if_yzoom;
226  ywp += 1;
227  break;
228 
229  default:
230  tp_h = yrp / 2;
231  bt_h = yrp - tp_h;
232  ywp += 2;
233  break;
234  }
235 
236  /*
237  * We've now divided our Qt window up into image pixel slots as
238  * follows:
239  *
240  * - All slots are xzoom by yzoom pixels in size, except:
241  * slots in the top row are tp_h pixels high
242  * slots in the bottom row are bt_h pixels high
243  * slots in the left column are lf_w pixels wide
244  * slots in the right column are rt_w pixels wide
245  * - The window is xwp by ywp slots in size.
246  */
247 
248  /*
249  * We can think of xcenter as being "number of pixels we'd like
250  * displayed on the left half of the screen". We have xwp/2
251  * pixels available on the left half. We use this information to
252  * calculate the remaining parameters as noted.
253  */
254  want = ifp->if_xcenter;
255  avail = xwp/2;
256  if (want >= avail) {
257  /*
258  * Just enough or too many pixels to display. We'll be butted
259  * up against the left edge, so
260  * - the leftmost pixels will have an x coordinate of 0;
261  * - the leftmost column of image pixels will be as wide as the
262  * leftmost column of image pixel slots; and
263  * - the leftmost image pixel displayed will have an x
264  * coordinate equal to the number of pixels that didn't fit.
265  */
266  qi->qi_xlf = 0;
267  qi->qi_ilf_w = lf_w;
268  qi->qi_ilf = want - avail;
269  } else {
270  /*
271  * Not enough image pixels to fill the area. We'll be offset
272  * from the left edge, so
273  * - the leftmost pixels will have an x coordinate equal
274  * to the number of pixels taken up by the unused image
275  * pixel slots;
276  * - the leftmost column of image pixels will be as wide as the
277  * xzoom width; and
278  * - the leftmost image pixel displayed will have a zero
279  * x coordinate.
280  */
281  qi->qi_xlf = lf_w + (avail - want - 1) * ifp->if_xzoom;
282  qi->qi_ilf_w = ifp->if_xzoom;
283  qi->qi_ilf = 0;
284  }
285 
286  /* Calculation for bottom edge. */
287  want = ifp->if_ycenter;
288  avail = ywp/2;
289  if (want >= avail) {
290  /*
291  * Just enough or too many pixels to display. We'll be
292  * butted up against the bottom edge, so
293  * - the bottommost pixels will have a y coordinate
294  * equal to the window height minus 1;
295  * - the bottommost row of image pixels will be as tall as the
296  * bottommost row of image pixel slots; and
297  * - the bottommost image pixel displayed will have a y
298  * coordinate equal to the number of pixels that didn't fit.
299  */
300  qi->qi_xbt = qi->qi_qheight - 1;
301  qi->qi_ibt_h = bt_h;
302  qi->qi_ibt = want - avail;
303  } else {
304  /*
305  * Not enough image pixels to fill the area. We'll be
306  * offset from the bottom edge, so
307  * - the bottommost pixels will have a y coordinate equal
308  * to the window height, less the space taken up by the
309  * unused image pixel slots, minus 1;
310  * - the bottom row of image pixels will be as tall as the
311  * yzoom width; and
312  * - the bottommost image pixel displayed will have a zero
313  * y coordinate.
314  */
315  qi->qi_xbt = qi->qi_qheight - (bt_h + (avail - want - 1) *
316  ifp->if_yzoom) - 1;
317  qi->qi_ibt_h = ifp->if_yzoom;
318  qi->qi_ibt = 0;
319  }
320 
321  /* Calculation for right edge. */
322  want = qi->qi_iwidth - ifp->if_xcenter;
323  avail = xwp - xwp/2;
324  if (want >= avail) {
325  /*
326  * Just enough or too many pixels to display. We'll be
327  * butted up against the right edge, so
328  * - the rightmost pixels will have an x coordinate equal
329  * to the window width minus 1;
330  * - the rightmost column of image pixels will be as wide as
331  * the rightmost column of image pixel slots; and
332  * - the rightmost image pixel displayed will have an x
333  * coordinate equal to the center plus the number of pixels
334  * that fit, minus 1.
335  */
336  qi->qi_xrt = qi->qi_qwidth - 1;
337  qi->qi_irt_w = rt_w;
338  qi->qi_irt = ifp->if_xcenter + avail - 1;
339  } else {
340  /*
341  * Not enough image pixels to fill the area. We'll be
342  * offset from the right edge, so
343  * - the rightmost pixels will have an x coordinate equal
344  * to the window width, less the space taken up by the
345  * unused image pixel slots, minus 1;
346  * - the rightmost column of image pixels will be as wide as
347  * the xzoom width; and
348  * - the rightmost image pixel displayed will have an x
349  * coordinate equal to the width of the image minus 1.
350  */
351  qi->qi_xrt = qi->qi_qwidth - (rt_w + (avail - want - 1) *
352  ifp->if_xzoom) - 1;
353  qi->qi_irt_w = ifp->if_xzoom;
354  qi->qi_irt = qi->qi_iwidth - 1;
355  }
356 
357  /* Calculation for top edge. */
358  want = qi->qi_iheight - ifp->if_ycenter;
359  avail = ywp - ywp/2;
360  if (want >= avail) {
361  /*
362  * Just enough or too many pixels to display. We'll be
363  * butted up against the top edge, so
364  * - the topmost pixels will have a y coordinate of 0;
365  * - the topmost row of image pixels will be as tall as
366  * the topmost row of image pixel slots; and
367  * - the topmost image pixel displayed will have a y
368  * coordinate equal to the center plus the number of pixels
369  * that fit, minus 1.
370  */
371  qi->qi_xtp = 0;
372  qi->qi_itp_h = tp_h;
373  qi->qi_itp = ifp->if_ycenter + avail - 1;
374  } else {
375  /*
376  * Not enough image pixels to fill the area. We'll be
377  * offset from the top edge, so
378  * - the topmost pixels will have a y coordinate equal
379  * to the space taken up by the unused image pixel slots;
380  * - the topmost row of image pixels will be as tall as
381  * the yzoom height; and
382  * - the topmost image pixel displayed will have a y
383  * coordinate equal to the height of the image minus 1.
384  */
385  qi->qi_xtp = tp_h + (avail - want - 1) * ifp->if_yzoom;
386  qi->qi_itp_h = ifp->if_yzoom;
387  qi->qi_itp = qi->qi_iheight - 1;
388  }
389 }
390 
392 
393 void
394 qt_configureWindow(fb *ifp, int width, int height)
395 {
396  struct qtinfo *qi = QI(ifp);
397 
398  FB_CK_FB(ifp);
399 
400  if (!qi) {
401  return;
402  }
403 
404  if (width == qi->qi_qwidth && height == qi->qi_qheight) {
405  return;
406  }
407 
408  ifp->if_width = width;
409  ifp->if_height = height;
410 
411  qi->qi_qwidth = qi->qi_iwidth = width;
412  qi->qi_qheight = qi->qi_iheight = height;
413 
414  ifp->if_xcenter = width/2;
415  ifp->if_ycenter = height/2;
416 
417  /* destroy old image struct and image buffers */
418  delete qi->qi_image;
419  free(qi->qi_pix);
420 
421  if ((qi->qi_pix = (unsigned char *) calloc((width + 1) * (height + 1) * sizeof(RGBpixel),
422  sizeof(char))) == NULL) {
423  fb_log("qt_open_existing: pix malloc failed");
424  }
425 
426  qi->qi_image = new QImage(qi->qi_pix, width, height, QImage::Format_RGB888);
427  *qi->qi_parent_img = qi->qi_image;
428 
429  qt_updstate(ifp);
430 }
431 
432 HIDDEN int
433 qt_configure_window(fb *ifp, int width, int height)
434 {
435  qt_configureWindow(ifp, width, height);
436  return 0;
437 }
438 
439 HIDDEN int
440 qt_refresh(fb *UNUSED(ifp), int UNUSED(x), int UNUSED(y), int UNUSED(w), int UNUSED(h))
441 {
442  return 0;
443 }
444 
445 int
447 {
448  struct qtinfo *qi = QI(ifp);
449  FB_CK_FB(ifp);
450 
451  if (qi->qi_image)
452  delete qi->qi_image;
453 
454  free((char *)qi);
455 
456  return 0;
457 }
458 
460 
461 
462 HIDDEN void
463 qt_update(fb *ifp, int x1, int y1, int w, int h)
464 {
465  struct qtinfo *qi = QI(ifp);
466 
467  int x2 = x1 + w - 1; /* Convert to rectangle corners */
468  int y2 = y1 + h - 1;
469 
470  int x1wd, x2wd, y1ht, y2ht;
471  int ox, oy;
472  int xdel, ydel;
473  int xwd, xht;
474 
475  unsigned char *ip;
476  unsigned char *op;
477 
478  int x, y;
479 
480  unsigned int a_pixel;
481 
482  unsigned char *red = qi->qi_redmap;
483  unsigned char *grn = qi->qi_grnmap;
484  unsigned char *blu = qi->qi_blumap;
485 
486  FB_CK_FB(ifp);
487 
488  /*
489  * Figure out sizes of outermost image pixels
490  */
491  x1wd = (x1 == qi->qi_ilf) ? qi->qi_ilf_w : ifp->if_xzoom;
492  x2wd = (x2 == qi->qi_irt) ? qi->qi_irt_w : ifp->if_xzoom;
493  y1ht = (y1 == qi->qi_ibt) ? qi->qi_ibt_h : ifp->if_yzoom;
494  y2ht = (y2 == qi->qi_itp) ? qi->qi_itp_h : ifp->if_yzoom;
495 
496  /* Compute ox: offset from left edge of window to left pixel */
497  xdel = x1 - qi->qi_ilf;
498  if (xdel) {
499  ox = x1wd + ((xdel - 1) * ifp->if_xzoom) + qi->qi_xlf;
500  } else {
501  ox = qi->qi_xlf;
502  }
503 
504  /* Compute oy: offset from top edge of window to bottom pixel */
505  ydel = y1 - qi->qi_ibt;
506  if (ydel) {
507  oy = qi->qi_xbt - (y1ht + ((ydel - 1) * ifp->if_yzoom));
508  } else {
509  oy = qi->qi_xbt;
510  }
511 
512  if (x2 == x1) {
513  xwd = x1wd;
514  } else {
515  xwd = x1wd + x2wd + ifp->if_xzoom * (x2 - x1 - 1);
516  }
517 
518  if (y2 == y1) {
519  xht = y1ht;
520  } else {
521  xht = y1ht + y2ht + ifp->if_yzoom * (y2 - y1 - 1);
522  }
523 
524  /*
525  * Set pointers to start of source and destination areas; note
526  * that we're going from lower to higher image coordinates, so
527  * irgb increases, but since images are in quadrant I and Qt uses
528  * quadrant IV, opix _decreases_.
529  */
530  ip = &(qi->qi_mem[(y1 * qi->qi_iwidth + x1) *
531  sizeof (RGBpixel)]);
532  op = &qi->qi_pix[oy * qi->qi_image->bytesPerLine() + ox];
533 
534  for (y = y1; y <= y2; y++) {
535  unsigned char *line_irgb;
536  unsigned char *p;
537 
538  /* Save pointer to start of line */
539  line_irgb = ip;
540  p = (unsigned char *)op;
541 
542  /* For the first line, convert/copy pixels */
543  for (x = x1; x <= x2; x++) {
544  int pxwd;
545  /* Calculate # pixels needed */
546  if (x == x1) {
547  pxwd = x1wd;
548  } else if (x == x2) {
549  pxwd = x2wd;
550  } else {
551  pxwd = ifp->if_xzoom;
552  }
553 
554  /*
555  * Construct a pixel with the color components
556  * in the right places as described by the
557  * red, green and blue masks.
558  */
559  if (qi->qi_flags & FLG_LINCMAP) {
560  a_pixel = (line_irgb[0] << 16);
561  a_pixel |= (line_irgb[1] << 8);
562  a_pixel |= (line_irgb[2]);
563  } else {
564  a_pixel = (red[line_irgb[0]] << 16);
565  a_pixel |= (grn[line_irgb[1]] << 8);
566  a_pixel |= (blu[line_irgb[2]]);
567  }
568 
569  while (pxwd--) {
570  *p++ = (a_pixel >> 16) & 0xff;
571  *p++ = (a_pixel >> 8) & 0xff;
572  *p++ = a_pixel & 0xff;
573  }
574 
575  /*
576  * Move to the next input line.
577  */
578  line_irgb += sizeof (RGBpixel);
579  }
580 
581  /*
582  * move to the next line
583  */
584  op -= qi->qi_image->bytesPerLine();
585 
586  ip += qi->qi_iwidth * sizeof(RGBpixel);
587  }
588 
589  if (qi->alive == 0) {
590  qi->qi_painter->drawImage(ox, oy - xht + 1, *qi->qi_image, ox, oy - xht + 1, xwd, xht);
591  }
592 
593  QApplication::sendEvent(qi->win, new QEvent(QEvent::UpdateRequest));
594  qi->qapp->processEvents();
595 }
596 
597 
598 HIDDEN int
599 qt_rmap(fb *ifp, ColorMap *cmp)
600 {
601  struct qtinfo *qi = QI(ifp);
602  FB_CK_FB(ifp);
603 
604  memcpy(cmp, qi->qi_rgb_cmap, sizeof (ColorMap));
605 
606  return 0;
607 }
608 
609 
610 HIDDEN int
611 qt_wmap(fb *ifp, const ColorMap *cmp)
612 {
613  struct qtinfo *qi = QI(ifp);
614  ColorMap *map = qi->qi_rgb_cmap;
615  int waslincmap;
616  int i;
617  unsigned char *red = qi->qi_redmap;
618  unsigned char *grn = qi->qi_grnmap;
619  unsigned char *blu = qi->qi_blumap;
620 
621  FB_CK_FB(ifp);
622 
623  /* Did we have a linear colormap before this call? */
624  waslincmap = qi->qi_flags & FLG_LINCMAP;
625 
626  /* Clear linear colormap flag, since it may be changing */
627  qi->qi_flags &= ~FLG_LINCMAP;
628 
629  /* Copy in or generate colormap */
630 
631  if (cmp) {
632  if (cmp != map)
633  memcpy(map, cmp, sizeof (ColorMap));
634  } else {
635  fb_make_linear_cmap(map);
636  qi->qi_flags |= FLG_LINCMAP;
637  }
638 
639  /* Decide if this colormap is linear */
640  if (!(qi->qi_flags & FLG_LINCMAP)) {
641  int nonlin = 0;
642 
643  for (i = 0; i < 256; i++)
644  if (map->cm_red[i] >> 8 != i ||
645  map->cm_green[i] >> 8 != i ||
646  map->cm_blue[i] >> 8 != i) {
647  nonlin = 1;
648  break;
649  }
650 
651  if (!nonlin)
652  qi->qi_flags |= FLG_LINCMAP;
653  }
654 
655  /*
656  * If it was linear before, and they're making it linear again,
657  * there's nothing to do.
658  */
659  if (waslincmap && qi->qi_flags & FLG_LINCMAP)
660  return 0;
661 
662  /* Copy into our fake colormap arrays. */
663  for (i = 0; i < 256; i++) {
664  red[i] = map->cm_red[i] >> 8;
665  grn[i] = map->cm_green[i] >> 8;
666  blu[i] = map->cm_blue[i] >> 8;
667  }
668 
669  /*
670  * If we're initialized, redraw the screen to make changes
671  * take effect.
672  */
673  if (qi->qi_flags & FLG_INIT)
674  qt_update(ifp, 0, 0, qi->qi_iwidth, qi->qi_iheight);
675 
676  return 0;
677 }
678 
679 HIDDEN int
680 qt_setup(fb *ifp, int width, int height)
681 {
682  struct qtinfo *qi = QI(ifp);
683  int argc = 1;
684  char *argv[] = {(char *)"Frame buffer"};
685  FB_CK_FB(ifp);
686 
687  qi->qi_qwidth = width;
688  qi->qi_qheight = height;
689 
690  qi->qapp = new QApplication(argc, argv);
691 
692  if ((qi->qi_pix = (unsigned char *) calloc(width * height * sizeof(RGBpixel),
693  sizeof(char))) == NULL) {
694  fb_log("qt_open: pix malloc failed");
695  }
696 
697  qi->qi_image = new QImage(qi->qi_pix, width, height, QImage::Format_RGB888);
698 
699  qi->win = new QMainWindow(ifp, qi->qi_image);
700  qi->win->setWidth(width);
701  qi->win->setHeight(height);
702  qi->win->show();
703 
704  while(!qi->win->isExposed()) {
705  qi->qapp->processEvents();
706  }
707 
708  return 0;
709 }
710 
711 HIDDEN void
712 qt_destroy(struct qtinfo *qi)
713 {
714  if (qi) {
715  free(qi);
716  }
717 }
718 
719 HIDDEN int
720 qt_open(fb *ifp, const char *file, int width, int height)
721 {
722  struct qtinfo *qi;
723 
724  unsigned long mode;
725  size_t size;
726  unsigned char *mem = NULL;
727 
728  FB_CK_FB(ifp);
729  mode = MODE1_LINGERING;
730 
731  if (file != NULL) {
732  const char *cp;
733  char modebuf[80];
734  char *mp;
735  int alpha;
736  struct modeflags *mfp;
737 
738  if (bu_strncmp(file, ifp->if_name, strlen(ifp->if_name))) {
739  mode = 0;
740  } else {
741  alpha = 0;
742  mp = &modebuf[0];
743  cp = &file[sizeof("/dev/Qt")-1];
744  while (*cp != '\0' && !isspace((int)(*cp))) {
745  *mp++ = *cp;
746  if (isdigit((int)(*cp))) {
747  cp++;
748  continue;
749  }
750  alpha++;
751  for (mfp = modeflags; mfp->c != '\0'; mfp++) {
752  if (mfp->c == *cp) {
753  mode = (mode&~mfp->mask)|mfp->value;
754  break;
755  }
756  }
757  if (mfp->c == '\0' && *cp != '-') {
758  fb_log("if_qt: unknown option '%c' ignored\n", *cp);
759  }
760  cp++;
761  }
762  *mp = '\0';
763  if (!alpha)
764  mode |= atoi(modebuf);
765  }
766  }
767 
768  if (width <= 0)
769  width = ifp->if_width;
770  if(height <= 0)
771  height = ifp->if_height;
772  if (width > ifp->if_max_width)
773  width = ifp->if_max_width;
774  if (height > ifp->if_max_height)
775  height = ifp->if_max_height;
776 
777  ifp->if_width = width;
778  ifp->if_height = height;
779 
780  ifp->if_xzoom = 1;
781  ifp->if_yzoom = 1;
782  ifp->if_xcenter = width/2;
783  ifp->if_ycenter = height/2;
784 
785  if ((qi = (struct qtinfo *)calloc(1, sizeof(struct qtinfo))) ==
786  NULL) {
787  fb_log("qt_open: qtinfo malloc failed\n");
788  return -1;
789  }
790  QI_SET(ifp, qi);
791 
792  qi->qi_mode = mode;
793  qi->qi_iwidth = width;
794  qi->qi_iheight = height;
795 
796  /* allocate backing store */
797  size = ifp->if_max_height * ifp->if_max_width * sizeof(RGBpixel) + sizeof (*qi->qi_rgb_cmap);;
798  if ((mem = (unsigned char *)malloc(size)) == 0) {
799  fb_log("if_qt: Unable to allocate %d bytes of backing \
800  store\n Run shell command 'limit datasize unlimited' and try again.\n", size);
801  return -1;
802  }
803  qi->qi_rgb_cmap = (ColorMap *) mem;
804  qi->qi_redmap = (unsigned char *)malloc(256);
805  qi->qi_grnmap = (unsigned char *)malloc(256);
806  qi->qi_blumap = (unsigned char *)malloc(256);
807 
808  if (!qi->qi_redmap || !qi->qi_grnmap || !qi->qi_blumap) {
809  fb_log("if_qt: Can't allocate colormap memory\n");
810  return -1;
811  }
812  qi->qi_mem = (unsigned char *) mem + sizeof (*qi->qi_rgb_cmap);
813 
814  /* Set up an Qt window */
815  if (qt_setup(ifp, width, height) < 0) {
816  qt_destroy(qi);
817  return -1;
818  }
819 
820  qt_updstate(ifp);
821 
822  qi->alive = 1;
823 
824  /* Mark display ready */
825  qi->qi_flags |= FLG_INIT;
826 
827  /* Set up default linear colormap */
828  qt_wmap(ifp, NULL);
829 
830  return 0;
831 }
832 
833 
836 {
837  struct fb_platform_specific *fb_ps = NULL;
838  struct qt_fb_info *data = NULL;
839  BU_GET(fb_ps, struct fb_platform_specific);
840  BU_GET(data, struct qt_fb_info);
841  fb_ps->magic = magic;
842  fb_ps->data = data;
843  return fb_ps;
844 }
845 
846 
847 HIDDEN void
849 {
850  BU_CKMAG(fbps, FB_QT_MAGIC, "Qt framebuffer");
851  BU_PUT(fbps->data, struct qt_fb_info);
852  BU_PUT(fbps, struct fb_platform_specific);
853  return;
854 }
855 
856 int
857 _qt_open_existing(fb *ifp, int width, int height, void *qapp, void *qwin, void *qpainter, void *draw, void **qimg)
858 {
859  struct qtinfo *qi;
860 
861  unsigned long mode;
862  size_t size;
863  unsigned char *mem = NULL;
864 
865  FB_CK_FB(ifp);
866 
867  mode = MODE1_LINGERING;
868 
869  if (width <= 0)
870  width = ifp->if_width;
871  if(height <= 0)
872  height = ifp->if_height;
873  if (width > ifp->if_max_width)
874  width = ifp->if_max_width;
875  if (height > ifp->if_max_height)
876  height = ifp->if_max_height;
877 
878  ifp->if_width = width;
879  ifp->if_height = height;
880 
881  ifp->if_xzoom = 1;
882  ifp->if_yzoom = 1;
883  ifp->if_xcenter = width/2;
884  ifp->if_ycenter = height/2;
885 
886  if ((qi = (struct qtinfo *)calloc(1, sizeof(struct qtinfo))) ==
887  NULL) {
888  fb_log("qt_open: qtinfo malloc failed\n");
889  return -1;
890  }
891  QI_SET(ifp, qi);
892 
893  qi->qi_mode = mode;
894  qi->qi_iwidth = width;
895  qi->qi_iheight = height;
896 
897  /* allocate backing store */
898  size = ifp->if_max_height * ifp->if_max_width * sizeof(RGBpixel) + sizeof (*qi->qi_rgb_cmap);;
899  if ((mem = (unsigned char *)malloc(size)) == 0) {
900  fb_log("if_qt: Unable to allocate %d bytes of backing \
901  store\n Run shell command 'limit datasize unlimited' and try again.\n", size);
902  return -1;
903  }
904  qi->qi_rgb_cmap = (ColorMap *) mem;
905  qi->qi_redmap = (unsigned char *)malloc(256);
906  qi->qi_grnmap = (unsigned char *)malloc(256);
907  qi->qi_blumap = (unsigned char *)malloc(256);
908 
909  if (!qi->qi_redmap || !qi->qi_grnmap || !qi->qi_blumap) {
910  fb_log("if_qt: Can't allocate colormap memory\n");
911  return -1;
912  }
913  qi->qi_mem = (unsigned char *) mem + sizeof (*qi->qi_rgb_cmap);
914 
915  /* Set up an Qt window */
916  qi->qi_qwidth = width;
917  qi->qi_qheight = height;
918 
919  qi->qapp = (QApplication *)qapp;
920 
921  if ((qi->qi_pix = (unsigned char *) calloc(width * height * sizeof(RGBpixel),
922  sizeof(char))) == NULL) {
923  fb_log("qt_open_existing: pix malloc failed");
924  }
925 
926  qi->qi_image = new QImage(qi->qi_pix, width, height, QImage::Format_RGB888);
927  *qimg = qi->qi_image;
928 
929  qi->qi_parent_img = qimg;
930  qi->qi_painter = (QPainter *)qpainter;
931  qi->win = (QWindow *)qwin;
932 
933  qt_updstate(ifp);
934  qi->alive = 0;
935  qi->drawFb = (int *)draw;
936 
937  /* Set up default linear colormap */
938  qt_wmap(ifp, NULL);
939 
940  /* Mark display ready */
941  qi->qi_flags |= FLG_INIT;
942 
943  return 0;
944 }
945 
946 HIDDEN int
947 qt_open_existing(fb *ifp, int width, int height, struct fb_platform_specific *fb_p)
948 {
949  struct qt_fb_info *qt_internal = (struct qt_fb_info *)fb_p->data;
950  BU_CKMAG(fb_p, FB_QT_MAGIC, "qt framebuffer");
951  return _qt_open_existing(ifp, width, height, qt_internal->qapp, qt_internal->qwin,
952  qt_internal->qpainter, qt_internal->draw, qt_internal->qimg);
953 }
954 
955 
956 HIDDEN int
958 {
959  struct qtinfo *qi = QI(ifp);
960 
961  /* if a window was created wait for user input and process events */
962  if (qi->alive == 1) {
963  return qi->qapp->exec();
964  }
965 
966  qt_destroy(qi);
967 
968  return 0;
969 }
970 
971 
972 HIDDEN int
973 qt_clear(fb *ifp, unsigned char *pp)
974 {
975  struct qtinfo *qi = QI(ifp);
976 
977  int red, grn, blu;
978  int npix;
979  int n;
980  unsigned char *cp;
981 
982  FB_CK_FB(ifp);
983 
984  if (pp == (unsigned char *)NULL) {
985  red = grn = blu = 0;
986  } else {
987  red = pp[0];
988  grn = pp[1];
989  blu = pp[2];
990  }
991 
992  /* Clear the backing store */
993  npix = qi->qi_iwidth * qi->qi_qheight;
994 
995  if (red == grn && red == blu) {
996  memset(qi->qi_mem, red, npix*3);
997  } else {
998  cp = qi->qi_mem;
999  n = npix;
1000  while (n--) {
1001  *cp++ = red;
1002  *cp++ = grn;
1003  *cp++ = blu;
1004  }
1005  }
1006 
1007  qt_update(ifp, 0, 0, qi->qi_iwidth, qi->qi_iheight);
1008 
1009  return 0;
1010 }
1011 
1012 
1014 qt_read(fb *ifp, int x, int y, unsigned char *pixelp, size_t count)
1015 {
1016  struct qtinfo *qi = QI(ifp);
1017  size_t maxcount;
1018 
1019  FB_CK_FB(ifp);
1020 
1021  /* check origin bounds */
1022  if (x < 0 || x >= qi->qi_iwidth || y < 0 || y >= qi->qi_iheight)
1023  return -1;
1024 
1025  /* clip read length */
1026  maxcount = qi->qi_iwidth * (qi->qi_iheight - y) - x;
1027  if (count > maxcount)
1028  count = maxcount;
1029 
1030  memcpy(pixelp, &(qi->qi_mem[(y*qi->qi_iwidth + x)*sizeof(RGBpixel)]), count*sizeof(RGBpixel));
1031 
1032  return count;
1033 }
1034 
1035 
1037 qt_write(fb *ifp, int x, int y, const unsigned char *pixelp, size_t count)
1038 {
1039  struct qtinfo *qi = QI(ifp);
1040  size_t maxcount;
1041 
1042  FB_CK_FB(ifp);
1043 
1044  /* Check origin bounds */
1045  if (x < 0 || x >= qi->qi_iwidth || y < 0 || y >= qi->qi_iheight)
1046  return -1;
1047 
1048  /* Clip write length */
1049  maxcount = qi->qi_iwidth * (qi->qi_iheight - y) - x;
1050  if (count > maxcount)
1051  count = maxcount;
1052 
1053  /* Save it in 24bit backing store */
1054  memcpy(&(qi->qi_mem[(y * qi->qi_iwidth + x) * sizeof(RGBpixel)]),
1055  pixelp, count * sizeof(RGBpixel));
1056 
1057  if (qi->alive == 0) {
1058  if (*qi->drawFb == 0)
1059  *qi->drawFb = 1;
1060  }
1061 
1062  if (x + count <= (size_t)qi->qi_iwidth) {
1063  qt_update(ifp, x, y, count, 1);
1064  } else {
1065  size_t ylines, tcount;
1066 
1067  tcount = count - (qi->qi_iwidth - x);
1068  ylines = 1 + (tcount + qi->qi_iwidth - 1) / qi->qi_iwidth;
1069 
1070  qt_update(ifp, 0, y, qi->qi_iwidth, ylines);
1071  }
1072  return count;
1073 }
1074 
1075 
1076 HIDDEN int
1077 qt_view(fb *ifp, int xcenter, int ycenter, int xzoom, int yzoom)
1078 {
1079  struct qtinfo *qi = QI(ifp);
1080 
1081  FB_CK_FB(ifp);
1082 
1083  /* bypass if no change */
1084  if (ifp->if_xcenter == xcenter && ifp->if_ycenter == ycenter
1085  && ifp->if_xzoom == xcenter && ifp->if_yzoom == ycenter)
1086  return 0;
1087 
1088  /* check bounds */
1089  if (xcenter < 0 || xcenter >= qi->qi_iwidth
1090  || ycenter < 0 || ycenter >= qi->qi_iheight)
1091  return -1;
1092  if (xzoom <= 0 || xzoom >= qi->qi_iwidth/2
1093  || yzoom <= 0 || yzoom >= qi->qi_iheight/2)
1094  return -1;
1095 
1096  ifp->if_xcenter = xcenter;
1097  ifp->if_ycenter = ycenter;
1098  ifp->if_xzoom = xzoom;
1099  ifp->if_yzoom = yzoom;
1100 
1101  qt_updstate(ifp);
1102  qt_update(ifp, 0, 0, qi->qi_iwidth, qi->qi_iheight);
1103 
1104  return 0;
1105 }
1106 
1107 
1108 HIDDEN int
1109 qt_getview(fb *ifp, int *xcenter, int *ycenter, int *xzoom, int *yzoom)
1110 {
1111  FB_CK_FB(ifp);
1112 
1113  *xcenter = ifp->if_xcenter;
1114  *ycenter = ifp->if_ycenter;
1115  *xzoom = ifp->if_xzoom;
1116  *yzoom = ifp->if_yzoom;
1117 
1118  return 0;
1119 }
1120 
1121 
1122 HIDDEN int
1123 qt_setcursor(fb *UNUSED(ifp), const unsigned char *UNUSED(bits), int UNUSED(xbits), int UNUSED(ybits), int UNUSED(xorig), int UNUSED(yorig))
1124 {
1125  fb_log("qt_setcursor\n");
1126 
1127  return 0;
1128 }
1129 
1130 
1131 HIDDEN int
1132 qt_cursor(fb *UNUSED(ifp), int UNUSED(mode), int UNUSED(x), int UNUSED(y))
1133 {
1134  fb_log("qt_cursor\n");
1135 
1136  return 0;
1137 }
1138 
1139 
1140 HIDDEN int
1141 qt_getcursor(fb *UNUSED(ifp), int *UNUSED(mode), int *UNUSED(x), int *UNUSED(y))
1142 {
1143  fb_log("qt_getcursor\n");
1144 
1145  return 0;
1146 }
1147 
1148 
1149 HIDDEN int
1150 qt_readrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
1151 {
1152  struct qtinfo *qi = QI(ifp);
1153  FB_CK_FB(ifp);
1154 
1155  /* Clip arguments */
1156  if (xmin < 0)
1157  xmin = 0;
1158  if (ymin < 0)
1159  ymin = 0;
1160  if (xmin + width > qi->qi_iwidth)
1161  width = qi->qi_iwidth - xmin;
1162  if (ymin + height > qi->qi_iheight)
1163  height = qi->qi_iheight - ymin;
1164 
1165  /* Do copy to backing store */
1166  if (xmin == 0 && width == qi->qi_iwidth) {
1167  /* We can do it all in one copy */
1168  memcpy(pp, &(qi->qi_mem[ymin * qi->qi_iwidth *
1169  sizeof (RGBpixel)]),
1170  width * height * sizeof (RGBpixel));
1171  } else {
1172  /* Need to do individual lines */
1173  int ht = height;
1174  unsigned char *p = &(qi->qi_mem[(ymin * qi->qi_iwidth + xmin) *
1175  sizeof (RGBpixel)]);
1176 
1177  while (ht--) {
1178  memcpy(pp, p, width * sizeof (RGBpixel));
1179  p += qi->qi_iwidth * sizeof (RGBpixel);
1180  pp += width * sizeof (RGBpixel);
1181  }
1182  }
1183 
1184  return width * height;
1185 }
1186 
1187 
1188 HIDDEN int
1189 qt_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
1190 {
1191  struct qtinfo *qi = QI(ifp);
1192  FB_CK_FB(ifp);
1193 
1194  /* Clip arguments */
1195  if (xmin < 0)
1196  xmin = 0;
1197  if (ymin < 0)
1198  ymin = 0;
1199  if (xmin + width > qi->qi_iwidth)
1200  width = qi->qi_iwidth - xmin;
1201  if (ymin + height > qi->qi_iheight)
1202  height = qi->qi_iheight - ymin;
1203 
1204  /* Do copy to backing store */
1205  if (xmin == 0 && width == qi->qi_iwidth) {
1206  /* We can do it all in one copy */
1207  memcpy(&(qi->qi_mem[ymin * qi->qi_iwidth * sizeof (RGBpixel)]),
1208  pp, width * height * sizeof (RGBpixel));
1209  } else {
1210  /* Need to do individual lines */
1211  int ht = height;
1212  unsigned char *p = &(qi->qi_mem[(ymin * qi->qi_iwidth + xmin) *
1213  sizeof (RGBpixel)]);
1214 
1215  while (ht--) {
1216  memcpy(p, pp, width * sizeof (RGBpixel));
1217  p += qi->qi_iwidth * sizeof (RGBpixel);
1218  pp += width * sizeof (RGBpixel);
1219  }
1220  }
1221 
1222  /* Flush to screen */
1223  qt_update(ifp, xmin, ymin, width, height);
1224 
1225  return width * height;
1226 }
1227 
1228 
1229 HIDDEN int
1231 {
1232  fb_log("Description: %s\n", qt_interface.if_type);
1233  fb_log("Device: %s\n", ifp->if_name);
1234  fb_log("Max width/height: %d %d\n",
1237  fb_log("Default width/height: %d %d\n",
1240  fb_log("Useful for Benchmarking/Debugging\n");
1241  return 0;
1242 }
1243 
1244 
1245 HIDDEN void
1246 qt_handle_event(fb *ifp, QEvent *event)
1247 {
1248  struct qtinfo *qi = QI(ifp);
1249  FB_CK_FB(ifp);
1250 
1251  switch (event->type()) {
1252  case QEvent::MouseButtonPress:
1253  {
1254  QMouseEvent *ev = (QMouseEvent *)event;
1255  int button = ev->button();
1256 
1257  switch (button) {
1258  case Qt::LeftButton:
1259  break;
1260  case Qt::MiddleButton:
1261  {
1262  int x, sy;
1263  int ix, isy;
1264  unsigned char *cp;
1265 
1266  x = ev->x();
1267  sy = qi->qi_qheight - ev->y() - 1;
1268 
1269  x -= qi->qi_xlf;
1270  sy -= qi->qi_qheight - qi->qi_xbt - 1;
1271  if (x < 0 || sy < 0) {
1272  fb_log("No RGB (outside image) 1\n");
1273  break;
1274  }
1275 
1276  if (x < qi->qi_ilf_w)
1277  ix = qi->qi_ilf;
1278  else
1279  ix = qi->qi_ilf + (x - qi->qi_ilf_w + ifp->if_xzoom - 1) / ifp->if_xzoom;
1280 
1281  if (sy < qi->qi_ibt_h)
1282  isy = qi->qi_ibt;
1283  else
1284  isy = qi->qi_ibt + (sy - qi->qi_ibt_h + ifp->if_yzoom - 1) / ifp->if_yzoom;
1285 
1286  if (ix >= qi->qi_iwidth || isy >= qi->qi_iheight) {
1287  fb_log("No RGB (outside image) 2\n");
1288  break;
1289  }
1290 
1291  cp = &(qi->qi_mem[(isy*qi->qi_iwidth + ix)*3]);
1292  fb_log("At image (%d, %d), real RGB=(%3d %3d %3d)\n",
1293  ix, isy, cp[0], cp[1], cp[2]);
1294 
1295  break;
1296  }
1297  case Qt::RightButton:
1298  qi->qapp->exit();
1299  break;
1300  }
1301  break;
1302  }
1303  case 6 /* QEvent::KeyPress */:
1304  {
1305  QKeyEvent *ev = (QKeyEvent *)event;
1306  if (ev->key() == Qt::Key_H)
1307  qt_help(ifp);
1308  break;
1309  }
1310  default:
1311  break;
1312  }
1313 
1314  return;
1315 }
1316 
1317 
1318 HIDDEN int
1320 {
1321  fb_log("qt_poll\n");
1322 
1323  return 0;
1324 }
1325 
1326 
1327 HIDDEN int
1329 {
1330  struct qtinfo *qi = QI(ifp);
1331 
1332  qi->qapp->processEvents();
1333 
1334  return 0;
1335 }
1336 
1337 
1338 HIDDEN int
1340 {
1341  fb_log("qt_free\n");
1342 
1343  return 0;
1344 }
1345 
1346 
1348  0,
1349  FB_QT_MAGIC,
1350  qt_open, /* device_open */
1353  qt_get_fbps,
1354  qt_put_fbps,
1355  qt_close, /* device_close */
1356  qt_clear, /* device_clear */
1357  qt_read, /* buffer_read */
1358  qt_write, /* buffer_write */
1359  qt_rmap, /* colormap_read */
1360  qt_wmap, /* colormap_write */
1361  qt_view, /* set view */
1362  qt_getview, /* get view */
1363  qt_setcursor, /* define cursor */
1364  qt_cursor, /* set cursor */
1365  qt_getcursor, /* get cursor */
1366  qt_readrect, /* rectangle read */
1367  qt_writerect, /* rectangle write */
1368  qt_readrect, /* bw rectangle read */
1369  qt_writerect, /* bw rectangle write */
1371  qt_refresh,
1372  qt_poll, /* handle events */
1373  qt_flush, /* flush output */
1374  qt_free, /* free resources */
1375  qt_help, /* help message */
1376  (char *)"Qt Device",/* device description */
1377  2048, /* max width */
1378  2048, /* max height */
1379  (char *)"/dev/Qt", /* short device name */
1380  512, /* default/current width */
1381  512, /* default/current height */
1382  -1, /* select fd */
1383  -1, /* file descriptor */
1384  1, 1, /* zoom */
1385  256, 256, /* window center */
1386  0, 0, 0, /* cursor */
1387  PIXEL_NULL, /* page_base */
1388  PIXEL_NULL, /* page_curp */
1389  PIXEL_NULL, /* page_endp */
1390  -1, /* page_no */
1391  0, /* page_dirty */
1392  0L, /* page_curpos */
1393  0L, /* page_pixels */
1394  0, /* debug */
1395  50000, /* refresh rate */
1396  {0}, /* u1 */
1397  {0}, /* u2 */
1398  {0}, /* u3 */
1399  {0}, /* u4 */
1400  {0}, /* u5 */
1401  {0} /* u6 */
1402 };
1403 
1404 
1405 /**
1406  * ===================================================== Main window class ===============================================
1407  */
1408 
1409 QMainWindow::QMainWindow(fb *fbp, QImage *img, QWindow *win)
1410  : QWindow(win)
1411  , m_update_pending(false)
1412 {
1413  m_backingStore = new QBackingStore(this);
1414  create();
1415  image = img;
1416  ifp = fbp;
1417 }
1418 
1420 {
1421  delete m_backingStore;
1422  close();
1423 }
1424 
1425 void QMainWindow::exposeEvent(QExposeEvent *)
1426 {
1427  if (isExposed()) {
1428  renderNow();
1429  }
1430 }
1431 
1432 void QMainWindow::resizeEvent(QResizeEvent *resizeEv)
1433 {
1434  m_backingStore->resize(resizeEv->size());
1435  if (isExposed())
1436  renderNow();
1437 }
1438 
1439 bool QMainWindow::event(QEvent *ev)
1440 {
1441  if (ev->type() == QEvent::UpdateRequest) {
1442  m_update_pending = false;
1443  renderNow();
1444  return true;
1445  }
1446 
1447  qt_handle_event(ifp, ev);
1448 
1449  return QWindow::event(ev);
1450 }
1451 
1453 {
1454  if (!isExposed()) {
1455  return;
1456  }
1457 
1458  QRect rect(0, 0, width(), height());
1459  m_backingStore->beginPaint(rect);
1460 
1461  QPaintDevice *device = m_backingStore->paintDevice();
1462  QPainter painter(device);
1463 
1464  render(&painter);
1465 
1466  m_backingStore->endPaint();
1467  m_backingStore->flush(rect);
1468 }
1469 
1470 void QMainWindow::render(QPainter *painter)
1471 {
1472  painter->drawPixmap(0, 0, QPixmap::fromImage(*image));
1473 }
1474 
1475 
1476 /*
1477  * Local Variables:
1478  * mode: C++
1479  * tab-width: 8
1480  * indent-tabs-mode: t
1481  * c-file-style: "stroustrup"
1482  * End:
1483  * ex: shiftwidth=4 tabstop=8
1484  */
int qt_close_existing(fb *ifp)
Definition: if_qt.cpp:446
int qi_ibt_h
Definition: if_qt.cpp:92
ptrdiff_t ssize_t
Definition: common.h:119
HIDDEN int qt_clear(fb *ifp, unsigned char *pp)
Definition: if_qt.cpp:973
unsigned char RGBpixel[3]
Definition: fb.h:73
HIDDEN int qt_configure_window(fb *ifp, int width, int height)
Definition: if_qt.cpp:433
int qi_qheight
Definition: if_qt.cpp:96
HIDDEN int qt_writerect(fb *ifp, int xmin, int ymin, int width, int height, const unsigned char *pp)
Definition: if_qt.cpp:1189
int qi_irt_w
Definition: if_qt.cpp:91
void fb_log(const char *fmt,...) _BU_ATTR_PRINTF12
Definition: fb_log.c:42
void * data
Definition: fb.h:176
bool event(QEvent *event)
Definition: if_qt.cpp:1439
unsigned short cm_green[256]
Definition: fb.h:84
#define BU_CKMAG(_ptr, _magic, _str)
Definition: magic.h:233
HIDDEN int qt_getcursor(fb *ifp, int *mode, int *x, int *y)
Definition: if_qt.cpp:1141
int _qt_open_existing(fb *ifp, int width, int height, void *qapp, void *qwin, void *qpainter, void *draw, void **qimg)
Definition: if_qt.cpp:857
#define FLG_INIT
Definition: if_qt.cpp:114
QApplication * qapp
Definition: if_qt.cpp:67
void fb_make_linear_cmap(ColorMap *cmap)
HIDDEN int qt_refresh(fb *ifp, int x, int y, int w, int h)
Definition: if_qt.cpp:440
int qi_ibt
Definition: if_qt.cpp:86
virtual void render(QPainter *painter)
Definition: if_qt.cpp:1470
ColorMap * qi_rgb_cmap
Definition: if_qt.cpp:103
int qi_itp
Definition: if_qt.cpp:88
#define PIXEL_NULL
Definition: fb.h:89
HIDDEN int qt_close(fb *ifp)
Definition: if_qt.cpp:957
int qi_qwidth
Definition: if_qt.cpp:95
int if_xzoom
zoom factors
Definition: fb_private.h:120
HIDDEN void qt_handle_event(fb *ifp, QEvent *event)
Definition: if_qt.cpp:1246
Header file for the BRL-CAD common definitions.
int if_max_width
max device width
Definition: fb_private.h:111
unsigned char * qi_blumap
Definition: if_qt.cpp:105
HIDDEN int qt_rmap(fb *ifp, ColorMap *cmp)
Definition: if_qt.cpp:599
HIDDEN int qt_setup(fb *ifp, int width, int height)
Definition: if_qt.cpp:680
ustring width
#define HIDDEN
Definition: common.h:86
char * if_type
what "open" calls it
Definition: fb_private.h:110
int if_ycenter
Definition: fb_private.h:123
~QMainWindow()
Definition: if_qt.cpp:1419
void resizeEvent(QResizeEvent *event)
Definition: if_qt.cpp:1432
#define MODE10_SHARED
Definition: if_qt.cpp:125
int qi_xrt
Definition: if_qt.cpp:99
HIDDEN ssize_t qt_read(fb *ifp, int x, int y, unsigned char *pixelp, size_t count)
Definition: if_qt.cpp:1014
if(share_geom)
Definition: nmg_mod.c:3829
#define FLG_LINCMAP
Definition: if_qt.cpp:113
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
COMPLEX data[64]
Definition: fftest.c:34
HIDDEN int qt_help(fb *ifp)
Definition: if_qt.cpp:1230
void * memset(void *s, int c, size_t n)
int qi_iwidth
Definition: if_qt.cpp:82
int qi_itp_h
Definition: if_qt.cpp:93
#define QI_SET(ptr, val)
Definition: if_qt.cpp:110
int alive
Definition: if_qt.cpp:73
#define FB_CK_FB(_p)
Definition: fb.h:100
int qi_xbt
Definition: if_qt.cpp:101
#define QI(ptr)
Definition: if_qt.cpp:109
HIDDEN int qt_open(fb *ifp, const char *file, int width, int height)
Definition: if_qt.cpp:720
HIDDEN int qt_view(fb *ifp, int xcenter, int ycenter, int xzoom, int yzoom)
Definition: if_qt.cpp:1077
#define __BEGIN_DECLS
Definition: common.h:73
#define FB_QT_MAGIC
Definition: magic.h:185
unsigned char * qi_grnmap
Definition: if_qt.cpp:106
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
unsigned long qi_flags
Definition: if_qt.cpp:77
HIDDEN int qt_getview(fb *ifp, int *xcenter, int *ycenter, int *xzoom, int *yzoom)
Definition: if_qt.cpp:1109
unsigned short cm_red[256]
Definition: fb.h:83
int qi_ilf_w
Definition: if_qt.cpp:90
HIDDEN int qt_open_existing(fb *ifp, int width, int height, struct fb_platform_specific *fb_p)
Definition: if_qt.cpp:947
HIDDEN int qt_poll(fb *ifp)
Definition: if_qt.cpp:1319
int if_max_height
max device height
Definition: fb_private.h:112
QWindow * win
Definition: if_qt.cpp:68
HIDDEN int qt_wmap(fb *ifp, const ColorMap *cmp)
Definition: if_qt.cpp:611
void exposeEvent(QExposeEvent *event)
Definition: if_qt.cpp:1425
HIDDEN int qt_readrect(fb *ifp, int xmin, int ymin, int width, int height, unsigned char *pp)
Definition: if_qt.cpp:1150
HIDDEN struct fb_platform_specific * qt_get_fbps(uint32_t magic)
Definition: if_qt.cpp:835
oldeumate l2 magic
Definition: nmg_mod.c:3843
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
QMainWindow(fb *ifp, QImage *image, QWindow *parent=0)
Definition: if_qt.cpp:1409
ustring alpha
HIDDEN void qt_destroy(struct qtinfo *qi)
Definition: if_qt.cpp:712
HIDDEN int qt_free(fb *ifp)
Definition: if_qt.cpp:1339
Definition: fb.h:82
int qi_iheight
Definition: if_qt.cpp:83
int qi_xtp
Definition: if_qt.cpp:100
#define MODE1_MASK
Definition: if_qt.cpp:117
int qi_irt
Definition: if_qt.cpp:87
HIDDEN void qt_updstate(fb *ifp)
Definition: if_qt.cpp:148
int qi_ilf
Definition: if_qt.cpp:85
HIDDEN int qt_cursor(fb *ifp, int mode, int x, int y)
Definition: if_qt.cpp:1132
HIDDEN void qt_put_fbps(struct fb_platform_specific *fbps)
Definition: if_qt.cpp:848
uint32_t magic
Definition: fb.h:176
HIDDEN int qt_flush(fb *ifp)
Definition: if_qt.cpp:1328
HIDDEN ssize_t qt_write(fb *ifp, int x, int y, const unsigned char *pixelp, size_t count)
Definition: if_qt.cpp:1037
#define MODE10_MASK
Definition: if_qt.cpp:123
QImage * qi_image
Definition: if_qt.cpp:69
void renderNow()
Definition: if_qt.cpp:1452
Definition: if_qt.cpp:66
#define MODE1_TRANSIENT
Definition: if_qt.cpp:118
HIDDEN int qt_setcursor(fb *ifp, const unsigned char *bits, int xbits, int ybits, int xorig, int yorig)
Definition: if_qt.cpp:1123
#define MODE1_LINGERING
Definition: if_qt.cpp:119
int qi_xlf
Definition: if_qt.cpp:98
#define __END_DECLS
Definition: common.h:74
unsigned long qi_mode
Definition: if_qt.cpp:76
A frame-buffer IO structure.
Definition: fb_private.h:80
fb qt_interface
Definition: if_qt.cpp:1347
int if_width
current values
Definition: fb_private.h:115
int * drawFb
Definition: if_qt.cpp:74
unsigned short cm_blue[256]
Definition: fb.h:85
HIDDEN void qt_update(fb *ifp, int x1, int y1, int w, int h)
Definition: if_qt.cpp:463
unsigned char * qi_pix
Definition: if_qt.cpp:80
char * if_name
what the user called it
Definition: fb_private.h:114
QPainter * qi_painter
Definition: if_qt.cpp:71
void ** qi_parent_img
Definition: if_qt.cpp:70
void qt_configureWindow(fb *ifp, int width, int height)
Definition: if_qt.cpp:394
int if_xcenter
pan position
Definition: fb_private.h:122
unsigned char * qi_mem
Definition: if_qt.cpp:79
unsigned char * qi_redmap
Definition: if_qt.cpp:104