SDL  2.0
test.cpp
Go to the documentation of this file.
1 /*******************************************************
2  Demo Program for HIDAPI
3 
4  Alan Ott
5  Signal 11 Software
6 
7  2010-07-20
8 
9  Copyright 2010, All Rights Reserved
10 
11  This contents of this file may be used by anyone
12  for any reason without any conditions and may be
13  used as a starting point for your own applications
14  which use HIDAPI.
15 ********************************************************/
16 
17 
18 #include <fx.h>
19 
20 #include "hidapi.h"
21 #include "mac_support.h"
22 #include <string.h>
23 #include <stdlib.h>
24 #include <limits.h>
25 
26 #ifdef _WIN32
27  // Thanks Microsoft, but I know how to use strncpy().
28  #pragma warning(disable:4996)
29 #endif
30 
31 class MainWindow : public FXMainWindow {
32  FXDECLARE(MainWindow)
33 
34 public:
35  enum {
36  ID_FIRST = FXMainWindow::ID_LAST,
47  };
48 
49 private:
50  FXList *device_list;
51  FXButton *connect_button;
52  FXButton *disconnect_button;
53  FXButton *rescan_button;
54  FXButton *output_button;
55  FXLabel *connected_label;
56  FXTextField *output_text;
57  FXTextField *output_len;
58  FXButton *feature_button;
59  FXButton *get_feature_button;
60  FXTextField *feature_text;
61  FXTextField *feature_len;
62  FXTextField *get_feature_text;
63  FXText *input_text;
64  FXFont *title_font;
65 
67  hid_device *connected_device;
68  size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len);
69  int getLengthFromTextField(FXTextField *tf);
70 
71 
72 protected:
73  MainWindow() {};
74 public:
75  MainWindow(FXApp *a);
76  ~MainWindow();
77  virtual void create();
78 
79  long onConnect(FXObject *sender, FXSelector sel, void *ptr);
80  long onDisconnect(FXObject *sender, FXSelector sel, void *ptr);
81  long onRescan(FXObject *sender, FXSelector sel, void *ptr);
82  long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr);
83  long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
84  long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
85  long onClear(FXObject *sender, FXSelector sel, void *ptr);
86  long onTimeout(FXObject *sender, FXSelector sel, void *ptr);
87  long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr);
88 };
89 
90 // FOX 1.7 changes the timeouts to all be nanoseconds.
91 // Fox 1.6 had all timeouts as milliseconds.
92 #if (FOX_MINOR >= 7)
93  const int timeout_scalar = 1000*1000;
94 #else
95  const int timeout_scalar = 1;
96 #endif
97 
98 FXMainWindow *g_main_window;
99 
100 
101 FXDEFMAP(MainWindow) MainWindowMap [] = {
102  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CONNECT, MainWindow::onConnect ),
103  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_DISCONNECT, MainWindow::onDisconnect ),
104  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_RESCAN, MainWindow::onRescan ),
108  FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CLEAR, MainWindow::onClear ),
109  FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
110  FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
111 };
112 
113 FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap));
114 
116  : FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 425,700)
117 {
118  devices = NULL;
120 
121  FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
122 
123  FXLabel *label = new FXLabel(vf, "HIDAPI Test Tool");
124  title_font = new FXFont(getApp(), "Arial", 14, FXFont::Bold);
125  label->setFont(title_font);
126 
127  new FXLabel(vf,
128  "Select a device and press Connect.", NULL, JUSTIFY_LEFT);
129  new FXLabel(vf,
130  "Output data bytes can be entered in the Output section, \n"
131  "separated by space, comma or brackets. Data starting with 0x\n"
132  "is treated as hex. Data beginning with a 0 is treated as \n"
133  "octal. All other data is treated as decimal.", NULL, JUSTIFY_LEFT);
134  new FXLabel(vf,
135  "Data received from the device appears in the Input section.",
136  NULL, JUSTIFY_LEFT);
137  new FXLabel(vf,
138  "Optionally, a report length may be specified. Extra bytes are\n"
139  "padded with zeros. If no length is specified, the length is \n"
140  "inferred from the data.",
141  NULL, JUSTIFY_LEFT);
142  new FXLabel(vf, "");
143 
144  // Device List and Connect/Disconnect buttons
145  FXHorizontalFrame *hf = new FXHorizontalFrame(vf, LAYOUT_FILL_X);
146  //device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0,0,300,200);
147  device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,300,200);
148  FXVerticalFrame *buttonVF = new FXVerticalFrame(hf);
149  connect_button = new FXButton(buttonVF, "Connect", NULL, this, ID_CONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
150  disconnect_button = new FXButton(buttonVF, "Disconnect", NULL, this, ID_DISCONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
151  disconnect_button->disable();
152  rescan_button = new FXButton(buttonVF, "Re-Scan devices", NULL, this, ID_RESCAN, BUTTON_NORMAL|LAYOUT_FILL_X);
153  new FXHorizontalFrame(buttonVF, 0, 0,0,0,0, 0,0,50,0);
154 
155  connected_label = new FXLabel(vf, "Disconnected");
156 
157  new FXHorizontalFrame(vf);
158 
159  // Output Group Box
160  FXGroupBox *gb = new FXGroupBox(vf, "Output", FRAME_GROOVE|LAYOUT_FILL_X);
161  FXMatrix *matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
162  new FXLabel(matrix, "Data");
163  new FXLabel(matrix, "Length");
164  new FXLabel(matrix, "");
165 
166  //hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
167  output_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
168  output_text->setText("1 0x81 0");
169  output_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
170  output_button = new FXButton(matrix, "Send Output Report", NULL, this, ID_SEND_OUTPUT_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
171  output_button->disable();
172  //new FXHorizontalFrame(matrix, LAYOUT_FILL_X);
173 
174  //hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
175  feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
176  feature_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
177  feature_button = new FXButton(matrix, "Send Feature Report", NULL, this, ID_SEND_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
178  feature_button->disable();
179 
180  get_feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
181  new FXWindow(matrix);
182  get_feature_button = new FXButton(matrix, "Get Feature Report", NULL, this, ID_GET_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
183  get_feature_button->disable();
184 
185 
186  // Input Group Box
187  gb = new FXGroupBox(vf, "Input", FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
188  FXVerticalFrame *innerVF = new FXVerticalFrame(gb, LAYOUT_FILL_X|LAYOUT_FILL_Y);
189  input_text = new FXText(new FXHorizontalFrame(innerVF,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
190  input_text->setEditable(false);
191  new FXButton(innerVF, "Clear", NULL, this, ID_CLEAR, BUTTON_NORMAL|LAYOUT_RIGHT);
192 
193 
194 }
195 
197 {
198  if (connected_device)
200  hid_exit();
201  delete title_font;
202 }
203 
204 void
206 {
207  FXMainWindow::create();
208  show();
209 
210  onRescan(NULL, 0, NULL);
211 
212 
213 #ifdef __APPLE__
215 #endif
216 
217  getApp()->addTimeout(this, ID_MAC_TIMER,
218  50 * timeout_scalar /*50ms*/);
219 }
220 
221 long
222 MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
223 {
224  if (connected_device != NULL)
225  return 1;
226 
227  FXint cur_item = device_list->getCurrentItem();
228  if (cur_item < 0)
229  return -1;
230  FXListItem *item = device_list->getItem(cur_item);
231  if (!item)
232  return -1;
233  struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
234  if (!device_info)
235  return -1;
236 
237  connected_device = hid_open_path(device_info->path);
238 
239  if (!connected_device) {
240  FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
241  return -1;
242  }
243 
245 
246  getApp()->addTimeout(this, ID_TIMER,
247  5 * timeout_scalar /*5ms*/);
248 
249  FXString s;
250  s.format("Connected to: %04hx:%04hx -", device_info->vendor_id, device_info->product_id);
251  s += FXString(" ") + device_info->manufacturer_string;
252  s += FXString(" ") + device_info->product_string;
253  connected_label->setText(s);
254  output_button->enable();
255  feature_button->enable();
256  get_feature_button->enable();
257  connect_button->disable();
258  disconnect_button->enable();
259  input_text->setText("");
260 
261 
262  return 1;
263 }
264 
265 long
266 MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
267 {
270  connected_label->setText("Disconnected");
271  output_button->disable();
272  feature_button->disable();
273  get_feature_button->disable();
274  connect_button->enable();
275  disconnect_button->disable();
276 
277  getApp()->removeTimeout(this, ID_TIMER);
278 
279  return 1;
280 }
281 
282 long
283 MainWindow::onRescan(FXObject *sender, FXSelector sel, void *ptr)
284 {
285  struct hid_device_info *cur_dev;
286 
287  device_list->clearItems();
288 
289  // List the Devices
291  devices = hid_enumerate(0x0, 0x0);
292  cur_dev = devices;
293  while (cur_dev) {
294  // Add it to the List Box.
295  FXString s;
296  FXString usage_str;
297  s.format("%04hx:%04hx -", cur_dev->vendor_id, cur_dev->product_id);
298  s += FXString(" ") + cur_dev->manufacturer_string;
299  s += FXString(" ") + cur_dev->product_string;
300  usage_str.format(" (usage: %04hx:%04hx) ", cur_dev->usage_page, cur_dev->usage);
301  s += usage_str;
302  FXListItem *li = new FXListItem(s, NULL, cur_dev);
303  device_list->appendItem(li);
304 
305  cur_dev = cur_dev->next;
306  }
307 
308  if (device_list->getNumItems() == 0)
309  device_list->appendItem("*** No Devices Connected ***");
310  else {
311  device_list->selectItem(0);
312  }
313 
314  return 1;
315 }
316 
317 size_t
318 MainWindow::getDataFromTextField(FXTextField *tf, char *buf, size_t len)
319 {
320  const char *delim = " ,{}\t\r\n";
321  FXString data = tf->getText();
322  const FXchar *d = data.text();
323  size_t i = 0;
324 
325  // Copy the string from the GUI.
326  size_t sz = strlen(d);
327  char *str = (char*) malloc(sz+1);
328  strcpy(str, d);
329 
330  // For each token in the string, parse and store in buf[].
331  char *token = strtok(str, delim);
332  while (token) {
333  char *endptr;
334  long int val = strtol(token, &endptr, 0);
335  buf[i++] = val;
336  token = strtok(NULL, delim);
337  }
338 
339  free(str);
340  return i;
341 }
342 
343 /* getLengthFromTextField()
344  Returns length:
345  0: empty text field
346  >0: valid length
347  -1: invalid length */
348 int
350 {
351  long int len;
352  FXString str = tf->getText();
353  size_t sz = str.length();
354 
355  if (sz > 0) {
356  char *endptr;
357  len = strtol(str.text(), &endptr, 0);
358  if (endptr != str.text() && *endptr == '\0') {
359  if (len <= 0) {
360  FXMessageBox::error(this, MBOX_OK, "Invalid length", "Enter a length greater than zero.");
361  return -1;
362  }
363  return len;
364  }
365  else
366  return -1;
367  }
368 
369  return 0;
370 }
371 
372 long
373 MainWindow::onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
374 {
375  char buf[256];
376  size_t data_len, len;
377  int textfield_len;
378 
379  memset(buf, 0x0, sizeof(buf));
380  textfield_len = getLengthFromTextField(output_len);
381  data_len = getDataFromTextField(output_text, buf, sizeof(buf));
382 
383  if (textfield_len < 0) {
384  FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
385  return 1;
386  }
387 
388  if (textfield_len > sizeof(buf)) {
389  FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
390  return 1;
391  }
392 
393  len = (textfield_len)? textfield_len: data_len;
394 
395  int res = hid_write(connected_device, (const unsigned char*)buf, len);
396  if (res < 0) {
397  FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not write to device. Error reported was: %ls", hid_error(connected_device));
398  }
399 
400  return 1;
401 }
402 
403 long
404 MainWindow::onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
405 {
406  char buf[256];
407  size_t data_len, len;
408  int textfield_len;
409 
410  memset(buf, 0x0, sizeof(buf));
411  textfield_len = getLengthFromTextField(feature_len);
412  data_len = getDataFromTextField(feature_text, buf, sizeof(buf));
413 
414  if (textfield_len < 0) {
415  FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
416  return 1;
417  }
418 
419  if (textfield_len > sizeof(buf)) {
420  FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
421  return 1;
422  }
423 
424  len = (textfield_len)? textfield_len: data_len;
425 
426  int res = hid_send_feature_report(connected_device, (const unsigned char*)buf, len);
427  if (res < 0) {
428  FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not send feature report to device. Error reported was: %ls", hid_error(connected_device));
429  }
430 
431  return 1;
432 }
433 
434 long
435 MainWindow::onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
436 {
437  char buf[256];
438  size_t len;
439 
440  memset(buf, 0x0, sizeof(buf));
441  len = getDataFromTextField(get_feature_text, buf, sizeof(buf));
442 
443  if (len != 1) {
444  FXMessageBox::error(this, MBOX_OK, "Too many numbers", "Enter only a single report number in the text field");
445  }
446 
447  int res = hid_get_feature_report(connected_device, (unsigned char*)buf, sizeof(buf));
448  if (res < 0) {
449  FXMessageBox::error(this, MBOX_OK, "Error Getting Report", "Could not get feature report from device. Error reported was: %ls", hid_error(connected_device));
450  }
451 
452  if (res > 0) {
453  FXString s;
454  s.format("Returned Feature Report. %d bytes:\n", res);
455  for (int i = 0; i < res; i++) {
456  FXString t;
457  t.format("%02hhx ", buf[i]);
458  s += t;
459  if ((i+1) % 4 == 0)
460  s += " ";
461  if ((i+1) % 16 == 0)
462  s += "\n";
463  }
464  s += "\n";
465  input_text->appendText(s);
466  input_text->setBottomLine(INT_MAX);
467  }
468 
469  return 1;
470 }
471 
472 long
473 MainWindow::onClear(FXObject *sender, FXSelector sel, void *ptr)
474 {
475  input_text->setText("");
476  return 1;
477 }
478 
479 long
480 MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
481 {
482  unsigned char buf[256];
483  int res = hid_read(connected_device, buf, sizeof(buf));
484 
485  if (res > 0) {
486  FXString s;
487  s.format("Received %d bytes:\n", res);
488  for (int i = 0; i < res; i++) {
489  FXString t;
490  t.format("%02hhx ", buf[i]);
491  s += t;
492  if ((i+1) % 4 == 0)
493  s += " ";
494  if ((i+1) % 16 == 0)
495  s += "\n";
496  }
497  s += "\n";
498  input_text->appendText(s);
499  input_text->setBottomLine(INT_MAX);
500  }
501  if (res < 0) {
502  input_text->appendText("hid_read() returned error\n");
503  input_text->setBottomLine(INT_MAX);
504  }
505 
506  getApp()->addTimeout(this, ID_TIMER,
507  5 * timeout_scalar /*5ms*/);
508  return 1;
509 }
510 
511 long
512 MainWindow::onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
513 {
514 #ifdef __APPLE__
516 
517  getApp()->addTimeout(this, ID_MAC_TIMER,
518  50 * timeout_scalar /*50ms*/);
519 #endif
520 
521  return 1;
522 }
523 
524 int main(int argc, char **argv)
525 {
526  FXApp app("HIDAPI Test Application", "Signal 11 Software");
527  app.init(argc, argv);
528  g_main_window = new MainWindow(&app);
529  app.create();
530  app.run();
531  return 0;
532 }
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error(hid_device *device)
Get a string describing the last error which occurred.
Definition: hid.cpp:1149
GLuint GLenum matrix
int getLengthFromTextField(FXTextField *tf)
Definition: test.cpp:349
FXTextField * feature_len
Definition: test.cpp:61
FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap))
long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:512
FXList * device_list
Definition: test.cpp:50
long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:373
GLdouble s
Definition: SDL_opengl.h:2063
long onConnect(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:222
FXDEFMAP(MainWindow) MainWindowMap []
FXTextField * output_text
Definition: test.cpp:56
const int timeout_scalar
Definition: test.cpp:95
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
Free an enumeration Linked List.
Definition: hid.cpp:979
long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:404
FXButton * output_button
Definition: test.cpp:54
struct hid_device_info * devices
Definition: test.cpp:66
MainWindow()
Definition: test.cpp:73
SDL_EventEntry * free
Definition: SDL_events.c:84
FXMainWindow * g_main_window
Definition: test.cpp:98
~MainWindow()
Definition: test.cpp:196
#define memset
Definition: SDL_malloc.c:619
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
static char * tf(SDL_bool tf)
Definition: testatomic.c:23
long onTimeout(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:480
long onRescan(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:283
wchar_t * manufacturer_string
Definition: hidapi.h:66
char * path
Definition: hidapi.h:55
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
Write an Output report to a HID device.
Definition: hid.cpp:1028
GLenum GLsizei len
GLuint res
FXButton * connect_button
Definition: test.cpp:51
struct hid_device_info * next
Definition: hidapi.h:82
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
Set the device handle to be non-blocking.
Definition: hid.cpp:1060
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
Close a HID device.
Definition: hid.cpp:1090
FXTextField * feature_text
Definition: test.cpp:60
GLuint GLfloat * val
unsigned short product_id
Definition: hidapi.h:59
hid_device * connected_device
Definition: test.cpp:67
GLuint GLsizei const GLchar * label
void init_apple_message_system()
Definition: mac_support.cpp:96
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
FXButton * get_feature_button
Definition: test.cpp:59
int hid_exit(void)
Finalize the HIDAPI library.
Definition: hid.cpp:1154
unsigned short vendor_id
Definition: hidapi.h:57
long onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:266
FXButton * rescan_button
Definition: test.cpp:53
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
Get a feature report from a HID device.
Definition: hid.cpp:1078
wchar_t * product_string
Definition: hidapi.h:68
unsigned short usage
Definition: hidapi.h:74
GLenum GLuint GLenum GLsizei const GLchar * buf
virtual void create()
Definition: test.cpp:205
int main(int argc, char **argv)
Definition: test.cpp:524
FXLabel * connected_label
Definition: test.cpp:55
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
FXFont * title_font
Definition: test.cpp:64
unsigned short usage_page
Definition: hidapi.h:71
FXButton * feature_button
Definition: test.cpp:58
GLuint GLfloat x0
long onClear(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:473
FXTextField * get_feature_text
Definition: test.cpp:62
HID_API_EXPORT hid_device *HID_API_CALL hid_open_path(const char *path, int bExclusive)
Open a HID device by its path name.
Definition: hid.cpp:995
FXButton * disconnect_button
Definition: test.cpp:52
size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len)
Definition: test.cpp:318
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
Send a Feature report to the device.
Definition: hid.cpp:1065
void check_apple_events()
FXText * input_text
Definition: test.cpp:63
GLboolean GLboolean GLboolean GLboolean a
long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
Definition: test.cpp:435
FXTextField * output_len
Definition: test.cpp:57
EGLDeviceEXT * devices
Definition: eglext.h:621
struct hid_device_info HID_API_EXPORT *HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
Enumerate the HID Devices.
Definition: hid.cpp:961
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
#define malloc
Definition: SDL_qsort.c:47
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
Read an Input report from a HID device.
Definition: hid.cpp:1053