Visual Servoing Platform  version 3.2.1 under development (2019-05-26)
vpDisplayX.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Image display.
33  *
34  * Authors:
35  * Fabien Spindler
36  * Anthony Saunier
37  *
38  *****************************************************************************/
39 
45 #include <visp3/core/vpConfig.h>
46 #ifdef VISP_HAVE_X11
47 
48 #include <cmath> // std::fabs
49 #include <iostream>
50 #include <limits> // numeric_limits
51 #include <stdio.h>
52 #include <stdlib.h>
53 
54 // Display stuff
55 #include <visp3/core/vpDisplay.h>
56 #include <visp3/gui/vpDisplayX.h>
57 
58 // debug / exception
59 #include <visp3/core/vpDebug.h>
60 #include <visp3/core/vpDisplayException.h>
61 
62 // math
63 #include <visp3/core/vpMath.h>
64 
87  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
88  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
89  BShift(0)
90 {
91  setScale(scaleType, I.getWidth(), I.getHeight());
92 
93  init(I);
94 }
95 
119 vpDisplayX::vpDisplayX(vpImage<unsigned char> &I, int x, int y, const std::string &title, vpScaleType scaleType)
120  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
121  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
122  BShift(0)
123 {
124  setScale(scaleType, I.getWidth(), I.getHeight());
125  init(I, x, y, title);
126 }
127 
148  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
149  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
150  BShift(0)
151 {
152  setScale(scaleType, I.getWidth(), I.getHeight());
153  init(I);
154 }
155 
177 vpDisplayX::vpDisplayX(vpImage<vpRGBa> &I, int x, int y, const std::string &title, vpScaleType scaleType)
178  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
179  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
180  BShift(0)
181 {
182  setScale(scaleType, I.getWidth(), I.getHeight());
183  init(I, x, y, title);
184 }
185 
208 vpDisplayX::vpDisplayX(int x, int y, const std::string &title)
209  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
210  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
211  BShift(0)
212 {
213  m_windowXPosition = x;
214  m_windowYPosition = y;
215 
216  m_title = title;
217 }
218 
239  : display(NULL), window(), Ximage(NULL), lut(), context(), screen(0), event(), pixmap(), x_color(NULL),
240  screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
241  BShift(0)
242 {
243 }
244 
249 
258 void vpDisplayX::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
259 {
261 
262  if (x_color == NULL) {
263  // id_unknown = number of predefined colors
264  x_color = new unsigned long[vpColor::id_unknown];
265  }
266 
267  XSizeHints hints;
268  if (x != -1)
269  m_windowXPosition = x;
270  if (y != -1)
271  m_windowYPosition = y;
272 
273  if (!title.empty())
274  m_title = title;
275 
276  // Positionnement de la fenetre dans l'ecran.
277  if ((m_windowXPosition < 0) || (m_windowYPosition < 0)) {
278  hints.flags = 0;
279  } else {
280  hints.flags = USPosition;
281  hints.x = m_windowXPosition;
282  hints.y = m_windowYPosition;
283  }
284 
285  // setup X11 --------------------------------------------------
286  m_width = I.getWidth() / m_scale;
287  m_height = I.getHeight() / m_scale;
288  display = XOpenDisplay(NULL);
289  if (display == NULL) {
290  vpERROR_TRACE("Can't connect display on server %s.\n", XDisplayName(NULL));
291  throw(vpDisplayException(vpDisplayException::connexionError, "Can't connect display on server."));
292  }
293 
294  screen = DefaultScreen(display);
295  lut = DefaultColormap(display, screen);
296  screen_depth = (unsigned int)DefaultDepth(display, screen);
297 
298  if ((window = XCreateSimpleWindow(display, RootWindow(display, screen), m_windowXPosition, m_windowYPosition, m_width,
299  m_height, 1, BlackPixel(display, screen), WhitePixel(display, screen))) == 0) {
300  vpERROR_TRACE("Can't create window.");
301  throw(vpDisplayException(vpDisplayException::cannotOpenWindowError, "Can't create window."));
302  }
303 
304  //
305  // Create color table for 8 and 16 bits screen
306  //
307  if (screen_depth == 8) {
308  lut = XCreateColormap(display, window, DefaultVisual(display, screen), AllocAll);
309  xcolor.flags = DoRed | DoGreen | DoBlue;
310 
311  for (unsigned int i = 0; i < 256; i++) {
312  xcolor.pixel = i;
313  xcolor.red = 256 * i;
314  xcolor.green = 256 * i;
315  xcolor.blue = 256 * i;
316  XStoreColor(display, lut, &xcolor);
317  }
318 
319  XSetWindowColormap(display, window, lut);
320  XInstallColormap(display, lut);
321  }
322 
323  else if (screen_depth == 16) {
324  for (unsigned int i = 0; i < 256; i++) {
325  xcolor.pad = 0;
326  xcolor.red = xcolor.green = xcolor.blue = 256 * i;
327  if (XAllocColor(display, lut, &xcolor) == 0) {
328  vpERROR_TRACE("Can't allocate 256 colors. Only %d allocated.", i);
329  throw(vpDisplayException(vpDisplayException::colorAllocError, "Can't allocate 256 colors."));
330  }
331  colortable[i] = xcolor.pixel;
332  }
333 
334  XSetWindowColormap(display, window, lut);
335  XInstallColormap(display, lut);
336 
337  Visual *visual = DefaultVisual(display, screen);
338  RMask = visual->red_mask;
339  GMask = visual->green_mask;
340  BMask = visual->blue_mask;
341 
342  RShift = 15 - getMsb(RMask); /* these are right-shifts */
343  GShift = 15 - getMsb(GMask);
344  BShift = 15 - getMsb(BMask);
345  }
346 
347  //
348  // Create colors for overlay
349  //
350  switch (screen_depth) {
351  case 8:
352  // Color BLACK and WHITE are set properly by default.
353 
354  // Color LIGHT GRAY.
355  x_color[vpColor::id_lightGray] = 254;
356  xcolor.pixel = x_color[vpColor::id_lightGray];
357  xcolor.red = 256 * 192;
358  xcolor.green = 256 * 192;
359  xcolor.blue = 256 * 192;
360  XStoreColor(display, lut, &xcolor);
361 
362  // Color GRAY.
363  x_color[vpColor::id_gray] = 253;
364  xcolor.pixel = x_color[vpColor::id_gray];
365  xcolor.red = 256 * 128;
366  xcolor.green = 256 * 128;
367  xcolor.blue = 256 * 128;
368  XStoreColor(display, lut, &xcolor);
369 
370  // Color DARK GRAY.
371  x_color[vpColor::id_darkGray] = 252;
372  xcolor.pixel = x_color[vpColor::id_darkGray];
373  xcolor.red = 256 * 64;
374  xcolor.green = 256 * 64;
375  xcolor.blue = 256 * 64;
376  XStoreColor(display, lut, &xcolor);
377 
378  // Color LIGHT RED.
379  x_color[vpColor::id_lightRed] = 251;
380  xcolor.pixel = x_color[vpColor::id_lightRed];
381  xcolor.red = 256 * 255;
382  xcolor.green = 256 * 140;
383  xcolor.blue = 256 * 140;
384  XStoreColor(display, lut, &xcolor);
385 
386  // Color RED.
387  x_color[vpColor::id_red] = 250;
388  xcolor.pixel = x_color[vpColor::id_red];
389  xcolor.red = 256 * 255;
390  xcolor.green = 0;
391  xcolor.blue = 0;
392  XStoreColor(display, lut, &xcolor);
393 
394  // Color DARK RED.
395  x_color[vpColor::id_darkRed] = 249;
396  xcolor.pixel = x_color[vpColor::id_darkRed];
397  xcolor.red = 256 * 128;
398  xcolor.green = 0;
399  xcolor.blue = 0;
400  XStoreColor(display, lut, &xcolor);
401 
402  // Color LIGHT GREEN.
403  x_color[vpColor::id_lightGreen] = 248;
404  xcolor.pixel = x_color[vpColor::id_lightGreen];
405  xcolor.red = 256 * 140;
406  xcolor.green = 256 * 255;
407  xcolor.blue = 256 * 140;
408  XStoreColor(display, lut, &xcolor);
409 
410  // Color GREEN.
411  x_color[vpColor::id_green] = 247;
412  xcolor.pixel = x_color[vpColor::id_green];
413  xcolor.red = 0;
414  xcolor.green = 256 * 255;
415  xcolor.blue = 0;
416  XStoreColor(display, lut, &xcolor);
417 
418  // Color DARK GREEN.
419  x_color[vpColor::id_darkGreen] = 246;
420  xcolor.pixel = x_color[vpColor::id_darkGreen];
421  xcolor.red = 0;
422  xcolor.green = 256 * 128;
423  xcolor.blue = 0;
424  XStoreColor(display, lut, &xcolor);
425 
426  // Color LIGHT BLUE.
427  x_color[vpColor::id_lightBlue] = 245;
428  xcolor.pixel = x_color[vpColor::id_lightBlue];
429  xcolor.red = 256 * 140;
430  xcolor.green = 256 * 140;
431  xcolor.blue = 256 * 255;
432  XStoreColor(display, lut, &xcolor);
433 
434  // Color BLUE.
435  x_color[vpColor::id_blue] = 244;
436  xcolor.pixel = x_color[vpColor::id_blue];
437  xcolor.red = 0;
438  xcolor.green = 0;
439  xcolor.blue = 256 * 255;
440  XStoreColor(display, lut, &xcolor);
441 
442  // Color DARK BLUE.
443  x_color[vpColor::id_darkBlue] = 243;
444  xcolor.pixel = x_color[vpColor::id_darkBlue];
445  xcolor.red = 0;
446  xcolor.green = 0;
447  xcolor.blue = 256 * 128;
448  XStoreColor(display, lut, &xcolor);
449 
450  // Color YELLOW.
451  x_color[vpColor::id_yellow] = 242;
452  xcolor.pixel = x_color[vpColor::id_yellow];
453  xcolor.red = 256 * 255;
454  xcolor.green = 256 * 255;
455  xcolor.blue = 0;
456  XStoreColor(display, lut, &xcolor);
457 
458  // Color ORANGE.
459  x_color[vpColor::id_orange] = 241;
460  xcolor.pixel = x_color[vpColor::id_orange];
461  xcolor.red = 256 * 255;
462  xcolor.green = 256 * 165;
463  xcolor.blue = 0;
464  XStoreColor(display, lut, &xcolor);
465 
466  // Color CYAN.
467  x_color[vpColor::id_cyan] = 240;
468  xcolor.pixel = x_color[vpColor::id_cyan];
469  xcolor.red = 0;
470  xcolor.green = 256 * 255;
471  xcolor.blue = 256 * 255;
472  XStoreColor(display, lut, &xcolor);
473 
474  // Color PURPLE.
475  x_color[vpColor::id_purple] = 239;
476  xcolor.pixel = x_color[vpColor::id_purple];
477  xcolor.red = 256 * 128;
478  xcolor.green = 0;
479  xcolor.blue = 256 * 128;
480  XStoreColor(display, lut, &xcolor);
481 
482  break;
483 
484  case 16:
485  case 24: {
486  xcolor.flags = DoRed | DoGreen | DoBlue;
487 
488  // Couleur BLACK.
489  xcolor.pad = 0;
490  xcolor.red = 0;
491  xcolor.green = 0;
492  xcolor.blue = 0;
493  XAllocColor(display, lut, &xcolor);
494  x_color[vpColor::id_black] = xcolor.pixel;
495 
496  // Couleur WHITE.
497  xcolor.pad = 0;
498  xcolor.red = 256 * 255;
499  xcolor.green = 256 * 255;
500  xcolor.blue = 256 * 255;
501  XAllocColor(display, lut, &xcolor);
502  x_color[vpColor::id_white] = xcolor.pixel;
503 
504  // Couleur LIGHT GRAY.
505  xcolor.pad = 0;
506  xcolor.red = 256 * 192;
507  xcolor.green = 256 * 192;
508  xcolor.blue = 256 * 192;
509  XAllocColor(display, lut, &xcolor);
510  x_color[vpColor::id_lightGray] = xcolor.pixel;
511 
512  // Couleur GRAY.
513  xcolor.pad = 0;
514  xcolor.red = 256 * 128;
515  xcolor.green = 256 * 128;
516  xcolor.blue = 256 * 128;
517  XAllocColor(display, lut, &xcolor);
518  x_color[vpColor::id_gray] = xcolor.pixel;
519 
520  // Couleur DARK GRAY.
521  xcolor.pad = 0;
522  xcolor.red = 256 * 64;
523  xcolor.green = 256 * 64;
524  xcolor.blue = 256 * 64;
525  XAllocColor(display, lut, &xcolor);
526  x_color[vpColor::id_darkGray] = xcolor.pixel;
527 
528  // Couleur LIGHT RED.
529  xcolor.pad = 0;
530  xcolor.red = 256 * 255;
531  xcolor.green = 256 * 140;
532  xcolor.blue = 256 * 140;
533  XAllocColor(display, lut, &xcolor);
534  x_color[vpColor::id_lightRed] = xcolor.pixel;
535 
536  // Couleur RED.
537  xcolor.pad = 0;
538  xcolor.red = 256 * 255;
539  xcolor.green = 0;
540  xcolor.blue = 0;
541  XAllocColor(display, lut, &xcolor);
542  x_color[vpColor::id_red] = xcolor.pixel;
543 
544  // Couleur DARK RED.
545  xcolor.pad = 0;
546  xcolor.red = 256 * 128;
547  xcolor.green = 0;
548  xcolor.blue = 0;
549  XAllocColor(display, lut, &xcolor);
550  x_color[vpColor::id_darkRed] = xcolor.pixel;
551 
552  // Couleur LIGHT GREEN.
553  xcolor.pad = 0;
554  xcolor.red = 256 * 140;
555  xcolor.green = 256 * 255;
556  xcolor.blue = 256 * 140;
557  XAllocColor(display, lut, &xcolor);
558  x_color[vpColor::id_lightGreen] = xcolor.pixel;
559 
560  // Couleur GREEN.
561  xcolor.pad = 0;
562  xcolor.red = 0;
563  xcolor.green = 256 * 255;
564  xcolor.blue = 0;
565  XAllocColor(display, lut, &xcolor);
566  x_color[vpColor::id_green] = xcolor.pixel;
567 
568  // Couleur DARK GREEN.
569  xcolor.pad = 0;
570  xcolor.red = 0;
571  xcolor.green = 256 * 128;
572  xcolor.blue = 0;
573  XAllocColor(display, lut, &xcolor);
574  x_color[vpColor::id_darkGreen] = xcolor.pixel;
575 
576  // Couleur LIGHT Blue.
577  xcolor.pad = 0;
578  xcolor.red = 256 * 140;
579  xcolor.green = 256 * 140;
580  xcolor.blue = 256 * 255;
581  XAllocColor(display, lut, &xcolor);
582  x_color[vpColor::id_lightBlue] = xcolor.pixel;
583 
584  // Couleur BLUE.
585  xcolor.pad = 0;
586  xcolor.red = 0;
587  xcolor.green = 0;
588  xcolor.blue = 256 * 255;
589  XAllocColor(display, lut, &xcolor);
590  x_color[vpColor::id_blue] = xcolor.pixel;
591 
592  // Couleur DARK BLUE.
593  xcolor.pad = 0;
594  xcolor.red = 0;
595  xcolor.green = 0;
596  xcolor.blue = 256 * 128;
597  XAllocColor(display, lut, &xcolor);
598  x_color[vpColor::id_darkBlue] = xcolor.pixel;
599 
600  // Couleur YELLOW.
601  xcolor.pad = 0;
602  xcolor.red = 256 * 255;
603  xcolor.green = 256 * 255;
604  xcolor.blue = 0;
605  XAllocColor(display, lut, &xcolor);
606  x_color[vpColor::id_yellow] = xcolor.pixel;
607 
608  // Couleur ORANGE.
609  xcolor.pad = 0;
610  xcolor.red = 256 * 255;
611  xcolor.green = 256 * 165;
612  xcolor.blue = 0;
613  XAllocColor(display, lut, &xcolor);
614  x_color[vpColor::id_orange] = xcolor.pixel;
615 
616  // Couleur CYAN.
617  xcolor.pad = 0;
618  xcolor.red = 0;
619  xcolor.green = 256 * 255;
620  xcolor.blue = 256 * 255;
621  XAllocColor(display, lut, &xcolor);
622  x_color[vpColor::id_cyan] = xcolor.pixel;
623 
624  // Couleur PURPLE.
625  xcolor.pad = 0;
626  xcolor.red = 256 * 128;
627  xcolor.green = 0;
628  xcolor.blue = 256 * 128;
629  XAllocColor(display, lut, &xcolor);
630  x_color[vpColor::id_purple] = xcolor.pixel;
631  break;
632  }
633  }
634 
635  XSetStandardProperties(display, window, this->m_title.c_str(), this->m_title.c_str(), None, 0, 0, &hints);
636  XMapWindow(display, window);
637  // Selection des evenements.
638  XSelectInput(display, window,
639  ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
640  StructureNotifyMask | PointerMotionMask);
641 
642  // graphic context creation
643  values.plane_mask = AllPlanes;
644  values.fill_style = FillSolid;
645  values.foreground = WhitePixel(display, screen);
646  values.background = BlackPixel(display, screen);
647  context = XCreateGC(display, window, GCPlaneMask | GCFillStyle | GCForeground | GCBackground, &values);
648 
649  if (context == NULL) {
650  vpERROR_TRACE("Can't create graphics context.");
651  throw(vpDisplayException(vpDisplayException::XWindowsError, "Can't create graphics context"));
652  }
653 
654  // Pixmap creation.
655  pixmap = XCreatePixmap(display, window, m_width, m_height, screen_depth);
656 
657  // Hangs when forward X11 is used to send the display to an other computer
658  // do
659  // XNextEvent ( display, &event );
660  // while ( event.xany.type != Expose );
661 
662  {
663  Ximage = XCreateImage(display, DefaultVisual(display, screen), screen_depth, ZPixmap, 0, NULL, m_width, m_height,
664  XBitmapPad(display), 0);
665 
666  Ximage->data = (char *)malloc(m_height * (unsigned int)Ximage->bytes_per_line);
667  ximage_data_init = true;
668  }
670 
671  XStoreName(display, window, m_title.c_str());
672 
673  XSync(display, 1);
674 
675  I.display = this;
676 }
677 
687 void vpDisplayX::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
688 {
690 
691  XSizeHints hints;
692  if (x != -1)
693  m_windowXPosition = x;
694  if (y != -1)
695  m_windowYPosition = y;
696 
697  if (x_color == NULL) {
698  // id_unknown = number of predefined colors
699  x_color = new unsigned long[vpColor::id_unknown];
700  }
701 
702  if (!title.empty())
703  m_title = title;
704 
705  // Positionnement de la fenetre dans l'ecran.
706  if ((m_windowXPosition < 0) || (m_windowYPosition < 0)) {
707  hints.flags = 0;
708  } else {
709  hints.flags = USPosition;
710  hints.x = m_windowXPosition;
711  hints.y = m_windowYPosition;
712  }
713 
714  // setup X11 --------------------------------------------------
715  m_width = I.getWidth() / m_scale;
716  m_height = I.getHeight() / m_scale;
717 
718  if ((display = XOpenDisplay(NULL)) == NULL) {
719  vpERROR_TRACE("Can't connect display on server %s.\n", XDisplayName(NULL));
720  throw(vpDisplayException(vpDisplayException::connexionError, "Can't connect display on server."));
721  }
722 
723  screen = DefaultScreen(display);
724  lut = DefaultColormap(display, screen);
725  screen_depth = (unsigned int)DefaultDepth(display, screen);
726 
727  vpDEBUG_TRACE(1, "Screen depth: %d\n", screen_depth);
728 
729  if ((window = XCreateSimpleWindow(display, RootWindow(display, screen), m_windowXPosition, m_windowYPosition, m_width,
730  m_height, 1, BlackPixel(display, screen), WhitePixel(display, screen))) == 0) {
731  vpERROR_TRACE("Can't create window.");
732  throw(vpDisplayException(vpDisplayException::cannotOpenWindowError, "Can't create window."));
733  }
734 
735  //
736  // Create color table for 8 and 16 bits screen
737  //
738  if (screen_depth == 8) {
739  lut = XCreateColormap(display, window, DefaultVisual(display, screen), AllocAll);
740  xcolor.flags = DoRed | DoGreen | DoBlue;
741 
742  for (unsigned int i = 0; i < 256; i++) {
743  xcolor.pixel = i;
744  xcolor.red = 256 * i;
745  xcolor.green = 256 * i;
746  xcolor.blue = 256 * i;
747  XStoreColor(display, lut, &xcolor);
748  }
749 
750  XSetWindowColormap(display, window, lut);
751  XInstallColormap(display, lut);
752  }
753 
754  else if (screen_depth == 16) {
755  for (unsigned int i = 0; i < 256; i++) {
756  xcolor.pad = 0;
757  xcolor.red = xcolor.green = xcolor.blue = 256 * i;
758  if (XAllocColor(display, lut, &xcolor) == 0) {
759  vpERROR_TRACE("Can't allocate 256 colors. Only %d allocated.", i);
760  throw(vpDisplayException(vpDisplayException::colorAllocError, "Can't allocate 256 colors."));
761  }
762  colortable[i] = xcolor.pixel;
763  }
764 
765  Visual *visual = DefaultVisual(display, screen);
766  RMask = visual->red_mask;
767  GMask = visual->green_mask;
768  BMask = visual->blue_mask;
769 
770  RShift = 15 - getMsb(RMask); /* these are right-shifts */
771  GShift = 15 - getMsb(GMask);
772  BShift = 15 - getMsb(BMask);
773 
774  XSetWindowColormap(display, window, lut);
775  XInstallColormap(display, lut);
776  }
777 
778  //
779  // Create colors for overlay
780  //
781  switch (screen_depth) {
782 
783  case 8:
784  // Color BLACK and WHITE are set properly.
785 
786  // Color LIGHT GRAY.
787  x_color[vpColor::id_lightGray] = 254;
788  xcolor.pixel = x_color[vpColor::id_lightGray];
789  xcolor.red = 256 * 192;
790  xcolor.green = 256 * 192;
791  xcolor.blue = 256 * 192;
792  XStoreColor(display, lut, &xcolor);
793 
794  // Color GRAY.
795  x_color[vpColor::id_gray] = 253;
796  xcolor.pixel = x_color[vpColor::id_gray];
797  xcolor.red = 256 * 128;
798  xcolor.green = 256 * 128;
799  xcolor.blue = 256 * 128;
800  XStoreColor(display, lut, &xcolor);
801 
802  // Color DARK GRAY.
803  x_color[vpColor::id_darkGray] = 252;
804  xcolor.pixel = x_color[vpColor::id_darkGray];
805  xcolor.red = 256 * 64;
806  xcolor.green = 256 * 64;
807  xcolor.blue = 256 * 64;
808  XStoreColor(display, lut, &xcolor);
809 
810  // Color LIGHT RED.
811  x_color[vpColor::id_lightRed] = 251;
812  xcolor.pixel = x_color[vpColor::id_lightRed];
813  xcolor.red = 256 * 255;
814  xcolor.green = 256 * 140;
815  xcolor.blue = 256 * 140;
816  XStoreColor(display, lut, &xcolor);
817 
818  // Color RED.
819  x_color[vpColor::id_red] = 250;
820  xcolor.pixel = x_color[vpColor::id_red];
821  xcolor.red = 256 * 255;
822  xcolor.green = 0;
823  xcolor.blue = 0;
824  XStoreColor(display, lut, &xcolor);
825 
826  // Color DARK RED.
827  x_color[vpColor::id_darkRed] = 249;
828  xcolor.pixel = x_color[vpColor::id_darkRed];
829  xcolor.red = 256 * 128;
830  xcolor.green = 0;
831  xcolor.blue = 0;
832  XStoreColor(display, lut, &xcolor);
833 
834  // Color LIGHT GREEN.
835  x_color[vpColor::id_lightGreen] = 248;
836  xcolor.pixel = x_color[vpColor::id_lightGreen];
837  xcolor.red = 256 * 140;
838  xcolor.green = 256 * 255;
839  xcolor.blue = 256 * 140;
840  XStoreColor(display, lut, &xcolor);
841 
842  // Color GREEN.
843  x_color[vpColor::id_green] = 247;
844  xcolor.pixel = x_color[vpColor::id_green];
845  xcolor.red = 0;
846  xcolor.green = 256 * 255;
847  xcolor.blue = 0;
848  XStoreColor(display, lut, &xcolor);
849 
850  // Color DARK GREEN.
851  x_color[vpColor::id_darkGreen] = 246;
852  xcolor.pixel = x_color[vpColor::id_darkGreen];
853  xcolor.red = 0;
854  xcolor.green = 256 * 128;
855  xcolor.blue = 0;
856  XStoreColor(display, lut, &xcolor);
857 
858  // Color LIGHT BLUE.
859  x_color[vpColor::id_lightBlue] = 245;
860  xcolor.pixel = x_color[vpColor::id_lightBlue];
861  xcolor.red = 256 * 140;
862  xcolor.green = 256 * 140;
863  xcolor.blue = 256 * 255;
864  XStoreColor(display, lut, &xcolor);
865 
866  // Color BLUE.
867  x_color[vpColor::id_blue] = 244;
868  xcolor.pixel = x_color[vpColor::id_blue];
869  xcolor.red = 0;
870  xcolor.green = 0;
871  xcolor.blue = 256 * 255;
872  XStoreColor(display, lut, &xcolor);
873 
874  // Color DARK BLUE.
875  x_color[vpColor::id_darkBlue] = 243;
876  xcolor.pixel = x_color[vpColor::id_darkBlue];
877  xcolor.red = 0;
878  xcolor.green = 0;
879  xcolor.blue = 256 * 128;
880  XStoreColor(display, lut, &xcolor);
881 
882  // Color YELLOW.
883  x_color[vpColor::id_yellow] = 242;
884  xcolor.pixel = x_color[vpColor::id_yellow];
885  xcolor.red = 256 * 255;
886  xcolor.green = 256 * 255;
887  xcolor.blue = 0;
888  XStoreColor(display, lut, &xcolor);
889 
890  // Color ORANGE.
891  x_color[vpColor::id_orange] = 241;
892  xcolor.pixel = x_color[vpColor::id_orange];
893  xcolor.red = 256 * 255;
894  xcolor.green = 256 * 165;
895  xcolor.blue = 0;
896  XStoreColor(display, lut, &xcolor);
897 
898  // Color CYAN.
899  x_color[vpColor::id_cyan] = 240;
900  xcolor.pixel = x_color[vpColor::id_cyan];
901  xcolor.red = 0;
902  xcolor.green = 256 * 255;
903  xcolor.blue = 256 * 255;
904  XStoreColor(display, lut, &xcolor);
905 
906  // Color PURPLE.
907  x_color[vpColor::id_purple] = 239;
908  xcolor.pixel = x_color[vpColor::id_purple];
909  xcolor.red = 256 * 128;
910  xcolor.green = 0;
911  xcolor.blue = 256 * 128;
912  XStoreColor(display, lut, &xcolor);
913 
914  break;
915 
916  case 16:
917  case 24: {
918  xcolor.flags = DoRed | DoGreen | DoBlue;
919 
920  // Couleur BLACK.
921  xcolor.pad = 0;
922  xcolor.red = 0;
923  xcolor.green = 0;
924  xcolor.blue = 0;
925  XAllocColor(display, lut, &xcolor);
926  x_color[vpColor::id_black] = xcolor.pixel;
927 
928  // Couleur WHITE.
929  xcolor.pad = 0;
930  xcolor.red = 256 * 255;
931  xcolor.green = 256 * 255;
932  xcolor.blue = 256 * 255;
933  XAllocColor(display, lut, &xcolor);
934  x_color[vpColor::id_white] = xcolor.pixel;
935 
936  // Couleur LIGHT GRAY.
937  xcolor.pad = 0;
938  xcolor.red = 256 * 192;
939  xcolor.green = 256 * 192;
940  xcolor.blue = 256 * 192;
941  XAllocColor(display, lut, &xcolor);
942  x_color[vpColor::id_lightGray] = xcolor.pixel;
943 
944  // Couleur GRAY.
945  xcolor.pad = 0;
946  xcolor.red = 256 * 128;
947  xcolor.green = 256 * 128;
948  xcolor.blue = 256 * 128;
949  XAllocColor(display, lut, &xcolor);
950  x_color[vpColor::id_gray] = xcolor.pixel;
951 
952  // Couleur DARK GRAY.
953  xcolor.pad = 0;
954  xcolor.red = 256 * 64;
955  xcolor.green = 256 * 64;
956  xcolor.blue = 256 * 64;
957  XAllocColor(display, lut, &xcolor);
958  x_color[vpColor::id_darkGray] = xcolor.pixel;
959 
960  // Couleur LIGHT RED.
961  xcolor.pad = 0;
962  xcolor.red = 256 * 255;
963  xcolor.green = 256 * 140;
964  xcolor.blue = 256 * 140;
965  XAllocColor(display, lut, &xcolor);
966  x_color[vpColor::id_lightRed] = xcolor.pixel;
967 
968  // Couleur RED.
969  xcolor.pad = 0;
970  xcolor.red = 256 * 255;
971  xcolor.green = 0;
972  xcolor.blue = 0;
973  XAllocColor(display, lut, &xcolor);
974  x_color[vpColor::id_red] = xcolor.pixel;
975 
976  // Couleur DARK RED.
977  xcolor.pad = 0;
978  xcolor.red = 256 * 128;
979  xcolor.green = 0;
980  xcolor.blue = 0;
981  XAllocColor(display, lut, &xcolor);
982  x_color[vpColor::id_darkRed] = xcolor.pixel;
983 
984  // Couleur LIGHT GREEN.
985  xcolor.pad = 0;
986  xcolor.red = 256 * 140;
987  xcolor.green = 256 * 255;
988  xcolor.blue = 256 * 140;
989  XAllocColor(display, lut, &xcolor);
990  x_color[vpColor::id_lightGreen] = xcolor.pixel;
991 
992  // Couleur GREEN.
993  xcolor.pad = 0;
994  xcolor.red = 0;
995  xcolor.green = 256 * 255;
996  xcolor.blue = 0;
997  XAllocColor(display, lut, &xcolor);
998  x_color[vpColor::id_green] = xcolor.pixel;
999 
1000  // Couleur DARK GREEN.
1001  xcolor.pad = 0;
1002  xcolor.red = 0;
1003  xcolor.green = 256 * 128;
1004  xcolor.blue = 0;
1005  XAllocColor(display, lut, &xcolor);
1006  x_color[vpColor::id_darkGreen] = xcolor.pixel;
1007 
1008  // Couleur LIGHT Blue.
1009  xcolor.pad = 0;
1010  xcolor.red = 256 * 140;
1011  xcolor.green = 256 * 140;
1012  xcolor.blue = 256 * 255;
1013  XAllocColor(display, lut, &xcolor);
1014  x_color[vpColor::id_lightBlue] = xcolor.pixel;
1015 
1016  // Couleur BLUE.
1017  xcolor.pad = 0;
1018  xcolor.red = 0;
1019  xcolor.green = 0;
1020  xcolor.blue = 256 * 255;
1021  XAllocColor(display, lut, &xcolor);
1022  x_color[vpColor::id_blue] = xcolor.pixel;
1023 
1024  // Couleur DARK BLUE.
1025  xcolor.pad = 0;
1026  xcolor.red = 0;
1027  xcolor.green = 0;
1028  xcolor.blue = 256 * 128;
1029  XAllocColor(display, lut, &xcolor);
1030  x_color[vpColor::id_darkBlue] = xcolor.pixel;
1031 
1032  // Couleur YELLOW.
1033  xcolor.pad = 0;
1034  xcolor.red = 256 * 255;
1035  xcolor.green = 256 * 255;
1036  xcolor.blue = 0;
1037  XAllocColor(display, lut, &xcolor);
1038  x_color[vpColor::id_yellow] = xcolor.pixel;
1039 
1040  // Couleur ORANGE.
1041  xcolor.pad = 0;
1042  xcolor.red = 256 * 255;
1043  xcolor.green = 256 * 165;
1044  xcolor.blue = 0;
1045  XAllocColor(display, lut, &xcolor);
1046  x_color[vpColor::id_orange] = xcolor.pixel;
1047 
1048  // Couleur CYAN.
1049  xcolor.pad = 0;
1050  xcolor.red = 0;
1051  xcolor.green = 256 * 255;
1052  xcolor.blue = 256 * 255;
1053  XAllocColor(display, lut, &xcolor);
1054  x_color[vpColor::id_cyan] = xcolor.pixel;
1055 
1056  // Couleur PURPLE.
1057  xcolor.pad = 0;
1058  xcolor.red = 256 * 128;
1059  xcolor.green = 0;
1060  xcolor.blue = 256 * 128;
1061  XAllocColor(display, lut, &xcolor);
1062  x_color[vpColor::id_purple] = xcolor.pixel;
1063  break;
1064  }
1065  }
1066 
1067  XSetStandardProperties(display, window, this->m_title.c_str(), this->m_title.c_str(), None, 0, 0, &hints);
1068  XMapWindow(display, window);
1069  // Selection des evenements.
1070  XSelectInput(display, window,
1071  ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
1072  StructureNotifyMask | PointerMotionMask);
1073 
1074  // Creation du contexte graphique
1075  values.plane_mask = AllPlanes;
1076  values.fill_style = FillSolid;
1077  values.foreground = WhitePixel(display, screen);
1078  values.background = BlackPixel(display, screen);
1079  context = XCreateGC(display, window, GCPlaneMask | GCFillStyle | GCForeground | GCBackground, &values);
1080 
1081  if (context == NULL) {
1082  vpERROR_TRACE("Can't create graphics context.");
1083  throw(vpDisplayException(vpDisplayException::XWindowsError, "Can't create graphics context"));
1084  }
1085 
1086  // Pixmap creation.
1087  pixmap = XCreatePixmap(display, window, m_width, m_height, screen_depth);
1088 
1089  // Hangs when forward X11 is used to send the display to an other computer
1090  // do
1091  // XNextEvent ( display, &event );
1092  // while ( event.xany.type != Expose );
1093 
1094  {
1095  Ximage = XCreateImage(display, DefaultVisual(display, screen), screen_depth, ZPixmap, 0, NULL, m_width, m_height,
1096  XBitmapPad(display), 0);
1097 
1098  Ximage->data = (char *)malloc(m_height * (unsigned int)Ximage->bytes_per_line);
1099  ximage_data_init = true;
1100  }
1102 
1103  XSync(display, true);
1104 
1105  XStoreName(display, window, m_title.c_str());
1106 
1107  I.display = this;
1108 }
1109 
1117 void vpDisplayX::init(unsigned int w, unsigned int h, int x, int y, const std::string &title)
1118 {
1119  setScale(m_scaleType, w, h);
1120 
1121  if (x_color == NULL) {
1122  // id_unknown = number of predefined colors
1123  x_color = new unsigned long[vpColor::id_unknown];
1124  }
1125  /* setup X11 -------------------------------------------------------------
1126  */
1127  this->m_width = w / m_scale;
1128  this->m_height = h / m_scale;
1129 
1130  XSizeHints hints;
1131 
1132  if (x != -1)
1133  m_windowXPosition = x;
1134  if (y != -1)
1135  m_windowYPosition = y;
1136  // Positionnement de la fenetre dans l'ecran.
1137  if ((m_windowXPosition < 0) || (m_windowYPosition < 0)) {
1138  hints.flags = 0;
1139  } else {
1140  hints.flags = USPosition;
1141  hints.x = m_windowXPosition;
1142  hints.y = m_windowYPosition;
1143  }
1144 
1145  m_title = title;
1146 
1147  if ((display = XOpenDisplay(NULL)) == NULL) {
1148  vpERROR_TRACE("Can't connect display on server %s.\n", XDisplayName(NULL));
1149  throw(vpDisplayException(vpDisplayException::connexionError, "Can't connect display on server."));
1150  }
1151 
1152  screen = DefaultScreen(display);
1153  lut = DefaultColormap(display, screen);
1154  screen_depth = (unsigned int)DefaultDepth(display, screen);
1155 
1156  vpTRACE("Screen depth: %d\n", screen_depth);
1157 
1158  if ((window = XCreateSimpleWindow(display, RootWindow(display, screen), m_windowXPosition, m_windowYPosition, m_width,
1159  m_height, 1, BlackPixel(display, screen), WhitePixel(display, screen))) == 0) {
1160  vpERROR_TRACE("Can't create window.");
1161  throw(vpDisplayException(vpDisplayException::cannotOpenWindowError, "Can't create window."));
1162  }
1163 
1164  //
1165  // Create color table for 8 and 16 bits screen
1166  //
1167  if (screen_depth == 8) {
1168  lut = XCreateColormap(display, window, DefaultVisual(display, screen), AllocAll);
1169  xcolor.flags = DoRed | DoGreen | DoBlue;
1170 
1171  for (unsigned int i = 0; i < 256; i++) {
1172  xcolor.pixel = i;
1173  xcolor.red = 256 * i;
1174  xcolor.green = 256 * i;
1175  xcolor.blue = 256 * i;
1176  XStoreColor(display, lut, &xcolor);
1177  }
1178 
1179  XSetWindowColormap(display, window, lut);
1180  XInstallColormap(display, lut);
1181  }
1182 
1183  else if (screen_depth == 16) {
1184  for (unsigned int i = 0; i < 256; i++) {
1185  xcolor.pad = 0;
1186  xcolor.red = xcolor.green = xcolor.blue = 256 * i;
1187  if (XAllocColor(display, lut, &xcolor) == 0) {
1188  vpERROR_TRACE("Can't allocate 256 colors. Only %d allocated.", i);
1189  throw(vpDisplayException(vpDisplayException::colorAllocError, "Can't allocate 256 colors."));
1190  }
1191  colortable[i] = xcolor.pixel;
1192  }
1193 
1194  XSetWindowColormap(display, window, lut);
1195  XInstallColormap(display, lut);
1196 
1197  Visual *visual = DefaultVisual(display, screen);
1198  RMask = visual->red_mask;
1199  GMask = visual->green_mask;
1200  BMask = visual->blue_mask;
1201 
1202  RShift = 15 - getMsb(RMask); /* these are right-shifts */
1203  GShift = 15 - getMsb(GMask);
1204  BShift = 15 - getMsb(BMask);
1205  }
1206 
1207  vpColor pcolor; // predefined colors
1208 
1209  //
1210  // Create colors for overlay
1211  //
1212  switch (screen_depth) {
1213 
1214  case 8:
1215  // Color BLACK: default set to 0
1216 
1217  // Color WHITE: default set to 255
1218 
1219  // Color LIGHT GRAY.
1220  pcolor = vpColor::lightGray;
1221  xcolor.pixel = 254; // affected to 254
1222  xcolor.red = 256 * pcolor.R;
1223  xcolor.green = 256 * pcolor.G;
1224  xcolor.blue = 256 * pcolor.B;
1225  XStoreColor(display, lut, &xcolor);
1226 
1227  // Color GRAY.
1228  pcolor = vpColor::gray;
1229  xcolor.pixel = 253; // affected to 253
1230  xcolor.red = 256 * pcolor.R;
1231  xcolor.green = 256 * pcolor.G;
1232  xcolor.blue = 256 * pcolor.B;
1233  XStoreColor(display, lut, &xcolor);
1234 
1235  // Color DARK GRAY.
1236  pcolor = vpColor::darkGray;
1237  xcolor.pixel = 252; // affected to 252
1238  xcolor.red = 256 * pcolor.R;
1239  xcolor.green = 256 * pcolor.G;
1240  xcolor.blue = 256 * pcolor.B;
1241  XStoreColor(display, lut, &xcolor);
1242 
1243  // Color LIGHT RED.
1244  pcolor = vpColor::lightRed;
1245  xcolor.pixel = 251; // affected to 251
1246  xcolor.red = 256 * pcolor.R;
1247  xcolor.green = 256 * pcolor.G;
1248  xcolor.blue = 256 * pcolor.B;
1249  XStoreColor(display, lut, &xcolor);
1250 
1251  // Color RED.
1252  pcolor = vpColor::red;
1253  xcolor.pixel = 250; // affected to 250
1254  xcolor.red = 256 * pcolor.R;
1255  xcolor.green = 256 * pcolor.G;
1256  xcolor.blue = 256 * pcolor.B;
1257  XStoreColor(display, lut, &xcolor);
1258 
1259  // Color DARK RED.
1260  pcolor = vpColor::darkRed;
1261  xcolor.pixel = 249; // affected to 249
1262  xcolor.red = 256 * pcolor.R;
1263  xcolor.green = 256 * pcolor.G;
1264  xcolor.blue = 256 * pcolor.B;
1265  XStoreColor(display, lut, &xcolor);
1266 
1267  // Color LIGHT GREEN.
1268  pcolor = vpColor::lightGreen;
1269  xcolor.pixel = 248; // affected to 248
1270  xcolor.red = 256 * pcolor.R;
1271  xcolor.green = 256 * pcolor.G;
1272  xcolor.blue = 256 * pcolor.B;
1273  XStoreColor(display, lut, &xcolor);
1274 
1275  // Color GREEN.
1276  pcolor = vpColor::green;
1277  xcolor.pixel = 247; // affected to 247
1278  xcolor.red = 256 * pcolor.R;
1279  xcolor.green = 256 * pcolor.G;
1280  xcolor.blue = 256 * pcolor.B;
1281  XStoreColor(display, lut, &xcolor);
1282 
1283  // Color DARK GREEN.
1284  pcolor = vpColor::darkGreen;
1285  xcolor.pixel = 246; // affected to 246
1286  xcolor.red = 256 * pcolor.R;
1287  xcolor.green = 256 * pcolor.G;
1288  xcolor.blue = 256 * pcolor.B;
1289  XStoreColor(display, lut, &xcolor);
1290 
1291  // Color LIGHT BLUE.
1292  pcolor = vpColor::lightBlue;
1293  xcolor.pixel = 245; // affected to 245
1294  xcolor.red = 256 * pcolor.R;
1295  xcolor.green = 256 * pcolor.G;
1296  xcolor.blue = 256 * pcolor.B;
1297  XStoreColor(display, lut, &xcolor);
1298 
1299  // Color BLUE.
1300  pcolor = vpColor::blue;
1301  xcolor.pixel = 244; // affected to 244
1302  xcolor.red = 256 * pcolor.R;
1303  xcolor.green = 256 * pcolor.G;
1304  xcolor.blue = 256 * pcolor.B;
1305  XStoreColor(display, lut, &xcolor);
1306 
1307  // Color DARK BLUE.
1308  pcolor = vpColor::darkBlue;
1309  xcolor.pixel = 243; // affected to 243
1310  xcolor.red = 256 * pcolor.R;
1311  xcolor.green = 256 * pcolor.G;
1312  xcolor.blue = 256 * pcolor.B;
1313  XStoreColor(display, lut, &xcolor);
1314 
1315  // Color YELLOW.
1316  pcolor = vpColor::yellow;
1317  xcolor.pixel = 242; // affected to 242
1318  xcolor.red = 256 * pcolor.R;
1319  xcolor.green = 256 * pcolor.G;
1320  xcolor.blue = 256 * pcolor.B;
1321  XStoreColor(display, lut, &xcolor);
1322 
1323  // Color ORANGE.
1324  pcolor = vpColor::orange;
1325  xcolor.pixel = 241; // affected to 241
1326  xcolor.red = 256 * pcolor.R;
1327  xcolor.green = 256 * pcolor.G;
1328  xcolor.blue = 256 * pcolor.B;
1329  XStoreColor(display, lut, &xcolor);
1330 
1331  // Color CYAN.
1332  pcolor = vpColor::cyan;
1333  xcolor.pixel = 240; // affected to 240
1334  xcolor.red = 256 * pcolor.R;
1335  xcolor.green = 256 * pcolor.G;
1336  xcolor.blue = 256 * pcolor.B;
1337  XStoreColor(display, lut, &xcolor);
1338 
1339  // Color PURPLE.
1340  pcolor = vpColor::purple;
1341  xcolor.pixel = 239; // affected to 239
1342  xcolor.red = 256 * pcolor.R;
1343  xcolor.green = 256 * pcolor.G;
1344  xcolor.blue = 256 * pcolor.B;
1345  XStoreColor(display, lut, &xcolor);
1346 
1347  break;
1348 
1349  case 16:
1350  case 24: {
1351  xcolor.flags = DoRed | DoGreen | DoBlue;
1352 
1353  // Couleur BLACK.
1354  pcolor = vpColor::black;
1355  xcolor.pad = 0;
1356  xcolor.red = 256 * pcolor.R;
1357  xcolor.green = 256 * pcolor.G;
1358  xcolor.blue = 256 * pcolor.B;
1359  XAllocColor(display, lut, &xcolor);
1360  x_color[vpColor::id_black] = xcolor.pixel;
1361 
1362  // Color WHITE.
1363  pcolor = vpColor::white;
1364  xcolor.pad = 0;
1365  xcolor.red = 256 * pcolor.R;
1366  xcolor.green = 256 * pcolor.G;
1367  xcolor.blue = 256 * pcolor.B;
1368  XAllocColor(display, lut, &xcolor);
1369  x_color[vpColor::id_white] = xcolor.pixel;
1370 
1371  // Color LIGHT GRAY.
1372  pcolor = vpColor::lightGray;
1373  xcolor.pad = 0;
1374  xcolor.red = 256 * pcolor.R;
1375  xcolor.green = 256 * pcolor.G;
1376  xcolor.blue = 256 * pcolor.B;
1377  XAllocColor(display, lut, &xcolor);
1378  x_color[vpColor::id_lightGray] = xcolor.pixel;
1379 
1380  // Color GRAY.
1381  pcolor = vpColor::gray;
1382  xcolor.pad = 0;
1383  xcolor.red = 256 * pcolor.R;
1384  xcolor.green = 256 * pcolor.G;
1385  xcolor.blue = 256 * pcolor.B;
1386  XAllocColor(display, lut, &xcolor);
1387  x_color[vpColor::id_gray] = xcolor.pixel;
1388 
1389  // Color DARK GRAY.
1390  pcolor = vpColor::darkGray;
1391  xcolor.pad = 0;
1392  xcolor.red = 256 * pcolor.R;
1393  xcolor.green = 256 * pcolor.G;
1394  xcolor.blue = 256 * pcolor.B;
1395  XAllocColor(display, lut, &xcolor);
1396  x_color[vpColor::id_darkGray] = xcolor.pixel;
1397 
1398  // Color LIGHT RED.
1399  pcolor = vpColor::lightRed;
1400  xcolor.pad = 0;
1401  xcolor.red = 256 * pcolor.R;
1402  xcolor.green = 256 * pcolor.G;
1403  xcolor.blue = 256 * pcolor.B;
1404  XAllocColor(display, lut, &xcolor);
1405  x_color[vpColor::id_lightRed] = xcolor.pixel;
1406 
1407  // Color RED.
1408  pcolor = vpColor::red;
1409  xcolor.pad = 0;
1410  xcolor.red = 256 * pcolor.R;
1411  xcolor.green = 256 * pcolor.G;
1412  xcolor.blue = 256 * pcolor.B;
1413  XAllocColor(display, lut, &xcolor);
1414  x_color[vpColor::id_red] = xcolor.pixel;
1415 
1416  // Color DARK RED.
1417  pcolor = vpColor::darkRed;
1418  xcolor.pad = 0;
1419  xcolor.red = 256 * pcolor.R;
1420  xcolor.green = 256 * pcolor.G;
1421  xcolor.blue = 256 * pcolor.B;
1422  XAllocColor(display, lut, &xcolor);
1423  x_color[vpColor::id_darkRed] = xcolor.pixel;
1424 
1425  // Color LIGHT GREEN.
1426  pcolor = vpColor::lightGreen;
1427  xcolor.pad = 0;
1428  xcolor.red = 256 * pcolor.R;
1429  xcolor.green = 256 * pcolor.G;
1430  xcolor.blue = 256 * pcolor.B;
1431  XAllocColor(display, lut, &xcolor);
1432  x_color[vpColor::id_lightGreen] = xcolor.pixel;
1433 
1434  // Color GREEN.
1435  pcolor = vpColor::green;
1436  xcolor.pad = 0;
1437  xcolor.red = 256 * pcolor.R;
1438  xcolor.green = 256 * pcolor.G;
1439  xcolor.blue = 256 * pcolor.B;
1440  XAllocColor(display, lut, &xcolor);
1441  x_color[vpColor::id_green] = xcolor.pixel;
1442 
1443  // Color DARK GREEN.
1444  pcolor = vpColor::darkGreen;
1445  xcolor.pad = 0;
1446  xcolor.red = 256 * pcolor.R;
1447  xcolor.green = 256 * pcolor.G;
1448  xcolor.blue = 256 * pcolor.B;
1449  XAllocColor(display, lut, &xcolor);
1450  x_color[vpColor::id_darkGreen] = xcolor.pixel;
1451 
1452  // Color LIGHT BLUE.
1453  pcolor = vpColor::lightBlue;
1454  xcolor.pad = 0;
1455  xcolor.red = 256 * pcolor.R;
1456  xcolor.green = 256 * pcolor.G;
1457  xcolor.blue = 256 * pcolor.B;
1458  XAllocColor(display, lut, &xcolor);
1459  x_color[vpColor::id_lightBlue] = xcolor.pixel;
1460 
1461  // Color BLUE.
1462  pcolor = vpColor::blue;
1463  xcolor.pad = 0;
1464  xcolor.red = 256 * pcolor.R;
1465  xcolor.green = 256 * pcolor.G;
1466  xcolor.blue = 256 * pcolor.B;
1467  XAllocColor(display, lut, &xcolor);
1468  x_color[vpColor::id_blue] = xcolor.pixel;
1469 
1470  // Color DARK BLUE.
1471  pcolor = vpColor::darkBlue;
1472  xcolor.pad = 0;
1473  xcolor.red = 256 * pcolor.R;
1474  xcolor.green = 256 * pcolor.G;
1475  xcolor.blue = 256 * pcolor.B;
1476  XAllocColor(display, lut, &xcolor);
1477  x_color[vpColor::id_darkBlue] = xcolor.pixel;
1478 
1479  // Color YELLOW.
1480  pcolor = vpColor::yellow;
1481  xcolor.pad = 0;
1482  xcolor.red = 256 * pcolor.R;
1483  xcolor.green = 256 * pcolor.G;
1484  xcolor.blue = 256 * pcolor.B;
1485  XAllocColor(display, lut, &xcolor);
1486  x_color[vpColor::id_yellow] = xcolor.pixel;
1487 
1488  // Color ORANGE.
1489  pcolor = vpColor::orange;
1490  xcolor.pad = 0;
1491  xcolor.red = 256 * pcolor.R;
1492  xcolor.green = 256 * pcolor.G;
1493  xcolor.blue = 256 * pcolor.B;
1494  XAllocColor(display, lut, &xcolor);
1495  x_color[vpColor::id_orange] = xcolor.pixel;
1496 
1497  // Color CYAN.
1498  pcolor = vpColor::cyan;
1499  xcolor.pad = 0;
1500  xcolor.red = 256 * pcolor.R;
1501  xcolor.green = 256 * pcolor.G;
1502  xcolor.blue = 256 * pcolor.B;
1503  XAllocColor(display, lut, &xcolor);
1504  x_color[vpColor::id_cyan] = xcolor.pixel;
1505 
1506  // Color PURPLE.
1507  pcolor = vpColor::purple;
1508  xcolor.pad = 0;
1509  xcolor.red = 256 * pcolor.R;
1510  xcolor.green = 256 * pcolor.G;
1511  xcolor.blue = 256 * pcolor.B;
1512  XAllocColor(display, lut, &xcolor);
1513  x_color[vpColor::id_purple] = xcolor.pixel;
1514  break;
1515  }
1516  }
1517 
1518  XSetStandardProperties(display, window, this->m_title.c_str(), this->m_title.c_str(), None, 0, 0, &hints);
1519  XMapWindow(display, window);
1520  // Selection des evenements.
1521  XSelectInput(display, window,
1522  ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
1523  StructureNotifyMask | PointerMotionMask);
1524 
1525  /* Creation du contexte graphique */
1526  values.plane_mask = AllPlanes;
1527  values.fill_style = FillSolid;
1528  values.foreground = WhitePixel(display, screen);
1529  values.background = BlackPixel(display, screen);
1530  context = XCreateGC(display, window, GCPlaneMask | GCFillStyle | GCForeground | GCBackground, &values);
1531 
1532  if (context == NULL) {
1533  vpERROR_TRACE("Can't create graphics context.");
1534  throw(vpDisplayException(vpDisplayException::XWindowsError, "Can't create graphics context"));
1535  }
1536 
1537  // Pixmap creation.
1538  pixmap = XCreatePixmap(display, window, m_width, m_height, screen_depth);
1539 
1540  // Hangs when forward X11 is used to send the display to an other computer
1541  // do
1542  // XNextEvent ( display, &event );
1543  // while ( event.xany.type != Expose );
1544 
1545  {
1546  Ximage = XCreateImage(display, DefaultVisual(display, screen), screen_depth, ZPixmap, 0, NULL, m_width, m_height,
1547  XBitmapPad(display), 0);
1548 
1549  Ximage->data = (char *)malloc(m_height * (unsigned int)Ximage->bytes_per_line);
1550  ximage_data_init = true;
1551  }
1553 
1554  XSync(display, true);
1555 
1556  XStoreName(display, window, m_title.c_str());
1557 }
1558 
1573 void vpDisplayX::setFont(const std::string &font)
1574 {
1576  if (!font.empty()) {
1577  try {
1578  Font stringfont;
1579  stringfont = XLoadFont(display, font.c_str()); //"-adobe-times-bold-r-normal--18*");
1580  XSetFont(display, context, stringfont);
1581  } catch (...) {
1583  }
1584  }
1585  } else {
1586  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1587  }
1588 }
1589 
1594 void vpDisplayX::setTitle(const std::string &title)
1595 {
1597  m_title = title;
1598  if (!title.empty())
1599  XStoreName(display, window, m_title.c_str());
1600  } else {
1601  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1602  }
1603 }
1604 
1614 void vpDisplayX::setWindowPosition(int winx, int winy)
1615 {
1617  XMoveWindow(display, window, winx, winy);
1618  } else {
1619  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1620  }
1621 }
1622 
1635 {
1637  switch (screen_depth) {
1638  case 8: {
1639  // Correction de l'image de facon a liberer les niveaux de gris
1640  // ROUGE, VERT, BLEU, JAUNE
1641  unsigned char nivGrisMax = 255 - vpColor::id_unknown;
1642  if (m_scale == 1) {
1643  unsigned char *src_8 = (unsigned char *)I.bitmap;
1644  unsigned char *dst_8 = (unsigned char *)Ximage->data;
1645  unsigned int i = 0;
1646  unsigned int size = m_width * m_height;
1647 
1648  while (i < size) {
1649  unsigned char nivGris = src_8[i];
1650  if (nivGris > nivGrisMax)
1651  dst_8[i] = 255;
1652  else
1653  dst_8[i] = nivGris;
1654  i++;
1655  }
1656  } else {
1657  // Correction de l'image de facon a liberer les niveaux de gris
1658  // ROUGE, VERT, BLEU, JAUNE
1659  unsigned char *dst_8 = (unsigned char *)Ximage->data;
1660  unsigned int k = 0;
1661  for (unsigned int i = 0; i < m_height; i++) {
1662  for (unsigned int j = 0; j < m_width; j++) {
1663  unsigned char nivGris = I[i * m_scale][j * m_scale];
1664  if (nivGris > nivGrisMax)
1665  dst_8[k++] = 255;
1666  else
1667  dst_8[k++] = nivGris;
1668  }
1669  }
1670  }
1671 
1672  // Affichage de l'image dans la Pixmap.
1673  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1674  XSetWindowBackgroundPixmap(display, window, pixmap);
1675  break;
1676  }
1677  case 16: {
1678  unsigned int bytes_per_line = (unsigned int)Ximage->bytes_per_line;
1679  if (m_scale == 1) {
1680  for (unsigned int i = 0; i < m_height; i++) {
1681  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
1682  unsigned short *dst_16 = (unsigned short *)dst_8;
1683  for (unsigned int j = 0; j < m_width; j++) {
1684  *(dst_16 + j) = (unsigned short)colortable[I[i][j]];
1685  }
1686  }
1687  } else {
1688  for (unsigned int i = 0; i < m_height; i++) {
1689  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
1690  unsigned short *dst_16 = (unsigned short *)dst_8;
1691  for (unsigned int j = 0; j < m_width; j++) {
1692  *(dst_16 + j) = (unsigned short)colortable[I[i * m_scale][j * m_scale]];
1693  }
1694  }
1695  }
1696 
1697  // Affichage de l'image dans la Pixmap.
1698  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1699  XSetWindowBackgroundPixmap(display, window, pixmap);
1700  break;
1701  }
1702 
1703  case 24:
1704  default: {
1705  unsigned char *dst_32 = (unsigned char *)Ximage->data;
1706  if (m_scale == 1) {
1707  unsigned int size_ = m_width * m_height;
1708  unsigned char *bitmap = I.bitmap;
1709  unsigned char *n = I.bitmap + size_;
1710  // for (unsigned int i = 0; i < size; i++) // suppression de
1711  // l'iterateur i
1712  if (XImageByteOrder(display) == 1) {
1713  // big endian
1714  while (bitmap < n) {
1715  unsigned char val = *(bitmap++);
1716  *(dst_32++) = vpRGBa::alpha_default;
1717  *(dst_32++) = val; // Red
1718  *(dst_32++) = val; // Green
1719  *(dst_32++) = val; // Blue
1720  }
1721  } else {
1722  // little endian
1723  while (bitmap < n) {
1724  unsigned char val = *(bitmap++);
1725  *(dst_32++) = val; // Blue
1726  *(dst_32++) = val; // Green
1727  *(dst_32++) = val; // Red
1728  *(dst_32++) = vpRGBa::alpha_default;
1729  }
1730  }
1731  } else {
1732  if (XImageByteOrder(display) == 1) {
1733  // big endian
1734  for (unsigned int i = 0; i < m_height; i++) {
1735  for (unsigned int j = 0; j < m_width; j++) {
1736  unsigned char val = I[i * m_scale][j * m_scale];
1737  *(dst_32++) = vpRGBa::alpha_default;
1738  *(dst_32++) = val; // Red
1739  *(dst_32++) = val; // Green
1740  *(dst_32++) = val; // Blue
1741  }
1742  }
1743  } else {
1744  // little endian
1745  for (unsigned int i = 0; i < m_height; i++) {
1746  for (unsigned int j = 0; j < m_width; j++) {
1747  unsigned char val = I[i * m_scale][j * m_scale];
1748  *(dst_32++) = val; // Blue
1749  *(dst_32++) = val; // Green
1750  *(dst_32++) = val; // Red
1751  *(dst_32++) = vpRGBa::alpha_default;
1752  }
1753  }
1754  }
1755  }
1756 
1757  // Affichage de l'image dans la Pixmap.
1758  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1759  XSetWindowBackgroundPixmap(display, window, pixmap);
1760  break;
1761  }
1762  }
1763  } else {
1764  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1765  }
1766 }
1779 {
1781  switch (screen_depth) {
1782  case 16: {
1783  vpRGBa *bitmap = I.bitmap;
1784  unsigned int r, g, b;
1785  unsigned int bytes_per_line = (unsigned int)Ximage->bytes_per_line;
1786 
1787  if (m_scale == 1) {
1788  for (unsigned int i = 0; i < m_height; i++) {
1789  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
1790  unsigned short *dst_16 = (unsigned short *)dst_8;
1791  for (unsigned int j = 0; j < m_width; j++) {
1792  r = bitmap->R;
1793  g = bitmap->G;
1794  b = bitmap->B;
1795  *(dst_16 + j) =
1796  (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
1797  bitmap++;
1798  }
1799  }
1800  } else {
1801  for (unsigned int i = 0; i < m_height; i++) {
1802  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
1803  unsigned short *dst_16 = (unsigned short *)dst_8;
1804  for (unsigned int j = 0; j < m_width; j++) {
1805  vpRGBa val = I[i * m_scale][j * m_scale];
1806  r = val.R;
1807  g = val.G;
1808  b = val.B;
1809  *(dst_16 + j) =
1810  (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
1811  bitmap++;
1812  }
1813  }
1814  }
1815 
1816  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1817  XSetWindowBackgroundPixmap(display, window, pixmap);
1818 
1819  break;
1820  }
1821  case 24:
1822  case 32: {
1823  /*
1824  * 32-bit source, 24/32-bit destination
1825  */
1826  unsigned char *dst_32 = NULL;
1827  dst_32 = (unsigned char *)Ximage->data;
1828  if (m_scale == 1) {
1829  vpRGBa *bitmap = I.bitmap;
1830  unsigned int sizeI = m_width * m_height;
1831  if (XImageByteOrder(display) == 1) {
1832  // big endian
1833  for (unsigned int i = 0; i < sizeI; i++) {
1834  *(dst_32++) = bitmap->A;
1835  *(dst_32++) = bitmap->R;
1836  *(dst_32++) = bitmap->G;
1837  *(dst_32++) = bitmap->B;
1838  bitmap++;
1839  }
1840  } else {
1841  // little endian
1842  for (unsigned int i = 0; i < sizeI; i++) {
1843  *(dst_32++) = bitmap->B;
1844  *(dst_32++) = bitmap->G;
1845  *(dst_32++) = bitmap->R;
1846  *(dst_32++) = bitmap->A;
1847  bitmap++;
1848  }
1849  }
1850  } else {
1851  if (XImageByteOrder(display) == 1) {
1852  // big endian
1853  for (unsigned int i = 0; i < m_height; i++) {
1854  for (unsigned int j = 0; j < m_width; j++) {
1855  vpRGBa val = I[i * m_scale][j * m_scale];
1856  *(dst_32++) = val.A;
1857  *(dst_32++) = val.R;
1858  *(dst_32++) = val.G;
1859  *(dst_32++) = val.B;
1860  }
1861  }
1862  } else {
1863  // little endian
1864  for (unsigned int i = 0; i < m_height; i++) {
1865  for (unsigned int j = 0; j < m_width; j++) {
1866  vpRGBa val = I[i * m_scale][j * m_scale];
1867  *(dst_32++) = val.B;
1868  *(dst_32++) = val.G;
1869  *(dst_32++) = val.R;
1870  *(dst_32++) = val.A;
1871  }
1872  }
1873  }
1874  }
1875 
1876  // Affichage de l'image dans la Pixmap.
1877  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1878  XSetWindowBackgroundPixmap(display, window, pixmap);
1879  break;
1880  }
1881  default:
1883  "Unsupported depth (%d bpp) for color display", screen_depth));
1884  }
1885  } else {
1886  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1887  }
1888 }
1889 
1901 void vpDisplayX::displayImage(const unsigned char *bitmap)
1902 {
1903 
1905  unsigned char *dst_32 = (unsigned char *)Ximage->data;
1906  for (unsigned int i = 0; i < m_width * m_height; i++) {
1907  *(dst_32++) = *bitmap; // red component.
1908  *(dst_32++) = *bitmap; // green component.
1909  *(dst_32++) = *bitmap; // blue component.
1910  *(dst_32++) = *bitmap; // luminance component.
1911  bitmap++;
1912  }
1913 
1914  // Affichage de l'image dans la Pixmap.
1915  XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, m_width, m_height);
1916  XSetWindowBackgroundPixmap(display, window, pixmap);
1917  } else {
1918  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
1919  }
1920 }
1921 
1937 void vpDisplayX::displayImageROI(const vpImage<unsigned char> &I, const vpImagePoint &iP, const unsigned int w,
1938  const unsigned int h)
1939 {
1941  switch (screen_depth) {
1942  case 8: {
1943  // Correction de l'image de facon a liberer les niveaux de gris
1944  // ROUGE, VERT, BLEU, JAUNE
1945  unsigned char nivGrisMax = 255 - vpColor::id_unknown;
1946  if (m_scale == 1) {
1947  unsigned char *src_8 = (unsigned char *)I.bitmap;
1948  unsigned char *dst_8 = (unsigned char *)Ximage->data;
1949  unsigned int iwidth = I.getWidth();
1950 
1951  src_8 = src_8 + (int)(iP.get_i() * iwidth + iP.get_j());
1952  dst_8 = dst_8 + (int)(iP.get_i() * m_width + iP.get_j());
1953 
1954  unsigned int i = 0;
1955  while (i < h) {
1956  unsigned int j = 0;
1957  while (j < w) {
1958  unsigned char nivGris = *(src_8 + j);
1959  if (nivGris > nivGrisMax)
1960  *(dst_8 + j) = 255;
1961  else
1962  *(dst_8 + j) = nivGris;
1963  j++;
1964  }
1965  src_8 = src_8 + iwidth;
1966  dst_8 = dst_8 + m_width;
1967  i++;
1968  }
1969 
1970  XPutImage(display, pixmap, context, Ximage, (int)iP.get_u(), (int)iP.get_v(), (int)iP.get_u(), (int)iP.get_v(),
1971  w, h);
1972  } else {
1973  // Correction de l'image de facon a liberer les niveaux de gris
1974  // ROUGE, VERT, BLEU, JAUNE
1975  int i_min = (std::max)((int)ceil(iP.get_i() / m_scale), 0);
1976  int j_min = (std::max)((int)ceil(iP.get_j() / m_scale), 0);
1977  int i_max = (std::min)((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
1978  int j_max = (std::min)((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
1979 
1980  unsigned int i_min_ = (unsigned int)i_min;
1981  unsigned int i_max_ = (unsigned int)i_max;
1982  unsigned int j_min_ = (unsigned int)j_min;
1983  unsigned int j_max_ = (unsigned int)j_max;
1984 
1985  for (unsigned int i = i_min_; i < i_max_; i++) {
1986  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * m_width;
1987  for (unsigned int j = j_min_; j < j_max_; j++) {
1988  unsigned char nivGris = I[i * m_scale][j * m_scale];
1989  if (nivGris > nivGrisMax)
1990  dst_8[j] = 255;
1991  else
1992  dst_8[j] = nivGris;
1993  }
1994  }
1995  XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
1996  }
1997 
1998  // Affichage de l'image dans la Pixmap.
1999  XSetWindowBackgroundPixmap(display, window, pixmap);
2000  break;
2001  }
2002  case 16: {
2003  unsigned int bytes_per_line = (unsigned int)Ximage->bytes_per_line;
2004  if (m_scale == 1) {
2005  for (unsigned int i = (unsigned int)iP.get_i(); i < (unsigned int)(iP.get_i() + h); i++) {
2006  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
2007  unsigned short *dst_16 = (unsigned short *)dst_8;
2008  for (unsigned int j = (unsigned int)iP.get_j(); j < (unsigned int)(iP.get_j() + w); j++) {
2009  *(dst_16 + j) = (unsigned short)colortable[I[i][j]];
2010  }
2011  }
2012 
2013  XPutImage(display, pixmap, context, Ximage, (int)iP.get_u(), (int)iP.get_v(), (int)iP.get_u(), (int)iP.get_v(),
2014  w, h);
2015  } else {
2016  int i_min = (std::max)((int)ceil(iP.get_i() / m_scale), 0);
2017  int j_min = (std::max)((int)ceil(iP.get_j() / m_scale), 0);
2018  int i_max = (std::min)((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
2019  int j_max = (std::min)((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
2020 
2021  unsigned int i_min_ = (unsigned int)i_min;
2022  unsigned int i_max_ = (unsigned int)i_max;
2023  unsigned int j_min_ = (unsigned int)j_min;
2024  unsigned int j_max_ = (unsigned int)j_max;
2025 
2026  for (unsigned int i = i_min_; i < i_max_; i++) {
2027  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
2028  unsigned short *dst_16 = (unsigned short *)dst_8;
2029  for (unsigned int j = j_min_; j < j_max_; j++) {
2030  *(dst_16 + j) = (unsigned short)colortable[I[i * m_scale][j * m_scale]];
2031  }
2032  }
2033 
2034  XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
2035  }
2036 
2037  XSetWindowBackgroundPixmap(display, window, pixmap);
2038  break;
2039  }
2040 
2041  case 24:
2042  default: {
2043  if (m_scale == 1) {
2044  unsigned int iwidth = I.getWidth();
2045  unsigned char *src_8 = I.bitmap + (int)(iP.get_i() * iwidth + iP.get_j());
2046  unsigned char *dst_32 = (unsigned char *)Ximage->data + (int)(iP.get_i() * 4 * m_width + iP.get_j() * 4);
2047 
2048  if (XImageByteOrder(display) == 1) {
2049  // big endian
2050  unsigned int i = 0;
2051  while (i < h) {
2052  unsigned int j = 0;
2053  while (j < w) {
2054  unsigned char val = *(src_8 + j);
2055  *(dst_32 + 4 * j) = vpRGBa::alpha_default;
2056  *(dst_32 + 4 * j + 1) = val;
2057  *(dst_32 + 4 * j + 2) = val;
2058  *(dst_32 + 4 * j + 3) = val;
2059  j++;
2060  }
2061  src_8 = src_8 + iwidth;
2062  dst_32 = dst_32 + 4 * m_width;
2063  i++;
2064  }
2065  } else {
2066  // little endian
2067  unsigned int i = 0;
2068  while (i < h) {
2069  unsigned int j = 0;
2070  while (j < w) {
2071  unsigned char val = *(src_8 + j);
2072  *(dst_32 + 4 * j) = val;
2073  *(dst_32 + 4 * j + 1) = val;
2074  *(dst_32 + 4 * j + 2) = val;
2075  *(dst_32 + 4 * j + 3) = vpRGBa::alpha_default;
2076  j++;
2077  }
2078  src_8 = src_8 + iwidth;
2079  dst_32 = dst_32 + 4 * m_width;
2080  i++;
2081  }
2082  }
2083 
2084  XPutImage(display, pixmap, context, Ximage, (int)iP.get_u(), (int)iP.get_v(), (int)iP.get_u(), (int)iP.get_v(),
2085  w, h);
2086  } else {
2087  int i_min = (std::max)((int)ceil(iP.get_i() / m_scale), 0);
2088  int j_min = (std::max)((int)ceil(iP.get_j() / m_scale), 0);
2089  int i_max = (std::min)((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
2090  int j_max = (std::min)((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
2091 
2092  unsigned int i_min_ = (unsigned int)i_min;
2093  unsigned int i_max_ = (unsigned int)i_max;
2094  unsigned int j_min_ = (unsigned int)j_min;
2095  unsigned int j_max_ = (unsigned int)j_max;
2096 
2097  if (XImageByteOrder(display) == 1) {
2098  // big endian
2099  for (unsigned int i = i_min_; i < i_max_; i++) {
2100  unsigned char *dst_32 = (unsigned char *)Ximage->data + (int)(i * 4 * m_width + j_min_ * 4);
2101  for (unsigned int j = j_min_; j < j_max_; j++) {
2102  unsigned char val = I[i * m_scale][j * m_scale];
2103  *(dst_32++) = vpRGBa::alpha_default;
2104  *(dst_32++) = val;
2105  *(dst_32++) = val;
2106  *(dst_32++) = val;
2107  }
2108  }
2109  } else {
2110  // little endian
2111  for (unsigned int i = i_min_; i < i_max_; i++) {
2112  unsigned char *dst_32 = (unsigned char *)Ximage->data + (int)(i * 4 * m_width + j_min_ * 4);
2113  for (unsigned int j = j_min_; j < j_max_; j++) {
2114  unsigned char val = I[i * m_scale][j * m_scale];
2115  *(dst_32++) = val;
2116  *(dst_32++) = val;
2117  *(dst_32++) = val;
2118  *(dst_32++) = vpRGBa::alpha_default;
2119  }
2120  }
2121  }
2122 
2123  XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
2124  }
2125 
2126  XSetWindowBackgroundPixmap(display, window, pixmap);
2127  break;
2128  }
2129  }
2130  } else {
2131  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2132  }
2133 }
2134 
2150 void vpDisplayX::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, const unsigned int w,
2151  const unsigned int h)
2152 {
2154  switch (screen_depth) {
2155  case 16: {
2156  if (m_scale == 1) {
2157  unsigned int bytes_per_line = (unsigned int)Ximage->bytes_per_line;
2158  for (unsigned int i = (unsigned int)iP.get_i(); i < (unsigned int)(iP.get_i() + h); i++) {
2159  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
2160  unsigned short *dst_16 = (unsigned short *)dst_8;
2161  for (unsigned int j = (unsigned int)iP.get_j(); j < (unsigned int)(iP.get_j() + w); j++) {
2162  vpRGBa val = I[i][j];
2163  unsigned int r = val.R;
2164  unsigned int g = val.G;
2165  unsigned int b = val.B;
2166  *(dst_16 + j) =
2167  (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
2168  }
2169  }
2170  XPutImage(display, pixmap, context, Ximage, (int)iP.get_u(), (int)iP.get_v(), (int)iP.get_u(), (int)iP.get_v(),
2171  w, h);
2172  } else {
2173  unsigned int bytes_per_line = (unsigned int)Ximage->bytes_per_line;
2174  int i_min = (std::max)((int)ceil(iP.get_i() / m_scale), 0);
2175  int j_min = (std::max)((int)ceil(iP.get_j() / m_scale), 0);
2176  int i_max = (std::min)((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
2177  int j_max = (std::min)((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
2178 
2179  unsigned int i_min_ = (unsigned int)i_min;
2180  unsigned int i_max_ = (unsigned int)i_max;
2181  unsigned int j_min_ = (unsigned int)j_min;
2182  unsigned int j_max_ = (unsigned int)j_max;
2183 
2184  for (unsigned int i = i_min_; i < i_max_; i++) {
2185  unsigned char *dst_8 = (unsigned char *)Ximage->data + i * bytes_per_line;
2186  unsigned short *dst_16 = (unsigned short *)dst_8;
2187  for (unsigned int j = j_min_; j < j_max_; j++) {
2188  vpRGBa val = I[i * m_scale][j * m_scale];
2189  unsigned int r = val.R;
2190  unsigned int g = val.G;
2191  unsigned int b = val.B;
2192  *(dst_16 + j) =
2193  (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
2194  }
2195  }
2196  XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
2197  }
2198 
2199  XSetWindowBackgroundPixmap(display, window, pixmap);
2200 
2201  break;
2202  }
2203  case 24:
2204  case 32: {
2205  /*
2206  * 32-bit source, 24/32-bit destination
2207  */
2208 
2209  if (m_scale == 1) {
2210  unsigned char *dst_32 = (unsigned char *)Ximage->data;
2211  vpRGBa *src_32 = I.bitmap;
2212 
2213  unsigned int iwidth = I.getWidth();
2214 
2215  src_32 = src_32 + (int)(iP.get_i() * iwidth + iP.get_j());
2216  dst_32 = dst_32 + (int)(iP.get_i() * 4 * m_width + iP.get_j() * 4);
2217 
2218  unsigned int i = 0;
2219 
2220  if (XImageByteOrder(display) == 1) {
2221  // big endian
2222  while (i < h) {
2223  unsigned int j = 0;
2224  while (j < w) {
2225  *(dst_32 + 4 * j) = (src_32 + j)->A;
2226  *(dst_32 + 4 * j + 1) = (src_32 + j)->R;
2227  *(dst_32 + 4 * j + 2) = (src_32 + j)->G;
2228  *(dst_32 + 4 * j + 3) = (src_32 + j)->B;
2229 
2230  j++;
2231  }
2232  src_32 = src_32 + iwidth;
2233  dst_32 = dst_32 + 4 * m_width;
2234  i++;
2235  }
2236 
2237  } else {
2238  // little endian
2239  while (i < h) {
2240  unsigned int j = 0;
2241  while (j < w) {
2242  *(dst_32 + 4 * j) = (src_32 + j)->B;
2243  *(dst_32 + 4 * j + 1) = (src_32 + j)->G;
2244  *(dst_32 + 4 * j + 2) = (src_32 + j)->R;
2245  *(dst_32 + 4 * j + 3) = (src_32 + j)->A;
2246 
2247  j++;
2248  }
2249  src_32 = src_32 + iwidth;
2250  dst_32 = dst_32 + 4 * m_width;
2251  i++;
2252  }
2253  }
2254 
2255  XPutImage(display, pixmap, context, Ximage, (int)iP.get_u(), (int)iP.get_v(), (int)iP.get_u(), (int)iP.get_v(),
2256  w, h);
2257  } else {
2258  int i_min = (std::max)((int)ceil(iP.get_i() / m_scale), 0);
2259  int j_min = (std::max)((int)ceil(iP.get_j() / m_scale), 0);
2260  int i_max = (std::min)((int)ceil((iP.get_i() + h) / m_scale), (int)m_height);
2261  int j_max = (std::min)((int)ceil((iP.get_j() + w) / m_scale), (int)m_width);
2262 
2263  unsigned int i_min_ = (unsigned int)i_min;
2264  unsigned int i_max_ = (unsigned int)i_max;
2265  unsigned int j_min_ = (unsigned int)j_min;
2266  unsigned int j_max_ = (unsigned int)j_max;
2267 
2268  if (XImageByteOrder(display) == 1) {
2269  // big endian
2270  for (unsigned int i = i_min_; i < i_max_; i++) {
2271  unsigned char *dst_32 = (unsigned char *)Ximage->data + (int)(i * 4 * m_width + j_min_ * 4);
2272  for (unsigned int j = j_min_; j < j_max_; j++) {
2273  vpRGBa val = I[i * m_scale][j * m_scale];
2274  *(dst_32++) = val.A;
2275  *(dst_32++) = val.R;
2276  *(dst_32++) = val.G;
2277  *(dst_32++) = val.B;
2278  }
2279  }
2280  } else {
2281  // little endian
2282  for (unsigned int i = i_min_; i < i_max_; i++) {
2283  unsigned char *dst_32 = (unsigned char *)Ximage->data + (int)(i * 4 * m_width + j_min_ * 4);
2284  for (unsigned int j = j_min_; j < j_max_; j++) {
2285  vpRGBa val = I[i * m_scale][j * m_scale];
2286  *(dst_32++) = val.B;
2287  *(dst_32++) = val.G;
2288  *(dst_32++) = val.R;
2289  *(dst_32++) = val.A;
2290  }
2291  }
2292  }
2293  XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
2294  }
2295 
2296  XSetWindowBackgroundPixmap(display, window, pixmap);
2297  break;
2298  }
2299  default:
2301  "Unsupported depth (%d bpp) for color display", screen_depth));
2302  }
2303  } else {
2304  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2305  }
2306 }
2307 
2316 {
2318  if (ximage_data_init == true)
2319  free(Ximage->data);
2320 
2321  Ximage->data = NULL;
2322  XDestroyImage(Ximage);
2323 
2324  XFreePixmap(display, pixmap);
2325 
2326  XFreeGC(display, context);
2327  XDestroyWindow(display, window);
2328  XCloseDisplay(display);
2329 
2331 
2332  if (x_color != NULL) {
2333  delete[] x_color;
2334  x_color = NULL;
2335  }
2336  }
2337 }
2338 
2345 {
2347  XClearWindow(display, window);
2348  XFlush(display);
2349  } else {
2350  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2351  }
2352 }
2353 
2361 void vpDisplayX::flushDisplayROI(const vpImagePoint &iP, const unsigned int w, const unsigned int h)
2362 {
2364  XClearArea(display, window, (int)(iP.get_u() / m_scale), (int)(iP.get_v() / m_scale), w / m_scale, h / m_scale, 0);
2365  XFlush(display);
2366  } else {
2367  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2368  }
2369 }
2370 
2376 {
2378 
2379  if (color.id < vpColor::id_unknown)
2380  XSetWindowBackground(display, window, x_color[color.id]);
2381  else {
2382  xcolor.pad = 0;
2383  xcolor.red = 256 * color.R;
2384  xcolor.green = 256 * color.G;
2385  xcolor.blue = 256 * color.B;
2386  XAllocColor(display, lut, &xcolor);
2387  XSetForeground(display, context, xcolor.pixel);
2388  }
2389 
2390  XClearWindow(display, window);
2391 
2392  XFreePixmap(display, pixmap);
2393  // Pixmap creation.
2394  pixmap = XCreatePixmap(display, window, m_width, m_height, screen_depth);
2395  } else {
2396  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2397  }
2398 }
2399 
2407 void vpDisplayX::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int w,
2408  unsigned int h, unsigned int thickness)
2409 {
2411  double a = ip2.get_i() - ip1.get_i();
2412  double b = ip2.get_j() - ip1.get_j();
2413  double lg = sqrt(vpMath::sqr(a) + vpMath::sqr(b));
2414 
2415  // if ( ( a==0 ) && ( b==0 ) )
2416  if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
2417  (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
2418  // DisplayCrossLarge(i1,j1,3,col) ;
2419  } else {
2420  a /= lg;
2421  b /= lg;
2422 
2423  vpImagePoint ip3;
2424  ip3.set_i(ip2.get_i() - w * a);
2425  ip3.set_j(ip2.get_j() - w * b);
2426 
2427  vpImagePoint ip4;
2428  ip4.set_i(ip3.get_i() - b * h);
2429  ip4.set_j(ip3.get_j() + a * h);
2430 
2431  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
2432  displayLine(ip2, ip4, color, thickness);
2433 
2434  ip4.set_i(ip3.get_i() + b * h);
2435  ip4.set_j(ip3.get_j() - a * h);
2436 
2437  if (lg > 2 * vpImagePoint::distance(ip2, ip4))
2438  displayLine(ip2, ip4, color, thickness);
2439 
2440  displayLine(ip1, ip2, color, thickness);
2441  }
2442  } else {
2443  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2444  }
2445 }
2446 
2458 void vpDisplayX::displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color)
2459 {
2461  if (color.id < vpColor::id_unknown)
2462  XSetForeground(display, context, x_color[color.id]);
2463  else {
2464  xcolor.pad = 0;
2465  xcolor.red = 256 * color.R;
2466  xcolor.green = 256 * color.G;
2467  xcolor.blue = 256 * color.B;
2468  XAllocColor(display, lut, &xcolor);
2469  XSetForeground(display, context, xcolor.pixel);
2470  }
2471  XDrawString(display, pixmap, context, (int)(ip.get_u() / m_scale), (int)(ip.get_v() / m_scale), text,
2472  (int)strlen(text));
2473  } else {
2474  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2475  }
2476 }
2477 
2487 void vpDisplayX::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
2488  unsigned int thickness)
2489 {
2491  if (thickness == 1)
2492  thickness = 0;
2493  if (color.id < vpColor::id_unknown)
2494  XSetForeground(display, context, x_color[color.id]);
2495  else {
2496  xcolor.pad = 0;
2497  xcolor.red = 256 * color.R;
2498  xcolor.green = 256 * color.G;
2499  xcolor.blue = 256 * color.B;
2500  XAllocColor(display, lut, &xcolor);
2501  XSetForeground(display, context, xcolor.pixel);
2502  }
2503 
2504  XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
2505 
2506  if (fill == false) {
2507  XDrawArc(display, pixmap, context, vpMath::round((center.get_u() - radius) / m_scale),
2508  vpMath::round((center.get_v() - radius) / m_scale), radius * 2 / m_scale, radius * 2 / m_scale, 0,
2509  23040); /* 23040 = 360*64 */
2510  } else {
2511  XFillArc(display, pixmap, context, vpMath::round((center.get_u() - radius) / m_scale),
2512  vpMath::round((center.get_v() - radius) / m_scale), radius * 2 / m_scale, radius * 2 / m_scale, 0,
2513  23040); /* 23040 = 360*64 */
2514  }
2515  } else {
2516  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2517  }
2518 }
2519 
2527 void vpDisplayX::displayCross(const vpImagePoint &ip, unsigned int cross_size, const vpColor &color,
2528  unsigned int thickness)
2529 {
2531  double i = ip.get_i();
2532  double j = ip.get_j();
2533  vpImagePoint ip1, ip2;
2534 
2535  ip1.set_i(i - cross_size / 2);
2536  ip1.set_j(j);
2537  ip2.set_i(i + cross_size / 2);
2538  ip2.set_j(j);
2539  displayLine(ip1, ip2, color, thickness);
2540 
2541  ip1.set_i(i);
2542  ip1.set_j(j - cross_size / 2);
2543  ip2.set_i(i);
2544  ip2.set_j(j + cross_size / 2);
2545 
2546  displayLine(ip1, ip2, color, thickness);
2547  } else {
2548  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2549  }
2550 }
2557 void vpDisplayX::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
2558  unsigned int thickness)
2559 {
2561  if (thickness == 1)
2562  thickness = 0;
2563 
2564  if (color.id < vpColor::id_unknown)
2565  XSetForeground(display, context, x_color[color.id]);
2566  else {
2567  xcolor.pad = 0;
2568  xcolor.red = 256 * color.R;
2569  xcolor.green = 256 * color.G;
2570  xcolor.blue = 256 * color.B;
2571  XAllocColor(display, lut, &xcolor);
2572  XSetForeground(display, context, xcolor.pixel);
2573  }
2574 
2575  XSetLineAttributes(display, context, thickness, LineOnOffDash, CapButt, JoinBevel);
2576 
2577  XDrawLine(display, pixmap, context, vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale),
2578  vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale));
2579  } else {
2580  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2581  }
2582 }
2583 
2590 void vpDisplayX::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
2591  unsigned int thickness)
2592 {
2594  if (thickness == 1)
2595  thickness = 0;
2596 
2597  if (color.id < vpColor::id_unknown)
2598  XSetForeground(display, context, x_color[color.id]);
2599  else {
2600  xcolor.pad = 0;
2601  xcolor.red = 256 * color.R;
2602  xcolor.green = 256 * color.G;
2603  xcolor.blue = 256 * color.B;
2604  XAllocColor(display, lut, &xcolor);
2605  XSetForeground(display, context, xcolor.pixel);
2606  }
2607 
2608  XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
2609 
2610  XDrawLine(display, pixmap, context, vpMath::round(ip1.get_u() / m_scale), vpMath::round(ip1.get_v() / m_scale),
2611  vpMath::round(ip2.get_u() / m_scale), vpMath::round(ip2.get_v() / m_scale));
2612  } else {
2613  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2614  }
2615 }
2616 
2623 void vpDisplayX::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
2624 {
2626  if (color.id < vpColor::id_unknown)
2627  XSetForeground(display, context, x_color[color.id]);
2628  else {
2629  xcolor.pad = 0;
2630  xcolor.red = 256 * color.R;
2631  xcolor.green = 256 * color.G;
2632  xcolor.blue = 256 * color.B;
2633  XAllocColor(display, lut, &xcolor);
2634  XSetForeground(display, context, xcolor.pixel);
2635  }
2636 
2637  if (thickness == 1) {
2638  XDrawPoint(display, pixmap, context, vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale));
2639  } else {
2640  XFillRectangle(display, pixmap, context, vpMath::round(ip.get_u() / m_scale), vpMath::round(ip.get_v() / m_scale),
2641  thickness, thickness);
2642  }
2643 
2644  } else {
2645  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2646  }
2647 }
2648 
2662 void vpDisplayX::displayRectangle(const vpImagePoint &topLeft, unsigned int w, unsigned int h, const vpColor &color,
2663  bool fill, unsigned int thickness)
2664 {
2666  if (thickness == 1)
2667  thickness = 0;
2668  if (color.id < vpColor::id_unknown)
2669  XSetForeground(display, context, x_color[color.id]);
2670  else {
2671  xcolor.pad = 0;
2672  xcolor.red = 256 * color.R;
2673  xcolor.green = 256 * color.G;
2674  xcolor.blue = 256 * color.B;
2675  XAllocColor(display, lut, &xcolor);
2676  XSetForeground(display, context, xcolor.pixel);
2677  }
2678  XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
2679  if (fill == false) {
2680  XDrawRectangle(display, pixmap, context, vpMath::round(topLeft.get_u() / m_scale),
2681  vpMath::round(topLeft.get_v() / m_scale), w / m_scale, h / m_scale);
2682  } else {
2683  XFillRectangle(display, pixmap, context, vpMath::round(topLeft.get_u() / m_scale),
2684  vpMath::round(topLeft.get_v() / m_scale), w / m_scale, h / m_scale);
2685  }
2686  } else {
2687  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2688  }
2689 }
2690 
2703 void vpDisplayX::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight, const vpColor &color,
2704  bool fill, unsigned int thickness)
2705 {
2707  if (thickness == 1)
2708  thickness = 0;
2709  if (color.id < vpColor::id_unknown)
2710  XSetForeground(display, context, x_color[color.id]);
2711  else {
2712  xcolor.pad = 0;
2713  xcolor.red = 256 * color.R;
2714  xcolor.green = 256 * color.G;
2715  xcolor.blue = 256 * color.B;
2716  XAllocColor(display, lut, &xcolor);
2717  XSetForeground(display, context, xcolor.pixel);
2718  }
2719 
2720  XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
2721 
2722  vpImagePoint topLeft_ = topLeft / m_scale;
2723  vpImagePoint bottomRight_ = bottomRight / m_scale;
2724  unsigned int w = (unsigned int)vpMath::round(std::fabs(bottomRight_.get_u() - topLeft_.get_u()));
2725  unsigned int h = (unsigned int)vpMath::round(std::fabs(bottomRight_.get_v() - topLeft_.get_v()));
2726  if (fill == false) {
2727 
2728  XDrawRectangle(display, pixmap, context,
2729  vpMath::round(topLeft_.get_u() < bottomRight_.get_u() ? topLeft_.get_u() : bottomRight_.get_u()),
2730  vpMath::round(topLeft_.get_v() < bottomRight_.get_v() ? topLeft_.get_v() : bottomRight_.get_v()),
2731  w > 0 ? w : 1, h > 0 ? h : 1);
2732  } else {
2733  XFillRectangle(display, pixmap, context,
2734  vpMath::round(topLeft_.get_u() < bottomRight_.get_u() ? topLeft_.get_u() : bottomRight_.get_u()),
2735  vpMath::round(topLeft_.get_v() < bottomRight_.get_v() ? topLeft_.get_v() : bottomRight_.get_v()),
2736  w, h);
2737  }
2738  } else {
2739  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2740  }
2741 }
2742 
2755 void vpDisplayX::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
2756 {
2758  if (thickness == 1)
2759  thickness = 0;
2760  if (color.id < vpColor::id_unknown)
2761  XSetForeground(display, context, x_color[color.id]);
2762  else {
2763  xcolor.pad = 0;
2764  xcolor.red = 256 * color.R;
2765  xcolor.green = 256 * color.G;
2766  xcolor.blue = 256 * color.B;
2767  XAllocColor(display, lut, &xcolor);
2768  XSetForeground(display, context, xcolor.pixel);
2769  }
2770 
2771  XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
2772 
2773  if (fill == false) {
2774  XDrawRectangle(display, pixmap, context, vpMath::round(rectangle.getLeft() / m_scale),
2775  vpMath::round(rectangle.getTop() / m_scale),
2776  (unsigned int)vpMath::round(rectangle.getWidth() / m_scale - 1),
2777  (unsigned int)vpMath::round(rectangle.getHeight() / m_scale - 1));
2778  } else {
2779  XFillRectangle(display, pixmap, context, vpMath::round(rectangle.getLeft() / m_scale),
2780  vpMath::round(rectangle.getTop() / m_scale),
2781  (unsigned int)vpMath::round(rectangle.getWidth() / m_scale),
2782  (unsigned int)vpMath::round(rectangle.getHeight() / m_scale));
2783  }
2784 
2785  } else {
2786  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2787  }
2788 }
2789 
2806 bool vpDisplayX::getClick(bool blocking)
2807 {
2808 
2809  bool ret = false;
2810 
2812  Window rootwin, childwin;
2813  int root_x, root_y, win_x, win_y;
2814  unsigned int modifier;
2815 
2816  // Event testing
2817  if (blocking) {
2818  XCheckMaskEvent(display, ButtonPressMask, &event);
2819  XCheckMaskEvent(display, ButtonReleaseMask, &event);
2820  XMaskEvent(display, ButtonPressMask, &event);
2821  ret = true;
2822  } else {
2823  ret = XCheckMaskEvent(display, ButtonPressMask, &event);
2824  }
2825 
2826  if (ret) {
2827  /* Recuperation de la coordonnee du pixel clique. */
2828  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
2829  }
2830  }
2831  } else {
2832  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2833  }
2834  return ret;
2835 }
2836 
2853 bool vpDisplayX::getClick(vpImagePoint &ip, bool blocking)
2854 {
2855 
2856  bool ret = false;
2858 
2859  Window rootwin, childwin;
2860  int root_x, root_y, win_x, win_y;
2861  unsigned int modifier;
2862  // Event testing
2863  if (blocking) {
2864  XCheckMaskEvent(display, ButtonPressMask, &event);
2865  XCheckMaskEvent(display, ButtonReleaseMask, &event);
2866  XMaskEvent(display, ButtonPressMask, &event);
2867  ret = true;
2868  } else {
2869  ret = XCheckMaskEvent(display, ButtonPressMask, &event);
2870  }
2871 
2872  if (ret) {
2873  // Get mouse position
2874  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
2875  ip.set_u((double)event.xbutton.x * m_scale);
2876  ip.set_v((double)event.xbutton.y * m_scale);
2877  }
2878  }
2879  } else {
2880  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2881  }
2882  return ret;
2883 }
2884 
2905 {
2906 
2907  bool ret = false;
2909 
2910  Window rootwin, childwin;
2911  int root_x, root_y, win_x, win_y;
2912  unsigned int modifier;
2913 
2914  // Event testing
2915  if (blocking) {
2916  XCheckMaskEvent(display, ButtonPressMask, &event);
2917  XCheckMaskEvent(display, ButtonReleaseMask, &event);
2918  XMaskEvent(display, ButtonPressMask, &event);
2919  ret = true;
2920  } else {
2921  ret = XCheckMaskEvent(display, ButtonPressMask, &event);
2922  }
2923 
2924  if (ret) {
2925  // Get mouse position
2926  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
2927  ip.set_u((double)event.xbutton.x * m_scale);
2928  ip.set_v((double)event.xbutton.y * m_scale);
2929  switch (event.xbutton.button) {
2930  case Button1:
2931  button = vpMouseButton::button1;
2932  break;
2933  case Button2:
2934  button = vpMouseButton::button2;
2935  break;
2936  case Button3:
2937  button = vpMouseButton::button3;
2938  break;
2939  }
2940  }
2941  }
2942  } else {
2943  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
2944  }
2945  return ret;
2946 }
2947 
2972 {
2973 
2974  bool ret = false;
2976  Window rootwin, childwin;
2977  int root_x, root_y, win_x, win_y;
2978  unsigned int modifier;
2979 
2980  // Event testing
2981  if (blocking) {
2982  XCheckMaskEvent(display, ButtonPressMask, &event);
2983  XCheckMaskEvent(display, ButtonReleaseMask, &event);
2984  XMaskEvent(display, ButtonReleaseMask, &event);
2985  ret = true;
2986  } else {
2987  ret = XCheckMaskEvent(display, ButtonReleaseMask, &event);
2988  }
2989 
2990  if (ret) {
2991  /* Recuperation de la coordonnee du pixel clique. */
2992  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
2993  ip.set_u((double)event.xbutton.x * m_scale);
2994  ip.set_v((double)event.xbutton.y * m_scale);
2995  switch (event.xbutton.button) {
2996  case Button1:
2997  button = vpMouseButton::button1;
2998  break;
2999  case Button2:
3000  button = vpMouseButton::button2;
3001  break;
3002  case Button3:
3003  button = vpMouseButton::button3;
3004  break;
3005  }
3006  }
3007  }
3008  } else {
3009  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3010  }
3011  return ret;
3012 }
3013 
3014 /*
3015  Gets the displayed image (including the overlay plane)
3016  and returns an RGBa image. If a scale factor is set using setScale(), the
3017  size of the image is the size of the downscaled image.
3018 
3019  \param I : Image to get.
3020 */
3022 {
3024  XImage *xi;
3025 
3026  XCopyArea(display, window, pixmap, context, 0, 0, m_width, m_height, 0, 0);
3027 
3028  xi = XGetImage(display, pixmap, 0, 0, m_width, m_height, AllPlanes, ZPixmap);
3029 
3030  I.resize(m_height, m_width);
3031 
3032  unsigned char *src_32 = NULL;
3033  src_32 = (unsigned char *)xi->data;
3034 
3035  if (screen_depth == 16) {
3036  for (unsigned int i = 0; i < I.getHeight(); i++) {
3037  size_t i_ = i * m_width;
3038  for (unsigned int j = 0; j < m_height; j++) {
3039  size_t ij_ = i_ + j;
3040  unsigned long pixel = XGetPixel(xi, (int)j, (int)i);
3041  I.bitmap[ij_].R = (((pixel & RMask) << RShift) >> 8);
3042  I.bitmap[ij_].G = (((pixel & GMask) << GShift) >> 8);
3043  I.bitmap[ij_].B = (((pixel & BMask) << BShift) >> 8);
3044  // On OSX the bottom/right corner (arround the resizing icon) has
3045  // alpha component with different values than 255. That's why we
3046  // force alpha to vpRGBa::alpha_default
3047  I.bitmap[ij_].A = vpRGBa::alpha_default;
3048  }
3049  }
3050 
3051  } else {
3052  if (XImageByteOrder(display) == 1) {
3053  // big endian
3054  for (unsigned int i = 0; i < m_width * m_height; i++) {
3055  // On OSX the bottom/right corner (arround the resizing icon) has
3056  // alpha component with different values than 255. That's why we
3057  // force alpha to vpRGBa::alpha_default
3058  I.bitmap[i].A = vpRGBa::alpha_default; // src_32[i*4] ;
3059  I.bitmap[i].R = src_32[i * 4 + 1];
3060  I.bitmap[i].G = src_32[i * 4 + 2];
3061  I.bitmap[i].B = src_32[i * 4 + 3];
3062  }
3063  } else {
3064  // little endian
3065  for (unsigned int i = 0; i < m_width * m_height; i++) {
3066  I.bitmap[i].B = src_32[i * 4];
3067  I.bitmap[i].G = src_32[i * 4 + 1];
3068  I.bitmap[i].R = src_32[i * 4 + 2];
3069  // On OSX the bottom/right corner (arround the resizing icon) has
3070  // alpha component with different values than 255. That's why we
3071  // force alpha to vpRGBa::alpha_default
3072  I.bitmap[i].A = vpRGBa::alpha_default; // src_32[i*4 + 3];
3073  }
3074  }
3075  }
3076  XDestroyImage(xi);
3077  } else {
3078  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3079  }
3080 }
3081 
3086 {
3087  Display *display_;
3088  int screen_;
3089  unsigned int depth;
3090 
3091  if ((display_ = XOpenDisplay(NULL)) == NULL) {
3092  throw(vpDisplayException(vpDisplayException::connexionError, "Can't connect display on server %s.",
3093  XDisplayName(NULL)));
3094  }
3095  screen_ = DefaultScreen(display_);
3096  depth = (unsigned int)DefaultDepth(display_, screen_);
3097 
3098  XCloseDisplay(display_);
3099 
3100  return (depth);
3101 }
3102 
3107 void vpDisplayX::getScreenSize(unsigned int &w, unsigned int &h)
3108 {
3109  Display *display_;
3110  int screen_;
3111 
3112  if ((display_ = XOpenDisplay(NULL)) == NULL) {
3113  throw(vpDisplayException(vpDisplayException::connexionError, "Can't connect display on server %s.",
3114  XDisplayName(NULL)));
3115  }
3116  screen_ = DefaultScreen(display_);
3117  w = (unsigned int)DisplayWidth(display_, screen_);
3118  h = (unsigned int)DisplayHeight(display_, screen_);
3119 
3120  XCloseDisplay(display_);
3121 }
3122 
3127 {
3128  unsigned int width, height;
3129  getScreenSize(width, height);
3130  return width;
3131 }
3132 
3137 {
3138  unsigned int width, height;
3139  getScreenSize(width, height);
3140  return height;
3141 }
3142 
3163 bool vpDisplayX::getKeyboardEvent(bool blocking)
3164 {
3165 
3166  bool ret = false;
3167 
3169  // Event testing
3170  if (blocking) {
3171  XMaskEvent(display, KeyPressMask, &event);
3172  ret = true;
3173  } else {
3174  ret = XCheckMaskEvent(display, KeyPressMask, &event);
3175  }
3176  } else {
3177  vpERROR_TRACE("X not initialized ");
3178  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3179  }
3180  return ret;
3181 }
3205 bool vpDisplayX::getKeyboardEvent(std::string &key, bool blocking)
3206 {
3207  bool ret = false;
3208  KeySym keysym;
3209  // int count;
3210  XComposeStatus compose_status;
3211  char buffer;
3212 
3214  // Event testing
3215  if (blocking) {
3216  XMaskEvent(display, KeyPressMask, &event);
3217  /* count = */ XLookupString((XKeyEvent *)&event, &buffer, 1, &keysym, &compose_status);
3218  key = buffer;
3219  ret = true;
3220  } else {
3221  ret = XCheckMaskEvent(display, KeyPressMask, &event);
3222  if (ret) {
3223  /* count = */ XLookupString((XKeyEvent *)&event, &buffer, 1, &keysym, &compose_status);
3224  key = buffer;
3225  }
3226  }
3227  } else {
3228  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3229  }
3230  return ret;
3231 }
3245 {
3246 
3247  bool ret = false;
3249 
3250  Window rootwin, childwin;
3251  int root_x, root_y, win_x, win_y;
3252  unsigned int modifier;
3253  // Event testing
3254  ret = XCheckMaskEvent(display, PointerMotionMask, &event);
3255 
3256  if (ret) {
3257  // Get mouse position
3258  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
3259  ip.set_u((double)event.xbutton.x * m_scale);
3260  ip.set_v((double)event.xbutton.y * m_scale);
3261  }
3262  }
3263  } else {
3264  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3265  }
3266  return ret;
3267 }
3268 
3280 {
3281 
3282  bool ret = false;
3284 
3285  Window rootwin, childwin;
3286  int root_x, root_y, win_x, win_y;
3287  unsigned int modifier;
3288  // Event testing
3289  ret = true;
3290 
3291  if (ret) {
3292  // Get mouse position
3293  if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
3294  ip.set_u((double)win_x * m_scale);
3295  ip.set_v((double)win_y * m_scale);
3296  }
3297  }
3298  } else {
3299  throw(vpDisplayException(vpDisplayException::notInitializedError, "X not initialized"));
3300  }
3301  return ret;
3302 }
3303 
3307 int vpDisplayX::getMsb(unsigned int u32val)
3308 {
3309  int i;
3310 
3311  for (i = 31; i >= 0; --i) {
3312  if (u32val & 0x80000000L)
3313  break;
3314  u32val <<= 1;
3315  }
3316  return i;
3317 }
3318 
3319 #elif !defined(VISP_BUILD_SHARED_LIBS)
3320 // Work arround to avoid warning: libvisp_core.a(vpDisplayX.cpp.o) has no
3321 // symbols
3322 void dummy_vpDisplayX(){};
3323 #endif
unsigned int m_height
Definition: vpDisplay.h:210
void closeDisplay()
void clearDisplay(const vpColor &color=vpColor::white)
vpDisplay * display
Definition: vpImage.h:135
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Definition: vpDisplayX.cpp:258
double getTop() const
Definition: vpRect.h:173
int m_windowYPosition
display position
Definition: vpDisplay.h:208
double get_v() const
Definition: vpImagePoint.h:274
unsigned int getScreenDepth()
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true)
double get_i() const
Definition: vpImagePoint.h:204
unsigned int getWidth() const
Definition: vpImage.h:237
unsigned char B
Blue component.
Definition: vpRGBa.h:150
Type * bitmap
points toward the bitmap
Definition: vpImage.h:134
static const vpColor black
Definition: vpColor.h:174
static const vpColor darkRed
Definition: vpColor.h:181
#define vpERROR_TRACE
Definition: vpDebug.h:393
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
double get_u() const
Definition: vpImagePoint.h:263
static const vpColor lightGray
Definition: vpColor.h:176
void displayImage(const vpImage< unsigned char > &I)
double getHeight() const
Definition: vpRect.h:147
void flushDisplay()
static const vpColor darkBlue
Definition: vpColor.h:187
unsigned char G
Green component.
Definition: vpRGBa.h:149
bool m_displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:204
static const vpColor green
Definition: vpColor.h:183
static int round(const double x)
Definition: vpMath.h:241
double get_j() const
Definition: vpImagePoint.h:215
static const vpColor lightRed
Definition: vpColor.h:179
Definition: vpRGBa.h:66
static const vpColor red
Definition: vpColor.h:180
bool getPointerPosition(vpImagePoint &ip)
vpWin32Window window
The window.
static const vpColor orange
Definition: vpColor.h:190
unsigned int getScreenWidth()
bool getClick(bool blocking=true)
vpColorIdentifier id
Definition: vpColor.h:169
void set_i(const double ii)
Definition: vpImagePoint.h:167
double getWidth() const
Definition: vpRect.h:195
int m_windowXPosition
display position
Definition: vpDisplay.h:206
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, const unsigned int width, const unsigned int height)
static const vpColor cyan
Definition: vpColor.h:189
static const vpColor lightGreen
Definition: vpColor.h:182
unsigned int m_scale
Definition: vpDisplay.h:212
void setScale(vpScaleType scaleType, unsigned int width, unsigned int height)
Definition: vpDisplay.cpp:260
void set_u(const double u)
Definition: vpImagePoint.h:226
#define vpTRACE
Definition: vpDebug.h:416
static double sqr(double x)
Definition: vpMath.h:114
void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)
static void display(const vpImage< unsigned char > &I)
void getScreenSize(unsigned int &width, unsigned int &height)
void set_v(const double v)
Definition: vpImagePoint.h:237
unsigned char A
Additionnal component.
Definition: vpRGBa.h:151
int getMsb(unsigned int u32val)
vpScaleType m_scaleType
Definition: vpDisplay.h:213
bool getKeyboardEvent(bool blocking=true)
std::string m_title
Definition: vpDisplay.h:211
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:863
static const vpColor gray
Definition: vpColor.h:177
void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
void flushDisplayROI(const vpImagePoint &iP, const unsigned int width, const unsigned int height)
void setWindowPosition(int winx, int winy)
virtual ~vpDisplayX()
Definition: vpDisplayX.cpp:248
static const vpColor darkGray
Definition: vpColor.h:178
void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
void set_j(const double jj)
Definition: vpImagePoint.h:178
Error that can be emited by the vpDisplay class and its derivates.
unsigned int m_width
Definition: vpDisplay.h:209
unsigned char R
Red component.
Definition: vpRGBa.h:148
void setTitle(const std::string &title)
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
unsigned int getHeight() const
Definition: vpImage.h:179
Defines a rectangle in the plane.
Definition: vpRect.h:78
void setFont(const std::string &font)
static const vpColor darkGreen
Definition: vpColor.h:184
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static const vpColor yellow
Definition: vpColor.h:188
static const vpColor lightBlue
Definition: vpColor.h:185
static const vpColor purple
Definition: vpColor.h:191
static const vpColor white
Definition: vpColor.h:175
double getLeft() const
Definition: vpRect.h:154
void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
bool getPointerMotionEvent(vpImagePoint &ip)
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
Definition: vpImagePoint.h:285
void getImage(vpImage< vpRGBa > &I)
get the window pixmap and put it in vpRGBa image
unsigned int getScreenHeight()
static const vpColor blue
Definition: vpColor.h:186
void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)