2 #include "structmember.h"
11 X52PRO_BUTTON_TRIGGER1
= 0,
25 X52PRO_BUTTON_TRIGGER2
,
26 X52PRO_BUTTON_MOUSE_CLICK
,
27 X52PRO_BUTTON_MOUSE_SCROLL_FORWARD
,
28 X52PRO_BUTTON_MOUSE_SCROLL_BACK
,
29 X52PRO_BUTTON_MOUSE_SCROLL_CLICK
,
30 X52PRO_BUTTON_COOLIE_UP
,
31 X52PRO_BUTTON_COOLIE_RIGHT
,
32 X52PRO_BUTTON_COOLIE_DOWN
,
33 X52PRO_BUTTON_COOLIE_LEFT
,
34 X52PRO_BUTTON_THROTTLEHAT_BACK
,
35 X52PRO_BUTTON_THROTTLEHAT_RIGHT
,
36 X52PRO_BUTTON_THROTTLEHAT_FORWARD
,
37 X52PRO_BUTTON_THROTTLEHAT_LEFT
,
42 X52PRO_BUTTON_MFD_FUNCTION
,
43 X52PRO_BUTTON_MFD_STARTSTOP
,
44 X52PRO_BUTTON_MFD_RESET
,
45 X52PRO_BUTTON_MFD_PAGE_UP
,
46 X52PRO_BUTTON_MFD_PAGE_DOWN
,
47 X52PRO_BUTTON_MFD_SEL_UP
,
48 X52PRO_BUTTON_MFD_SEL_DOWN
,
58 static PyTypeObject PyX52_X52_type
;
59 static PyMethodDef PyX52_methods
[];
60 static PyMethodDef PyX52_X52_methods
[];
62 static PyObject
*PyX52_X52_new(PyTypeObject
*);
63 static int PyX52_X52_init(PyX52_X52_object
*);
64 static void PyX52_X52_dealloc(PyX52_X52_object
*);
66 static PyObject
*PyX52_X52_gettype(PyX52_X52_object
*);
67 static PyObject
*PyX52_X52_settext(PyX52_X52_object
*, PyObject
*, PyObject
*);
68 static PyObject
*PyX52_X52_setbri(PyX52_X52_object
*, PyObject
*, PyObject
*);
69 static PyObject
*PyX52_X52_setled(PyX52_X52_object
*, PyObject
*, PyObject
*);
70 static PyObject
*PyX52_X52_settime(PyX52_X52_object
*, PyObject
*, PyObject
*);
71 static PyObject
*PyX52_X52_setoffs(PyX52_X52_object
*, PyObject
*, PyObject
*);
72 static PyObject
*PyX52_X52_setsecond(PyX52_X52_object
*, PyObject
*, PyObject
*);
73 static PyObject
*PyX52_X52_setdate(PyX52_X52_object
*, PyObject
*, PyObject
*);
76 PyX52_X52_new(PyTypeObject
*type
)
79 PyX52_X52_object
*self
;
80 self
= (PyX52_X52_object
*)type
->tp_alloc(type
, 0);
85 return (PyObject
*)self
;
89 PyX52_X52_init(PyX52_X52_object
*self
)
92 self
->handle
= x52_init();
93 if (self
->handle
== NULL
)
95 PyErr_SetString(PyExc_RuntimeError
, "No compatible joysticks found.");
98 x52_debug(self
->handle
, 0);
103 PyX52_X52_dealloc(PyX52_X52_object
*self
)
106 if (self
->handle
!= NULL
)
108 x52_close(self
->handle
);
111 self
->ob_type
->tp_free((PyObject
*)self
);
115 PyX52_X52_gettype(PyX52_X52_object
*self
)
117 enum x52_type type
= x52_gettype(self
->handle
);
118 return Py_BuildValue("i", type
);
122 PyX52_X52_settext(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
124 if (x52_gettype(self
->handle
) == DEV_YOKE
)
126 PyErr_SetString(PyExc_RuntimeError
, "Cannot call settext on this device.");
131 PyObject
*line
= Py_BuildValue("s", "");
133 static char *kwlist
[] = {"line_no", "line", NULL
};
134 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "iO", kwlist
, &line_no
, &line
))
137 if (line_no
< 0 || line_no
> 2)
139 PyErr_SetString(PyExc_AttributeError
, "line_no must be in the range 0-2.");
143 if (!PyString_Check(line
))
145 PyErr_SetString(PyExc_AttributeError
, "line must be a string or subtype of string.");
150 if (PyString_Size(line
) > 0)
152 line_buf
= (char *)malloc(sizeof(char)*17);
153 memset(line_buf
, '\0', 16);
154 strncpy(line_buf
, PyString_AsString(line
), 17);
160 if (x52_settext(self
->handle
, line_no
, line_buf
, strlen(line_buf
)) != 0)
162 PyErr_SetString(PyExc_RuntimeError
, "Could not set text.");
171 PyX52_X52_setbri(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
173 if (x52_gettype(self
->handle
) == DEV_YOKE
)
175 PyErr_SetString(PyExc_RuntimeError
, "Cannot call setbri on this device.");
182 static char *kwlist
[] = {"mode", "bri", NULL
};
183 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "ii", kwlist
, &mode
, &bri
))
186 if (mode
!= 0 && mode
!= 1)
188 PyErr_SetString(PyExc_AttributeError
, "Invalid mode.");
192 if (mode
== 0 && x52_gettype(self
->handle
) != DEV_X52PRO
)
194 PyErr_SetString(PyExc_AttributeError
, "Cannot set LED brightness on this device.");
198 if (bri
< 0 || bri
> 127)
200 PyErr_SetString(PyExc_AttributeError
, "Invalid brightness value.");
204 if (x52_setbri(self
->handle
, mode
, bri
) != 0)
206 PyErr_SetString(PyExc_RuntimeError
, "Could not set brightness.");
215 PyX52_X52_setled(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
217 if (x52_gettype(self
->handle
) != DEV_X52PRO
)
219 PyErr_SetString(PyExc_RuntimeError
, "Cannot call setled on this device.");
224 * TODO: Allow passing of a dict with LEDs/states
225 * TODO: Allow abstraction to button colour (i.e. PyX52.X52.buttons["coolie"].orange())
230 static char *kwlist
[] = {"led", "state", NULL
};
231 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "ii", kwlist
, &led
, &state
))
234 if (state
!= 0 && state
!= 1)
236 PyErr_SetString(PyExc_AttributeError
, "Invalid LED state.");
240 if (led
< X52PRO_LED_FIRE
|| led
> X52PRO_LED_IGREEN
)
242 PyErr_SetString(PyExc_AttributeError
, "Invalid LED ID.");
246 if (x52_setled(self
->handle
, led
, state
) != 0)
248 PyErr_SetString(PyExc_RuntimeError
, "Could not set LED status.");
257 PyX52_X52_settime(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
261 struct tm
*ltime
= NULL
;
262 time_t t
= time(NULL
);
265 int hour
= ltime
->tm_hour
;
266 int minute
= ltime
->tm_min
;
268 static char *kwlist
[] = {"hour", "minute", "h24", NULL
};
269 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "|iii", kwlist
, &hour
, &minute
, &h24
))
272 if (x52_settime(self
->handle
, h24
, hour
, minute
) != 0)
274 PyErr_SetString(PyExc_RuntimeError
, "Could not set time.");
283 PyX52_X52_setoffs(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
286 * TODO: default to local timezones
288 if (x52_gettype(self
->handle
) == DEV_YOKE
)
290 PyErr_SetString(PyExc_RuntimeError
, "Cannot call setoffs on this device.");
297 static char *kwlist
[] = {"offs2", "offs3", NULL
};
298 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "|ii", kwlist
, &offs2
, &offs3
))
309 x52_setoffs(self
->handle
, 0, 1, inv2
, offs2
);
318 x52_setoffs(self
->handle
, 1, 1, inv3
, offs3
);
326 PyX52_X52_setsecond(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
328 if (x52_gettype(self
->handle
) != DEV_YOKE
)
330 PyErr_SetString(PyExc_RuntimeError
, "Cannot call setsecond on this device.");
335 time_t t
= time(NULL
);
338 int second
= ltime
->tm_sec
;
340 static char *kwlist
[] = {"second", NULL
};
341 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "|iii", kwlist
, &second
))
344 x52_setsecond(self
->handle
, second
);
351 PyX52_X52_setdate(PyX52_X52_object
*self
, PyObject
*args
, PyObject
*kws
)
353 if (x52_gettype(self
->handle
) == DEV_YOKE
)
355 PyErr_SetString(PyExc_RuntimeError
, "Cannot call setdate on this device.");
364 int year
= ltime
->tm_year
- 100;
365 int month
= ltime
->tm_mon
+ 1;
366 int day
= ltime
->tm_mday
;
368 static char *kwlist
[] = {"year", "month", "day", NULL
};
369 if (!PyArg_ParseTupleAndKeywords(args
, kws
, "|iii", kwlist
, &year
, &month
, &day
))
372 if (x52_setdate(self
->handle
, year
, month
, day
) != 0)
374 PyErr_SetString(PyExc_RuntimeError
, "Could not set date.");
382 static PyMethodDef PyX52_X52_methods
[] = {
383 {"gettype", (PyCFunction
)PyX52_X52_gettype
, METH_NOARGS
, "Get the type of X52 device."},
384 {"settext", (PyCFunction
)PyX52_X52_settext
, METH_VARARGS
| METH_KEYWORDS
, "Set the text on the MFD. (X52 and X52 Pro only.)"},
385 {"setbri", (PyCFunction
)PyX52_X52_setbri
, METH_VARARGS
| METH_KEYWORDS
, "Set the brightness of either the LEDs or the MFD. (X52 and X52 Pro only.)"},
386 {"setled", (PyCFunction
)PyX52_X52_setled
, METH_VARARGS
| METH_KEYWORDS
, "Set an LED's state. (X52 Pro only.)"},
387 {"settime", (PyCFunction
)PyX52_X52_settime
, METH_VARARGS
| METH_KEYWORDS
, "Set the MFD display time. If arguments are not supplied, sets the current time in 24 hour format. (X52, X52 Pro and Yoke.)"},
388 {"setoffs", (PyCFunction
)PyX52_X52_setoffs
, METH_VARARGS
| METH_KEYWORDS
, "Set the time offset. (X52, X52 Pro.)"},
389 {"setsecond", (PyCFunction
)PyX52_X52_setsecond
, METH_VARARGS
| METH_KEYWORDS
, "Set the second. If no arguments are supplied, current second is used. (Yoke only.)"},
390 {"setdate", (PyCFunction
)PyX52_X52_setdate
, METH_VARARGS
| METH_KEYWORDS
, "Set the date. If no arguments are supplied, current date is used. (X52, X52 Pro.)"},
391 {NULL
, NULL
, 0, NULL
}
394 static PyTypeObject PyX52_X52_type
= {
395 PyObject_HEAD_INIT(NULL
)
397 "PyX52.X52", /*tp_name*/
398 sizeof(PyX52_X52_object
), /*tp_basicsize*/
400 (destructor
)PyX52_X52_dealloc
, /*tp_dealloc*/
407 0, /*tp_as_sequence*/
415 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
416 "X52 joystick object", /* tp_doc */
419 0, /* tp_richcompare */
420 0, /* tp_weaklistoffset */
423 PyX52_X52_methods
, /* tp_methods */
428 0, /* tp_descr_get */
429 0, /* tp_descr_set */
430 0, /* tp_dictoffset */
431 (initproc
)PyX52_X52_init
, /* tp_init */
433 (newfunc
)PyX52_X52_new
, /* tp_new */
436 static PyMethodDef PyX52_methods
[] = {
440 #ifndef PyMODINIT_FUNC
441 #define PyMODINIT_FUNC void
448 if (PyType_Ready(&PyX52_X52_type
) < 0)
451 m
= Py_InitModule3("PyX52", PyX52_methods
, "Provides functions for handling Saitek X52, X52 Pro and Yoke joystick devices.");
455 Py_INCREF(&PyX52_X52_type
);
456 PyModule_AddObject(m
, "X52", (PyObject
*) &PyX52_X52_type
);
458 PyModule_AddIntConstant(m
, "LED_FIRE", X52PRO_LED_FIRE
);
459 PyModule_AddIntConstant(m
, "LED_ARED", X52PRO_LED_ARED
);
460 PyModule_AddIntConstant(m
, "LED_AGREEN", X52PRO_LED_AGREEN
);
461 PyModule_AddIntConstant(m
, "LED_BRED", X52PRO_LED_BRED
);
462 PyModule_AddIntConstant(m
, "LED_BGREEN", X52PRO_LED_BGREEN
);
463 PyModule_AddIntConstant(m
, "LED_DRED", X52PRO_LED_DRED
);
464 PyModule_AddIntConstant(m
, "LED_DGREEN", X52PRO_LED_DGREEN
);
465 PyModule_AddIntConstant(m
, "LED_ERED", X52PRO_LED_ERED
);
466 PyModule_AddIntConstant(m
, "LED_EGREEN", X52PRO_LED_EGREEN
);
467 PyModule_AddIntConstant(m
, "LED_T1RED", X52PRO_LED_T1RED
);
468 PyModule_AddIntConstant(m
, "LED_T1GREEN", X52PRO_LED_T1GREEN
);
469 PyModule_AddIntConstant(m
, "LED_T2RED", X52PRO_LED_T2RED
);
470 PyModule_AddIntConstant(m
, "LED_T2GREEN", X52PRO_LED_T2GREEN
);
471 PyModule_AddIntConstant(m
, "LED_T3RED", X52PRO_LED_T3RED
);
472 PyModule_AddIntConstant(m
, "LED_T3GREEN", X52PRO_LED_T3GREEN
);
473 PyModule_AddIntConstant(m
, "LED_CORED", X52PRO_LED_CORED
);
474 PyModule_AddIntConstant(m
, "LED_COGREEN", X52PRO_LED_COGREEN
);
475 PyModule_AddIntConstant(m
, "LED_IRED", X52PRO_LED_IRED
);
476 PyModule_AddIntConstant(m
, "LED_IGREEN", X52PRO_LED_IGREEN
);
478 PyModule_AddIntConstant(m
, "BUTTON_TRIGGER1", X52PRO_BUTTON_TRIGGER1
);
479 PyModule_AddIntConstant(m
, "BUTTON_FIRE", X52PRO_BUTTON_FIRE
);
480 PyModule_AddIntConstant(m
, "BUTTON_A", X52PRO_BUTTON_A
);
481 PyModule_AddIntConstant(m
, "BUTTON_B", X52PRO_BUTTON_B
);
482 PyModule_AddIntConstant(m
, "BUTTON_C", X52PRO_BUTTON_C
);
483 PyModule_AddIntConstant(m
, "BUTTON_PINKIE", X52PRO_BUTTON_PINKIE
);
484 PyModule_AddIntConstant(m
, "BUTTON_D", X52PRO_BUTTON_D
);
485 PyModule_AddIntConstant(m
, "BUTTON_E", X52PRO_BUTTON_E
);
486 PyModule_AddIntConstant(m
, "BUTTON_T1", X52PRO_BUTTON_T1
);
487 PyModule_AddIntConstant(m
, "BUTTON_T2", X52PRO_BUTTON_T2
);
488 PyModule_AddIntConstant(m
, "BUTTON_T3", X52PRO_BUTTON_T3
);
489 PyModule_AddIntConstant(m
, "BUTTON_T4", X52PRO_BUTTON_T4
);
490 PyModule_AddIntConstant(m
, "BUTTON_T5", X52PRO_BUTTON_T5
);
491 PyModule_AddIntConstant(m
, "BUTTON_T6", X52PRO_BUTTON_T6
);
492 PyModule_AddIntConstant(m
, "BUTTON_TRIGGER2", X52PRO_BUTTON_TRIGGER2
);
493 PyModule_AddIntConstant(m
, "BUTTON_MOUSE_CLICK", X52PRO_BUTTON_MOUSE_CLICK
);
494 PyModule_AddIntConstant(m
, "BUTTON_MOUSE_SCROLL_FORWARD", X52PRO_BUTTON_MOUSE_SCROLL_FORWARD
);
495 PyModule_AddIntConstant(m
, "BUTTON_MOUSE_SCROLL_BACK", X52PRO_BUTTON_MOUSE_SCROLL_BACK
);
496 PyModule_AddIntConstant(m
, "BUTTON_MOUSE_SCROLL_CLICK", X52PRO_BUTTON_MOUSE_SCROLL_CLICK
);
497 PyModule_AddIntConstant(m
, "BUTTON_COOLIE_UP", X52PRO_BUTTON_COOLIE_UP
);
498 PyModule_AddIntConstant(m
, "BUTTON_COOLIE_RIGHT", X52PRO_BUTTON_COOLIE_RIGHT
);
499 PyModule_AddIntConstant(m
, "BUTTON_COOLIE_DOWN", X52PRO_BUTTON_COOLIE_DOWN
);
500 PyModule_AddIntConstant(m
, "BUTTON_COOLIE_LEFT", X52PRO_BUTTON_COOLIE_LEFT
);
501 PyModule_AddIntConstant(m
, "BUTTON_THROTTLEHAT_BACK", X52PRO_BUTTON_THROTTLEHAT_BACK
);
502 PyModule_AddIntConstant(m
, "BUTTON_THROTTLEHAT_RIGHT", X52PRO_BUTTON_THROTTLEHAT_RIGHT
);
503 PyModule_AddIntConstant(m
, "BUTTON_THROTTLEHAT_FORWARD", X52PRO_BUTTON_THROTTLEHAT_FORWARD
);
504 PyModule_AddIntConstant(m
, "BUTTON_THROTTLEHAT_LEFT", X52PRO_BUTTON_THROTTLEHAT_LEFT
);
505 PyModule_AddIntConstant(m
, "BUTTON_MODE1", X52PRO_BUTTON_MODE1
);
506 PyModule_AddIntConstant(m
, "BUTTON_MODE2", X52PRO_BUTTON_MODE2
);
507 PyModule_AddIntConstant(m
, "BUTTON_MODE3", X52PRO_BUTTON_MODE3
);
508 PyModule_AddIntConstant(m
, "BUTTON_I", X52PRO_BUTTON_I
);
509 PyModule_AddIntConstant(m
, "BUTTON_MFD_FUNCTION", X52PRO_BUTTON_MFD_FUNCTION
);
510 PyModule_AddIntConstant(m
, "BUTTON_MFD_STARTSTOP", X52PRO_BUTTON_MFD_STARTSTOP
);
511 PyModule_AddIntConstant(m
, "BUTTON_MFD_RESET", X52PRO_BUTTON_MFD_RESET
);
512 PyModule_AddIntConstant(m
, "BUTTON_MFD_PAGE_UP", X52PRO_BUTTON_MFD_PAGE_UP
);
513 PyModule_AddIntConstant(m
, "BUTTON_MFD_PAGE_DN", X52PRO_BUTTON_MFD_PAGE_DOWN
);
514 PyModule_AddIntConstant(m
, "BUTTON_MFD_SEL_UP", X52PRO_BUTTON_MFD_SEL_UP
);
515 PyModule_AddIntConstant(m
, "BUTTON_MFD_SEL_DOWN", X52PRO_BUTTON_MFD_SEL_DOWN
);
516 PyModule_AddIntConstant(m
, "BUTTON_MFD_SEL", X52PRO_BUTTON_MFD_SEL
);
518 PyModule_AddIntConstant(m
, "TYPE_X52", DEV_X52
);
519 PyModule_AddIntConstant(m
, "TYPE_X52PRO", DEV_X52PRO
);
520 PyModule_AddIntConstant(m
, "TYPE_YOKE", DEV_YOKE
);