moved the main message loop entirely into Python

This commit is contained in:
Amy Bowersox 2019-12-09 13:29:37 -07:00
parent f74e663658
commit a96a427e49
9 changed files with 133 additions and 57 deletions

View File

@ -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])

View File

@ -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 \

68
src/ep_msg.c Executable file
View File

@ -0,0 +1,68 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#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;
}

View File

@ -1,9 +1,11 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#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;
@ -39,6 +57,12 @@ PyObject *Epython_init_upiwin_module(void)
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);
pstate->backlight_on = TRUE;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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 */

View File

@ -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);