Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpDisplayWin32.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Windows 32 display base class
32  *
33  * Authors:
34  * Bruno Renier
35  *
36  *****************************************************************************/
37 
38 #include <visp3/core/vpConfig.h>
39 #if ( defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9) )
40 
41 #include <visp3/gui/vpDisplayWin32.h>
42 #include <visp3/core/vpDisplayException.h>
43 #include <string>
44 
45 const int vpDisplayWin32::MAX_INIT_DELAY = 5000;
46 
51 void vpCreateWindow(threadParam * param)
52 {
53  //char* title = param->title;
54  (param->vpDisp)->window.initWindow(param->title.c_str(), param->x, param->y,
55  param->w, param->h);
56  delete param;
57 }
58 
62 vpDisplayWin32::vpDisplayWin32(vpWin32Renderer * rend) :
63  iStatus(false), window(rend)
64 {
65 }
66 
67 
72 {
73  closeDisplay();
74 }
75 
76 
88  int x,
89  int y,
90  const std::string &title)
91 {
92  if ((I.getHeight() == 0) || (I.getWidth()==0))
93  {
94  vpERROR_TRACE("Image not initialized " ) ;
96  "Image not initialized")) ;
97  }
98 
100  init(I.getWidth(), I.getHeight(), x, y, title);
101  window.renderer->setWidth(I.getWidth()/m_scale);
102  window.renderer->setHeight(I.getHeight()/m_scale);
103  window.renderer->setImg(I);
104 
105  I.display = this ;
106 }
107 
108 
118  int x,
119  int y,
120  const std::string &title)
121 {
122  if ((I.getHeight() == 0) || (I.getWidth()==0))
123  {
124  vpERROR_TRACE("Image not initialized " ) ;
126  "Image not initialized")) ;
127  }
128 
130  init (I.getWidth(), I.getHeight(), x, y, title) ;
131  window.renderer->setWidth(I.getWidth()/m_scale);
132  window.renderer->setHeight(I.getHeight()/m_scale);
133  window.renderer->setImg(I);
134 
135  I.display = this ;
136 }
137 
138 
147 void vpDisplayWin32::init(unsigned int width, unsigned int height,
148  int x, int y,
149  const std::string &title)
150 {
151  if (!title.empty())
152  m_title = title;
153  else
154  m_title = std::string(" ");
155 
156  if (x != -1)
157  m_windowXPosition = x;
158  if (y != -1)
159  m_windowYPosition = y;
160 
161  //we prepare the window's thread creation
162  setScale(m_scaleType, width, height);
163  threadParam * param = new threadParam;
164  param->x = m_windowXPosition;
165  param->y = m_windowYPosition;
166  param->w = width / m_scale;
167  param->h = height / m_scale;
168  param->vpDisp = this;
169  param->title = this->m_title;
170 
171  //creates the window in a separate thread
172  hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)vpCreateWindow,
173  param,0,&threadId);
174 
175  //the initialization worked
176  iStatus = (hThread != (HANDLE)NULL);
177 
179 }
180 
181 
187 {
188  //if the window is not initialized yet
189  if(!window.isInitialized())
190  {
191  //wait
192  if( WAIT_OBJECT_0 != WaitForSingleObject(window.semaInit,MAX_INIT_DELAY))
194  "Window not initialized")) ;
195  //problem : the window is not initialized
196  }
197 }
198 
199 
212 {
213  //waits if the window is not initialized
214  waitForInit();
215 
216  //sets the image to render
217  window.renderer->setImg(I);
218  //sends a message to the window
219  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
220 }
221 
222 
240 void vpDisplayWin32::displayImageROI ( const vpImage<vpRGBa> &I,const vpImagePoint &iP, const unsigned int width, const unsigned int height )
241 {
242  //waits if the window is not initialized
243  waitForInit();
244 
245  //sets the image to render
246  window.renderer->setImgROI(I,iP,width,height);
247  //sends a message to the window
248  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
249 }
250 
251 
264 {
265  //wait if the window is not initialized
266  waitForInit();
267 
268  //sets the image to render
269  window.renderer->setImg(I);
270  //sends a message to the window
271  //PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
272 }
273 
291 void vpDisplayWin32::displayImageROI ( const vpImage<unsigned char> &I,const vpImagePoint &iP, const unsigned int width, const unsigned int height )
292 {
293  //waits if the window is not initialized
294  waitForInit();
295 
296  //sets the image to render
297  window.renderer->setImgROI(I,iP,width,height);
298  //sends a message to the window
299  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
300 }
301 
302 
318 bool vpDisplayWin32::getClick( bool blocking)
319 {
320  //wait if the window is not initialized
321  waitForInit();
322  bool ret = false;
323  //sends a message to the window
324  // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
325 
326  //waits for a button to be pressed
327  if(blocking){
328  WaitForSingleObject(window.semaClick, 0);
329  WaitForSingleObject(window.semaClickUp, 0); //to erase previous events
330  WaitForSingleObject(window.semaClick, INFINITE);
331  ret = true;
332  }
333  else {
334  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
335  }
336 
337  return ret;
338 }
339 
340 
357 bool vpDisplayWin32::getClick(vpImagePoint &ip, bool blocking)
358 {
359  //wait if the window is not initialized
360  waitForInit();
361 
362  bool ret = false ;
363  double u, v;
364  //tells the window there has been a getclick demand
365  // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
366  //waits for a click
367  if(blocking){
368  WaitForSingleObject(window.semaClick, 0);
369  WaitForSingleObject(window.semaClickUp, 0);//to erase previous events
370  WaitForSingleObject(window.semaClick, INFINITE);
371  ret = true;
372  }
373  else {
374  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
375  }
376 
377  u = window.clickX;
378  v = window.clickY;
379  ip.set_u( u*m_scale );
380  ip.set_v( v*m_scale);
381 
382  return ret;
383 }
384 
385 
406  bool blocking)
407 {
408  //wait if the window is not initialized
409  waitForInit();
410  bool ret = false;
411  double u, v;
412  //tells the window there has been a getclickup demand
413  // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
414  //waits for a click
415  if(blocking){
416  WaitForSingleObject(window.semaClick, 0);
417  WaitForSingleObject(window.semaClickUp, 0);//to erase previous events
418  WaitForSingleObject(window.semaClick, INFINITE);
419  ret = true;
420  }
421  else
422  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
423 
424  u = window.clickX;
425  v = window.clickY;
426  ip.set_u( u*m_scale);
427  ip.set_v( v*m_scale);
428  button = window.clickButton;
429 
430  return ret;
431 }
432 
433 
458  bool blocking)
459 {
460  //wait if the window is not initialized
461  waitForInit();
462  bool ret = false;
463  double u, v;
464  //tells the window there has been a getclickup demand
465  // PostMessage(window.getHWnd(), vpWM_GETCLICKUP, 0,0);
466 
467  //waits for a click release
468  if(blocking){
469  WaitForSingleObject(window.semaClickUp, 0);
470  WaitForSingleObject(window.semaClick, 0);//to erase previous events
471  WaitForSingleObject(window.semaClickUp, INFINITE);
472  ret = true;
473  }
474  else
475  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClickUp, 0));
476 
477  u = window.clickXUp;
478  v = window.clickYUp;
479  ip.set_u( u*m_scale);
480  ip.set_v( v*m_scale);
481  button = window.clickButtonUp;
482 
483  return ret;
484 }
485 
501 bool vpDisplayWin32::getKeyboardEvent( bool blocking )
502 {
503  //wait if the window is not initialized
504  waitForInit();
505 
506  bool ret = false ;
507  //waits for a keyboard event
508  if(blocking){
509  WaitForSingleObject(window.semaKey, 0); // key down
510  WaitForSingleObject(window.semaKey, 0); // key up
511  WaitForSingleObject(window.semaKey, INFINITE);
512  ret = true;
513  }
514  else
515  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
516 
517  return ret;
518 }
538 bool vpDisplayWin32::getKeyboardEvent(std::string &key, bool blocking)
539 {
540  //wait if the window is not initialized
541  waitForInit();
542 
543  bool ret = false ;
544  //waits for a keyboard event
545  if(blocking){
546  WaitForSingleObject(window.semaKey, 0); // key down
547  WaitForSingleObject(window.semaKey, 0); // key up
548  WaitForSingleObject(window.semaKey, INFINITE);
549  ret = true;
550  }
551  else {
552  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
553  }
554  // printf("key: %ud\n", window.key);
555  std::stringstream ss;
556  ss << window.lpString;
557  key = ss.str();
558 
559  return ret;
560 }
571 bool
573 {
574  //wait if the window is not initialized
575  waitForInit();
576 
577  bool ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaMove, 0));
578  if (ret)
579  {
580  double u, v;
581  //tells the window there has been a getclick demand
582  //PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
583 
584  u = window.coordX;
585  v = window.coordY;
586  ip.set_u( u*m_scale);
587  ip.set_v( v*m_scale);
588  }
589 
590  return ret;
591 }
592 
603 bool
605 {
606  //wait if the window is not initialized
607  waitForInit();
608 
609  bool ret = true ;
610  double u, v;
611  //tells the window there has been a getclick demand
612  //PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
613 
614  u = window.coordX;
615  v = window.coordY;
616  ip.set_u( u*m_scale);
617  ip.set_v( v*m_scale);
618 
619  return ret;
620 }
621 
628 void vpDisplayWin32::setWindowPosition(int winx, int winy)
629 {
630  //wait if the window is not initialized
631  waitForInit();
632 
633  //cahange the window position only
634  SetWindowPos(window.hWnd,HWND_TOP, winx, winy, 0, 0,
635  SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER |SWP_NOSIZE);
636 
637 }
638 
639 
645 void vpDisplayWin32::setTitle(const std::string &windowtitle)
646 {
647  //wait if the window is not initialized
648  waitForInit();
649  SetWindowText(window.hWnd, windowtitle.c_str());
650 }
651 
652 
658 void vpDisplayWin32::setFont(const std::string & /* fontname */)
659 {
660  vpERROR_TRACE("Not yet implemented" ) ;
661 }
662 
663 
670 {
671  //waits if the window is not initialized
672  waitForInit();
673 
674  //sends a message to the window
675  PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
676 }
677 
683 void vpDisplayWin32::flushDisplayROI(const vpImagePoint &iP, const unsigned int width, const unsigned int height)
684 {
685  //waits if the window is not initialized
686  waitForInit();
687  /*
688  Under windows, flushing an ROI takes more time than
689  flushing the whole image.
690  Therefore, we update the maximum area even when asked to update a region.
691  */
692  WORD left = (WORD)iP.get_u();
693  WORD right = (WORD)(iP.get_u()+width-1);
694 
695  WORD top = (WORD)iP.get_v();
696  WORD bottom = (WORD)(iP.get_v()+height-1);
697 
698  //sends a message to the window
699  WPARAM wp = MAKEWPARAM(left, right);
700  LPARAM lp = MAKELPARAM(top, bottom);
701 
702  PostMessage(window.getHWnd(), vpWM_DISPLAY_ROI, wp,lp);
703 }
704 
705 
713  const vpColor &color, unsigned int thickness)
714 {
715  //wait if the window is not initialized
716  waitForInit();
717  if (thickness == 1) {
718  window.renderer->setPixel(ip, color);
719  }
720  else {
721  window.renderer->drawRect(ip, thickness*m_scale, thickness*m_scale, color, true, 1);
722  }
723 }
724 
732  const vpImagePoint &ip2,
733  const vpColor &color,
734  unsigned int thickness )
735 {
736  //wait if the window is not initialized
737  waitForInit();
738  window.renderer->drawLine(ip1, ip2, color, thickness);
739 }
740 
741 
752  const vpImagePoint &ip2,
753  const vpColor &color,
754  unsigned int thickness )
755 {
756  //wait if the window is not initialized
757  waitForInit();
758  window.renderer->drawLine(ip1, ip2, color, thickness, PS_DASHDOT);
759 }
760 
775  unsigned int width, unsigned int height,
776  const vpColor &color, bool fill,
777  unsigned int thickness )
778 {
779  //wait if the window is not initialized
780  waitForInit();
781  window.renderer->drawRect(topLeft,width,height,color, fill, thickness);
782 }
783 
784 
798  const vpImagePoint &bottomRight,
799  const vpColor &color, bool fill,
800  unsigned int thickness )
801 {
802  //wait if the window is not initialized
803  waitForInit();
804  unsigned int width = static_cast<unsigned int>( bottomRight.get_j() - topLeft.get_j() );
805  unsigned int height = static_cast<unsigned int>(bottomRight.get_i() - topLeft.get_i() );
806  window.renderer->drawRect(topLeft,width,height,color, fill, thickness);
807 }
808 
821  const vpColor &color, bool fill,
822  unsigned int thickness )
823 {
824  //wait if the window is not initialized
825  waitForInit();
826  vpImagePoint topLeft;
827  topLeft.set_i(rectangle.getTop());
828  topLeft.set_j(rectangle.getLeft());
829  window.renderer->drawRect(topLeft,
830  static_cast<unsigned int>( rectangle.getWidth() ),
831  static_cast<unsigned int>( rectangle.getHeight() ),
832  color, fill, thickness);
833 }
834 
835 
846  unsigned int radius,
847  const vpColor &color,
848  bool fill,
849  unsigned int thickness )
850 {
851  //wait if the window is not initialized
852  waitForInit();
853  window.renderer->drawCircle(center,radius,color,fill,thickness);
854 }
855 
863  const char *text,
864  const vpColor &color )
865 {
866  //wait if the window is not initialized
867  waitForInit();
868  window.renderer->drawText(ip,text,color);
869 }
870 
879  unsigned int size,
880  const vpColor &color,
881  unsigned int thickness)
882 {
883  //wait if the window is not initialized
884  waitForInit();
885  window.renderer->drawCross(ip, size, color, thickness);
886 }
887 
888 
897  const vpImagePoint &ip2,
898  const vpColor &color,
899  unsigned int w,unsigned int h,
900  unsigned int thickness)
901 
902 {
903  //wait if the window is not initialized
904  waitForInit();
905  window.renderer->drawArrow(ip1, ip2, color, w, h, thickness);
906 }
907 
908 
914  //wait if the window is not initialized
915  waitForInit();
916  window.renderer->clear(color);
917 }
918 
919 
925 {
927  waitForInit();
928  PostMessage(window.getHWnd(), vpWM_CLOSEDISPLAY, 0,0);
929  //if the destructor is called for a reason different than a
930  //problem in the thread creation
931  if (iStatus) {
932  //waits for the thread to end
933  WaitForSingleObject(hThread, INFINITE);
934  CloseHandle(hThread);
935  }
937  window.initialized = false ;
938  }
939 }
940 
946 {
947  //wait if the window is not initialized
948  waitForInit();
949  window.renderer->getImage(I);
950 }
951 
956 void vpDisplayWin32::getScreenSize ( unsigned int &w, unsigned int &h )
957 {
958  w = GetSystemMetrics(SM_CXSCREEN);
959  h = GetSystemMetrics(SM_CYSCREEN);
960 }
961 
966 {
967  unsigned int width, height;
968  getScreenSize(width, height);
969  return width;
970 }
971 
976 {
977  unsigned int width, height;
978  getScreenSize(width, height);
979  return height;
980 }
981 #elif !defined(VISP_BUILD_SHARED_LIBS)
982 // Work arround to avoid warning: libvisp_core.a(vpDisplayWin32.cpp.o) has no symbols
983 void dummy_vpDisplayWin32() {};
984 #endif
void getScreenSize(unsigned int &width, unsigned int &height)
vpDisplay * display
Definition: vpImage.h:135
static const int MAX_INIT_DELAY
Maximum delay for window initialization.
DWORD threadId
Id of the window's thread.
double getTop() const
Definition: vpRect.h:178
void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)
int m_windowYPosition
display position
Definition: vpDisplay.h:194
double get_v() const
Definition: vpImagePoint.h:268
void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
void displayCircle(const vpImagePoint &center, unsigned int radius, const vpColor &color, bool fill=false, unsigned int thickness=1)
void setFont(const std::string &fontname)
Set the font used to display text.
double get_i() const
Definition: vpImagePoint.h:199
unsigned int getWidth() const
Definition: vpImage.h:226
virtual ~vpDisplayWin32()
bool getClick(bool blocking=true)
#define vpERROR_TRACE
Definition: vpDebug.h:391
Class to define colors available for display functionnalities.
Definition: vpColor.h:121
double get_u() const
Definition: vpImagePoint.h:257
void displayPoint(const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
double getHeight() const
Definition: vpRect.h:152
unsigned int getScreenWidth()
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
bool m_displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:190
bool iStatus
Initialization status.
void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)
double get_j() const
Definition: vpImagePoint.h:210
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, const unsigned int width, const unsigned int height)
bool getKeyboardEvent(bool blocking=true)
void setTitle(const std::string &windowtitle)
vpDisplayWin32(vpWin32Renderer *rend=NULL)
vpWin32Window window
The window.
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true)
void set_i(const double ii)
Definition: vpImagePoint.h:163
double getWidth() const
Definition: vpRect.h:199
void displayImage(const vpImage< vpRGBa > &I)
int m_windowXPosition
display position
Definition: vpDisplay.h:192
unsigned int m_scale
Definition: vpDisplay.h:198
void setScale(vpScaleType scaleType, unsigned int width, unsigned int height)
Definition: vpDisplay.cpp:276
void set_u(const double u)
Definition: vpImagePoint.h:221
void set_v(const double v)
Definition: vpImagePoint.h:232
vpScaleType m_scaleType
Definition: vpDisplay.h:199
std::string m_title
Definition: vpDisplay.h:197
void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, 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)
unsigned int getScreenHeight()
friend void vpCreateWindow(threadParam *param)
Function used to launch the window in a thread.
void set_j(const double jj)
Definition: vpImagePoint.h:174
bool getPointerMotionEvent(vpImagePoint &ip)
Error that can be emited by the vpDisplay class and its derivates.
HANDLE hThread
Handle of the window's thread.
unsigned int getHeight() const
Definition: vpImage.h:175
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Defines a rectangle in the plane.
Definition: vpRect.h:82
void flushDisplayROI(const vpImagePoint &iP, const unsigned int width, const unsigned int height)
flush the Win32 buffer It's necessary to use this function to see the results of any drawing ...
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void clearDisplay(const vpColor &color=vpColor::white)
void flushDisplay()
flush the Win32 buffer It's necessary to use this function to see the results of any drawing ...
void setWindowPosition(int winx, int winy)
double getLeft() const
Definition: vpRect.h:159
bool getPointerPosition(vpImagePoint &ip)
void getImage(vpImage< vpRGBa > &I)