From a96a427e498e9b43357ff6fb4c7fe1d481752e24 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:29:37 -0700 Subject: [PATCH] moved the main message loop entirely into Python --- scripts/tmp_main.py | 26 +++++++++++++++++ src/Makefile | 3 +- src/ep_msg.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/ep_upiwin.c | 26 ++++++++++++++++- src/ep_upiwin.h | 7 +++++ src/main.c | 57 ++----------------------------------- src/msg.h | 1 + src/sysinput.c | 1 + src/sysinput.h | 1 + 9 files changed, 133 insertions(+), 57 deletions(-) create mode 100755 src/ep_msg.c diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 9152af5..0e656b9 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,6 +1,9 @@ # Initial test script import upiwin_tmp +def log_touch(event, x, y): + print("Touch {0} at ({1), {2})\n".format(event, x, y)) + upiwin_tmp.filled_rectangle(10, 10, 50, 50, upiwin_tmp.FBPRIMCLR_RED, False) upiwin_tmp.filled_rectangle(60, 10, 100, 50, upiwin_tmp.FBPRIMCLR_GREEN, False) upiwin_tmp.filled_rectangle(110, 10, 150, 50, upiwin_tmp.FBPRIMCLR_BLUE, False) @@ -14,3 +17,26 @@ upiwin_tmp.line(10, 150, 150, 110, upiwin_tmp.FBPRIMCLR_WHITE, False) upiwin_tmp.line(0, 180, 319, 180, upiwin_tmp.FBPRIMCLR_RED, False); upiwin_tmp.line(0, 196, 319, 196, upiwin_tmp.FBPRIMCLR_RED, False); upiwin_tmp.textout(10, 180, 'Amy was here!!!') + +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_HWBUTTONDOWN: + print("Button {0} was pressed.\n".format(msg['attrs'][0]) + elif msg['message'] == upiwin.WM_HWBUTTONUP: + print("Button {0} was released.\n".format(msg['attrs'][0]) + bn = msg['attrs'][0] + if bn == 1: + print("Backlight ON.\n") + upiwin.set_backlight(True) + elif bn == 2: + print("Backlight OFF.\n") + upiwin.set_backlight(True) + elif bn == 4: + print("Quitting the application.\n") + upiwin.post_quit_message(0) + elif msg['message'] == upiwin.WM_TOUCHDOWN: + log_touch('DOWN', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHMOVE: + log_touch('MOVE', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHUP: + log_touch('UP', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/Makefile b/src/Makefile index bcc135c..393fa29 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,8 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o rect.o fontengine.o fbprimitive.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_upiwin_tmp.o ep_util.o \ + fbinit.o rect.o fontengine.o fbprimitive.o \ log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ diff --git a/src/ep_msg.c b/src/ep_msg.c new file mode 100755 index 0000000..c00fe51 --- /dev/null +++ b/src/ep_msg.c @@ -0,0 +1,68 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "msg_queue.h" +#include "sysinput.h" +#include "ep_upiwin.h" +#include "ep_init.h" + +static HRESULT convert_msg(PyDictObject *target, PMSG source) +{ + PyObject *attr; + + 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) +{ + PyDictObject *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, NULL, WM_QUIT, exitcode); + Py_RETURN_NONE; +} diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 9c99dc3..4c51e34 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -1,9 +1,11 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" -#include "ep_init.h" +#include "msg.h" #include "gpio.h" +#include "ep_init.h" #include "ep_upiwin.h" +#include "ep_util.h" static PyMethodDef UPIWINMethods[] = { /* Backlight control functions */ @@ -15,6 +17,11 @@ static PyMethodDef UPIWINMethods[] = { "Returns the current intensity level of the backlight."}, {"set_backlight_level", Epython_set_backlight_level, METH_VARARGS, "Sets the current intensity level of the backlight. Returns a SCODE."}, + /* Message functions */ + {"get_message", Epython_get_message, METH_VARARGS, + "Retrieves a message from the message queue, blocking if necessary."}, + {"post_quit_message", Epython_post_quit_message, METH_VARARGS, + "Posts a WM_QUIT message to the message queue, with an exit code."}, {NULL, NULL, 0, NULL} }; @@ -30,6 +37,17 @@ static PyModuleDef DefUPIWIN = { NULL /* no free function */ }; +BEGIN_CONSTANT_TABLE(UPIWINConstants) + /* Message constants */ + CONSTANT_INT_MACRO(WM_NULL) + CONSTANT_INT_MACRO(WM_QUIT) + CONSTANT_INT_MACRO(WM_HWBUTTONDOWN) + CONSTANT_INT_MACRO(WM_HWBUTTONUP) + CONSTANT_INT_MACRO(WM_TOUCHDOWN) + CONSTANT_INT_MACRO(WM_TOUCHMOVE) + CONSTANT_INT_MACRO(WM_TOUCHUP) +END_CONSTANT_TABLE + PyObject *Epython_init_upiwin_module(void) { PyObject *module; @@ -38,6 +56,12 @@ PyObject *Epython_init_upiwin_module(void) module = PyModule_Create(&DefUPIWIN); if (!module) return NULL; + + if (FAILED(Epython_register_constants(module, UPIWINConstants))) + { + Py_DECREF(module); + return NULL; + } /* set up the module state */ pstate = (PUPIWIN_STATE)PyModule_GetState(module); diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index fa41b43..b6dbe14 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -11,9 +11,16 @@ typedef struct tagUPIWIN_STATE { } UPIWIN_STATE, *PUPIWIN_STATE; /* method definitions go here */ + +/* ep_backlight.c */ extern PyObject *Epython_get_backlight(PyObject *self, PyObject *args); extern PyObject *Epython_set_backlight(PyObject *self, PyObject *args); extern PyObject *Epython_get_backlight_level(PyObject *self, PyObject *args); extern PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args); +/* ep_msg.c */ +extern PyObject *Epython_get_message(PyObject *self, PyObject *args); +extern PyObject *Epython_post_quit_message(PyObject *self, PyObject *args); + + #endif /* __EP_UPIWIN_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 21e8622..29a4b87 100644 --- a/src/main.c +++ b/src/main.c @@ -12,11 +12,6 @@ #include "ep_init.h" #include "sysinput.h" -static void log_touch(const char *event, UINT_PTR x, UINT_PTR y) -{ - Log(LINFO, "Touch %s at (%u, %u)", event, x, y); -} - int main(int argc, char *argv[]) { HRESULT hr; @@ -47,54 +42,6 @@ int main(int argc, char *argv[]) if (FAILED(Epython_run())) return EXIT_FAILURE; - Log(LINFO, "Script returned and event loop ready."); - - while (running) - { - if (Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) - { - switch (msg.message) - { - case WM_HWBUTTONDOWN: - Log(LINFO, "Button %d was pressed.", (int)(msg.attrs[0])); - break; - - case WM_HWBUTTONUP: - Log(LINFO, "Button %d was released.", (int)(msg.attrs[0])); - if (msg.attrs[0] == 1) - { - Log(LINFO, "Backlight ON."); - Gpio_set_backlight(GSB_BACKLIGHT_MAX); - } - if (msg.attrs[0] == 2) - { - Log(LINFO, "Backlight OFF."); - Gpio_set_backlight(0); - } - if (msg.attrs[0] == 4) - { - Log(LINFO, "Quitting the message loop."); - running = 0; - } - break; - - case WM_TOUCHDOWN: - log_touch("DOWN", msg.attrs[0], msg.attrs[1]); - break; - - case WM_TOUCHMOVE: - log_touch("MOVE", msg.attrs[0], msg.attrs[1]); - break; - - case WM_TOUCHUP: - log_touch("UP", msg.attrs[0], msg.attrs[1]); - break; - - default: - break; - } - } - } - - return EXIT_SUCCESS; + Log(LINFO, "Script returned with exit code %d", Sys_Exit_Code); + return Sys_Exit_Code; } diff --git a/src/msg.h b/src/msg.h index 03f91c2..7778bde 100644 --- a/src/msg.h +++ b/src/msg.h @@ -13,6 +13,7 @@ typedef struct tagMSG { } MSG, *PMSG; #define WM_NULL 0x0000 +#define WM_QUIT 0x0001 #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 diff --git a/src/sysinput.c b/src/sysinput.c index 788547e..44335bd 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -16,6 +16,7 @@ #define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */ PMSG_QUEUE Sys_Queue = NULL; /* system message queue */ +INT32 Sys_Exit_Code = -1; /* system exit code, set on WM_QUIT */ static int ts_fd = 0; /* file descriptor for touchscreen */ static pthread_t ithread; /* input thread handle */ diff --git a/src/sysinput.h b/src/sysinput.h index e39c6e1..e191b66 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -5,6 +5,7 @@ #include "msg_queue.h" extern PMSG_QUEUE Sys_Queue; +extern INT32 Sys_Exit_Code; extern HRESULT Sys_enable_input(void); extern void Sys_wait_for_input(void);