Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpDisplayWin32.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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 * Windows 32 display base class
33 *
34 * Authors:
35 * Bruno Renier
36 *
37*****************************************************************************/
38
39#include <visp3/core/vpConfig.h>
40#if (defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9))
41
42#include <string>
43#include <visp3/core/vpDisplayException.h>
44#include <visp3/gui/vpDisplayWin32.h>
45
46const int vpDisplayWin32::MAX_INIT_DELAY = 5000;
47
52void vpCreateWindow(threadParam *param)
53{
54 // char* title = param->title;
55 (param->vpDisp)->window.initWindow(param->title.c_str(), param->x, param->y, param->w, param->h);
56 delete param;
57}
58
62vpDisplayWin32::vpDisplayWin32(vpWin32Renderer *rend) : iStatus(false), window(rend) {}
63
68
79void vpDisplayWin32::init(vpImage<unsigned char> &I, int x, int y, const std::string &title)
80{
81 if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
82 vpERROR_TRACE("Image not initialized ");
83 throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
84 }
85
87 init(I.getWidth(), I.getHeight(), x, y, title);
88 window.renderer->setWidth(I.getWidth() / m_scale);
89 window.renderer->setHeight(I.getHeight() / m_scale);
90 window.renderer->setImg(I);
91
92 I.display = this;
93}
94
103void vpDisplayWin32::init(vpImage<vpRGBa> &I, int x, int y, const std::string &title)
104{
105 if ((I.getHeight() == 0) || (I.getWidth() == 0)) {
106 vpERROR_TRACE("Image not initialized ");
107 throw(vpDisplayException(vpDisplayException::notInitializedError, "Image not initialized"));
108 }
109
111 init(I.getWidth(), I.getHeight(), x, y, title);
112 window.renderer->setWidth(I.getWidth() / m_scale);
113 window.renderer->setHeight(I.getHeight() / m_scale);
114 window.renderer->setImg(I);
115
116 I.display = this;
117}
118
127void vpDisplayWin32::init(unsigned int width, unsigned int height, int x, int y, const std::string &title)
128{
129 if (!title.empty())
130 m_title = title;
131 else
132 m_title = std::string(" ");
133
134 if (x != -1)
136 if (y != -1)
138
139 // we prepare the window's thread creation
140 setScale(m_scaleType, width, height);
141 threadParam *param = new threadParam;
142 param->x = m_windowXPosition;
143 param->y = m_windowYPosition;
144 param->w = width / m_scale;
145 param->h = height / m_scale;
146 param->vpDisp = this;
147 param->title = this->m_title;
148
149 // creates the window in a separate thread
150 hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)vpCreateWindow, param, 0, &threadId);
151
152 // the initialization worked
153 iStatus = (hThread != (HANDLE)NULL);
154
156}
157
163{
164 // if the window is not initialized yet
165 if (!window.isInitialized()) {
166 // wait
167 if (WAIT_OBJECT_0 != WaitForSingleObject(window.semaInit, MAX_INIT_DELAY))
168 throw(vpDisplayException(vpDisplayException::notInitializedError, "Window not initialized"));
169 // problem : the window is not initialized
170 }
171}
172
185{
186 // waits if the window is not initialized
187 waitForInit();
188
189 // sets the image to render
190 window.renderer->setImg(I);
191 // sends a message to the window
192 // PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
193}
194
212void vpDisplayWin32::displayImageROI(const vpImage<vpRGBa> &I, const vpImagePoint &iP, unsigned int width,
213 unsigned int height)
214{
215 // waits if the window is not initialized
216 waitForInit();
217
218 // sets the image to render
219 window.renderer->setImgROI(I, iP, width, height);
220 // sends a message to the window
221 // PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
222}
223
236{
237 // wait if the window is not initialized
238 waitForInit();
239
240 // sets the image to render
241 window.renderer->setImg(I);
242 // sends a message to the window
243 // PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
244}
245
263void vpDisplayWin32::displayImageROI(const vpImage<unsigned char> &I, const vpImagePoint &iP, unsigned int width,
264 unsigned int height)
265{
266 // waits if the window is not initialized
267 waitForInit();
268
269 // sets the image to render
270 window.renderer->setImgROI(I, iP, width, height);
271 // sends a message to the window
272 // PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
273}
274
290bool vpDisplayWin32::getClick(bool blocking)
291{
292 // wait if the window is not initialized
293 waitForInit();
294 bool ret = false;
295 // sends a message to the window
296 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
297
298 // waits for a button to be pressed
299 if (blocking) {
300 WaitForSingleObject(window.semaClick, 0);
301 WaitForSingleObject(window.semaClickUp, 0); // to erase previous events
302 WaitForSingleObject(window.semaClick, INFINITE);
303 ret = true;
304 } else {
305 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
306 }
307
308 return ret;
309}
310
328{
329 // wait if the window is not initialized
330 waitForInit();
331
332 bool ret = false;
333 double u, v;
334 // tells the window there has been a getclick demand
335 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
336 // waits for a click
337 if (blocking) {
338 WaitForSingleObject(window.semaClick, 0);
339 WaitForSingleObject(window.semaClickUp, 0); // to erase previous events
340 WaitForSingleObject(window.semaClick, INFINITE);
341 ret = true;
342 } else {
343 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
344 }
345
346 u = window.clickX;
347 v = window.clickY;
348 ip.set_u(u * m_scale);
349 ip.set_v(v * m_scale);
350
351 return ret;
352}
353
373{
374 // wait if the window is not initialized
375 waitForInit();
376 bool ret = false;
377 double u, v;
378 // tells the window there has been a getclickup demand
379 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
380 // waits for a click
381 if (blocking) {
382 WaitForSingleObject(window.semaClick, 0);
383 WaitForSingleObject(window.semaClickUp, 0); // to erase previous events
384 WaitForSingleObject(window.semaClick, INFINITE);
385 ret = true;
386 } else
387 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
388
389 u = window.clickX;
390 v = window.clickY;
391 ip.set_u(u * m_scale);
392 ip.set_v(v * m_scale);
393 button = window.clickButton;
394
395 return ret;
396}
397
421{
422 // wait if the window is not initialized
423 waitForInit();
424 bool ret = false;
425 double u, v;
426 // tells the window there has been a getclickup demand
427 // PostMessage(window.getHWnd(), vpWM_GETCLICKUP, 0,0);
428
429 // waits for a click release
430 if (blocking) {
431 WaitForSingleObject(window.semaClickUp, 0);
432 WaitForSingleObject(window.semaClick, 0); // to erase previous events
433 WaitForSingleObject(window.semaClickUp, INFINITE);
434 ret = true;
435 } else
436 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClickUp, 0));
437
438 u = window.clickXUp;
439 v = window.clickYUp;
440 ip.set_u(u * m_scale);
441 ip.set_v(v * m_scale);
442 button = window.clickButtonUp;
443
444 return ret;
445}
446
463{
464 // wait if the window is not initialized
465 waitForInit();
466
467 bool ret = false;
468 // waits for a keyboard event
469 if (blocking) {
470 WaitForSingleObject(window.semaKey, 0); // key down
471 WaitForSingleObject(window.semaKey, 0); // key up
472 WaitForSingleObject(window.semaKey, INFINITE);
473 ret = true;
474 } else
475 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
476
477 return ret;
478}
498bool vpDisplayWin32::getKeyboardEvent(std::string &key, bool blocking)
499{
500 // wait if the window is not initialized
501 waitForInit();
502
503 bool ret = false;
504 // waits for a keyboard event
505 if (blocking) {
506 WaitForSingleObject(window.semaKey, 0); // key down
507 WaitForSingleObject(window.semaKey, 0); // key up
508 WaitForSingleObject(window.semaKey, INFINITE);
509 ret = true;
510 } else {
511 ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
512 }
513 // printf("key: %ud\n", window.key);
514 std::stringstream ss;
515 ss << window.lpString;
516 key = ss.str();
517
518 return ret;
519}
531{
532 // wait if the window is not initialized
533 waitForInit();
534
535 bool ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaMove, 0));
536 if (ret) {
537 double u, v;
538 // tells the window there has been a getclick demand
539 // PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
540
541 u = window.coordX;
542 v = window.coordY;
543 ip.set_u(u * m_scale);
544 ip.set_v(v * m_scale);
545 }
546
547 return ret;
548}
549
561{
562 // wait if the window is not initialized
563 waitForInit();
564
565 bool ret = true;
566 double u, v;
567 // tells the window there has been a getclick demand
568 // PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
569
570 u = window.coordX;
571 v = window.coordY;
572 ip.set_u(u * m_scale);
573 ip.set_v(v * m_scale);
574
575 return ret;
576}
577
585void vpDisplayWin32::setWindowPosition(int winx, int winy)
586{
587 // wait if the window is not initialized
588 waitForInit();
589
590 // cahange the window position only
591 SetWindowPos(window.hWnd, HWND_TOP, winx, winy, 0, 0,
592 SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
593}
594
600void vpDisplayWin32::setTitle(const std::string &windowtitle)
601{
602 // wait if the window is not initialized
603 waitForInit();
604 SetWindowText(window.hWnd, windowtitle.c_str());
605}
606
612void vpDisplayWin32::setFont(const std::string & /* fontname */) { vpERROR_TRACE("Not yet implemented"); }
613
620{
621 // waits if the window is not initialized
622 waitForInit();
623
624 // sends a message to the window
625 PostMessage(window.getHWnd(), vpWM_DISPLAY, 0, 0);
626}
627
633void vpDisplayWin32::flushDisplayROI(const vpImagePoint &iP, unsigned int width, unsigned int height)
634{
635 // waits if the window is not initialized
636 waitForInit();
637 /*
638 Under windows, flushing an ROI takes more time than
639 flushing the whole image.
640 Therefore, we update the maximum area even when asked to update a region.
641 */
642 WORD left = (WORD)iP.get_u();
643 WORD right = (WORD)(iP.get_u() + width - 1);
644
645 WORD top = (WORD)iP.get_v();
646 WORD bottom = (WORD)(iP.get_v() + height - 1);
647
648 // sends a message to the window
649 WPARAM wp = MAKEWPARAM(left, right);
650 LPARAM lp = MAKELPARAM(top, bottom);
651
652 PostMessage(window.getHWnd(), vpWM_DISPLAY_ROI, wp, lp);
653}
654
661void vpDisplayWin32::displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness)
662{
663 // wait if the window is not initialized
664 waitForInit();
665 if (thickness == 1) {
666 window.renderer->setPixel(ip, color);
667 } else {
668 window.renderer->drawRect(ip, thickness * m_scale, thickness * m_scale, color, true, 1);
669 }
670}
671
678void vpDisplayWin32::displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
679 unsigned int thickness)
680{
681 // wait if the window is not initialized
682 waitForInit();
683 window.renderer->drawLine(ip1, ip2, color, thickness);
684}
685
695void vpDisplayWin32::displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
696 unsigned int thickness)
697{
698 // wait if the window is not initialized
699 waitForInit();
700 window.renderer->drawLine(ip1, ip2, color, thickness, PS_DASHDOT);
701}
702
716void vpDisplayWin32::displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height,
717 const vpColor &color, bool fill, unsigned int thickness)
718{
719 // wait if the window is not initialized
720 waitForInit();
721 window.renderer->drawRect(topLeft, width, height, color, fill, thickness);
722}
723
736void vpDisplayWin32::displayRectangle(const vpImagePoint &topLeft, const vpImagePoint &bottomRight,
737 const vpColor &color, bool fill, unsigned int thickness)
738{
739 // wait if the window is not initialized
740 waitForInit();
741 unsigned int width = static_cast<unsigned int>(bottomRight.get_j() - topLeft.get_j());
742 unsigned int height = static_cast<unsigned int>(bottomRight.get_i() - topLeft.get_i());
743 window.renderer->drawRect(topLeft, width, height, color, fill, thickness);
744}
745
757void vpDisplayWin32::displayRectangle(const vpRect &rectangle, const vpColor &color, bool fill, unsigned int thickness)
758{
759 // wait if the window is not initialized
760 waitForInit();
761 vpImagePoint topLeft;
762 topLeft.set_i(rectangle.getTop());
763 topLeft.set_j(rectangle.getLeft());
764 window.renderer->drawRect(topLeft, static_cast<unsigned int>(rectangle.getWidth()),
765 static_cast<unsigned int>(rectangle.getHeight()), color, fill, thickness);
766}
767
777void vpDisplayWin32::displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill,
778 unsigned int thickness)
779{
780 // wait if the window is not initialized
781 waitForInit();
782 window.renderer->drawCircle(center, radius, color, fill, thickness);
783}
784
791void vpDisplayWin32::displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color)
792{
793 // wait if the window is not initialized
794 waitForInit();
795 window.renderer->drawText(ip, text, color);
796}
797
805void vpDisplayWin32::displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color,
806 unsigned int thickness)
807{
808 // wait if the window is not initialized
809 waitForInit();
810 window.renderer->drawCross(ip, size, color, thickness);
811}
812
820void vpDisplayWin32::displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color,
821 unsigned int w, unsigned int h, unsigned int thickness)
822
823{
824 // wait if the window is not initialized
825 waitForInit();
826 window.renderer->drawArrow(ip1, ip2, color, w, h, thickness);
827}
828
834{
835 // wait if the window is not initialized
836 waitForInit();
837 window.renderer->clear(color);
838}
839
845{
847 waitForInit();
848 PostMessage(window.getHWnd(), vpWM_CLOSEDISPLAY, 0, 0);
849 // if the destructor is called for a reason different than a
850 // problem in the thread creation
851 if (iStatus) {
852 // waits for the thread to end
853 WaitForSingleObject(hThread, INFINITE);
854 CloseHandle(hThread);
855 }
857 window.initialized = false;
858 }
859}
860
866{
867 // wait if the window is not initialized
868 waitForInit();
869 window.renderer->getImage(I);
870}
871
876void vpDisplayWin32::getScreenSize(unsigned int &w, unsigned int &h)
877{
878 w = GetSystemMetrics(SM_CXSCREEN);
879 h = GetSystemMetrics(SM_CYSCREEN);
880}
881
886{
887 unsigned int width, height;
888 getScreenSize(width, height);
889 return width;
890}
891
896{
897 unsigned int width, height;
898 getScreenSize(width, height);
899 return height;
900}
901#elif !defined(VISP_BUILD_SHARED_LIBS)
902// Work around to avoid warning: libvisp_core.a(vpDisplayWin32.cpp.o) has no
903// symbols
904void dummy_vpDisplayWin32(){};
905#endif
Class to define RGB colors available for display functionalities.
Definition vpColor.h:152
Error that can be emitted by the vpDisplay class and its derivatives.
@ notInitializedError
Display not initialized.
void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
DWORD threadId
Id of the window's thread.
vpWin32Window window
The window.
void setFont(const std::string &fontname)
Set the font used to display text.
void getImage(vpImage< vpRGBa > &I)
vpDisplayWin32(vpWin32Renderer *rend=NULL)
unsigned int getScreenWidth()
bool getKeyboardEvent(bool blocking=true)
void clearDisplay(const vpColor &color=vpColor::white)
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true)
void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
void setWindowPosition(int winx, int winy)
unsigned int getScreenHeight()
HANDLE hThread
Handle of the window's thread.
void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)
friend void vpCreateWindow(threadParam *param)
Function used to launch the window in a thread.
bool getPointerPosition(vpImagePoint &ip)
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)
bool iStatus
Initialization status.
void flushDisplayROI(const vpImagePoint &iP, unsigned int width, unsigned int height)
flush the Win32 buffer It's necessary to use this function to see the results of any drawing
void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
static const int MAX_INIT_DELAY
Maximum delay for window initialization.
bool getPointerMotionEvent(vpImagePoint &ip)
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, unsigned int width, unsigned int height)
void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
virtual ~vpDisplayWin32()
void getScreenSize(unsigned int &width, unsigned int &height)
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
bool getClick(bool blocking=true)
void flushDisplay()
flush the Win32 buffer It's necessary to use this function to see the results of any drawing
void displayImage(const vpImage< vpRGBa > &I)
void setTitle(const std::string &windowtitle)
vpScaleType m_scaleType
Definition vpDisplay.h:215
int m_windowXPosition
display position
Definition vpDisplay.h:208
std::string m_title
Definition vpDisplay.h:213
int m_windowYPosition
display position
Definition vpDisplay.h:210
unsigned int m_scale
Definition vpDisplay.h:214
bool m_displayHasBeenInitialized
display has been initialized
Definition vpDisplay.h:206
void setScale(vpScaleType scaleType, unsigned int width, unsigned int height)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_j(double jj)
double get_j() const
void set_i(double ii)
double get_u() const
void set_u(double u)
void set_v(double v)
double get_i() const
double get_v() const
Definition of the vpImage class member functions.
Definition vpImage.h:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
vpDisplay * display
Definition vpImage.h:140
Defines a rectangle in the plane.
Definition vpRect.h:76
double getWidth() const
Definition vpRect.h:224
double getLeft() const
Definition vpRect.h:170
double getHeight() const
Definition vpRect.h:163
double getTop() const
Definition vpRect.h:189
#define vpERROR_TRACE
Definition vpDebug.h:388