main.c (170 lines of code) (raw):

#include <stdarg.h> #include <Python.h> #include "structmember.h" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include <numpy/arrayobject.h> typedef enum { NOTSET = 0, DEBUG = 10, INFO = 20, WARNING = 30, ERROR = 40, CRITICAL = 50, } logging_level_e; static PyObject *logger; // First-time import the logging module, or throw an exception trying int logger_init(void) { PyObject *logging_module = NULL; // python: import logging if (NULL == logger) { logging_module = PyImport_ImportModuleNoBlock("logging"); if (NULL == logging_module) { PyErr_SetString(PyExc_ImportError, "Failed to import 'logging' module"); return -1; } } return 0; } void logger_str(logging_level_e level, const char *format, ...) { char buf[1024]; // Should be enough for anybody... va_list(args); va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); va_end(args); PyObject_CallMethod(logger, "log", "is", level, buf); } typedef struct { PyObject_HEAD /* Type-specific fields go here. */ } go_vncdriver_VNCSession_object; static PyObject *go_vncdriver_Error; /* Go functions exposed directly to Python */ // PyObject * GoVNCDriver_VNCSession_peek(PyObject *, PyObject *); // PyObject * GoVNCDriver_VNCSession_flip(PyObject *, PyObject *); PyObject * GoVNCDriver_VNCSession_step(PyObject *, PyObject *); PyObject * GoVNCDriver_VNCSession_close(PyObject *, PyObject *, PyObject *); PyObject * GoVNCDriver_VNCSession_render(PyObject *, PyObject *, PyObject *); PyObject * GoVNCDriver_VNCSession_connect(PyObject *, PyObject *, PyObject *); PyObject * GoVNCDriver_VNCSession_update(PyObject *, PyObject *, PyObject *); /* Go functions which are called only from C */ int GoVNCDriver_VNCSession_c_init(go_vncdriver_VNCSession_object *); void GoVNCDriver_VNCSession_c_dealloc(go_vncdriver_VNCSession_object *); /* Global functions */ PyObject * GoVNCDriver_setup(PyObject *, PyObject *); /* end go functions */ void PyErr_SetGoVNCDriverError(char* msg) { PyErr_SetString(go_vncdriver_Error, msg); free(msg); } PyObject *GoPyArray_SimpleNew(int nd, npy_intp* dims, int typenum) { return PyArray_SimpleNew(nd, dims, typenum); } PyObject *GoPyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void *data) { return PyArray_SimpleNewFromData(nd, dims, typenum, data); } /* VNCSession object */ static void go_vncdriver_VNCSession_dealloc(go_vncdriver_VNCSession_object* self) { GoVNCDriver_VNCSession_c_dealloc(self); #if PY_MAJOR_VERSION >= 3 Py_TYPE(self)->tp_free((PyObject*)self); #else self->ob_type->tp_free((PyObject*)self); #endif } static int go_vncdriver_VNCSession_init(go_vncdriver_VNCSession_object *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {NULL}; // No args! if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1; int res = GoVNCDriver_VNCSession_c_init(self); if (res == -1) { return -1; } return 0; } static PyMemberDef go_vncdriver_VNCSession_members[] = { {NULL} /* Sentinel */ }; static PyMethodDef go_vncdriver_VNCSession_methods[] = { {"connect", (PyCFunction)GoVNCDriver_VNCSession_connect, METH_VARARGS|METH_KEYWORDS, "Connect an index to a new remote"}, {"close", (PyCFunction)GoVNCDriver_VNCSession_close, METH_VARARGS|METH_KEYWORDS, "Closes the connection"}, // {"flip", (PyCFunction)GoVNCDriver_VNCSession_flip, METH_NOARGS, "Flips to the most recently updates screen"}, // {"peek", (PyCFunction)GoVNCDriver_VNCSession_peek, METH_NOARGS, "Peek at the last returned screen"}, {"render", (PyCFunction)GoVNCDriver_VNCSession_render, METH_VARARGS|METH_KEYWORDS, "Render the screen"}, {"step", (PyCFunction)GoVNCDriver_VNCSession_step, METH_O, "Perform actions and then flip"}, {"update", (PyCFunction) GoVNCDriver_VNCSession_update, METH_VARARGS|METH_KEYWORDS, "Update the connection options"}, {NULL} /* Sentinel */ }; // https://docs.python.org/2.7/extending/newtypes.html PyTypeObject go_vncdriver_VNCSession_type = { PyVarObject_HEAD_INIT(NULL, 0) "go_vncdriver.VNCSession", /*tp_name*/ sizeof(go_vncdriver_VNCSession_object), /*tp_basicsize*/ }; // Needed because CGo can't access static variables PyObject *get_go_vncdriver_VNCSession_type() { return (PyObject *) &go_vncdriver_VNCSession_type; } static PyMethodDef go_vncdriver_module_methods[] = { {NULL, NULL, 0, NULL} }; // https://docs.python.org/3/howto/cporting.html#module-initialization-and-state struct go_vncdriver_module_state { PyObject *error; }; #if PY_MAJOR_VERSION >= 3 #define GETSTATE(m) ((struct go_vncdriver_module_state*)PyModule_GetState(m)) #else #define GETSTATE(m) (&_state) static struct go_vncdriver_module_state _state; #endif static PyObject * error_out(PyObject *m) { struct go_vncdriver_module_state *st = GETSTATE(m); PyErr_SetString(go_vncdriver_Error, "something bad happened"); return NULL; } #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef go_vncdriver_module = { PyModuleDef_HEAD_INIT, "go_vncdriver", NULL, sizeof(struct go_vncdriver_module_state), go_vncdriver_module_methods, NULL, NULL, // No traverse for now NULL, // No clear for now NULL }; #define INITERROR return NULL PyMODINIT_FUNC PyInit_go_vncdriver(void) #else #define INITERROR return void initgo_vncdriver(void) #endif { #if PY_MAJOR_VERSION >= 3 PyObject *module = PyModule_Create(&go_vncdriver_module); #else PyObject *module = Py_InitModule("go_vncdriver", go_vncdriver_module_methods); #endif if (logger_init() < 0) INITERROR; if (module == NULL) INITERROR; struct go_vncdriver_module_state *st = GETSTATE(module); go_vncdriver_Error = PyErr_NewException("go_vncdriver.Error", NULL, NULL); if (go_vncdriver_Error == NULL) { Py_DECREF(module); INITERROR; } Py_INCREF(go_vncdriver_Error); PyModule_AddObject(module, "Error", go_vncdriver_Error); go_vncdriver_VNCSession_type.tp_dealloc = (destructor)go_vncdriver_VNCSession_dealloc; go_vncdriver_VNCSession_type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; go_vncdriver_VNCSession_type.tp_doc = "VNCSession objects"; go_vncdriver_VNCSession_type.tp_methods = go_vncdriver_VNCSession_methods; go_vncdriver_VNCSession_type.tp_members = go_vncdriver_VNCSession_members; go_vncdriver_VNCSession_type.tp_init = (initproc)go_vncdriver_VNCSession_init; go_vncdriver_VNCSession_type.tp_new = PyType_GenericNew; if (PyType_Ready(&go_vncdriver_VNCSession_type) < 0) { Py_DECREF(module); INITERROR; } Py_INCREF(&go_vncdriver_VNCSession_type); PyModule_AddObject(module, "VNCSession", (PyObject *) &go_vncdriver_VNCSession_type); // TODO: need to py3 this? import_array(); #if PY_MAJOR_VERSION >= 3 return module; #endif }