7#if defined(linux) && !defined(VRPN_CLIENT_ONLY) && !defined(__ANDROID__)
8#define VRPN_USE_LINUX_PARALLEL_SUPPORT
14#ifndef VRPN_CLIENT_ONLY
24#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(_WIN32_WCE)
28#if (defined(sgi) && (!defined(VRPN_CLIENT_ONLY)))
36#define BUTTON_READY (1)
37#define BUTTON_FAIL (-1)
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;
59#define PACK_ADMIN_MESSAGE(i, event) \
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"); \
69#define PACK_ALERT_MESSAGE(i, event) \
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"); \
80#define PACK_MESSAGE(i, event) \
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"); \
108 d_connection->register_message_type(
"vrpn_Button Change");
112 d_connection->register_message_type(
"vrpn_Button States");
133 fprintf(stderr,
"vrpn_Button: Can't register IDs\n");
171 if (i == 0 || i == 1)
174 fprintf(stderr,
"Invalid send_alert state\n");
182 sprintf(msg,
"vrpn_Button::set_momentary() buttons id %d is greater "
183 "than the number of buttons(%d)\n",
196 sprintf(msg,
"vrpn_Button::set_momentary() buttons id %d is greater "
197 "than the number of buttons(%d)\n",
206 vrpn_int32 current_state)
210 sprintf(msg,
"vrpn_Button::set_toggle() buttons id %d is greater then "
211 "the number of buttons(%d)\n",
231 sprintf(msg,
"vrpn_Button::set_toggle() buttons id %d is greater then "
232 "the number of buttons(%d)\n",
280 printf(
"CurrButtons: ");
282 printf(
"%c",
buttons[i] ?
'1' :
'0');
286 printf(
"LastButtons: ");
309 return 1000 - buflen;
360 const char *bufptr = p.
buffer;
411 fprintf(stderr,
"vrpn_Button::report_changes(): Button %d in \
412 invalid state (%d)\n",
419 fprintf(stderr,
"vrpn_Button: No valid connection\n");
434 fprintf(stderr,
"vrpn_Button: No valid connection\n");
442 char *msgbuf = (
char *)ibuf;
451 fprintf(stderr,
"vrpn_Button: cannot write states message: tossing\n");
455#ifndef VRPN_CLIENT_ONLY
483 buttons[button] = (
unsigned char)(new_value != 0);
508 struct timeval current_time;
524 timestamp.tv_usec = current_time.tv_usec;
542 int portno,
unsigned porthex)
545#if defined(VRPN_USE_LINUX_PARALLEL_SUPPORT)
546 const char *portname;
549 portname =
"/dev/lp0";
552 portname =
"/dev/lp1";
555 portname =
"/dev/lp2";
558 fprintf(stderr,
"vrpn_Button_Parallel: "
559 "Bad port number (%x) for Linux lp#\n",
562 portname =
"UNKNOWN";
567 if ((
port = open(portname, O_RDWR)) < 0) {
568 perror(
"vrpn_Button_Parallel::vrpn_Button_Parallel(): "
570 fprintf(stderr,
"vrpn_Button_Parallel::vrpn_Button_Parallel(): "
571 "Can't open port %s\n",
580 fprintf(stderr,
"vrpn_Button: need giveio driver for port access!\n");
581 fprintf(stderr,
"vrpn_Button: can't use vrpn_Button()\n");
601 fprintf(stderr,
"vrpn_Button_Parallel: Bad port number (%d)\n",
607 fprintf(stderr,
"vrpn_Button_Parallel: Using port %x\n",
port);
609 fprintf(stderr,
"vrpn_Button_Parallel: not supported on this platform\n?");
612 porthex = porthex + 1;
616#if defined(VRPN_USE_LINUX_PARALLEL_SUPPORT) || defined(_WIN32)
625 const unsigned short DATA_REGISTER_OFFSET = 0;
626 _outp((
unsigned short)(
port + DATA_REGISTER_OFFSET), 3);
628 fprintf(stderr,
"vrpn_Button_Parallel: Not setting bit 0 on Linux, may not "
629 "work with all ports\n");
645#ifdef VRPN_USE_LINUX_PARALLEL_SUPPORT
679 fprintf(stderr,
"vrpn_Button_Python failure!\n");
692 const int debounce_count = 30;
693 int status_register[debounce_count];
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");
710 const unsigned short STATUS_REGISTER_OFFSET = 1;
711 for (i = 0; i < debounce_count; i++) {
714 _inp((
unsigned short)(
port + STATUS_REGISTER_OFFSET));
716 status_register[i] = 0;
720 for (i = 0; i < debounce_count; i++) {
721 status_register[i] = 0;
725 for (i = 0; i < debounce_count; i++) {
726 status_register[i] = 0;
729 for (i = 0; i < debounce_count; i++) {
730 status_register[i] = status_register[i] & BIT_MASK;
735 for (i = 1; i < debounce_count; i++) {
736 if (status_register[0] != status_register[i]) {
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);
752 const char *port,
long baud)
757 fprintf(stderr,
"vrpn_Button_Serial: NULL port name\n");
768 fprintf(stderr,
"vrpn_Button_Serial: Cannot Open serial port\n");
782 const char *port,
long baud)
792 "vrpn_Button_PinchGlove: Too many buttons. The limit is ");
822 fprintf(stderr,
"vrpn_Button_PinchGlove failure!\n");
860 unsigned char mask = 0x10;
862 for (
int j = 0; j < 5; j++, mask = (
unsigned char)(mask >> 1)) {
879 "vrpn_Button_PinchGlove message start byte: time stamped byte!",
900 struct timeval timeout = {
902 struct timeval timeout_to_pass;
909 timeout_to_pass.tv_sec = timeout.tv_sec;
910 timeout_to_pass.tv_usec = timeout.tv_usec;
932 "vrpn_Button_Remote: can't register change handler\n");
938 "vrpn_Button_Remote: can't register states handler\n");
943 fprintf(stderr,
"vrpn_Button_Remote: Can't get connection!\n");
971 const char *bufptr = p.
buffer;
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)));
995 const char *bufptr = p.
buffer;
996 vrpn_int32 numbuttons;
1026#ifndef VRPN_CLIENT_ONLY
1028int vrpn_Button_Parallel::openGiveIO(
void)
1032 memset(&osvi, 0,
sizeof(OSVERSIONINFO));
1033 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
1034 GetVersionEx(&osvi);
1037 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
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) {
1056 "vrpn_Button_Parallel::openGiveIO: unknown windows version\n");
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.
vrpn_BaseClass(const char *name, vrpn_Connection *c=NULL)
Names the device and assigns or opens connection, calls registration methods.
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
This structure is what is passed to a vrpn_Connection message 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.
int vrpn_close_commport(int comm)
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
int vrpn_drain_output_buffer(int comm)
Wait until all of the characters in the output buffer are sent, then return.
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.
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.
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
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.
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