Panda3D

winGraphicsWindow.h

00001 // Filename: winGraphicsWindow.h
00002 // Created by:  drose (20Dec02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #ifndef WINGRAPHICSWINDOW_H
00016 #define WINGRAPHICSWINDOW_H
00017 
00018 #include "pandabase.h"
00019 #include "graphicsWindow.h"
00020 #ifndef WIN32_LEAN_AND_MEAN
00021   #define WIN32_LEAN_AND_MEAN 1
00022 #endif
00023 #include <windows.h>
00024 
00025 class WinGraphicsPipe;
00026 
00027 #define PM_ACTIVE   (WM_APP+123)
00028 
00029 #define PM_INACTIVE  (WM_APP+124)
00030 
00031 typedef struct {
00032   int x;
00033   int y;
00034   int width;
00035   int height;
00036 }
00037 WINDOW_METRICS;
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //       Class : WinGraphicsWindow
00041 // Description : An abstract base class for glGraphicsWindow and
00042 //               dxGraphicsWindow (and, in general, graphics windows
00043 //               that interface with the Microsoft Windows API).
00044 //
00045 //               This class includes all the code for manipulating
00046 //               windows themselves: opening them, closing them,
00047 //               responding to user keyboard and mouse input, and so
00048 //               on.  It does not make any 3-D rendering calls into
00049 //               the window; that is the province of the
00050 //               GraphicsStateGuardian.
00051 ////////////////////////////////////////////////////////////////////
00052 class EXPCL_PANDAWIN WinGraphicsWindow : public GraphicsWindow {
00053 public:
00054   WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
00055                     const string &name,
00056                     const FrameBufferProperties &fb_prop,
00057                     const WindowProperties &win_prop,
00058                     int flags,
00059                     GraphicsStateGuardian *gsg,
00060                     GraphicsOutput *host);
00061   virtual ~WinGraphicsWindow();
00062 
00063   virtual bool move_pointer(int device, int x, int y);
00064 
00065   virtual void close_ime();
00066 
00067   virtual void begin_flip();
00068 
00069   virtual void process_events();
00070   virtual void set_properties_now(WindowProperties &properties);
00071   void receive_windows_message(unsigned int msg, int wparam, int lparam);
00072   virtual LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
00073   static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
00074   virtual bool handle_mouse_motion(int x, int y);
00075   virtual void handle_mouse_exit();
00076 
00077   INLINE HWND get_ime_hwnd();
00078 
00079 
00080 protected:
00081   virtual void close_window();
00082   virtual bool open_window();
00083   virtual void fullscreen_minimized(WindowProperties &properties);
00084   virtual void fullscreen_restored(WindowProperties &properties);
00085 
00086   virtual bool do_reshape_request(int x_origin, int y_origin, bool has_origin,
00087                                   int x_size, int y_size);
00088 
00089   virtual void handle_reshape();
00090   virtual bool do_fullscreen_resize(int x_size, int y_size);
00091 
00092   virtual bool do_fullscreen_switch();
00093   virtual bool do_windowed_switch();
00094   virtual bool do_fullscreen_enable();
00095   virtual bool do_fullscreen_disable();
00096 
00097   virtual bool calculate_metrics(bool fullscreen, DWORD style,
00098                                  WINDOW_METRICS &metrics, bool &has_origin);
00099 
00100   virtual DWORD make_style(bool fullscreen);
00101 
00102   virtual void reconsider_fullscreen_size(DWORD &x_size, DWORD &y_size, 
00103                                           DWORD &bitdepth);
00104 
00105   virtual void support_overlay_window(bool flag);
00106 
00107 private:
00108   bool open_graphic_window(bool fullscreen);
00109   void adjust_z_order();
00110   void adjust_z_order(WindowProperties::ZOrder last_z_order,
00111                       WindowProperties::ZOrder this_z_order);
00112   void initialize_input_devices();
00113   void handle_raw_input(HRAWINPUT hraw);
00114   void track_mouse_leaving(HWND hwnd);
00115 
00116   void set_focus();
00117 
00118   static void process_1_event();
00119 
00120   INLINE void handle_keypress(ButtonHandle key, int x, int y, double time);
00121   INLINE void handle_keyresume(ButtonHandle key, double time);
00122   INLINE void handle_keyrelease(ButtonHandle key, double time);
00123   ButtonHandle lookup_key(WPARAM wparam) const;
00124   INLINE int translate_mouse(int pos) const;
00125   INLINE void set_cursor_in_window();
00126   INLINE void set_cursor_out_of_window();
00127 
00128   INLINE static double get_message_time();
00129 
00130   void resend_lost_keypresses();
00131   static void update_cursor_window(WinGraphicsWindow *to_window);
00132   static void hide_or_show_cursor(bool hide_cursor);
00133 
00134   static bool find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight,
00135                                            DWORD bpp, DEVMODE &dm);
00136   static void show_error_message(DWORD message_id = 0);
00137 
00138 protected:
00139   HWND _hWnd;
00140   HWND _hparent;
00141 
00142 private:
00143   HWND _ime_hWnd;
00144   bool _ime_open;
00145   bool _ime_active;
00146   bool _tracking_mouse_leaving;
00147   bool _maximized;
00148   bool _bCursor_in_WindowClientArea;
00149   HANDLE _input_device_handle[32];
00150   HCURSOR _cursor;
00151   DEVMODE _fullscreen_display_mode;
00152 
00153   // This is used to remember the state of the keyboard when keyboard
00154   // focus is lost.
00155   enum { num_virtual_keys = 256 };
00156   // You might be wondering why the above is an enum. Originally the line
00157   // read "static const int num_virtual_keys = 256"
00158   // but in trying to support the MSVC6 compiler, we found that you
00159   // were not allowed to define the value of a const within a class like
00160   // that. Defining the value outside the class helps, but then we can't
00161   // use the value to define the length of the _keyboard_state array, and
00162   // also it creates multiply defined symbol errors when you link, because
00163   // other files include this header file. This enum is a clever solution
00164   // to work around the problem.
00165 
00166   BYTE _keyboard_state[num_virtual_keys];
00167   bool _lost_keypresses;
00168 
00169   // These are used to store the status of the individual left and right
00170   // shift, control, and alt keys.  Keyboard events are not sent for
00171   // these individual keys, but for each pair as a whole.  The status
00172   // of each key must be checked as keypress and keyrelease events are
00173   // received.
00174   bool _lshift_down;
00175   bool _rshift_down;
00176   bool _lcontrol_down;
00177   bool _rcontrol_down;
00178   bool _lalt_down;
00179   bool _ralt_down;
00180 
00181 private:
00182   // We need this map to support per-window calls to window_proc().
00183   typedef map<HWND, WinGraphicsWindow *> WindowHandles;
00184   static WindowHandles _window_handles;
00185 
00186   // And we need a static pointer to the current WinGraphicsWindow we
00187   // are creating at the moment, since CreateWindow() starts
00188   // generating window events before it gives us the window handle.
00189   static WinGraphicsWindow *_creating_window;
00190 
00191   // This tracks the current GraphicsWindow whose client area contains
00192   // the mouse.  There will only be one of these at a time, and
00193   // storing the pointer here allows us to handle ambiguities in the
00194   // order in which messages are passed from Windows to the various
00195   // windows we manage.  This pointer is used by
00196   // set_cursor_in_window() to determine when it is time to call
00197   // update_cursor() to hide the cursor (or do other related
00198   // operations).
00199   static WinGraphicsWindow *_cursor_window;
00200   static bool _cursor_hidden;
00201   static bool _got_saved_params;
00202   static int _saved_mouse_trails;
00203   static BOOL _saved_cursor_shadow;
00204   static BOOL _saved_mouse_vanish;
00205 
00206   // Since the Panda API requests icons and cursors by filename, we
00207   // need a table mapping filenames to handles, so we can avoid
00208   // re-reading the file each time we change icons.
00209   typedef pmap<Filename, HANDLE> IconFilenames;
00210   static IconFilenames _icon_filenames;
00211   static IconFilenames _cursor_filenames;
00212 
00213   static HICON get_icon(const Filename &filename);
00214   static HCURSOR get_cursor(const Filename &filename);
00215 
00216   // The table of window classes we have registered.  We need to
00217   // register a different window class for each different window icon
00218   // (the cursor we can specify dynamically, later).  We might have
00219   // other requirements too, later.
00220   class WindowClass {
00221   public:
00222     INLINE WindowClass(const WindowProperties &props);
00223     INLINE bool operator < (const WindowClass &other) const;
00224 
00225     string _name;
00226     HICON _icon;
00227   };
00228 
00229   typedef pset<WindowClass> WindowClasses;
00230   static WindowClasses _window_classes;
00231   static int _window_class_index;
00232 
00233   static const WindowClass &register_window_class(const WindowProperties &props);
00234 private:
00235   // This subclass of WindowHandle is stored in _window_handle to
00236   // represent this particular window.  We use it to add hooks for
00237   // communicating with the parent window, in particular to receive
00238   // keyboard events from the parent window when necessary.
00239   class WinWindowHandle : public WindowHandle {
00240   public:
00241     WinWindowHandle(WinGraphicsWindow *window,
00242                     const WindowHandle &copy);
00243     void clear_window();
00244 
00245   protected:
00246     virtual void receive_windows_message(unsigned int msg, int wparam, int lparam);
00247 
00248   private:
00249     // Not reference-counted, to avoid a circular reference count.
00250     WinGraphicsWindow *_window;
00251 
00252   public:
00253     static TypeHandle get_class_type() {
00254       return _type_handle;
00255     }
00256     static void init_type() {
00257       WindowHandle::init_type();
00258       register_type(_type_handle, "WinWindowHandle",
00259                     WindowHandle::get_class_type());
00260     }
00261     virtual TypeHandle get_type() const {
00262       return get_class_type();
00263     }
00264     virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00265     
00266   private:
00267     static TypeHandle _type_handle;
00268   };
00269 
00270 public:
00271   static TypeHandle get_class_type() {
00272     return _type_handle;
00273   }
00274   static void init_type() {
00275     GraphicsWindow::init_type();
00276     register_type(_type_handle, "WinGraphicsWindow",
00277                   GraphicsWindow::get_class_type());
00278     WinWindowHandle::init_type();
00279   }
00280   virtual TypeHandle get_type() const {
00281     return get_class_type();
00282   }
00283   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00284 
00285 private:
00286   static TypeHandle _type_handle;
00287 };
00288 
00289 #define PRINT_LAST_ERROR 0
00290 extern EXPCL_PANDAWIN void PrintErrorMessage(DWORD msgID);
00291 extern EXPCL_PANDAWIN void ClearToBlack(HWND hWnd, const WindowProperties &props);
00292 extern EXPCL_PANDAWIN void get_client_rect_screen(HWND hwnd, RECT *view_rect);
00293 
00294 #include "winGraphicsWindow.I"
00295 
00296 #endif
 All Classes Functions Variables Enumerations