ViSP  2.8.0
vpDisplayWin32.cpp
1 /****************************************************************************
2  *
3  * $Id: vpDisplayWin32.cpp 4174 2013-03-22 10:28:41Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Windows 32 display base class
36  *
37  * Authors:
38  * Bruno Renier
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpConfig.h>
43 #if ( defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9) )
44 
45 #define FLUSH_ROI
46 #include <visp/vpDisplayWin32.h>
47 #include <visp/vpDisplayException.h>
48 #include <string>
49 
50 
51 
52 const int vpDisplayWin32::MAX_INIT_DELAY = 5000;
53 
58 void vpCreateWindow(threadParam * param)
59 {
60  //char* title = param->title;
61  (param->vpDisp)->window.initWindow(param->title, param->x, param->y,
62  param->w, param->h);
63  delete param;
64 }
65 
69 vpDisplayWin32::vpDisplayWin32(vpWin32Renderer * rend) :
70  iStatus(false), window(rend)
71 {
72 }
73 
74 
79 {
80  closeDisplay();
81 }
82 
83 
95  int x,
96  int y,
97  const char *title)
98 {
99  if ((I.getHeight() == 0) || (I.getWidth()==0))
100  {
101  vpERROR_TRACE("Image not initialized " ) ;
103  "Image not initialized")) ;
104  }
105 
106  window.renderer->setImg(I);
107 
108  init (I.getWidth(), I.getHeight(), x, y, title) ;
109  I.display = this ;
110 }
111 
112 
122  int x,
123  int y,
124  const char *title)
125 {
126  if ((I.getHeight() == 0) || (I.getWidth()==0))
127  {
128  vpERROR_TRACE("Image not initialized " ) ;
130  "Image not initialized")) ;
131  }
132 
133  window.renderer->setImg(I);
134 
135  init (I.getWidth(), I.getHeight(), x, y, title) ;
136  I.display = this ;
137 }
138 
139 
148 void vpDisplayWin32::init(unsigned int width, unsigned int height,
149  int x, int y,
150  const char *title)
151 {
152  if (title != NULL)
153  strcpy(this->title, title) ;
154 
155  if (x != -1)
156  windowXPosition = x;
157  if (y != -1)
158  windowYPosition = y;
159 
160  //we prepare the window's thread creation
161  threadParam * param = new threadParam;
162  param->x = windowXPosition;
163  param->y = windowYPosition;
164  param->w = width;
165  param->h = height;
166  param->vpDisp = this;
167  param->title = this->title;
168 
169  //creates the window in a separate thread
170  hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)vpCreateWindow,
171  param,0,&threadId);
172 
173  //the initialization worked
174  iStatus = (hThread != (HANDLE)NULL);
175 
177 }
178 
179 
185 {
186  //if the window is not initialized yet
187  if(!window.isInitialized())
188  {
189  //wait
190  if( WAIT_OBJECT_0 != WaitForSingleObject(window.semaInit,MAX_INIT_DELAY))
192  "Window not initialized")) ;
193  //problem : the window is not initialized
194  }
195 }
196 
197 
210 {
211  //waits if the window is not initialized
212  waitForInit();
213 
214  //sets the image to render
215  window.renderer->setImg(I);
216  //sends a message to the window
217  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
218 }
219 
220 
238 void vpDisplayWin32::displayImageROI ( const vpImage<vpRGBa> &I,const vpImagePoint &iP, const unsigned int width, const unsigned int height )
239 {
240  //waits if the window is not initialized
241  waitForInit();
242 
243  //sets the image to render
244  window.renderer->setImgROI(I,iP,width,height);
245  //sends a message to the window
246  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
247 }
248 
249 
262 {
263  //wait if the window is not initialized
264  waitForInit();
265 
266  //sets the image to render
267  window.renderer->setImg(I);
268  //sends a message to the window
269  //PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
270 }
271 
289 void vpDisplayWin32::displayImageROI ( const vpImage<unsigned char> &I,const vpImagePoint &iP, const unsigned int width, const unsigned int height )
290 {
291  //waits if the window is not initialized
292  waitForInit();
293 
294  //sets the image to render
295  window.renderer->setImgROI(I,iP,width,height);
296  //sends a message to the window
297  //PostMessage(window.getHWnd(),vpWM_DISPLAY,0,0);
298 }
299 
300 
316 bool vpDisplayWin32::getClick( bool blocking)
317 {
318  //wait if the window is not initialized
319  waitForInit();
320  bool ret = false;
321  //sends a message to the window
322 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
323 
324  //waits for a button to be pressed
325  if(blocking){
326  WaitForSingleObject(window.semaClick, 0);
327  WaitForSingleObject(window.semaClickUp, 0); //to erase previous events
328  WaitForSingleObject(window.semaClick, INFINITE);
329  ret = true;
330  }
331  else {
332  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
333  }
334 
335  return ret;
336 }
337 
338 
355 bool vpDisplayWin32::getClick(vpImagePoint &ip, bool blocking)
356 {
357  //wait if the window is not initialized
358  waitForInit();
359 
360  bool ret = false ;
361  double u, v;
362  //tells the window there has been a getclick demand
363 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
364  //waits for a click
365  if(blocking){
366  WaitForSingleObject(window.semaClick, 0);
367  WaitForSingleObject(window.semaClickUp, 0);//to erase previous events
368  WaitForSingleObject(window.semaClick, INFINITE);
369  ret = true;
370  }
371  else {
372  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
373  }
374 
375  u = window.clickX;
376  v = window.clickY;
377  ip.set_u( u );
378  ip.set_v( v );
379 
380  return ret;
381 }
382 
383 
404  bool blocking)
405 {
406  //wait if the window is not initialized
407  waitForInit();
408  bool ret = false;
409  double u, v;
410  //tells the window there has been a getclickup demand
411 // PostMessage(window.getHWnd(), vpWM_GETCLICK, 0,0);
412  //waits for a click
413  if(blocking){
414  WaitForSingleObject(window.semaClick, 0);
415  WaitForSingleObject(window.semaClickUp, 0);//to erase previous events
416  WaitForSingleObject(window.semaClick, INFINITE);
417  ret = true;
418  }
419  else
420  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClick, 0));
421 
422  u = window.clickX;
423  v = window.clickY;
424  ip.set_u( u );
425  ip.set_v( v );
426  button = window.clickButton;
427 
428  return ret;
429 }
430 
431 
456  bool blocking)
457 {
458  //wait if the window is not initialized
459  waitForInit();
460  bool ret = false;
461  double u, v;
462  //tells the window there has been a getclickup demand
463 // PostMessage(window.getHWnd(), vpWM_GETCLICKUP, 0,0);
464 
465  //waits for a click release
466  if(blocking){
467  WaitForSingleObject(window.semaClickUp, 0);
468  WaitForSingleObject(window.semaClick, 0);//to erase previous events
469  WaitForSingleObject(window.semaClickUp, INFINITE);
470  ret = true;
471  }
472  else
473  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaClickUp, 0));
474 
475  u = window.clickXUp;
476  v = window.clickYUp;
477  ip.set_u( u );
478  ip.set_v( v );
479  button = window.clickButtonUp;
480 
481  return ret;
482 }
483 
499 bool vpDisplayWin32::getKeyboardEvent( bool blocking )
500 {
501  //wait if the window is not initialized
502  waitForInit();
503 
504  bool ret = false ;
505  //waits for a keyboard event
506  if(blocking){
507  WaitForSingleObject(window.semaKey, 0); // key down
508  WaitForSingleObject(window.semaKey, 0); // key up
509  WaitForSingleObject(window.semaKey, INFINITE);
510  ret = true;
511  }
512  else
513  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
514 
515  return ret;
516 }
536 bool vpDisplayWin32::getKeyboardEvent(char *string, bool blocking)
537 {
538  //wait if the window is not initialized
539  waitForInit();
540 
541  bool ret = false ;
542  //waits for a keyboard event
543  if(blocking){
544  WaitForSingleObject(window.semaKey, 0); // key down
545  WaitForSingleObject(window.semaKey, 0); // key up
546  WaitForSingleObject(window.semaKey, INFINITE);
547  ret = true;
548  }
549  else {
550  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaKey, 0));
551  }
552  // printf("key: %ud\n", window.key);
553  sprintf(string, "%s", window.lpString);
554 
555  return ret;
556 }
567 bool
569 {
570  //wait if the window is not initialized
571  waitForInit();
572 
573  bool ret = false;
574 
575  ret = (WAIT_OBJECT_0 == WaitForSingleObject(window.semaMove, 0));
576  if (ret)
577  {
578  double u, v;
579  std::cout << "toto";
580  //tells the window there has been a getclick demand
581  //PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
582 
583  u = window.coordX;
584  v = window.coordY;
585  ip.set_u( u );
586  ip.set_v( v );
587  }
588 
589  return ret;
590 }
591 
602 bool
604 {
605  //wait if the window is not initialized
606  waitForInit();
607 
608  bool ret = true ;
609  double u, v;
610  //tells the window there has been a getclick demand
611  //PostMessage(window.getHWnd(), vpWM_GETPOINTERMOTIONEVENT, 0,0);
612 
613  u = window.coordX;
614  v = window.coordY;
615  ip.set_u( u );
616  ip.set_v( v );
617 
618  return ret;
619 }
620 
627 void vpDisplayWin32::setWindowPosition(int winx, int winy)
628 {
629  //wait if the window is not initialized
630  waitForInit();
631 
632  //cahange the window position only
633  SetWindowPos(window.hWnd,HWND_TOP, winx, winy, 0, 0,
634  SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOZORDER |SWP_NOSIZE);
635 
636 }
637 
638 
644 void vpDisplayWin32::setTitle(const char *windowtitle)
645 {
646  //wait if the window is not initialized
647  waitForInit();
648  SetWindowText(window.hWnd, windowtitle);
649 }
650 
651 
657 void vpDisplayWin32::setFont(const char * /* fontname */)
658 {
659  vpERROR_TRACE("Not yet implemented" ) ;
660 }
661 
662 
669 {
670  //waits if the window is not initialized
671  waitForInit();
672 
673  //sends a message to the window
674  PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
675 }
676 
682 void vpDisplayWin32::flushDisplayROI(const vpImagePoint &iP, const unsigned int width, const unsigned int height)
683 {
684  //waits if the window is not initialized
685  waitForInit();
686 
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 #ifdef FLUSH_ROI
693  typedef struct _half_rect_t{
694  unsigned short left_top;
695  unsigned short right_bottom;
696  } half_rect_t;
697 
698  half_rect_t hr1;
699  half_rect_t hr2;
700 
701  hr1.left_top = (unsigned short)iP.get_u();
702  hr1.right_bottom = (unsigned short)(iP.get_u()+width-1);
703 
704  hr2.left_top = (unsigned short)iP.get_v();
705  hr2.right_bottom = (unsigned short)(iP.get_v()+height-1);
706 
707  //sends a message to the window
708 # if 1 // new version FS
709  WPARAM wp = (hr1.left_top << sizeof(unsigned short)) + hr1.right_bottom;
710  LPARAM lp = (hr2.left_top << sizeof(unsigned short)) + hr2.right_bottom;
711 # else // produce warnings with MinGW
712  WPARAM wp=*((WPARAM*)(&hr1));
713  LPARAM lp=*((WPARAM*)(&hr2));
714 # endif
715  PostMessage(window.getHWnd(), vpWM_DISPLAY_ROI, wp,lp);
716 #else
717  PostMessage(window.getHWnd(), vpWM_DISPLAY, 0,0);
718 #endif
719 }
720 
721 
728  const vpColor &color )
729 {
730  //wait if the window is not initialized
731  waitForInit();
732  window.renderer->setPixel(ip, color);
733 }
734 
742  const vpImagePoint &ip2,
743  const vpColor &color,
744  unsigned int thickness )
745 {
746  //wait if the window is not initialized
747  waitForInit();
748  window.renderer->drawLine(ip1, ip2, color, thickness);
749 }
750 
751 
762  const vpImagePoint &ip2,
763  const vpColor &color,
764  unsigned int thickness )
765 {
766  //wait if the window is not initialized
767  waitForInit();
768  window.renderer->drawLine(ip1,ip2,color,thickness,PS_DASHDOT);
769 }
770 
785  unsigned int width, unsigned int height,
786  const vpColor &color, bool fill,
787  unsigned int thickness )
788 {
789  //wait if the window is not initialized
790  waitForInit();
791  window.renderer->drawRect(topLeft,width,height,color, fill, thickness);
792 }
793 
794 
808  const vpImagePoint &bottomRight,
809  const vpColor &color, bool fill,
810  unsigned int thickness )
811 {
812  //wait if the window is not initialized
813  waitForInit();
814  unsigned int width = static_cast<unsigned int>( bottomRight.get_j() - topLeft.get_j() );
815  unsigned int height = static_cast<unsigned int>(bottomRight.get_i() - topLeft.get_i() );
816  window.renderer->drawRect(topLeft,width,height,color, fill, thickness);
817 }
818 
831  const vpColor &color, bool fill,
832  unsigned int thickness )
833 {
834  //wait if the window is not initialized
835  waitForInit();
836  vpImagePoint topLeft;
837  topLeft.set_i(rectangle.getTop());
838  topLeft.set_j(rectangle.getLeft());
839  window.renderer->drawRect(topLeft,
840  static_cast<unsigned int>( rectangle.getWidth() ),
841  static_cast<unsigned int>( rectangle.getHeight() ),
842  color, fill, thickness);
843 }
844 
845 
856  unsigned int radius,
857  const vpColor &color,
858  bool fill,
859  unsigned int thickness )
860 {
861  //wait if the window is not initialized
862  waitForInit();
863  window.renderer->drawCircle(center,radius,color,fill,thickness);
864 }
865 
873  const char *text,
874  const vpColor &color )
875 {
876  //wait if the window is not initialized
877  waitForInit();
878  window.renderer->drawText(ip,text,color);
879 }
880 
889  unsigned int size,
890  const vpColor &color,
891  unsigned int thickness)
892 {
893  //wait if the window is not initialized
894  waitForInit();
895  window.renderer->drawCross(ip, size, color, thickness);
896 }
897 
898 
907  const vpImagePoint &ip2,
908  const vpColor &color,
909  unsigned int w,unsigned int h,
910  unsigned int thickness)
911 
912 {
913  //wait if the window is not initialized
914  waitForInit();
915  window.renderer->drawArrow(ip1, ip2, color, w, h, thickness);
916 }
917 
918 
924  //wait if the window is not initialized
925  waitForInit();
926  window.renderer->clear(color);
927 }
928 
929 
935 {
937  waitForInit();
938  PostMessage(window.getHWnd(), vpWM_CLOSEDISPLAY, 0,0);
939  //if the destructor is called for a reason different than a
940  //problem in the thread creation
941  if (iStatus) {
942  //waits for the thread to end
943  WaitForSingleObject(hThread, INFINITE);
944  CloseHandle(hThread);
945  }
946  displayHasBeenInitialized = false ;
947  window.initialized = false ;
948  }
949 }
950 
956 {
957  //wait if the window is not initialized
958  waitForInit();
959  window.renderer->getImage(I);
960 }
961 
962 #endif
void set_j(const double j)
Definition: vpImagePoint.h:156
vpDisplay * display
Definition: vpImage.h:121
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:169
void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)
double get_v() const
Definition: vpImagePoint.h:250
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)
unsigned int width
Definition: vpDisplay.h:187
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:159
virtual ~vpDisplayWin32()
bool getClick(bool blocking=true)
#define vpERROR_TRACE
Definition: vpDebug.h:379
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
double get_u() const
Definition: vpImagePoint.h:239
void setFont(const char *fontname)
Set the font used to display text.
void set_i(const double i)
Definition: vpImagePoint.h:145
double getHeight() const
Definition: vpRect.h:150
char * title
display title
Definition: vpDisplay.h:185
bool displayHasBeenInitialized
display has been initialized
Definition: vpDisplay.h:179
void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
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:192
void displayImageROI(const vpImage< unsigned char > &I, const vpImagePoint &iP, const unsigned int width, const unsigned int height)
bool getKeyboardEvent(bool blocking=true)
vpDisplayWin32(vpWin32Renderer *rend=NULL)
vpWin32Window window
The window.
bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true)
double getWidth() const
Definition: vpRect.h:188
void displayImage(const vpImage< vpRGBa > &I)
void set_u(const double u)
Definition: vpImagePoint.h:203
unsigned int height
Definition: vpDisplay.h:188
void set_v(const double v)
Definition: vpImagePoint.h:214
void setTitle(const char *windowtitle)
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)
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
void displayPoint(const vpImagePoint &ip, const vpColor &color)
friend void vpCreateWindow(threadParam *param)
Function used to launch the window in a thread.
bool getPointerMotionEvent(vpImagePoint &ip)
Error that can be emited by the vpDisplay class and its derivates.
HANDLE hThread
Handle of the window's thread.
int windowXPosition
display position
Definition: vpDisplay.h:181
unsigned int getHeight() const
Definition: vpImage.h:150
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:92
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 ...
int windowYPosition
display position
Definition: vpDisplay.h:183
void setWindowPosition(int winx, int winy)
double getLeft() const
Definition: vpRect.h:156
bool getPointerPosition(vpImagePoint &ip)
void getImage(vpImage< vpRGBa > &I)