Panda3D
|
00001 // Filename: graphicsWindowInputDevice.cxx 00002 // Created by: drose (24May00) 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 00016 #include "graphicsWindowInputDevice.h" 00017 #include "mouseButton.h" 00018 #include "keyboardButton.h" 00019 00020 #define EXPCL EXPCL_PANDA_DISPLAY 00021 #define EXPTP EXPTP_PANDA_DISPLAY 00022 #define TYPE GraphicsWindowInputDevice 00023 #define NAME vector_GraphicsWindowInputDevice 00024 00025 #include "vector_src.cxx" 00026 00027 // Tell GCC that we'll take care of the instantiation explicitly here. 00028 #ifdef __GNUC__ 00029 #pragma implementation 00030 #endif 00031 00032 //////////////////////////////////////////////////////////////////// 00033 // Function: GraphicsWindowInputDevice::Constructor 00034 // Access: Private 00035 // Description: Defines a new InputDevice for the window. Most 00036 // windows will have exactly one InputDevice: a 00037 // keyboard/mouse pair. Some may also add joystick 00038 // data, or additional mice or something. 00039 // 00040 // This private constructor is only used internally by 00041 // the named constructors, below. 00042 //////////////////////////////////////////////////////////////////// 00043 GraphicsWindowInputDevice:: 00044 GraphicsWindowInputDevice(GraphicsWindow *host, const string &name, int flags) : 00045 _host(host), 00046 _name(name), 00047 _flags(flags), 00048 _device_index(0), 00049 _event_sequence(0), 00050 _pointer_mode_enable(false), 00051 _pointer_speed(1.0), 00052 _pointer_true_x(0.0), 00053 _pointer_true_y(0.0), 00054 _enable_pointer_events(false) 00055 { 00056 } 00057 00058 //////////////////////////////////////////////////////////////////// 00059 // Function: GraphicsWindowInputDevice::pointer_only 00060 // Access: Public 00061 // Description: This named constructor returns an input device that 00062 // only has a pointing device, no keyboard. 00063 //////////////////////////////////////////////////////////////////// 00064 GraphicsWindowInputDevice GraphicsWindowInputDevice:: 00065 pointer_only(GraphicsWindow *host, const string &name) { 00066 return GraphicsWindowInputDevice(host, name, IDF_has_pointer); 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: GraphicsWindowInputDevice::keyboard_only 00071 // Access: Public 00072 // Description: This named constructor returns an input device that 00073 // only has a keyboard, no pointing device. 00074 //////////////////////////////////////////////////////////////////// 00075 GraphicsWindowInputDevice GraphicsWindowInputDevice:: 00076 keyboard_only(GraphicsWindow *host, const string &name) { 00077 return GraphicsWindowInputDevice(host, name, IDF_has_keyboard); 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: GraphicsWindowInputDevice::pointer_and_keyboard 00082 // Access: Public 00083 // Description: This named constructor returns an input device that 00084 // has both a keyboard and pointer. 00085 //////////////////////////////////////////////////////////////////// 00086 GraphicsWindowInputDevice GraphicsWindowInputDevice:: 00087 pointer_and_keyboard(GraphicsWindow *host, const string &name) { 00088 return 00089 GraphicsWindowInputDevice(host, name, IDF_has_pointer | IDF_has_keyboard); 00090 } 00091 00092 //////////////////////////////////////////////////////////////////// 00093 // Function: GraphicsWindowInputDevice::Copy Constructor 00094 // Access: Public 00095 // Description: 00096 //////////////////////////////////////////////////////////////////// 00097 GraphicsWindowInputDevice:: 00098 GraphicsWindowInputDevice(const GraphicsWindowInputDevice ©) 00099 { 00100 *this = copy; 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function: GraphicsWindowInputDevice::Copy Assignment Operator 00105 // Access: Public 00106 // Description: 00107 //////////////////////////////////////////////////////////////////// 00108 void GraphicsWindowInputDevice:: 00109 operator = (const GraphicsWindowInputDevice ©) 00110 { 00111 LightMutexHolder holder(_lock); 00112 LightMutexHolder holder1(copy._lock); 00113 _host = copy._host; 00114 _name = copy._name; 00115 _flags = copy._flags; 00116 _device_index = copy._device_index; 00117 _event_sequence = copy._event_sequence; 00118 _pointer_mode_enable = copy._pointer_mode_enable; 00119 _pointer_speed = copy._pointer_speed; 00120 _pointer_true_x = copy._pointer_true_x; 00121 _pointer_true_y = copy._pointer_true_y; 00122 _enable_pointer_events = copy._enable_pointer_events; 00123 _mouse_data = copy._mouse_data; 00124 _true_mouse_data = copy._true_mouse_data; 00125 _button_events = copy._button_events; 00126 _pointer_events = copy._pointer_events; 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: GraphicsWindowInputDevice::Destructor 00131 // Access: Public 00132 // Description: 00133 //////////////////////////////////////////////////////////////////// 00134 GraphicsWindowInputDevice:: 00135 ~GraphicsWindowInputDevice() { 00136 } 00137 00138 //////////////////////////////////////////////////////////////////// 00139 // Function: GraphicsWindowInputDevice::has_button_event 00140 // Access: Public 00141 // Description: Returns true if this device has a pending button 00142 // event (a mouse button or keyboard button down/up), 00143 // false otherwise. If this returns true, the 00144 // particular event may be extracted via 00145 // get_button_event(). 00146 //////////////////////////////////////////////////////////////////// 00147 bool GraphicsWindowInputDevice:: 00148 has_button_event() const { 00149 LightMutexHolder holder(_lock); 00150 return !_button_events.empty(); 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: GraphicsWindowInputDevice::get_button_event 00155 // Access: Public 00156 // Description: Assuming a previous call to has_button_event() 00157 // returned true, this returns the pending button event. 00158 //////////////////////////////////////////////////////////////////// 00159 ButtonEvent GraphicsWindowInputDevice:: 00160 get_button_event() { 00161 LightMutexHolder holder(_lock); 00162 ButtonEvent be = _button_events.front(); 00163 _button_events.pop_front(); 00164 return be; 00165 } 00166 00167 //////////////////////////////////////////////////////////////////// 00168 // Function: GraphicsWindowInputDevice::has_pointer_event 00169 // Access: Public 00170 // Description: Returns true if this device has a pending pointer 00171 // event (a mouse movement), or false otherwise. If 00172 // this returns true, the particular event may be 00173 // extracted via get_pointer_event(). 00174 //////////////////////////////////////////////////////////////////// 00175 bool GraphicsWindowInputDevice:: 00176 has_pointer_event() const { 00177 LightMutexHolder holder(_lock); 00178 return (_pointer_events != 0); 00179 } 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: GraphicsWindowInputDevice::get_pointer_events 00183 // Access: Public 00184 // Description: Returns a PointerEventList containing all the recent 00185 // pointer events. 00186 //////////////////////////////////////////////////////////////////// 00187 PT(PointerEventList) GraphicsWindowInputDevice:: 00188 get_pointer_events() { 00189 LightMutexHolder holder(_lock); 00190 PT(PointerEventList) result = _pointer_events; 00191 _pointer_events = 0; 00192 return result; 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: GraphicsWindowInputDevice::enable_pointer_mode 00197 // Access: Public 00198 // Description: There are two modes: raw mode, and pointer mode. 00199 // In pointer mode, the mouse stops when it reaches the 00200 // edges of the window. In raw mode, the mouse ignores 00201 // the screen boundaries and can continue indefinitely, 00202 // even into negative coordinates. In raw mode, each 00203 // "blip" from the mouse hardware corresponds to a 00204 // change of 1 unit in the mouse's (x,y) coordinate. 00205 // In pointer mode, a variety of speed adjustment factors 00206 // and concepts like "mouse acceleration" may be applied. 00207 // 00208 // Mouse zero represents the system mouse pointer. This 00209 // is by definition a pointer, not a raw mouse. It is 00210 // an error to try to enable or disable pointer mode on 00211 // mouse zero. 00212 //////////////////////////////////////////////////////////////////// 00213 void GraphicsWindowInputDevice:: 00214 enable_pointer_mode(double speed) { 00215 LightMutexHolder holder(_lock); 00216 nassertv(_device_index != 0); 00217 _pointer_mode_enable = true; 00218 _pointer_speed = speed; 00219 _pointer_true_x = _host->get_x_size() * 0.5; 00220 _pointer_true_y = _host->get_y_size() * 0.5; 00221 _mouse_data._in_window = true; 00222 _mouse_data._xpos = int(_pointer_true_x + 0.5); 00223 _mouse_data._ypos = int(_pointer_true_y + 0.5); 00224 } 00225 00226 //////////////////////////////////////////////////////////////////// 00227 // Function: GraphicsWindowInputDevice::disable_pointer_mode 00228 // Access: Public 00229 // Description: see enable_pointer_mode. 00230 //////////////////////////////////////////////////////////////////// 00231 void GraphicsWindowInputDevice:: 00232 disable_pointer_mode() { 00233 LightMutexHolder holder(_lock); 00234 nassertv(_device_index != 0); 00235 _pointer_mode_enable = false; 00236 _pointer_speed = 1.0; 00237 _pointer_true_x = 0.0; 00238 _pointer_true_y = 0.0; 00239 _mouse_data = _true_mouse_data; 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: GraphicsWindowInputDevice::set_pointer 00244 // Access: Public 00245 // Description: Records that a mouse movement has taken place. 00246 //////////////////////////////////////////////////////////////////// 00247 void GraphicsWindowInputDevice:: 00248 set_pointer(bool inwin, int x, int y, double time) { 00249 LightMutexHolder holder(_lock); 00250 00251 int delta_x = x - _true_mouse_data._xpos; 00252 int delta_y = y - _true_mouse_data._ypos; 00253 _true_mouse_data._in_window = inwin; 00254 _true_mouse_data._xpos = x; 00255 _true_mouse_data._ypos = y; 00256 00257 if (_pointer_mode_enable) { 00258 _pointer_true_x += (delta_x * _pointer_speed); 00259 _pointer_true_y += (delta_y * _pointer_speed); 00260 double xhi = _host->get_x_size(); 00261 double yhi = _host->get_y_size(); 00262 if (_pointer_true_x < 0.0) _pointer_true_x = 0.0; 00263 if (_pointer_true_y < 0.0) _pointer_true_y = 0.0; 00264 if (_pointer_true_x > xhi) _pointer_true_x = xhi; 00265 if (_pointer_true_y > yhi) _pointer_true_y = yhi; 00266 _mouse_data._in_window = true; 00267 _mouse_data._xpos = int(_pointer_true_x + 0.5); 00268 _mouse_data._ypos = int(_pointer_true_y + 0.5); 00269 } else { 00270 _mouse_data = _true_mouse_data; 00271 } 00272 00273 if (_enable_pointer_events) { 00274 int seq = _event_sequence++; 00275 if (_pointer_events == 0) { 00276 _pointer_events = new PointerEventList(); 00277 } 00278 _pointer_events->add_event(_mouse_data._in_window, 00279 _mouse_data._xpos, 00280 _mouse_data._ypos, 00281 seq, time); 00282 } 00283 } 00284 00285 //////////////////////////////////////////////////////////////////// 00286 // Function: GraphicsWindowInputDevice::button_down 00287 // Access: Public 00288 // Description: Records that the indicated button has been depressed. 00289 //////////////////////////////////////////////////////////////////// 00290 void GraphicsWindowInputDevice:: 00291 button_down(ButtonHandle button, double time) { 00292 LightMutexHolder holder(_lock); 00293 _button_events.push_back(ButtonEvent(button, ButtonEvent::T_down, time)); 00294 _buttons_held.insert(button); 00295 } 00296 00297 //////////////////////////////////////////////////////////////////// 00298 // Function: GraphicsWindowInputDevice::button_resume_down 00299 // Access: Public 00300 // Description: Records that the indicated button was depressed 00301 // earlier, and we only just detected the event after 00302 // the fact. This is mainly useful for tracking the 00303 // state of modifier keys. 00304 //////////////////////////////////////////////////////////////////// 00305 void GraphicsWindowInputDevice:: 00306 button_resume_down(ButtonHandle button, double time) { 00307 LightMutexHolder holder(_lock); 00308 _button_events.push_back(ButtonEvent(button, ButtonEvent::T_resume_down, time) 00309 ); 00310 _buttons_held.insert(button); 00311 } 00312 00313 //////////////////////////////////////////////////////////////////// 00314 // Function: GraphicsWindowInputDevice::button_up 00315 // Access: Public 00316 // Description: Records that the indicated button has been released. 00317 //////////////////////////////////////////////////////////////////// 00318 void GraphicsWindowInputDevice:: 00319 button_up(ButtonHandle button, double time) { 00320 LightMutexHolder holder(_lock); 00321 _button_events.push_back(ButtonEvent(button, ButtonEvent::T_up, time)); 00322 _buttons_held.erase(button); 00323 } 00324 00325 //////////////////////////////////////////////////////////////////// 00326 // Function: GraphicsWindowInputDevice::keystroke 00327 // Access: Public 00328 // Description: Records that the indicated keystroke has been 00329 // generated. 00330 //////////////////////////////////////////////////////////////////// 00331 void GraphicsWindowInputDevice:: 00332 keystroke(int keycode, double time) { 00333 LightMutexHolder holder(_lock); 00334 _button_events.push_back(ButtonEvent(keycode, time)); 00335 } 00336 00337 //////////////////////////////////////////////////////////////////// 00338 // Function: GraphicsWindowInputDevice::candidate 00339 // Access: Public 00340 // Description: Records that the indicated candidate string has been 00341 // highlighted. This is used to implement IME support 00342 // for typing in international languages, especially 00343 // Chinese/Japanese/Korean. 00344 //////////////////////////////////////////////////////////////////// 00345 void GraphicsWindowInputDevice:: 00346 candidate(const wstring &candidate_string, size_t highlight_start, 00347 size_t highlight_end, size_t cursor_pos) { 00348 LightMutexHolder holder(_lock); 00349 _button_events.push_back(ButtonEvent(candidate_string, 00350 highlight_start, highlight_end, 00351 cursor_pos)); 00352 } 00353 00354 //////////////////////////////////////////////////////////////////// 00355 // Function: GraphicsWindowInputDevice::focus_lost 00356 // Access: Public 00357 // Description: This should be called when the window focus is lost, 00358 // so that we may miss upcoming button events 00359 // (especially "up" events) for the next period of time. 00360 // It generates keyboard and mouse "up" events for those 00361 // buttons that we previously sent unpaired "down" 00362 // events, so that the Panda application will believe 00363 // all buttons are now released. 00364 //////////////////////////////////////////////////////////////////// 00365 void GraphicsWindowInputDevice:: 00366 focus_lost(double time) { 00367 LightMutexHolder holder(_lock); 00368 ButtonsHeld::iterator bi; 00369 for (bi = _buttons_held.begin(); bi != _buttons_held.end(); ++bi) { 00370 _button_events.push_back(ButtonEvent(*bi, ButtonEvent::T_up, time)); 00371 } 00372 _buttons_held.clear(); 00373 }