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>
40 #define _UnimplementedToolTrap 0xA89F
41 #define _CommToolboxTrap 0x8B
42 #define _UnimplementedOSTrap 0x9F
44 static char *errornames
[] = {
51 "No Request Pending", /* 6 */
52 "Not Supported", /* 7 */
54 "User Cancel", /* 9 */
56 "Unknown Error", /* 11 */
57 #define MAX_POS_ERROR 11
60 extern PyObject
*PyErr_Mac(PyObject
*,int);
63 PyCtb_Error(PyObject
*errobj
, int errcode
)
65 if ( errcode
> 0 && errcode
<= MAX_POS_ERROR
) {
66 PyErr_SetString(errobj
, errornames
[errcode
]);
69 return PyErr_Mac(errobj
, errcode
);
73 static PyObject
*ErrorObject
;
77 ConnHandle hdl
; /* The handle to the connection */
78 PyObject
*callback
; /* Python callback routine */
79 int has_callback
; /* True if callback not None */
80 int err
; /* Error to pass to the callback */
83 staticforward PyTypeObject ctbcmtype
;
85 #define is_ctbcmobject(v) ((v)->ob_type == &ctbcmtype)
88 TrapAvailable(short tNumber
, TrapType tType
)
93 unImplemented
= _UnimplementedOSTrap
;
95 unImplemented
= _UnimplementedToolTrap
;
97 return NGetTrapAddress(tNumber
, tType
) != NGetTrapAddress(unImplemented
, tType
);
104 static initialized
= -1;
106 if ( initialized
>= 0 )
110 if ( !TrapAvailable(_CommToolboxTrap
, OSTrap
) ) {
111 PyErr_SetString(ErrorObject
, "CTB not available");
114 if ( (err
=InitCTBUtilities()) ) {
115 PyCtb_Error(ErrorObject
, (int)err
);
118 if ( (err
=InitCRM()) ) {
119 PyCtb_Error(ErrorObject
, (int)err
);
122 if ( (err
=InitCM()) ) {
123 PyCtb_Error(ErrorObject
, (int)err
);
131 ctbcm_pycallback(arg
)
134 ctbcmobject
*self
= (ctbcmobject
*)arg
;
137 if ( !self
->has_callback
) /* It could have been removed in the meantime */
139 args
= Py_BuildValue("(i)", self
->err
);
140 rv
= PyEval_CallObject(self
->callback
, args
);
148 /*DBG*/int ncallback
;
150 ctbcm_ctbcallback(hconn
)
155 /* XXXX Do I have to do the A5 mumbo-jumbo? */
157 self
= (ctbcmobject
*)CMGetUserData(hconn
);
158 self
->err
= (int)((*hconn
)->errCode
);
159 Py_AddPendingCall(ctbcm_pycallback
, (void *)self
);
167 self
= PyObject_NEW(ctbcmobject
, &ctbcmtype
);
172 self
->callback
= Py_None
;
173 self
->has_callback
= 0;
184 (void)CMClose(self
->hdl
, 0, (ConnectionCompletionUPP
)0, 0, 1);
185 /*XXXX Is this safe? */
186 CMDispose(self
->hdl
);
193 ctbcm_open(self
, args
)
199 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
201 if (!PyArg_Parse(args
, "l", &timeout
))
203 if ( (err
=CMOpen(self
->hdl
, self
->has_callback
, cb_upp
, timeout
)) != 0)
204 return PyCtb_Error(ErrorObject
, (int)err
);
210 ctbcm_listen(self
, args
)
216 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
218 if (!PyArg_Parse(args
, "l", &timeout
))
220 if ( (err
=CMListen(self
->hdl
,self
->has_callback
, cb_upp
, timeout
)) != 0)
221 return PyCtb_Error(ErrorObject
, (int)err
);
227 ctbcm_accept(self
, args
)
234 if (!PyArg_Parse(args
, "i", &accept
))
236 if ( (err
=CMAccept(self
->hdl
, accept
)) != 0)
237 return PyCtb_Error(ErrorObject
, (int)err
);
243 ctbcm_close(self
, args
)
250 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
252 if (!PyArg_Parse(args
, "(li)", &timeout
, &now
))
254 if ( (err
=CMClose(self
->hdl
, self
->has_callback
, cb_upp
, timeout
, now
)) != 0)
255 return PyCtb_Error(ErrorObject
, (int)err
);
261 ctbcm_read(self
, args
)
270 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
272 if (!PyArg_Parse(args
, "(lil)", &len
, &chan
, &timeout
))
274 if ((rv
=PyString_FromStringAndSize(NULL
, len
)) == NULL
)
276 if ((err
=CMRead(self
->hdl
, (Ptr
)PyString_AsString(rv
), &len
, (CMChannel
)chan
,
277 self
->has_callback
, cb_upp
, timeout
, &flags
)) != 0 && err
!= cmTimeOut
)
278 return PyCtb_Error(ErrorObject
, (int)err
);
279 _PyString_Resize(&rv
, len
);
280 rrv
= Py_BuildValue("(Oi)", rv
, (int)flags
);
286 ctbcm_write(self
, args
)
291 int chan
, ilen
, flags
;
294 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
296 if (!PyArg_Parse(args
, "(s#ili)", &buf
, &ilen
, &chan
, &timeout
, &flags
))
299 if ((err
=CMWrite(self
->hdl
, (Ptr
)buf
, &len
, (CMChannel
)chan
,
300 self
->has_callback
, cb_upp
, timeout
, (CMFlags
)flags
)) != 0 && err
!= cmTimeOut
)
301 return PyCtb_Error(ErrorObject
, (int)err
);
302 return PyInt_FromLong((int)len
);
306 ctbcm_status(self
, args
)
315 if (!PyArg_NoArgs(args
))
317 if ((err
=CMStatus(self
->hdl
, sizes
, &flags
)) != 0)
318 return PyCtb_Error(ErrorObject
, (int)err
);
319 rv
= Py_BuildValue("(llllll)", sizes
[0], sizes
[1], sizes
[2], sizes
[3], sizes
[4], sizes
[5]);
322 rrv
= Py_BuildValue("(Ol)", rv
, (long)flags
);
328 ctbcm_getconfig(self
, args
)
334 if (!PyArg_NoArgs(args
))
336 if ((rv
=(char *)CMGetConfig(self
->hdl
)) == NULL
) {
337 PyErr_SetString(ErrorObject
, "CMGetConfig failed");
340 return PyString_FromString(rv
);
344 ctbcm_setconfig(self
, args
)
351 if (!PyArg_Parse(args
, "s", &cfg
))
353 rv
=CMSetConfig(self
->hdl
, (Ptr
)cfg
);
354 return PyInt_FromLong((long)rv
);
358 ctbcm_choose(self
, args
)
365 if (!PyArg_NoArgs(args
))
369 rv
=CMChoose(&self
->hdl
, pt
, (ConnectionChooseIdleUPP
)0);
370 return PyInt_FromLong(rv
);
374 ctbcm_idle(self
, args
)
378 if (!PyArg_NoArgs(args
))
386 ctbcm_abort(self
, args
)
390 if (!PyArg_NoArgs(args
))
398 ctbcm_reset(self
, args
)
402 if (!PyArg_NoArgs(args
))
410 ctbcm_break(self
, args
)
415 ConnectionCompletionUPP cb_upp
= NewConnectionCompletionProc(ctbcm_ctbcallback
);
417 if (!PyArg_Parse(args
, "l", &duration
))
419 CMBreak(self
->hdl
, duration
,self
->has_callback
, cb_upp
);
424 static struct PyMethodDef ctbcm_methods
[] = {
425 {"Open", (PyCFunction
)ctbcm_open
},
426 {"Close", (PyCFunction
)ctbcm_close
},
427 {"Read", (PyCFunction
)ctbcm_read
},
428 {"Write", (PyCFunction
)ctbcm_write
},
429 {"Status", (PyCFunction
)ctbcm_status
},
430 {"GetConfig", (PyCFunction
)ctbcm_getconfig
},
431 {"SetConfig", (PyCFunction
)ctbcm_setconfig
},
432 {"Choose", (PyCFunction
)ctbcm_choose
},
433 {"Idle", (PyCFunction
)ctbcm_idle
},
434 {"Listen", (PyCFunction
)ctbcm_listen
},
435 {"Accept", (PyCFunction
)ctbcm_accept
},
436 {"Abort", (PyCFunction
)ctbcm_abort
},
437 {"Reset", (PyCFunction
)ctbcm_reset
},
438 {"Break", (PyCFunction
)ctbcm_break
},
439 {NULL
, NULL
} /* sentinel */
443 ctbcm_getattr(self
, name
)
447 if ( strcmp(name
, "callback") == 0 ) {
448 Py_INCREF(self
->callback
);
449 return self
->callback
;
451 return Py_FindMethod(ctbcm_methods
, (PyObject
*)self
, name
);
455 ctbcm_setattr(self
, name
, v
)
460 if ( strcmp(name
, "callback") != 0 ) {
461 PyErr_SetString(PyExc_AttributeError
, "ctbcm objects have callback attr only");
469 self
->has_callback
= (v
!= Py_None
);
473 statichere PyTypeObject ctbcmtype
= {
474 PyObject_HEAD_INIT(&PyType_Type
)
476 "CTBConnectionMgr", /*tp_name*/
477 sizeof(ctbcmobject
), /*tp_basicsize*/
480 (destructor
)ctbcm_dealloc
, /*tp_dealloc*/
482 (getattrfunc
)ctbcm_getattr
, /*tp_getattr*/
483 (setattrfunc
)ctbcm_setattr
, /*tp_setattr*/
487 0, /*tp_as_sequence*/
491 /* --------------------------------------------------------------------- */
493 /* Function of no arguments returning new ctbcm object */
496 ctb_cmnew(self
, args
)
497 PyObject
*self
; /* Not used */
503 unsigned char p_str
[255];
509 if (!PyArg_Parse(args
, "(s#O)", &c_str
, &strlen
, &sizes_obj
))
511 strncpy((char *)p_str
+1, c_str
, strlen
);
513 if (!initialize_ctb())
515 if ( sizes_obj
== Py_None
) {
516 memset(sizes
, '\0', sizeof sizes
);
518 if ( !PyArg_Parse(sizes_obj
, "(llllll)", &sizes
[0], &sizes
[1], &sizes
[2],
519 &sizes
[3], &sizes
[4], &sizes
[5]))
522 if ( (procid
=CMGetProcID(p_str
)) < 0 )
523 return PyCtb_Error(ErrorObject
, procid
);
524 hdl
= CMNew(procid
, cmNoMenus
|cmQuiet
, sizes
, 0, 0);
526 PyErr_SetString(ErrorObject
, "CMNew failed");
529 rv
= newctbcmobject(args
);
531 return NULL
; /* XXXX Should dispose of hdl */
533 CMSetUserData(hdl
, (long)rv
);
534 return (PyObject
*)rv
;
538 ctb_available(self
, args
)
544 if (!PyArg_NoArgs(args
))
546 ok
= initialize_ctb();
548 return PyInt_FromLong(ok
);
551 /* List of functions defined in the module */
553 static struct PyMethodDef ctb_methods
[] = {
554 {"CMNew", ctb_cmnew
},
555 {"available", ctb_available
},
556 {NULL
, NULL
} /* sentinel */
560 /* Initialization function for the module (*must* be called initctb) */
567 /* Create the module and add the functions */
568 m
= Py_InitModule("ctb", ctb_methods
);
570 /* Add some symbolic constants to the module */
571 d
= PyModule_GetDict(m
);
573 #define CMCONST(name, value) o = PyInt_FromLong(value); PyDict_SetItemString(d, name, o)
575 CMCONST("cmData", 1);
576 CMCONST("cmCntl", 2);
577 CMCONST("cmAttn", 3);
579 CMCONST("cmFlagsEOM", 1);
581 CMCONST("chooseDisaster", -2);
582 CMCONST("chooseFailed", -1);
583 CMCONST("chooseAborted", 0);
584 CMCONST("chooseOKMinor", 1);
585 CMCONST("chooseOKMajor", 2);
586 CMCONST("chooseCancel", 3);
588 CMCONST("cmStatusOpening", 1);
589 CMCONST("cmStatusOpen", 2);
590 CMCONST("cmStatusClosing", 4);
591 CMCONST("cmStatusDataAvail", 8);
592 CMCONST("cmStatusCntlAvail", 0x10);
593 CMCONST("cmStatusAttnAvail", 0x20);
594 CMCONST("cmStatusDRPend", 0x40);
595 CMCONST("cmStatusDWPend", 0x80);
596 CMCONST("cmStatusCWPend", 0x100);
597 CMCONST("cmStatusCWPend", 0x200);
598 CMCONST("cmStatusARPend", 0x400);
599 CMCONST("cmStatusAWPend", 0x800);
600 CMCONST("cmStatusBreakPending", 0x1000);
601 CMCONST("cmStatusListenPend", 0x2000);
602 CMCONST("cmStatusIncomingCallPresent", 0x4000);
604 ErrorObject
= PyErr_NewException("ctb.error", NULL
, NULL
);
605 PyDict_SetItemString(d
, "error", ErrorObject
);
606 ctbcmtype
.ob_type
= &PyType_Type
;
607 Py_INCREF(&ctbcmtype
);
608 PyDict_SetItemString(d
, "CTBConnectionMgrType", (PyObject
*)&ctbcmtype
);