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