summaryrefslogtreecommitdiffstats
path: root/Mac/Modules/ctbmodule.c
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1994-12-14 13:31:11 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1994-12-14 13:31:11 (GMT)
commitee735be06a5f37ab59f4f51b6965ddb30314bc55 (patch)
tree38839c3b5892216af56cc3d127efe86c72cb4383 /Mac/Modules/ctbmodule.c
parent115590d22f15d25b1f2b1f96b8b8cf00f1e53784 (diff)
downloadcpython-ee735be06a5f37ab59f4f51b6965ddb30314bc55.zip
cpython-ee735be06a5f37ab59f4f51b6965ddb30314bc55.tar.gz
cpython-ee735be06a5f37ab59f4f51b6965ddb30314bc55.tar.bz2
Interface to Mac Communications Toolbox (only Connection Manager for
now)
Diffstat (limited to 'Mac/Modules/ctbmodule.c')
-rw-r--r--Mac/Modules/ctbmodule.c585
1 files changed, 585 insertions, 0 deletions
diff --git a/Mac/Modules/ctbmodule.c b/Mac/Modules/ctbmodule.c
new file mode 100644
index 0000000..52009a0
--- /dev/null
+++ b/Mac/Modules/ctbmodule.c
@@ -0,0 +1,585 @@
+/***********************************************************
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Note: This file is partially converted to the new naming standard */
+/* ctbcm objects */
+
+
+#include "allobjects.h"
+#include "modsupport.h" /* For getargs() etc. */
+
+#include <stdio.h>
+#include <CommResources.h>
+#include <Connections.h>
+#include <ToolUtils.h>
+#include <OSUtils.h>
+/* #include <pascal.h> */
+#ifndef __MWERKS__
+#define ConnectionCompletionUPP ProcPtr
+#define ConnectionChooseIdleUPP ProcPtr
+#define NewConnectionCompletionProc(x) (x)
+#define NewConnectionChooseIdleProc(x) (x)
+#endif
+
+#define _UnimplementedToolTrap 0xA89F
+#define _CommToolboxTrap 0x8B
+#define _UnimplementedOSTrap 0x9F
+
+extern object *PyErr_Mac(object *,int);
+
+static object *ErrorObject;
+
+typedef struct {
+ OB_HEAD
+ ConnHandle hdl; /* The handle to the connection */
+ object *callback; /* Python callback routine */
+ int has_callback; /* True if callback not None */
+ int err; /* Error to pass to the callback */
+} ctbcmobject;
+
+staticforward typeobject ctbcmtype;
+
+#define is_ctbcmobject(v) ((v)->ob_type == &ctbcmtype)
+
+static
+TrapAvailable(short tNumber, TrapType tType)
+{
+ short unImplemented;
+
+ if (tType == OSTrap)
+ unImplemented = _UnimplementedOSTrap;
+ else
+ unImplemented = _UnimplementedToolTrap;
+
+ return NGetTrapAddress(tNumber, tType) != NGetTrapAddress(unImplemented, tType);
+}
+
+static
+initialize_ctb()
+{
+ OSErr err;
+ static initialized = -1;
+
+ if ( initialized >= 0 )
+ return initialized;
+ initialized = 0;
+
+ if ( !TrapAvailable(_CommToolboxTrap, OSTrap) ) {
+ err_setstr(ErrorObject, "CTB not available");
+ return 0;
+ }
+ if ( (err=InitCTBUtilities()) ) {
+ PyErr_Mac(ErrorObject, (int)err);
+ return 0;
+ }
+ if ( (err=InitCRM()) ) {
+ PyErr_Mac(ErrorObject, (int)err);
+ return 0;
+ }
+ if ( (err=InitCM()) ) {
+ PyErr_Mac(ErrorObject, (int)err);
+ return 0;
+ }
+ initialized = 1;
+ return 1;
+}
+
+static int
+ctbcm_pycallback(arg)
+ void *arg;
+{
+ ctbcmobject *self = (ctbcmobject *)arg;
+ object *args, *rv;
+
+ if ( !self->has_callback ) /* It could have been removed in the meantime */
+ return 0;
+ args = mkvalue("(i)", self->err);
+ rv = call_object(self->callback, args);
+ DECREF(args);
+ if( rv == NULL )
+ return -1;
+ DECREF(rv);
+ return 0;
+}
+
+/*DBG*/int ncallback;
+static pascal void
+ctbcm_ctbcallback(hconn)
+ ConnHandle hconn;
+{
+ ctbcmobject *self;
+
+ /* XXXX Do I have to do the A5 mumbo-jumbo? */
+ ncallback++; /*DBG*/
+ self = (ctbcmobject *)CMGetUserData(hconn);
+ self->err = (int)((*hconn)->errCode);
+ Py_AddPendingCall(ctbcm_pycallback, (void *)self);
+}
+
+static ctbcmobject *
+newctbcmobject(arg)
+ object *arg;
+{
+ ctbcmobject *self;
+ self = NEWOBJ(ctbcmobject, &ctbcmtype);
+ if (self == NULL)
+ return NULL;
+ self->hdl = NULL;
+ INCREF(None);
+ self->callback = None;
+ self->has_callback = 0;
+ return self;
+}
+
+/* ctbcm methods */
+
+static void
+ctbcm_dealloc(self)
+ ctbcmobject *self;
+{
+ if ( self->hdl ) {
+ (void)CMClose(self->hdl, 0, (ConnectionCompletionUPP)0, 0, 1);
+ /*XXXX Is this safe? */
+ CMDispose(self->hdl);
+ self->hdl = NULL;
+ }
+ DEL(self);
+}
+
+static object *
+ctbcm_open(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ long timeout;
+ OSErr err;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "l", &timeout))
+ return NULL;
+ if ( (err=CMOpen(self->hdl, self->has_callback, cb_upp, timeout)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_listen(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ long timeout;
+ OSErr err;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "l", &timeout))
+ return NULL;
+ if ( (err=CMListen(self->hdl,self->has_callback, cb_upp, timeout)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_accept(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ int accept;
+ OSErr err;
+
+ if (!getargs(args, "i", &accept))
+ return NULL;
+ if ( (err=CMAccept(self->hdl, accept)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_close(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ int now;
+ long timeout;
+ OSErr err;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "(li)", &timeout, &now))
+ return NULL;
+ if ( (err=CMClose(self->hdl, self->has_callback, cb_upp, timeout, now)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_read(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ long timeout, len;
+ int chan;
+ CMFlags flags;
+ OSErr err;
+ object *rv;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "(lil)", &len, &chan, &timeout))
+ return NULL;
+ if ((rv=newsizedstringobject(NULL, len)) == NULL)
+ return NULL;
+ if ((err=CMRead(self->hdl, (Ptr)getstringvalue(rv), &len, (CMChannel)chan,
+ self->has_callback, cb_upp, timeout, &flags)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ resizestring(&rv, len);
+ return mkvalue("(Oi)", rv, (int)flags);
+}
+
+static object *
+ctbcm_write(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ long timeout, len;
+ int chan, ilen, flags;
+ OSErr err;
+ char *buf;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "(s#ili)", &buf, &ilen, &chan, &timeout, &flags))
+ return NULL;
+ len = ilen;
+ if ((err=CMWrite(self->hdl, (Ptr)buf, &len, (CMChannel)chan,
+ self->has_callback, cb_upp, timeout, (CMFlags)flags)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ return newintobject((int)len);
+}
+
+static object *
+ctbcm_status(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ CMBufferSizes sizes;
+ CMStatFlags flags;
+ OSErr err;
+ object *rv;
+
+ if (!getnoarg(args))
+ return NULL;
+ if ((err=CMStatus(self->hdl, sizes, &flags)) < 0)
+ return PyErr_Mac(ErrorObject, (int)err);
+ rv = mkvalue("(llllll)", sizes[0], sizes[1], sizes[2], sizes[3], sizes[4], sizes[5]);
+ if ( rv == NULL )
+ return NULL;
+ return mkvalue("(Ol)", rv, (long)flags);
+}
+
+static object *
+ctbcm_getconfig(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ char *rv;
+
+ if (!getnoarg(args))
+ return NULL;
+ if ((rv=(char *)CMGetConfig(self->hdl)) == NULL ) {
+ err_setstr(ErrorObject, "CMGetConfig failed");
+ return NULL;
+ }
+ return newstringobject(rv);
+}
+
+static object *
+ctbcm_setconfig(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ char *cfg;
+ OSErr err;
+
+ if (!getargs(args, "s", &cfg))
+ return NULL;
+ if ((err=CMSetConfig(self->hdl, (Ptr)cfg)) < 0)
+ return PyErr_Mac(ErrorObject, err);
+ return newintobject((int)err);
+}
+
+static object *
+ctbcm_choose(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ int rv;
+ Point pt;
+
+ if (!getnoarg(args))
+ return NULL;
+ pt.v = 40;
+ pt.h = 40;
+ rv=CMChoose(&self->hdl, pt, (ConnectionChooseIdleUPP)0);
+ return newintobject(rv);
+}
+
+static object *
+ctbcm_idle(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ if (!getnoarg(args))
+ return NULL;
+ CMIdle(self->hdl);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_abort(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ if (!getnoarg(args))
+ return NULL;
+ CMAbort(self->hdl);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_reset(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ if (!getnoarg(args))
+ return NULL;
+ CMReset(self->hdl);
+ INCREF(None);
+ return None;
+}
+
+static object *
+ctbcm_break(self, args)
+ ctbcmobject *self;
+ object *args;
+{
+ long duration;
+ ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
+
+ if (!getargs(args, "l", &duration))
+ return NULL;
+ CMBreak(self->hdl, duration,self->has_callback, cb_upp);
+ INCREF(None);
+ return None;
+}
+
+static struct methodlist ctbcm_methods[] = {
+ {"Open", (method)ctbcm_open},
+ {"Close", (method)ctbcm_close},
+ {"Read", (method)ctbcm_read},
+ {"Write", (method)ctbcm_write},
+ {"Status", (method)ctbcm_status},
+ {"GetConfig", (method)ctbcm_getconfig},
+ {"SetConfig", (method)ctbcm_setconfig},
+ {"Choose", (method)ctbcm_choose},
+ {"Idle", (method)ctbcm_idle},
+ {"Listen", (method)ctbcm_listen},
+ {"Accept", (method)ctbcm_accept},
+ {"Abort", (method)ctbcm_abort},
+ {"Reset", (method)ctbcm_reset},
+ {"Break", (method)ctbcm_break},
+ {NULL, NULL} /* sentinel */
+};
+
+static object *
+ctbcm_getattr(self, name)
+ ctbcmobject *self;
+ char *name;
+{
+ if ( strcmp(name, "callback") == 0 ) {
+ INCREF(self->callback);
+ return self->callback;
+ }
+ return findmethod(ctbcm_methods, (object *)self, name);
+}
+
+static int
+ctbcm_setattr(self, name, v)
+ ctbcmobject *self;
+ char *name;
+ object *v;
+{
+ if ( strcmp(name, "callback") != 0 ) {
+ err_setstr(AttributeError, "ctbcm objects have callback attr only");
+ return -1;
+ }
+ if ( v == NULL ) {
+ v = None;
+ }
+ INCREF(v); /* XXXX Must I do this? */
+ self->callback = v;
+ self->has_callback = (v != None);
+ return 0;
+}
+
+static typeobject ctbcmtype = {
+ OB_HEAD_INIT(&Typetype)
+ 0, /*ob_size*/
+ "ctbcm", /*tp_name*/
+ sizeof(ctbcmobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)ctbcm_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)ctbcm_getattr, /*tp_getattr*/
+ (setattrfunc)ctbcm_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+/* --------------------------------------------------------------------- */
+
+/* Function of no arguments returning new ctbcm object */
+
+static object *
+ctb_cmnew(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ int strlen;
+ object *sizes_obj;
+ char *c_str;
+ unsigned char p_str[255];
+ CMBufferSizes sizes;
+ short procid;
+ ConnHandle hdl;
+ ctbcmobject *rv;
+
+ if (!getargs(args, "(s#O)", &c_str, &strlen, &sizes_obj))
+ return NULL;
+ strncpy((char *)p_str+1, c_str, strlen);
+ p_str[0] = strlen;
+ if (!initialize_ctb())
+ return NULL;
+ if ( sizes_obj == None ) {
+ memset(sizes, '\0', sizeof sizes);
+ } else {
+ if ( !getargs(sizes_obj, "(llllll)", &sizes[0], &sizes[1], &sizes[2],
+ &sizes[3], &sizes[4], &sizes[5]))
+ return NULL;
+ }
+ if ( (procid=CMGetProcID(p_str)) < 0 )
+ return PyErr_Mac(ErrorObject, procid);
+ hdl = CMNew(procid, cmNoMenus|cmQuiet, sizes, 0, 0);
+ if ( hdl == NULL ) {
+ err_setstr(ErrorObject, "CMNew failed");
+ return NULL;
+ }
+ rv = newctbcmobject(args);
+ if ( rv == NULL )
+ return NULL; /* XXXX Should dispose of hdl */
+ rv->hdl = hdl;
+ CMSetUserData(hdl, (long)rv);
+ return (object *)rv;
+}
+
+static object *
+ctb_available(self, args)
+ object *self;
+ object *args;
+{
+ int ok;
+
+ if (!getnoarg(args))
+ return NULL;
+ ok = initialize_ctb();
+ err_clear();
+ return newintobject(ok);
+}
+
+/* List of functions defined in the module */
+
+static struct methodlist ctb_methods[] = {
+ {"CMNew", ctb_cmnew},
+ {"available", ctb_available},
+ {NULL, NULL} /* sentinel */
+};
+
+
+/* Initialization function for the module (*must* be called initctb) */
+
+void
+initctb()
+{
+ object *m, *d, *o;
+
+ /* Create the module and add the functions */
+ m = initmodule("ctb", ctb_methods);
+
+ /* Add some symbolic constants to the module */
+ d = getmoduledict(m);
+
+#define CMCONST(name, value) o = newintobject(value); dictinsert(d, name, o)
+
+ CMCONST("cmData", 1);
+ CMCONST("cmCntl", 2);
+ CMCONST("cmAttn", 3);
+
+ CMCONST("cmFlagsEOM", 1);
+
+ CMCONST("chooseDisaster", -2);
+ CMCONST("chooseFailed", -1);
+ CMCONST("chooseAborted", 0);
+ CMCONST("chooseOKMinor", 1);
+ CMCONST("chooseOKMajor", 2);
+ CMCONST("chooseCancel", 3);
+
+ CMCONST("cmStatusOpening", 1);
+ CMCONST("cmStatusOpen", 2);
+ CMCONST("cmStatusClosing", 4);
+ CMCONST("cmStatusDataAvail", 8);
+ CMCONST("cmStatusCntlAvail", 0x10);
+ CMCONST("cmStatusAttnAvail", 0x20);
+ CMCONST("cmStatusDRPend", 0x40);
+ CMCONST("cmStatusDWPend", 0x80);
+ CMCONST("cmStatusCWPend", 0x100);
+ CMCONST("cmStatusCWPend", 0x200);
+ CMCONST("cmStatusARPend", 0x400);
+ CMCONST("cmStatusAWPend", 0x800);
+ CMCONST("cmStatusBreakPending", 0x1000);
+ CMCONST("cmStatusListenPend", 0x2000);
+ CMCONST("cmStatusIncomingCallPresent", 0x4000);
+
+ ErrorObject = newstringobject("ctb.error");
+ dictinsert(d, "error", ErrorObject);
+
+ /* Check for errors */
+ if (err_occurred())
+ fatal("can't initialize module ctb");
+}