39 #include <visp3/core/vpConfig.h>
49 #include <visp3/core/vpDisplay.h>
50 #include <visp3/gui/vpDisplayX.h>
53 #include <visp3/core/vpDisplayException.h>
56 #include <visp3/core/vpMath.h>
58 #ifndef DOXYGEN_SHOULD_SKIP_THIS
61 #include <X11/Xutil.h>
70 class vpDisplayX::Impl
74 : display(nullptr), window(), Ximage(nullptr), lut(), context(), screen(0), event(), pixmap(), x_color(nullptr),
75 screen_depth(8), xcolor(), values(), ximage_data_init(false), RMask(0), GMask(0), BMask(0), RShift(0), GShift(0),
81 void clearDisplay(
const vpColor &color,
unsigned int width,
unsigned int height)
84 XSetWindowBackground(display, window, x_color[color.
id]);
87 xcolor.red = 256 * color.
R;
88 xcolor.green = 256 * color.
G;
89 xcolor.blue = 256 * color.
B;
90 XAllocColor(display, lut, &xcolor);
91 XSetForeground(display, context, xcolor.pixel);
94 XClearWindow(display, window);
96 XFreePixmap(display, pixmap);
98 pixmap = XCreatePixmap(display, window, width, height, screen_depth);
103 if (ximage_data_init ==
true)
106 Ximage->data =
nullptr;
107 XDestroyImage(Ximage);
109 XFreePixmap(display, pixmap);
111 XFreeGC(display, context);
112 XDestroyWindow(display, window);
113 XCloseDisplay(display);
115 if (x_color !=
nullptr) {
121 void displayText(
const vpImagePoint &ip,
const std::string &text,
const vpColor &color,
unsigned int scale)
124 XSetForeground(display, context, x_color[color.
id]);
127 xcolor.red = 256 * color.
R;
128 xcolor.green = 256 * color.
G;
129 xcolor.blue = 256 * color.
B;
130 XAllocColor(display, lut, &xcolor);
131 XSetForeground(display, context, xcolor.pixel);
133 XDrawString(display, pixmap, context, (
int)(ip.
get_u() / scale), (
int)(ip.
get_v() / scale), text.c_str(),
137 void displayCircle(
const vpImagePoint ¢er,
unsigned int radius,
const vpColor &color,
bool fill,
138 unsigned int thickness,
unsigned int scale)
141 XSetForeground(display, context, x_color[color.
id]);
144 xcolor.red = 256 * color.
R;
145 xcolor.green = 256 * color.
G;
146 xcolor.blue = 256 * color.
B;
147 XAllocColor(display, lut, &xcolor);
148 XSetForeground(display, context, xcolor.pixel);
151 XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
155 vpMath::round((center.
get_v() - radius) / scale), radius * 2 / scale, radius * 2 / scale, 0,
160 vpMath::round((center.
get_v() - radius) / scale), radius * 2 / scale, radius * 2 / scale, 0,
169 XSetForeground(display, context, x_color[color.
id]);
172 xcolor.red = 256 * color.
R;
173 xcolor.green = 256 * color.
G;
174 xcolor.blue = 256 * color.
B;
175 XAllocColor(display, lut, &xcolor);
176 XSetForeground(display, context, xcolor.pixel);
179 XSetLineAttributes(display, context, thickness, LineOnOffDash, CapButt, JoinBevel);
185 void displayImage(
const vpImage<unsigned char> &I,
unsigned int scale,
unsigned int width,
unsigned int height)
187 switch (screen_depth) {
193 unsigned char *src_8 = (
unsigned char *)I.
bitmap;
194 unsigned char *dst_8 = (
unsigned char *)Ximage->data;
196 unsigned int size = width * height;
199 unsigned char nivGris = src_8[i];
200 if (nivGris > nivGrisMax) {
212 unsigned char *dst_8 = (
unsigned char *)Ximage->data;
214 for (
unsigned int i = 0; i < height; i++) {
215 for (
unsigned int j = 0; j < width; j++) {
216 unsigned char nivGris = I[i * scale][j * scale];
217 if (nivGris > nivGrisMax)
220 dst_8[k++] = nivGris;
226 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
227 XSetWindowBackgroundPixmap(display, window, pixmap);
231 unsigned int bytes_per_line = (
unsigned int)Ximage->bytes_per_line;
233 for (
unsigned int i = 0; i < height; i++) {
234 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
235 unsigned short *dst_16 = (
unsigned short *)dst_8;
236 for (
unsigned int j = 0; j < width; j++) {
237 *(dst_16 + j) = (
unsigned short)colortable[I[i][j]];
242 for (
unsigned int i = 0; i < height; i++) {
243 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
244 unsigned short *dst_16 = (
unsigned short *)dst_8;
245 for (
unsigned int j = 0; j < width; j++) {
246 *(dst_16 + j) = (
unsigned short)colortable[I[i * scale][j * scale]];
252 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
253 XSetWindowBackgroundPixmap(display, window, pixmap);
259 unsigned char *dst_32 = (
unsigned char *)Ximage->data;
261 unsigned int size_ = width * height;
262 unsigned char *bitmap = I.
bitmap;
263 unsigned char *n = I.
bitmap + size_;
266 if (XImageByteOrder(display) == 1) {
269 unsigned char val = *(bitmap++);
279 unsigned char val = *(bitmap++);
288 if (XImageByteOrder(display) == 1) {
290 for (
unsigned int i = 0; i < height; i++) {
291 for (
unsigned int j = 0; j < width; j++) {
292 unsigned char val = I[i * scale][j * scale];
302 for (
unsigned int i = 0; i < height; i++) {
303 for (
unsigned int j = 0; j < width; j++) {
304 unsigned char val = I[i * scale][j * scale];
315 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
316 XSetWindowBackgroundPixmap(display, window, pixmap);
322 void displayImage(
const vpImage<vpRGBa> &I,
unsigned int scale,
unsigned int width,
unsigned int height)
324 switch (screen_depth) {
327 unsigned int r, g, b;
328 unsigned int bytes_per_line = (
unsigned int)Ximage->bytes_per_line;
331 for (
unsigned int i = 0; i < height; i++) {
332 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
333 unsigned short *dst_16 = (
unsigned short *)dst_8;
334 for (
unsigned int j = 0; j < width; j++) {
339 (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
345 for (
unsigned int i = 0; i < height; i++) {
346 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
347 unsigned short *dst_16 = (
unsigned short *)dst_8;
348 for (
unsigned int j = 0; j < width; j++) {
349 vpRGBa val = I[i * scale][j * scale];
354 (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
360 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
361 XSetWindowBackgroundPixmap(display, window, pixmap);
370 unsigned char *dst_32 =
nullptr;
371 dst_32 = (
unsigned char *)Ximage->data;
374 unsigned int sizeI = width * height;
375 if (XImageByteOrder(display) == 1) {
377 for (
unsigned int i = 0; i < sizeI; i++) {
378 *(dst_32++) = bitmap->
A;
379 *(dst_32++) = bitmap->
R;
380 *(dst_32++) = bitmap->
G;
381 *(dst_32++) = bitmap->
B;
387 for (
unsigned int i = 0; i < sizeI; i++) {
388 *(dst_32++) = bitmap->
B;
389 *(dst_32++) = bitmap->
G;
390 *(dst_32++) = bitmap->
R;
391 *(dst_32++) = bitmap->
A;
397 if (XImageByteOrder(display) == 1) {
399 for (
unsigned int i = 0; i < height; i++) {
400 for (
unsigned int j = 0; j < width; j++) {
401 vpRGBa val = I[i * scale][j * scale];
411 for (
unsigned int i = 0; i < height; i++) {
412 for (
unsigned int j = 0; j < width; j++) {
413 vpRGBa val = I[i * scale][j * scale];
424 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
425 XSetWindowBackgroundPixmap(display, window, pixmap);
430 "Unsupported depth (%d bpp) for color display", screen_depth));
434 void displayImage(
const unsigned char *bitmap,
unsigned int width,
unsigned int height)
436 unsigned char *dst_32 = (
unsigned char *)Ximage->data;
437 for (
unsigned int i = 0; i < width * height; i++) {
438 *(dst_32++) = *bitmap;
439 *(dst_32++) = *bitmap;
440 *(dst_32++) = *bitmap;
441 *(dst_32++) = *bitmap;
446 XPutImage(display, pixmap, context, Ximage, 0, 0, 0, 0, width, height);
447 XSetWindowBackgroundPixmap(display, window, pixmap);
451 unsigned int scale,
unsigned int width,
unsigned int height)
453 switch (screen_depth) {
459 unsigned char *src_8 = (
unsigned char *)I.
bitmap;
460 unsigned char *dst_8 = (
unsigned char *)Ximage->data;
463 src_8 = src_8 + (int)(iP.
get_i() * iwidth + iP.
get_j());
464 dst_8 = dst_8 + (int)(iP.
get_i() * width + iP.
get_j());
470 unsigned char nivGris = *(src_8 + j);
471 if (nivGris > nivGrisMax)
474 *(dst_8 + j) = nivGris;
477 src_8 = src_8 + iwidth;
478 dst_8 = dst_8 + width;
482 XPutImage(display, pixmap, context, Ximage, (
int)iP.
get_u(), (
int)iP.
get_v(), (
int)iP.
get_u(), (
int)iP.
get_v(),
488 int i_min = std::max<int>((
int)ceil(iP.
get_i() / scale), 0);
489 int j_min = std::max<int>((
int)ceil(iP.
get_j() / scale), 0);
490 int i_max = std::min<int>((
int)ceil((iP.
get_i() + h) / scale), (
int)height);
491 int j_max = std::min<int>((
int)ceil((iP.
get_j() + w) / scale), (
int)width);
493 unsigned int i_min_ = (
unsigned int)i_min;
494 unsigned int i_max_ = (
unsigned int)i_max;
495 unsigned int j_min_ = (
unsigned int)j_min;
496 unsigned int j_max_ = (
unsigned int)j_max;
498 for (
unsigned int i = i_min_; i < i_max_; i++) {
499 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * width;
500 for (
unsigned int j = j_min_; j < j_max_; j++) {
501 unsigned char nivGris = I[i * scale][j * scale];
502 if (nivGris > nivGrisMax)
508 XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
512 XSetWindowBackgroundPixmap(display, window, pixmap);
516 unsigned int bytes_per_line = (
unsigned int)Ximage->bytes_per_line;
518 for (
unsigned int i = (
unsigned int)iP.
get_i(); i < (
unsigned int)(iP.
get_i() + h); i++) {
519 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
520 unsigned short *dst_16 = (
unsigned short *)dst_8;
521 for (
unsigned int j = (
unsigned int)iP.
get_j(); j < (
unsigned int)(iP.
get_j() + w); j++) {
522 *(dst_16 + j) = (
unsigned short)colortable[I[i][j]];
526 XPutImage(display, pixmap, context, Ximage, (
int)iP.
get_u(), (
int)iP.
get_v(), (
int)iP.
get_u(), (
int)iP.
get_v(),
530 int i_min = std::max<int>((
int)ceil(iP.
get_i() / scale), 0);
531 int j_min = std::max<int>((
int)ceil(iP.
get_j() / scale), 0);
532 int i_max = std::min<int>((
int)ceil((iP.
get_i() + h) / scale), (
int)height);
533 int j_max = std::min<int>((
int)ceil((iP.
get_j() + w) / scale), (
int)width);
535 unsigned int i_min_ = (
unsigned int)i_min;
536 unsigned int i_max_ = (
unsigned int)i_max;
537 unsigned int j_min_ = (
unsigned int)j_min;
538 unsigned int j_max_ = (
unsigned int)j_max;
540 for (
unsigned int i = i_min_; i < i_max_; i++) {
541 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
542 unsigned short *dst_16 = (
unsigned short *)dst_8;
543 for (
unsigned int j = j_min_; j < j_max_; j++) {
544 *(dst_16 + j) = (
unsigned short)colortable[I[i * scale][j * scale]];
548 XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
551 XSetWindowBackgroundPixmap(display, window, pixmap);
560 unsigned char *dst_32 = (
unsigned char *)Ximage->data + (
int)(iP.
get_i() * 4 * width + iP.
get_j() * 4);
562 if (XImageByteOrder(display) == 1) {
568 unsigned char val = *(src_8 + j);
570 *(dst_32 + 4 * j + 1) = val;
571 *(dst_32 + 4 * j + 2) = val;
572 *(dst_32 + 4 * j + 3) = val;
575 src_8 = src_8 + iwidth;
576 dst_32 = dst_32 + 4 * width;
586 unsigned char val = *(src_8 + j);
587 *(dst_32 + 4 * j) = val;
588 *(dst_32 + 4 * j + 1) = val;
589 *(dst_32 + 4 * j + 2) = val;
593 src_8 = src_8 + iwidth;
594 dst_32 = dst_32 + 4 * width;
599 XPutImage(display, pixmap, context, Ximage, (
int)iP.
get_u(), (
int)iP.
get_v(), (
int)iP.
get_u(), (
int)iP.
get_v(),
603 int i_min = std::max<int>((
int)ceil(iP.
get_i() / scale), 0);
604 int j_min = std::max<int>((
int)ceil(iP.
get_j() / scale), 0);
605 int i_max = std::min<int>((
int)ceil((iP.
get_i() + h) / scale), (
int)height);
606 int j_max = std::min<int>((
int)ceil((iP.
get_j() + w) / scale), (
int)width);
608 unsigned int i_min_ = (
unsigned int)i_min;
609 unsigned int i_max_ = (
unsigned int)i_max;
610 unsigned int j_min_ = (
unsigned int)j_min;
611 unsigned int j_max_ = (
unsigned int)j_max;
613 if (XImageByteOrder(display) == 1) {
615 for (
unsigned int i = i_min_; i < i_max_; i++) {
616 unsigned char *dst_32 = (
unsigned char *)Ximage->data + (
int)(i * 4 * width + j_min_ * 4);
617 for (
unsigned int j = j_min_; j < j_max_; j++) {
618 unsigned char val = I[i * scale][j * scale];
628 for (
unsigned int i = i_min_; i < i_max_; i++) {
629 unsigned char *dst_32 = (
unsigned char *)Ximage->data + (
int)(i * 4 * width + j_min_ * 4);
630 for (
unsigned int j = j_min_; j < j_max_; j++) {
631 unsigned char val = I[i * scale][j * scale];
640 XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
643 XSetWindowBackgroundPixmap(display, window, pixmap);
650 unsigned int scale,
unsigned int width,
unsigned int height)
652 switch (screen_depth) {
655 unsigned int bytes_per_line = (
unsigned int)Ximage->bytes_per_line;
656 for (
unsigned int i = (
unsigned int)iP.
get_i(); i < (
unsigned int)(iP.
get_i() + h); i++) {
657 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
658 unsigned short *dst_16 = (
unsigned short *)dst_8;
659 for (
unsigned int j = (
unsigned int)iP.
get_j(); j < (
unsigned int)(iP.
get_j() + w); j++) {
661 unsigned int r = val.
R;
662 unsigned int g = val.
G;
663 unsigned int b = val.
B;
665 (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
668 XPutImage(display, pixmap, context, Ximage, (
int)iP.
get_u(), (
int)iP.
get_v(), (
int)iP.
get_u(), (
int)iP.
get_v(),
672 unsigned int bytes_per_line = (
unsigned int)Ximage->bytes_per_line;
673 int i_min = std::max<int>((
int)ceil(iP.
get_i() / scale), 0);
674 int j_min = std::max<int>((
int)ceil(iP.
get_j() / scale), 0);
675 int i_max = std::min<int>((
int)ceil((iP.
get_i() + h) / scale), (
int)height);
676 int j_max = std::min<int>((
int)ceil((iP.
get_j() + w) / scale), (
int)width);
678 unsigned int i_min_ = (
unsigned int)i_min;
679 unsigned int i_max_ = (
unsigned int)i_max;
680 unsigned int j_min_ = (
unsigned int)j_min;
681 unsigned int j_max_ = (
unsigned int)j_max;
683 for (
unsigned int i = i_min_; i < i_max_; i++) {
684 unsigned char *dst_8 = (
unsigned char *)Ximage->data + i * bytes_per_line;
685 unsigned short *dst_16 = (
unsigned short *)dst_8;
686 for (
unsigned int j = j_min_; j < j_max_; j++) {
687 vpRGBa val = I[i * scale][j * scale];
688 unsigned int r = val.
R;
689 unsigned int g = val.
G;
690 unsigned int b = val.
B;
692 (((r << 8) >> RShift) & RMask) | (((g << 8) >> GShift) & GMask) | (((b << 8) >> BShift) & BMask);
695 XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
698 XSetWindowBackgroundPixmap(display, window, pixmap);
709 unsigned char *dst_32 = (
unsigned char *)Ximage->data;
714 src_32 = src_32 + (int)(iP.
get_i() * iwidth + iP.
get_j());
715 dst_32 = dst_32 + (int)(iP.
get_i() * 4 * width + iP.
get_j() * 4);
719 if (XImageByteOrder(display) == 1) {
724 *(dst_32 + 4 * j) = (src_32 + j)->A;
725 *(dst_32 + 4 * j + 1) = (src_32 + j)->R;
726 *(dst_32 + 4 * j + 2) = (src_32 + j)->G;
727 *(dst_32 + 4 * j + 3) = (src_32 + j)->B;
731 src_32 = src_32 + iwidth;
732 dst_32 = dst_32 + 4 * width;
742 *(dst_32 + 4 * j) = (src_32 + j)->B;
743 *(dst_32 + 4 * j + 1) = (src_32 + j)->G;
744 *(dst_32 + 4 * j + 2) = (src_32 + j)->R;
745 *(dst_32 + 4 * j + 3) = (src_32 + j)->A;
749 src_32 = src_32 + iwidth;
750 dst_32 = dst_32 + 4 * width;
755 XPutImage(display, pixmap, context, Ximage, (
int)iP.
get_u(), (
int)iP.
get_v(), (
int)iP.
get_u(), (
int)iP.
get_v(),
759 int i_min = std::max<int>((
int)ceil(iP.
get_i() / scale), 0);
760 int j_min = std::max<int>((
int)ceil(iP.
get_j() / scale), 0);
761 int i_max = std::min<int>((
int)ceil((iP.
get_i() + h) / scale), (
int)height);
762 int j_max = std::min<int>((
int)ceil((iP.
get_j() + w) / scale), (
int)width);
764 unsigned int i_min_ = (
unsigned int)i_min;
765 unsigned int i_max_ = (
unsigned int)i_max;
766 unsigned int j_min_ = (
unsigned int)j_min;
767 unsigned int j_max_ = (
unsigned int)j_max;
769 if (XImageByteOrder(display) == 1) {
771 for (
unsigned int i = i_min_; i < i_max_; i++) {
772 unsigned char *dst_32 = (
unsigned char *)Ximage->data + (
int)(i * 4 * width + j_min_ * 4);
773 for (
unsigned int j = j_min_; j < j_max_; j++) {
774 vpRGBa val = I[i * scale][j * scale];
784 for (
unsigned int i = i_min_; i < i_max_; i++) {
785 unsigned char *dst_32 = (
unsigned char *)Ximage->data + (
int)(i * 4 * width + j_min_ * 4);
786 for (
unsigned int j = j_min_; j < j_max_; j++) {
787 vpRGBa val = I[i * scale][j * scale];
795 XPutImage(display, pixmap, context, Ximage, j_min, i_min, j_min, i_min, j_max_ - j_min_, i_max_ - i_min_);
798 XSetWindowBackgroundPixmap(display, window, pixmap);
803 "Unsupported depth (%d bpp) for color display", screen_depth));
811 XSetForeground(display, context, x_color[color.
id]);
814 xcolor.red = 256 * color.
R;
815 xcolor.green = 256 * color.
G;
816 xcolor.blue = 256 * color.
B;
817 XAllocColor(display, lut, &xcolor);
818 XSetForeground(display, context, xcolor.pixel);
821 XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
827 void displayPoint(
const vpImagePoint &ip,
const vpColor &color,
unsigned int thickness,
unsigned int scale)
830 XSetForeground(display, context, x_color[color.
id]);
833 xcolor.red = 256 * color.
R;
834 xcolor.green = 256 * color.
G;
835 xcolor.blue = 256 * color.
B;
836 XAllocColor(display, lut, &xcolor);
837 XSetForeground(display, context, xcolor.pixel);
840 if (thickness == 1) {
845 thickness, thickness);
849 void displayRectangle(
const vpImagePoint &topLeft,
unsigned int w,
unsigned int h,
const vpColor &color,
bool fill,
850 unsigned int thickness,
unsigned int scale)
853 XSetForeground(display, context, x_color[color.
id]);
856 xcolor.red = 256 * color.
R;
857 xcolor.green = 256 * color.
G;
858 xcolor.blue = 256 * color.
B;
859 XAllocColor(display, lut, &xcolor);
860 XSetForeground(display, context, xcolor.pixel);
862 XSetLineAttributes(display, context, thickness, LineSolid, CapButt, JoinBevel);
875 XClearWindow(display, window);
879 void flushDisplayROI(
const vpImagePoint &iP,
unsigned int w,
unsigned int h,
unsigned int scale)
881 XClearArea(display, window, (
int)(iP.
get_u() / scale), (
int)(iP.
get_v() / scale), w / scale, h / scale, 0);
888 Window rootwin, childwin;
889 int root_x, root_y, win_x, win_y;
890 unsigned int modifier;
894 XCheckMaskEvent(display, ButtonPressMask, &event);
895 XCheckMaskEvent(display, ButtonReleaseMask, &event);
896 XMaskEvent(display, ButtonPressMask, &event);
900 ret = XCheckMaskEvent(display, ButtonPressMask, &event);
905 if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
906 ip.
set_u((
double)event.xbutton.x * scale);
907 ip.
set_v((
double)event.xbutton.y * scale);
908 switch (event.xbutton.button) {
928 Window rootwin, childwin;
929 int root_x, root_y, win_x, win_y;
930 unsigned int modifier;
934 XCheckMaskEvent(display, ButtonPressMask, &event);
935 XCheckMaskEvent(display, ButtonReleaseMask, &event);
936 XMaskEvent(display, ButtonReleaseMask, &event);
940 ret = XCheckMaskEvent(display, ButtonReleaseMask, &event);
945 if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
946 ip.
set_u((
double)event.xbutton.x * scale);
947 ip.
set_v((
double)event.xbutton.y * scale);
948 switch (event.xbutton.button) {
965 void getImage(
vpImage<vpRGBa> &I,
unsigned int width,
unsigned int height)
969 XCopyArea(display, window, pixmap, context, 0, 0, width, height, 0, 0);
971 xi = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap);
975 unsigned char *src_32 =
nullptr;
976 src_32 = (
unsigned char *)xi->data;
978 if (screen_depth == 16) {
979 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
980 size_t i_ = i * width;
981 for (
unsigned int j = 0; j < height; j++) {
983 unsigned long pixel = XGetPixel(xi, (
int)j, (
int)i);
984 I.
bitmap[ij_].R = (((pixel & RMask) << RShift) >> 8);
985 I.
bitmap[ij_].G = (((pixel & GMask) << GShift) >> 8);
986 I.
bitmap[ij_].B = (((pixel & BMask) << BShift) >> 8);
996 if (XImageByteOrder(display) == 1) {
998 for (
unsigned int i = 0; i < width * height; i++) {
1003 I.
bitmap[i].R = src_32[i * 4 + 1];
1004 I.
bitmap[i].G = src_32[i * 4 + 2];
1005 I.
bitmap[i].B = src_32[i * 4 + 3];
1010 for (
unsigned int i = 0; i < width * height; i++) {
1011 I.
bitmap[i].B = src_32[i * 4];
1012 I.
bitmap[i].G = src_32[i * 4 + 1];
1013 I.
bitmap[i].R = src_32[i * 4 + 2];
1024 bool getKeyboardEvent(
bool blocking)
1030 XMaskEvent(display, KeyPressMask, &event);
1034 ret = XCheckMaskEvent(display, KeyPressMask, &event);
1040 bool getKeyboardEvent(std::string &key,
bool blocking)
1045 XComposeStatus compose_status;
1050 XMaskEvent(display, KeyPressMask, &event);
1051 XLookupString((XKeyEvent *)&event, &buffer, 1, &keysym, &compose_status);
1056 ret = XCheckMaskEvent(display, KeyPressMask, &event);
1058 XLookupString((XKeyEvent *)&event, &buffer, 1, &keysym, &compose_status);
1069 int getMsb(
unsigned int u32val)
1073 for (i = 31; i >= 0; --i) {
1074 if (u32val & 0x80000000L)
1081 bool getPointerMotionEvent(
vpImagePoint &ip,
unsigned int scale)
1085 Window rootwin, childwin;
1086 int root_x, root_y, win_x, win_y;
1087 unsigned int modifier;
1089 ret = XCheckMaskEvent(display, PointerMotionMask, &event);
1093 if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
1094 ip.
set_u((
double)event.xbutton.x * scale);
1095 ip.
set_v((
double)event.xbutton.y * scale);
1102 bool getPointerPosition(
vpImagePoint &ip,
unsigned int scale)
1105 Window rootwin, childwin;
1106 int root_x, root_y, win_x, win_y;
1107 unsigned int modifier;
1113 if (XQueryPointer(display, window, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifier)) {
1114 ip.
set_u((
double)win_x * scale);
1115 ip.
set_v((
double)win_y * scale);
1122 unsigned int getScreenDepth()
1128 if ((display_ = XOpenDisplay(
nullptr)) ==
nullptr) {
1130 XDisplayName(
nullptr)));
1132 screen_ = DefaultScreen(display_);
1133 depth = (
unsigned int)DefaultDepth(display_, screen_);
1135 XCloseDisplay(display_);
1140 void getScreenSize(
unsigned int &w,
unsigned int &h)
1145 if ((display_ = XOpenDisplay(
nullptr)) ==
nullptr) {
1147 XDisplayName(
nullptr)));
1149 screen_ = DefaultScreen(display_);
1150 w = (
unsigned int)DisplayWidth(display_, screen_);
1151 h = (
unsigned int)DisplayHeight(display_, screen_);
1153 XCloseDisplay(display_);
1156 void init(
unsigned int win_width,
unsigned int win_height,
int win_x,
int win_y,
const std::string &win_title)
1158 if (x_color ==
nullptr) {
1166 if ((win_x < 0) || (win_y < 0)) {
1170 hints.flags = USPosition;
1175 if ((display = XOpenDisplay(
nullptr)) ==
nullptr) {
1179 screen = DefaultScreen(display);
1180 lut = DefaultColormap(display, screen);
1181 screen_depth = (
unsigned int)DefaultDepth(display, screen);
1183 if ((window = XCreateSimpleWindow(display, RootWindow(display, screen), win_x, win_y, win_width, win_height, 1,
1184 BlackPixel(display, screen), WhitePixel(display, screen))) == 0) {
1191 if (screen_depth == 8) {
1192 lut = XCreateColormap(display, window, DefaultVisual(display, screen), AllocAll);
1193 xcolor.flags = DoRed | DoGreen | DoBlue;
1195 for (
unsigned int i = 0; i < 256; i++) {
1197 xcolor.red = 256 * i;
1198 xcolor.green = 256 * i;
1199 xcolor.blue = 256 * i;
1200 XStoreColor(display, lut, &xcolor);
1203 XSetWindowColormap(display, window, lut);
1204 XInstallColormap(display, lut);
1207 else if (screen_depth == 16) {
1208 for (
unsigned int i = 0; i < 256; i++) {
1210 xcolor.red = xcolor.green = xcolor.blue = 256 * i;
1211 if (XAllocColor(display, lut, &xcolor) == 0) {
1214 colortable[i] = xcolor.pixel;
1217 XSetWindowColormap(display, window, lut);
1218 XInstallColormap(display, lut);
1220 Visual *visual = DefaultVisual(display, screen);
1221 RMask = visual->red_mask;
1222 GMask = visual->green_mask;
1223 BMask = visual->blue_mask;
1225 RShift = 15 - getMsb(RMask);
1226 GShift = 15 - getMsb(GMask);
1227 BShift = 15 - getMsb(BMask);
1235 switch (screen_depth) {
1245 xcolor.
red = 256 * 192;
1246 xcolor.
green = 256 * 192;
1247 xcolor.
blue = 256 * 192;
1248 XStoreColor(display, lut, &xcolor);
1253 xcolor.red = 256 * 128;
1254 xcolor.green = 256 * 128;
1255 xcolor.blue = 256 * 128;
1256 XStoreColor(display, lut, &xcolor);
1261 xcolor.red = 256 * 64;
1262 xcolor.green = 256 * 64;
1263 xcolor.blue = 256 * 64;
1264 XStoreColor(display, lut, &xcolor);
1269 xcolor.red = 256 * 255;
1270 xcolor.green = 256 * 140;
1271 xcolor.blue = 256 * 140;
1272 XStoreColor(display, lut, &xcolor);
1277 xcolor.red = 256 * 255;
1280 XStoreColor(display, lut, &xcolor);
1285 xcolor.red = 256 * 128;
1288 XStoreColor(display, lut, &xcolor);
1293 xcolor.red = 256 * 140;
1294 xcolor.green = 256 * 255;
1295 xcolor.blue = 256 * 140;
1296 XStoreColor(display, lut, &xcolor);
1302 xcolor.green = 256 * 255;
1304 XStoreColor(display, lut, &xcolor);
1310 xcolor.green = 256 * 128;
1312 XStoreColor(display, lut, &xcolor);
1317 xcolor.red = 256 * 140;
1318 xcolor.green = 256 * 140;
1319 xcolor.blue = 256 * 255;
1320 XStoreColor(display, lut, &xcolor);
1327 xcolor.blue = 256 * 255;
1328 XStoreColor(display, lut, &xcolor);
1335 xcolor.blue = 256 * 128;
1336 XStoreColor(display, lut, &xcolor);
1341 xcolor.red = 256 * 255;
1342 xcolor.green = 256 * 255;
1344 XStoreColor(display, lut, &xcolor);
1349 xcolor.red = 256 * 255;
1350 xcolor.green = 256 * 165;
1352 XStoreColor(display, lut, &xcolor);
1358 xcolor.green = 256 * 255;
1359 xcolor.blue = 256 * 255;
1360 XStoreColor(display, lut, &xcolor);
1365 xcolor.red = 256 * 128;
1367 xcolor.blue = 256 * 128;
1368 XStoreColor(display, lut, &xcolor);
1375 xcolor.flags = DoRed | DoGreen | DoBlue;
1380 xcolor.
red = 256 * pcolor.
R;
1381 xcolor.green = 256 * pcolor.
G;
1382 xcolor.blue = 256 * pcolor.
B;
1383 XAllocColor(display, lut, &xcolor);
1389 xcolor.
red = 256 * pcolor.
R;
1390 xcolor.green = 256 * pcolor.
G;
1391 xcolor.blue = 256 * pcolor.
B;
1392 XAllocColor(display, lut, &xcolor);
1398 xcolor.
red = 256 * pcolor.
R;
1399 xcolor.green = 256 * pcolor.
G;
1400 xcolor.blue = 256 * pcolor.
B;
1401 XAllocColor(display, lut, &xcolor);
1407 xcolor.
red = 256 * pcolor.
R;
1408 xcolor.green = 256 * pcolor.
G;
1409 xcolor.blue = 256 * pcolor.
B;
1410 XAllocColor(display, lut, &xcolor);
1416 xcolor.
red = 256 * pcolor.
R;
1417 xcolor.green = 256 * pcolor.
G;
1418 xcolor.blue = 256 * pcolor.
B;
1419 XAllocColor(display, lut, &xcolor);
1425 xcolor.
red = 256 * pcolor.
R;
1426 xcolor.green = 256 * pcolor.
G;
1427 xcolor.blue = 256 * pcolor.
B;
1428 XAllocColor(display, lut, &xcolor);
1434 xcolor.
red = 256 * pcolor.
R;
1435 xcolor.green = 256 * pcolor.
G;
1436 xcolor.blue = 256 * pcolor.
B;
1437 XAllocColor(display, lut, &xcolor);
1443 xcolor.
red = 256 * pcolor.
R;
1444 xcolor.green = 256 * pcolor.
G;
1445 xcolor.blue = 256 * pcolor.
B;
1446 XAllocColor(display, lut, &xcolor);
1452 xcolor.
red = 256 * pcolor.
R;
1453 xcolor.green = 256 * pcolor.
G;
1454 xcolor.blue = 256 * pcolor.
B;
1455 XAllocColor(display, lut, &xcolor);
1461 xcolor.
red = 256 * pcolor.
R;
1462 xcolor.green = 256 * pcolor.
G;
1463 xcolor.blue = 256 * pcolor.
B;
1464 XAllocColor(display, lut, &xcolor);
1470 xcolor.
red = 256 * pcolor.
R;
1471 xcolor.green = 256 * pcolor.
G;
1472 xcolor.blue = 256 * pcolor.
B;
1473 XAllocColor(display, lut, &xcolor);
1479 xcolor.
red = 256 * pcolor.
R;
1480 xcolor.green = 256 * pcolor.
G;
1481 xcolor.blue = 256 * pcolor.
B;
1482 XAllocColor(display, lut, &xcolor);
1488 xcolor.
red = 256 * pcolor.
R;
1489 xcolor.green = 256 * pcolor.
G;
1490 xcolor.blue = 256 * pcolor.
B;
1491 XAllocColor(display, lut, &xcolor);
1497 xcolor.
red = 256 * pcolor.
R;
1498 xcolor.green = 256 * pcolor.
G;
1499 xcolor.blue = 256 * pcolor.
B;
1500 XAllocColor(display, lut, &xcolor);
1506 xcolor.
red = 256 * pcolor.
R;
1507 xcolor.green = 256 * pcolor.
G;
1508 xcolor.blue = 256 * pcolor.
B;
1509 XAllocColor(display, lut, &xcolor);
1515 xcolor.
red = 256 * pcolor.
R;
1516 xcolor.green = 256 * pcolor.
G;
1517 xcolor.blue = 256 * pcolor.
B;
1518 XAllocColor(display, lut, &xcolor);
1524 xcolor.
red = 256 * pcolor.
R;
1525 xcolor.green = 256 * pcolor.
G;
1526 xcolor.blue = 256 * pcolor.
B;
1527 XAllocColor(display, lut, &xcolor);
1533 xcolor.
red = 256 * pcolor.
R;
1534 xcolor.green = 256 * pcolor.
G;
1535 xcolor.blue = 256 * pcolor.
B;
1536 XAllocColor(display, lut, &xcolor);
1542 XSetStandardProperties(display, window, win_title.c_str(), win_title.c_str(), None, 0, 0, &hints);
1543 XMapWindow(display, window);
1545 XSelectInput(display, window,
1546 ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
1547 StructureNotifyMask | PointerMotionMask);
1550 values.plane_mask = AllPlanes;
1551 values.fill_style = FillSolid;
1552 values.foreground = WhitePixel(display, screen);
1553 values.background = BlackPixel(display, screen);
1554 context = XCreateGC(display, window, GCPlaneMask | GCFillStyle | GCForeground | GCBackground, &values);
1556 if (context ==
nullptr) {
1561 pixmap = XCreatePixmap(display, window, win_width, win_height, screen_depth);
1569 Ximage = XCreateImage(display, DefaultVisual(display, screen), screen_depth, ZPixmap, 0,
nullptr, win_width,
1570 win_height, XBitmapPad(display), 0);
1572 Ximage->data = (
char *)malloc(win_height * (
unsigned int)Ximage->bytes_per_line);
1573 ximage_data_init =
true;
1576 XSync(display,
true);
1578 XStoreName(display, window, win_title.c_str());
1581 void setFont(
const std::string &fontname)
1585 stringfont = XLoadFont(display, fontname.c_str());
1586 XSetFont(display, context, stringfont);
1593 void setTitle(
const std::string &title) { XStoreName(display, window, title.c_str()); }
1595 void setWindowPosition(
int win_x,
int win_y) { XMoveWindow(display, window, win_x, win_y); }
1606 unsigned long *x_color;
1607 unsigned int screen_depth;
1608 unsigned short colortable[256];
1611 bool ximage_data_init;
1612 unsigned int RMask, GMask, BMask;
1613 int RShift, GShift, BShift;
1664 vpDisplayX::vpDisplayX(
vpImage<unsigned char> &I,
int x,
int y,
const std::string &title, vpScaleType scaleType)
1668 init(I, x, y, title);
1717 vpDisplayX::vpDisplayX(
vpImage<vpRGBa> &I,
int x,
int y,
const std::string &title, vpScaleType scaleType)
1721 init(I, x, y, title);
1749 vpDisplayX::vpDisplayX(
int x,
int y,
const std::string &title) :
vpDisplay(), m_impl(new Impl())
1751 m_windowXPosition = x;
1752 m_windowYPosition = y;
1780 vpDisplayX::vpDisplayX() :
vpDisplay(), m_impl(new Impl()) { }
1785 vpDisplayX::~vpDisplayX()
1805 m_windowXPosition = win_x;
1807 m_windowYPosition = win_y;
1809 if (!win_title.empty())
1810 m_title = win_title;
1816 m_displayHasBeenInitialized =
true;
1827 void vpDisplayX::init(
vpImage<vpRGBa> &I,
int win_x,
int win_y,
const std::string &win_title)
1834 m_windowXPosition = win_x;
1836 m_windowYPosition = win_y;
1838 if (!win_title.empty())
1839 m_title = win_title;
1845 m_displayHasBeenInitialized =
true;
1855 void vpDisplayX::init(
unsigned int win_width,
unsigned int win_height,
int win_x,
int win_y,
1856 const std::string &win_title)
1858 setScale(m_scaleType, win_width, win_height);
1860 m_width = win_width / m_scale;
1861 m_height = win_height / m_scale;
1864 m_windowXPosition = win_x;
1866 m_windowYPosition = win_y;
1868 m_title = win_title;
1870 m_impl->init(m_width, m_height, m_windowXPosition, m_windowYPosition, m_title);
1872 m_displayHasBeenInitialized =
true;
1889 void vpDisplayX::setFont(
const std::string &fontname)
1891 if (m_displayHasBeenInitialized) {
1892 if (!fontname.empty()) {
1893 m_impl->setFont(fontname);
1905 void vpDisplayX::setTitle(
const std::string &title)
1907 if (m_displayHasBeenInitialized) {
1910 m_impl->setTitle(title);
1926 void vpDisplayX::setWindowPosition(
int win_x,
int win_y)
1928 if (m_displayHasBeenInitialized) {
1929 m_impl->setWindowPosition(win_x, win_y);
1949 if (m_displayHasBeenInitialized) {
1950 m_impl->displayImage(I, m_scale, m_width, m_height);
1970 if (m_displayHasBeenInitialized) {
1971 m_impl->displayImage(I, m_scale, m_width, m_height);
1989 void vpDisplayX::displayImage(
const unsigned char *bitmap)
1991 if (m_displayHasBeenInitialized) {
1992 m_impl->displayImage(bitmap, m_width, m_height);
2017 if (m_displayHasBeenInitialized) {
2018 m_impl->displayImageROI(I, iP, w, h, m_scale, m_width, m_height);
2042 if (m_displayHasBeenInitialized) {
2043 m_impl->displayImageROI(I, iP, w, h, m_scale, m_width, m_height);
2057 void vpDisplayX::closeDisplay()
2059 if (m_displayHasBeenInitialized) {
2060 m_impl->closeDisplay();
2062 m_displayHasBeenInitialized =
false;
2071 void vpDisplayX::flushDisplay()
2073 if (m_displayHasBeenInitialized) {
2074 m_impl->flushDisplay();
2088 void vpDisplayX::flushDisplayROI(
const vpImagePoint &iP,
unsigned int w,
unsigned int h)
2090 if (m_displayHasBeenInitialized) {
2091 m_impl->flushDisplayROI(iP, w, h, m_scale);
2102 void vpDisplayX::clearDisplay(
const vpColor &color)
2104 if (m_displayHasBeenInitialized) {
2105 m_impl->clearDisplay(color, m_width, m_height);
2120 unsigned int h,
unsigned int thickness)
2122 if (m_displayHasBeenInitialized) {
2128 if ((std::fabs(a) <= std::numeric_limits<double>::epsilon()) &&
2129 (std::fabs(b) <= std::numeric_limits<double>::epsilon())) {
2145 displayLine(ip2, ip4, color, thickness);
2151 displayLine(ip2, ip4, color, thickness);
2153 displayLine(ip1, ip2, color, thickness);
2172 void vpDisplayX::displayText(
const vpImagePoint &ip,
const std::string &text,
const vpColor &color)
2174 if (m_displayHasBeenInitialized) {
2175 m_impl->displayText(ip, text, color, m_scale);
2191 void vpDisplayX::displayCircle(
const vpImagePoint ¢er,
unsigned int radius,
const vpColor &color,
bool fill,
2192 unsigned int thickness)
2194 if (m_displayHasBeenInitialized) {
2197 m_impl->displayCircle(center, radius, color, fill, thickness, m_scale);
2211 void vpDisplayX::displayCross(
const vpImagePoint &ip,
unsigned int cross_size,
const vpColor &color,
2212 unsigned int thickness)
2214 if (m_displayHasBeenInitialized) {
2215 double i = ip.
get_i();
2216 double j = ip.
get_j();
2219 ip1.
set_i(i - cross_size / 2);
2221 ip2.
set_i(i + cross_size / 2);
2223 displayLine(ip1, ip2, color, thickness);
2226 ip1.
set_j(j - cross_size / 2);
2228 ip2.
set_j(j + cross_size / 2);
2230 displayLine(ip1, ip2, color, thickness);
2243 unsigned int thickness)
2245 if (m_displayHasBeenInitialized) {
2249 m_impl->displayDotLine(ip1, ip2, color, thickness, m_scale);
2263 unsigned int thickness)
2265 if (m_displayHasBeenInitialized) {
2268 m_impl->displayLine(ip1, ip2, color, thickness, m_scale);
2281 void vpDisplayX::displayPoint(
const vpImagePoint &ip,
const vpColor &color,
unsigned int thickness)
2283 if (m_displayHasBeenInitialized) {
2284 m_impl->displayPoint(ip, color, thickness, m_scale);
2304 void vpDisplayX::displayRectangle(
const vpImagePoint &topLeft,
unsigned int w,
unsigned int h,
const vpColor &color,
2305 bool fill,
unsigned int thickness)
2307 if (m_displayHasBeenInitialized) {
2311 m_impl->displayRectangle(topLeft, w, h, color, fill, thickness, m_scale);
2331 bool fill,
unsigned int thickness)
2333 if (m_displayHasBeenInitialized) {
2340 m_impl->displayRectangle(topLeft, w, h, color, fill, thickness, m_scale);
2359 void vpDisplayX::displayRectangle(
const vpRect &rectangle,
const vpColor &color,
bool fill,
unsigned int thickness)
2361 if (m_displayHasBeenInitialized) {
2367 m_impl->displayRectangle(topLeft, w, h, color, fill, thickness, m_scale);
2389 bool vpDisplayX::getClick(
bool blocking)
2393 if (m_displayHasBeenInitialized) {
2396 ret = m_impl->getClick(ip, button, blocking, m_scale);
2419 bool vpDisplayX::getClick(
vpImagePoint &ip,
bool blocking)
2423 if (m_displayHasBeenInitialized) {
2425 ret = m_impl->getClick(ip, button, blocking, m_scale);
2456 if (m_displayHasBeenInitialized) {
2457 ret = m_impl->getClick(ip, button, blocking, m_scale);
2492 if (m_displayHasBeenInitialized) {
2493 ret = m_impl->getClickUp(ip, button, blocking, m_scale);
2510 if (m_displayHasBeenInitialized) {
2511 m_impl->getImage(I, m_width, m_height);
2521 unsigned int vpDisplayX::getScreenDepth() {
return m_impl->getScreenDepth(); }
2527 void vpDisplayX::getScreenSize(
unsigned int &w,
unsigned int &h) { m_impl->getScreenSize(w, h); }
2532 unsigned int vpDisplayX::getScreenWidth()
2534 unsigned int width, height;
2535 getScreenSize(width, height);
2542 unsigned int vpDisplayX::getScreenHeight()
2544 unsigned int width, height;
2545 getScreenSize(width, height);
2569 bool vpDisplayX::getKeyboardEvent(
bool blocking)
2573 if (m_displayHasBeenInitialized) {
2574 ret = m_impl->getKeyboardEvent(blocking);
2605 bool vpDisplayX::getKeyboardEvent(std::string &key,
bool blocking)
2608 if (m_displayHasBeenInitialized) {
2609 ret = m_impl->getKeyboardEvent(key, blocking);
2628 bool vpDisplayX::getPointerMotionEvent(
vpImagePoint &ip)
2632 if (m_displayHasBeenInitialized) {
2633 ret = m_impl->getPointerMotionEvent(ip, m_scale);
2654 if (m_displayHasBeenInitialized) {
2655 ret = m_impl->getPointerPosition(ip, m_scale);
2665 #elif !defined(VISP_BUILD_SHARED_LIBS)
2667 void dummy_vpDisplayX() { };
Class to define RGB colors available for display functionalities.
static const vpColor white
static const vpColor darkGray
static const vpColor cyan
static const vpColor orange
static const vpColor darkRed
static const vpColor blue
static const vpColor lightGray
static const vpColor lightBlue
static const vpColor darkGreen
static const vpColor darkBlue
static const vpColor purple
static const vpColor lightGreen
static const vpColor yellow
static const vpColor lightRed
static const vpColor black
static const vpColor green
static const vpColor gray
Error that can be emitted by the vpDisplay class and its derivatives.
@ connexionError
Connection error.
@ colorAllocError
Color allocation error.
@ cannotOpenWindowError
Unable to open display window.
@ notInitializedError
Display not initialized.
@ XWindowsError
XWindow error.
@ depthNotSupportedError
Color depth not supported.
Class that defines generic functionalities for display.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
void init(unsigned int h, unsigned int w, Type value)
static double sqr(double x)
static int round(double x)
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
unsigned char A
Additionnal component.
Defines a rectangle in the plane.
vpImagePoint getTopLeft() const