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