1 /*
2 pygame - Python Game Library
3 Copyright (C) 2000-2001 Pete Shinners
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Pete Shinners
20 pete@shinners.org
21 */
22
23 #define PYGAMEAPI_JOYSTICK_INTERNAL
24 #include "pygame.h"
25
26 #include "pgcompat.h"
27
28 #include "doc/joystick_doc.h"
29
30 static pgJoystickObject *joylist_head = NULL;
31 static PyObject *joy_instance_map = NULL;
32 static PyTypeObject pgJoystick_Type;
33 static PyObject *pgJoystick_New(int);
34 static int _joy_map_insert(pgJoystickObject *jstick);
35 #define pgJoystick_Check(x) ((x)->ob_type == &pgJoystick_Type)
36
37 static PyObject *
init(PyObject * self)38 init(PyObject *self)
39 {
40 if (!SDL_WasInit(SDL_INIT_JOYSTICK)) {
41 if (SDL_InitSubSystem(SDL_INIT_JOYSTICK))
42 return RAISE(pgExc_SDLError, SDL_GetError());
43 SDL_JoystickEventState(SDL_ENABLE);
44 }
45 Py_RETURN_NONE;
46 }
47
48 static PyObject *
quit(PyObject * self)49 quit(PyObject *self)
50 {
51 /* Walk joystick objects to deallocate the stick objects. */
52 pgJoystickObject *cur = joylist_head;
53 while (cur) {
54 if (cur->joy) {
55 SDL_JoystickClose(cur->joy);
56 cur->joy = NULL;
57 }
58 cur = cur->next;
59 }
60
61 if (SDL_WasInit(SDL_INIT_JOYSTICK)) {
62 SDL_JoystickEventState(SDL_ENABLE);
63 SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
64 }
65 Py_RETURN_NONE;
66 }
67
68 static PyObject *
get_init(PyObject * self)69 get_init(PyObject *self)
70 {
71 return PyBool_FromLong(SDL_WasInit(SDL_INIT_JOYSTICK) != 0);
72 }
73
74 /*joystick object funcs*/
75 static void
joy_dealloc(PyObject * self)76 joy_dealloc(PyObject *self)
77 {
78 pgJoystickObject *jstick = (pgJoystickObject *) self;
79
80 if (jstick->joy) {
81 SDL_JoystickClose(jstick->joy);
82 }
83
84 if (jstick->prev) {
85 jstick->prev->next = jstick->next;
86 } else {
87 joylist_head = jstick->next;
88 }
89 if (jstick->next) {
90 jstick->next->prev = jstick->prev;
91 }
92
93 PyObject_DEL(self);
94 }
95
96 static PyObject *
Joystick(PyObject * self,PyObject * args)97 Joystick(PyObject *self, PyObject *args)
98 {
99 int id;
100 if (!PyArg_ParseTuple(args, "i", &id)) {
101 return NULL;
102 }
103
104 JOYSTICK_INIT_CHECK();
105
106 return pgJoystick_New(id);
107 }
108
109 static PyObject *
get_count(PyObject * self,PyObject * args)110 get_count(PyObject *self, PyObject *args)
111 {
112 JOYSTICK_INIT_CHECK();
113 return PyInt_FromLong(SDL_NumJoysticks());
114 }
115
116
117 static PyObject *
joy_init(PyObject * self,PyObject * args)118 joy_init(PyObject *self, PyObject *args)
119 {
120 pgJoystickObject *jstick = (pgJoystickObject *) self;
121
122 if (!jstick->joy) {
123 jstick->joy = SDL_JoystickOpen(jstick->id);
124 if (!jstick->joy) {
125 return RAISE(pgExc_SDLError, SDL_GetError());
126 }
127 }
128
129 if (-1 == _joy_map_insert(jstick)) {
130 return NULL;
131 }
132
133 Py_RETURN_NONE;
134 }
135
136 static int
_joy_map_insert(pgJoystickObject * jstick)137 _joy_map_insert(pgJoystickObject *jstick) {
138 SDL_JoystickID instance_id;
139 PyObject *k, *v;
140
141 if (!joy_instance_map) {
142 return -1;
143 }
144
145 instance_id = SDL_JoystickInstanceID(jstick->joy);
146 if (instance_id < 0) {
147 PyErr_SetString(pgExc_SDLError, SDL_GetError());
148 return -1;
149 }
150 k = PyInt_FromLong(instance_id);
151 v = PyInt_FromLong(jstick->id);
152 if (k && v) {
153 PyDict_SetItem(joy_instance_map, k, v);
154 }
155 Py_XDECREF(k);
156 Py_XDECREF(v);
157
158 return 0;
159 }
160
161 static PyObject *
joy_quit(PyObject * self,PyObject * args)162 joy_quit(PyObject *self, PyObject *args)
163 {
164 pgJoystickObject *joy = (pgJoystickObject *) self;
165
166 JOYSTICK_INIT_CHECK();
167 if (joy->joy) {
168 SDL_JoystickClose(joy->joy);
169 joy->joy = NULL;
170 }
171 Py_RETURN_NONE;
172 }
173
174 static PyObject *
joy_get_init(PyObject * self,PyObject * args)175 joy_get_init(PyObject *self, PyObject *args)
176 {
177 SDL_Joystick *joy = pgJoystick_AsSDL(self);
178 return PyBool_FromLong(joy != NULL);
179 }
180
181 static PyObject *
joy_get_id(PyObject * self,PyObject * args)182 joy_get_id(PyObject *self, PyObject *args)
183 {
184 int joy_id = pgJoystick_AsID(self);
185 return PyInt_FromLong(joy_id);
186 }
187
188
189 static PyObject *
joy_get_instance_id(PyObject * self,PyObject * args)190 joy_get_instance_id(PyObject *self, PyObject *args)
191 {
192 SDL_Joystick *joy = pgJoystick_AsSDL(self);
193
194 JOYSTICK_INIT_CHECK();
195 if (!joy) {
196 return RAISE(pgExc_SDLError, "Joystick not initialized");
197 }
198
199 return PyInt_FromLong(SDL_JoystickInstanceID(joy));
200 }
201
202
203 static PyObject *
joy_get_guid(PyObject * self,PyObject * args)204 joy_get_guid(PyObject *self, PyObject *args)
205 {
206 SDL_Joystick *joy = pgJoystick_AsSDL(self);
207 SDL_JoystickGUID guid;
208 char strguid[33];
209
210 JOYSTICK_INIT_CHECK();
211 if (joy) {
212 guid = SDL_JoystickGetGUID(joy);
213 } else {
214 guid = SDL_JoystickGetDeviceGUID(pgJoystick_AsID(self));
215 }
216
217 SDL_JoystickGetGUIDString(guid, strguid, 33);
218
219 return Text_FromUTF8(strguid);
220 }
221
222
_pg_powerlevel_string(SDL_JoystickPowerLevel level)223 const char *_pg_powerlevel_string(SDL_JoystickPowerLevel level) {
224 switch (level) {
225 case SDL_JOYSTICK_POWER_EMPTY:
226 return "empty";
227 case SDL_JOYSTICK_POWER_LOW:
228 return "low";
229 case SDL_JOYSTICK_POWER_MEDIUM:
230 return "medium";
231 case SDL_JOYSTICK_POWER_FULL:
232 return "full";
233 case SDL_JOYSTICK_POWER_WIRED:
234 return "wired";
235 case SDL_JOYSTICK_POWER_MAX:
236 return "max";
237 default:
238 return "unknown";
239 }
240 }
241
242
243 static PyObject *
joy_get_power_level(PyObject * self,PyObject * args)244 joy_get_power_level(PyObject *self, PyObject *args)
245 {
246 SDL_JoystickPowerLevel level;
247 const char *leveltext;
248 SDL_Joystick *joy = pgJoystick_AsSDL(self);
249
250 JOYSTICK_INIT_CHECK();
251 if (!joy) {
252 return RAISE(pgExc_SDLError, "Joystick not initialized");
253 }
254
255 level = SDL_JoystickCurrentPowerLevel(joy);
256 leveltext = _pg_powerlevel_string(level);
257
258 return Text_FromUTF8(leveltext);
259 }
260
261 static PyObject *
joy_rumble(pgJoystickObject * self,PyObject * args,PyObject * kwargs)262 joy_rumble(pgJoystickObject *self, PyObject *args, PyObject *kwargs)
263 {
264 #if SDL_VERSION_ATLEAST(2, 0, 9)
265
266 SDL_Joystick *joy = self->joy;
267 float low;
268 float high;
269 uint32_t duration;
270 int res;
271
272 char *keywords[] = {
273 "low_frequency",
274 "high_frequency",
275 "duration",
276 NULL,
277 };
278
279 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ffI", keywords, &low,
280 &high, &duration)) {
281 return NULL;
282 }
283
284 JOYSTICK_INIT_CHECK();
285 if (!joy) {
286 return RAISE(pgExc_SDLError, "Joystick not initialized");
287 }
288
289 if (low < 0) {
290 low = 0.f;
291 }
292 else if (low > 1.f) {
293 low = 1.f;
294 }
295
296 if (high < 0) {
297 high = 0.f;
298 }
299 else if (high > 1.f) {
300 high = 1.f;
301 }
302 low *= 0xFFFF;
303 high *= 0xFFFF;
304
305 res = SDL_JoystickRumble(joy, low, high, duration);
306 if (res == -1) {
307 Py_RETURN_FALSE;
308 }
309 Py_RETURN_TRUE;
310
311 #else
312 Py_RETURN_FALSE;
313 #endif
314 }
315
316 static PyObject *
joy_stop_rumble(pgJoystickObject * self)317 joy_stop_rumble(pgJoystickObject *self)
318 {
319 #if SDL_VERSION_ATLEAST(2, 0, 9)
320 SDL_Joystick *joy = self->joy;
321 SDL_JoystickRumble(joy, 0, 0, 1);
322 #endif
323 Py_RETURN_NONE;
324 }
325
326
327 static PyObject *
joy_get_name(PyObject * self,PyObject * args)328 joy_get_name(PyObject *self, PyObject *args)
329 {
330 SDL_Joystick *joy = pgJoystick_AsSDL(self);
331 return Text_FromUTF8(SDL_JoystickName(joy));
332 }
333
334 static PyObject *
joy_get_numaxes(PyObject * self,PyObject * args)335 joy_get_numaxes(PyObject *self, PyObject *args)
336 {
337 SDL_Joystick *joy = pgJoystick_AsSDL(self);
338 JOYSTICK_INIT_CHECK();
339 if (!joy) {
340 return RAISE(pgExc_SDLError, "Joystick not initialized");
341 }
342
343 return PyInt_FromLong(SDL_JoystickNumAxes(joy));
344 }
345
346 static PyObject *
joy_get_axis(PyObject * self,PyObject * args)347 joy_get_axis(PyObject *self, PyObject *args)
348 {
349 SDL_Joystick *joy = pgJoystick_AsSDL(self);
350 int axis, value;
351
352 if (!PyArg_ParseTuple(args, "i", &axis)) {
353 return NULL;
354 }
355
356 JOYSTICK_INIT_CHECK();
357 if (!joy) {
358 return RAISE(pgExc_SDLError, "Joystick not initialized");
359 }
360 if (axis < 0 || axis >= SDL_JoystickNumAxes(joy)) {
361 return RAISE(pgExc_SDLError, "Invalid joystick axis");
362 }
363
364 value = SDL_JoystickGetAxis(joy, axis);
365 #ifdef DEBUG
366 /*printf("SDL_JoystickGetAxis value:%d:\n", value);*/
367 #endif
368
369 return PyFloat_FromDouble(value / 32768.0);
370 }
371
372 static PyObject *
joy_get_numbuttons(PyObject * self,PyObject * args)373 joy_get_numbuttons(PyObject *self, PyObject *args)
374 {
375 SDL_Joystick *joy = pgJoystick_AsSDL(self);
376
377 JOYSTICK_INIT_CHECK();
378 if (!joy) {
379 return RAISE(pgExc_SDLError, "Joystick not initialized");
380 }
381
382 return PyInt_FromLong(SDL_JoystickNumButtons(joy));
383 }
384
385 static PyObject *
joy_get_button(PyObject * self,PyObject * args)386 joy_get_button(PyObject *self, PyObject *args)
387 {
388 SDL_Joystick *joy = pgJoystick_AsSDL(self);
389 int _index, value;
390
391 if (!PyArg_ParseTuple(args, "i", &_index)) {
392 return NULL;
393 }
394
395 JOYSTICK_INIT_CHECK();
396 if (!joy) {
397 return RAISE(pgExc_SDLError, "Joystick not initialized");
398 }
399 if (_index < 0 || _index >= SDL_JoystickNumButtons(joy)) {
400 return RAISE(pgExc_SDLError, "Invalid joystick button");
401 }
402
403 value = SDL_JoystickGetButton(joy, _index);
404 #ifdef DEBUG
405 /*printf("SDL_JoystickGetButton value:%d:\n", value);*/
406 #endif
407 return PyInt_FromLong(value);
408 }
409
410 static PyObject *
joy_get_numballs(PyObject * self,PyObject * args)411 joy_get_numballs(PyObject *self, PyObject *args)
412 {
413 SDL_Joystick *joy = pgJoystick_AsSDL(self);
414
415 JOYSTICK_INIT_CHECK();
416 if (!joy) {
417 return RAISE(pgExc_SDLError, "Joystick not initialized");
418 }
419
420 return PyInt_FromLong(SDL_JoystickNumBalls(joy));
421 }
422
423 static PyObject *
joy_get_ball(PyObject * self,PyObject * args)424 joy_get_ball(PyObject *self, PyObject *args)
425 {
426 SDL_Joystick *joy = pgJoystick_AsSDL(self);
427 int _index, dx, dy;
428 int value;
429
430 if (!PyArg_ParseTuple(args, "i", &_index)) {
431 return NULL;
432 }
433
434 JOYSTICK_INIT_CHECK();
435 if (!joy) {
436 return RAISE(pgExc_SDLError, "Joystick not initialized");
437 }
438 value = SDL_JoystickNumBalls(joy);
439 #ifdef DEBUG
440 /*printf("SDL_JoystickNumBalls value:%d:\n", value);*/
441 #endif
442 if (_index < 0 || _index >= value) {
443 return RAISE(pgExc_SDLError, "Invalid joystick trackball");
444 }
445
446 SDL_JoystickGetBall(joy, _index, &dx, &dy);
447 return Py_BuildValue("(ii)", dx, dy);
448 }
449
450 static PyObject *
joy_get_numhats(PyObject * self,PyObject * args)451 joy_get_numhats(PyObject *self, PyObject *args)
452 {
453 Uint32 value;
454 SDL_Joystick *joy = pgJoystick_AsSDL(self);
455
456 JOYSTICK_INIT_CHECK();
457 if (!joy) {
458 return RAISE(pgExc_SDLError, "Joystick not initialized");
459 }
460
461 value = SDL_JoystickNumHats(joy);
462 #ifdef DEBUG
463 /*printf("SDL_JoystickNumHats value:%d:\n", value);*/
464 #endif
465 return PyInt_FromLong(value);
466 }
467
468 static PyObject *
joy_get_hat(PyObject * self,PyObject * args)469 joy_get_hat(PyObject *self, PyObject *args)
470 {
471 SDL_Joystick *joy = pgJoystick_AsSDL(self);
472 int _index, px, py;
473 Uint32 value;
474
475 if (!PyArg_ParseTuple(args, "i", &_index)) {
476 return NULL;
477 }
478
479 JOYSTICK_INIT_CHECK();
480 if (!joy) {
481 return RAISE(pgExc_SDLError, "Joystick not initialized");
482 }
483 if (_index < 0 || _index >= SDL_JoystickNumHats(joy)) {
484 return RAISE(pgExc_SDLError, "Invalid joystick hat");
485 }
486
487 px = py = 0;
488 value = SDL_JoystickGetHat(joy, _index);
489 #ifdef DEBUG
490 /*printf("SDL_JoystickGetHat value:%d:\n", value);*/
491 #endif
492 if (value & SDL_HAT_UP) {
493 py = 1;
494 }
495 else if (value & SDL_HAT_DOWN) {
496 py = -1;
497 }
498 if (value & SDL_HAT_RIGHT) {
499 px = 1;
500 }
501 else if (value & SDL_HAT_LEFT) {
502 px = -1;
503 }
504
505 return Py_BuildValue("(ii)", px, py);
506 }
507
508 static PyMethodDef joy_methods[] = {
509 {"init", joy_init, METH_NOARGS, DOC_JOYSTICKINIT},
510 {"quit", joy_quit, METH_NOARGS, DOC_JOYSTICKQUIT},
511 {"get_init", joy_get_init, METH_NOARGS, DOC_JOYSTICKGETINIT},
512
513 {"get_id", joy_get_id, METH_NOARGS, DOC_JOYSTICKGETID},
514 {"get_instance_id", joy_get_instance_id, METH_NOARGS, DOC_JOYSTICKGETINSTANCEID},
515 {"get_guid", joy_get_guid, METH_NOARGS, DOC_JOYSTICKGETGUID},
516 {"get_power_level", joy_get_power_level, METH_NOARGS, DOC_JOYSTICKGETPOWERLEVEL},
517 {"rumble", (PyCFunction)joy_rumble, METH_VARARGS | METH_KEYWORDS, DOC_JOYSTICKRUMBLE},
518 {"stop_rumble", (PyCFunction)joy_stop_rumble, METH_NOARGS, DOC_JOYSTICKSTOPRUMBLE},
519 {"get_name", joy_get_name, METH_NOARGS, DOC_JOYSTICKGETNAME},
520
521 {"get_numaxes", joy_get_numaxes, METH_NOARGS,
522 DOC_JOYSTICKGETNUMAXES},
523 {"get_axis", joy_get_axis, METH_VARARGS, DOC_JOYSTICKGETAXIS},
524 {"get_numbuttons", joy_get_numbuttons, METH_NOARGS,
525 DOC_JOYSTICKGETNUMBUTTONS},
526 {"get_button", joy_get_button, METH_VARARGS, DOC_JOYSTICKGETBUTTON},
527 {"get_numballs", joy_get_numballs, METH_NOARGS,
528 DOC_JOYSTICKGETNUMBALLS},
529 {"get_ball", joy_get_ball, METH_VARARGS, DOC_JOYSTICKGETBALL},
530 {"get_numhats", joy_get_numhats, METH_NOARGS,
531 DOC_JOYSTICKGETNUMHATS},
532 {"get_hat", joy_get_hat, METH_VARARGS, DOC_JOYSTICKGETHAT},
533
534 {NULL, NULL, 0, NULL}};
535
536 static PyTypeObject pgJoystick_Type = {
537 PyVarObject_HEAD_INIT(NULL,0)
538 "Joystick", /* name */
539 sizeof(pgJoystickObject), /* basic size */
540 0, /* itemsize */
541 joy_dealloc, /* dealloc */
542 0, /* print */
543 0, /* getattr */
544 0, /* setattr */
545 0, /* compare */
546 0, /* repr */
547 0, /* as_number */
548 0, /* as_sequence */
549 0, /* as_mapping */
550 0, /* hash */
551 0, /* call */
552 0, /* str */
553 0, /* tp_getattro */
554 0, /* tp_setattro */
555 0, /* tp_as_buffer */
556 0, /* flags */
557 DOC_PYGAMEJOYSTICKJOYSTICK, /* Documentation string */
558 0, /* tp_traverse */
559 0, /* tp_clear */
560 0, /* tp_richcompare */
561 0, /* tp_weaklistoffset */
562 0, /* tp_iter */
563 0, /* tp_iternext */
564 joy_methods, /* tp_methods */
565 0, /* tp_members */
566 0, /* tp_getset */
567 0, /* tp_base */
568 0, /* tp_dict */
569 0, /* tp_descr_get */
570 0, /* tp_descr_set */
571 0, /* tp_dictoffset */
572 0, /* tp_init */
573 0, /* tp_alloc */
574 0, /* tp_new */
575 };
576
577 static PyObject *
pgJoystick_New(int id)578 pgJoystick_New(int id)
579 {
580 pgJoystickObject *jstick, *cur;
581 SDL_Joystick *joy;
582
583 JOYSTICK_INIT_CHECK();
584
585 /* Open the SDL device */
586 if (id >= SDL_NumJoysticks()) {
587 return RAISE(pgExc_SDLError, "Invalid joystick device number");
588 }
589 joy = SDL_JoystickOpen(id);
590 if (!joy) {
591 return RAISE(pgExc_SDLError, SDL_GetError());
592 }
593
594 /* Search existing joystick objects to see if we already have this stick. */
595 cur = joylist_head;
596 while (cur) {
597 if (cur->joy == joy) {
598 Py_INCREF(cur);
599 return (PyObject *) cur;
600 }
601 cur = cur->next;
602 }
603
604 /* Construct the Python object */
605 jstick = PyObject_NEW(pgJoystickObject, &pgJoystick_Type);
606 if (!jstick) {
607 return NULL;
608 }
609 jstick->id = id;
610 jstick->joy = joy;
611 jstick->prev = NULL;
612 jstick->next = joylist_head;
613 if (joylist_head) {
614 joylist_head->prev = jstick;
615 }
616 joylist_head = jstick;
617
618 if (-1 == _joy_map_insert(jstick)) {
619 Py_DECREF(jstick);
620 return NULL;
621 }
622
623 return (PyObject *)jstick;
624 }
625
626 static PyMethodDef _joystick_methods[] = {
627 {"init", (PyCFunction)init, METH_NOARGS, DOC_PYGAMEJOYSTICKINIT},
628 {"quit", (PyCFunction)quit, METH_NOARGS, DOC_PYGAMEJOYSTICKQUIT},
629 {"get_init", (PyCFunction)get_init, METH_NOARGS,
630 DOC_PYGAMEJOYSTICKGETINIT},
631 {"get_count", (PyCFunction)get_count, METH_NOARGS,
632 DOC_PYGAMEJOYSTICKGETCOUNT},
633 {"Joystick", Joystick, METH_VARARGS, DOC_PYGAMEJOYSTICKJOYSTICK},
634 {NULL, NULL, 0, NULL}};
635
MODINIT_DEFINE(joystick)636 MODINIT_DEFINE(joystick)
637 {
638 PyObject *module, *dict, *apiobj;
639 int ecode;
640 static void *c_api[PYGAMEAPI_JOYSTICK_NUMSLOTS];
641
642 static struct PyModuleDef _module = {PyModuleDef_HEAD_INIT,
643 "joystick",
644 DOC_PYGAMEJOYSTICK,
645 -1,
646 _joystick_methods,
647 NULL,
648 NULL,
649 NULL,
650 NULL};
651
652 /* imported needed apis; Do this first so if there is an error
653 the module is not loaded.
654 */
655 import_pygame_base();
656 if (PyErr_Occurred()) {
657 MODINIT_ERROR;
658 }
659
660 /* type preparation */
661 if (PyType_Ready(&pgJoystick_Type) == -1) {
662 MODINIT_ERROR;
663 }
664
665 /* Grab the instance -> device id mapping */
666 module = PyImport_ImportModule("pygame.event");
667 if (!module) {
668 MODINIT_ERROR;
669 }
670 joy_instance_map = PyObject_GetAttrString(module, "_joy_instance_map");
671 Py_DECREF(module);
672
673 /* create the module */
674 module = PyModule_Create(&_module);
675 if (module == NULL) {
676 MODINIT_ERROR;
677 }
678 dict = PyModule_GetDict(module);
679
680 if (PyDict_SetItemString(dict, "JoystickType",
681 (PyObject *)&pgJoystick_Type) == -1) {
682 DECREF_MOD(module);
683 MODINIT_ERROR;
684 }
685
686 /* export the c api */
687 c_api[0] = &pgJoystick_Type;
688 c_api[1] = pgJoystick_New;
689 apiobj = encapsulate_api(c_api, "joystick");
690 if (apiobj == NULL) {
691 DECREF_MOD(module);
692 MODINIT_ERROR;
693 }
694 ecode = PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
695 Py_DECREF(apiobj);
696 if (ecode == -1) {
697 DECREF_MOD(module);
698 MODINIT_ERROR;
699 }
700 MODINIT_RETURN(module);
701 }
702