]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Interface to Mac Communications Toolbox (only Connection Manager for
authorJack Jansen <jack.jansen@cwi.nl>
Wed, 14 Dec 1994 13:31:11 +0000 (13:31 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Wed, 14 Dec 1994 13:31:11 +0000 (13:31 +0000)
now)

Mac/Modules/ctbmodule.c [new file with mode: 0644]

diff --git a/Mac/Modules/ctbmodule.c b/Mac/Modules/ctbmodule.c
new file mode 100644 (file)
index 0000000..52009a0
--- /dev/null
@@ -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");
+}