vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Mouse.C
Go to the documentation of this file.
1/* file: vrpn_Mouse.cpp
2 * author: Mike Weiblen mew@mew.cx 2004-01-14
3 * copyright: (C) 2003,2004 Michael Weiblen
4 * license: Released to the Public Domain.
5 * depends: gpm 1.19.6, VRPN 06_04
6 * tested on: Linux w/ gcc 2.95.4
7 * references: http://mew.cx/ http://vrpn.org/
8 * http://linux.schottelius.org/gpm/
9*/
10
11#include <stdio.h> // for NULL, fprintf, printf, etc
12#include <string.h>
13
14#include "vrpn_BaseClass.h" // for ::vrpn_TEXT_ERROR
15#include "vrpn_Mouse.h"
16#include "vrpn_Serial.h" // for vrpn_open_commport, etc
17
18#if defined(linux) && defined(VRPN_USE_GPM_MOUSE)
19#include <gpm.h> // for Gpm_Event, Gpm_Connect, etc
20#endif
21
22
23#if !( defined(_WIN32) && defined(VRPN_USE_WINSOCK_SOCKETS) )
24# include <sys/select.h> // for select, FD_ISSET, FD_SET, etc
25#endif
26
27#ifdef _WIN32
28#include <windows.h>
29
30#pragma comment (lib, "user32.lib")
31
32// Fix sent in by Andrei State to make this compile under Visual Studio 6.0.
33// If you need this, you also have to copy multimon.h from the DirectX or
34// another Windows SDK into a place where the compiler can find it.
35#ifndef SM_XVIRTUALSCREEN
36#define COMPILE_MULTIMON_STUBS
37#include "multimon.h"
38#endif
39
40#endif
41
43
44vrpn_Mouse::vrpn_Mouse( const char* name, vrpn_Connection * cxn ) :
45 vrpn_Analog( name, cxn ),
46 vrpn_Button_Filter( name, cxn )
47{
48 int i;
49
50 // initialize the vrpn_Analog
52 for( i = 0; i < vrpn_Analog::num_channel; i++) {
54 }
55
56 // initialize the vrpn_Button_Filter
58 for( i = 0; i < vrpn_Button_Filter::num_buttons; i++) {
60 }
61
62#if defined(linux) && defined(VRPN_USE_GPM_MOUSE)
63 // attempt to connect to the GPM server
64 gpm_zerobased = 1;
65 gpm_visiblepointer = 1;
66
67 Gpm_Connect gc;
68 gc.eventMask = ~0;
69 gc.defaultMask = GPM_MOVE | GPM_HARD;
70 gc.maxMod = 0;
71 gc.minMod = 0;
72
73 if( Gpm_Open( &gc, 0 ) < 0 )
74 {
75 // either GPM server is not running, or we're trying to run
76 // on an xterm.
77 throw GpmOpenFailure();
78 }
79
80 set_alerts( 1 );
81#elif defined(_WIN32)
82 // Nothing needs to be opened under Windows; we just make direct
83 // calls below to find the values.
84#else
85 fprintf(stderr,"vrpn_Mouse::vrpn_Mouse() Not implement on this architecture\n");
86#endif
87}
88
90
92{
93#if defined(linux) && defined(VRPN_USE_GPM_MOUSE)
94 Gpm_Close();
95#endif
96}
97
99
101{
102 get_report();
104}
105
107
109{
110#if defined(linux) && defined(VRPN_USE_GPM_MOUSE)
111 fd_set readset;
112
113 FD_ZERO( &readset );
114 FD_SET( gpm_fd, &readset );
115 struct timeval timeout = { 0, 0 };
116 select( gpm_fd+1, &readset, NULL, NULL, &timeout );
117 if( ! FD_ISSET( gpm_fd, &readset ) )
118 return 0;
119
120 Gpm_Event evt;
121 if( Gpm_GetEvent( &evt ) <= 0 )
122 return 0;
123
124 if( evt.type & GPM_UP )
125 {
126 if( evt.buttons & GPM_B_LEFT ) buttons[0] = 0;
127 if( evt.buttons & GPM_B_MIDDLE ) buttons[1] = 0;
128 if( evt.buttons & GPM_B_RIGHT ) buttons[2] = 0;
129 }
130 else
131 {
132 buttons[0] = (evt.buttons & GPM_B_LEFT) ? 1 : 0;
133 buttons[1] = (evt.buttons & GPM_B_MIDDLE) ? 1 : 0;
134 buttons[2] = (evt.buttons & GPM_B_RIGHT) ? 1 : 0;
135 }
136
137 channel[0] = (vrpn_float64) evt.dx / gpm_mx;
138 channel[1] = (vrpn_float64) evt.dy / gpm_my;
139 return 1;
140#elif defined(_WIN32)
141 const unsigned LEFT_MOUSE_BUTTON = 0x01;
142 const unsigned RIGHT_MOUSE_BUTTON = 0x02;
143 const unsigned MIDDLE_MOUSE_BUTTON = 0x04;
144
145 // Find out if the mouse buttons are pressed.
146 if (0x80000 & GetKeyState(LEFT_MOUSE_BUTTON)) {
148 } else {
150 }
151 if (0x80000 & GetKeyState(MIDDLE_MOUSE_BUTTON)) {
153 } else {
155 }
156 if (0x80000 & GetKeyState(RIGHT_MOUSE_BUTTON)) {
158 } else {
160 }
161
162 // Find the position of the cursor in X,Y with range 0..1 across the screen
163 POINT curPos;
164 GetCursorPos(&curPos);
165 vrpn_Analog::channel[0] = (vrpn_float64)(curPos.x - GetSystemMetrics(SM_XVIRTUALSCREEN)) / GetSystemMetrics(SM_CXVIRTUALSCREEN);
166 vrpn_Analog::channel[1] = (vrpn_float64)(curPos.y - GetSystemMetrics(SM_YVIRTUALSCREEN)) / GetSystemMetrics(SM_CYVIRTUALSCREEN);
167
170 return 1;
171#else
172 return 0;
173#endif
174}
175
177
186
188
189void vrpn_Mouse::report( vrpn_uint32 class_of_service )
190{
193
194 vrpn_Analog::report( class_of_service );
196}
197
199#define BUTTON_READY (1)
200#define BUTTON_FAIL (-1)
201
202// (RDK) serial mouse wired up as button device
204 const char *port, int baud, vrpn_MOUSETYPE type)
205 : vrpn_Button_Filter(name, c)
206{
208 printed_error = false;
209 // Find out the port name and baud rate;
210 if (port == NULL) {
211 fprintf(stderr,"vrpn_Button_SerialMouse: NULL port name\n");
212 return;
213 } else {
214 vrpn_strcpy(portname, port);
215 portname[sizeof(portname)-1] = '\0';
216 }
217 num_buttons = 3;
218 baudrate = baud;
219
220 // Open the serial port we are going to use
222 fprintf(stderr,"vrpn_Button_SerialMouse: Cannot open serial port\n");
223 return;
224 }
225
226 for (vrpn_int32 i = 0; i < num_buttons; i++) {
227 buttons[i] = lastbuttons[i] = 0;
229 }
230
231 mousetype = type;
232 lastL = lastR = 0;
233 // first time in read(), this will get set to 0
235
236 // Say we are ready and find out what time it is
239}
240
242{
243 // Call the generic server mainloop, since we are a server
245
246 switch (status) {
247 case BUTTON_READY:
248 read();
250 break;
251 case BUTTON_FAIL:
252 {
253 if (printed_error) break;
254 printed_error = true;
255 send_text_message("vrpn_Button_SerialMouse failure!", timestamp, vrpn_TEXT_ERROR);
256 }
257 break;
258 }
259}
260
261// Fill in the buttons[] array with the current value of each of the
262// buttons For a description of the protocols for a Microsoft 3button
263// mouse and a MouseSystems mouse, see http://www.hut.fi/~then/mytexts/mouse.html
265{
266 // Make sure we're ready to read
267 if (status != BUTTON_READY) {
268 return;
269 }
270
271 unsigned char buffer;
272
273 // process as long as we can get characters
274 int num = 1;
275 int debounce = 0;
276 while (num)
277 {
278 num = vrpn_read_available_characters(serial_fd, &buffer, 1);
279
280 if (num <= 0) {
281 if (debounce) {
282#ifdef VERBOSE
283 fprintf (stderr,"state: %d %d %d last: %d %d %d\n",
284 buttons[0],buttons[1],buttons[2],
285 lastL, lastM, lastR);
286#endif
287 lastL = buttons[0];
288 lastM = buttons[1];
289 lastR = buttons[2];
290 }
291 return; // nothing there or error, so return
292 }
293
294 switch (mousetype) {
296 // a mouse capable of 3 button emulation
297 // this mouse encodes its buttons in a byte that is one of
298 // 0xc0 0xd0 0xe0 0xf0.
299
300 // Throw away all bytes that are not one of C0, D0, E0 or F0.
301 if ( (buffer != 0xc0) && (buffer != 0xd0) &&
302 (buffer != 0xe0) && (buffer != 0xf0) ) {
303 continue;
304 }
305
306 buttons[0] = (unsigned char)( (buffer & 0x20)?1:0 );
307 buttons[2] = (unsigned char)( (buffer & 0x10)?1:0 );
308 // middle button check:: we get here without a change in left or right
309 // This means that we toggle the middle button by moving the mouse
310 // around while not pressing or releasing the other buttons!
311 if ((buttons[0] == lastL) && (buttons[2] == lastR) && !debounce) {
312 buttons[1] = (unsigned char)( lastM?0:1 );
313 }
314 debounce = 1;
315 break;
316
317 case MOUSESYSTEMS:
318
319 // mousesystems (real PC 3 button mouse) protocol
320 // The pc three button mouse encodes its buttons in a byte
321 // that looks like 1 0 0 0 0 lb mb rb
322
323 if ((buffer & 0xf8) != 0x80) { // Ignore all bytes but first in record
324 continue;
325 }
326 debounce = 1;
327 buttons[0] = (unsigned char)( (buffer & 4)?0:1 );
328 buttons[1] = (unsigned char)( (buffer & 2)?0:1 );
329 buttons[2] = (unsigned char)( (buffer & 1)?0:1 );
330 break;
331
332 default:
333 printf("vrpn_Button_SerialMouse::read(): Unknown mouse type\n");
334 break;
335 } // switch
336 } // while (num)
337}
338
339
340/*EOF*/
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:39
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
struct timeval timestamp
Definition vrpn_Analog.h:41
vrpn_int32 num_channel
Definition vrpn_Analog.h:40
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition vrpn_Analog.C:94
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition vrpn_Analog.C:71
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition vrpn_Button.h:66
virtual void report_changes(void)
vrpn_int32 buttonstate[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:68
void set_alerts(vrpn_int32)
vrpn_MOUSETYPE mousetype
Definition vrpn_Mouse.h:114
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition vrpn_Mouse.C:241
vrpn_Button_SerialMouse(const char *name, vrpn_Connection *connection, const char *port, int baud, vrpn_MOUSETYPE type)
Definition vrpn_Mouse.C:203
vrpn_int32 num_buttons
Definition vrpn_Button.h:48
struct timeval timestamp
Definition vrpn_Button.h:49
virtual void report_changes(void)
unsigned char lastbuttons[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:46
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition vrpn_Button.h:45
Generic connection class not specific to the transport mechanism.
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
send report whether or not changed
Definition vrpn_Mouse.C:189
virtual ~vrpn_Mouse()
Definition vrpn_Mouse.C:91
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition vrpn_Mouse.C:100
virtual int get_report()
Try to read reports from the device. Returns 1 if msg received, or 0 if none received.
Definition vrpn_Mouse.C:108
vrpn_Mouse(const char *name, vrpn_Connection *cxn)
Definition vrpn_Mouse.C:44
struct timeval timestamp
time of last report from device
Definition vrpn_Mouse.h:82
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
@ vrpn_TEXT_ERROR
#define BUTTON_READY
Definition vrpn_Button.C:36
#define BUTTON_FAIL
Definition vrpn_Button.C:37
const int vrpn_BUTTON_MOMENTARY
Definition vrpn_Button.h:19
vrpn_MOUSETYPE
Definition vrpn_Mouse.h:97
@ THREEBUTTON_EMULATION
Definition vrpn_Mouse.h:97
@ MOUSESYSTEMS
Definition vrpn_Mouse.h:97
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
int vrpn_open_commport(const char *portname, long baud, int charsize, vrpn_SER_PARITY parity, bool rts_flow)
Open a serial port, given its name and baud rate.
Definition vrpn_Serial.C:54
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
void vrpn_strcpy(char(&to)[charCount], const char *pSrc)
Null-terminated-string copy function that both guarantees not to overrun the buffer and guarantees th...
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99