#define PY_SSIZE_T_CLEAN #include #include "scode.h" #include "log.h" #include "msg_queue.h" #include "sysinput.h" #include "ep_upiwin.h" #include "ep_init.h" static HRESULT convert_msg(PyObject *target, PMSG source) { PyObject *attr; ASSERT(PyDict_CheckExact(target)); PyDict_Clear(target); attr = PyLong_FromUnsignedLong(source->target); if (!attr) return E_FAIL; if (PyDict_SetItemString(target, "target", attr)) return E_FAIL; attr = PyLong_FromUnsignedLong(source->message); if (!attr) return E_FAIL; if (PyDict_SetItemString(target, "message", attr)) return E_FAIL; attr = Py_BuildValue("[k,k]", source->attrs[0], source->attrs[1]); if (!attr) return E_FAIL; if (PyDict_SetItemString(target, "attrs", attr)) return E_FAIL; attr = PyLong_FromUnsignedLongLong(source->timestamp); if (!attr) return E_FAIL; if (PyDict_SetItemString(target, "timestamp", attr)) return E_FAIL; return S_OK; } PyObject *Epython_get_message(PyObject *self, PyObject *args) { PyObject *out; MSG msg; if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out)) return NULL; /* release the GIL to allow us to block waiting for input if necessary */ Py_BEGIN_ALLOW_THREADS while (!Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) Sys_wait_for_input(); Py_END_ALLOW_THREADS if (FAILED(convert_msg(out, &msg))) { PyErr_SetString(PyExc_RuntimeError, "could not convert received message"); return NULL; } return PyBool_FromLong(msg.message != WM_QUIT); } PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) { INT32 exitcode; if (!PyArg_ParseTuple(args, "i", &exitcode)) return NULL; Sys_Exit_Code = exitcode; Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Py_RETURN_NONE; }