vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Button.C
Go to the documentation of this file.
1#include <stdio.h> // for fprintf, stderr, NULL, etc
2#ifndef _WIN32_WCE
3#include <fcntl.h> // for open, O_RDWR
4#endif
5#include <string.h>
6
7#if defined(linux) && !defined(VRPN_CLIENT_ONLY) && !defined(__ANDROID__)
8#define VRPN_USE_LINUX_PARALLEL_SUPPORT
9#include <linux/lp.h> // for LPGETSTATUS
10#include <sys/ioctl.h> // for ioctl
11#endif
12
13#include "vrpn_Connection.h" // for vrpn_Connection, etc
14#ifndef VRPN_CLIENT_ONLY
15#include "vrpn_Serial.h"
16#endif
17// Include vrpn_Shared.h _first_ to avoid conflicts with sys/time.h
18// and unistd.h
19#include "vrpn_Shared.h" // for timeval, vrpn_buffer, etc
20
21#ifdef linux
22#include <unistd.h>
23#endif
24#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(_WIN32_WCE)
25#include <conio.h> // for _inp()
26#endif
27
28#if (defined(sgi) && (!defined(VRPN_CLIENT_ONLY)))
29#include <gl/device.h>
30// need these for the gl based setdblight calls
31#include <gl/gl.h>
32#endif
33
34#include "vrpn_Button.h"
35
36#define BUTTON_READY (1)
37#define BUTTON_FAIL (-1)
38
39// Bits in the status register
40#ifndef VRPN_CLIENT_ONLY
41static const unsigned char PORT_ERROR = (1 << 3);
42static const unsigned char PORT_SLCT = (1 << 4);
43static const unsigned char PORT_PE = (1 << 5);
44static const unsigned char PORT_ACK = (1 << 6);
45static const unsigned char PORT_BUSY = (1 << 7);
46static const unsigned char BIT_MASK =
47 PORT_ERROR | PORT_SLCT | PORT_PE | PORT_ACK | PORT_BUSY;
48
49// message constants for the PinchGlove code.
50const unsigned char PG_START_BYTE_DATA(0x80);
51const unsigned char PG_START_BYTE_DATA_TIME(0x81);
52//const unsigned char PG_START_BYTE_TEXT(0x82);
53const unsigned char PG_END_BYTE(0x8F);
54#endif
55
56static int VRPN_CALLBACK
57client_msg_handler(void *userdata, vrpn_HANDLERPARAM p);
58
59#define PACK_ADMIN_MESSAGE(i, event) \
60 { \
61 char msgbuf[1000]; \
62 vrpn_int32 len = encode_to(msgbuf, i, event); \
63 if (d_connection->pack_message(len, timestamp, admin_message_id, \
64 d_sender_id, msgbuf, \
65 vrpn_CONNECTION_RELIABLE)) { \
66 fprintf(stderr, "vrpn_Button: can't write message: tossing\n"); \
67 } \
68 }
69#define PACK_ALERT_MESSAGE(i, event) \
70 { \
71 char msgbuf[1000]; \
72 vrpn_int32 len = encode_to(msgbuf, i, event); \
73 if (d_connection->pack_message(len, timestamp, alert_message_id, \
74 d_sender_id, msgbuf, \
75 vrpn_CONNECTION_RELIABLE)) { \
76 fprintf(stderr, "vrpn_Button: can't write message: tossing\n"); \
77 } \
78 }
79
80#define PACK_MESSAGE(i, event) \
81 { \
82 char msgbuf[1000]; \
83 vrpn_int32 len = encode_to(msgbuf, i, event); \
84 if (d_connection->pack_message(len, timestamp, change_message_id, \
85 d_sender_id, msgbuf, \
86 vrpn_CONNECTION_RELIABLE)) { \
87 fprintf(stderr, "vrpn_Button: can't write message: tossing\n"); \
88 } \
89 }
90
92 : vrpn_BaseClass(name, c)
93 , num_buttons(0)
94{
96
97 // Set the time to 0 just to have something there.
98 timestamp.tv_usec = timestamp.tv_sec = 0;
99 for (vrpn_int32 i = 0; i < vrpn_BUTTON_MAX_BUTTONS; i++) {
100 buttons[i] = lastbuttons[i] = 0;
101 }
102}
103
105{
106 // used to handle button strikes
108 d_connection->register_message_type("vrpn_Button Change");
109
110 // used to handle button states reports
112 d_connection->register_message_type("vrpn_Button States");
113
114 // to handle button state changes -- see Button_Filter should register a
115 // handler
116 // for this ID -- ideally the message will be ignored otherwise
118
119 return 0;
120}
121
122// virtual
124{
125
126 // do nothing
127}
128
130 : vrpn_Button(name, c)
131{
132 if ((d_sender_id == -1) || (admin_message_id == -1)) {
133 fprintf(stderr, "vrpn_Button: Can't register IDs\n");
134 d_connection = NULL;
135 }
136 register_autodeleted_handler(admin_message_id, client_msg_handler, this);
137
138 // setup message id type for alert messages to alert a device about changes
140 send_alerts = 0; // used to turn on/off alerts -- send and admin message
141 // from
142 // remote to turn it on -- or server side call set_alerts();
143
144 // Set up callback handler for ping message from client so that it
145 // sends the button states. This will make sure that the other side hears
146 // the initial button states. Also set this up
147 // to fire on the "new connection" system message.
148
154
155 // set button default buttonstates
156 for (vrpn_int32 i = 0; i < vrpn_BUTTON_MAX_BUTTONS; i++) {
158 }
159 return;
160}
161
163{
165 me->report_states();
166 return 0;
167}
168
170{
171 if (i == 0 || i == 1)
172 send_alerts = i;
173 else
174 fprintf(stderr, "Invalid send_alert state\n");
175 return;
176}
177
178void vrpn_Button_Filter::set_momentary(vrpn_int32 which_button)
179{
180 if (which_button >= num_buttons) {
181 char msg[200];
182 sprintf(msg, "vrpn_Button::set_momentary() buttons id %d is greater "
183 "than the number of buttons(%d)\n",
184 which_button, num_buttons);
186 return;
187 }
188 buttonstate[which_button] = vrpn_BUTTON_MOMENTARY;
190}
191
192void vrpn_Button::set_momentary(vrpn_int32 which_button)
193{
194 if (which_button >= num_buttons) {
195 char msg[200];
196 sprintf(msg, "vrpn_Button::set_momentary() buttons id %d is greater "
197 "than the number of buttons(%d)\n",
198 which_button, num_buttons);
200 return;
201 }
203}
204
205void vrpn_Button_Filter::set_toggle(vrpn_int32 which_button,
206 vrpn_int32 current_state)
207{
208 if (which_button >= num_buttons) {
209 char msg[200];
210 sprintf(msg, "vrpn_Button::set_toggle() buttons id %d is greater then "
211 "the number of buttons(%d)\n",
212 which_button, num_buttons);
214 return;
215 }
216 if (current_state == vrpn_BUTTON_TOGGLE_ON) {
217 buttonstate[which_button] = vrpn_BUTTON_TOGGLE_ON;
218 if (send_alerts)
220 }
221 else {
222 buttonstate[which_button] = vrpn_BUTTON_TOGGLE_OFF;
223 if (send_alerts)
225 }
226}
227void vrpn_Button::set_toggle(vrpn_int32 which_button, vrpn_int32 current_state)
228{
229 if (which_button >= num_buttons) {
230 char msg[200];
231 sprintf(msg, "vrpn_Button::set_toggle() buttons id %d is greater then "
232 "the number of buttons(%d)\n",
233 which_button, num_buttons);
235 return;
236 }
237 if (current_state == vrpn_BUTTON_TOGGLE_ON) {
239 }
240 else {
242 }
243}
244
246{
247 for (vrpn_int32 i = 0; i < num_buttons; i++) {
251 }
252 }
253}
254
256{
258}
259
260void vrpn_Button::set_all_toggle(vrpn_int32 default_state)
261{
262 PACK_ADMIN_MESSAGE(vrpn_ALL_ID, default_state);
263}
264
265void vrpn_Button_Filter::set_all_toggle(vrpn_int32 default_state)
266{
267 for (vrpn_int32 i = 0; i < num_buttons; i++) {
269 buttonstate[i] = default_state;
270 if (send_alerts) {
271 PACK_ALERT_MESSAGE(i, default_state);
272 }
273 }
274 }
275}
276
278{
279 vrpn_int32 i;
280 printf("CurrButtons: ");
281 for (i = num_buttons - 1; i >= 0; i--) {
282 printf("%c", buttons[i] ? '1' : '0');
283 }
284 printf("\n");
285
286 printf("LastButtons: ");
287 for (i = num_buttons - 1; i >= 0; i--) {
288 printf("%c", lastbuttons[i] ? '1' : '0');
289 }
290 printf("\n");
291}
292
299vrpn_int32 vrpn_Button::encode_to(char *buf, vrpn_int32 button,
300 vrpn_int32 state)
301{
302 char *bufptr = buf;
303 int buflen = 1000;
304
305 // Message includes: vrpn_int32 buttonNum, vrpn_int32 state
306 vrpn_buffer(&bufptr, &buflen, button);
307 vrpn_buffer(&bufptr, &buflen, state);
308
309 return 1000 - buflen;
310}
311
318vrpn_int32 vrpn_Button::encode_states_to(char *buf)
319{
320 // Message includes: vrpn_int32 number_of_buttons, vrpn_int32 states
321 // Byte order of each needs to be reversed to match network standard
322
323 vrpn_int32 int_btn = num_buttons;
324 int buflen = (vrpn_BUTTON_MAX_BUTTONS + 1) * sizeof(vrpn_int32);
325
326 vrpn_buffer(&buf, &buflen, int_btn);
327 for (int i = 0; i < num_buttons; i++) {
328 vrpn_int32 state = buttons[i];
329 vrpn_buffer(&buf, &buflen, state);
330 }
331
332 return (num_buttons + 1) * sizeof(vrpn_int32);
333}
334
342{
343 // Message includes: vrpn_int32 number_of_buttons, vrpn_int32 state
344 // Byte order of each needs to be reversed to match network standard
345
346 vrpn_int32 int_btn = num_buttons;
347 int buflen = (vrpn_BUTTON_MAX_BUTTONS + 1) * sizeof(vrpn_int32);
348
349 vrpn_buffer(&buf, &buflen, int_btn);
350 for (int i = 0; i < num_buttons; i++) {
351 vrpn_buffer(&buf, &buflen, buttonstate[i]);
352 }
353
354 return (num_buttons + 1) * sizeof(vrpn_int32);
355}
356
357static int VRPN_CALLBACK client_msg_handler(void *userdata, vrpn_HANDLERPARAM p)
358{
359 vrpn_Button_Filter *instance = (vrpn_Button_Filter *)userdata;
360 const char *bufptr = p.buffer;
361 vrpn_int32 event;
362 vrpn_int32 buttonid;
363
364 vrpn_unbuffer(&bufptr, &buttonid);
365 vrpn_unbuffer(&bufptr, &event);
366
367 if (event == vrpn_BUTTON_MOMENTARY) {
368 if (buttonid == vrpn_ALL_ID)
369 instance->set_all_momentary();
370 else
371 instance->set_momentary(buttonid);
372 }
373 else if (event == vrpn_BUTTON_TOGGLE_OFF ||
374 event == vrpn_BUTTON_TOGGLE_ON) {
375 if (buttonid == vrpn_ALL_ID)
376 instance->set_all_toggle(event);
377 else
378 instance->set_toggle(buttonid, event);
379 }
380 return 0;
381}
382
384{
385 vrpn_int32 i;
386
387 // vrpn_Button::report_changes();
388 if (d_connection) {
389 for (i = 0; i < num_buttons; i++) {
390 switch (buttonstate[i]) {
392 if (buttons[i] != lastbuttons[i]) PACK_MESSAGE(i, buttons[i]);
393 break;
395 if (buttons[i] && !lastbuttons[i]) {
397 if (send_alerts)
399 PACK_MESSAGE(i, 0);
400 }
401 break;
403 if (buttons[i] && !lastbuttons[i]) {
405 if (send_alerts)
407 PACK_MESSAGE(i, 1);
408 }
409 break;
410 default:
411 fprintf(stderr, "vrpn_Button::report_changes(): Button %d in \
412 invalid state (%d)\n",
413 i, buttonstate[i]);
414 }
415 lastbuttons[i] = buttons[i];
416 }
417 }
418 else {
419 fprintf(stderr, "vrpn_Button: No valid connection\n");
420 }
421}
422
424{
425 vrpn_int32 i;
426
427 if (d_connection) {
428 for (i = 0; i < num_buttons; i++) {
429 if (buttons[i] != lastbuttons[i]) PACK_MESSAGE(i, buttons[i]);
430 lastbuttons[i] = buttons[i];
431 }
432 }
433 else {
434 fprintf(stderr, "vrpn_Button: No valid connection\n");
435 }
436}
437
439{
440 // msgbuf must be int32-aligned!
441 vrpn_int32 ibuf[vrpn_BUTTON_MAX_BUTTONS + 1];
442 char *msgbuf = (char *)ibuf;
443
444 vrpn_int32 len;
445
446 len = vrpn_Button::encode_states_to(msgbuf);
447 if (d_connection &&
449 d_sender_id, msgbuf,
451 fprintf(stderr, "vrpn_Button: cannot write states message: tossing\n");
452 }
453}
454
455#ifndef VRPN_CLIENT_ONLY
456
458 int numbuttons)
459 : vrpn_Button_Filter(name, c)
460{
461 if (numbuttons > vrpn_BUTTON_MAX_BUTTONS) {
463 }
464 else {
465 num_buttons = numbuttons;
466 }
467}
468
470
472{
475}
476
477int vrpn_Button_Server::set_button(int button, int new_value)
478{
479 if ((button < 0) || (button >= num_buttons)) {
480 return -1;
481 }
482
483 buttons[button] = (unsigned char)(new_value != 0);
484
485 return 0;
486}
487
490 int numbuttons,
491 vrpn_float64 rate)
492 : vrpn_Button_Filter(name, c)
493{
494 if (numbuttons > vrpn_BUTTON_MAX_BUTTONS) {
496 }
497 else {
498 num_buttons = numbuttons;
499 }
500
501 _update_rate = rate;
502
503 // IN A REAL SERVER, open the device that will service the buttons here
504}
505
507{
508 struct timeval current_time;
509 int i;
510
511 // Call the generic server mainloop, since we are a server
513
514 // See if its time to generate a new report (every 1 second).
515 // IN A REAL SERVER, this check would not be done; although the
516 // time of the report would be updated to the current time so
517 // that the correct timestamp would be issued on the report.
518 vrpn_gettimeofday(&current_time, NULL);
519 if (vrpn_TimevalDuration(current_time, timestamp) >=
520 1000000.0 / _update_rate) {
521
522 // Update the time
523 timestamp.tv_sec = current_time.tv_sec;
524 timestamp.tv_usec = current_time.tv_usec;
525
526 // Update the values for the buttons, to say that each one has
527 // switched its state.
528 // THIS CODE WILL BE REPLACED by the user code that
529 // actually reads from the button devices and fills in buttons[]
530 // appropriately.
531 for (i = 0; i < num_buttons; i++) {
532 buttons[i] = !lastbuttons[i];
533 }
534
535 // Send reports. Stays the same in a real server.
537 }
538}
539
540// changed to take raw port hex address
542 int portno, unsigned porthex)
543 : vrpn_Button_Filter(name, c)
544{
545#if defined(VRPN_USE_LINUX_PARALLEL_SUPPORT)
546 const char *portname;
547 switch (portno) {
548 case 1:
549 portname = "/dev/lp0";
550 break;
551 case 2:
552 portname = "/dev/lp1";
553 break;
554 case 3:
555 portname = "/dev/lp2";
556 break;
557 default:
558 fprintf(stderr, "vrpn_Button_Parallel: "
559 "Bad port number (%x) for Linux lp#\n",
560 portno);
562 portname = "UNKNOWN";
563 break;
564 }
565
566 // Open the port
567 if ((port = open(portname, O_RDWR)) < 0) {
568 perror("vrpn_Button_Parallel::vrpn_Button_Parallel(): "
569 "Can't open port");
570 fprintf(stderr, "vrpn_Button_Parallel::vrpn_Button_Parallel(): "
571 "Can't open port %s\n",
572 portname);
574 return;
575 }
576#elif defined(_WIN32)
577 // if on NT we need a device driver to do direct reads
578 // from the parallel port
579 if (!openGiveIO()) {
580 fprintf(stderr, "vrpn_Button: need giveio driver for port access!\n");
581 fprintf(stderr, "vrpn_Button: can't use vrpn_Button()\n");
583 return;
584 }
585 if (porthex != 0) // using direct hex port address
586 port = porthex;
587 else { // using old style port 1, 2, or 3
588 switch (portno) {
589 // we use this mapping, although LPT? can actually
590 // have different addresses.
591 case 1:
592 port = 0x378;
593 break; // usually LPT1
594 case 2:
595 port = 0x3bc;
596 break; // usually LPT2
597 case 3:
598 port = 0x278;
599 break; // usually LPT3
600 default:
601 fprintf(stderr, "vrpn_Button_Parallel: Bad port number (%d)\n",
602 portno);
604 break;
605 }
606 }
607 fprintf(stderr, "vrpn_Button_Parallel: Using port %x\n", port);
608#else // not linux or _WIN32
609 fprintf(stderr, "vrpn_Button_Parallel: not supported on this platform\n?");
611 portno = portno + 1; // unused argument if we don't do something with it
612 porthex = porthex + 1; // unused argument if we don't do something with it
613 return;
614#endif
615
616#if defined(VRPN_USE_LINUX_PARALLEL_SUPPORT) || defined(_WIN32)
617// Set the INIT line on the device to provide power to the python
618// update: don't need this for builtin LPT1 on DELLs, but do need it
619// for warp9 PCI parallel port. Added next lines. BCE Nov07.00
620// Setting Bit 1 high also for a specific HiBall system
621// requirement (IR blocking device on same port)
622// - BCE 08 July 03
623
624#ifdef _outp
625 const unsigned short DATA_REGISTER_OFFSET = 0;
626 _outp((unsigned short)(port + DATA_REGISTER_OFFSET), 3);
627#else
628 fprintf(stderr, "vrpn_Button_Parallel: Not setting bit 0 on Linux, may not "
629 "work with all ports\n");
630#endif
631
632 // Zero the button states
633 num_buttons = 5; // XXX This is specific to the python
634 for (vrpn_int32 i = 0; i < num_buttons; i++) {
635 buttons[i] = lastbuttons[i] = 0;
636 }
637
640#endif
641}
642
644{
645#ifdef VRPN_USE_LINUX_PARALLEL_SUPPORT
646 if (port >= 0) {
647 close(port);
648 }
649#endif
650}
651
653 int p)
654 : vrpn_Button_Parallel(name, c, p)
655 , d_first_fail(true)
656{
657}
658
660 int p, unsigned ph)
661 : vrpn_Button_Parallel(name, c, p, ph)
662 , d_first_fail(true)
663{
664}
665
667{
668 // Call the generic server mainloop, since we are a server
670
671 switch (status) {
672 case BUTTON_READY:
673 read();
675 break;
676 case BUTTON_FAIL:
677 if (d_first_fail) {
678 d_first_fail = false;
679 fprintf(stderr, "vrpn_Button_Python failure!\n");
681 }
682 break;
683 }
684}
685
686// Fill in the buttons[] array with the current value of each of the
687// buttons. Debounce the buttons (make sure that they have had the
688// same value for the past several times to debounce noise).
690{
691 int i;
692 const int debounce_count = 30;
693 int status_register[debounce_count];
694
695 // Make sure we're ready to read
696 if (status != BUTTON_READY) {
697 return;
698 }
699
700// Read from the status register, read 3 times to debounce noise.
701#if defined(VRPN_USE_LINUX_PARALLEL_SUPPORT)
702 for (i = 0; i < debounce_count; i++)
703 if (ioctl(port, LPGETSTATUS, &status_register[i]) == -1) {
704 perror("vrpn_Button_Python::read(): ioctl() failed");
705 return;
706 }
707
708#elif defined(_WIN32)
709#ifndef __CYGWIN__
710 const unsigned short STATUS_REGISTER_OFFSET = 1;
711 for (i = 0; i < debounce_count; i++) {
712#ifdef _inp
713 status_register[i] =
714 _inp((unsigned short)(port + STATUS_REGISTER_OFFSET));
715#else // !_inp
716 status_register[i] = 0;
717#endif // _inp
718 }
719#else // __CYGWIN__
720 for (i = 0; i < debounce_count; i++) {
721 status_register[i] = 0;
722 }
723#endif // __CYGWIN
724#else // not _WIN32 or VRPN_USE_LINUX_PARALLEL_SUPPORT
725 for (i = 0; i < debounce_count; i++) {
726 status_register[i] = 0;
727 }
728#endif // _WIN32, VRPN_USE_LINUX_PARALLEL_SUPPORT
729 for (i = 0; i < debounce_count; i++) {
730 status_register[i] = status_register[i] & BIT_MASK;
731 }
732
733 // Make sure they are all the same; if not, return and assume that
734 // we are still debouncing.
735 for (i = 1; i < debounce_count; i++) {
736 if (status_register[0] != status_register[i]) {
737 return;
738 }
739 }
740
741 // Assign values to the bits based on the control signals
742 buttons[0] = ((status_register[0] & PORT_SLCT) == 0);
743 buttons[1] = ((status_register[0] & PORT_BUSY) != 0);
744 buttons[2] = ((status_register[0] & PORT_PE) == 0);
745 buttons[3] = ((status_register[0] & PORT_ERROR) == 0);
746 buttons[4] = ((status_register[0] & PORT_ACK) == 0);
747
749}
750
752 const char *port, long baud)
753 : vrpn_Button_Filter(name, c)
754{
755 // port name and baud rate
756 if (port == NULL) {
757 fprintf(stderr, "vrpn_Button_Serial: NULL port name\n");
759 return;
760 }
761 else {
762 vrpn_strcpy(portname, port);
763 }
764 baudrate = baud;
765
766 // Open the serial port
768 fprintf(stderr, "vrpn_Button_Serial: Cannot Open serial port\n");
770 }
771
772 // Reset the tracker and find out what time it is
775}
776
778
779// init pinch glove to send hand data only
782 const char *port, long baud)
783 : vrpn_Button_Serial(name, c, port, baud)
784 , reported_failure(false)
785{
786 num_buttons = 10; // 0-4: right, 5-9: left starting from thumb
788
789 // check if the number of buttons is not more than max allowed.
791 fprintf(stderr,
792 "vrpn_Button_PinchGlove: Too many buttons. The limit is ");
793 fprintf(stderr, "%i but this device has %i.\n", vrpn_BUTTON_MAX_BUTTONS,
796 }
797
798 // set glove to report with no timestamp
800
801 // initialize the buttons
802 for (vrpn_int32 i = 0; i < num_buttons; i++)
804
805 // Reset the tracker and find out what time it is
807}
808
810{
811 // Call the generic server mainloop, since we are a server
813
814 switch (status) {
815 case BUTTON_READY:
816 read();
818 break;
819 case BUTTON_FAIL: {
820 if (!reported_failure) {
821 reported_failure = true;
822 fprintf(stderr, "vrpn_Button_PinchGlove failure!\n");
823 }
824 } break;
825 }
826 return;
827}
828
829// Pinch glove should only report hand data(see contructor). If the message has
830// time stamp data change the the message type by sending command to just send
831// hand data. Any other kind of message is ignored and the buffer is read until
832// end of message byte(PG_END_BYTE) is reached.
834{
835 // check if button is ready
836 if (status != BUTTON_READY) return;
837
838 // check if there is something to read
839 if (vrpn_read_available_characters(serial_fd, buffer, 1) != 1) return;
840
841 // This while loop is to keep reading messages until its empty.
842 while (buffer[0] != PG_END_BYTE) {
843 // switch according to its message start byte
844 if (buffer[0] == PG_START_BYTE_DATA) {
845 // reset button state
846 for (vrpn_int32 i = 0; i < num_buttons; i++)
848
849 // read next message
851
852 // read until end of message
853 while (buffer[0] != PG_END_BYTE) {
854
855 // if only one byte read, read the left hand byte
856 while (bufcount != 2)
858 buffer + 1, 1);
859
860 unsigned char mask = 0x10;
861 // set button states
862 for (int j = 0; j < 5; j++, mask = (unsigned char)(mask >> 1)) {
863 if (mask & buffer[1]) { // right hand
865 }
866 if (mask & buffer[0]) { // left hand
867 buttons[j + 5] = VRPN_BUTTON_ON;
868 }
869 }
870
871 // read next bytes
873 } // while (buffer[0] != PG_END_BYTE)
874 // if there is another message read it
875 if (bufcount != 1) buffer[0] = buffer[1];
876 } // if (buffer[0] == PG_START_BYTE_DATA) {
877 else if (buffer[0] == PG_START_BYTE_DATA_TIME) {
879 "vrpn_Button_PinchGlove message start byte: time stamped byte!",
882 }
883 else { // ignore any other type of messages: empty butter till
884 // PG_END_BYTE
885 // clear messages
886 while (buffer[0] != PG_END_BYTE)
888 send_text_message("vrpn_Button_PinchGlove wrong message start byte",
890 } // else
891 } // while (buffer[0] != PG_END_BYTE )
892
894 return;
895}
896
897// set the glove to report data without timestamp
899{
900 struct timeval timeout = {
901 0, 30000}; // time_out for response from glove: 30 msec
902 struct timeval timeout_to_pass;
903
904 // read until correct reply is received
905 do {
907 vrpn_write_characters(serial_fd, (const unsigned char *)"T0", 2);
909 timeout_to_pass.tv_sec = timeout.tv_sec;
910 timeout_to_pass.tv_usec = timeout.tv_usec;
912 &timeout_to_pass);
913 } while ((bufcount != 3) || (buffer[1] != '0') ||
914 (buffer[2] != PG_END_BYTE));
915
916 return;
917}
918
919#endif // VRPN_CLIENT_ONLY
920
922 : vrpn_Button(name, cn)
923{
924 vrpn_int32 i;
925
926 // Register a handler for the change callback from this device,
927 // if we got a connection.
928 if (d_connection != NULL) {
931 fprintf(stderr,
932 "vrpn_Button_Remote: can't register change handler\n");
933 d_connection = NULL;
934 }
937 fprintf(stderr,
938 "vrpn_Button_Remote: can't register states handler\n");
939 d_connection = NULL;
940 }
941 }
942 else {
943 fprintf(stderr, "vrpn_Button_Remote: Can't get connection!\n");
944 }
945
946 // Fill in all possible buttons with off. The number of buttons
947 // will be overwritten when the states message comes in from the
948 // server.
950 for (i = 0; i < num_buttons; i++) {
951 buttons[i] = lastbuttons[i] = 0;
952 }
954}
955
956// virtual
958
960{
961 if (d_connection) {
963 }
965}
966
969{
971 const char *bufptr = p.buffer;
972 vrpn_BUTTONCB bp;
973
974 // Fill in the parameters to the button from the message
975 if (p.payload_len != 2 * sizeof(vrpn_int32)) {
976 fprintf(stderr, "vrpn_Button: change message payload error\n");
977 fprintf(stderr, " (got %d, expected %lud)\n", p.payload_len,
978 static_cast<unsigned long>(2 * sizeof(vrpn_int32)));
979 return -1;
980 }
981 bp.msg_time = p.msg_time;
982 vrpn_unbuffer(&bufptr, &bp.button);
983 vrpn_unbuffer(&bufptr, &bp.state);
984
985 // Go down the list of callbacks that have been registered.
986 // Fill in the parameter and call each.
988
989 return 0;
990}
991
994{
995 const char *bufptr = p.buffer;
996 vrpn_int32 numbuttons; //< Number of buttons
999
1000 cp.msg_time = p.msg_time;
1001 vrpn_unbuffer(&bufptr, &numbuttons);
1002 cp.num_buttons = numbuttons;
1003 me->num_buttons = cp.num_buttons;
1004 for (vrpn_int32 i = 0; i < cp.num_buttons; i++) {
1005 vrpn_unbuffer(&bufptr, &cp.states[i]);
1006 }
1007
1008 // Go down the list of callbacks that have been registered.
1009 // Fill in the parameter and call each.
1011
1012 return 0;
1013}
1014
1015// We use _inp (inport) to read the parallel port status register
1016// since we haven't found a way to do it through the Win32 API.
1017// On NT we need a special device driver (giveio) to be installed
1018// so that we can get permission to execute _inp. On Win95 we
1019// don't need to do anything.
1020//
1021// The giveio driver is from the May 1996 issue of Dr. Dobb's,
1022// an article by Dale Roberts called "Direct Port I/O and Windows NT"
1023//
1024// This function returns 1 if either running Win95 or running NT and
1025// the giveio device was opened. 0 if device not opened.
1026#ifndef VRPN_CLIENT_ONLY
1027#ifdef _WIN32
1028int vrpn_Button_Parallel::openGiveIO(void)
1029{
1030 OSVERSIONINFO osvi;
1031
1032 memset(&osvi, 0, sizeof(OSVERSIONINFO));
1033 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1034 GetVersionEx(&osvi);
1035
1036 // if Win95: no initialization required
1037 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
1038 return 1;
1039 }
1040
1041 // else if NT: use giveio driver
1042 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
1043 HANDLE h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,
1044 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1045 if (h == INVALID_HANDLE_VALUE) {
1046 // maybe driver not installed?
1047 return 0;
1048 }
1049 CloseHandle(h);
1050 // giveio opened successfully
1051 return 1;
1052 }
1053
1054 // else GetVersionEx gave unexpected result
1055 fprintf(stderr,
1056 "vrpn_Button_Parallel::openGiveIO: unknown windows version\n");
1057 return 0;
1058}
1059#endif // _WIN32
1060#endif // VRPN_CLIENT_ONLY
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Connection * d_connection
Connection that this object talks to.
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
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.
vrpn_int32 d_ping_message_id
Ask the server if they are there.
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Button.C:506
vrpn_Button_Example_Server(const char *name, vrpn_Connection *c, int numbuttons=1, vrpn_float64 rate=1.0)
Definition: vrpn_Button.C:488
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 set_momentary(vrpn_int32 which_button)
Definition: vrpn_Button.C:178
vrpn_int32 alert_message_id
Definition: vrpn_Button.h:79
virtual void report_changes(void)
Definition: vrpn_Button.C:383
static int VRPN_CALLBACK handle_ping_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Button.C:162
vrpn_int32 buttonstate[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:68
vrpn_Button_Filter(const char *, vrpn_Connection *c=NULL)
Definition: vrpn_Button.C:129
virtual void set_toggle(vrpn_int32 which_button, vrpn_int32 current_state)
Definition: vrpn_Button.C:205
virtual void set_all_toggle(vrpn_int32 default_state)
Definition: vrpn_Button.C:265
virtual vrpn_int32 encode_states_to(char *buf)
Encode a message describing the state of all buttons.
Definition: vrpn_Button.C:341
void set_alerts(vrpn_int32)
Definition: vrpn_Button.C:169
virtual void set_all_momentary(void)
Definition: vrpn_Button.C:245
vrpn_Button_Parallel(const char *name, vrpn_Connection *connection, int portno, unsigned porthex=0)
Definition: vrpn_Button.C:541
virtual void read()
Definition: vrpn_Button.C:833
vrpn_Button_PinchGlove(const char *name, vrpn_Connection *c, const char *port="/dev/ttyS1/", long baud=38400)
Definition: vrpn_Button.C:780
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Button.C:809
vrpn_Button_Python(const char *name, vrpn_Connection *c, int p)
Definition: vrpn_Button.C:652
virtual void read(void)
Definition: vrpn_Button.C:689
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Button.C:666
static int VRPN_CALLBACK handle_states_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Button.C:992
vrpn_Button_Remote(const char *name, vrpn_Connection *cn=NULL)
Definition: vrpn_Button.C:921
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Button.C:967
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Button.C:959
vrpn_Callback_List< vrpn_BUTTONCB > d_callback_list
Definition: vrpn_Button.h:287
vrpn_Callback_List< vrpn_BUTTONSTATESCB > d_states_callback_list
Definition: vrpn_Button.h:291
virtual ~vrpn_Button_Remote(void)
Definition: vrpn_Button.C:957
char portname[VRPN_BUTTON_BUF_SIZE]
Definition: vrpn_Button.h:181
virtual ~vrpn_Button_Serial()
Definition: vrpn_Button.C:777
vrpn_Button_Serial(const char *name, vrpn_Connection *c, const char *port="/dev/ttyS1/", long baud=38400)
Definition: vrpn_Button.C:751
unsigned char buffer[VRPN_BUTTON_BUF_SIZE]
Definition: vrpn_Button.h:187
vrpn_uint32 bufcount
Definition: vrpn_Button.h:188
virtual void mainloop()
Called once each time through the server program's mainloop to handle various functions (like setting...
Definition: vrpn_Button.C:471
vrpn_Button_Server(const char *name, vrpn_Connection *c, int numbuttons=1)
Definition: vrpn_Button.C:457
int set_button(int button, int new_value)
Allows the server program to set current button states (to 0 or 1)
Definition: vrpn_Button.C:477
int number_of_buttons(void)
Tells how many buttons there are (may be clipped to MAX_BUTTONS)
Definition: vrpn_Button.C:469
This is the base class for both the client and server for a button device (a device with one or more ...
Definition: vrpn_Button.h:31
virtual vrpn_int32 encode_states_to(char *buf)
Encode a message describing the state of all buttons.
Definition: vrpn_Button.C:318
virtual vrpn_int32 encode_to(char *buf, vrpn_int32 button, vrpn_int32 state)
Encode a message describing the new state of a button.
Definition: vrpn_Button.C:299
virtual ~vrpn_Button(void)
Definition: vrpn_Button.C:123
virtual void set_toggle(vrpn_int32 which_button, vrpn_int32 current_state)
Definition: vrpn_Button.C:227
vrpn_int32 change_message_id
Definition: vrpn_Button.h:50
void print(void)
Definition: vrpn_Button.C:277
vrpn_int32 admin_message_id
Definition: vrpn_Button.h:52
virtual void report_states(void)
Definition: vrpn_Button.C:438
virtual void set_momentary(vrpn_int32 which_button)
Definition: vrpn_Button.C:192
vrpn_int32 num_buttons
Definition: vrpn_Button.h:48
vrpn_int32 states_message_id
Definition: vrpn_Button.h:51
struct timeval timestamp
Definition: vrpn_Button.h:49
vrpn_Button(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Button.C:91
virtual void report_changes(void)
Definition: vrpn_Button.C:423
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
Definition: vrpn_Button.C:104
unsigned char lastbuttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:46
virtual void set_all_toggle(vrpn_int32 default_state)
Definition: vrpn_Button.C:260
virtual void set_all_momentary(void)
Definition: vrpn_Button.C:255
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:45
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Generic connection class not specific to the transport mechanism.
virtual vrpn_int32 register_message_type(const char *name)
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
vrpn_int32 button
Definition: vrpn_Button.h:228
vrpn_int32 state
Definition: vrpn_Button.h:229
struct timeval msg_time
Definition: vrpn_Button.h:227
vrpn_int32 states[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:242
vrpn_int32 num_buttons
Definition: vrpn_Button.h:241
struct timeval msg_time
Definition: vrpn_Button.h:240
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
vrpn_int32 payload_len
@ vrpn_TEXT_ERROR
#define PACK_ALERT_MESSAGE(i, event)
Definition: vrpn_Button.C:69
#define PACK_MESSAGE(i, event)
Definition: vrpn_Button.C:80
#define BUTTON_READY
Definition: vrpn_Button.C:36
#define PACK_ADMIN_MESSAGE(i, event)
Definition: vrpn_Button.C:59
const unsigned char PG_START_BYTE_DATA(0x80)
const unsigned char PG_END_BYTE(0x8F)
#define BUTTON_FAIL
Definition: vrpn_Button.C:37
const unsigned char PG_START_BYTE_DATA_TIME(0x81)
#define VRPN_BUTTON_ON
Definition: vrpn_Button.h:224
const int vrpn_BUTTON_MAX_BUTTONS
Definition: vrpn_Button.h:13
const int vrpn_BUTTON_TOGGLE_ON
Definition: vrpn_Button.h:21
const int vrpn_BUTTON_MOMENTARY
Definition: vrpn_Button.h:19
const int vrpn_ALL_ID
Definition: vrpn_Button.h:24
#define VRPN_BUTTON_OFF
Definition: vrpn_Button.h:223
const int vrpn_BUTTON_TOGGLE_OFF
Definition: vrpn_Button.h:20
#define VRPN_CALLBACK
const char * vrpn_got_connection
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
const int vrpn_ANY_SENDER
vrpn_ANY_SENDER can be used to register callbacks on a given message type from any sender.
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
Definition: vrpn_Serial.C:651
int vrpn_close_commport(int comm)
Definition: vrpn_Serial.C:348
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
Definition: vrpn_Serial.C:438
int vrpn_drain_output_buffer(int comm)
Wait until all of the characters in the output buffer are sent, then return.
Definition: vrpn_Serial.C:488
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
Definition: vrpn_Serial.C:515
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...
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:321
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
Definition: vrpn_Shared.C:138
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
Definition: vrpn_Shared.C:250
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...
Definition: vrpn_Shared.h:510
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:99