Panda3D
 All Classes Functions Variables Enumerations
graphicsWindowInputDevice.cxx
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 &copy) 
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 &copy) 
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 }
 All Classes Functions Variables Enumerations