00001
00002 #include "dev/dev.H"
00003 #include "mlib/points.H"
00004 #include "std/stop_watch.H"
00005 #include "std/config.H"
00006
00007 #include <GL/glut.h>
00008 #include "glut_winsys.H"
00009 #include "tty_glut.H"
00010 #include "mouse.H"
00011
00012 #include "kbd.H"
00013
00014 using mlib::PIXEL;
00015 using mlib::CXYpt;
00016
00017 #ifdef USE_GLUT_WACOM
00018 #include "glutwacom/glutwacom.h"
00019
00020 static bool stylus_down = false;
00021 static bool eraser_down = false;
00022 static bool stylus2_down = false;
00023
00024 static bool debug = Config::get_var_bool("DEBUG_GLUT_WACOM",false);
00025
00026 inline str_ptr
00027 wacom_device_name(int device)
00028 {
00029
00030
00031 switch(device) {
00032 case GLUT_WACOM_CURSOR:
00033 return "cursor";
00034 case GLUT_WACOM_STYLUS:
00035 return "stylus";
00036 case GLUT_WACOM_ERASER:
00037 return "eraser";
00038 case GLUT_WACOM_MENU:
00039 return "menu";
00040 default:
00041 return "unkown device";
00042 }
00043 }
00044
00045 inline str_ptr
00046 wacom_button_state(int state)
00047 {
00048
00049
00050 switch (state) {
00051 case GLUT_WACOM_DOWN:
00052 return "down";
00053 case GLUT_WACOM_UP:
00054 return "up";
00055 default:
00056 return "unknown state";
00057 }
00058 }
00059
00060 inline str_ptr
00061 wacom_tablet_state(int state)
00062 {
00063
00064
00065 switch (state) {
00066 case GLUT_WACOM_STATE_OFF_TABLET:
00067 return "off tablet";
00068 case GLUT_WACOM_STATE_ON_TABLET:
00069 return "on tablet";
00070 case GLUT_WACOM_NO_STATE_INFO:
00071 return "unknown tablet state";
00072 default:
00073 return "undefined tablet state";
00074 }
00075 }
00076
00077 extern "C"
00078 void
00079 wacom_button_callback(
00080 int device, int button, int state, int tablet_state,
00081 float x, float y, float pressure, float xtilt, float ytilt,
00082 int proximity
00083 )
00084 {
00085 GLUT_MANAGER *mgr = (GLUT_MANAGER *)FD_MANAGER::mgr(); assert(mgr);
00086
00087
00088 if (mgr->get_blocker() == GLUT_WINSYS::window()) return;
00089
00090 if (debug || Config::get_var_bool("DEBUG_MOUSE_BUTTON_CALLBACK",false,true)) {
00091 cerr << wacom_device_name(device) << ", "
00092 << "(" << wacom_tablet_state(tablet_state) << "), "
00093 << "button: " << button << ", "
00094 << "(" << wacom_button_state(state) << ")"
00095 << endl;
00096 }
00097
00098 switch (device) {
00099 case GLUT_WACOM_CURSOR:
00100
00101 switch (button) {
00102 case GLUT_WACOM_TOP_LEFT_BUTTON:
00103 case GLUT_WACOM_TOP_MIDDLE_BUTTON:
00104 case GLUT_WACOM_TOP_RIGHT_BUTTON:
00105 case GLUT_WACOM_BOTTOM_RIGHT_BUTTON:
00106 case GLUT_WACOM_BOTTOM_LEFT_BUTTON:
00107 err_adv(debug, "wacom_button_callback: cursor button pressed");
00108 break;
00109 }
00110 break;
00111 case GLUT_WACOM_STYLUS:
00112
00113 switch (button) {
00114 case GLUT_WACOM_NO_BUTTON:
00115
00116 if (tablet_state == GLUT_WACOM_STATE_ON_TABLET) {
00117 stylus_down = true;
00118 GLUT_MOUSE::mouse()->buttons().event(
00119 GLUT_LEFT_BUTTON, DEVice_buttons::DOWN, Evd::NONE
00120 );
00121 } else {
00122 GLUT_MOUSE::mouse()->buttons().event(
00123 GLUT_LEFT_BUTTON, DEVice_buttons::UP, Evd::NONE
00124 );
00125 }
00126 break;
00127 case GLUT_WACOM_TOP_BUTTON:
00128 if (state == GLUT_WACOM_DOWN) {
00129 err_adv(debug, "wacom_button_callback: stylus top button pressed");
00130 } else {
00131 err_adv(debug, "wacom_button_callback: stylus top button released");
00132 }
00133 break;
00134 case GLUT_WACOM_BOTTOM_BUTTON:
00135 if (state == GLUT_WACOM_DOWN) {
00136 stylus2_down = true;
00137 GLUT_MOUSE::mouse()->buttons().event(
00138 GLUT_MIDDLE_BUTTON, DEVice_buttons::DOWN, Evd::NONE
00139 );
00140 } else {
00141 GLUT_MOUSE::mouse()->buttons().event(
00142 GLUT_MIDDLE_BUTTON, DEVice_buttons::UP, Evd::NONE
00143 );
00144 }
00145 break;
00146 }
00147 break;
00148 case GLUT_WACOM_ERASER:
00149
00150 if (tablet_state == GLUT_WACOM_STATE_ON_TABLET) {
00151 eraser_down = true;
00152 GLUT_MOUSE::mouse()->buttons().event(
00153 GLUT_RIGHT_BUTTON, DEVice_buttons::DOWN, Evd::NONE
00154 );
00155 } else {
00156 eraser_down = false;
00157 GLUT_MOUSE::mouse()->buttons().event(
00158 GLUT_RIGHT_BUTTON, DEVice_buttons::UP, Evd::NONE
00159 );
00160 }
00161 break;
00162 }
00163 }
00164
00165 extern "C"
00166 void
00167 wacom_motion_callback(
00168 int device, int tablet_state,
00169 float x, float y, float pressure,
00170 float , float ,
00171 int
00172 )
00173 {
00174
00175
00176
00177
00178
00179 GLUT_MOUSE *mouse = GLUT_MOUSE::mouse();
00180
00181 int w, h;
00182 mouse->winsys()->size(w, h);
00183 CXYpt cur(PIXEL(x, (double) h - y));
00184 mouse->pointer().set_pressure(pressure);
00185 mouse->pointer().event(cur, Evd::NONE);
00186
00187
00188
00189 if (debug) {
00190 cerr << wacom_device_name(device) << ", "
00191 << "(" << wacom_tablet_state(tablet_state) << "), "
00192 << cur << ", "
00193 << "pressure: " << pressure << endl;
00194 }
00195 }
00196
00197 #endif
00198
00199 ARRAY<GLUT_MOUSE *> GLUT_MOUSE::_mice(1);
00200
00201 extern "C"
00202 void
00203 mouse_motion_callback(
00204 int x,
00205 int y
00206 )
00207 {
00208 GLUT_MANAGER *mgr = (GLUT_MANAGER *)FD_MANAGER::mgr(); assert(mgr);
00209
00210
00211 if (mgr->get_blocker() == GLUT_WINSYS::window()) return;
00212
00213 #ifdef USE_GLUT_WACOM
00214 err_adv(debug, "mouse_motion_callback");
00215
00216
00217
00218 if (stylus_down || stylus2_down || eraser_down)
00219 return;
00220 #endif
00221
00222 GLUT_MOUSE *mouse = GLUT_MOUSE::mouse();
00223 int w, h;
00224 mouse->winsys()->size(w, h);
00225 CXYpt curs(PIXEL(x, (double) h - y));
00226
00227
00228
00229 mouse->pointer().set_pressure(1.0);
00230 mouse->pointer().event(curs, Evd::NONE);
00231
00232
00233
00234 mouse->winsys()->show_special_cursor(false);
00235 }
00236
00237 extern "C"
00238 void
00239 HACK_mouse_right_button_up()
00240 {
00241 #ifdef USE_GLUT_WACOM
00242 err_adv(debug, "HACK_mouse_right_button_up called");
00243 #endif
00244 GLUT_MOUSE::mouse()->buttons().event(
00245 GLUT_RIGHT_BUTTON, DEVice_buttons::UP, Evd::NONE
00246 );
00247 }
00248
00249 extern "C"
00250 void
00251 mouse_button_callback(
00252 int button,
00253 int state,
00254 int ,
00255 int
00256 )
00257 {
00258 GLUT_MANAGER *mgr = (GLUT_MANAGER *)FD_MANAGER::mgr(); assert(mgr);
00259
00260
00261 if (mgr->get_blocker() == GLUT_WINSYS::window()) return;
00262
00263 #ifdef USE_GLUT_WACOM
00264
00265
00266
00267
00268
00269 if (stylus_down) {
00270 if (state == GLUT_UP)
00271 stylus_down = false;
00272 return;
00273 }
00274 if (stylus2_down) {
00275 if (state == GLUT_UP)
00276 stylus2_down = false;
00277 return;
00278 }
00279 if (eraser_down) {
00280 if (state == GLUT_UP)
00281 eraser_down = false;
00282 return;
00283 }
00284 #endif
00285
00286 err_adv(Config::get_var_bool("DEBUG_MOUSE_BUTTON_CALLBACK",false,true),
00287 "button: %d, %s",
00288 button,
00289 (state == GLUT_DOWN) ? "down" : "up"
00290 );
00291
00292 GLUT_MOUSE *mouse = GLUT_MOUSE::mouse();
00293
00294 const int glut_mods = glutGetModifiers();
00295
00296 Evd::DEVmod mods = Evd::NONE;
00297
00298 switch (glut_mods) {
00299 case GLUT_ACTIVE_SHIFT:
00300 mods = Evd::SHIFT;
00301 break;
00302 case GLUT_ACTIVE_CTRL:
00303 mods = Evd::CONTROL;
00304 break;
00305 default:
00306 ;
00307 }
00308
00309 mouse->buttons().event(
00310 button,
00311 (state == GLUT_DOWN) ? DEVice_buttons::DOWN : DEVice_buttons::UP,
00312 mods);
00313 }
00314
00315
00316 GLUT_MOUSE::GLUT_MOUSE(GLUT_WINSYS *winsys) :
00317 _winsys(winsys)
00318 {
00319 while (_mice.num() <= winsys->id()) {
00320
00321
00322 _mice += (GLUT_MOUSE *) 0;
00323 }
00324 _mice[winsys->id()] = this;
00325
00326 #ifdef USE_GLUT_WACOM
00327 if (glutDeviceGet(GLUT_HAS_WACOM_TABLET)) {
00328 glutInitWacom();
00329 glutWacomButtonFunc(wacom_button_callback);
00330 glutWacomMotionFunc(wacom_motion_callback);
00331 err_adv(debug, "Initialized glutwacom");
00332
00333 } else {
00334 err_msg("GLUT_MOUSE::GLUT_MOUSE: Error: Tablet device not found");
00335 }
00336 #endif
00337
00338
00339
00340 glutMouseFunc(mouse_button_callback);
00341 glutMotionFunc(mouse_motion_callback);
00342 glutPassiveMotionFunc(mouse_motion_callback);
00343 }
00344
00345 GLUT_MOUSE::~GLUT_MOUSE()
00346 {
00347 cerr << "~GLUT_MOUSE" << endl;
00348 _mice[_winsys->id()] = 0;
00349 }
00350
00351 GLUT_MOUSE *
00352 GLUT_MOUSE::mouse()
00353 {
00354 return _mice[glutGetWindow()];
00355 }
00356
00357 void
00358 GLUT_CURSpush::push(
00359 CXYpt &pt
00360 )
00361 {
00362 if (_win) {
00363 _win->push_cursor(pt);
00364 }
00365 }
00366
00367
00368 void
00369 GLUT_CURSpush::handle_event(
00370 CEvd &e
00371 )
00372 {
00373 DEVice_2d *ice = (DEVice_2d *)e._d;
00374 push(ice->cur());
00375 }