1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Note: This file is partially converted to the new naming standard */
33 #include <CommResources.h>
34 #include <Connections.h>
35 #include <CTBUtilities.h>
36 #include <ToolUtils.h>
39 #ifndef HAVE_UNIVERSAL_HEADERS
40 #define ConnectionCompletionUPP ProcPtr
41 #define ConnectionChooseIdleUPP ProcPtr
42 #define NewConnectionCompletionProc(x) (x)
43 #define NewConnectionChooseIdleProc(x) (x)
46 #define _UnimplementedToolTrap 0xA89F
47 #define _CommToolboxTrap 0x8B
48 #define _UnimplementedOSTrap 0x9F
50 static char *errornames
[] = {
57 "No Request Pending", /* 6 */
58 "Not Supported", /* 7 */
60 "User Cancel", /* 9 */
62 "Unknown Error", /* 11 */
63 #define MAX_POS_ERROR 11
66 extern PyObject
*PyErr_Mac(PyObject
*,int);
69 PyCtb_Error(PyObject
*errobj
, int errcode
)
71 if ( errcode
> 0 && errcode
<= MAX_POS_ERROR
) {
72 PyErr_SetString(errobj
, errornames
[errcode
]);
75 return PyErr_Mac(errobj
, errcode
);
79 static PyObject
*ErrorObject
;
83 ConnHandle hdl
; /* The handle to the connection */
84 PyObject
*callback
; /* Python callback routine */
85 int has_callback
; /* True if callback not None */
86 int err
; /* Error to pass to the callback */
89 staticforward PyTypeObject ctbcmtype
;
91 #define is_ctbcmobject(v) ((v)->ob_type == &ctbcmtype)
94 TrapAvailable(short tNumber
, TrapType tType
)
99 unImplemented
= _UnimplementedOSTrap
;
101 unImplemented
= _UnimplementedToolTrap
;
103 return NGetTrapAddress(tNumber
, tType
) != NGetTrapAddress(unImplemented
, tType
);
110 static initialized
= -1;
112 if ( initialized
>= 0 )
116 if ( !TrapAvailable(_CommToolboxTrap
, OSTrap
) ) {
117 PyErr_SetString(ErrorObject
, "CTB not available");
120 if ( (err
=InitCTBUtilities()) ) {
121 PyCtb_Error(ErrorObject
, (int)err
);
124 if ( (err
=InitCRM()) ) {
125 PyCtb_Error(ErrorObject
, (int)err
);
128 if ( (err
=InitCM()) ) {
129 PyCtb_Error(ErrorObject
, (int)err
);
137 ctbcm_pycallback(arg
)
140 ctbcmobject
*self
= (ctbcmobject
*)arg
;
143 if ( !self
->has_callback
) /* It could have been removed in the meantime */
145 args
= Py_BuildValue("(i)", self
->err
);
146 rv
= PyEval_CallObject(self
->callback
, args
);
154 /*DBG*/int ncallback
;
156 ctbcm_ctbcallback(hconn
)
161 /* XXXX Do I have to do the A5 mumbo-jumbo? */
163 self
= (ctbcmobject
*)CMGetUserData(hconn
);
164 self
->err
= (int)((*hconn
)->errCode
);
165 Py_AddPendingCall(ctbcm_pycallback
, (void *)self
);
173 self
= PyObject_NEW(ctbcmobject
, &ctbcmtype
);
178 self
->callback
= Py_None
;
179 self
->has_callback
= 0;
190 (void)CMClose(self
->hdl
, 0, (ConnectionCompletionUPP
)0, 0, 1);
191 /*XXXX Is this safe? */
192 CMDispose(self
->hdl
);
199 ctbcm_open(self
, args
)
205 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
207 if (!PyArg_Parse(args
, "l", &timeout
))
209 if ( (err
=CMOpen(self
->hdl
, self
->has_callback
, cb_upp
, timeout
)) != 0)
210 return PyCtb_Error(ErrorObject
, (int)err
);
216 ctbcm_listen(self
, args
)
222 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
224 if (!PyArg_Parse(args
, "l", &timeout
))
226 if ( (err
=CMListen(self
->hdl
,self
->has_callback
, cb_upp
, timeout
)) != 0)
227 return PyCtb_Error(ErrorObject
, (int)err
);
233 ctbcm_accept(self
, args
)
240 if (!PyArg_Parse(args
, "i", &accept
))
242 if ( (err
=CMAccept(self
->hdl
, accept
)) != 0)
243 return PyCtb_Error(ErrorObject
, (int)err
);
249 ctbcm_close(self
, args
)
256 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
258 if (!PyArg_Parse(args
, "(li)", &timeout
, &now
))
260 if ( (err
=CMClose(self
->hdl
, self
->has_callback
, cb_upp
, timeout
, now
)) != 0)
261 return PyCtb_Error(ErrorObject
, (int)err
);
267 ctbcm_read(self
, args
)
276 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
278 if (!PyArg_Parse(args
, "(lil)", &len
, &chan
, &timeout
))
280 if ((rv
=PyString_FromStringAndSize(NULL
, len
)) == NULL
)
282 if ((err
=CMRead(self
->hdl
, (Ptr
)PyString_AsString(rv
), &len
, (CMChannel
)chan
,
283 self
->has_callback
, cb_upp
, timeout
, &flags
)) != 0 && err
!= cmTimeOut
)
284 return PyCtb_Error(ErrorObject
, (int)err
);
285 _PyString_Resize(&rv
, len
);
286 rrv
= Py_BuildValue("(Oi)", rv
, (int)flags
);
292 ctbcm_write(self
, args
)
297 int chan
, ilen
, flags
;
300 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
302 if (!PyArg_Parse(args
, "(s#ili)", &buf
, &ilen
, &chan
, &timeout
, &flags
))
305 if ((err
=CMWrite(self
->hdl
, (Ptr
)buf
, &len
, (CMChannel
)chan
,
306 self
->has_callback
, cb_upp
, timeout
, (CMFlags
)flags
)) != 0 && err
!= cmTimeOut
)
307 return PyCtb_Error(ErrorObject
, (int)err
);
308 return PyInt_FromLong((int)len
);
312 ctbcm_status(self
, args
)
321 if (!PyArg_NoArgs(args
))
323 if ((err
=CMStatus(self
->hdl
, sizes
, &flags
)) != 0)
324 return PyCtb_Error(ErrorObject
, (int)err
);
325 rv
= Py_BuildValue("(llllll)", sizes
[0], sizes
[1], sizes
[2], sizes
[3], sizes
[4], sizes
[5]);
328 rrv
= Py_BuildValue("(Ol)", rv
, (long)flags
);
334 ctbcm_getconfig(self
, args
)
340 if (!PyArg_NoArgs(args
))
342 if ((rv
=(char *)CMGetConfig(self
->hdl
)) == NULL
) {
343 PyErr_SetString(ErrorObject
, "CMGetConfig failed");
346 return PyString_FromString(rv
);
350 ctbcm_setconfig(self
, args
)
357 if (!PyArg_Parse(args
, "s", &cfg
))
359 rv
=CMSetConfig(self
->hdl
, (Ptr
)cfg
);
360 return PyInt_FromLong((long)rv
);
364 ctbcm_choose(self
, args
)
371 if (!PyArg_NoArgs(args
))
375 rv
=CMChoose(&self
->hdl
, pt
, (ConnectionChooseIdleUPP
)0);
376 return PyInt_FromLong(rv
);
380 ctbcm_idle(self
, args
)
384 if (!PyArg_NoArgs(args
))
392 ctbcm_abort(self
, args
)
396 if (!PyArg_NoArgs(args
))
404 ctbcm_reset(self
, args
)
408 if (!PyArg_NoArgs(args
))
416 ctbcm_break(self
, args
)
421 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
423 if (!PyArg_Parse(args
, "l", &duration
))
425 CMBreak(self
->hdl
, duration
,self
->has_callback
, cb_upp
);
430 static struct PyMethodDef ctbcm_methods
[] = {
431 {"Open", (PyCFunction
)ctbcm_open
},
432 {"Close", (PyCFunction
)ctbcm_close
},
433 {"Read", (PyCFunction
)ctbcm_read
},
434 {"Write", (PyCFunction
)ctbcm_write
},
435 {"Status", (PyCFunction
)ctbcm_status
},
436 {"GetConfig", (PyCFunction
)ctbcm_getconfig
},
437 {"SetConfig", (PyCFunction
)ctbcm_setconfig
},
438 {"Choose", (PyCFunction
)ctbcm_choose
},
439 {"Idle", (PyCFunction
)ctbcm_idle
},
440 {"Listen", (PyCFunction
)ctbcm_listen
},
441 {"Accept", (PyCFunction
)ctbcm_accept
},
442 {"Abort", (PyCFunction
)ctbcm_abort
},
443 {"Reset", (PyCFunction
)ctbcm_reset
},
444 {"Break", (PyCFunction
)ctbcm_break
},
445 {NULL
, NULL
} /* sentinel */
449 ctbcm_getattr(self
, name
)
453 if ( strcmp(name
, "callback") == 0 ) {
454 Py_INCREF(self
->callback
);
455 return self
->callback
;
457 return Py_FindMethod(ctbcm_methods
, (PyObject
*)self
, name
);
461 ctbcm_setattr(self
, name
, v
)
466 if ( strcmp(name
, "callback") != 0 ) {
467 PyErr_SetString(PyExc_AttributeError
, "ctbcm objects have callback attr only");
475 self
->has_callback
= (v
!= Py_None
);
479 statichere PyTypeObject ctbcmtype
= {
480 PyObject_HEAD_INIT(&PyType_Type
)
482 "CTBConnectionMgr", /*tp_name*/
483 sizeof(ctbcmobject
), /*tp_basicsize*/
486 (destructor
)ctbcm_dealloc
, /*tp_dealloc*/
488 (getattrfunc
)ctbcm_getattr
, /*tp_getattr*/
489 (setattrfunc
)ctbcm_setattr
, /*tp_setattr*/
493 0, /*tp_as_sequence*/
497 /* --------------------------------------------------------------------- */
499 /* Function of no arguments returning new ctbcm object */
502 ctb_cmnew(self
, args
)
503 PyObject
*self
; /* Not used */
509 unsigned char p_str
[255];
515 if (!PyArg_Parse(args
, "(s#O)", &c_str
, &strlen
, &sizes_obj
))
517 strncpy((char *)p_str
+1, c_str
, strlen
);
519 if (!initialize_ctb())
521 if ( sizes_obj
== Py_None
) {
522 memset(sizes
, '\0', sizeof sizes
);
524 if ( !PyArg_Parse(sizes_obj
, "(llllll)", &sizes
[0], &sizes
[1], &sizes
[2],
525 &sizes
[3], &sizes
[4], &sizes
[5]))
528 if ( (procid
=CMGetProcID(p_str
)) < 0 )
529 return PyCtb_Error(ErrorObject
, procid
);
530 hdl
= CMNew(procid
, cmNoMenus
|cmQuiet
, sizes
, 0, 0);
532 PyErr_SetString(ErrorObject
, "CMNew failed");
535 rv
= newctbcmobject(args
);
537 return NULL
; /* XXXX Should dispose of hdl */
539 CMSetUserData(hdl
, (long)rv
);
540 return (PyObject
*)rv
;
544 ctb_available(self
, args
)
550 if (!PyArg_NoArgs(args
))
552 ok
= initialize_ctb();
554 return PyInt_FromLong(ok
);
557 /* List of functions defined in the module */
559 static struct PyMethodDef ctb_methods
[] = {
560 {"CMNew", ctb_cmnew
},
561 {"available", ctb_available
},
562 {NULL
, NULL
} /* sentinel */
566 /* Initialization function for the module (*must* be called initctb) */
573 /* Create the module and add the functions */
574 m
= Py_InitModule("ctb", ctb_methods
);
576 /* Add some symbolic constants to the module */
577 d
= PyModule_GetDict(m
);
579 #define CMCONST(name, value) o = PyInt_FromLong(value); PyDict_SetItemString(d, name, o)
581 CMCONST("cmData", 1);
582 CMCONST("cmCntl", 2);
583 CMCONST("cmAttn", 3);
585 CMCONST("cmFlagsEOM", 1);
587 CMCONST("chooseDisaster", -2);
588 CMCONST("chooseFailed", -1);
589 CMCONST("chooseAborted", 0);
590 CMCONST("chooseOKMinor", 1);
591 CMCONST("chooseOKMajor", 2);
592 CMCONST("chooseCancel", 3);
594 CMCONST("cmStatusOpening", 1);
595 CMCONST("cmStatusOpen", 2);
596 CMCONST("cmStatusClosing", 4);
597 CMCONST("cmStatusDataAvail", 8);
598 CMCONST("cmStatusCntlAvail", 0x10);
599 CMCONST("cmStatusAttnAvail", 0x20);
600 CMCONST("cmStatusDRPend", 0x40);
601 CMCONST("cmStatusDWPend", 0x80);
602 CMCONST("cmStatusCWPend", 0x100);
603 CMCONST("cmStatusCWPend", 0x200);
604 CMCONST("cmStatusARPend", 0x400);
605 CMCONST("cmStatusAWPend", 0x800);
606 CMCONST("cmStatusBreakPending", 0x1000);
607 CMCONST("cmStatusListenPend", 0x2000);
608 CMCONST("cmStatusIncomingCallPresent", 0x4000);
610 ErrorObject
= PyErr_NewException("ctb.error", NULL
, NULL
);
611 PyDict_SetItemString(d
, "error", ErrorObject
);
612 ctbcmtype
.ob_type
= &PyType_Type
;
613 Py_INCREF(&ctbcmtype
);
614 PyDict_SetItemString(d
, "CTBConnectionMgrType", (PyObject
*)&ctbcmtype
);