Panda3D
|
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 PANDA_WIN7 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 ®ister_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 ©); 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