From 2da798238b1f902cc945d44fda822499ae2a926b Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 29 Nov 2019 01:52:56 -0700 Subject: [PATCH 001/162] first gpio and low-level logging --- .gitignore | 1 + src/gpio.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/log.c | 25 +++++++ src/log.h | 12 +++ 4 files changed, 251 insertions(+) create mode 100644 .gitignore create mode 100644 src/gpio.c create mode 100644 src/log.c create mode 100644 src/log.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/src/gpio.c b/src/gpio.c new file mode 100644 index 0000000..65df20f --- /dev/null +++ b/src/gpio.c @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include "log.h" + +#define GLINE_BUTTON1 17 +#define GLINE_BUTTON2 22 +#define GLINE_BUTTON3 23 +#define GLINE_BUTTON4 27 + +#define STATE_BUTTON1 (1 << 0) +#define STATE_BUTTON2 (1 << 1) +#define STATE_BUTTON3 (1 << 2) +#define STATE_BUTTON4 (1 << 3) + +#define INPUT 1 /* is really 0 for control register! */ +#define OUTPUT 0 /* is really 1 for control register! */ +#define ALT0 4 + +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +#define FSEL_OFFSET 0 +#define SET_OFFSET 7 +#define CLR_OFFSET 10 +#define PINLEVEL_OFFSET 13 +#define EVENT_DETECT_OFFSET 16 +#define RISING_ED_OFFSET 19 +#define FALLING_ED_OFFSET 22 +#define HIGH_DETECT_OFFSET 25 +#define LOW_DETECT_OFFSET 28 +#define PULLUPDN_OFFSET 37 +#define PULLUPDNCLK_OFFSET 38 + +#define PULLUPDN_OFFSET_2711_0 57 +#define PULLUPDN_OFFSET_2711_1 58 +#define PULLUPDN_OFFSET_2711_2 59 +#define PULLUPDN_OFFSET_2711_3 60 +#define PULLUPDN_2711_MAGIC 0x6770696F + +#define BLOCK_SIZE (4*1024) + +static int mem_fd = -1; +static volatile uint32_t *gpio_map = NULL; +static int is_2711 = 0; +static int last_state = 0; + +static void short_wait(void) +{ + int i; + + for (i=0; i<150; i++) + { /* wait 150 cycles */ + asm volatile("nop"); + } +} + +static int setup_the_memmap(void) +{ + if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0) + { + if ((gpio_map = (unit32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) + { + gpio_map = NULL; + close(mem_fd); + log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); + return -1; + } + } + + /* ignore the rest of the possibilities for now */ + return 0; +} + +static void set_pullupdn(int gpio, int pud) +{ + if (is_2711) + { /* method for RPi 4 */ + int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4); + int pullshift = (gpio & 0xF) << 1; + uint32_t pullbits; + unsigned pull = 0; + switch (pud) + { + case PUD_OFF: pull = 0; break; + case PUD_UP: pull = 1; break; + case PUD_DOWN: pull = 2; break; + default: pull = 0; /* keep as "off" */ + } + pullbits = *(gpio_map + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio_map + pullreg) = pullbits; + } + else + { /* method for older models */ + int clk_offset = PULLUPDNCLK_OFFSET + (gpio / 32); + int shift = gpio % 32; + + if (pud == PUD_DOWN) + { + *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_DOWN; + } + else if (pud == PUD_UP) + { + *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_UP; + } + else + { /* pud == PUD_OFF */ + *(gpio_map + PULLUPDN_OFFSET) &= ~3; + } + short_wait(); + *(gpio_map + clk_offset) = 1 << shift; + short_wait(); + *(gpio_map + PULLUPDN_OFFSET) &= ~3; + *(gpio_map + clk_offset) = 0; + } +} + +static void setup_gpio_line(int gpio, int direction, int pud) +{ + int offset = FSEL_OFFSET + (gpio / 10); + int shift = (gpio % 10) * 3; + + set_pullupdn(gpio, pud); + if (direction == OUTPUT) + *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (1 << shift); + else /* direction == INPUT */ + *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)); +} + +static int gpio_input(int gpio) +{ + int offset, value, mask; + + offset = PINLEVEL_OFFSET + (gpio / 32); + mask = (1 << gpio % 32); + value = *(gpio_map + offset) & mask; + return value; +} + +int Gpio_setup(void) +{ + if (setup_the_memmap() != 0) + return -1; + + is_2711 = (*(gpio_map + PULLUPDN_OFFSET_2711_3) != PULLUPDN_2711_MAGIC); + + setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_UP); + /* TODO: other setup */ + + last_state = 0; + return 0; +} + +void Gpio_cleanup(void) +{ + /* TODO: additional cleanup may be required */ + + setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_OFF); + + if (gpio_map) + { + munmap(gpio_map, BLOCK_SIZE); + gpio_map = NULL; + } + if (mem_fd >= 0) + { + close(mem_fd); + mem_fd = -1; + } +} + +int Gpio_poll_buttons(void) +{ + int new_state = 0; + int tmp, ndx, mask; + + if (gpio_input(GLINE_BUTTON1) == 0) + new_state |= STATE_BUTTON1; + if (gpio_input(GLINE_BUTTON2) == 0) + new_state |= STATE_BUTTON2; + if (gpio_input(GLINE_BUTTON3) == 0) + new_state |= STATE_BUTTON3; + if (gpio_input(GLINE_BUTTON4) == 0) + new_state |= STATE_BUTTON4; + + if (last_state != new_state) + { + tmp = last_state & ~new_state; + for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) + { + if (tmp & mask) + log(LDEBUG, "Button %d was released", ndx); + } + tmp = new_state & ~last_state; + for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) + { + if (tmp & mask) + log(LDEBUG, "Button %d was pressed", ndx); + } + last_state = new_state; + } + return new_state; +} diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..3bfe8dc --- /dev/null +++ b/src/log.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include "log.h" + +static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" }; + +void log(int level, const char *format, ...) +{ + va_list argp; + struct timeval tv; + struct tm tm; + char timestamp[32]; + char buf[1024]; + + va_start(argp, format); + vsnprintf(buf, 1024, format, argp); + va_end(argp); + + gettimeofday(&tv); + localtime_r(&(tv.tv_sec), &tm) + strftime(timestamp, 32, "%F %T", &tm); + printf("%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..c7eaaf2 --- /dev/null +++ b/src/log.h @@ -0,0 +1,12 @@ +#ifndef __LOG_H_INCLUDED +#define __LOG_H_INCLUDED + +#define LFATAL 0 +#define LERROR 1 +#define LWARN 2 +#define LINFO 3 +#define LDEBUG 4 + +extern void log(int level, const char *format, ...); + +#endif /* __LOG_H_INCLUDED */ From a2335a9d746133ff653bf7bfa3ffa69b06c72992 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 29 Nov 2019 02:05:30 -0700 Subject: [PATCH 002/162] ready to test GPIO code --- src/Makefile | 8 ++++++++ src/gpio.c | 1 + src/gpio.h | 8 ++++++++ src/main.c | 16 ++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 src/Makefile create mode 100644 src/gpio.h create mode 100644 src/main.c diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..ca829a2 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,8 @@ +OBJS=main.o log.o gpio.o +LIBS= + +upiwin: $(OBJS) + gcc -o upiwin $(OBJS) $(LIBS) + +.c.o: + gcc -c $(CFLAGS) $< diff --git a/src/gpio.c b/src/gpio.c index 65df20f..76f2cc1 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -3,6 +3,7 @@ #include #include #include "log.h" +#include "gpio.h" #define GLINE_BUTTON1 17 #define GLINE_BUTTON2 22 diff --git a/src/gpio.h b/src/gpio.h new file mode 100644 index 0000000..a1d48b7 --- /dev/null +++ b/src/gpio.h @@ -0,0 +1,8 @@ +#ifndef __GPIO_H_INCLUDED +#define __GPIO_H_INCLUDED + +extern int Gpio_setup(void); +extern void Gpio_cleanup(void); +extern int Gpio_poll_buttons(void); + +#endif /* __GPIO_H_INCLUDED */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..8275d52 --- /dev/null +++ b/src/main.c @@ -0,0 +1,16 @@ +#include +#include "gpio.h" +#include "log.h" + +int main(int argc, char *argv[]) +{ + if (Gpio_setup() != 0) + return EXIT_FAILURE; + atexit(Gpio_cleanup); + + log(LINFO, "System ready."); + + for (;;) { + Gpio_poll_buttons(); + } +} From 59e8fa59d590a79207df41a030c96b6bde20cba8 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 29 Nov 2019 02:18:02 -0700 Subject: [PATCH 003/162] compilation errors fixed --- .gitignore | 2 ++ src/gpio.c | 12 +++++++----- src/log.c | 6 +++--- src/log.h | 2 +- src/main.c | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index b25c15b..d5e8893 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *~ +*.o +src/upiwin diff --git a/src/gpio.c b/src/gpio.c index 76f2cc1..02f5e52 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,6 +1,8 @@ +#include #include #include #include +#include #include #include "log.h" #include "gpio.h" @@ -62,11 +64,11 @@ static int setup_the_memmap(void) { if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0) { - if ((gpio_map = (unit32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) + if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) { gpio_map = NULL; close(mem_fd); - log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); + Log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); return -1; } } @@ -170,7 +172,7 @@ void Gpio_cleanup(void) if (gpio_map) { - munmap(gpio_map, BLOCK_SIZE); + munmap((void *)gpio_map, BLOCK_SIZE); gpio_map = NULL; } if (mem_fd >= 0) @@ -200,13 +202,13 @@ int Gpio_poll_buttons(void) for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) { if (tmp & mask) - log(LDEBUG, "Button %d was released", ndx); + Log(LDEBUG, "Button %d was released", ndx); } tmp = new_state & ~last_state; for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) { if (tmp & mask) - log(LDEBUG, "Button %d was pressed", ndx); + Log(LDEBUG, "Button %d was pressed", ndx); } last_state = new_state; } diff --git a/src/log.c b/src/log.c index 3bfe8dc..de98b14 100644 --- a/src/log.c +++ b/src/log.c @@ -6,7 +6,7 @@ static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" }; -void log(int level, const char *format, ...) +void Log(int level, const char *format, ...) { va_list argp; struct timeval tv; @@ -18,8 +18,8 @@ void log(int level, const char *format, ...) vsnprintf(buf, 1024, format, argp); va_end(argp); - gettimeofday(&tv); - localtime_r(&(tv.tv_sec), &tm) + gettimeofday(&tv, NULL); + localtime_r(&(tv.tv_sec), &tm); strftime(timestamp, 32, "%F %T", &tm); printf("%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); } diff --git a/src/log.h b/src/log.h index c7eaaf2..8c040b8 100644 --- a/src/log.h +++ b/src/log.h @@ -7,6 +7,6 @@ #define LINFO 3 #define LDEBUG 4 -extern void log(int level, const char *format, ...); +extern void Log(int level, const char *format, ...); #endif /* __LOG_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 8275d52..0781b05 100644 --- a/src/main.c +++ b/src/main.c @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; atexit(Gpio_cleanup); - log(LINFO, "System ready."); + Log(LINFO, "System ready."); for (;;) { Gpio_poll_buttons(); From 87db1f4d0279c34f46055be358ed8ed64ceb9136 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:02:08 -0700 Subject: [PATCH 004/162] implemented the system input queue and system input thread --- src/Makefile | 2 +- src/gpio.c | 16 ++++++++- src/gpio.h | 1 + src/main.c | 30 ++++++++++++++-- src/msg.h | 20 +++++++++++ src/msg_queue.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ src/msg_queue.h | 27 +++++++++++++++ src/sysinput.c | 68 ++++++++++++++++++++++++++++++++++++ src/sysinput.h | 11 ++++++ src/time_func.c | 25 ++++++++++++++ src/time_func.h | 10 ++++++ src/wintype.h | 8 +++++ 12 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 src/msg.h create mode 100644 src/msg_queue.c create mode 100644 src/msg_queue.h create mode 100644 src/sysinput.c create mode 100644 src/sysinput.h create mode 100644 src/time_func.c create mode 100644 src/time_func.h create mode 100644 src/wintype.h diff --git a/src/Makefile b/src/Makefile index ca829a2..d77522a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o log.o gpio.o +OBJS=main.o sysinput.o log.o gpio.o msg_queue.o time_func.o LIBS= upiwin: $(OBJS) diff --git a/src/gpio.c b/src/gpio.c index 02f5e52..1e2f902 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -182,9 +182,23 @@ void Gpio_cleanup(void) } } +int Gpio_read_buttons(void) +{ + int rc = 0; + + if (gpio_input(GLINE_BUTTON1) == 0) + rc |= STATE_BUTTON1; + if (gpio_input(GLINE_BUTTON2) == 0) + rc |= STATE_BUTTON2; + if (gpio_input(GLINE_BUTTON3) == 0) + rc |= STATE_BUTTON3; + if (gpio_input(GLINE_BUTTON4) == 0) + rc |= STATE_BUTTON4; +} + int Gpio_poll_buttons(void) { - int new_state = 0; + int new_state = Gpio_read_buttons(); int tmp, ndx, mask; if (gpio_input(GLINE_BUTTON1) == 0) diff --git a/src/gpio.h b/src/gpio.h index a1d48b7..416d4bc 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -3,6 +3,7 @@ extern int Gpio_setup(void); extern void Gpio_cleanup(void); +extern int Gpio_read_buttons(void); extern int Gpio_poll_buttons(void); #endif /* __GPIO_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 0781b05..1490722 100644 --- a/src/main.c +++ b/src/main.c @@ -1,16 +1,42 @@ #include #include "gpio.h" #include "log.h" +#include "time_func.h" +#include "sysinput.h" int main(int argc, char *argv[]) { + MSG msg; + + TimeInit(); if (Gpio_setup() != 0) return EXIT_FAILURE; atexit(Gpio_cleanup); + if (SysEnableInput() != 0) + return EXIT_FAILURE; + atexit(SysDisableInput); Log(LINFO, "System ready."); - for (;;) { - Gpio_poll_buttons(); + for (;;) + { + if (MqPeek(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])); + break; + + default: + break; + } + } } + + return EXIT_SUCCESS; } diff --git a/src/msg.h b/src/msg.h new file mode 100644 index 0000000..c880d76 --- /dev/null +++ b/src/msg.h @@ -0,0 +1,20 @@ +#ifndef __MSG_H_INCLUDED +#define __MSG_H_INCLUDED + +#include "wintype.h" + +#define MSG_ATTRCOUNT 2 + +typedef tagMSG { + uintptr_t target; + unsigned message; + uintptr_t attrs[MSG_ATTRCOUNT]; + TIMESTAMP timestamp; +} MSG, *PMSG; + +#define WM_NULL 0x0000 + +#define WM_HWBUTTONDOWN 0x0020 +#define WM_HWBUTTONUP 0x0021 + +#endif /* __MSG_H_INCLUDED */ diff --git a/src/msg_queue.c b/src/msg_queue.c new file mode 100644 index 0000000..9d89ae3 --- /dev/null +++ b/src/msg_queue.c @@ -0,0 +1,92 @@ +#include +#include +#include "wintype.h" +#include "time_func.h" +#include "msg_queue.h" + +PMSG_QUEUE MqAlloc(int nentries) +{ + int sz = sizeof(MSG_QUEUE) + (nentries * sizeof(MSG)); + PMSG_QUEUE rc; + + rc = (PMSG_QUEUE)malloc(sz); + if (!rc) + return NULL; + memset(rc, 0 sz); + rc->startbound = &(rc->messagestore); + rc->endbound = rc->startbound + nentries; + rc->head = rc->tail = rc->startbound; + rc->nentries = nentries; + pthread_mutex_init(&(rc->mutex), NULL); + return rc; +} + +void MqDestroy(PMSG_QUEUE queue) +{ + pthread_mutex_destroy(&(queue->mutex)); + free(queue); +} + +static void post_internal(PMSG_QUEUE queue, PMSG msg) +{ + PMSG nexttail; + + pthread_mutex_lock(&(queue->mutex)); + nexttail = queue->tail + 1; + if (nexttail == queue->endbound) + nexttail = queue->startbound; + if (nexttail != queue->head) + { + memcpy(queue->tail, msg, sizeof(MSG)); + queue->tail = nexttail; + } + /* else drop the message silently */ + + pthread_mutex_unlock(&(queue->mutex)); +} + +void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) +{ + MSG tmpmsg; + + memset(&tmpmsg, 0, sizeof(MSG)); + tmpmsg.target = target; + tmpmsg.message = message; + if (nattrs > MSG_ATTRCOUNT) + nattrs = MSG_ATTRCOUNT; + if (nattrs > 0) + memcpy(&(tmpmsg.attrs), attrs, sizeof(uintptr_t) * nattrs); + tmpmsg.timestamp = TimeSinceStart(); + post_internal(queue, &tmpmsg); +} + +void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) +{ + MSG tmpmsg; + + memset(&tmpmsg, 0, sizeof(MSG)); + tmpmsg.target = target; + tmpmsg.message = message; + tmpmsg.attrs[0] = attr1; + tmpmsg.timestamp = TimeSinceStart(); + post_internal(queue, &tmpmsg); +} + +int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags) +{ + int rc = 0; + PMSG nexthead; + + pthread_mutex_lock(&(queue->mutex)); + if (queue->head != queue->tail) + { + nexthead = queue->head + 1; + if (nexthead == queue->endbound) + nexthead = queue->startbound; + memcpy(msg, queue->head, sizeof(MSG)); + if (flags & PEEK_REMOVE) + queue->head = nexthead; + } + pthread_mutex_unlock(&(queue->mutex)); + return rc; +} diff --git a/src/msg_queue.h b/src/msg_queue.h new file mode 100644 index 0000000..4b0ddc5 --- /dev/null +++ b/src/msg_queue.h @@ -0,0 +1,27 @@ +#ifndef __MSG_QUEUE_H_INCLUDED +#define __MSG_QUEUE_H_INCLUDED + +#include "wintype.h" +#include "msg.h" + +typedef struct tagMSG_QUEUE { + struct tagMSG_QUEUE *next; + PMSG startbound; + PMSG endbound; + PMSG head; + PMSG tail; + int nentries; + pthread_mutex_t mutex; + MSG messagestore[0]; +} MSG_QUEUE, *PMSG_QUEUE; + +#define PEEK_REMOVE 0x0001 +#define PEEK_NOREMOVE 0x0000 + +extern PMSG_QUEUE MqAlloc(int nentries); +extern void MqDestroy(PMSG_QUEUE queue); +extern void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); +extern void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); +extern int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags); + +#endif /* __MSG_QUEUE_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c new file mode 100644 index 0000000..27fda6c --- /dev/null +++ b/src/sysinput.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include "log.h" +#include "msg_queue.h" +#include "gpio.h" + +PMSG_QUEUE Sys_Queue = NULL; + +static pthread_t ithread; +static volatile sig_atomic_t running = 1; +static int last_bstate = 0; + +static void *input_thread(void *arg) +{ + int st, tmp, mask; + uintptr_t attr; + + while (running) + { + /* poll hardware buttons */ + st = Gpio_read_buttons(); + if (st != last_bstate) + { + tmp = last_state & ~st; + for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) + { + if (tmp & mask) + MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + } + tmp = st & ~last_state; + for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) + { + if (tmp & mask) + MqPost1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + } + last_bstate = st; + } + + /* additional poll activity here */ + } + return NULL; +} + +int SysEnableInput(void) +{ + int rc; + + Sys_Queue = MqAlloc(64); + if (!Sys_Queue) + { + Log(LFATAL, "Unable to allocate system message queue."); + return 1; + } + running = 1; + rc = pthread_create(&ithread, NULL, input_thread, NULL); + if (rc != 0) + Log(LFATAL, "Unable to start system input thread (%d).", rc); + return rc; +} + +void SysDisableInput(void) +{ + running = 0; + pthread_join(ithread, NULL); + MqDestroy(Sys_Queue); + Sys_Queue = NULL; +} diff --git a/src/sysinput.h b/src/sysinput.h new file mode 100644 index 0000000..29b5a18 --- /dev/null +++ b/src/sysinput.h @@ -0,0 +1,11 @@ +#ifndef __SYSINPUT_H_INCLUDED +#define __SYSINPUT_H_INCLUDED + +#include "msg_queue.h" + +extern PMSG_QUEUE Sys_Queue; + +extern int SysEnableInput(void); +extern void SysDisableInput(void); + +#endif /* __SYSINPUT_H_INCLUDED */ diff --git a/src/time_func.c b/src/time_func.c new file mode 100644 index 0000000..1ca8487 --- /dev/null +++ b/src/time_func.c @@ -0,0 +1,25 @@ +#include +#include +#include "time_func.h" + +static TIMESTAMP start_timestamp = 0; + +TIMESTAMP TimeSinceEpoch(void) +{ + TIMESTAMP rc; + struct timeval tv; + + gettimeofday(&tv, NULL); + rc = (tv.tv_sec * (TIMESTAMP)1000) + (tv.tv_usec / (TIMESTAMP)1000); + return rc; +} + +TIMESTAMP TimeSinceStart(void) +{ + return TimeSinceEpoch() - start_timestamp; +} + +void TimeInit(void) +{ + start_timestamp = TimeSinceEpoch(); +} diff --git a/src/time_func.h b/src/time_func.h new file mode 100644 index 0000000..80e0b14 --- /dev/null +++ b/src/time_func.h @@ -0,0 +1,10 @@ +#ifndef __TIMEFUNC_H_INCLUDED +#define __TIMEFUNC_H_INCLUDED + +#include "wintype.h" + +extern TIMESTAMP TimeSinceEpoch(void); +extern TIMESTAMP TimeSinceStart(void); +extern void TimeInit(void); + +#endif /* __TIMEFUNC_H_INCLUDED */ diff --git a/src/wintype.h b/src/wintype.h new file mode 100644 index 0000000..08d921b --- /dev/null +++ b/src/wintype.h @@ -0,0 +1,8 @@ +#ifndef __WINTYPE_H_INCLUDED +#define __WINTYPE_H_INCLUDED + +#include + +typedef uint64_t TIMESTAMP; + +#endif /* __WINTYPE_H_INCLUDED */ From 340e08232e8939fef7d4b0738175a9adc896ed5f Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:07:37 -0700 Subject: [PATCH 005/162] fixed compilation errors --- src/Makefile | 2 +- src/msg.h | 2 +- src/msg_queue.c | 5 +++-- src/sysinput.c | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Makefile b/src/Makefile index d77522a..de01b8a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ OBJS=main.o sysinput.o log.o gpio.o msg_queue.o time_func.o -LIBS= +LIBS=-lpthread upiwin: $(OBJS) gcc -o upiwin $(OBJS) $(LIBS) diff --git a/src/msg.h b/src/msg.h index c880d76..a09d269 100644 --- a/src/msg.h +++ b/src/msg.h @@ -5,7 +5,7 @@ #define MSG_ATTRCOUNT 2 -typedef tagMSG { +typedef struct tagMSG { uintptr_t target; unsigned message; uintptr_t attrs[MSG_ATTRCOUNT]; diff --git a/src/msg_queue.c b/src/msg_queue.c index 9d89ae3..ff94048 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -1,4 +1,5 @@ #include +#include #include #include "wintype.h" #include "time_func.h" @@ -12,8 +13,8 @@ PMSG_QUEUE MqAlloc(int nentries) rc = (PMSG_QUEUE)malloc(sz); if (!rc) return NULL; - memset(rc, 0 sz); - rc->startbound = &(rc->messagestore); + memset(rc, 0, sz); + rc->startbound = &(rc->messagestore[0]); rc->endbound = rc->startbound + nentries; rc->head = rc->tail = rc->startbound; rc->nentries = nentries; diff --git a/src/sysinput.c b/src/sysinput.c index 27fda6c..2834660 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -22,13 +22,13 @@ static void *input_thread(void *arg) st = Gpio_read_buttons(); if (st != last_bstate) { - tmp = last_state & ~st; + tmp = last_bstate & ~st; for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { if (tmp & mask) MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); } - tmp = st & ~last_state; + tmp = st & ~last_bstate; for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { if (tmp & mask) From 0a20f315d57d546e3b8c210de38743d83694f3de Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:11:46 -0700 Subject: [PATCH 006/162] add some extra logging --- src/sysinput.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sysinput.c b/src/sysinput.c index 2834660..8f45b37 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -26,13 +26,19 @@ static void *input_thread(void *arg) for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { if (tmp & mask) + { + Log(LDEBUG, "posting WM_HWBUTTONUP(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + } } tmp = st & ~last_bstate; for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { if (tmp & mask) + { + Log(LDEBUG, "posting WM_HWBUTTONDOWN(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + } } last_bstate = st; } From 969fefd0aa09687c72995e056af81e57630d88f5 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:18:59 -0700 Subject: [PATCH 007/162] simplified the input thread's internal loop --- src/sysinput.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index 8f45b37..c45d6f7 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -13,7 +13,7 @@ static int last_bstate = 0; static void *input_thread(void *arg) { - int st, tmp, mask; + int st, down, up, mask; uintptr_t attr; while (running) @@ -22,19 +22,16 @@ static void *input_thread(void *arg) st = Gpio_read_buttons(); if (st != last_bstate) { - tmp = last_bstate & ~st; + up = last_bstate & ~st; + down = st & ~last_bstate; for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { - if (tmp & mask) + if (up & mask) { Log(LDEBUG, "posting WM_HWBUTTONUP(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); } - } - tmp = st & ~last_bstate; - for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) - { - if (tmp & mask) + else if (down & mask) { Log(LDEBUG, "posting WM_HWBUTTONDOWN(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); From bb98f165cad1caa54c4e613124f0e0d0b50fc097 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:21:26 -0700 Subject: [PATCH 008/162] bugfix in read_buttons --- src/gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gpio.c b/src/gpio.c index 1e2f902..873fd6c 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -194,6 +194,7 @@ int Gpio_read_buttons(void) rc |= STATE_BUTTON3; if (gpio_input(GLINE_BUTTON4) == 0) rc |= STATE_BUTTON4; + return rc; } int Gpio_poll_buttons(void) From 97ee88caf3acfab8e0f9e3927c56b49e629ecf55 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:24:15 -0700 Subject: [PATCH 009/162] cleaning up access to the system queue --- src/sysinput.c | 2 +- src/sysinput.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index c45d6f7..503c2f3 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -5,7 +5,7 @@ #include "msg_queue.h" #include "gpio.h" -PMSG_QUEUE Sys_Queue = NULL; +volatile PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; diff --git a/src/sysinput.h b/src/sysinput.h index 29b5a18..bc08960 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -3,7 +3,7 @@ #include "msg_queue.h" -extern PMSG_QUEUE Sys_Queue; +extern volatile PMSG_QUEUE Sys_Queue; extern int SysEnableInput(void); extern void SysDisableInput(void); From 1bf4e3397ef8420ec57ebbc616a36c7792f82a88 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:28:10 -0700 Subject: [PATCH 010/162] another approach --- src/sysinput.c | 2 +- src/sysinput.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index 503c2f3..055a86f 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -5,7 +5,7 @@ #include "msg_queue.h" #include "gpio.h" -volatile PMSG_QUEUE Sys_Queue = NULL; +MSG_QUEUE volatile *Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; diff --git a/src/sysinput.h b/src/sysinput.h index bc08960..7142f4b 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -3,7 +3,7 @@ #include "msg_queue.h" -extern volatile PMSG_QUEUE Sys_Queue; +extern MSG_QUEUE volatile *Sys_Queue; extern int SysEnableInput(void); extern void SysDisableInput(void); From 9588d1e94b5e96ffe00c163118532de156cec7aa Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:31:13 -0700 Subject: [PATCH 011/162] now reflect volatile into the msg_queue definitions --- src/msg_queue.c | 8 ++++---- src/msg_queue.h | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/msg_queue.c b/src/msg_queue.c index ff94048..6d46c84 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -28,7 +28,7 @@ void MqDestroy(PMSG_QUEUE queue) free(queue); } -static void post_internal(PMSG_QUEUE queue, PMSG msg) +static void post_internal(MSG_QUEUE volatile *queue, PMSG msg) { PMSG nexttail; @@ -46,7 +46,7 @@ static void post_internal(PMSG_QUEUE queue, PMSG msg) pthread_mutex_unlock(&(queue->mutex)); } -void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) +void MqPost(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) { MSG tmpmsg; @@ -61,7 +61,7 @@ void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_ post_internal(queue, &tmpmsg); } -void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) +void MqPost1(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, uintptr_t attr1) { MSG tmpmsg; @@ -73,7 +73,7 @@ void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t att post_internal(queue, &tmpmsg); } -int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags) +int MqPeek(MSG_QUEUE volatile *queue, PMSG msg, unsigned flags) { int rc = 0; PMSG nexthead; diff --git a/src/msg_queue.h b/src/msg_queue.h index 4b0ddc5..fd44f0f 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -20,8 +20,9 @@ typedef struct tagMSG_QUEUE { extern PMSG_QUEUE MqAlloc(int nentries); extern void MqDestroy(PMSG_QUEUE queue); -extern void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); -extern void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); -extern int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags); +extern void MqPost(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, const uintptr_t *attrs, + int nattrs); +extern void MqPost1(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, uintptr_t attr1); +extern int MqPeek(MSG_QUEUE volatile *queue, PMSG msg, unsigned flags); #endif /* __MSG_QUEUE_H_INCLUDED */ From de84145e55b68a5a01850509373a0cb612f96091 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:36:07 -0700 Subject: [PATCH 012/162] found the bug, now I think I've got it right --- src/msg_queue.c | 9 +++++---- src/msg_queue.h | 7 +++---- src/sysinput.c | 2 +- src/sysinput.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/msg_queue.c b/src/msg_queue.c index 6d46c84..caa5afe 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -28,7 +28,7 @@ void MqDestroy(PMSG_QUEUE queue) free(queue); } -static void post_internal(MSG_QUEUE volatile *queue, PMSG msg) +static void post_internal(PMSG_QUEUE queue, PMSG msg) { PMSG nexttail; @@ -46,7 +46,7 @@ static void post_internal(MSG_QUEUE volatile *queue, PMSG msg) pthread_mutex_unlock(&(queue->mutex)); } -void MqPost(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) +void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) { MSG tmpmsg; @@ -61,7 +61,7 @@ void MqPost(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, const post_internal(queue, &tmpmsg); } -void MqPost1(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, uintptr_t attr1) +void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) { MSG tmpmsg; @@ -73,7 +73,7 @@ void MqPost1(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, uint post_internal(queue, &tmpmsg); } -int MqPeek(MSG_QUEUE volatile *queue, PMSG msg, unsigned flags) +int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags) { int rc = 0; PMSG nexthead; @@ -87,6 +87,7 @@ int MqPeek(MSG_QUEUE volatile *queue, PMSG msg, unsigned flags) memcpy(msg, queue->head, sizeof(MSG)); if (flags & PEEK_REMOVE) queue->head = nexthead; + rc = 1; } pthread_mutex_unlock(&(queue->mutex)); return rc; diff --git a/src/msg_queue.h b/src/msg_queue.h index fd44f0f..4b0ddc5 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -20,9 +20,8 @@ typedef struct tagMSG_QUEUE { extern PMSG_QUEUE MqAlloc(int nentries); extern void MqDestroy(PMSG_QUEUE queue); -extern void MqPost(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, const uintptr_t *attrs, - int nattrs); -extern void MqPost1(MSG_QUEUE volatile *queue, uintptr_t target, unsigned message, uintptr_t attr1); -extern int MqPeek(MSG_QUEUE volatile *queue, PMSG msg, unsigned flags); +extern void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); +extern void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); +extern int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags); #endif /* __MSG_QUEUE_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index 055a86f..c45d6f7 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -5,7 +5,7 @@ #include "msg_queue.h" #include "gpio.h" -MSG_QUEUE volatile *Sys_Queue = NULL; +PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; diff --git a/src/sysinput.h b/src/sysinput.h index 7142f4b..29b5a18 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -3,7 +3,7 @@ #include "msg_queue.h" -extern MSG_QUEUE volatile *Sys_Queue; +extern PMSG_QUEUE Sys_Queue; extern int SysEnableInput(void); extern void SysDisableInput(void); From 69c5261ec4a1040ac21c720fb6891675d6deaca6 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 01:40:28 -0700 Subject: [PATCH 013/162] removed some extra code and made Button 4 be a "quit" function --- src/gpio.c | 33 --------------------------------- src/gpio.h | 1 - src/main.c | 8 +++++++- src/sysinput.c | 6 ------ 4 files changed, 7 insertions(+), 41 deletions(-) diff --git a/src/gpio.c b/src/gpio.c index 873fd6c..a3496fe 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -196,36 +196,3 @@ int Gpio_read_buttons(void) rc |= STATE_BUTTON4; return rc; } - -int Gpio_poll_buttons(void) -{ - int new_state = Gpio_read_buttons(); - int tmp, ndx, mask; - - if (gpio_input(GLINE_BUTTON1) == 0) - new_state |= STATE_BUTTON1; - if (gpio_input(GLINE_BUTTON2) == 0) - new_state |= STATE_BUTTON2; - if (gpio_input(GLINE_BUTTON3) == 0) - new_state |= STATE_BUTTON3; - if (gpio_input(GLINE_BUTTON4) == 0) - new_state |= STATE_BUTTON4; - - if (last_state != new_state) - { - tmp = last_state & ~new_state; - for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) - { - if (tmp & mask) - Log(LDEBUG, "Button %d was released", ndx); - } - tmp = new_state & ~last_state; - for (ndx = 1, mask = 1; ndx <= 4; ndx++, mask <<= 1) - { - if (tmp & mask) - Log(LDEBUG, "Button %d was pressed", ndx); - } - last_state = new_state; - } - return new_state; -} diff --git a/src/gpio.h b/src/gpio.h index 416d4bc..b70caf0 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -4,6 +4,5 @@ extern int Gpio_setup(void); extern void Gpio_cleanup(void); extern int Gpio_read_buttons(void); -extern int Gpio_poll_buttons(void); #endif /* __GPIO_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 1490722..d474fc0 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ int main(int argc, char *argv[]) { + int running = 1; MSG msg; TimeInit(); @@ -18,7 +19,7 @@ int main(int argc, char *argv[]) Log(LINFO, "System ready."); - for (;;) + while (running) { if (MqPeek(Sys_Queue, &msg, PEEK_REMOVE)) { @@ -30,6 +31,11 @@ int main(int argc, char *argv[]) case WM_HWBUTTONUP: Log(LINFO, "Button %d was released.", (int)(msg.attrs[0])); + if (msg.attrs[0] == 4) + { + Log(LINFO, "Quitting the message loop."); + running = 0; + } break; default: diff --git a/src/sysinput.c b/src/sysinput.c index c45d6f7..e14291f 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -27,15 +27,9 @@ static void *input_thread(void *arg) for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) { if (up & mask) - { - Log(LDEBUG, "posting WM_HWBUTTONUP(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); - } else if (down & mask) - { - Log(LDEBUG, "posting WM_HWBUTTONDOWN(%d)", (int)attr); MqPost1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); - } } last_bstate = st; } From 3a5befa36f57d5f02f33e178d0fc6116983ba47b Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 14:18:31 -0700 Subject: [PATCH 014/162] use the BCM2835 library to abstract out the GPIO details --- src/Makefile | 2 +- src/gpio.c | 194 +++++++++------------------------------------ src/gpio_old.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+), 159 deletions(-) create mode 100644 src/gpio_old.c diff --git a/src/Makefile b/src/Makefile index de01b8a..08f0b3a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ OBJS=main.o sysinput.o log.o gpio.o msg_queue.o time_func.o -LIBS=-lpthread +LIBS=-lbcm2835 -lpthread upiwin: $(OBJS) gcc -o upiwin $(OBJS) $(LIBS) diff --git a/src/gpio.c b/src/gpio.c index a3496fe..b3143b7 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -4,195 +4,73 @@ #include #include #include +#include #include "log.h" #include "gpio.h" -#define GLINE_BUTTON1 17 -#define GLINE_BUTTON2 22 -#define GLINE_BUTTON3 23 -#define GLINE_BUTTON4 27 +#define GLINE_BUTTON1 17 +#define GLINE_BUTTON2 22 +#define GLINE_BUTTON3 23 +#define GLINE_BUTTON4 27 +#define GLINE_BACKLIGHT 18 #define STATE_BUTTON1 (1 << 0) #define STATE_BUTTON2 (1 << 1) #define STATE_BUTTON3 (1 << 2) #define STATE_BUTTON4 (1 << 3) -#define INPUT 1 /* is really 0 for control register! */ -#define OUTPUT 0 /* is really 1 for control register! */ -#define ALT0 4 - -#define PUD_OFF 0 -#define PUD_DOWN 1 -#define PUD_UP 2 - -#define FSEL_OFFSET 0 -#define SET_OFFSET 7 -#define CLR_OFFSET 10 -#define PINLEVEL_OFFSET 13 -#define EVENT_DETECT_OFFSET 16 -#define RISING_ED_OFFSET 19 -#define FALLING_ED_OFFSET 22 -#define HIGH_DETECT_OFFSET 25 -#define LOW_DETECT_OFFSET 28 -#define PULLUPDN_OFFSET 37 -#define PULLUPDNCLK_OFFSET 38 - -#define PULLUPDN_OFFSET_2711_0 57 -#define PULLUPDN_OFFSET_2711_1 58 -#define PULLUPDN_OFFSET_2711_2 59 -#define PULLUPDN_OFFSET_2711_3 60 -#define PULLUPDN_2711_MAGIC 0x6770696F - -#define BLOCK_SIZE (4*1024) - -static int mem_fd = -1; -static volatile uint32_t *gpio_map = NULL; -static int is_2711 = 0; -static int last_state = 0; - -static void short_wait(void) -{ - int i; - - for (i=0; i<150; i++) - { /* wait 150 cycles */ - asm volatile("nop"); - } -} - -static int setup_the_memmap(void) -{ - if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0) - { - if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) - { - gpio_map = NULL; - close(mem_fd); - Log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); - return -1; - } - } - - /* ignore the rest of the possibilities for now */ - return 0; -} - -static void set_pullupdn(int gpio, int pud) -{ - if (is_2711) - { /* method for RPi 4 */ - int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4); - int pullshift = (gpio & 0xF) << 1; - uint32_t pullbits; - unsigned pull = 0; - switch (pud) - { - case PUD_OFF: pull = 0; break; - case PUD_UP: pull = 1; break; - case PUD_DOWN: pull = 2; break; - default: pull = 0; /* keep as "off" */ - } - pullbits = *(gpio_map + pullreg); - pullbits &= ~(3 << pullshift); - pullbits |= (pull << pullshift); - *(gpio_map + pullreg) = pullbits; - } - else - { /* method for older models */ - int clk_offset = PULLUPDNCLK_OFFSET + (gpio / 32); - int shift = gpio % 32; - - if (pud == PUD_DOWN) - { - *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_DOWN; - } - else if (pud == PUD_UP) - { - *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_UP; - } - else - { /* pud == PUD_OFF */ - *(gpio_map + PULLUPDN_OFFSET) &= ~3; - } - short_wait(); - *(gpio_map + clk_offset) = 1 << shift; - short_wait(); - *(gpio_map + PULLUPDN_OFFSET) &= ~3; - *(gpio_map + clk_offset) = 0; - } -} - -static void setup_gpio_line(int gpio, int direction, int pud) -{ - int offset = FSEL_OFFSET + (gpio / 10); - int shift = (gpio % 10) * 3; - - set_pullupdn(gpio, pud); - if (direction == OUTPUT) - *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (1 << shift); - else /* direction == INPUT */ - *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)); -} - -static int gpio_input(int gpio) -{ - int offset, value, mask; - - offset = PINLEVEL_OFFSET + (gpio / 32); - mask = (1 << gpio % 32); - value = *(gpio_map + offset) & mask; - return value; -} - int Gpio_setup(void) { - if (setup_the_memmap() != 0) + if (!bcm2835_init()) + { + Log(LFATAL, "Error initializing BCM2835 library"); return -1; + } - is_2711 = (*(gpio_map + PULLUPDN_OFFSET_2711_3) != PULLUPDN_2711_MAGIC); + /* configure the buttons */ + bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_UP); + bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_UP); + bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_UP); + bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_UP); + bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT); - setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_UP); /* TODO: other setup */ - last_state = 0; return 0; } void Gpio_cleanup(void) { /* TODO: additional cleanup may be required */ - - setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_OFF); - - if (gpio_map) - { - munmap((void *)gpio_map, BLOCK_SIZE); - gpio_map = NULL; - } - if (mem_fd >= 0) - { - close(mem_fd); - mem_fd = -1; - } + + /* close down the button lines */ + bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT); + + if (!bcm2835_close()) + Log(LWARN, "Closing BCM2835 library failed"); } int Gpio_read_buttons(void) { int rc = 0; - if (gpio_input(GLINE_BUTTON1) == 0) + if (bcm2835_gpio_lev(GLINE_BUTTON1) == LOW) rc |= STATE_BUTTON1; - if (gpio_input(GLINE_BUTTON2) == 0) + if (bcm2835_gpio_lev(GLINE_BUTTON2) == LOW) rc |= STATE_BUTTON2; - if (gpio_input(GLINE_BUTTON3) == 0) + if (bcm2835_gpio_lev(GLINE_BUTTON3) == LOW) rc |= STATE_BUTTON3; - if (gpio_input(GLINE_BUTTON4) == 0) + if (bcm2835_gpio_lev(GLINE_BUTTON4) == LOW) rc |= STATE_BUTTON4; return rc; } diff --git a/src/gpio_old.c b/src/gpio_old.c new file mode 100644 index 0000000..eb332eb --- /dev/null +++ b/src/gpio_old.c @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include +#include "log.h" +#include "gpio.h" + +#define GLINE_BUTTON1 17 +#define GLINE_BUTTON2 22 +#define GLINE_BUTTON3 23 +#define GLINE_BUTTON4 27 +#define GLINE_BACKLIGHT 18 + +#define STATE_BUTTON1 (1 << 0) +#define STATE_BUTTON2 (1 << 1) +#define STATE_BUTTON3 (1 << 2) +#define STATE_BUTTON4 (1 << 3) + +#define INPUT 1 /* is really 0 for control register! */ +#define OUTPUT 0 /* is really 1 for control register! */ +#define ALT0 4 + +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +#define FSEL_OFFSET 0 +#define SET_OFFSET 7 +#define CLR_OFFSET 10 +#define PINLEVEL_OFFSET 13 +#define EVENT_DETECT_OFFSET 16 +#define RISING_ED_OFFSET 19 +#define FALLING_ED_OFFSET 22 +#define HIGH_DETECT_OFFSET 25 +#define LOW_DETECT_OFFSET 28 +#define PULLUPDN_OFFSET 37 +#define PULLUPDNCLK_OFFSET 38 + +#define PULLUPDN_OFFSET_2711_0 57 +#define PULLUPDN_OFFSET_2711_1 58 +#define PULLUPDN_OFFSET_2711_2 59 +#define PULLUPDN_OFFSET_2711_3 60 +#define PULLUPDN_2711_MAGIC 0x6770696F + +#define BLOCK_SIZE (4*1024) + +static int mem_fd = -1; +static volatile uint32_t *gpio_map = NULL; +static int is_2711 = 0; +static int last_state = 0; + +static void short_wait(void) +{ + int i; + + for (i=0; i<150; i++) + { /* wait 150 cycles */ + asm volatile("nop"); + } +} + +static int setup_the_memmap(void) +{ + if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0) + { + if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) + { + gpio_map = NULL; + close(mem_fd); + Log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); + return -1; + } + } + + /* ignore the rest of the possibilities for now */ + return 0; +} + +static void set_pullupdn(int gpio, int pud) +{ + if (is_2711) + { /* method for RPi 4 */ + int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4); + int pullshift = (gpio & 0xF) << 1; + uint32_t pullbits; + unsigned pull = 0; + switch (pud) + { + case PUD_OFF: pull = 0; break; + case PUD_UP: pull = 1; break; + case PUD_DOWN: pull = 2; break; + default: pull = 0; /* keep as "off" */ + } + pullbits = *(gpio_map + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio_map + pullreg) = pullbits; + } + else + { /* method for older models */ + int clk_offset = PULLUPDNCLK_OFFSET + (gpio / 32); + int shift = gpio % 32; + + if (pud == PUD_DOWN) + { + *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_DOWN; + } + else if (pud == PUD_UP) + { + *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_UP; + } + else + { /* pud == PUD_OFF */ + *(gpio_map + PULLUPDN_OFFSET) &= ~3; + } + short_wait(); + *(gpio_map + clk_offset) = 1 << shift; + short_wait(); + *(gpio_map + PULLUPDN_OFFSET) &= ~3; + *(gpio_map + clk_offset) = 0; + } +} + +static void setup_gpio_line(int gpio, int direction, int pud) +{ + int offset = FSEL_OFFSET + (gpio / 10); + int shift = (gpio % 10) * 3; + + set_pullupdn(gpio, pud); + if (direction == OUTPUT) + *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (1 << shift); + else /* direction == INPUT */ + *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)); +} + +static void setup_gpio_alt5(int gpio) +{ + int offset = FSEL_OFFSET + (gpio / 10); + int shift = (gpio % 10) * 3; + + set_pullupdn(gpio, PUD_OFF); + *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (2 << shift); +} + +static int gpio_input(int gpio) +{ + int offset, value, mask; + + offset = PINLEVEL_OFFSET + (gpio / 32); + mask = (1 << gpio % 32); + value = *(gpio_map + offset) & mask; + return value; +} + +int Gpio_setup(void) +{ + if (setup_the_memmap() != 0) + return -1; + + is_2711 = (*(gpio_map + PULLUPDN_OFFSET_2711_3) != PULLUPDN_2711_MAGIC); + + setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_UP); + setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_UP); + /* TODO: other setup */ + + last_state = 0; + return 0; +} + +void Gpio_cleanup(void) +{ + /* TODO: additional cleanup may be required */ + + setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_OFF); + setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_OFF); + + if (gpio_map) + { + munmap((void *)gpio_map, BLOCK_SIZE); + gpio_map = NULL; + } + if (mem_fd >= 0) + { + close(mem_fd); + mem_fd = -1; + } +} + +int Gpio_read_buttons(void) +{ + int rc = 0; + + if (gpio_input(GLINE_BUTTON1) == 0) + rc |= STATE_BUTTON1; + if (gpio_input(GLINE_BUTTON2) == 0) + rc |= STATE_BUTTON2; + if (gpio_input(GLINE_BUTTON3) == 0) + rc |= STATE_BUTTON3; + if (gpio_input(GLINE_BUTTON4) == 0) + rc |= STATE_BUTTON4; + return rc; +} From 05e102821118424e0e8f7adeac4383b958cc0fbf Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 14:34:57 -0700 Subject: [PATCH 015/162] add backlight control to the code --- src/gpio.c | 25 ++++-- src/gpio.h | 8 ++ src/gpio_old.c | 208 ------------------------------------------------- src/main.c | 10 +++ 4 files changed, 37 insertions(+), 214 deletions(-) delete mode 100644 src/gpio_old.c diff --git a/src/gpio.c b/src/gpio.c index b3143b7..74d9974 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -14,10 +14,7 @@ #define GLINE_BUTTON4 27 #define GLINE_BACKLIGHT 18 -#define STATE_BUTTON1 (1 << 0) -#define STATE_BUTTON2 (1 << 1) -#define STATE_BUTTON3 (1 << 2) -#define STATE_BUTTON4 (1 << 3) +#define PWM_BACKLIGHT 0 int Gpio_setup(void) { @@ -37,14 +34,23 @@ int Gpio_setup(void) bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_UP); bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT); - /* TODO: other setup */ + /* configure the PWM for the backlight */ + bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_ALT5); + bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2); + bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 1); + bcm2835_pwm_set_range(PWM_BACKLIGHT, BACKLIGHT_MAX + 1); + bcm2835_pwm_set_data(PWM_BACKLIGHT, BACKLIGHT_MAX); return 0; } void Gpio_cleanup(void) { - /* TODO: additional cleanup may be required */ + /* close down the backlight lines */ + bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 0); + bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_INPT); /* close down the button lines */ bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_OFF); @@ -74,3 +80,10 @@ int Gpio_read_buttons(void) rc |= STATE_BUTTON4; return rc; } + +void Gpio_set_backlight(unsigned level) +{ + if (level > BACKLIGHT_MAX) + level = BACKLIGHT_MAX; + bcm2835_pwm_set_data(PWM_BACKLIGHT, level); +} diff --git a/src/gpio.h b/src/gpio.h index b70caf0..a46ef22 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,8 +1,16 @@ #ifndef __GPIO_H_INCLUDED #define __GPIO_H_INCLUDED +#define STATE_BUTTON1 (1 << 0) +#define STATE_BUTTON2 (1 << 1) +#define STATE_BUTTON3 (1 << 2) +#define STATE_BUTTON4 (1 << 3) + +#define BACKLIGHT_MAX 1023 + extern int Gpio_setup(void); extern void Gpio_cleanup(void); extern int Gpio_read_buttons(void); +extern void Gpio_set_backlight(unsigned level); #endif /* __GPIO_H_INCLUDED */ diff --git a/src/gpio_old.c b/src/gpio_old.c deleted file mode 100644 index eb332eb..0000000 --- a/src/gpio_old.c +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "log.h" -#include "gpio.h" - -#define GLINE_BUTTON1 17 -#define GLINE_BUTTON2 22 -#define GLINE_BUTTON3 23 -#define GLINE_BUTTON4 27 -#define GLINE_BACKLIGHT 18 - -#define STATE_BUTTON1 (1 << 0) -#define STATE_BUTTON2 (1 << 1) -#define STATE_BUTTON3 (1 << 2) -#define STATE_BUTTON4 (1 << 3) - -#define INPUT 1 /* is really 0 for control register! */ -#define OUTPUT 0 /* is really 1 for control register! */ -#define ALT0 4 - -#define PUD_OFF 0 -#define PUD_DOWN 1 -#define PUD_UP 2 - -#define FSEL_OFFSET 0 -#define SET_OFFSET 7 -#define CLR_OFFSET 10 -#define PINLEVEL_OFFSET 13 -#define EVENT_DETECT_OFFSET 16 -#define RISING_ED_OFFSET 19 -#define FALLING_ED_OFFSET 22 -#define HIGH_DETECT_OFFSET 25 -#define LOW_DETECT_OFFSET 28 -#define PULLUPDN_OFFSET 37 -#define PULLUPDNCLK_OFFSET 38 - -#define PULLUPDN_OFFSET_2711_0 57 -#define PULLUPDN_OFFSET_2711_1 58 -#define PULLUPDN_OFFSET_2711_2 59 -#define PULLUPDN_OFFSET_2711_3 60 -#define PULLUPDN_2711_MAGIC 0x6770696F - -#define BLOCK_SIZE (4*1024) - -static int mem_fd = -1; -static volatile uint32_t *gpio_map = NULL; -static int is_2711 = 0; -static int last_state = 0; - -static void short_wait(void) -{ - int i; - - for (i=0; i<150; i++) - { /* wait 150 cycles */ - asm volatile("nop"); - } -} - -static int setup_the_memmap(void) -{ - if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) > 0) - { - if ((gpio_map = (uint32_t *)mmap(NULL, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0)) == MAP_FAILED) - { - gpio_map = NULL; - close(mem_fd); - Log(LFATAL, "Unable to map /dev/gpiomem (%d)", errno); - return -1; - } - } - - /* ignore the rest of the possibilities for now */ - return 0; -} - -static void set_pullupdn(int gpio, int pud) -{ - if (is_2711) - { /* method for RPi 4 */ - int pullreg = PULLUPDN_OFFSET_2711_0 + (gpio >> 4); - int pullshift = (gpio & 0xF) << 1; - uint32_t pullbits; - unsigned pull = 0; - switch (pud) - { - case PUD_OFF: pull = 0; break; - case PUD_UP: pull = 1; break; - case PUD_DOWN: pull = 2; break; - default: pull = 0; /* keep as "off" */ - } - pullbits = *(gpio_map + pullreg); - pullbits &= ~(3 << pullshift); - pullbits |= (pull << pullshift); - *(gpio_map + pullreg) = pullbits; - } - else - { /* method for older models */ - int clk_offset = PULLUPDNCLK_OFFSET + (gpio / 32); - int shift = gpio % 32; - - if (pud == PUD_DOWN) - { - *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_DOWN; - } - else if (pud == PUD_UP) - { - *(gpio_map + PULLUPDN_OFFSET) = (*(gpio_map + PULLUPDN_OFFSET) & ~3) | PUD_UP; - } - else - { /* pud == PUD_OFF */ - *(gpio_map + PULLUPDN_OFFSET) &= ~3; - } - short_wait(); - *(gpio_map + clk_offset) = 1 << shift; - short_wait(); - *(gpio_map + PULLUPDN_OFFSET) &= ~3; - *(gpio_map + clk_offset) = 0; - } -} - -static void setup_gpio_line(int gpio, int direction, int pud) -{ - int offset = FSEL_OFFSET + (gpio / 10); - int shift = (gpio % 10) * 3; - - set_pullupdn(gpio, pud); - if (direction == OUTPUT) - *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (1 << shift); - else /* direction == INPUT */ - *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)); -} - -static void setup_gpio_alt5(int gpio) -{ - int offset = FSEL_OFFSET + (gpio / 10); - int shift = (gpio % 10) * 3; - - set_pullupdn(gpio, PUD_OFF); - *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift)) | (2 << shift); -} - -static int gpio_input(int gpio) -{ - int offset, value, mask; - - offset = PINLEVEL_OFFSET + (gpio / 32); - mask = (1 << gpio % 32); - value = *(gpio_map + offset) & mask; - return value; -} - -int Gpio_setup(void) -{ - if (setup_the_memmap() != 0) - return -1; - - is_2711 = (*(gpio_map + PULLUPDN_OFFSET_2711_3) != PULLUPDN_2711_MAGIC); - - setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_UP); - setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_UP); - /* TODO: other setup */ - - last_state = 0; - return 0; -} - -void Gpio_cleanup(void) -{ - /* TODO: additional cleanup may be required */ - - setup_gpio_line(GLINE_BUTTON1, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON2, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON3, INPUT, PUD_OFF); - setup_gpio_line(GLINE_BUTTON4, INPUT, PUD_OFF); - - if (gpio_map) - { - munmap((void *)gpio_map, BLOCK_SIZE); - gpio_map = NULL; - } - if (mem_fd >= 0) - { - close(mem_fd); - mem_fd = -1; - } -} - -int Gpio_read_buttons(void) -{ - int rc = 0; - - if (gpio_input(GLINE_BUTTON1) == 0) - rc |= STATE_BUTTON1; - if (gpio_input(GLINE_BUTTON2) == 0) - rc |= STATE_BUTTON2; - if (gpio_input(GLINE_BUTTON3) == 0) - rc |= STATE_BUTTON3; - if (gpio_input(GLINE_BUTTON4) == 0) - rc |= STATE_BUTTON4; - return rc; -} diff --git a/src/main.c b/src/main.c index d474fc0..5702dec 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,16 @@ int main(int argc, char *argv[]) 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(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."); From 2f6118d4363240b4e1705566b75eddd5fa69785c Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 15:43:05 -0700 Subject: [PATCH 016/162] code cleanup --- src/gpio.c | 13 ++++--------- src/gpio.h | 12 +++++++----- src/main.c | 10 +++++----- src/msg_queue.c | 14 +++++++------- src/msg_queue.h | 10 +++++----- src/sysinput.c | 14 +++++++------- src/sysinput.h | 4 ++-- src/time_func.c | 6 +++--- src/time_func.h | 6 +++--- 9 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/gpio.c b/src/gpio.c index 74d9974..f6b5d98 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,9 +1,4 @@ -#include #include -#include -#include -#include -#include #include #include "log.h" #include "gpio.h" @@ -39,8 +34,8 @@ int Gpio_setup(void) bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_ALT5); bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2); bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 1); - bcm2835_pwm_set_range(PWM_BACKLIGHT, BACKLIGHT_MAX + 1); - bcm2835_pwm_set_data(PWM_BACKLIGHT, BACKLIGHT_MAX); + bcm2835_pwm_set_range(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX + 1); + bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX); return 0; } @@ -83,7 +78,7 @@ int Gpio_read_buttons(void) void Gpio_set_backlight(unsigned level) { - if (level > BACKLIGHT_MAX) - level = BACKLIGHT_MAX; + if (level > GSB_BACKLIGHT_MAX) + level = GSB_BACKLIGHT_MAX; bcm2835_pwm_set_data(PWM_BACKLIGHT, level); } diff --git a/src/gpio.h b/src/gpio.h index a46ef22..28b0f54 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,12 +1,14 @@ #ifndef __GPIO_H_INCLUDED #define __GPIO_H_INCLUDED -#define STATE_BUTTON1 (1 << 0) -#define STATE_BUTTON2 (1 << 1) -#define STATE_BUTTON3 (1 << 2) -#define STATE_BUTTON4 (1 << 3) +#define GPIO_BUTTON_COUNT 4 -#define BACKLIGHT_MAX 1023 +#define GRB_STATE_BUTTON1 (1 << 0) +#define GRB_STATE_BUTTON2 (1 << 1) +#define GRB_STATE_BUTTON3 (1 << 2) +#define GRB_STATE_BUTTON4 (1 << 3) + +#define GSB_BACKLIGHT_MAX 1023 extern int Gpio_setup(void); extern void Gpio_cleanup(void); diff --git a/src/main.c b/src/main.c index 5702dec..03a10dd 100644 --- a/src/main.c +++ b/src/main.c @@ -9,19 +9,19 @@ int main(int argc, char *argv[]) int running = 1; MSG msg; - TimeInit(); + Time_init(); if (Gpio_setup() != 0) return EXIT_FAILURE; atexit(Gpio_cleanup); - if (SysEnableInput() != 0) + if (Sys_enable_input() != 0) return EXIT_FAILURE; - atexit(SysDisableInput); + atexit(Sys_disable_input); Log(LINFO, "System ready."); while (running) { - if (MqPeek(Sys_Queue, &msg, PEEK_REMOVE)) + if (Mq_peek(Sys_Queue, &msg, PEEK_REMOVE)) { switch (msg.message) { @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) if (msg.attrs[0] == 1) { Log(LINFO, "Backlight ON."); - Gpio_set_backlight(BACKLIGHT_MAX); + Gpio_set_backlight(GRB_BACKLIGHT_MAX); } if (msg.attrs[0] == 2) { diff --git a/src/msg_queue.c b/src/msg_queue.c index caa5afe..85d35a2 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -5,7 +5,7 @@ #include "time_func.h" #include "msg_queue.h" -PMSG_QUEUE MqAlloc(int nentries) +PMSG_QUEUE Mq_alloc(int nentries) { int sz = sizeof(MSG_QUEUE) + (nentries * sizeof(MSG)); PMSG_QUEUE rc; @@ -22,7 +22,7 @@ PMSG_QUEUE MqAlloc(int nentries) return rc; } -void MqDestroy(PMSG_QUEUE queue) +void Mq_destroy(PMSG_QUEUE queue) { pthread_mutex_destroy(&(queue->mutex)); free(queue); @@ -46,7 +46,7 @@ static void post_internal(PMSG_QUEUE queue, PMSG msg) pthread_mutex_unlock(&(queue->mutex)); } -void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) +void Mq_post(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) { MSG tmpmsg; @@ -57,11 +57,11 @@ void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_ nattrs = MSG_ATTRCOUNT; if (nattrs > 0) memcpy(&(tmpmsg.attrs), attrs, sizeof(uintptr_t) * nattrs); - tmpmsg.timestamp = TimeSinceStart(); + tmpmsg.timestamp = Time_since_start(); post_internal(queue, &tmpmsg); } -void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) +void Mq_post1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) { MSG tmpmsg; @@ -69,11 +69,11 @@ void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t att tmpmsg.target = target; tmpmsg.message = message; tmpmsg.attrs[0] = attr1; - tmpmsg.timestamp = TimeSinceStart(); + tmpmsg.timestamp = Time_since_start(); post_internal(queue, &tmpmsg); } -int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags) +int Mq_peek(PMSG_QUEUE queue, PMSG msg, unsigned flags) { int rc = 0; PMSG nexthead; diff --git a/src/msg_queue.h b/src/msg_queue.h index 4b0ddc5..0df41e4 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -18,10 +18,10 @@ typedef struct tagMSG_QUEUE { #define PEEK_REMOVE 0x0001 #define PEEK_NOREMOVE 0x0000 -extern PMSG_QUEUE MqAlloc(int nentries); -extern void MqDestroy(PMSG_QUEUE queue); -extern void MqPost(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); -extern void MqPost1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); -extern int MqPeek(PMSG_QUEUE queue, PMSG msg, unsigned flags); +extern PMSG_QUEUE Mq_alloc(int nentries); +extern void Mq_destroy(PMSG_QUEUE queue); +extern void Mq_post(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); +extern void Mq_post1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); +extern int Mq_peek(PMSG_QUEUE queue, PMSG msg, unsigned flags); #endif /* __MSG_QUEUE_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index e14291f..826a363 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -24,12 +24,12 @@ static void *input_thread(void *arg) { up = last_bstate & ~st; down = st & ~last_bstate; - for (attr = 1, mask = 1; attr <= 4; attr++, mask <<= 1) + for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { if (up & mask) - MqPost1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); else if (down & mask) - MqPost1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); } last_bstate = st; } @@ -39,11 +39,11 @@ static void *input_thread(void *arg) return NULL; } -int SysEnableInput(void) +int Sys_enable_input(void) { int rc; - Sys_Queue = MqAlloc(64); + Sys_Queue = Mq_alloc(64); if (!Sys_Queue) { Log(LFATAL, "Unable to allocate system message queue."); @@ -56,10 +56,10 @@ int SysEnableInput(void) return rc; } -void SysDisableInput(void) +void Sys_disable_input(void) { running = 0; pthread_join(ithread, NULL); - MqDestroy(Sys_Queue); + Mq_destroy(Sys_Queue); Sys_Queue = NULL; } diff --git a/src/sysinput.h b/src/sysinput.h index 29b5a18..fb01f36 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -5,7 +5,7 @@ extern PMSG_QUEUE Sys_Queue; -extern int SysEnableInput(void); -extern void SysDisableInput(void); +extern int Sys_enable_input(void); +extern void Sys_disable_input(void); #endif /* __SYSINPUT_H_INCLUDED */ diff --git a/src/time_func.c b/src/time_func.c index 1ca8487..bce148a 100644 --- a/src/time_func.c +++ b/src/time_func.c @@ -4,7 +4,7 @@ static TIMESTAMP start_timestamp = 0; -TIMESTAMP TimeSinceEpoch(void) +TIMESTAMP Time_since_epoch(void) { TIMESTAMP rc; struct timeval tv; @@ -14,12 +14,12 @@ TIMESTAMP TimeSinceEpoch(void) return rc; } -TIMESTAMP TimeSinceStart(void) +TIMESTAMP Time_since_start(void) { return TimeSinceEpoch() - start_timestamp; } -void TimeInit(void) +void Time_init(void) { start_timestamp = TimeSinceEpoch(); } diff --git a/src/time_func.h b/src/time_func.h index 80e0b14..635ca03 100644 --- a/src/time_func.h +++ b/src/time_func.h @@ -3,8 +3,8 @@ #include "wintype.h" -extern TIMESTAMP TimeSinceEpoch(void); -extern TIMESTAMP TimeSinceStart(void); -extern void TimeInit(void); +extern TIMESTAMP Time_since_epoch(void); +extern TIMESTAMP Time_since_start(void); +extern void Time_init(void); #endif /* __TIMEFUNC_H_INCLUDED */ From b550994effff6eccbabd6cf9f9c97acdd0f6e54e Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 15:45:46 -0700 Subject: [PATCH 017/162] corrected compilation errors --- src/gpio.c | 8 ++++---- src/main.c | 2 +- src/time_func.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gpio.c b/src/gpio.c index f6b5d98..8042f3b 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -66,13 +66,13 @@ int Gpio_read_buttons(void) int rc = 0; if (bcm2835_gpio_lev(GLINE_BUTTON1) == LOW) - rc |= STATE_BUTTON1; + rc |= GRB_STATE_BUTTON1; if (bcm2835_gpio_lev(GLINE_BUTTON2) == LOW) - rc |= STATE_BUTTON2; + rc |= GRB_STATE_BUTTON2; if (bcm2835_gpio_lev(GLINE_BUTTON3) == LOW) - rc |= STATE_BUTTON3; + rc |= GRB_STATE_BUTTON3; if (bcm2835_gpio_lev(GLINE_BUTTON4) == LOW) - rc |= STATE_BUTTON4; + rc |= GRB_STATE_BUTTON4; return rc; } diff --git a/src/main.c b/src/main.c index 03a10dd..868fbee 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) if (msg.attrs[0] == 1) { Log(LINFO, "Backlight ON."); - Gpio_set_backlight(GRB_BACKLIGHT_MAX); + Gpio_set_backlight(GSB_BACKLIGHT_MAX); } if (msg.attrs[0] == 2) { diff --git a/src/time_func.c b/src/time_func.c index bce148a..8bdda09 100644 --- a/src/time_func.c +++ b/src/time_func.c @@ -16,10 +16,10 @@ TIMESTAMP Time_since_epoch(void) TIMESTAMP Time_since_start(void) { - return TimeSinceEpoch() - start_timestamp; + return Time_since_epoch() - start_timestamp; } void Time_init(void) { - start_timestamp = TimeSinceEpoch(); + start_timestamp = Time_since_epoch(); } From 3595dfdbbdb8ad843742589ff59efa86b071075d Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 18:53:54 -0700 Subject: [PATCH 018/162] add framebuffer initialization --- src/Makefile | 2 +- src/fbinit.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/fbinit.h | 7 +++++ src/main.c | 4 +++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 src/fbinit.c create mode 100644 src/fbinit.h diff --git a/src/Makefile b/src/Makefile index 08f0b3a..ac35150 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o log.o gpio.o msg_queue.o time_func.o +OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o LIBS=-lbcm2835 -lpthread upiwin: $(OBJS) diff --git a/src/fbinit.c b/src/fbinit.c new file mode 100644 index 0000000..477dc8f --- /dev/null +++ b/src/fbinit.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include "log.h" +#include "fbinit.h" + +static int fb_fd = -1; + +static void dump_fixed_info(const struct fb_fix_screeninfo *p) +{ + Log(LDEBUG, "--Fixed screen info follows--"); + Log(LDEBUG, "ID=%s SMEM@0x%08x/%u TYPE=%u TYPEAUX=%u VIZ=%u", + p->id, p->smem_start, p->smem_len, p->type, p->type_aux, p->visual); + Log(LDEBUG, "XPAN=%u YPAN=%u YWRAP=%u LINELEN=%u", p->xpanstep, p->ypanstep, p->ywrapstep, p->line_length); + Log(LDEBUG, "MMIO@0x%08x/%u ACCEL=%02x CAP=%08x", p->mmio_start, p->mmio_len, p->accel, p->capabilities); + Log(LDEBUG, "--ends--"); +} + +static void dump_var_info(const struct fb_var_screeninfo *p) +{ + Log(LDEBUG, "--Variable screen info follows--"); + Log(LDEBUG, "RES=(%u,%u) VRES=(%u,%u) OFS=(%u,%u) BPP=%u GS=%u", p->xres, p->yres, + p->xres_virtual, p->yres_virtual, p->xoffset, p->yoffset, p->bits_per_pixel, p->grayscale); + Log(LDEBUG, "RedBits: ofs=%u len=%u mright=%u", p->red.offset, p->red.length, p->red.msb_right); + Log(LDEBUG, "GreenBits: ofs=%u len=%u mright=%u", p->green.offset, p->green.length, p->green.msb_right); + Log(LDEBUG, "BlueBits: ofs=%u len=%u mright=%u", p->blue.offset, p->blue.length, p->blue.msb_right); + Log(LDEBUG, "XparBits: ofs=%u len=%u mright=%u", p->transp.offset, p->transp.length, p->transp.msb_right); + Log(LDEBUG, "NONSTD=%u ACTIV=%u PSIZ=(%u,%u) AFLG=%08x", + p->nonstd, p->activate, p->width, p->height, p->accel_flags); + Log(LDEBUG, "PIXCLK=%u LM=%u RM=%u TM=%u BM=%u HSYNC=%u VSYNC=%u", p->pixclock, p->left_margin, p->right_margin, + p->upper_margin, p->lower_margin, p->hsync_len, p->vsync_len); + Log(LDEBUG, "SYNC=%u VMODE=%u ROT=%u COLORSP=%u", p->sync, p->vmode, p->rotate, p->colorspace); + Log(LDEBUG, "--ends--"); +} + +int Fb_setup(void) +{ + struct fb_fix_screeninfo fixed; + struct fb_var_screeninfo var; + + fb_fd = open("/dev/fb1", O_RDWR); + if (fb_fd == -1) + { + Log(LFATAL, "Unable to open framebuffer (%d)", errno); + return -1; + } + + if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed)) + { + Log(LFATAL, "Could not get fixed screen info (%d)", errno); + return -1; + } + + dump_fixed_info(&fixed); + + if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) + { + Log(LFATAL, "Could not get variable screen info (%d)", errno); + return -1; + } + + dump_fixed_info(&var); + + /* additional initialization here */ + + return 0; +} + +void Fb_cleanup(void) +{ + /* additional cleanup here */ + + close(fb_fd); +} diff --git a/src/fbinit.h b/src/fbinit.h new file mode 100644 index 0000000..40737f3 --- /dev/null +++ b/src/fbinit.h @@ -0,0 +1,7 @@ +#ifndef __FBINIT_H_INCLUDED +#define __FBINIT_H_INCLUDED + +extern int Fb_setup(void); +extern void Fb_cleanup(void); + +#endif /* __FBINIT_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 868fbee..f0d546f 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include #include "gpio.h" #include "log.h" +#include "fbinit.h" #include "time_func.h" #include "sysinput.h" @@ -10,6 +11,9 @@ int main(int argc, char *argv[]) MSG msg; Time_init(); + if (Fb_setup() != 0) + return EXIT_FAILURE; + atexit(Fb_cleanup); if (Gpio_setup() != 0) return EXIT_FAILURE; atexit(Gpio_cleanup); From cde4022da2c49d5ad9ee7888537a3299ee753396 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 19:20:04 -0700 Subject: [PATCH 019/162] compilation fixes --- src/fbinit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fbinit.c b/src/fbinit.c index 477dc8f..a1477c7 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -61,7 +62,7 @@ int Fb_setup(void) return -1; } - dump_fixed_info(&var); + dump_var_info(&var); /* additional initialization here */ From 58ef012d44266b1d4fe3e778e1c919957be102c4 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 19:39:14 -0700 Subject: [PATCH 020/162] add the framebuffer info, mapping the frame buffer, and actually putting something on screen --- src/fbinit.c | 66 +++++++++++++++++++++++++++++++--------------------- src/fbinit.h | 25 ++++++++++++++++++++ src/main.c | 7 ++++++ 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/fbinit.c b/src/fbinit.c index a1477c7..890968d 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -1,39 +1,24 @@ #include +#include #include #include #include #include +#include #include #include "log.h" #include "fbinit.h" static int fb_fd = -1; -static void dump_fixed_info(const struct fb_fix_screeninfo *p) -{ - Log(LDEBUG, "--Fixed screen info follows--"); - Log(LDEBUG, "ID=%s SMEM@0x%08x/%u TYPE=%u TYPEAUX=%u VIZ=%u", - p->id, p->smem_start, p->smem_len, p->type, p->type_aux, p->visual); - Log(LDEBUG, "XPAN=%u YPAN=%u YWRAP=%u LINELEN=%u", p->xpanstep, p->ypanstep, p->ywrapstep, p->line_length); - Log(LDEBUG, "MMIO@0x%08x/%u ACCEL=%02x CAP=%08x", p->mmio_start, p->mmio_len, p->accel, p->capabilities); - Log(LDEBUG, "--ends--"); -} +static FBINFO local_info; +PCFBINFO Fb_Info = &local_info; -static void dump_var_info(const struct fb_var_screeninfo *p) +uint16_t *Fb_Ptr = NULL; + +inline static unsigned makemask(unsigned offset, unsigned length) { - Log(LDEBUG, "--Variable screen info follows--"); - Log(LDEBUG, "RES=(%u,%u) VRES=(%u,%u) OFS=(%u,%u) BPP=%u GS=%u", p->xres, p->yres, - p->xres_virtual, p->yres_virtual, p->xoffset, p->yoffset, p->bits_per_pixel, p->grayscale); - Log(LDEBUG, "RedBits: ofs=%u len=%u mright=%u", p->red.offset, p->red.length, p->red.msb_right); - Log(LDEBUG, "GreenBits: ofs=%u len=%u mright=%u", p->green.offset, p->green.length, p->green.msb_right); - Log(LDEBUG, "BlueBits: ofs=%u len=%u mright=%u", p->blue.offset, p->blue.length, p->blue.msb_right); - Log(LDEBUG, "XparBits: ofs=%u len=%u mright=%u", p->transp.offset, p->transp.length, p->transp.msb_right); - Log(LDEBUG, "NONSTD=%u ACTIV=%u PSIZ=(%u,%u) AFLG=%08x", - p->nonstd, p->activate, p->width, p->height, p->accel_flags); - Log(LDEBUG, "PIXCLK=%u LM=%u RM=%u TM=%u BM=%u HSYNC=%u VSYNC=%u", p->pixclock, p->left_margin, p->right_margin, - p->upper_margin, p->lower_margin, p->hsync_len, p->vsync_len); - Log(LDEBUG, "SYNC=%u VMODE=%u ROT=%u COLORSP=%u", p->sync, p->vmode, p->rotate, p->colorspace); - Log(LDEBUG, "--ends--"); + return ((1 << length) - 1) << offset; } int Fb_setup(void) @@ -54,7 +39,8 @@ int Fb_setup(void) return -1; } - dump_fixed_info(&fixed); + local_info.linebytes = fixed.line_length; + local_info.screenbytes = fixed.smem_len; if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) { @@ -62,9 +48,32 @@ int Fb_setup(void) return -1; } - dump_var_info(&var); + local_info.width = var.xres; + local_info.height = var.yres; + local_info.virtual_width = var.xres_virtual; + local_info.virtual_height = var.yres_virtual; + local_info.bpp = var.bits_per_pixel; + local_info.red_offset = var.red.offset; + local_info.red_length = var.red.length; + local_info.red_mask = makemask(var.red.offset, var.red.length); + local_info.green_offset = var.green.offset; + local_info.green_length = var.green.length; + local_info.green_mask = makemask(var.green.offset, var.green.length); + local_info.blue_offset = var.blue.offset; + local_info.blue_length = var.blue.length; + local_info.blue_mask = makemask(var.blue.offset, var.blue.length); - /* additional initialization here */ + Fb_Ptr = (uint16_t *)mmap(0, fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0); + if ((int)Fb_Ptr == -1) + { + Log(LFATAL, "Unable to memmap framebuffer (%d)", errno); + Fb_Ptr = NULL; + close(fb_fd); + fb_fd = -1; + return -1; + } + + /* additional setup here */ return 0; } @@ -73,5 +82,10 @@ void Fb_cleanup(void) { /* additional cleanup here */ + memset(Fb_Ptr, 0, local_info.screenbytes); + munmap((void *)Fb_Ptr, local_info.screenbytes); + Fb_Ptr = NULL; + close(fb_fd); + fb_fd = -1; } diff --git a/src/fbinit.h b/src/fbinit.h index 40737f3..a4612d4 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -1,6 +1,31 @@ #ifndef __FBINIT_H_INCLUDED #define __FBINIT_H_INCLUDED +#include + +typedef struct tagFBINFO { + uint32_t width; + uint32_t height; + uint32_t virtual_width; + uint32_t virtual_height; + uint32_t bpp; + uint32_t linebytes; + uint32_t screenbytes; + uint16_t red_offset; + uint16_t red_length; + uint16_t red_mask; + uint16_t green_offset; + uint16_t green_length; + uint16_t green_mask; + uint16_t blue_offset; + uint16_t blue_length; + uint16_t blue_mask; +} FBINFO; +typedef const FBINFO * const PCFBINFO; + +extern PCFBINFO Fb_Info; +extern uint16_t *Fb_Ptr; + extern int Fb_setup(void); extern void Fb_cleanup(void); diff --git a/src/main.c b/src/main.c index f0d546f..afb7cc6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,5 @@ #include +#include #include "gpio.h" #include "log.h" #include "fbinit.h" @@ -9,6 +10,7 @@ int main(int argc, char *argv[]) { int running = 1; MSG msg; + char *tmp; Time_init(); if (Fb_setup() != 0) @@ -21,6 +23,11 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; atexit(Sys_disable_input); + /* temporary drawing here */ + tmp = (char *)Fb_Ptr; + memset(tmp, 0xFF, Fb-Info->screenbytes / 2); + memset(tmp + (Fb-Info->screenbytes / 2), 0x1B, Fb-Info->screenbytes / 2); + Log(LINFO, "System ready."); while (running) From eea6a5445d515a83ffac285b0899ef1c9d4e9eba Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 19:42:05 -0700 Subject: [PATCH 021/162] fix compilation errors --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index afb7cc6..76d7a46 100644 --- a/src/main.c +++ b/src/main.c @@ -25,8 +25,8 @@ int main(int argc, char *argv[]) /* temporary drawing here */ tmp = (char *)Fb_Ptr; - memset(tmp, 0xFF, Fb-Info->screenbytes / 2); - memset(tmp + (Fb-Info->screenbytes / 2), 0x1B, Fb-Info->screenbytes / 2); + memset(tmp, 0xFF, Fb_Info->screenbytes / 2); + memset(tmp + (Fb_Info->screenbytes / 2), 0x1B, Fb_Info->screenbytes / 2); Log(LINFO, "System ready."); From 421d441ad09ca4588c4fc4c65e918cc67e569194 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 1 Dec 2019 20:57:36 -0700 Subject: [PATCH 022/162] trying another type of drawing --- src/main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 76d7a46..7c871a1 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,22 @@ #include "time_func.h" #include "sysinput.h" +static void do_draw(void) +{ + /* + tmp = (char *)Fb_Ptr; + memset(tmp, 0xFF, Fb_Info->screenbytes / 2); + memset(tmp + (Fb_Info->screenbytes / 2), 0x1B, Fb_Info->screenbytes / 2); + */ + uint16_t pixel = Fb_Info->green_mask; + unsigned npix = Fb_Info->screenbytes / sizeof(uint16_t); + uint16_t *p = Fb_Ptr; + unsigned i; + + for (i=0; iscreenbytes / 2); - memset(tmp + (Fb_Info->screenbytes / 2), 0x1B, Fb_Info->screenbytes / 2); - + do_draw(); + Log(LINFO, "System ready."); while (running) From 0849582c7b622c744284f155441da0912cf1dbad Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Mon, 2 Dec 2019 23:30:46 -0700 Subject: [PATCH 023/162] added clean rule and a bunch of definitions --- src/Makefile | 3 ++ src/scode.h | 68 ++++++++++++++++++++++++ src/wintype.h | 143 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 src/scode.h diff --git a/src/Makefile b/src/Makefile index ac35150..4a6441b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,3 +6,6 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< + +clean: + rm -f upiwin *.o *~ diff --git a/src/scode.h b/src/scode.h new file mode 100644 index 0000000..b151bee --- /dev/null +++ b/src/scode.h @@ -0,0 +1,68 @@ +#ifndef __SCODE_H_INCLUDED +#define __SCODE_H_INCLUDED + +#include + +/*------------------------------------------------------------------- + * Status codes are defined as follows: + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |S| Facility | Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 9 8 7 6 5 4 3 2 1 0 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * + * S = Severity: 0 = success, 1 = error + * Facility = Facility code + * Code = Specific error code + *------------------------------------------------------------------- + */ + +/* Severity codes */ +#define SEVERITY_SUCCESS 0x00000000 +#define SEVERITY_ERROR 0x80000000 + +/* Facility codes - compatible with M$ */ +#define FACILITY_NULL 0 +#define FACILITY_RPC 1 +#define FACILITY_STORAGE 3 +#define FACILITY_ITF 4 +#define FACILITY_UNIX 5 +#define FACILITY_UPIWIN 6 + +#define SUCCEEDED(s) (((s) & SEVERITY_ERROR) == 0) +#define FAILED(s) (((s) & SEVERITY_ERROR) != 0) + +#define SCODE_FACILITY(s) (((s) >> 16) & 0x7FFF) +#define SCODE_CODE(s) ((s) & 0xFFFF) + +#define MAKE_SCODE(sev, fac, err) ((SCODE)((sev) | (((fac) & 0x7FFF) << 16) | ((err) & 0xFFFF))) + +#define ERRNO_AS_SCODE MAKE_SCODE(SEVERITY_ERROR, FACILITY_UNIX, errno) + +#define SCODE_CAST(x) ((SCODE)(x)) + +/* Basic success codes */ +#define S_OK SCODE_CAST(0x00000000) /* OK return */ +#define S_FALSE SCODE_CAST(0x00000001) /* "False" return */ + +/* Basic error codes */ +#define E_NOTIMPL SCODE_CAST(0x80000001) /* not implemented */ +#define E_OUTOFMEMORY SCODE_CAST(0x80000002) /* out of memory */ +#define E_INVALIDARG SCODE_CAST(0x80000003) /* invalid argument */ +#define E_NOINTERFACE SCODE_CAST(0x80000004) /* no such interface */ +#define E_POINTER SCODE_CAST(0x80000005) /* invalid pointer */ +#define E_HANDLE SCODE_CAST(0x80000006) /* invalid handle */ +#define E_ABORT SCODE_CAST(0x80000007) /* aborted operation */ +#define E_FAIL SCODE_CAST(0x80000008) /* unspecified failure */ +#define E_ACCESSDENIED SCODE_CAST(0x80000009) /* access denied */ +#define E_PENDING SCODE_CAST(0x8000000A) /* data not yet available */ +#define E_BOUNDS SCODE_CAST(0x8000000B) /* access outside valid range */ +#define E_CHANGED_STATE SCODE_CAST(0x8000000C) /* object changed state, result now invalid */ +#define E_ILLEGAL_STATE_CHANGE SCODE_CAST(0x8000000D) /* illegal state change */ +#define E_ILLEGAL_METHOD_CALL SCODE_CAST(0x8000000E) /* illegal method call */ +#define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */ + +/* UPIWIN-specific errorcodes */ +#define UPIWIN_E_OUTOFRANGE SCODE_CAST(0x80060000) /* value out of range */ + +#endif /* __SCODE_H_INCLUDED */ diff --git a/src/wintype.h b/src/wintype.h index 08d921b..8fa5cd8 100644 --- a/src/wintype.h +++ b/src/wintype.h @@ -3,6 +3,147 @@ #include -typedef uint64_t TIMESTAMP; +/* Integral limit values */ +/*#define INT16_MIN 0x8000 - defined in stdint.h */ +/*#define INT16_MAX 0x7FFF - defined in stdint.h */ +#define UINT16_MIN 0 +/*#define UINT16_MAX 0xFFFF - defined in stdint.h*/ +/*#define INT32_MIN 0x80000000 - defined in stdint.h*/ +/*#define INT32_MAX 0x7FFFFFFF - defined in stdint.h*/ +#define UINT32_MIN 0 +/*#define UINT32_MAX 0xFFFFFFFF - defined in stdint.h*/ +/*#define INT64_MIN 0x8000000000000000 - defined in stdint.h*/ +/*#define INT64_MAX 0x7FFFFFFFFFFFFFFF - defined in stdint.h*/ +#define UINT64_MIN 0 +/*#define UINT64_MAX 0xFFFFFFFFFFFFFFFF - defined in stdint.h*/ + +#define INT_PTR_MIN INTPTR_MIN +#define INT_PTR_MAX INTPTR_MAX +#define UINT_PTR_MIN 0 +#define UINT_PTR_MAX UINTPTR_MAX +#define DWORD_MIN UINT32_MIN +#define DWORD_MAX UINT32_MAX + +/* Number of bits */ +#define INT16_BITS 16 +#define UINT16_BITS 16 +#define INT32_BITS 32 +#define UINT32_BITS 32 +#define INT64_BITS 64 +#define UINT64_BITS 64 + +#define LOG_PTRSIZE 2 /* log2(sizeof(void *)) */ + +#define LOG_INTSIZE 2 /* log2(sizeof(int)) */ +#define LOG_UINTSIZE 2 /* log2(sizeof(UINT32)) */ +#define LOG_INT64SIZE 3 /* log2(sizeof(long long)) */ + +#define PTRSIZE (1U << LOG_PTRSIZE) +#define PTR_MASK (PTRSIZE - 1) +#define PTR_CEILING(a) (((a) + PTR_MASK) & ~PTR_MASK) + +/* Boolean values */ +#define TRUE 1 +#define FALSE 0 + +/* NULL value */ +#ifndef NULL +#define NULL 0 +#endif + +/* Integral types */ +typedef int16_t INT16; +typedef uint16_t UINT16; +typedef int32_t INT32; +typedef uint32_t UINT32; +typedef int64_t INT64; +typedef uint64_t UINT64; + +typedef UINT16 WORD; +typedef UINT32 DWORD; +typedef UINT64 QWORD; +typedef INT32 LONG; +typedef UINT32 ULONG; +typedef INT64 LONG64; +typedef UINT64 ULONG64; + +typedef INT32 INT; +typedef UINT32 UINT; + +typedef INT64 LONGLONG; +typedef UINT64 ULONGLONG; + +typedef intptr_t INT_PTR; +typedef uintptr_t UINT_PTR; + +typedef UINT_PTR SIZE_T; +typedef INT_PTR SSIZE_T; + +/* Base pointer types */ +typedef INT16 *PINT16; +typedef UINT16 *PUINT16; +typedef INT32 *PINT32; +typedef UINT32 *PUINT32; +typedef INT64 *PINT64; +typedef UINT64 *PUINT64; +typedef SIZE_T *PSIZE_T; +typedef void *PVOID; +typedef const void *PCVOID; +typedef WORD *PWORD; +typedef DWORD *PDWORD; +typedef QWORD *PQWORD; +typedef LONGLONG *PLONGLONG; +typedef ULONGLONG *PULONGLONG; + +/* Pointer-to-pointer types */ +typedef PVOID *PPVOID; + +/* Character types */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; +typedef uint16_t WCHAR; + +typedef CHAR *PCHAR; +typedef const CHAR *PCCHAR; +typedef UCHAR *PUCHAR; +typedef BYTE *PBYTE; +typedef const BYTE *PCBYTE; +typedef WCHAR *PWCHAR; +typedef const WCHAR *PCWCHAR; +typedef PCCHAR *PPCCHAR; +typedef CHAR *PSTR; +typedef const CHAR *PCSTR; +typedef WCHAR *PWSTR; +typedef const WCHAR *PCWSTR; + +/* Boolean type */ +typedef int BOOL; + +/* Handle type */ +typedef UINT_PTR HANDLE; +typedef HANDLE *PHANDLE; + +/* Status code/result types */ +typedef UINT32 SCODE; +typedef SCODE *PSCODE; +typedef SCODE HRESULT; + +typedef UINT64 TIMESTAMP; + +#define MAKEBOOL(val) ((val) ? TRUE : FALSE) +#define OFFSETOF(struc, field) ((UINT_PTR)(&(((struc *)0)->field))) +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#define MAKEWORD(a, b) ((WORD)((((UINT_PTR)(a)) & 0xFF) | ((((UINT_PTR)(b)) & 0xFF) << 8))) +#define MAKELONG(a, b) ((LONG)((((UINT_PTR)(a)) & 0xFFFF) | ((((UINT_PTR)(b)) & 0xFFFF) << 16))) +#define MAKELONG64(a, b) ((LONG64)((((UINT64)(a)) & 0xFFFFFFFF) | ((((UINT64)(b)) & 0xFFFFFFFF) << 32))) +#define LODWORD(l) ((DWORD)(((UINT64)(l)) & 0xFFFFFFFF)) +#define HIDWORD(l) ((DWORD)((((UINT64)(l)) >> 32) & 0xFFFFFFFF)) +#define LOWORD(l) ((WORD)(((UINT_PTR)(l)) & 0xFFFF)) +#define HIWORD(l) ((WORD)((((UINT_PTR)(l)) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((BYTE)(((UINT_PTR)(w)) & 0xFF)) +#define HIBYTE(w) ((BYTE)((((UINT_PTR)(w)) >> 8) & 0xFF)) #endif /* __WINTYPE_H_INCLUDED */ From 09f4b5ceb5a66b88c0e9276803af8f6f2385169a Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Thu, 5 Dec 2019 18:21:37 -0700 Subject: [PATCH 024/162] adapted code to use the wintype.h types and the error codes --- src/fbinit.c | 34 ++++++++++++++++++++-------------- src/fbinit.h | 38 +++++++++++++++++++------------------- src/gpio.c | 13 +++++++------ src/gpio.h | 8 +++++--- src/main.c | 13 +++++++------ src/msg.h | 6 +++--- src/msg_queue.c | 12 ++++++------ src/msg_queue.h | 10 +++++----- src/scode.h | 5 +++-- src/sysinput.c | 23 ++++++++++++++--------- src/sysinput.h | 3 ++- 11 files changed, 91 insertions(+), 74 deletions(-) diff --git a/src/fbinit.c b/src/fbinit.c index 890968d..82f2af4 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -8,35 +8,39 @@ #include #include "log.h" #include "fbinit.h" +#include "scode.h" static int fb_fd = -1; static FBINFO local_info; PCFBINFO Fb_Info = &local_info; -uint16_t *Fb_Ptr = NULL; +UINT16 *Fb_Ptr = NULL; -inline static unsigned makemask(unsigned offset, unsigned length) +inline static UINT16 makemask(unsigned offset, unsigned length) { - return ((1 << length) - 1) << offset; + return (UINT16)(((1 << length) - 1) << offset); } -int Fb_setup(void) +HRESULT Fb_setup(void) { + HRESULT hr = S_OK; struct fb_fix_screeninfo fixed; struct fb_var_screeninfo var; fb_fd = open("/dev/fb1", O_RDWR); if (fb_fd == -1) { - Log(LFATAL, "Unable to open framebuffer (%d)", errno); - return -1; + hr = ERRNO_AS_SCODE; + Log(LFATAL, "Unable to open framebuffer (%08X)", hr); + return hr; } if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed)) { - Log(LFATAL, "Could not get fixed screen info (%d)", errno); - return -1; + hr = ERRNO_AS_SCODE; + Log(LFATAL, "Could not get fixed screen info (%08X)", hr); + return hr; } local_info.linebytes = fixed.line_length; @@ -44,8 +48,9 @@ int Fb_setup(void) if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) { - Log(LFATAL, "Could not get variable screen info (%d)", errno); - return -1; + hr = ERRNO_AS_SCODE; + Log(LFATAL, "Could not get variable screen info (%08X)", hr); + return hr; } local_info.width = var.xres; @@ -63,19 +68,20 @@ int Fb_setup(void) local_info.blue_length = var.blue.length; local_info.blue_mask = makemask(var.blue.offset, var.blue.length); - Fb_Ptr = (uint16_t *)mmap(0, fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0); + Fb_Ptr = (UINT16 *)mmap(0, fixed.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0); if ((int)Fb_Ptr == -1) { - Log(LFATAL, "Unable to memmap framebuffer (%d)", errno); + hr = ERRNO_AS_SCODE; + Log(LFATAL, "Unable to memmap framebuffer (%08X)", hr); Fb_Ptr = NULL; close(fb_fd); fb_fd = -1; - return -1; + return hr; } /* additional setup here */ - return 0; + return hr; } void Fb_cleanup(void) diff --git a/src/fbinit.h b/src/fbinit.h index a4612d4..2b5d256 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -1,32 +1,32 @@ #ifndef __FBINIT_H_INCLUDED #define __FBINIT_H_INCLUDED -#include +#include "wintype.h" typedef struct tagFBINFO { - uint32_t width; - uint32_t height; - uint32_t virtual_width; - uint32_t virtual_height; - uint32_t bpp; - uint32_t linebytes; - uint32_t screenbytes; - uint16_t red_offset; - uint16_t red_length; - uint16_t red_mask; - uint16_t green_offset; - uint16_t green_length; - uint16_t green_mask; - uint16_t blue_offset; - uint16_t blue_length; - uint16_t blue_mask; + UINT32 width; + UINT32 height; + UINT32 virtual_width; + UINT32 virtual_height; + UINT32 bpp; + UINT32 linebytes; + UINT32 screenbytes; + UINT16 red_offset; + UINT16 red_length; + UINT16 red_mask; + UINT16 green_offset; + UINT16 green_length; + UINT16 green_mask; + UINT16 blue_offset; + UINT16 blue_length; + UINT16 blue_mask; } FBINFO; typedef const FBINFO * const PCFBINFO; extern PCFBINFO Fb_Info; -extern uint16_t *Fb_Ptr; +extern UINT16 *Fb_Ptr; -extern int Fb_setup(void); +extern HRESULT Fb_setup(void); extern void Fb_cleanup(void); #endif /* __FBINIT_H_INCLUDED */ diff --git a/src/gpio.c b/src/gpio.c index 8042f3b..13255e9 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,6 +1,7 @@ #include #include #include "log.h" +#include "scode.h" #include "gpio.h" #define GLINE_BUTTON1 17 @@ -11,12 +12,12 @@ #define PWM_BACKLIGHT 0 -int Gpio_setup(void) +HRESULT Gpio_setup(void) { if (!bcm2835_init()) { Log(LFATAL, "Error initializing BCM2835 library"); - return -1; + return E_FAIL; } /* configure the buttons */ @@ -37,7 +38,7 @@ int Gpio_setup(void) bcm2835_pwm_set_range(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX + 1); bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX); - return 0; + return S_OK; } void Gpio_cleanup(void) @@ -61,9 +62,9 @@ void Gpio_cleanup(void) Log(LWARN, "Closing BCM2835 library failed"); } -int Gpio_read_buttons(void) +UINT32 Gpio_read_buttons(void) { - int rc = 0; + UINT32 rc = 0; if (bcm2835_gpio_lev(GLINE_BUTTON1) == LOW) rc |= GRB_STATE_BUTTON1; @@ -76,7 +77,7 @@ int Gpio_read_buttons(void) return rc; } -void Gpio_set_backlight(unsigned level) +void Gpio_set_backlight(UINT32 level) { if (level > GSB_BACKLIGHT_MAX) level = GSB_BACKLIGHT_MAX; diff --git a/src/gpio.h b/src/gpio.h index 28b0f54..38d5555 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,6 +1,8 @@ #ifndef __GPIO_H_INCLUDED #define __GPIO_H_INCLUDED +#include "wintype.h" + #define GPIO_BUTTON_COUNT 4 #define GRB_STATE_BUTTON1 (1 << 0) @@ -10,9 +12,9 @@ #define GSB_BACKLIGHT_MAX 1023 -extern int Gpio_setup(void); +extern HRESULT Gpio_setup(void); extern void Gpio_cleanup(void); -extern int Gpio_read_buttons(void); -extern void Gpio_set_backlight(unsigned level); +extern UINT32 Gpio_read_buttons(void); +extern void Gpio_set_backlight(UINT32 level); #endif /* __GPIO_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 7c871a1..915a990 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include "scode.h" #include "gpio.h" #include "log.h" #include "fbinit.h" @@ -13,9 +14,9 @@ static void do_draw(void) memset(tmp, 0xFF, Fb_Info->screenbytes / 2); memset(tmp + (Fb_Info->screenbytes / 2), 0x1B, Fb_Info->screenbytes / 2); */ - uint16_t pixel = Fb_Info->green_mask; - unsigned npix = Fb_Info->screenbytes / sizeof(uint16_t); - uint16_t *p = Fb_Ptr; + UINT16 pixel = Fb_Info->green_mask; + unsigned npix = Fb_Info->screenbytes / sizeof(UINT16); + UINT16 *p = Fb_Ptr; unsigned i; for (i=0; imutex)); } -void Mq_post(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs) +void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs) { MSG tmpmsg; @@ -61,7 +61,7 @@ void Mq_post(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr post_internal(queue, &tmpmsg); } -void Mq_post1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1) +void Mq_post1(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1) { MSG tmpmsg; @@ -73,9 +73,9 @@ void Mq_post1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t at post_internal(queue, &tmpmsg); } -int Mq_peek(PMSG_QUEUE queue, PMSG msg, unsigned flags) +BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags) { - int rc = 0; + BOOL rc = FALSE; PMSG nexthead; pthread_mutex_lock(&(queue->mutex)); @@ -87,7 +87,7 @@ int Mq_peek(PMSG_QUEUE queue, PMSG msg, unsigned flags) memcpy(msg, queue->head, sizeof(MSG)); if (flags & PEEK_REMOVE) queue->head = nexthead; - rc = 1; + rc = TRUE; } pthread_mutex_unlock(&(queue->mutex)); return rc; diff --git a/src/msg_queue.h b/src/msg_queue.h index 0df41e4..a5220a5 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -10,7 +10,7 @@ typedef struct tagMSG_QUEUE { PMSG endbound; PMSG head; PMSG tail; - int nentries; + UINT32 nentries; pthread_mutex_t mutex; MSG messagestore[0]; } MSG_QUEUE, *PMSG_QUEUE; @@ -18,10 +18,10 @@ typedef struct tagMSG_QUEUE { #define PEEK_REMOVE 0x0001 #define PEEK_NOREMOVE 0x0000 -extern PMSG_QUEUE Mq_alloc(int nentries); +extern PMSG_QUEUE Mq_alloc(UINT32 nentries); extern void Mq_destroy(PMSG_QUEUE queue); -extern void Mq_post(PMSG_QUEUE queue, uintptr_t target, unsigned message, const uintptr_t *attrs, int nattrs); -extern void Mq_post1(PMSG_QUEUE queue, uintptr_t target, unsigned message, uintptr_t attr1); -extern int Mq_peek(PMSG_QUEUE queue, PMSG msg, unsigned flags); +extern void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs); +extern void Mq_post1(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1); +extern BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags); #endif /* __MSG_QUEUE_H_INCLUDED */ diff --git a/src/scode.h b/src/scode.h index b151bee..6880804 100644 --- a/src/scode.h +++ b/src/scode.h @@ -1,7 +1,7 @@ #ifndef __SCODE_H_INCLUDED #define __SCODE_H_INCLUDED -#include +#include "wintype.h" /*------------------------------------------------------------------- * Status codes are defined as follows: @@ -37,7 +37,8 @@ #define MAKE_SCODE(sev, fac, err) ((SCODE)((sev) | (((fac) & 0x7FFF) << 16) | ((err) & 0xFFFF))) -#define ERRNO_AS_SCODE MAKE_SCODE(SEVERITY_ERROR, FACILITY_UNIX, errno) +#define SCODE_FROM_ERRNO(x) MAKE_SCODE(SEVERITY_ERROR, FACILITY_UNIX, (x)) +#define ERRNO_AS_SCODE SCODE_FROM_ERRNO(errno) #define SCODE_CAST(x) ((SCODE)(x)) diff --git a/src/sysinput.c b/src/sysinput.c index 826a363..bf02ca7 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -1,6 +1,7 @@ #include #include #include +#include "scode.h" #include "log.h" #include "msg_queue.h" #include "gpio.h" @@ -9,12 +10,12 @@ PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; -static int last_bstate = 0; +static UINT32 last_bstate = 0; static void *input_thread(void *arg) { - int st, down, up, mask; - uintptr_t attr; + UINT32 st, down, up, mask; + UINT_PTR attr; while (running) { @@ -39,20 +40,24 @@ static void *input_thread(void *arg) return NULL; } -int Sys_enable_input(void) +HRESULT Sys_enable_input(void) { - int rc; + HRESULT rc = S_OK; + int threadrc; Sys_Queue = Mq_alloc(64); if (!Sys_Queue) { Log(LFATAL, "Unable to allocate system message queue."); - return 1; + return E_OUTOFMEMORY; } running = 1; - rc = pthread_create(&ithread, NULL, input_thread, NULL); - if (rc != 0) - Log(LFATAL, "Unable to start system input thread (%d).", rc); + threadrc = pthread_create(&ithread, NULL, input_thread, NULL); + if (threadrc != 0) + { + rc = SCODE_FROM_ERRNO(threadrc); + Log(LFATAL, "Unable to start system input thread (%08X).", rc); + } return rc; } diff --git a/src/sysinput.h b/src/sysinput.h index fb01f36..60b7833 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -1,11 +1,12 @@ #ifndef __SYSINPUT_H_INCLUDED #define __SYSINPUT_H_INCLUDED +#include "wintype.h" #include "msg_queue.h" extern PMSG_QUEUE Sys_Queue; -extern int Sys_enable_input(void); +extern HRESULT Sys_enable_input(void); extern void Sys_disable_input(void); #endif /* __SYSINPUT_H_INCLUDED */ From 4f879c4d6dbb895c4d43d8ce6fe08e6b796194a5 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:27:52 -0700 Subject: [PATCH 025/162] add splash screen graphic as PNG and conversion program --- buildutils/Makefile | 7 + buildutils/mksplash.c | 304 ++++++++++++++++++++++++++++++++++++++++++ src/splash.png | Bin 0 -> 12679 bytes 3 files changed, 311 insertions(+) create mode 100644 buildutils/Makefile create mode 100644 buildutils/mksplash.c create mode 100644 src/splash.png diff --git a/buildutils/Makefile b/buildutils/Makefile new file mode 100644 index 0000000..91c309c --- /dev/null +++ b/buildutils/Makefile @@ -0,0 +1,7 @@ +ALL: mksplash + +mksplash: mksplash.c + gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng12 -lz + +clean: + rm -f *.o mksplash diff --git a/buildutils/mksplash.c b/buildutils/mksplash.c new file mode 100644 index 0000000..b32bfb0 --- /dev/null +++ b/buildutils/mksplash.c @@ -0,0 +1,304 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef png_jmpbuf +#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#endif + +png_structp png_ptr = NULL; +png_infop info_ptr = NULL; + +png_uint_32 width, height; +int bit_depth, color_type; +uch *image_data = NULL; + +/* returns 0 on success, -1 on error */ +int readpng_init(const char *fname, FILE *infile, ulg *pWidth, ulg *pHeight) +{ + uch sig[8]; + + fread(sig, 1, 8, infile); + if (!png_check_sig(sig, 8)) + { + fprintf(stderr, "%s: invalid PNG file signature\n", fname); + return -1; + } + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + fprintf(stderr, "%s: out of memory\n", fname); + return -1; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, NULL, NULL); + fprintf(stderr, "%s: out of memory\n", fname); + return -1; + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fprintf(stderr, "%s: bad header in PNG image\n", fname); + return -1; + } + + png_init_io(png_ptr, infile); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + *pWidth = width; + *pHeight = height; + + return 0; +} + +/* returns -1 on error, 0 otherwise (out vars not touched if we can't find background */ +int readpng_get_bgcolor(const char *fname, uch *red, uch *green, uch *blue) +{ + png_color_16p pBackground; + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fprintf(stderr, "%s: unspecified error in background reading\n", fname); + return -1; + } + + if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) + return 0; + + png_get_bKGD(png_ptr, info_ptr, &pBackground); + + if (bit_depth == 16) + { + *red = pBackground->red >> 8; + *green = pBackground->green >> 8; + *blue = pBackground->blue >> 8; + } + else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + { + if (bit_depth == 1) + *red = *green = *blue = pBackground->gray ? 255 : 0; + else if (bit_depth == 2) + *red = *green = *blue = (255/3) * pBackground->gray; + else /* bit_depth == 4 */ + *red = *green = *blue = (255/15) * pBackground->gray; + } + else + { + *red = (uch)pBackground->red; + *green = (uch)pBackground->green; + *blue = (uch)pBackground->blue; + } + + return 0; +} + +/* display_exponent == LUT_exponent * CRT_exponent */ +uch *readpng_get_image(const char *fname, double display_exponent, int *pChannels, ulg *pRowbytes) +{ + double gamma; + png_uint_32 i, rowbytes; + png_bytepp row_pointers = NULL; + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fprintf(stderr, "%s: unspecified error in image data reading\n", fname); + return NULL; + } + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (bit_depth == 16) + png_set_strip_16(png_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + + if (png_get_gAMA(png_ptr, info_ptr, &gamma)) + png_set_gamma(png_ptr, display_exponent, gamma); + + png_read_update_info(png_ptr, info_ptr); + + *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); + *pChannels = (int)png_get_channels(png_ptr, info_ptr); + + if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + fprintf(stderr, "%s: could not allocate image buffer\n", fname); + return NULL; + } + + if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + free(image_data); + image_data = NULL; + fprintf(stderr, "%s: could not allocate image row buffer\n", fname); + return NULL; + } + + fprintf(stderr, "image %s: chans=%d rowbytes=%ld height=%ld\n", fname, *pChannels, + rowbytes, height); + + for (i = 0; i < height; ++i) + row_pointers[i] = image_data + i * rowbytes; + + png_read_image(png_ptr, row_pointers); + + free(row_pointers); + row_pointers = NULL; + + png_read_end(png_ptr, NULL); + + return image_data; +} + +void readpng_cleanup(int free_image_data) +{ + if (free_image_data && image_data) + { + free(image_data); + image_data = NULL; + } + + if (png_ptr && info_ptr) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_ptr = NULL; + info_ptr = NULL; + } +} + +int do_convert(const char *infilename, const char *outfilename) +{ + ulg image_width, image_height, image_rowbytes, row, i; + FILE *fpin; + uch *image_data, *src; + uint16_t bred, bgreen, bblue, buf; + int image_channels, fdout; + uch bg_red=0, bg_green=0, bg_blue=0, br, bg, bb, ba; + double display_exponent = 2.2; /* a guesstimate */ + + if (!(fpin = fopen(infilename, "rb"))) + { + fprintf(stderr, "%s: could not open file\n", infilename); + return -1; + } + + if (readpng_init(fpin, &image_width, &image_height)) + { + readpng_cleanup(1); + fclose(fpin); + return -1; + } + + if ((image_width != 320) || (image_height != 240)) + { + readpng_cleanup(1); + fclose(fpin); + fprintf(stderr, "%s: image is %lux%lu, should be 320x240\n", infilename, image_width, image_height); + return -1; + } + + if (readpng_get_bgcolor(infilename, &bg_red, &bg_green, &bg_blue)) + { + readpng_cleanup(1); + fclose(fpin); + return -1; + } + + image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes); + readpng_cleanup(0); + fclose(fpin); + if (!image_data) + return -1; + + if ((fdout = creat(outfilename, S_IREAD|S_IWRITE)) < 0) + { + free(image_data); + fprintf(stderr, "%s: could not open file\n", outfilename); + return -1; + } + + for (row = 0; row < image_height; ++row) + { + src = image_data + (row * image_rowbytes); + for (i = image_width; i > 0; --i) + { + if (image_channels == 3) + { + bred = *src++; + bgreen = *src++; + bblue = *src++; + } + else if (image_channels == 4) + { + br = *src++; + bg = *src++; + bb = *src++; + ba = *src++; + if (ba == 255) + { + bred = br; + bgreen = bg; + bblue = bb; + } + else if (ba == 0) + { + bred = bg_red; + bgreen = bg_green; + bblue = bg_blue; + } + else + { + alpha_composite(bred, br, ba, bg_red); + alpha_composite(bgreen, bg, ba, bg_green); + alpha_composite(bblue, bb, ba, bg_blue); + } + } + bred = (bred >> 3) & 0x1F; + bgreen = (bgreen >> 2) & 0x3F; + bblue = (bblue >> 3) & 0x1F; + buf = (bred << 11) | (bgreen << 5) | bblue; + if (write(fdout, &buf, sizeof(uint16_t)) < 0) + { + close(fdout); + free(image_data); + fprintf(stderr, "%s: error writing image data\n", outfilename); + return -1; + } + } + } + + close(fdout); + free(image_data); + return 0; +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) + { + fprintf(stderr, "usage: mksplash inputfile outputfile\n"); + return EXIT_FAILURE; + } + + if (do_convert(argv[1], argv[2])) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/src/splash.png b/src/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..f272d2f34f65143e24b6dd5c4d4cdb03c764bbc9 GIT binary patch literal 12679 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 literal 0 HcmV?d00001 From 667ac01f9281017818f00349db0805a8de052d78 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:29:11 -0700 Subject: [PATCH 026/162] changes to wintype.h so as not to collide with bcm2835.h --- src/wintype.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wintype.h b/src/wintype.h index 8fa5cd8..01a2401 100644 --- a/src/wintype.h +++ b/src/wintype.h @@ -133,8 +133,12 @@ typedef UINT64 TIMESTAMP; #define MAKEBOOL(val) ((val) ? TRUE : FALSE) #define OFFSETOF(struc, field) ((UINT_PTR)(&(((struc *)0)->field))) +#ifndef MIN #define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif +#ifndef MAX #define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif #define MAKEWORD(a, b) ((WORD)((((UINT_PTR)(a)) & 0xFF) | ((((UINT_PTR)(b)) & 0xFF) << 8))) #define MAKELONG(a, b) ((LONG)((((UINT_PTR)(a)) & 0xFFFF) | ((((UINT_PTR)(b)) & 0xFFFF) << 16))) From 2768155f4ece0bb5017ec8d39321a92e64a92353 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:36:51 -0700 Subject: [PATCH 027/162] fixed all the build errors --- .gitignore | 1 + buildutils/Makefile | 2 +- buildutils/mksplash.c | 18 +++++++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index d5e8893..b28b2d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ *.o src/upiwin +buildutils/mksplash diff --git a/buildutils/Makefile b/buildutils/Makefile index 91c309c..fb1c6ca 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,7 +1,7 @@ ALL: mksplash mksplash: mksplash.c - gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng12 -lz + gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng16 -lz clean: rm -f *.o mksplash diff --git a/buildutils/mksplash.c b/buildutils/mksplash.c index b32bfb0..62e3edc 100644 --- a/buildutils/mksplash.c +++ b/buildutils/mksplash.c @@ -7,6 +7,10 @@ #include #include +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + #ifndef png_jmpbuf #define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif @@ -152,7 +156,7 @@ uch *readpng_get_image(const char *fname, double display_exponent, int *pChannel return NULL; } - fprintf(stderr, "image %s: chans=%d rowbytes=%ld height=%ld\n", fname, *pChannels, + fprintf(stderr, "image %s: chans=%d rowbytes=%u height=%u\n", fname, *pChannels, rowbytes, height); for (i = 0; i < height; ++i) @@ -189,7 +193,7 @@ int do_convert(const char *infilename, const char *outfilename) ulg image_width, image_height, image_rowbytes, row, i; FILE *fpin; uch *image_data, *src; - uint16_t bred, bgreen, bblue, buf; + uint16_t bred = 0, bgreen = 0, bblue = 0, buf = 0; int image_channels, fdout; uch bg_red=0, bg_green=0, bg_blue=0, br, bg, bb, ba; double display_exponent = 2.2; /* a guesstimate */ @@ -200,7 +204,7 @@ int do_convert(const char *infilename, const char *outfilename) return -1; } - if (readpng_init(fpin, &image_width, &image_height)) + if (readpng_init(infilename, fpin, &image_width, &image_height)) { readpng_cleanup(1); fclose(fpin); @@ -222,7 +226,7 @@ int do_convert(const char *infilename, const char *outfilename) return -1; } - image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes); + image_data = readpng_get_image(infilename, display_exponent, &image_channels, &image_rowbytes); readpng_cleanup(0); fclose(fpin); if (!image_data) @@ -266,9 +270,9 @@ int do_convert(const char *infilename, const char *outfilename) } else { - alpha_composite(bred, br, ba, bg_red); - alpha_composite(bgreen, bg, ba, bg_green); - alpha_composite(bblue, bb, ba, bg_blue); + png_composite(bred, br, ba, bg_red); + png_composite(bgreen, bg, ba, bg_green); + png_composite(bblue, bb, ba, bg_blue); } } bred = (bred >> 3) & 0x1F; From 374f1d78eba0d124331ebfae1fe97647d24052d0 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:41:26 -0700 Subject: [PATCH 028/162] added the rules to create the splash screen data and the external references to the binary data --- src/Makefile | 8 +++++++- src/fbinit.c | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 4a6441b..30a6305 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o +OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o splash.o LIBS=-lbcm2835 -lpthread upiwin: $(OBJS) @@ -7,5 +7,11 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< +splash.o: splash.bin + ld -r -b binary --rename-section .data=.rodata,alloc,load,readonly,data,contents -o splash.o splash.bin + +splash.bin: splash.png ../buildutils/mksplash + ../buildutils/mksplash splash.png splash.bin + clean: rm -f upiwin *.o *~ diff --git a/src/fbinit.c b/src/fbinit.c index 82f2af4..79a2cde 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -10,6 +10,11 @@ #include "fbinit.h" #include "scode.h" +/* references to splash screen data in splash.o/splash.bin */ +extern uint8_t _binary_splash_start[]; +extern uint8_t _binary_splash_end; +extern uint8_t _binary_splash_size; + static int fb_fd = -1; static FBINFO local_info; From 6538ddeb531012337451ad91cd6dfcd382fc8fd3 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:51:41 -0700 Subject: [PATCH 029/162] fixed up the makefile and the symbol references in fbinit.c --- .gitignore | 1 + src/Makefile | 4 ++-- src/fbinit.c | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index b28b2d3..eff2a80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *~ *.o src/upiwin +src/splash.bin buildutils/mksplash diff --git a/src/Makefile b/src/Makefile index 30a6305..381f052 100644 --- a/src/Makefile +++ b/src/Makefile @@ -8,10 +8,10 @@ upiwin: $(OBJS) gcc -c $(CFLAGS) $< splash.o: splash.bin - ld -r -b binary --rename-section .data=.rodata,alloc,load,readonly,data,contents -o splash.o splash.bin + objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o splash.bin: splash.png ../buildutils/mksplash ../buildutils/mksplash splash.png splash.bin clean: - rm -f upiwin *.o *~ + rm -f upiwin *.o splash.bin *~ diff --git a/src/fbinit.c b/src/fbinit.c index 79a2cde..c77706d 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -11,9 +11,9 @@ #include "scode.h" /* references to splash screen data in splash.o/splash.bin */ -extern uint8_t _binary_splash_start[]; -extern uint8_t _binary_splash_end; -extern uint8_t _binary_splash_size; +extern uint8_t _binary_splash_bin_start[]; +extern uint8_t _binary_splash_bin_end; +extern uint8_t _binary_splash_bin_size; static int fb_fd = -1; From 2663de9d4219b12641daa048a418cc4b8f8bddda Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 20:57:44 -0700 Subject: [PATCH 030/162] code to actually display the splash screen --- src/fbinit.c | 8 ++++++++ src/fbinit.h | 1 + src/main.c | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/src/fbinit.c b/src/fbinit.c index c77706d..a25dfd0 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -84,6 +84,9 @@ HRESULT Fb_setup(void) return hr; } + /* display the splash screen */ + memcpy(Fb_ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size)); + /* additional setup here */ return hr; @@ -100,3 +103,8 @@ void Fb_cleanup(void) close(fb_fd); fb_fd = -1; } + +void Fb_clear(void) +{ + memset(Fb_Ptr, 0, local_info.screenbytes); +} diff --git a/src/fbinit.h b/src/fbinit.h index 2b5d256..11f4d8b 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -28,5 +28,6 @@ extern UINT16 *Fb_Ptr; extern HRESULT Fb_setup(void); extern void Fb_cleanup(void); +extern void Fb_clear(void); #endif /* __FBINIT_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 915a990..1d8525b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include "scode.h" #include "gpio.h" #include "log.h" @@ -39,7 +40,10 @@ int main(int argc, char *argv[]) if (FAILED(Sys_enable_input())) return EXIT_FAILURE; atexit(Sys_disable_input); + Log(LINFO, "Pausing at startup."); + sleep(5); /* wait to show off splash screen */ + Fb_clear(); /* temporary drawing here */ do_draw(); From 15d85ce2eb4c44d86566ab01ad844574173db8c9 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 21:15:44 -0700 Subject: [PATCH 031/162] compile errors fixed --- src/fbinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fbinit.c b/src/fbinit.c index a25dfd0..f6664dc 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -85,7 +85,7 @@ HRESULT Fb_setup(void) } /* display the splash screen */ - memcpy(Fb_ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size)); + memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size)); /* additional setup here */ From 8b7bd918175677002ee232c6bffc4041a7f3e144 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 21:25:15 -0700 Subject: [PATCH 032/162] added debounce logic for hardware buttons --- src/sysinput.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sysinput.c b/src/sysinput.c index bf02ca7..b5688ac 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -1,10 +1,14 @@ #include #include +#include #include #include "scode.h" #include "log.h" #include "msg_queue.h" #include "gpio.h" +#include "time_func.h" + +#define DEBOUNCE_BUTTON_MSEC 350 PMSG_QUEUE Sys_Queue = NULL; @@ -16,6 +20,10 @@ static void *input_thread(void *arg) { UINT32 st, down, up, mask; UINT_PTR attr; + TIMESTAMP now; + TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; + + memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP)); while (running) { @@ -23,12 +31,18 @@ static void *input_thread(void *arg) st = Gpio_read_buttons(); if (st != last_bstate) { + now = Time_since_start(); up = last_bstate & ~st; down = st & ~last_bstate; for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { + if (now < button_event_ok[attr - 1]) + continue; if (up & mask) + { + button_event_ok[attr - 1] = now + DEBOUNCE_BUTTON_MSEC; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + } else if (down & mask) Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); } From 5e2269bf2b8a8299f8ef12dcb13fc8fa2a3c83f9 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 21:28:16 -0700 Subject: [PATCH 033/162] a value of 100 milliseconds is adequate for the debounce constant --- src/sysinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysinput.c b/src/sysinput.c index b5688ac..59c503b 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -8,7 +8,7 @@ #include "gpio.h" #include "time_func.h" -#define DEBOUNCE_BUTTON_MSEC 350 +#define DEBOUNCE_BUTTON_MSEC 100 PMSG_QUEUE Sys_Queue = NULL; From e2946fc714ff93820e278198d8d5e573e037c767 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 22:06:05 -0700 Subject: [PATCH 034/162] added global configuration data block and our own "atexit" type mechanism that doesn't depend on enough free slots in the C library --- src/config.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ src/config.h | 19 ++++++++++++++ src/fbinit.c | 30 ++++++++++++--------- src/fbinit.h | 1 - src/gpio.c | 50 +++++++++++++++++++---------------- src/gpio.h | 1 - src/main.c | 8 +++--- src/msg_queue.c | 2 +- src/sysinput.c | 28 +++++++++++--------- src/sysinput.h | 1 - 10 files changed, 155 insertions(+), 55 deletions(-) create mode 100644 src/config.c create mode 100644 src/config.h diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..f16c844 --- /dev/null +++ b/src/config.c @@ -0,0 +1,70 @@ +#include +#include "config.h" +#include "log.h" + +#define EXITFUNCBLOCK_FUNCCOUNT 64 + +typedef struct tagEXITFUNCBLOCK +{ + struct tagEXITFUNCBLOCK *next; + int num_funcs; + PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT]; +} EXITFUNCBLOCK, *PEXITFUNCBLOCK; + +/* The global configuration data */ +GLOBAL_CONFIG Gconfig; + +static PEXITFUNCBLOCK exitfuncs = NULL; + +static void run_exit_funcs(void) +{ + int i; + PEXITFUNCBLOCK p; + + while (exitfuncs) + { + p = exitfuncs; + exitfuncs = p->next; + for (i = p->num_funcs - 1; i >= 0; i++) + (*(p->funcs[i]))(); + free(p); + } +} + +static void init_defaults(void) +{ + Gconfig.framebuffer_device = "/dev/fb1"; + Gconfig.button_debounce = 100; + Gconfig.sys_mq_length = 64; +} + +HRESULT Config_setup(void) +{ + if (atexit(run_exit_funcs)) + { + Log(LFATAL, "Unable to set up exit function mechanism"); + return E_FAIL; + } + init_defaults(); + return S_OK; +} + +HRESULT Config_exitfunc(PEXITFUNC pfn) +{ + PEXITFUNCBLOCK p; + + if (!exitfuncs || (exitfuncs->num_funcs == EXITFUNCBLOCK_FUNCCOUNT)) + { + p = (PEXITFUNCBLOCK)malloc(sizeof(EXITFUNCBLOCK)); + if (!p) + { + Log(LERROR, "unable to allocate another exit function block"); + return E_OUTOFMEMORY; + } + p->next = exitfuncs; + p->num_funcs = 0; + exitfuncs = p; + } + exitfuncs->funcs[exitfuncs->num_funcs++] = pfn; + return S_OK; +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..b716af5 --- /dev/null +++ b/src/config.h @@ -0,0 +1,19 @@ +#ifndef __CONFIG_H_INCLUDED +#define __CONFIG_H_INCLUDED + +#include "wintype.h" + +typedef void (*PEXITFUNC)(void); + +typedef struct tagGLOBAL_CONFIG { + PCSTR framebuffer_device; + UINT32 button_debounce; + UINT32 sys_mq_length; +} GLOBAL_CONFIG; + +extern GLOBAL_CONFIG Gconfig; + +extern HRESULT Config_setup(void); +extern HRESULT Config_exitfunc(PEXITFUNC pfn); + +#endif /* __CONFIG_H_INCLUDED */ diff --git a/src/fbinit.c b/src/fbinit.c index f6664dc..24cbe7e 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -6,6 +6,7 @@ #include #include #include +#include "config.h" #include "log.h" #include "fbinit.h" #include "scode.h" @@ -27,13 +28,25 @@ inline static UINT16 makemask(unsigned offset, unsigned length) return (UINT16)(((1 << length) - 1) << offset); } +static void do_cleanup(void) +{ + /* additional cleanup here */ + + memset(Fb_Ptr, 0, local_info.screenbytes); + munmap((void *)Fb_Ptr, local_info.screenbytes); + Fb_Ptr = NULL; + + close(fb_fd); + fb_fd = -1; +} + HRESULT Fb_setup(void) { HRESULT hr = S_OK; struct fb_fix_screeninfo fixed; struct fb_var_screeninfo var; - fb_fd = open("/dev/fb1", O_RDWR); + fb_fd = open(Gconfig.framebuffer_device, O_RDWR); if (fb_fd == -1) { hr = ERRNO_AS_SCODE; @@ -89,21 +102,12 @@ HRESULT Fb_setup(void) /* additional setup here */ + hr = Config_exitfunc(do_cleanup); + if (FAILED(hr)) + do_cleanup(); return hr; } -void Fb_cleanup(void) -{ - /* additional cleanup here */ - - memset(Fb_Ptr, 0, local_info.screenbytes); - munmap((void *)Fb_Ptr, local_info.screenbytes); - Fb_Ptr = NULL; - - close(fb_fd); - fb_fd = -1; -} - void Fb_clear(void) { memset(Fb_Ptr, 0, local_info.screenbytes); diff --git a/src/fbinit.h b/src/fbinit.h index 11f4d8b..8638317 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -27,7 +27,6 @@ extern PCFBINFO Fb_Info; extern UINT16 *Fb_Ptr; extern HRESULT Fb_setup(void); -extern void Fb_cleanup(void); extern void Fb_clear(void); #endif /* __FBINIT_H_INCLUDED */ diff --git a/src/gpio.c b/src/gpio.c index 13255e9..b4e8758 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,5 +1,6 @@ #include #include +#include "config.h" #include "log.h" #include "scode.h" #include "gpio.h" @@ -12,8 +13,31 @@ #define PWM_BACKLIGHT 0 +static void do_cleanup(void) +{ + /* close down the backlight lines */ + bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 0); + bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_INPT); + + /* close down the button lines */ + bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT); + + if (!bcm2835_close()) + Log(LWARN, "Closing BCM2835 library failed"); +} + HRESULT Gpio_setup(void) { + HRESULT hr; + if (!bcm2835_init()) { Log(LFATAL, "Error initializing BCM2835 library"); @@ -38,28 +62,10 @@ HRESULT Gpio_setup(void) bcm2835_pwm_set_range(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX + 1); bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX); - return S_OK; -} - -void Gpio_cleanup(void) -{ - /* close down the backlight lines */ - bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 0); - bcm2835_gpio_set_pud(GLINE_BACKLIGHT, BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_fsel(GLINE_BACKLIGHT, BCM2835_GPIO_FSEL_INPT); - - /* close down the button lines */ - bcm2835_gpio_set_pud(GLINE_BUTTON1, BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_fsel(GLINE_BUTTON1, BCM2835_GPIO_FSEL_INPT); - bcm2835_gpio_set_pud(GLINE_BUTTON2, BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_fsel(GLINE_BUTTON2, BCM2835_GPIO_FSEL_INPT); - bcm2835_gpio_set_pud(GLINE_BUTTON3, BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_fsel(GLINE_BUTTON3, BCM2835_GPIO_FSEL_INPT); - bcm2835_gpio_set_pud(GLINE_BUTTON4, BCM2835_GPIO_PUD_OFF); - bcm2835_gpio_fsel(GLINE_BUTTON4, BCM2835_GPIO_FSEL_INPT); - - if (!bcm2835_close()) - Log(LWARN, "Closing BCM2835 library failed"); + hr = Config_exitfunc(do_cleanup); + if (FAILED(hr)) + do_cleanup(); + return hr; } UINT32 Gpio_read_buttons(void) diff --git a/src/gpio.h b/src/gpio.h index 38d5555..24c7398 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -13,7 +13,6 @@ #define GSB_BACKLIGHT_MAX 1023 extern HRESULT Gpio_setup(void); -extern void Gpio_cleanup(void); extern UINT32 Gpio_read_buttons(void); extern void Gpio_set_backlight(UINT32 level); diff --git a/src/main.c b/src/main.c index 1d8525b..d56555b 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include #include #include "scode.h" +#include "config.h" #include "gpio.h" #include "log.h" #include "fbinit.h" @@ -29,17 +30,16 @@ int main(int argc, char *argv[]) int running = 1; MSG msg; char *tmp; - + Time_init(); + if (FAILED(Config_setup())) + return EXIT_FAILURE; if (FAILED(Fb_setup())) return EXIT_FAILURE; - atexit(Fb_cleanup); if (FAILED(Gpio_setup())) return EXIT_FAILURE; - atexit(Gpio_cleanup); if (FAILED(Sys_enable_input())) return EXIT_FAILURE; - atexit(Sys_disable_input); Log(LINFO, "Pausing at startup."); sleep(5); /* wait to show off splash screen */ diff --git a/src/msg_queue.c b/src/msg_queue.c index add55ae..fbe483e 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -56,7 +56,7 @@ void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *at if (nattrs > MSG_ATTRCOUNT) nattrs = MSG_ATTRCOUNT; if (nattrs > 0) - memcpy(&(tmpmsg.attrs), attrs, sizeof(uintptr_t) * nattrs); + memcpy(&(tmpmsg.attrs), attrs, sizeof(UINT_PTR) * nattrs); tmpmsg.timestamp = Time_since_start(); post_internal(queue, &tmpmsg); } diff --git a/src/sysinput.c b/src/sysinput.c index 59c503b..12aca3f 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -8,8 +8,6 @@ #include "gpio.h" #include "time_func.h" -#define DEBOUNCE_BUTTON_MSEC 100 - PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; @@ -40,7 +38,7 @@ static void *input_thread(void *arg) continue; if (up & mask) { - button_event_ok[attr - 1] = now + DEBOUNCE_BUTTON_MSEC; + button_event_ok[attr - 1] = now + Gconfig.button_debounce; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); } else if (down & mask) @@ -54,12 +52,20 @@ static void *input_thread(void *arg) return NULL; } +static void do_disable_input(void) +{ + running = 0; + pthread_join(ithread, NULL); + Mq_destroy(Sys_Queue); + Sys_Queue = NULL; +} + HRESULT Sys_enable_input(void) { HRESULT rc = S_OK; int threadrc; - Sys_Queue = Mq_alloc(64); + Sys_Queue = Mq_alloc(Gconfig.sys_mq_length); if (!Sys_Queue) { Log(LFATAL, "Unable to allocate system message queue."); @@ -72,13 +78,11 @@ HRESULT Sys_enable_input(void) rc = SCODE_FROM_ERRNO(threadrc); Log(LFATAL, "Unable to start system input thread (%08X).", rc); } + if (SUCCEEDED(rc)) + { + rc = Config_exitfunc(do_disable_input); + if (FAILED(rc)) + do_disable_input(); + } return rc; } - -void Sys_disable_input(void) -{ - running = 0; - pthread_join(ithread, NULL); - Mq_destroy(Sys_Queue); - Sys_Queue = NULL; -} diff --git a/src/sysinput.h b/src/sysinput.h index 60b7833..8f316d0 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -7,6 +7,5 @@ extern PMSG_QUEUE Sys_Queue; extern HRESULT Sys_enable_input(void); -extern void Sys_disable_input(void); #endif /* __SYSINPUT_H_INCLUDED */ From dde3bda516bb4d84922e4068c77ee4b4b7492342 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 22:37:20 -0700 Subject: [PATCH 035/162] added command line parsing for options --- src/config.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/config.h | 2 +- src/main.c | 6 ++++- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index f16c844..1ede164 100644 --- a/src/config.c +++ b/src/config.c @@ -1,7 +1,25 @@ #include +#include +#include #include "config.h" #include "log.h" +static const struct option long_options[] = { + {"framebuffer", required_argument, 0, 'F'}, + {"help", no_argument, 0, 'h'}, + { NULL, 0, 0, 0 } +}; + +static const char *short_options = "F:h"; + +static const char *helptext = + "UPIWIN - Micro Pi Windows server program\n\n" + "Usage: upiwin [options] scriptname [scriptargs]\n\n" + "Available options:\n" + " -F,--framebuffer [devname] - Specifies the framebuffer device name\n" + " -h,--help - Displays this help message.\n" + ""; + #define EXITFUNCBLOCK_FUNCCOUNT 64 typedef struct tagEXITFUNCBLOCK @@ -38,14 +56,70 @@ static void init_defaults(void) Gconfig.sys_mq_length = 64; } -HRESULT Config_setup(void) +static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) { + int c; + PSTR pstr; + BOOL help = FALSE; + + memset(parsed, 0, sizeof(GLOBAL_CONFIG)); + for (;;) + { + c = getopt_long(argc, argv, short_options, long_options, NULL); + if (c==-1) + break; + switch (c) + { + case 'F': + pstr = strdup(optarg); + if (!pstr) + { + Log(LERROR, "Out of memory in parse_cmdline"); + return E_OUTOFMEMORY; + } + if (parsed->framebuffer_device) + free(parsed->framebuffer_device); + parsed->framebuffer_device = pstr; + break; + + case 'h': + help = TRUE; + break; + + default: + fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c); + return E_UNEXPECTED; + } + } + if (help) + { + fputs(helptext, stdout); + return S_FALSE; + } + return S_OK; +} + +static void overlay_config(GLOBAL_CONFIG *p) +{ + if (p->framebuffer_device) + Gconfig.framebuffer_device = p->framebuffer_device; +} + +HRESULT Config_setup(int argc, char *argv[]) +{ + HRESULT hr; + GLOBAL_CONFIG from_commandline; + if (atexit(run_exit_funcs)) { Log(LFATAL, "Unable to set up exit function mechanism"); return E_FAIL; } init_defaults(); + hr = parse_cmdline(argc, argv, &from_commandline); + if (hr != S_OK) + return hr; + overlay_config(&from_commandline) return S_OK; } diff --git a/src/config.h b/src/config.h index b716af5..4916612 100644 --- a/src/config.h +++ b/src/config.h @@ -13,7 +13,7 @@ typedef struct tagGLOBAL_CONFIG { extern GLOBAL_CONFIG Gconfig; -extern HRESULT Config_setup(void); +extern HRESULT Config_setup(int argc, char *argv[]); extern HRESULT Config_exitfunc(PEXITFUNC pfn); #endif /* __CONFIG_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index d56555b..8716e56 100644 --- a/src/main.c +++ b/src/main.c @@ -27,13 +27,17 @@ static void do_draw(void) int main(int argc, char *argv[]) { + HRESULT hr; int running = 1; MSG msg; char *tmp; Time_init(); - if (FAILED(Config_setup())) + hr = Config_setup(argc, argv); + if (FAILED(hr)) return EXIT_FAILURE; + else if (hr != S_OK) + return EXIT_SUCCESS; if (FAILED(Fb_setup())) return EXIT_FAILURE; if (FAILED(Gpio_setup())) From cfc067786aaa35eaa723e39e16f1abd024156e30 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 22:45:01 -0700 Subject: [PATCH 036/162] fixed compile errors and makefile error omitting config.o --- src/Makefile | 2 +- src/config.c | 7 +++++-- src/sysinput.c | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 381f052..26bfb95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o splash.o +OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lbcm2835 -lpthread upiwin: $(OBJS) diff --git a/src/config.c b/src/config.c index 1ede164..89cdbfc 100644 --- a/src/config.c +++ b/src/config.c @@ -1,7 +1,10 @@ +#include #include #include #include +#include #include "config.h" +#include "scode.h" #include "log.h" static const struct option long_options[] = { @@ -78,7 +81,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) return E_OUTOFMEMORY; } if (parsed->framebuffer_device) - free(parsed->framebuffer_device); + free((PVOID)(parsed->framebuffer_device)); parsed->framebuffer_device = pstr; break; @@ -119,7 +122,7 @@ HRESULT Config_setup(int argc, char *argv[]) hr = parse_cmdline(argc, argv, &from_commandline); if (hr != S_OK) return hr; - overlay_config(&from_commandline) + overlay_config(&from_commandline); return S_OK; } diff --git a/src/sysinput.c b/src/sysinput.c index 12aca3f..2cb2aff 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -3,6 +3,7 @@ #include #include #include "scode.h" +#include "config.h" #include "log.h" #include "msg_queue.h" #include "gpio.h" From 7b1c8dd5bbdfd62f32156464755ef7bd4bb20b15 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 23:26:13 -0700 Subject: [PATCH 037/162] implemented frame buffer primitives --- src/Makefile | 2 +- src/fbprimitive.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++ src/fbprimitive.h | 20 ++++++++ src/main.c | 19 +++----- src/wintype.h | 1 + 5 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 src/fbprimitive.c create mode 100644 src/fbprimitive.h diff --git a/src/Makefile b/src/Makefile index 26bfb95..c1558d4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o fbinit.o log.o gpio.o msg_queue.o time_func.o config.o splash.o +OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lbcm2835 -lpthread upiwin: $(OBJS) diff --git a/src/fbprimitive.c b/src/fbprimitive.c new file mode 100644 index 0000000..2292f48 --- /dev/null +++ b/src/fbprimitive.c @@ -0,0 +1,113 @@ +#include "wintype.h" +#include "fbinit.h" + +inline static PUINT16 loc_from_coords(INT32 x, INT32 y) +{ + return Fb_Ptr + (y * Fb_Info->width) + x; +} + +UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor) +{ + UINT16 rc; + PUINT16 loc = loc_from_coords(x, y); + + rc = *loc; + if (xor) + *loc ^= color; + else + *loc = color; + return rc; +} + +void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) +{ + INT32 tmp; + INT32 dx = x2 - x1; + INT32 dy = y2 - y1; + + if (ABS(dx) < ABS(dy)) + { + if (y1 > y2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + x1 <<= 16; + dx = (dx << 16) / dy; + while (y1 <= y2) + { + Fb_setpixel(x1 >> 16, y1, color, xor); + x1 += dx; + y1++; + } + } + else + { + if (x1 > x2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + y1 <<= 16; + dy = dx ? (dy << 16) / dx : 0; + while (x1 <= x2) + { + Fb_setpixel(x1, y1 >> 16, color, xor); + y1 += dy; + x1++; + } + } +} + +void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) +{ + FB_line(x1, y1, x2, y1, color, xor); + FB_line(x2, y1 + 1, x2, y2 - 1, color, xor); + FB_line(x1, y2, x2, y2, color, xor); + FB_line(x1, y1 + 1, x1, y2 - 1, color, xor); +} + +void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) +{ + INT32 tmp; + PUINT16 ps, p; + + if (x1 > x2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 > y2) + { + tmp = y1; + y1 = y2; + y2 = tmp; + } + + ps = loc_from_coords(x1, y1); + for (; y1 <= y2; y1++) + { + p = ps; + for (tmp = x1; tmp <= x2; tmp++) + { + if (xor) + *p++ ^= color; + else + *p++ = color; + } + ps += Fb_Info->width; + } +} diff --git a/src/fbprimitive.h b/src/fbprimitive.h new file mode 100644 index 0000000..fddd6c8 --- /dev/null +++ b/src/fbprimitive.h @@ -0,0 +1,20 @@ +#ifndef __FBPRIMITIVE_H_INCLUDED +#define __FBPRIMITIVE_H_INCLUDED + +#include "wintype.h" + +#define FBPRIMCLR_BLACK 0x0000 +#define FBPRIMCLR_RED 0xF800 +#define FBPRIMCLR_GREEN 0x07E0 +#define FBPRIMCLR_BLUE 0x001F +#define FBPRIMCLR_YELLOW 0xFFE0 +#define FBPRIMCLR_CYAN 0x07FF +#define FBPRIMCLR_MAGENTA 0xF81F +#define FBPRIMCLR_WHITE 0xFFFF + +extern UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor); +extern void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); +extern void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); +extern void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); + +#endif /* __FBPRIMITIVE_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 8716e56..bd939e9 100644 --- a/src/main.c +++ b/src/main.c @@ -6,23 +6,18 @@ #include "gpio.h" #include "log.h" #include "fbinit.h" +#include "fbprimitive.h" #include "time_func.h" #include "sysinput.h" static void do_draw(void) { - /* - tmp = (char *)Fb_Ptr; - memset(tmp, 0xFF, Fb_Info->screenbytes / 2); - memset(tmp + (Fb_Info->screenbytes / 2), 0x1B, Fb_Info->screenbytes / 2); - */ - UINT16 pixel = Fb_Info->green_mask; - unsigned npix = Fb_Info->screenbytes / sizeof(UINT16); - UINT16 *p = Fb_Ptr; - unsigned i; - - for (i=0; i (y)) ? (x) : (y)) #endif +#define ABS(v) ((v) < 0 ? -(v) : (v)) #define MAKEWORD(a, b) ((WORD)((((UINT_PTR)(a)) & 0xFF) | ((((UINT_PTR)(b)) & 0xFF) << 8))) #define MAKELONG(a, b) ((LONG)((((UINT_PTR)(a)) & 0xFFFF) | ((((UINT_PTR)(b)) & 0xFFFF) << 16))) From 82ca8371e64a9cc833aade768fe9b9cdc1092591 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 23:34:34 -0700 Subject: [PATCH 038/162] fixed compile errors and a segfault on exit --- src/Makefile | 1 + src/config.c | 5 +++-- src/fbprimitive.c | 8 ++++---- src/main.c | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Makefile b/src/Makefile index c1558d4..b23af1d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,6 @@ OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lbcm2835 -lpthread +CFLAGS=-g upiwin: $(OBJS) gcc -o upiwin $(OBJS) $(LIBS) diff --git a/src/config.c b/src/config.c index 89cdbfc..4b6dd20 100644 --- a/src/config.c +++ b/src/config.c @@ -46,8 +46,9 @@ static void run_exit_funcs(void) { p = exitfuncs; exitfuncs = p->next; - for (i = p->num_funcs - 1; i >= 0; i++) - (*(p->funcs[i]))(); + for (i = p->num_funcs - 1; i >= 0; i--) + if (p->funcs[i]) + (*(p->funcs[i]))(); free(p); } } diff --git a/src/fbprimitive.c b/src/fbprimitive.c index 2292f48..805dcd4 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -73,10 +73,10 @@ void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) { - FB_line(x1, y1, x2, y1, color, xor); - FB_line(x2, y1 + 1, x2, y2 - 1, color, xor); - FB_line(x1, y2, x2, y2, color, xor); - FB_line(x1, y1 + 1, x1, y2 - 1, color, xor); + Fb_line(x1, y1, x2, y1, color, xor); + Fb_line(x2, y1 + 1, x2, y2 - 1, color, xor); + Fb_line(x1, y2, x2, y2, color, xor); + Fb_line(x1, y1 + 1, x1, y2 - 1, color, xor); } void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) diff --git a/src/main.c b/src/main.c index bd939e9..414f931 100644 --- a/src/main.c +++ b/src/main.c @@ -14,10 +14,10 @@ static void do_draw(void) { Fb_filled_rectangle(10, 10, 50, 50, FBPRIMCLR_RED, FALSE); Fb_filled_rectangle(60, 10, 100, 50, FBPRIMCLR_GREEN, FALSE); - Fb_filled_rectangle(110, 10, 160, 50, FBPRIMCLR_BLUE, FALSE); + Fb_filled_rectangle(110, 10, 150, 50, FBPRIMCLR_BLUE, FALSE); Fb_filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, FALSE); Fb_filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, FALSE); - Fb_filled_rectangle(110, 60, 160, 100, FBPRIMCLR_YELLOW, FALSE); + Fb_filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, FALSE); } int main(int argc, char *argv[]) From 0dc56d49e55705de9152e222ed7fdc48c0b2c598 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 6 Dec 2019 23:46:21 -0700 Subject: [PATCH 039/162] added the ASSERT and VERIFY macros to logging to help detect problems --- src/Makefile | 2 +- src/config.c | 6 ++++-- src/log.c | 5 +++++ src/log.h | 12 ++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index b23af1d..b9fd929 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lbcm2835 -lpthread -CFLAGS=-g +CFLAGS=-g -O -DDEBUG_ASSERT upiwin: $(OBJS) gcc -o upiwin $(OBJS) $(LIBS) diff --git a/src/config.c b/src/config.c index 4b6dd20..e940919 100644 --- a/src/config.c +++ b/src/config.c @@ -47,8 +47,10 @@ static void run_exit_funcs(void) p = exitfuncs; exitfuncs = p->next; for (i = p->num_funcs - 1; i >= 0; i--) - if (p->funcs[i]) - (*(p->funcs[i]))(); + { + ASSERT(p->funcs[i]); + (*(p->funcs[i]))(); + } free(p); } } diff --git a/src/log.c b/src/log.c index de98b14..81afc30 100644 --- a/src/log.c +++ b/src/log.c @@ -23,3 +23,8 @@ void Log(int level, const char *format, ...) strftime(timestamp, 32, "%F %T", &tm); printf("%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); } + +void Log_assert_failed(const char *test, const char *file, int line) +{ + Log(LERROR, "ASSERT FAILED: %s at %s:%d", test, file, line); +} diff --git a/src/log.h b/src/log.h index 8c040b8..82145f5 100644 --- a/src/log.h +++ b/src/log.h @@ -8,5 +8,17 @@ #define LDEBUG 4 extern void Log(int level, const char *format, ...); +extern void Log_assert_failed(const char *test, const char *file, int line); + +#define THIS_FILE __FILE__ +#define DECLARE_THIS_FILE() static const char THIS_FILE[] = __FILE__ + +#ifdef DEBUG_ASSERT +#define ASSERT(x) ((x) ? (void)0 : Log_assert_failed(#x, THIS_FILE, __LINE__)) +#define VERIFY(x) ASSERT(x) +#else +#define ASSERT(x) ((void)0) +#define VERIFY(x) ((void)(x)) +#endif #endif /* __LOG_H_INCLUDED */ From dfe9991496e3097c10fce205132c0d65e9cb22a8 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 00:46:27 -0700 Subject: [PATCH 040/162] implemented the touchscreen device events --- src/config.c | 19 ++++++- src/config.h | 1 + src/main.c | 17 ++++++ src/msg.h | 4 ++ src/msg_queue.c | 3 +- src/msg_queue.h | 5 +- src/sysinput.c | 138 +++++++++++++++++++++++++++++++++++++++--------- 7 files changed, 158 insertions(+), 29 deletions(-) diff --git a/src/config.c b/src/config.c index e940919..8aecc61 100644 --- a/src/config.c +++ b/src/config.c @@ -10,10 +10,11 @@ static const struct option long_options[] = { {"framebuffer", required_argument, 0, 'F'}, {"help", no_argument, 0, 'h'}, + {"touchscreen", required_argument, 0, 'T'}, { NULL, 0, 0, 0 } }; -static const char *short_options = "F:h"; +static const char *short_options = "F:hT:"; static const char *helptext = "UPIWIN - Micro Pi Windows server program\n\n" @@ -21,6 +22,7 @@ static const char *helptext = "Available options:\n" " -F,--framebuffer [devname] - Specifies the framebuffer device name\n" " -h,--help - Displays this help message.\n" + " -T,--touchscreen - Specifies the touchscreen device name\n" ""; #define EXITFUNCBLOCK_FUNCCOUNT 64 @@ -58,6 +60,7 @@ static void run_exit_funcs(void) static void init_defaults(void) { Gconfig.framebuffer_device = "/dev/fb1"; + Gconfig.touchscreen_device = "/dev/input/touchscreen"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; } @@ -92,6 +95,18 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) help = TRUE; break; + case 'T': + pstr = strdup(optarg); + if (!pstr) + { + Log(LERROR, "Out of memory in parse_cmdline"); + return E_OUTOFMEMORY; + } + if (parsed->touchscreen_device) + free((PVOID)(parsed->touchscreen_device)); + parsed->touchscreen_device = pstr; + break; + default: fprintf(stderr, "%s: unexpected option -%c\n", argv[0], c); return E_UNEXPECTED; @@ -109,6 +124,8 @@ static void overlay_config(GLOBAL_CONFIG *p) { if (p->framebuffer_device) Gconfig.framebuffer_device = p->framebuffer_device; + if (p->touchscreen_device) + Gconfig.touchscreen_device = p->touchscreen_device; } HRESULT Config_setup(int argc, char *argv[]) diff --git a/src/config.h b/src/config.h index 4916612..3955d9c 100644 --- a/src/config.h +++ b/src/config.h @@ -7,6 +7,7 @@ typedef void (*PEXITFUNC)(void); typedef struct tagGLOBAL_CONFIG { PCSTR framebuffer_device; + PCSTR touchscreen_device; UINT32 button_debounce; UINT32 sys_mq_length; } GLOBAL_CONFIG; diff --git a/src/main.c b/src/main.c index 414f931..b945f95 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,11 @@ static void do_draw(void) Fb_filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, FALSE); } +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; @@ -77,6 +82,18 @@ int main(int argc, char *argv[]) } 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; } diff --git a/src/msg.h b/src/msg.h index d388e24..03f91c2 100644 --- a/src/msg.h +++ b/src/msg.h @@ -17,4 +17,8 @@ typedef struct tagMSG { #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 +#define WM_TOUCHDOWN 0x0030 +#define WM_TOUCHMOVE 0x0031 +#define WM_TOUCHUP 0x0032 + #endif /* __MSG_H_INCLUDED */ diff --git a/src/msg_queue.c b/src/msg_queue.c index fbe483e..61252ad 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -61,7 +61,7 @@ void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *at post_internal(queue, &tmpmsg); } -void Mq_post1(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1) +void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2) { MSG tmpmsg; @@ -69,6 +69,7 @@ void Mq_post1(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1) tmpmsg.target = target; tmpmsg.message = message; tmpmsg.attrs[0] = attr1; + tmpmsg.attrs[1] = attr2; tmpmsg.timestamp = Time_since_start(); post_internal(queue, &tmpmsg); } diff --git a/src/msg_queue.h b/src/msg_queue.h index a5220a5..1ba3626 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -21,7 +21,10 @@ typedef struct tagMSG_QUEUE { extern PMSG_QUEUE Mq_alloc(UINT32 nentries); extern void Mq_destroy(PMSG_QUEUE queue); extern void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs); -extern void Mq_post1(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1); +extern void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2); extern BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags); +#define Mq_post0(q, tgt, msg) Mq_post2(q, tgt, msg, 0, 0) +#define Mq_post1(q, tgt, msg, attr) Mq_post2(q, tgt, msg, attr, 0) + #endif /* __MSG_QUEUE_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index 2cb2aff..dcec699 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -1,7 +1,11 @@ #include #include #include +#include +#include +#include #include +#include #include "scode.h" #include "config.h" #include "log.h" @@ -9,46 +13,113 @@ #include "gpio.h" #include "time_func.h" +#define INPUT_EVENT_BATCH 16 + PMSG_QUEUE Sys_Queue = NULL; static pthread_t ithread; static volatile sig_atomic_t running = 1; -static UINT32 last_bstate = 0; +static int ts_fd = 0; -static void *input_thread(void *arg) +static UINT32 last_bstate = 0; +static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; + +static UINT_PTR touch_x = 0; +static UINT_PTR touch_y = 0; +static UINT32 touch_nextmsg = WM_TOUCHMOVE; + +static void poll_buttons(void) { UINT32 st, down, up, mask; UINT_PTR attr; TIMESTAMP now; - TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; + /* poll hardware buttons */ + st = Gpio_read_buttons(); + if (st != last_bstate) + { + now = Time_since_start(); + up = last_bstate & ~st; + down = st & ~last_bstate; + for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) + { + if (now < button_event_ok[attr - 1]) + continue; + if (up & mask) + { + button_event_ok[attr - 1] = now + Gconfig.button_debounce; + Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + } + else if (down & mask) + Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + } + last_bstate = st; + } +} + +static void poll_touchscreen(void) +{ + int nb, nev, xerrno, i; + struct input_event buffer[INPUT_EVENT_BATCH]; + + nb = read(ts_fd, buffer, INPUT_EVENT_BATCH * sizeof(struct input_event)); + if (nb == -1) + { + xerrno = errno; + if ((xerrno != EAGAIN) && (xerrno != EWOULDBLOCK)) + Log(LERROR, "Error reading from touchscreen device (%d)", xerrno); + return; + } + else if (nb == 0) + { + Log(LERROR, "Unexpected end of file reading from touchscreen device"); + return; + } + nev = nb / sizeof(struct input_event); + xerrno = nev * sizeof(struct input_event); + if (nb > xerrno) + Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno); + for (i=0; i Date: Sat, 7 Dec 2019 00:54:55 -0700 Subject: [PATCH 041/162] made the drawn pattern a little fancier --- src/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.c b/src/main.c index b945f95..459ae84 100644 --- a/src/main.c +++ b/src/main.c @@ -18,6 +18,9 @@ static void do_draw(void) Fb_filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, FALSE); Fb_filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, FALSE); Fb_filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, FALSE); + Fb_rectangle(10, 110, 150, 150, PBPRIMCLR_WHITE, FALSE); + Fb_line(10, 110, 150, 150, FBPRIMCLR_WHITE, FALSE); + Fb_line(10, 150, 150, 110, FBPRIMCLR_WHITE, FALSE); } static void log_touch(const char *event, UINT_PTR x, UINT_PTR y) From 7e098aa63a94d7af96e3bc67810dfd154541029a Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 13:07:59 -0700 Subject: [PATCH 042/162] added more documentation --- src/config.c | 27 +++++++++++++++++++-------- src/config.h | 11 ++++++----- src/fbinit.c | 18 +++++++++--------- src/fbinit.h | 37 +++++++++++++++++++------------------ src/fbprimitive.c | 1 + src/fbprimitive.h | 1 + src/gpio.c | 3 ++- src/gpio.h | 5 +++-- src/log.c | 5 ++++- src/log.h | 13 ++++++++----- src/main.c | 3 ++- src/msg_queue.h | 23 +++++++++++++---------- src/sysinput.c | 30 ++++++++++++++++++------------ src/time_func.c | 2 +- src/wintype.h | 2 +- 15 files changed, 107 insertions(+), 74 deletions(-) diff --git a/src/config.c b/src/config.c index 8aecc61..dbfcb1a 100644 --- a/src/config.c +++ b/src/config.c @@ -7,6 +7,7 @@ #include "scode.h" #include "log.h" +/* command line options for UPIWIN */ static const struct option long_options[] = { {"framebuffer", required_argument, 0, 'F'}, {"help", no_argument, 0, 'h'}, @@ -16,6 +17,7 @@ static const struct option long_options[] = { static const char *short_options = "F:hT:"; +/* printed to stdout when upiwin is executed with -h/--help option */ static const char *helptext = "UPIWIN - Micro Pi Windows server program\n\n" "Usage: upiwin [options] scriptname [scriptargs]\n\n" @@ -25,19 +27,20 @@ static const char *helptext = " -T,--touchscreen - Specifies the touchscreen device name\n" ""; -#define EXITFUNCBLOCK_FUNCCOUNT 64 +#define EXITFUNCBLOCK_FUNCCOUNT 64 /* number of exit functions per function block */ +/* exit functions are stored in these data blocks */ typedef struct tagEXITFUNCBLOCK { - struct tagEXITFUNCBLOCK *next; - int num_funcs; - PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT]; + struct tagEXITFUNCBLOCK *next; /* chained in single linked list */ + int num_funcs; /* number of functions this block contains */ + PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT]; /* pointers to functions */ } EXITFUNCBLOCK, *PEXITFUNCBLOCK; /* The global configuration data */ GLOBAL_CONFIG Gconfig; -static PEXITFUNCBLOCK exitfuncs = NULL; +static PEXITFUNCBLOCK exitfuncs = NULL; /* pointer to head of exit function chain */ static void run_exit_funcs(void) { @@ -50,6 +53,7 @@ static void run_exit_funcs(void) exitfuncs = p->next; for (i = p->num_funcs - 1; i >= 0; i--) { + /* execute functions in LIFO order */ ASSERT(p->funcs[i]); (*(p->funcs[i]))(); } @@ -59,6 +63,7 @@ static void run_exit_funcs(void) static void init_defaults(void) { + memset(&Gconfig, 0, sizeof(GLOBAL_CONFIG)); Gconfig.framebuffer_device = "/dev/fb1"; Gconfig.touchscreen_device = "/dev/input/touchscreen"; Gconfig.button_debounce = 100; @@ -79,7 +84,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) break; switch (c) { - case 'F': + case 'F': /* frame buffer device name */ pstr = strdup(optarg); if (!pstr) { @@ -91,11 +96,11 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) parsed->framebuffer_device = pstr; break; - case 'h': + case 'h': /* show help */ help = TRUE; break; - case 'T': + case 'T': /* touchscreen device name */ pstr = strdup(optarg); if (!pstr) { @@ -138,10 +143,16 @@ HRESULT Config_setup(int argc, char *argv[]) Log(LFATAL, "Unable to set up exit function mechanism"); return E_FAIL; } + + /* set defaults */ init_defaults(); + + /* evaluate command line */ hr = parse_cmdline(argc, argv, &from_commandline); if (hr != S_OK) return hr; + + /* command line overrides everything */ overlay_config(&from_commandline); return S_OK; } diff --git a/src/config.h b/src/config.h index 3955d9c..e543bd4 100644 --- a/src/config.h +++ b/src/config.h @@ -5,14 +5,15 @@ typedef void (*PEXITFUNC)(void); +/* global configuration data for UPIWIN */ typedef struct tagGLOBAL_CONFIG { - PCSTR framebuffer_device; - PCSTR touchscreen_device; - UINT32 button_debounce; - UINT32 sys_mq_length; + PCSTR framebuffer_device; /* name of frame buffer device */ + PCSTR touchscreen_device; /* name of touchscreen device */ + UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ + UINT32 sys_mq_length; /* length of system message queue */ } GLOBAL_CONFIG; -extern GLOBAL_CONFIG Gconfig; +extern GLOBAL_CONFIG Gconfig; /* one global configuration to rule them all */ extern HRESULT Config_setup(int argc, char *argv[]); extern HRESULT Config_exitfunc(PEXITFUNC pfn); diff --git a/src/fbinit.c b/src/fbinit.c index 24cbe7e..11bbcd3 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -16,12 +16,13 @@ extern uint8_t _binary_splash_bin_start[]; extern uint8_t _binary_splash_bin_end; extern uint8_t _binary_splash_bin_size; -static int fb_fd = -1; +static int fb_fd = -1; /* framebuffer file descriptor */ +/* frame buffer information */ static FBINFO local_info; PCFBINFO Fb_Info = &local_info; -UINT16 *Fb_Ptr = NULL; +UINT16 *Fb_Ptr = NULL; /* pointer to memory-mapped frame buffer */ inline static UINT16 makemask(unsigned offset, unsigned length) { @@ -30,12 +31,11 @@ inline static UINT16 makemask(unsigned offset, unsigned length) static void do_cleanup(void) { - /* additional cleanup here */ - + /* black out the display */ memset(Fb_Ptr, 0, local_info.screenbytes); - munmap((void *)Fb_Ptr, local_info.screenbytes); - Fb_Ptr = NULL; + munmap((void *)Fb_Ptr, local_info.screenbytes); + Fb_Ptr = NULL; close(fb_fd); fb_fd = -1; } @@ -50,10 +50,11 @@ HRESULT Fb_setup(void) if (fb_fd == -1) { hr = ERRNO_AS_SCODE; - Log(LFATAL, "Unable to open framebuffer (%08X)", hr); + Log(LFATAL, "Unable to open framebuffer device %s (%08X)", Gconfig.framebuffer_device, hr); return hr; } + /* fixed info is needed to get the memory parameters for the display */ if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed)) { hr = ERRNO_AS_SCODE; @@ -64,6 +65,7 @@ HRESULT Fb_setup(void) local_info.linebytes = fixed.line_length; local_info.screenbytes = fixed.smem_len; + /* variable info is used to get scren geometry and color info */ if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) { hr = ERRNO_AS_SCODE; @@ -100,8 +102,6 @@ HRESULT Fb_setup(void) /* display the splash screen */ memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size)); - /* additional setup here */ - hr = Config_exitfunc(do_cleanup); if (FAILED(hr)) do_cleanup(); diff --git a/src/fbinit.h b/src/fbinit.h index 8638317..66e4f35 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -3,28 +3,29 @@ #include "wintype.h" +/* info about the frame buffer */ typedef struct tagFBINFO { - UINT32 width; - UINT32 height; - UINT32 virtual_width; - UINT32 virtual_height; - UINT32 bpp; - UINT32 linebytes; - UINT32 screenbytes; - UINT16 red_offset; - UINT16 red_length; - UINT16 red_mask; - UINT16 green_offset; - UINT16 green_length; - UINT16 green_mask; - UINT16 blue_offset; - UINT16 blue_length; - UINT16 blue_mask; + UINT32 width; /* screen width */ + UINT32 height; /* screen height */ + UINT32 virtual_width; /* virtual screen width */ + UINT32 virtual_height; /* virtual screen height */ + UINT32 bpp; /* bits per pixel (16) */ + UINT32 linebytes; /* number of bytes per line */ + UINT32 screenbytes; /* number of bytes for the entire screen */ + UINT16 red_offset; /* offset of "red" bits within pixel word (11) */ + UINT16 red_length; /* number of "red" bits within pixel word (5) */ + UINT16 red_mask; /* mask for the "red" bits in a pixel word */ + UINT16 green_offset; /* offset of "green" bits within pixel word (5) */ + UINT16 green_length; /* number of "green" bits within pixel word (6) */ + UINT16 green_mask; /* mask for the "green" bits in a pixel word */ + UINT16 blue_offset; /* offset of "blue" bits within pixel word (0) */ + UINT16 blue_length; /* number of "blue" bits within pixel word (5) */ + UINT16 blue_mask; /* mask for the "blue" bits in a pixel word */ } FBINFO; typedef const FBINFO * const PCFBINFO; -extern PCFBINFO Fb_Info; -extern UINT16 *Fb_Ptr; +extern PCFBINFO Fb_Info; /* pointer to screen information */ +extern UINT16 *Fb_Ptr; /* pointer to memory-mapped screen buffer */ extern HRESULT Fb_setup(void); extern void Fb_clear(void); diff --git a/src/fbprimitive.c b/src/fbprimitive.c index 805dcd4..f434226 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -25,6 +25,7 @@ void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor) INT32 dx = x2 - x1; INT32 dy = y2 - y1; + /* uses Bresenham's line algorithm with fixed-point arithmetic */ if (ABS(dx) < ABS(dy)) { if (y1 > y2) diff --git a/src/fbprimitive.h b/src/fbprimitive.h index fddd6c8..8f0ea8e 100644 --- a/src/fbprimitive.h +++ b/src/fbprimitive.h @@ -3,6 +3,7 @@ #include "wintype.h" +/* Some predefined "primitive" color values */ #define FBPRIMCLR_BLACK 0x0000 #define FBPRIMCLR_RED 0xF800 #define FBPRIMCLR_GREEN 0x07E0 diff --git a/src/gpio.c b/src/gpio.c index b4e8758..dfe0710 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -5,13 +5,14 @@ #include "scode.h" #include "gpio.h" +/* GPIO lines used by various peripheral devices */ #define GLINE_BUTTON1 17 #define GLINE_BUTTON2 22 #define GLINE_BUTTON3 23 #define GLINE_BUTTON4 27 #define GLINE_BACKLIGHT 18 -#define PWM_BACKLIGHT 0 +#define PWM_BACKLIGHT 0 /* PWM channel used for backlight */ static void do_cleanup(void) { diff --git a/src/gpio.h b/src/gpio.h index 24c7398..707393a 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -3,14 +3,15 @@ #include "wintype.h" -#define GPIO_BUTTON_COUNT 4 +#define GPIO_BUTTON_COUNT 4 /* number of GPIO buttons we have */ +/* state flags for the GPIO buttons */ #define GRB_STATE_BUTTON1 (1 << 0) #define GRB_STATE_BUTTON2 (1 << 1) #define GRB_STATE_BUTTON3 (1 << 2) #define GRB_STATE_BUTTON4 (1 << 3) -#define GSB_BACKLIGHT_MAX 1023 +#define GSB_BACKLIGHT_MAX 1023 /* maximum level for backlight */ extern HRESULT Gpio_setup(void); extern UINT32 Gpio_read_buttons(void); diff --git a/src/log.c b/src/log.c index 81afc30..e6ab3c6 100644 --- a/src/log.c +++ b/src/log.c @@ -4,8 +4,11 @@ #include #include "log.h" +/* string equivalents to the severity values */ static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" }; +static FILE *logfile = stdout; /* log file pointer */ + void Log(int level, const char *format, ...) { va_list argp; @@ -21,7 +24,7 @@ void Log(int level, const char *format, ...) gettimeofday(&tv, NULL); localtime_r(&(tv.tv_sec), &tm); strftime(timestamp, 32, "%F %T", &tm); - printf("%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); + fprintf(logfile, "%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); } void Log_assert_failed(const char *test, const char *file, int line) diff --git a/src/log.h b/src/log.h index 82145f5..a0871ca 100644 --- a/src/log.h +++ b/src/log.h @@ -1,18 +1,21 @@ #ifndef __LOG_H_INCLUDED #define __LOG_H_INCLUDED -#define LFATAL 0 -#define LERROR 1 -#define LWARN 2 -#define LINFO 3 -#define LDEBUG 4 +/* Logging level severities */ +#define LFATAL 0 /* fatal error */ +#define LERROR 1 /* error */ +#define LWARN 2 /* warning */ +#define LINFO 3 /* information */ +#define LDEBUG 4 /* debugging */ extern void Log(int level, const char *format, ...); extern void Log_assert_failed(const char *test, const char *file, int line); +/* Current file name definitions for assert macros */ #define THIS_FILE __FILE__ #define DECLARE_THIS_FILE() static const char THIS_FILE[] = __FILE__ +/* Assert macros */ #ifdef DEBUG_ASSERT #define ASSERT(x) ((x) ? (void)0 : Log_assert_failed(#x, THIS_FILE, __LINE__)) #define VERIFY(x) ASSERT(x) diff --git a/src/main.c b/src/main.c index 459ae84..7bdd267 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ int main(int argc, char *argv[]) MSG msg; char *tmp; + /* initialization sequence */ Time_init(); hr = Config_setup(argc, argv); if (FAILED(hr)) @@ -48,7 +49,7 @@ int main(int argc, char *argv[]) if (FAILED(Sys_enable_input())) return EXIT_FAILURE; Log(LINFO, "Pausing at startup."); - sleep(5); /* wait to show off splash screen */ + sleep(3); /* wait to show off splash screen */ Fb_clear(); /* temporary drawing here */ diff --git a/src/msg_queue.h b/src/msg_queue.h index 1ba3626..10c49ae 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -1,22 +1,25 @@ #ifndef __MSG_QUEUE_H_INCLUDED #define __MSG_QUEUE_H_INCLUDED +#include #include "wintype.h" #include "msg.h" +/* internal structure of a message queue */ typedef struct tagMSG_QUEUE { - struct tagMSG_QUEUE *next; - PMSG startbound; - PMSG endbound; - PMSG head; - PMSG tail; - UINT32 nentries; - pthread_mutex_t mutex; - MSG messagestore[0]; + struct tagMSG_QUEUE *next; /* allow us to be in a singly-linked list */ + PMSG startbound; /* start boundary for message buffer */ + PMSG endbound; /* end boundary for message buffer */ + PMSG head; /* head pointer of message queue */ + PMSG tail; /* tail pointer of message queue */ + UINT32 nentries; /* number of entries possible in message buffer */ + pthread_mutex_t mutex; /* controls access to queue from multiple threads */ + MSG messagestore[0]; /* message buffer */ } MSG_QUEUE, *PMSG_QUEUE; -#define PEEK_REMOVE 0x0001 -#define PEEK_NOREMOVE 0x0000 +/* flags to Mq_peek */ +#define PEEK_REMOVE 0x0001 /* remove message if found */ +#define PEEK_NOREMOVE 0x0000 /* do not remove message if found */ extern PMSG_QUEUE Mq_alloc(UINT32 nentries); extern void Mq_destroy(PMSG_QUEUE queue); diff --git a/src/sysinput.c b/src/sysinput.c index dcec699..530489c 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -13,20 +13,22 @@ #include "gpio.h" #include "time_func.h" -#define INPUT_EVENT_BATCH 16 +#define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */ -PMSG_QUEUE Sys_Queue = NULL; +PMSG_QUEUE Sys_Queue = NULL; /* system message queue */ +static int ts_fd = 0; /* file descriptor for touchscreen */ -static pthread_t ithread; -static volatile sig_atomic_t running = 1; -static int ts_fd = 0; +static pthread_t ithread; /* input thread handle */ +static volatile sig_atomic_t running = 1; /* "running" flag for input thread */ -static UINT32 last_bstate = 0; -static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; +/* Local data for poll_buttons() */ +static UINT32 last_bstate = 0; /* previous button state */ +static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ -static UINT_PTR touch_x = 0; -static UINT_PTR touch_y = 0; -static UINT32 touch_nextmsg = WM_TOUCHMOVE; +/* Local data for poll_touchscreen() */ +static UINT_PTR touch_x = 0; /* X coordinate to send with next message */ +static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ +static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ static void poll_buttons(void) { @@ -44,9 +46,10 @@ static void poll_buttons(void) for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { if (now < button_event_ok[attr - 1]) - continue; + continue; /* this is a "contact bounce" event, don't bother */ if (up & mask) { + /* reset contact bounce timer - only seems to happen after button releases */ button_event_ok[attr - 1] = now + Gconfig.button_debounce; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); } @@ -75,10 +78,12 @@ static void poll_touchscreen(void) Log(LERROR, "Unexpected end of file reading from touchscreen device"); return; } + nev = nb / sizeof(struct input_event); xerrno = nev * sizeof(struct input_event); if (nb > xerrno) Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno); + for (i=0; i #include "time_func.h" -static TIMESTAMP start_timestamp = 0; +static TIMESTAMP start_timestamp = 0; /* time since epoch at start of run */ TIMESTAMP Time_since_epoch(void) { diff --git a/src/wintype.h b/src/wintype.h index 96c3645..34bdf50 100644 --- a/src/wintype.h +++ b/src/wintype.h @@ -32,7 +32,7 @@ #define INT64_BITS 64 #define UINT64_BITS 64 -#define LOG_PTRSIZE 2 /* log2(sizeof(void *)) */ +#define LOG_PTRSIZE 2 /* log2(sizeof(void *)) */ #define LOG_INTSIZE 2 /* log2(sizeof(int)) */ #define LOG_UINTSIZE 2 /* log2(sizeof(UINT32)) */ From 2320ce5e999db11ff5b22ff8d50611b54fcf7534 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 13:11:46 -0700 Subject: [PATCH 043/162] some changes to Makefiles and added top-level Makefile --- Makefile | 7 +++++++ buildutils/Makefile | 2 +- src/Makefile | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1273313 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: + make -C buildutils all + make -C src all + +clean: + make -C buildutils clean + make -C src clean diff --git a/buildutils/Makefile b/buildutils/Makefile index fb1c6ca..296377c 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,4 +1,4 @@ -ALL: mksplash +all: mksplash mksplash: mksplash.c gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng16 -lz diff --git a/src/Makefile b/src/Makefile index b9fd929..902fc62 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,6 +2,8 @@ OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func LIBS=-lbcm2835 -lpthread CFLAGS=-g -O -DDEBUG_ASSERT +all: upiwin + upiwin: $(OBJS) gcc -o upiwin $(OBJS) $(LIBS) From aad0c5ed9847b2b390a0b8da0c6e446debb82df4 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 13:13:15 -0700 Subject: [PATCH 044/162] compile error - typo in color name --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 7bdd267..bc91640 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,7 @@ static void do_draw(void) Fb_filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, FALSE); Fb_filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, FALSE); Fb_filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, FALSE); - Fb_rectangle(10, 110, 150, 150, PBPRIMCLR_WHITE, FALSE); + Fb_rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, FALSE); Fb_line(10, 110, 150, 150, FBPRIMCLR_WHITE, FALSE); Fb_line(10, 150, 150, 110, FBPRIMCLR_WHITE, FALSE); } From 79bb9552da8ecdd7eab51f978cf132d77f92ef88 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 19:43:45 -0700 Subject: [PATCH 045/162] adding the embedded Python init/terminate code --- src/Makefile | 14 ++++--- src/config.c | 1 + src/config.h | 1 + src/ep_init.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/ep_init.h | 11 ++++++ src/ep_util.c | 44 +++++++++++++++++++++ src/ep_util.h | 11 ++++++ src/main.c | 5 ++- src/scode.h | 2 +- 9 files changed, 186 insertions(+), 7 deletions(-) create mode 100644 src/ep_init.c create mode 100644 src/ep_init.h create mode 100644 src/ep_util.c create mode 100644 src/ep_util.h diff --git a/src/Makefile b/src/Makefile index 902fc62..2d6dfaa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,17 +1,21 @@ -OBJS=main.o sysinput.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o -LIBS=-lbcm2835 -lpthread -CFLAGS=-g -O -DDEBUG_ASSERT +OBJS=main.o sysinput.o ep_init.o ep_util.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o \ + time_func.o config.o splash.o +LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm +CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT +LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \ + -Wl,-Bsymbolic-functions all: upiwin upiwin: $(OBJS) - gcc -o upiwin $(OBJS) $(LIBS) + gcc -o upiwin $(LDFLAGS) $(OBJS) $(LIBS) .c.o: gcc -c $(CFLAGS) $< splash.o: splash.bin - objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o + objcopy -I binary -O elf32-littlearm -B arm --rename-section \ + .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o splash.bin: splash.png ../buildutils/mksplash ../buildutils/mksplash splash.png splash.bin diff --git a/src/config.c b/src/config.c index dbfcb1a..d9aa37a 100644 --- a/src/config.c +++ b/src/config.c @@ -66,6 +66,7 @@ static void init_defaults(void) memset(&Gconfig, 0, sizeof(GLOBAL_CONFIG)); Gconfig.framebuffer_device = "/dev/fb1"; Gconfig.touchscreen_device = "/dev/input/touchscreen"; + Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; } diff --git a/src/config.h b/src/config.h index e543bd4..1bb94e4 100644 --- a/src/config.h +++ b/src/config.h @@ -9,6 +9,7 @@ typedef void (*PEXITFUNC)(void); typedef struct tagGLOBAL_CONFIG { PCSTR framebuffer_device; /* name of frame buffer device */ PCSTR touchscreen_device; /* name of touchscreen device */ + PCSTR python_loc; /* location of the Python3 executable */ UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ UINT32 sys_mq_length; /* length of system message queue */ } GLOBAL_CONFIG; diff --git a/src/ep_init.c b/src/ep_init.c new file mode 100644 index 0000000..a163039 --- /dev/null +++ b/src/ep_init.c @@ -0,0 +1,104 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "config.h" +#include "log.h" +#include "ep_init.h" +#include "ep_util.h" + +PCSTR Mod_UPIWIN = "upiwin"; /* name of the primary UPIWIN module */ +PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN module */ + +static wchar_t *python_name = NULL; /* location of the Python executable */ + +static PyObject *upiwin_module = NULL; +static PyObject *upiwin_tmp_module = NULL; + +static PyObject *init_upiwin_module(void) +{ +} + +static PyObject *init_upiwin_tmp_module(void) +{ +} + +/* used to link the two modules into Python's init table */ +static struct _inittab upiwin_inittab[] = { + { Mod_UPIWIN, init_upiwin_module }, + { Mod_UPIWIN_tmp, init_upiwin_tmp_module }, + { NULL, NULL } +}; + +static void epython_cleanup(void) +{ + Py_DECREF(upiwin_tmp_module); + upiwin_tmp_module = NULL; + Py_DECREF(upiwin_module); + upiwin_module = NULL; + if (!Py_FinalizeEx()) + Log(LWARN, "errors encountered when Python uninitialized itself"); + PyMem_RawFree(python_name); + python_name = NULL; +} + +HRESULT Epython_setup(void) +{ + HRESULT hr; + size_t size; + + python_name = Py_DecodeLocale(Gconfig.python_loc, &size); + if (!python_name) + { + if (size==(size_t)(-1)) + { + Log(LFATAL, "error allocating Python program location"); + return E_OUTOFMEMORY; + } + else + { + Log(LFATAL, "internal error in Py_DecodeLocale"); + return E_UNEXPECTED; + } + } + Py_SetProgramName(python_name); + + if (PyImport_ExtendInittab(upiwin_inittab)) + { + Log(LFATAL, "error allocating extended init table"); + hr = E_OUTOFMEMORY; + goto error_0; + } + + Py_Initialize(); + + /* Import the modules */ + upiwin_module = PyImport_ImportModule(Mod_UPIWIN); + if (!upiwin_module) + { + Log(LFATAL, "error importing the upiwin module"); + hr = Epython_trace_exception(); + goto error_1; + } + upiwin_tmp_module = PyImport_ImportModule(Mod_UPIWIN_tmp); + if (!upiwin_tmp_module) + { + Log(LFATAL, "error importing the upiwin_tmp module"); + hr = Epython_trace_exception(); + goto error_2; + } + + hr = Config_exitfunc(epython_cleanup); + if (FAILED(hr)) + epython_cleanup(); + return hr; + +error_2: + Py_DECREF(upiwin_module); + upiwin_module = NULL; +error_1: + Py_FinalizeEx(); +error_0: + PyMem_RawFree(python_name); + python_name = NULL; + return hr; +} diff --git a/src/ep_init.h b/src/ep_init.h new file mode 100644 index 0000000..bd376ab --- /dev/null +++ b/src/ep_init.h @@ -0,0 +1,11 @@ +#ifndef __EP_INIT_H_INCLUDED +#define __EP_INIT_H_INCLUDED + +#include "wintype.h" + +extern PCSTR Mod_UPIWIN; +extern PCSTR Mod_UPIWIN_tmp; + +extern HRESULT Epython_setup(void); + +#endif /* __EP_INIT_H_INCLUDED */ diff --git a/src/ep_util.c b/src/ep_util.c new file mode 100644 index 0000000..ee12f4a --- /dev/null +++ b/src/ep_util.c @@ -0,0 +1,44 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "ep_util.h" +#include "log.h" + +void Epython_log_object(int level, const char *label, PyObject *object) +{ + BOOL traced = FALSE; + PyObject *repr; + PCSTR pstr; + + repr = PyObject_Repr(object); + if (repr) + { + ASSERT(PyUnicode_Check(repr)); + pstr = PyUnicode_AsUTF8(repr); + Log(level, "object %s: %s", label, pstr); + traced = TRUE; + Py_DECREF(repr); + } + + if (!traced) + Log(level, "object %s: could not be logged (memory error)", label); +} + +HRESULT Epython_trace_exception(void) +{ + HRESULT hr = E_FAIL; + + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + if (!type) + return S_OK; + + Epython_log_object(LERROR, "exception type", type); + Epython_log_object(LERROR, "exception value", value); + Epython_log_object(LERROR, "exception traceback", value); + + Py_DECREF(type); + Py_DECREF(value); + Py_DECREF(traceback); + return hr; +} diff --git a/src/ep_util.h b/src/ep_util.h new file mode 100644 index 0000000..5644889 --- /dev/null +++ b/src/ep_util.h @@ -0,0 +1,11 @@ +#ifndef __EP_UTIL_H_INCLUDED +#define __EP_UTIL_H_INCLUDED + +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" + +extern void Epython_log_object(int level, const char *label, PyObject *object); +extern HRESULT Epython_trace_exception(void); + +#endif /* __EP_UTIL_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index bc91640..d683864 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "fbinit.h" #include "fbprimitive.h" #include "time_func.h" +#include "ep_init.h" #include "sysinput.h" static void do_draw(void) @@ -46,10 +47,12 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; if (FAILED(Gpio_setup())) return EXIT_FAILURE; + if (FAILED(Epython_setup())) + return EXIT_FAILURE; if (FAILED(Sys_enable_input())) return EXIT_FAILURE; Log(LINFO, "Pausing at startup."); - sleep(3); /* wait to show off splash screen */ + sleep(2); /* wait to show off splash screen */ Fb_clear(); /* temporary drawing here */ diff --git a/src/scode.h b/src/scode.h index 6880804..2f97a69 100644 --- a/src/scode.h +++ b/src/scode.h @@ -64,6 +64,6 @@ #define E_UNEXPECTED SCODE_CAST(0x8000FFFF) /* unexpected error */ /* UPIWIN-specific errorcodes */ -#define UPIWIN_E_OUTOFRANGE SCODE_CAST(0x80060000) /* value out of range */ +#define UPIWIN_E_INVALIDSTRING SCODE_CAST(0x80060000) /* invalid string (decode error) */ #endif /* __SCODE_H_INCLUDED */ From 3cbcda088666ed60763a41a3416f8e0607f00777 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 19:44:48 -0700 Subject: [PATCH 046/162] fixed logging errorx --- src/log.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/log.c b/src/log.c index e6ab3c6..3035f88 100644 --- a/src/log.c +++ b/src/log.c @@ -7,7 +7,7 @@ /* string equivalents to the severity values */ static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" }; -static FILE *logfile = stdout; /* log file pointer */ +static FILE *logfile = NULL; /* log file pointer */ void Log(int level, const char *format, ...) { @@ -24,7 +24,7 @@ void Log(int level, const char *format, ...) gettimeofday(&tv, NULL); localtime_r(&(tv.tv_sec), &tm); strftime(timestamp, 32, "%F %T", &tm); - fprintf(logfile, "%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); + fprintf(logfile ? logfile : stdout, "%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); } void Log_assert_failed(const char *test, const char *file, int line) From 05bdcdaa4b5948e07fe88462141cfaa48000b844 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 19:48:44 -0700 Subject: [PATCH 047/162] fixed compile errorsx --- src/ep_init.c | 4 ++-- src/ep_init.h | 4 ++-- src/log.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ep_init.c b/src/ep_init.c index a163039..a61dd9f 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -6,8 +6,8 @@ #include "ep_init.h" #include "ep_util.h" -PCSTR Mod_UPIWIN = "upiwin"; /* name of the primary UPIWIN module */ -PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN module */ +const PCSTR Mod_UPIWIN = "upiwin"; /* name of the primary UPIWIN module */ +const PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN module */ static wchar_t *python_name = NULL; /* location of the Python executable */ diff --git a/src/ep_init.h b/src/ep_init.h index bd376ab..3ef391c 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -3,8 +3,8 @@ #include "wintype.h" -extern PCSTR Mod_UPIWIN; -extern PCSTR Mod_UPIWIN_tmp; +extern const PCSTR Mod_UPIWIN; +extern const PCSTR Mod_UPIWIN_tmp; extern HRESULT Epython_setup(void); diff --git a/src/log.c b/src/log.c index 3035f88..a239fc9 100644 --- a/src/log.c +++ b/src/log.c @@ -24,7 +24,7 @@ void Log(int level, const char *format, ...) gettimeofday(&tv, NULL); localtime_r(&(tv.tv_sec), &tm); strftime(timestamp, 32, "%F %T", &tm); - fprintf(logfile ? logfile : stdout, "%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf); + fprintf(logfile ? logfile : stdout, "%s.%06ld %s %s\n", timestamp, tv.tv_usec, severities[level], buf); } void Log_assert_failed(const char *test, const char *file, int line) From 2576f6ae2e0118f9ab2cacb150fd78655764de3d Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 20:53:59 -0700 Subject: [PATCH 048/162] adding first module definition for UPIWIN (the backlight functions) --- src/Makefile | 2 +- src/ep_backlight.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ src/ep_init.c | 46 ++++++++++++++++++++------------- src/ep_init.h | 7 ++++++ src/ep_upiwin.c | 48 +++++++++++++++++++++++++++++++++++ src/ep_upiwin.h | 19 ++++++++++++++ src/gpio.c | 2 +- src/gpio.h | 2 ++ 8 files changed, 169 insertions(+), 20 deletions(-) create mode 100644 src/ep_backlight.c create mode 100644 src/ep_upiwin.c create mode 100644 src/ep_upiwin.h diff --git a/src/Makefile b/src/Makefile index 2d6dfaa..689392e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o ep_init.o ep_util.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_util.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o \ time_func.o config.o splash.o LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT diff --git a/src/ep_backlight.c b/src/ep_backlight.c new file mode 100644 index 0000000..04ccec9 --- /dev/null +++ b/src/ep_backlight.c @@ -0,0 +1,63 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "gpio.h" +#include "ep_upiwin.h" +#include "ep_init.h" + +PyObject *Epython_get_backlight(PyObject *self, PyObject *args) +{ + PUPIWIN_STATE pstate; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + return PyBool_FromLong((long)(pstate->backlight_on)); +} + +PyObject *Epython_set_backlight(PyObject *self, PyObject *args) +{ + PUPIWIN_STATE pstate; + int new_state; + + if (!PyArg_ParseTuple(args, "p", &new_state)) + return NULL; + pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + if (new_state && !(pstate->backlight_on)) + Gpio_set_backlight(pstate->backlight_level); + else if (!new_state && pstate->backlight_on) + Gpio_set_backlight(0); + pstate->backlight_on = MAKEBOOL(new_state); + return PyLong_FromUnsignedLong(S_OK); +} + +PyObject *Epython_get_backlight_level(PyObject *self, PyObject *args) +{ + PUPIWIN_STATE pstate; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + return PyLong_FromUnsignedLong(pstate->backlight_level); +} + +PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args) +{ + PUPIWIN_STATE pstate; + UINT32 new_level; + HRESULT hr = S_OK; + + if (!PyArg_ParseTuple(args, "k", &new_level)) + return NULL; + if (new_level <= GSB_BACKLIGHT_MAX) + { + pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + if (pstate->backlight_on) + Gpio_set_backlight(new_level); + pstate->backlight_level = new_level; + } + else + { + hr = E_INVALIDARG; + } + return PyLong_FromUnsignedLong(hr); +} diff --git a/src/ep_init.c b/src/ep_init.c index a61dd9f..2467a59 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -11,30 +11,40 @@ const PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN static wchar_t *python_name = NULL; /* location of the Python executable */ -static PyObject *upiwin_module = NULL; -static PyObject *upiwin_tmp_module = NULL; +PyObject *UPIWIN_module = NULL; +PyObject *UPIWIN_tmp_module = NULL; -static PyObject *init_upiwin_module(void) -{ -} +static PyModuleDef DefUPIWIN_tmp = { + PyModuleDef_HEAD_INIT, /* standard garbage */ + Mod_UPIWIN, /* module name */ + NULL, /* no doc string */ + -1, /* no per-module memory */ + NULL, /* method defs will be added later */ + NULL, /* no slots for multi-phase init */ + NULL, /* no traversal proc */ + NULL, /* no clear function */ + NULL /* no free function */ +}; static PyObject *init_upiwin_tmp_module(void) { + PyObject *module = PyModule_Create(&DefUPIWIN_tmp); + return module; } /* used to link the two modules into Python's init table */ static struct _inittab upiwin_inittab[] = { - { Mod_UPIWIN, init_upiwin_module }, - { Mod_UPIWIN_tmp, init_upiwin_tmp_module }, - { NULL, NULL } + { Mod_UPIWIN, Epython_init_upiwin_module }, + { Mod_UPIWIN_tmp, init_upiwin_tmp_module }, + { NULL, NULL } }; static void epython_cleanup(void) { - Py_DECREF(upiwin_tmp_module); - upiwin_tmp_module = NULL; - Py_DECREF(upiwin_module); - upiwin_module = NULL; + Py_DECREF(UPIWIN_tmp_module); + UPIWIN_tmp_module = NULL; + Py_DECREF(UPIWIN_module); + UPIWIN_module = NULL; if (!Py_FinalizeEx()) Log(LWARN, "errors encountered when Python uninitialized itself"); PyMem_RawFree(python_name); @@ -72,15 +82,15 @@ HRESULT Epython_setup(void) Py_Initialize(); /* Import the modules */ - upiwin_module = PyImport_ImportModule(Mod_UPIWIN); - if (!upiwin_module) + UPIWIN_module = PyImport_ImportModule(Mod_UPIWIN); + if (!UPIWIN_module) { Log(LFATAL, "error importing the upiwin module"); hr = Epython_trace_exception(); goto error_1; } - upiwin_tmp_module = PyImport_ImportModule(Mod_UPIWIN_tmp); - if (!upiwin_tmp_module) + UPIWIN_tmp_module = PyImport_ImportModule(Mod_UPIWIN_tmp); + if (!UPIWIN_tmp_module) { Log(LFATAL, "error importing the upiwin_tmp module"); hr = Epython_trace_exception(); @@ -93,8 +103,8 @@ HRESULT Epython_setup(void) return hr; error_2: - Py_DECREF(upiwin_module); - upiwin_module = NULL; + Py_DECREF(UPIWIN_module); + UPIWIN_module = NULL; error_1: Py_FinalizeEx(); error_0: diff --git a/src/ep_init.h b/src/ep_init.h index 3ef391c..8d12d97 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -1,11 +1,18 @@ #ifndef __EP_INIT_H_INCLUDED #define __EP_INIT_H_INCLUDED +#define PY_SSIZE_T_CLEAN +#include #include "wintype.h" extern const PCSTR Mod_UPIWIN; extern const PCSTR Mod_UPIWIN_tmp; +extern PyObject *UPIWIN_module; +extern PyObject *UPIWIN_tmp_module; + +extern PyObject *Epython_init_upiwin_module(void); + extern HRESULT Epython_setup(void); #endif /* __EP_INIT_H_INCLUDED */ diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c new file mode 100644 index 0000000..0434d3c --- /dev/null +++ b/src/ep_upiwin.c @@ -0,0 +1,48 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "ep_init.h" +#include "gpio.h" +#include "ep_upiwin.h" + +static PyMethodDef UPIWINMethods[] = { + /* Backlight control functions */ + {"get_backlight", Epython_get_backlight, METH_VARARGS, + "Returns the current status of the backlight (True=on, False=off)."}, + {"set_backlight", Epython_set_backlight, METH_VARARGS, + "Sets the current status of the backlight (True=on, False=off). Returns a SCODE."}, + {"get_backlight_level", Epython_get_backlight_level, METH_VARARGS, + "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."}, + {NULL, NULL, 0, NULL} +}; + +static PyModuleDef DefUPIWIN = { + PyModuleDef_HEAD_INIT, /* standard garbage */ + Mod_UPIWIN, /* module name */ + NULL, /* no doc string */ + sizeof(UPIWIN_STATE), /* per-module memory */ + UPIWINMethods, /* method defs */ + NULL, /* no slots for multi-phase init */ + NULL, /* no traversal proc */ + NULL, /* no clear function */ + NULL /* no free function */ +}; + +PyObject *Epython_init_upiwin_module(void) +{ + PyObject *module; + PUPIWIN_STATE pstate; + + module = PyModule_Create(&DefUPIWIN); + if (!module) + return NULL; + + /* set up the module state */ + pstate = (PUPIWIN_STATE)PyModule_GetState(module); + pstate->backlight_on = TRUE; + pstate->backlight_level = GSB_BACKLIGHT_DEFAULT; + + return module; +} diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h new file mode 100644 index 0000000..fa41b43 --- /dev/null +++ b/src/ep_upiwin.h @@ -0,0 +1,19 @@ +#ifndef __EP_UPIWIN_H_INCLUDED +#define __EP_UPIWIN_H_INCLUDED + +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" + +typedef struct tagUPIWIN_STATE { + BOOL backlight_on; + UINT32 backlight_level; +} UPIWIN_STATE, *PUPIWIN_STATE; + +/* method definitions go here */ +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); + +#endif /* __EP_UPIWIN_H_INCLUDED */ diff --git a/src/gpio.c b/src/gpio.c index dfe0710..ff877c4 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -61,7 +61,7 @@ HRESULT Gpio_setup(void) bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_2); bcm2835_pwm_set_mode(PWM_BACKLIGHT, 1, 1); bcm2835_pwm_set_range(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX + 1); - bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_MAX); + bcm2835_pwm_set_data(PWM_BACKLIGHT, GSB_BACKLIGHT_DEFAULT); hr = Config_exitfunc(do_cleanup); if (FAILED(hr)) diff --git a/src/gpio.h b/src/gpio.h index 707393a..e368291 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -13,6 +13,8 @@ #define GSB_BACKLIGHT_MAX 1023 /* maximum level for backlight */ +#define GSB_BACKLIGHT_DEFAULT GSB_BACKLIGHT_MAX + extern HRESULT Gpio_setup(void); extern UINT32 Gpio_read_buttons(void); extern void Gpio_set_backlight(UINT32 level); From ebc5ae5afc91a70731dfab508fac7ffe1b825d1e Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 20:59:18 -0700 Subject: [PATCH 049/162] compile errors fixed --- src/ep_backlight.c | 1 + src/ep_upiwin.c | 18 +++++++++--------- src/main.c | 1 - 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ep_backlight.c b/src/ep_backlight.c index 04ccec9..af4327b 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -1,5 +1,6 @@ #define PY_SSIZE_T_CLEAN #include +#include "scode.h" #include "gpio.h" #include "ep_upiwin.h" #include "ep_init.h" diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 0434d3c..c4b42d0 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -19,15 +19,15 @@ static PyMethodDef UPIWINMethods[] = { }; static PyModuleDef DefUPIWIN = { - PyModuleDef_HEAD_INIT, /* standard garbage */ - Mod_UPIWIN, /* module name */ - NULL, /* no doc string */ - sizeof(UPIWIN_STATE), /* per-module memory */ - UPIWINMethods, /* method defs */ - NULL, /* no slots for multi-phase init */ - NULL, /* no traversal proc */ - NULL, /* no clear function */ - NULL /* no free function */ + PyModuleDef_HEAD_INIT, /* standard garbage */ + "upiwin", /* module name */ + NULL, /* no doc string */ + sizeof(UPIWIN_STATE), /* per-module memory */ + UPIWINMethods, /* method defs */ + NULL, /* no slots for multi-phase init */ + NULL, /* no traversal proc */ + NULL, /* no clear function */ + NULL /* no free function */ }; PyObject *Epython_init_upiwin_module(void) diff --git a/src/main.c b/src/main.c index d683864..4c10738 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,6 @@ int main(int argc, char *argv[]) HRESULT hr; int running = 1; MSG msg; - char *tmp; /* initialization sequence */ Time_init(); From ffae4e3329aa3910dfc913bb51cfc7f6971a0abb Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 21:18:27 -0700 Subject: [PATCH 050/162] added the upiwin_tmp module definitions --- src/Makefile | 4 +-- src/ep_init.c | 31 +++-------------- src/ep_init.h | 5 +-- src/ep_upiwin.c | 2 +- src/ep_upiwin_tmp.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 src/ep_upiwin_tmp.c diff --git a/src/Makefile b/src/Makefile index 689392e..9afd643 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_util.o fbinit.o fbprimitive.o log.o gpio.o msg_queue.o \ - time_func.o config.o splash.o +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fbprimitive.o \ + log.o gpio.o msg_queue.o time_func.o config.o splash.o LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \ diff --git a/src/ep_init.c b/src/ep_init.c index 2467a59..83f3de3 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -6,37 +6,16 @@ #include "ep_init.h" #include "ep_util.h" -const PCSTR Mod_UPIWIN = "upiwin"; /* name of the primary UPIWIN module */ -const PCSTR Mod_UPIWIN_tmp = "upiwin_tmp"; /* name of the temporary UPIWIN module */ - static wchar_t *python_name = NULL; /* location of the Python executable */ PyObject *UPIWIN_module = NULL; PyObject *UPIWIN_tmp_module = NULL; -static PyModuleDef DefUPIWIN_tmp = { - PyModuleDef_HEAD_INIT, /* standard garbage */ - Mod_UPIWIN, /* module name */ - NULL, /* no doc string */ - -1, /* no per-module memory */ - NULL, /* method defs will be added later */ - NULL, /* no slots for multi-phase init */ - NULL, /* no traversal proc */ - NULL, /* no clear function */ - NULL /* no free function */ -}; - -static PyObject *init_upiwin_tmp_module(void) -{ - PyObject *module = PyModule_Create(&DefUPIWIN_tmp); - return module; -} - /* used to link the two modules into Python's init table */ static struct _inittab upiwin_inittab[] = { - { Mod_UPIWIN, Epython_init_upiwin_module }, - { Mod_UPIWIN_tmp, init_upiwin_tmp_module }, - { NULL, NULL } + { MOD_NAME_UPIWIN, Epython_init_upiwin_module }, + { MOD_NAME_UPIWIN_TMP, Epython_init_upiwin_tmp_module }, + { NULL, NULL } }; static void epython_cleanup(void) @@ -82,14 +61,14 @@ HRESULT Epython_setup(void) Py_Initialize(); /* Import the modules */ - UPIWIN_module = PyImport_ImportModule(Mod_UPIWIN); + UPIWIN_module = PyImport_ImportModule(MOD_NAME_UPIWIN); if (!UPIWIN_module) { Log(LFATAL, "error importing the upiwin module"); hr = Epython_trace_exception(); goto error_1; } - UPIWIN_tmp_module = PyImport_ImportModule(Mod_UPIWIN_tmp); + UPIWIN_tmp_module = PyImport_ImportModule(MOD_NAME_UPIWIN_TMP); if (!UPIWIN_tmp_module) { Log(LFATAL, "error importing the upiwin_tmp module"); diff --git a/src/ep_init.h b/src/ep_init.h index 8d12d97..69cf48c 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -5,13 +5,14 @@ #include #include "wintype.h" -extern const PCSTR Mod_UPIWIN; -extern const PCSTR Mod_UPIWIN_tmp; +#define MOD_NAME_UPIWIN "upiwin" +#define MOD_NAME_UPIWIN_TMP "upiwin_tmp" extern PyObject *UPIWIN_module; extern PyObject *UPIWIN_tmp_module; extern PyObject *Epython_init_upiwin_module(void); +extern PyObject *Epython_init_upiwin_tmp_module(void); extern HRESULT Epython_setup(void); diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index c4b42d0..9c99dc3 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -20,7 +20,7 @@ static PyMethodDef UPIWINMethods[] = { static PyModuleDef DefUPIWIN = { PyModuleDef_HEAD_INIT, /* standard garbage */ - "upiwin", /* module name */ + MOD_NAME_UPIWIN, /* module name */ NULL, /* no doc string */ sizeof(UPIWIN_STATE), /* per-module memory */ UPIWINMethods, /* method defs */ diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c new file mode 100644 index 0000000..5370bba --- /dev/null +++ b/src/ep_upiwin_tmp.c @@ -0,0 +1,81 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "scode.h" +#include "fbprimitive.h" +#include "ep_init.h" + +static PyObject *do_setpixel(PyObject *self, PyObject *args) +{ + INT32 x, y; + UINT16 color, oldcolor; + BOOL xor; + + if (!PyArg_ParseTuple(args, "iiHi", &x, &y, &color, &xor)) + return NULL; + oldcolor = Fb_setpixel(x, y, color, xor); + return PyLong_FromLong((long)oldcolor); +} + +static PyObject *do_line(PyObject *self, PyObject *args) +{ + INT32 x1, y1, x2, y2; + UINT16 color; + BOOL xor; + + if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor)) + return NULL; + Fb_line(x1, y1, x2, y2, color, xor); + Py_RETURN_NONE; +} + +static PyObject *do_rectangle(PyObject *self, PyObject *args) +{ + INT32 x1, y1, x2, y2; + UINT16 color; + BOOL xor; + + if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor)) + return NULL; + Fb_rectangle(x1, y1, x2, y2, color, xor); + Py_RETURN_NONE; +} + +static PyObject *do_filled_rectangle(PyObject *self, PyObject *args) +{ + INT32 x1, y1, x2, y2; + UINT16 color; + BOOL xor; + + if (!PyArg_ParseTuple(args, "iiiiHi", &x1, &y1, &x2, &y2, &color, &xor)) + return NULL; + Fb_filled_rectangle(x1, y1, x2, y2, color, xor); + Py_RETURN_NONE; +} + +static PyMethodDef UPIWIN_tmpMethods[] = { + {"setpixel", do_setpixel, METH_VARARGS, "Set a single pixel on the display."}, + {"line", do_line, METH_VARARGS, "Draw a line on the display."}, + {"rectangle", do_rectangle, METH_VARARGS, "Draw a rectangle on the display."}, + {"filled_rectangle", do_filled_rectangle, METH_VARARGS, "Draw a filled rectangle on the display."}, + {NULL, NULL, 0, NULL} +}; + +static PyModuleDef DefUPIWIN_tmp = { + PyModuleDef_HEAD_INIT, /* standard garbage */ + MOD_NAME_UPIWIN_TMP, /* module name */ + NULL, /* no doc string */ + -1, /* no per-module memory */ + UPIWIN_tmpMethods, /* method defs */ + NULL, /* no slots for multi-phase init */ + NULL, /* no traversal proc */ + NULL, /* no clear function */ + NULL /* no free function */ +}; + +PyObject *Epython_init_upiwin_tmp_module(void) +{ + PyObject *module; + + module = PyModule_Create(&DefUPIWIN); + return module; +} From f30a27ad7cd26586e865978566741c6556171e7e Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 21:20:40 -0700 Subject: [PATCH 051/162] fixed compile errors --- src/ep_upiwin_tmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 5370bba..82fc446 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -76,6 +76,6 @@ PyObject *Epython_init_upiwin_tmp_module(void) { PyObject *module; - module = PyModule_Create(&DefUPIWIN); + module = PyModule_Create(&DefUPIWIN_tmp); return module; } From aa94d80145461cb66eb151068d48b8e1b457e265 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 22:05:31 -0700 Subject: [PATCH 052/162] ready to try executing actual Python within UPIWIN --- scripts/tmp_main.py | 19 +++++++++++++++ src/config.c | 48 ++++++++++++++++++++++++++++++++++++++ src/config.h | 3 +++ src/ep_init.c | 57 +++++++++++++++++++++++++++++++++++++++++++-- src/ep_init.h | 1 + src/main.c | 19 +++------------ src/scode.h | 3 ++- src/wintype.h | 2 ++ 8 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 scripts/tmp_main.py diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py new file mode 100644 index 0000000..12a6781 --- /dev/null +++ b/scripts/tmp_main.py @@ -0,0 +1,19 @@ +# Initial test script +FBPRIMCLR_BLACK = 0x0000 +FBPRIMCLR_RED = 0xF800 +FBPRIMCLR_GREEN = 0x07E0 +FBPRIMCLR_BLUE = 0x001F +FBPRIMCLR_YELLOW = 0xFFE0 +FBPRIMCLR_CYAN = 0x07FF +FBPRIMCLR_MAGENTA = 0xF81F +FBPRIMCLR_WHITE = 0xFFFF + +upiwin_tmp.filled_rectangle(10, 10, 50, 50, FBPRIMCLR_RED, False) +upiwin_tmp.filled_rectangle(60, 10, 100, 50, FBPRIMCLR_GREEN, False) +upiwin_tmp.filled_rectangle(110, 10, 150, 50, FBPRIMCLR_BLUE, False) +upiwin_tmp.filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, False) +upiwin_tmp.filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, False) +upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False) +upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False) diff --git a/src/config.c b/src/config.c index d9aa37a..ecf476c 100644 --- a/src/config.c +++ b/src/config.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -75,6 +76,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) { int c; PSTR pstr; + PPCSTR pargs; BOOL help = FALSE; memset(parsed, 0, sizeof(GLOBAL_CONFIG)); @@ -123,6 +125,48 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) fputs(helptext, stdout); return S_FALSE; } + + if (optind < argc) + { + pstr = realpath(argv[optind], NULL); /* implicit strdup */ + if (!pstr) + { + Log(LERROR, "Out of memory in parse_cmdline"); + return E_OUTOFMEMORY; + } + if (access(pstr, R_OK)) + { + fprintf(stderr, "%s: script %s not found\n", argv[0], pstr); + return UPIWIN_E_INVALIDSCRIPT; + } + parsed->script_name = pstr; + if (++optind < argc) + { + parsed->script_arg_count = argc - optind; + pargs = (PPCSTR)malloc(sizeof(PCSTR) * parsed->script_arg_count); + if (!pargs) + { + Log(LERROR, "Out of memory in parse_cmdline"); + return E_OUTOFMEMORY; + } + for (c = 0; c < parsed->script_arg_count; c++) + { + pargs[c] = strdup(argv[optind++]); + if (!(pargs[c])) + { + Log(LERROR, "Out of memory in parse_cmdline"); + return E_OUTOFMEMORY; + } + } + parsed->script_args = pargs; + } + } + else + { + fprintf(stderr, "%s: no script specified\n", argv[0], c); + return UPIWIN_E_NOSCRIPT; + } + return S_OK; } @@ -132,6 +176,10 @@ static void overlay_config(GLOBAL_CONFIG *p) Gconfig.framebuffer_device = p->framebuffer_device; if (p->touchscreen_device) Gconfig.touchscreen_device = p->touchscreen_device; + /* always overlay the script name and arguments */ + Gconfig.script_name = p->script_name; + Gconfig.script_arg_count = p->script_arg_count; + Gconfig.script_args = p->script_args; } HRESULT Config_setup(int argc, char *argv[]) diff --git a/src/config.h b/src/config.h index 1bb94e4..0a514a7 100644 --- a/src/config.h +++ b/src/config.h @@ -12,6 +12,9 @@ typedef struct tagGLOBAL_CONFIG { PCSTR python_loc; /* location of the Python3 executable */ UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ UINT32 sys_mq_length; /* length of system message queue */ + PCSTR script_name; /* script name to be run */ + INT32 script_arg_count; /* number of arguments to pass to the script */ + PPCSTR script_args; /* arguments to pass to the script */ } GLOBAL_CONFIG; extern GLOBAL_CONFIG Gconfig; /* one global configuration to rule them all */ diff --git a/src/ep_init.c b/src/ep_init.c index 83f3de3..3eba18b 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -1,3 +1,6 @@ +#include +#include +#include #define PY_SSIZE_T_CLEAN #include #include "scode.h" @@ -24,8 +27,7 @@ static void epython_cleanup(void) UPIWIN_tmp_module = NULL; Py_DECREF(UPIWIN_module); UPIWIN_module = NULL; - if (!Py_FinalizeEx()) - Log(LWARN, "errors encountered when Python uninitialized itself"); + Py_FinalizeEx(); PyMem_RawFree(python_name); python_name = NULL; } @@ -91,3 +93,54 @@ error_0: python_name = NULL; return hr; } + +HRESULT Epython_run(void) +{ + HRESULT hr = S_OK; + int i; + FILE *fp; + wchar_t **args; + + Log(LINFO, "Ready to execute %s", Gconfig.script_name); + fp = fopen(Gconfig.script_name, "rb"); + if (fp) + { + args = (wchar_t **)alloca((Gconfig.script_arg_count + 1) * sizeof(wchar_t *)); + memset(args, 0, (Gconfig.script_arg_count + 1) * sizeof(wchar_t *)); + args[0] = Py_DecodeLocale(Gconfig.script_name, NULL); + if (args[0]) + { + for (i=0; i Date: Sat, 7 Dec 2019 22:09:27 -0700 Subject: [PATCH 053/162] fixed compile and runtime errors --- scripts/tmp_main.py | 2 ++ src/config.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 12a6781..02799af 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,4 +1,6 @@ # Initial test script +import upiwin_tmp + FBPRIMCLR_BLACK = 0x0000 FBPRIMCLR_RED = 0xF800 FBPRIMCLR_GREEN = 0x07E0 diff --git a/src/config.c b/src/config.c index ecf476c..5345597 100644 --- a/src/config.c +++ b/src/config.c @@ -163,7 +163,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) } else { - fprintf(stderr, "%s: no script specified\n", argv[0], c); + fprintf(stderr, "%s: no script specified\n", argv[0]); return UPIWIN_E_NOSCRIPT; } From 30106490c0e55a9eb166045954489f0e8e524c53 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 23:30:05 -0700 Subject: [PATCH 054/162] add text out capabilities using FreeType and the Inconsolata font --- scripts/tmp_main.py | 1 + src/Makefile | 7 ++-- src/ep_upiwin_tmp.c | 12 +++++++ src/fbprimitive.c | 31 +++++++++++++++++ src/fbprimitive.h | 1 + src/fontengine.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/fontengine.h | 11 ++++++ src/main.c | 2 ++ 8 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 src/fontengine.c create mode 100644 src/fontengine.h diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 02799af..f57eaef 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -19,3 +19,4 @@ upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False) upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False) upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False) upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False) +upiwin_tmp.textout(10, 180, 'Amy was here!!!') diff --git a/src/Makefile b/src/Makefile index 9afd643..b757ace 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,8 @@ -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fbprimitive.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fontengine.o 6fbprimitive.o \ log.o gpio.o msg_queue.o time_func.o config.o splash.o -LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm -CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT +LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm +CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \ + -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \ -Wl,-Bsymbolic-functions diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 82fc446..339f72a 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -52,11 +52,23 @@ static PyObject *do_filled_rectangle(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *do_textout(PyObject *self, PyObject *args) +{ + INT32 x, y; + PSTR text; + + if (!PyArg_ParseTuple(args, "iis", &x, &y, &text)) + return NULL; + Fb_textout(x, y, text); + Py_RETURN_NONE; +} + static PyMethodDef UPIWIN_tmpMethods[] = { {"setpixel", do_setpixel, METH_VARARGS, "Set a single pixel on the display."}, {"line", do_line, METH_VARARGS, "Draw a line on the display."}, {"rectangle", do_rectangle, METH_VARARGS, "Draw a rectangle on the display."}, {"filled_rectangle", do_filled_rectangle, METH_VARARGS, "Draw a filled rectangle on the display."}, + {"textout", do_textout, METH_VARARGS, "Draw text on the display."}, {NULL, NULL, 0, NULL} }; diff --git a/src/fbprimitive.c b/src/fbprimitive.c index f434226..72d1ad0 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,3 +1,4 @@ +#include #include "wintype.h" #include "fbinit.h" @@ -112,3 +113,33 @@ void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, B ps += Fb_Info->width; } } + +static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits) +{ + INT32 i, j; + BYTE b; + PUINT16 dptr, lbuf; + + if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height)) + return; + dptr = loc_from_coords(x, y); + lbuf = (PUINT16)alloca(width * sizeof(UINT16)); + for (i=0; i> 3) & 0x1F) << 11; + lbuf[i] |= ((UINT16)(b >> 2) & 0x3F) << 5; + lbuf[i] |= ((UINT16)(b >> 3) & 0x1F); + } + + memcpy(dptr, lbuf, width * sizeof(UINT16)); + dptr += Fb_Info->width; + } +} + +void Fb_textout(INT32 x, INT32 y, PCSTR pstr) +{ + FontEng_do_text_out(x, y, pstr, internal_textout); +} diff --git a/src/fbprimitive.h b/src/fbprimitive.h index 8f0ea8e..a9c4e52 100644 --- a/src/fbprimitive.h +++ b/src/fbprimitive.h @@ -17,5 +17,6 @@ extern UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor); extern void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); extern void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); extern void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor); +extern void Fb_textout(INT32 x, INT32 y, PCSTR pstr); #endif /* __FBPRIMITIVE_H_INCLUDED */ diff --git a/src/fontengine.c b/src/fontengine.c new file mode 100644 index 0000000..f8bfd7f --- /dev/null +++ b/src/fontengine.c @@ -0,0 +1,84 @@ +#include +#include FT_FREETYPE_H +#include "scode.h" +#include "config.h" +#include "log.h" +#include "fontengine.h" + +static FT_LIbrary library; +static FT_Face stdfont; + +static void fonteng_cleanup(void) +{ + FT_Done_Face(stdfont); + FT_Done_FreeType(library); +} + +HRESULT FontEng_setup(void) +{ + HRESULT hr = S_OK; + FT_Error err; + + err = FT_Init_FreeType(&library); + if (err != 0) + { + Log(LFATAL, "Unable to initialize Freetype (%d)", err); + return E_FAIL; + } + + err = FT_New_Face(library, "/usr/local/share/fonts/opentype/Inconsolata.otf", 0, &stdfont); + if (err != 0) + { + Log(LFATAL, "Unable to load font (%d)", err); + hr = E_FAIL; + goto error_0; + } + + err = FT_Set_Pixel_Sizes(stdfont, 0, 16); + if (err != 0) + { + Log(LFATAL, "Unable to set font size (%d)", err); + hr = E_FAIL; + goto error_1; + } + + hr = Config_exitfunc(fonteng_cleanup); + if (FAILED(hr)) + fonteng_cleanup(); + return hr; + +error_1: + FT_Done_Face(stdfont); +error_0: + FT_Done_FreeType(library); + return hr; +} + +HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc) +{ + HRESULT hr = S_OK; + FT_GlyphSlot slot = stdfont->glyph; + FT_UInt glyph_index; + FT_Error err; + + while (*pstr) + { + glyph_index = FT_Get_Char_Index(stdfont, *pstr++); + err = FT_Load_Glyph(stdfont, glyph_index, FT_LOAD_DEFAULT); + if (err != 0) + { + hr = E_FAIL; + break; + } + err = FT_Render_Glyph(stdfont->glyph, FT_RENDER_MODE_NORMAL); + if (err != 0) + { + hr = E_FAIL; + break; + } + (*renderfunc)(x, y, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.buffer); + x += slot->advance.x >> 6; + y += slot->advance.y >> 6; + } + return hr; +} diff --git a/src/fontengine.h b/src/fontengine.h new file mode 100644 index 0000000..5fa9187 --- /dev/null +++ b/src/fontengine.h @@ -0,0 +1,11 @@ +#ifndef __FONTENGINE_H_INCLUDED +#define __FONTENGINE_H_INCLUDED + +#include "wintype.h" + +typedef void (*TEXTOUTFUNC)(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits); + +extern HRESULT FontEng_setup(void); +extern HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc); + +#endif /* __FONTENGINE_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 9cadb84..957b5a0 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,8 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; if (FAILED(Fb_setup())) return EXIT_FAILURE; + if (FAILED(FontEng_setup())) + return EXIT_FAILURE; if (FAILED(Gpio_setup())) return EXIT_FAILURE; if (FAILED(Epython_setup())) From 6af1c1c0588b16e5d628cf6b092675966fb5916d Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 23:37:21 -0700 Subject: [PATCH 055/162] fixed compile errors --- src/Makefile | 2 +- src/fbprimitive.c | 3 +++ src/fontengine.c | 2 +- src/main.c | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index b757ace..835818e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fontengine.o 6fbprimitive.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.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/fbprimitive.c b/src/fbprimitive.c index 72d1ad0..325ef2f 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,6 +1,9 @@ +#include #include #include "wintype.h" #include "fbinit.h" +#include "fontengine.h" +#include "fbprimitive.h" inline static PUINT16 loc_from_coords(INT32 x, INT32 y) { diff --git a/src/fontengine.c b/src/fontengine.c index f8bfd7f..6ed7ec7 100644 --- a/src/fontengine.c +++ b/src/fontengine.c @@ -5,7 +5,7 @@ #include "log.h" #include "fontengine.h" -static FT_LIbrary library; +static FT_Library library; static FT_Face stdfont; static void fonteng_cleanup(void) diff --git a/src/main.c b/src/main.c index 957b5a0..21e8622 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include "log.h" #include "fbinit.h" #include "fbprimitive.h" +#include "fontengine.h" #include "time_func.h" #include "ep_init.h" #include "sysinput.h" From cc074e33e887624e94184a4c7d4bb799a7297799 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 23:41:55 -0700 Subject: [PATCH 056/162] looks like I'm doing disco debugging --- src/fbprimitive.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fbprimitive.c b/src/fbprimitive.c index 325ef2f..2ba096f 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,6 +1,7 @@ #include #include #include "wintype.h" +#inlcude "log.h" #include "fbinit.h" #include "fontengine.h" #include "fbprimitive.h" @@ -122,21 +123,24 @@ static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE INT32 i, j; BYTE b; PUINT16 dptr, lbuf; - + + Log(LDEBUG, "internal_textout(%d, %d, %d, %d, bits)", x, y, width, height); if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height)) return; dptr = loc_from_coords(x, y); lbuf = (PUINT16)alloca(width * sizeof(UINT16)); for (i=0; i> 3) & 0x1F) << 11; - lbuf[i] |= ((UINT16)(b >> 2) & 0x3F) << 5; - lbuf[i] |= ((UINT16)(b >> 3) & 0x1F); + lbuf[j] = ((UINT16)(b >> 3) & 0x1F) << 11; + lbuf[j] |= ((UINT16)(b >> 2) & 0x3F) << 5; + lbuf[j] |= ((UINT16)(b >> 3) & 0x1F); } + Log(LDEBUG, "rendering row %d", i); memcpy(dptr, lbuf, width * sizeof(UINT16)); dptr += Fb_Info->width; } From 68c9a64f8d97b3f1e495ca963c5ef56f0e779ebb Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 23:45:32 -0700 Subject: [PATCH 057/162] tyop fix --- src/fbprimitive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fbprimitive.c b/src/fbprimitive.c index 2ba096f..a7f0ea0 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,7 +1,7 @@ #include #include #include "wintype.h" -#inlcude "log.h" +#include "log.h" #include "fbinit.h" #include "fontengine.h" #include "fbprimitive.h" From 608fbec2bf8ab3a47717d2d434e3180f532dff59 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 7 Dec 2019 23:59:00 -0700 Subject: [PATCH 058/162] try to fix rendering of text --- src/fbprimitive.c | 2 -- src/fontengine.c | 8 ++++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/fbprimitive.c b/src/fbprimitive.c index a7f0ea0..189c62d 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -131,7 +131,6 @@ static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE lbuf = (PUINT16)alloca(width * sizeof(UINT16)); for (i=0; i> 3) & 0x1F); } - Log(LDEBUG, "rendering row %d", i); memcpy(dptr, lbuf, width * sizeof(UINT16)); dptr += Fb_Info->width; } diff --git a/src/fontengine.c b/src/fontengine.c index 6ed7ec7..f392706 100644 --- a/src/fontengine.c +++ b/src/fontengine.c @@ -61,9 +61,11 @@ HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc FT_UInt glyph_index; FT_Error err; + y += (stdfont->size->metrics.ascender >> 6); + while (*pstr) { - glyph_index = FT_Get_Char_Index(stdfont, *pstr++); + glyph_index = FT_Get_Char_Index(stdfont, *pstr); err = FT_Load_Glyph(stdfont, glyph_index, FT_LOAD_DEFAULT); if (err != 0) { @@ -76,9 +78,11 @@ HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc hr = E_FAIL; break; } - (*renderfunc)(x, y, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.buffer); + (*renderfunc)(x + slot->bitmap_left, y - slot->bitmap_top, slot->bitmap.width, + slot->bitmap.rows, slot->bitmap.buffer); x += slot->advance.x >> 6; y += slot->advance.y >> 6; + pstr++; } return hr; } From 161a854502210be1ae1d746fbcfdfe9fbb67f0a7 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 8 Dec 2019 00:07:28 -0700 Subject: [PATCH 059/162] checking out text rendering --- scripts/tmp_main.py | 3 +++ src/fbprimitive.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index f57eaef..e694840 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -19,4 +19,7 @@ upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False) upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False) upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False) upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False) + +upiwin_tmp.line(0, 180, 319, 180, FBPRIMCLR_RED, False); +upiwin_tmp.line(0, 196, 319, 196, FBPRIMCLR_RED, False); upiwin_tmp.textout(10, 180, 'Amy was here!!!') diff --git a/src/fbprimitive.c b/src/fbprimitive.c index 189c62d..fe3e6ab 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -124,7 +124,8 @@ static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE BYTE b; PUINT16 dptr, lbuf; - Log(LDEBUG, "internal_textout(%d, %d, %d, %d, bits)", x, y, width, height); + if ((width == 0) && (height == 0)) + return; /* must be drawing a space */ if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height)) return; dptr = loc_from_coords(x, y); From fb42797d5a2a94dd4491a5126e3229f7f389d30d Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sun, 8 Dec 2019 00:40:01 -0700 Subject: [PATCH 060/162] use Arial as the font for display --- src/fontengine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fontengine.c b/src/fontengine.c index f392706..ddc663d 100644 --- a/src/fontengine.c +++ b/src/fontengine.c @@ -26,7 +26,7 @@ HRESULT FontEng_setup(void) return E_FAIL; } - err = FT_New_Face(library, "/usr/local/share/fonts/opentype/Inconsolata.otf", 0, &stdfont); + err = FT_New_Face(library, "/usr/local/share/fonts/truetype/arial.ttf", 0, &stdfont); if (err != 0) { Log(LFATAL, "Unable to load font (%d)", err); From cc00d7a5efc7ca27ffde4afa1ef3aec9a084fd3a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 10:14:20 -0700 Subject: [PATCH 061/162] changed the splash screen and added a test to make sure we run as root --- src/splash.png => resources/splash-erbosoft.png | Bin resources/splash-vmwcblk.png | Bin 0 -> 8055 bytes src/Makefile | 8 ++++++-- src/config.c | 6 ++++++ 4 files changed, 12 insertions(+), 2 deletions(-) rename src/splash.png => resources/splash-erbosoft.png (100%) create mode 100755 resources/splash-vmwcblk.png diff --git a/src/splash.png b/resources/splash-erbosoft.png similarity index 100% rename from src/splash.png rename to resources/splash-erbosoft.png diff --git a/resources/splash-vmwcblk.png b/resources/splash-vmwcblk.png new file mode 100755 index 0000000000000000000000000000000000000000..1b33a4e17b5792f627d177d70d1ee9c7d9fa564b GIT binary patch literal 8055 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 G&;J2>_*m-z literal 0 HcmV?d00001 diff --git a/src/Makefile b/src/Makefile index 835818e..16b5f0c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,7 @@ +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 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 @@ -18,8 +22,8 @@ splash.o: splash.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o -splash.bin: splash.png ../buildutils/mksplash - ../buildutils/mksplash splash.png splash.bin +splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mksplash + $(BUILDUTILS)/mksplash $(RESOURCES)/$(SPLASHSCREEN) splash.bin clean: rm -f upiwin *.o splash.bin *~ diff --git a/src/config.c b/src/config.c index 5345597..cc2b67f 100644 --- a/src/config.c +++ b/src/config.c @@ -187,6 +187,12 @@ HRESULT Config_setup(int argc, char *argv[]) HRESULT hr; GLOBAL_CONFIG from_commandline; + if (geteuid() != 0) + { + Log(LFATAL, "upiwin must be run with root privileges"); + return E_ACCESSDENIED; + } + if (atexit(run_exit_funcs)) { Log(LFATAL, "Unable to set up exit function mechanism"); From 69a4c42d6871ef2a88a96590dba78760a4d61ff4 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:18:24 -0700 Subject: [PATCH 062/162] added the rectangle functions and a "wait for input" mechanism to the system input thread --- src/Makefile | 2 +- src/gfxtype.h | 31 +++++++++++++++++ src/msg_queue.c | 9 +++++ src/msg_queue.h | 1 + src/rect.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ src/sysinput.c | 79 +++++++++++++++++++++++++++++------------- src/sysinput.h | 1 + 7 files changed, 189 insertions(+), 25 deletions(-) create mode 100755 src/gfxtype.h create mode 100755 src/rect.c diff --git a/src/Makefile b/src/Makefile index 16b5f0c..bcc135c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ 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 fontengine.o fbprimitive.o \ +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 \ 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/gfxtype.h b/src/gfxtype.h new file mode 100755 index 0000000..e992d9e --- /dev/null +++ b/src/gfxtype.h @@ -0,0 +1,31 @@ +#ifndef __GFXTYPE_H_INCLUDED +#define __GFXTYPE_H_INCLUDED + +#include "wintype.h" + +typedef struct tagPOINT { + INT32 x; + INT32 y; +} POINT, *PPOINT; + +typedef struct tagRECT { + INT32 left; + INT32 top; + INT32 right; + INT32 bottom; +} RECT, *PRECT; + +typedef const POINT *PCPOINT; +typedef const RECT *PCRECT; + +extern BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom); +extern BOOL G_set_rect_empty(PRECT rect); +extern BOOL G_inflate_rect(PRECT rect, int dx, int dy); +extern BOOL G_offset_rect(PRECT rect, int dx, int dy); +extern BOOL G_is_rect_empty(PCRECT rect); +extern BOOL G_point_in_rect(PCRECT rect, PCPOINT pt); +extern BOOL G_rect_equal(PCRECT rect1, PCRECT rect2); +extern BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2); +extern BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2); + +#endif /* __GFXTYPE_H_INCLUDED */ diff --git a/src/msg_queue.c b/src/msg_queue.c index 61252ad..566dc0e 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -93,3 +93,12 @@ BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags) pthread_mutex_unlock(&(queue->mutex)); return rc; } + +BOOL Mq_is_empty(PMSG_QUEUE queue) +{ + BOOL rc; + pthread_mutex_lock(&(queue->mutex)); + rc = (queue->head == queue->tail); + pthread_mutex_unlock(&(queue->mutex)); + return rc; +} diff --git a/src/msg_queue.h b/src/msg_queue.h index 10c49ae..6ca5f75 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -26,6 +26,7 @@ extern void Mq_destroy(PMSG_QUEUE queue); extern void Mq_post(PMSG_QUEUE queue, HANDLE target, UINT32 message, const UINT_PTR *attrs, int nattrs); extern void Mq_post2(PMSG_QUEUE queue, HANDLE target, UINT32 message, UINT_PTR attr1, UINT_PTR attr2); extern BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags); +extern BOOL Mq_is_empty(PMSG_QUEUE queue); #define Mq_post0(q, tgt, msg) Mq_post2(q, tgt, msg, 0, 0) #define Mq_post1(q, tgt, msg, attr) Mq_post2(q, tgt, msg, attr, 0) diff --git a/src/rect.c b/src/rect.c new file mode 100755 index 0000000..b4cc505 --- /dev/null +++ b/src/rect.c @@ -0,0 +1,91 @@ +#include +#include "log.h" +#include "gfxtype.h" + +BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom) +{ + rect->left = left; + rect->top = top; + rect->right = right; + rect->bottom = bottom; + return TRUE; +} + +BOOL G_set_rect_empty(PRECT rect) +{ + memset(rect, 0, sizeof(RECT)); + return TRUE; +} + +BOOL G_inflate_rect(PRECT rect, int dx, int dy) +{ + rect->left += dx; + rect->top += dy; + rect->right -= dx; + rect->bottom -= dy; + return TRUE; +} + +BOOL G_offset_rect(PRECT rect, int dx, int dy) +{ + rect->left += dx; + rect->top += dy; + rect->right += dx; + rect->bottom += dy; + return TRUE; +} + +BOOL G_is_rect_empty(PCRECT rect) +{ + return (rect->right <= rect.left) || (rect->bottom <= rect.top); +} + +BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) +{ + return (rect->left <= pt->x) && (pt->x < rect->right) && (rect->top <= pt->y) && (pt->y < rect->bottom); +} + +BOOL G_rect_equal(PCRECT rect1, PCRECT rect2) +{ + return (memcmp(rect1, rect2, sizeof(RECT)) == 0); +} + +BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2) +{ + if (G_is_rect_empty(src1) || G_is_rect_empty(src2)) + { + memset(dest, 0, sizeof(RECT)); + return FALSE; + } + if ((src1->left >= src2->right) || (src2->left >= src1->right) || (src1->top >= src2->bottom) || (src2->top >= src1->bottom)) + { + memset(dest, 0, sizeof(RECT)); + return FALSE; + } + dest->left = MAX(src1->left, src2->left); + dest->top = MAX(src1->top, src2->top); + dest->right = MIN(src1->right, src2->right); + dest->bottom = MIN(src1->bottom, src2->bottom); + ASSERT(dest->left <= dest->right); + ASSERT(dest->top <= dest->bottom); + return TRUE; +} + +BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2) +{ + if (G_is_rect_empty(src1)) + { + memcpy(dest, src2, sizeof(RECT)); + return !G_is_rect_empty(src2); + } + else if (G_is_rect_empty(src2)) + { + memcpy(dest, src1, sizeof(RECT)); + return TRUE; + } + dest->left = MIN(src1->left, src2->left); + dest->top = MIN(src1->top, src2->top); + dest->right = MAX(src1->right, src2->right); + dest->bottom = MAX(src1->bottom, src2->bottom); + return TRUE; +} diff --git a/src/sysinput.c b/src/sysinput.c index 530489c..28e7864 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -21,6 +21,9 @@ static int ts_fd = 0; /* file descriptor for touchscreen */ static pthread_t ithread; /* input thread handle */ static volatile sig_atomic_t running = 1; /* "running" flag for input thread */ +static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER; /* mutex for waiting on input */ +static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for waiting on input */ + /* Local data for poll_buttons() */ static UINT32 last_bstate = 0; /* previous button state */ static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ @@ -30,8 +33,9 @@ static UINT_PTR touch_x = 0; /* X coordinate to send with next static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ -static void poll_buttons(void) +static BOOL poll_buttons(void) { + BOOL posted = FALSE; UINT32 st, down, up, mask; UINT_PTR attr; TIMESTAMP now; @@ -46,22 +50,28 @@ static void poll_buttons(void) for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1) { if (now < button_event_ok[attr - 1]) - continue; /* this is a "contact bounce" event, don't bother */ + continue; /* this is a "contact bounce" event, don't bother */ if (up & mask) { - /* reset contact bounce timer - only seems to happen after button releases */ - button_event_ok[attr - 1] = now + Gconfig.button_debounce; - Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + /* reset contact bounce timer - only seems to happen after button releases */ + button_event_ok[attr - 1] = now + Gconfig.button_debounce; + Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + posted = TRUE; } else if (down & mask) - Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + { + Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + posted = TRUE; + } } last_bstate = st; } + return posted; } -static void poll_touchscreen(void) +static BOOL poll_touchscreen(void) { + BOOL posted = FALSE; int nb, nev, xerrno, i; struct input_event buffer[INPUT_EVENT_BATCH]; @@ -89,33 +99,37 @@ static void poll_touchscreen(void) switch (buffer[i].type) { case EV_SYN: - if (buffer[i].code == SYN_REPORT) - { - Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); - touch_nextmsg = WM_TOUCHMOVE; - } - break; + if (buffer[i].code == SYN_REPORT) + { + Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); + touch_nextmsg = WM_TOUCHMOVE; + posted = TRUE; + } + break; case EV_ABS: - if (buffer[i].code == ABS_X) - touch_x = buffer[i].value; - else if (buffer[i].code == ABS_Y) - touch_y = buffer[i].value; - break; + if (buffer[i].code == ABS_X) + touch_x = buffer[i].value; + else if (buffer[i].code == ABS_Y) + touch_y = buffer[i].value; + break; case EV_KEY: - if (buffer[i].code == BTN_TOUCH) - touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP); - break; + if (buffer[i].code == BTN_TOUCH) + touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP); + break; default: - break; + break; } } + return posted; } static void *input_thread(void *arg) { + BOOL gotinput; + /* clear all state at startup */ last_bstate = 0; memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP)); @@ -124,8 +138,14 @@ static void *input_thread(void *arg) while (running) { - poll_buttons(); - poll_touchscreen(); + gotinput = poll_buttons(); + gotinput = poll_touchscreen() || gotinput; + if (gotinput) + { + pthread_mutex_lock(&wait_mutex); + pthread_cond_signal(&wait_cond); + pthread_mutex_unlock(&wait_mutex); + } } return NULL; } @@ -178,4 +198,15 @@ HRESULT Sys_enable_input(void) do_disable_input(); } return rc; + +error_0: + return rc; +} + +void Sys_wait_for_input(void) +{ + pthread_mutex_lock(&wait_mutex); + while (Mq_is_empty(Sys_Queue)) + pthread_cond_wait(&wait_cond); + pthread_mutex_unlock(&wait_mutex); } diff --git a/src/sysinput.h b/src/sysinput.h index 8f316d0..e39c6e1 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -7,5 +7,6 @@ extern PMSG_QUEUE Sys_Queue; extern HRESULT Sys_enable_input(void); +extern void Sys_wait_for_input(void); #endif /* __SYSINPUT_H_INCLUDED */ From 746962454d698f1a109bf6f4b184bf91db551a56 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:20:21 -0700 Subject: [PATCH 063/162] fixed build error --- src/sysinput.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index 28e7864..ebc0ae5 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -81,12 +81,12 @@ static BOOL poll_touchscreen(void) xerrno = errno; if ((xerrno != EAGAIN) && (xerrno != EWOULDBLOCK)) Log(LERROR, "Error reading from touchscreen device (%d)", xerrno); - return; + return FALSE; } else if (nb == 0) { Log(LERROR, "Unexpected end of file reading from touchscreen device"); - return; + return FALSE; } nev = nb / sizeof(struct input_event); @@ -207,6 +207,6 @@ void Sys_wait_for_input(void) { pthread_mutex_lock(&wait_mutex); while (Mq_is_empty(Sys_Queue)) - pthread_cond_wait(&wait_cond); + pthread_cond_wait(&wait_cond, &wait_mutex); pthread_mutex_unlock(&wait_mutex); } From 4bef88aecc404a239dd10cfe100412c558fef0fb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:23:06 -0700 Subject: [PATCH 064/162] finished restructuring Sys_enable_input --- src/sysinput.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index ebc0ae5..788547e 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -176,9 +176,8 @@ HRESULT Sys_enable_input(void) if (ts_fd < 0) { rc = ERRNO_AS_SCODE; - Mq_destroy(Sys_Queue); Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc); - return rc; + goto error_0; } running = 1; @@ -186,20 +185,20 @@ HRESULT Sys_enable_input(void) if (threadrc != 0) { rc = SCODE_FROM_ERRNO(threadrc); - close(ts_fd); - ts_fd = -1; - Mq_destroy(Sys_Queue); Log(LFATAL, "Unable to start system input thread (%08X).", rc); + goto error_1; } - if (SUCCEEDED(rc)) - { - rc = Config_exitfunc(do_disable_input); - if (FAILED(rc)) - do_disable_input(); - } - return rc; + rc = Config_exitfunc(do_disable_input); + if (FAILED(rc)) + do_disable_input(); + return rc; + +error_1: + close(ts_fd); + ts_fd = -1; error_0: + Mq_destroy(Sys_Queue); return rc; } From c97b0f7194479cebb16590813b8e6a51547b2db3 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 11:24:19 -0700 Subject: [PATCH 065/162] fixed build error in rect --- src/rect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rect.c b/src/rect.c index b4cc505..2f1c318 100755 --- a/src/rect.c +++ b/src/rect.c @@ -37,7 +37,7 @@ BOOL G_offset_rect(PRECT rect, int dx, int dy) BOOL G_is_rect_empty(PCRECT rect) { - return (rect->right <= rect.left) || (rect->bottom <= rect.top); + return (rect->right <= rect->left) || (rect->bottom <= rect->top); } BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) From 5ff7bd08585617ffed3c478f14057489406c7b1c Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:28:28 -0700 Subject: [PATCH 066/162] added constant registration capability --- scripts/tmp_main.py | 31 +++++++++++-------------------- src/ep_upiwin_tmp.c | 21 +++++++++++++++++++++ src/ep_util.c | 30 ++++++++++++++++++++++++++++++ src/ep_util.h | 19 +++++++++++++++++++ 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index e694840..9152af5 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,25 +1,16 @@ # Initial test script import upiwin_tmp -FBPRIMCLR_BLACK = 0x0000 -FBPRIMCLR_RED = 0xF800 -FBPRIMCLR_GREEN = 0x07E0 -FBPRIMCLR_BLUE = 0x001F -FBPRIMCLR_YELLOW = 0xFFE0 -FBPRIMCLR_CYAN = 0x07FF -FBPRIMCLR_MAGENTA = 0xF81F -FBPRIMCLR_WHITE = 0xFFFF +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) +upiwin_tmp.filled_rectangle(10, 60, 50, 100, upiwin_tmp.FBPRIMCLR_CYAN, False) +upiwin_tmp.filled_rectangle(60, 60, 100, 100, upiwin_tmp.FBPRIMCLR_MAGENTA, False) +upiwin_tmp.filled_rectangle(110, 60, 150, 100, upiwin_tmp.FBPRIMCLR_YELLOW, False) +upiwin_tmp.rectangle(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 110, 150, 150, upiwin_tmp.FBPRIMCLR_WHITE, False) +upiwin_tmp.line(10, 150, 150, 110, upiwin_tmp.FBPRIMCLR_WHITE, False) -upiwin_tmp.filled_rectangle(10, 10, 50, 50, FBPRIMCLR_RED, False) -upiwin_tmp.filled_rectangle(60, 10, 100, 50, FBPRIMCLR_GREEN, False) -upiwin_tmp.filled_rectangle(110, 10, 150, 50, FBPRIMCLR_BLUE, False) -upiwin_tmp.filled_rectangle(10, 60, 50, 100, FBPRIMCLR_CYAN, False) -upiwin_tmp.filled_rectangle(60, 60, 100, 100, FBPRIMCLR_MAGENTA, False) -upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False) -upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False) -upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False) -upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False) - -upiwin_tmp.line(0, 180, 319, 180, FBPRIMCLR_RED, False); -upiwin_tmp.line(0, 196, 319, 196, FBPRIMCLR_RED, 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!!!') diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 339f72a..51adcfb 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -3,6 +3,7 @@ #include "scode.h" #include "fbprimitive.h" #include "ep_init.h" +#include "ep_util.h" static PyObject *do_setpixel(PyObject *self, PyObject *args) { @@ -84,10 +85,30 @@ static PyModuleDef DefUPIWIN_tmp = { NULL /* no free function */ }; +BEGIN_CONSTANT_TABLE(UPIWIN_tmpConstants) + /* primitive color values */ + CONSTANT_INT_MACRO(FBPRIMCLR_BLACK) + CONSTANT_INT_MACRO(FBPRIMCLR_RED) + CONSTANT_INT_MACRO(FBPRIMCLR_GREEN) + CONSTANT_INT_MACRO(FBPRIMCLR_BLUE) + CONSTANT_INT_MACRO(FBPRIMCLR_YELLOW) + CONSTANT_INT_MACRO(FBPRIMCLR_CYAN) + CONSTANT_INT_MACRO(FBPRIMCLR_MAGENTA) + CONSTANT_INT_MACRO(FBPRIMCLR_WHITE) +END_CONSTANT_TABLE + PyObject *Epython_init_upiwin_tmp_module(void) { PyObject *module; module = PyModule_Create(&DefUPIWIN_tmp); + if (module) + { + if (FAILED(Epython_register_constants(module, UPIWIN_tmpConstants))) + { + Py_DECREF(module); + module = NULL; + } + } return module; } diff --git a/src/ep_util.c b/src/ep_util.c index ee12f4a..61184af 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -42,3 +42,33 @@ HRESULT Epython_trace_exception(void) Py_DECREF(traceback); return hr; } + +HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) +{ + HRESULT hr = S_OK; + int i = 0, rc; + + while (const_table[i].name) + { + switch (const_table[i].regtype) + { + case 'i': + rc = PyModule_AddIntConstant(module, const_table[i].name, const_table[i].value.ival); + break; + case 's': + rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval); + break; + default; + Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); + return E_UNEXPECTED; + } + if (!rc) + { + hr = E_FAIL; + break; + } + ++i; + } + + return hr; +} diff --git a/src/ep_util.h b/src/ep_util.h index 5644889..0406aca 100644 --- a/src/ep_util.h +++ b/src/ep_util.h @@ -5,7 +5,26 @@ #include #include "wintype.h" +typedef struct tagREGCONSTANT { + CHAR regtype; + PCSTR name; + union { + LONG ival; + PCSTR sval; + } value; +} REGCONSTANT, *PREGCONSTANT; + +typedef const REGCONSTANT *PCREGCONSTANT; + extern void Epython_log_object(int level, const char *label, PyObject *object); extern HRESULT Epython_trace_exception(void); +extern HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table); + +#define BEGIN_CONSTANT_TABLE(name) static const REGCONSTANT name[] = { +#define CONSTANT_INT(name, value) { 'i', name, { .ival = value } }, +#define CONSTANT_INT_MACRO(mac) CONSTANT_INT(#mac, mac) +#define CONSTANT_STRING(name, value) { 's', name, { .sval = value } }, +#define CONSTANT_STRING_MACRO(mac) CONSTANT_STRING(#mac, mac) +#define END_CONSTANT_TABLE { 0, NULL, { .sval = NULL } } }; #endif /* __EP_UTIL_H_INCLUDED */ From ccde6c71f92814191f7b5b6a69e919182e0eb885 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Mon, 9 Dec 2019 12:30:27 -0700 Subject: [PATCH 067/162] fixed typo --- src/ep_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_util.c b/src/ep_util.c index 61184af..456b5a8 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -58,7 +58,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) case 's': rc = PyModule_AddStringConstant(module, const_table[i].name, const_table[i].value.sval); break; - default; + default: Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); return E_UNEXPECTED; } From 4c2e9d9e15e01cb27dbc67e29f66522c7b0cf94d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:30:54 -0700 Subject: [PATCH 068/162] added a log message on failure --- src/ep_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ep_util.c b/src/ep_util.c index 456b5a8..f4a1c3a 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -64,6 +64,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) } if (!rc) { + Log(LERROR, "Failed to register constant %s", const_table[i].name); hr = E_FAIL; break; } From f74e663658fc29526a767b9e7d93cb5023b9b3ae Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 12:35:15 -0700 Subject: [PATCH 069/162] got a test backwards --- src/ep_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_util.c b/src/ep_util.c index f4a1c3a..44a49c8 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -62,7 +62,7 @@ HRESULT Epython_register_constants(PyObject *module, PCREGCONSTANT const_table) Log(LERROR, "register_constants type '%c' unknown", const_table[i].regtype); return E_UNEXPECTED; } - if (!rc) + if (rc) { Log(LERROR, "Failed to register constant %s", const_table[i].name); hr = E_FAIL; From a96a427e498e9b43357ff6fb4c7fe1d481752e24 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:29:37 -0700 Subject: [PATCH 070/162] 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); From 6f27ec7af89c046ae335ba84a1fae2a135b8bd67 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:33:23 -0700 Subject: [PATCH 071/162] cleaned up some compiler warnings --- src/ep_msg.c | 6 ++++-- src/main.c | 5 +---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/ep_msg.c b/src/ep_msg.c index c00fe51..d5c533b 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -1,15 +1,17 @@ #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(PyDictObject *target, PMSG source) +static HRESULT convert_msg(PyObject *target, PMSG source) { PyObject *attr; + ASSERT(PyDict_CheckExact(target)); PyDict_Clear(target); attr = PyLong_FromUnsignedLong(source->target); if (!attr) @@ -63,6 +65,6 @@ PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i", &exitcode)) return NULL; Sys_Exit_Code = exitcode; - Mq_post1(Sys_Queue, NULL, WM_QUIT, exitcode); + Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Py_RETURN_NONE; } diff --git a/src/main.c b/src/main.c index 29a4b87..99b9a63 100644 --- a/src/main.c +++ b/src/main.c @@ -2,11 +2,10 @@ #include #include #include "scode.h" +#include "log.h" #include "config.h" #include "gpio.h" -#include "log.h" #include "fbinit.h" -#include "fbprimitive.h" #include "fontengine.h" #include "time_func.h" #include "ep_init.h" @@ -15,8 +14,6 @@ int main(int argc, char *argv[]) { HRESULT hr; - int running = 1; - MSG msg; /* initialization sequence */ Time_init(); From c0c4242dfc28ee2491b036452e3ed9fe909697bb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:34:49 -0700 Subject: [PATCH 072/162] cleared up another warning --- src/ep_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_msg.c b/src/ep_msg.c index d5c533b..c647533 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -38,7 +38,7 @@ static HRESULT convert_msg(PyObject *target, PMSG source) PyObject *Epython_get_message(PyObject *self, PyObject *args) { - PyDictObject *out; + PyObject *out; MSG msg; if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &out)) From 351e2a2b47edc305a3a1b6e3f4304bbb4c0f71d8 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:37:02 -0700 Subject: [PATCH 073/162] error in Python script now --- scripts/tmp_main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 0e656b9..90c6f58 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -21,9 +21,9 @@ 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]) + 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]) + print("Button {0} was released.\n".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: print("Backlight ON.\n") From bb8b27fb2484ac1f42ffae14efa67f6df1a27619 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:38:01 -0700 Subject: [PATCH 074/162] forgot the Python import --- scripts/tmp_main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 90c6f58..c799dd4 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,4 +1,5 @@ # Initial test script +import upiwin import upiwin_tmp def log_touch(event, x, y): From 68be55a8f560331a56044dde9b416ef300a6975f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 13:42:55 -0700 Subject: [PATCH 075/162] tracing backlight problem and fixing a typo in a function definition --- scripts/tmp_main.py | 14 +++++++------- src/ep_backlight.c | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index c799dd4..815aa44 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -3,7 +3,7 @@ import upiwin import upiwin_tmp def log_touch(event, x, y): - print("Touch {0} at ({1), {2})\n".format(event, x, y)) + print("Touch {0} at ({1}, {2})".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) @@ -22,18 +22,18 @@ 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])) + print("Button {0} was pressed.".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: - print("Button {0} was released.\n".format(msg['attrs'][0])) + print("Button {0} was released.".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: - print("Backlight ON.\n") + print("Backlight ON.") upiwin.set_backlight(True) elif bn == 2: - print("Backlight OFF.\n") - upiwin.set_backlight(True) + print("Backlight OFF.") + upiwin.set_backlight(False) elif bn == 4: - print("Quitting the application.\n") + print("Quitting the application.") upiwin.post_quit_message(0) elif msg['message'] == upiwin.WM_TOUCHDOWN: log_touch('DOWN', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/ep_backlight.c b/src/ep_backlight.c index af4327b..bb37f07 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -1,6 +1,7 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" +#include "log.h" #include "gpio.h" #include "ep_upiwin.h" #include "ep_init.h" @@ -23,6 +24,7 @@ PyObject *Epython_set_backlight(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "p", &new_state)) return NULL; pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); + Log(LDEBUG, "set_backlight: old=%d, new=%d (level=%u)", pstate->backlight_on, new_state, pstate->backlight_level); if (new_state && !(pstate->backlight_on)) Gpio_set_backlight(pstate->backlight_level); else if (!new_state && pstate->backlight_on) From ee292d3aab2943be3a1a0ed1c55eafd5eed413eb Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Mon, 9 Dec 2019 17:02:04 -0700 Subject: [PATCH 076/162] starting to build device-independent drawing functions (work in progress) --- src/Makefile | 2 +- src/dc_screen.c | 5 +++++ src/dc_screen.h | 12 ++++++++++++ src/devctxt.c | 9 +++++++++ src/devctxt.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/ep_backlight.c | 1 - src/ep_msg.c | 1 + src/gfxobj.c | 30 +++++++++++++++++++++++++++++ src/gfxobj.h | 23 ++++++++++++++++++++++ src/gfxtype.h | 9 +++++++++ src/rect.c | 7 ++++++- 11 files changed, 144 insertions(+), 3 deletions(-) create mode 100755 src/dc_screen.c create mode 100755 src/dc_screen.h create mode 100755 src/devctxt.c create mode 100755 src/devctxt.h create mode 100755 src/gfxobj.c create mode 100755 src/gfxobj.h diff --git a/src/Makefile b/src/Makefile index 393fa29..1e3d59c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png 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 \ + fbinit.o rect.o gfxobj.o devctxt.o dc_screen.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/dc_screen.c b/src/dc_screen.c new file mode 100755 index 0000000..84fced2 --- /dev/null +++ b/src/dc_screen.c @@ -0,0 +1,5 @@ +#include "dc_screen.h" + +static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op) +{ +} diff --git a/src/dc_screen.h b/src/dc_screen.h new file mode 100755 index 0000000..4c4ad6e --- /dev/null +++ b/src/dc_screen.h @@ -0,0 +1,12 @@ +#ifndef __DC_SCREEN_H_INCLUDED +#define __DC_SCREEN_H_INCLUDED + +#include "wintype.h" +#include "gfxtype.h" + +typedef struct tagSCREENPRIVDATA { + UINT32 pix_per_row; + UINT16 *pdata; +} SCREENPRIVDATA, *PSCREENPRIVDATA; + +#endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c new file mode 100755 index 0000000..982325a --- /dev/null +++ b/src/devctxt.c @@ -0,0 +1,9 @@ +#include "gfxtype.h" +#include "devctxt.h" + +COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) +{ + if (!G_coords_in_rect(&(pdctxt->cliprect), x, y)) + return (COLORREF)(-1); + return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, xm, y, colorref, pdctxt->rop2); +} diff --git a/src/devctxt.h b/src/devctxt.h new file mode 100755 index 0000000..2e8f528 --- /dev/null +++ b/src/devctxt.h @@ -0,0 +1,48 @@ +#ifndef __DEVCTXT_H_INCLUDED +#define __DEVCTXT_H_INCLUDED + +#include "wintype.h" +#include "gfxtype.h" +#include "gfxobj.h" + +#define DCTXT_SIG_WORD 0x78744344 /* "DCtx */ + +/* Raster operation codes */ +#define R2_BLACK 1 +#define R2_NOTMERGEPEN 2 +#define R2_MASKNOTPEN 3 +#define R2_NOTCOPYPEN 4 +#define R2_MASKPENNOT 5 +#define R2_NOT 6 +#define R2_XORPEN 7 +#define R2_NOTMASKPEN 8 +#define R2_MASKPEN 9 +#define R2_NOTXORPEN 10 +#define R2_NOP 11 +#define R2_MERGENOTPEN 12 +#define R2_COPYPEN 13 +#define R2_MERGEPENNOT 14 +#define R2_MERGEPEN 15 +#define R2_WHITE 16 + +typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op); + +typedef struct tagDCFUNTABLE { + DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ +} DCFUNTABLE; + +typedef const DCFUNTABLE *PDCFUNTABLE; + +typedef struct tagDCTXT { + GFXOBJECT hdr; /* the header of all objects */ + PDCFUNTABLE funcs; /* device context functions */ + PVOID privdata; /* private data for the type of DC */ + RECT cliprect; /* clipping rectangle */ + POINT pos; /* current position */ + UINT32 rop2; /* current raster operation */ + COLORREF color; /* current drawing color (XXX replace with pens later) */ +} DCTXT, *PDCTXT; + +extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color); + +#endif /* __DEVCTXT_H_INCLUDED */ diff --git a/src/ep_backlight.c b/src/ep_backlight.c index bb37f07..e78cb58 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -24,7 +24,6 @@ PyObject *Epython_set_backlight(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "p", &new_state)) return NULL; pstate = (PUPIWIN_STATE)PyModule_GetState(UPIWIN_module); - Log(LDEBUG, "set_backlight: old=%d, new=%d (level=%u)", pstate->backlight_on, new_state, pstate->backlight_level); if (new_state && !(pstate->backlight_on)) Gpio_set_backlight(pstate->backlight_level); else if (!new_state && pstate->backlight_on) diff --git a/src/ep_msg.c b/src/ep_msg.c index c647533..9cf072b 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -68,3 +68,4 @@ PyObject *Epython_post_quit_message(PyObject *self, PyObject *args) Mq_post1(Sys_Queue, 0, WM_QUIT, exitcode); Py_RETURN_NONE; } + diff --git a/src/gfxobj.c b/src/gfxobj.c new file mode 100755 index 0000000..882ca1a --- /dev/null +++ b/src/gfxobj.c @@ -0,0 +1,30 @@ +#include +#include "gfxobj.h" + +void Go_unchain(PGFXOBJECT obj) +{ + if (!(obj->next || obj->prev)) + return; + if (obj->next) + obj->next->prev = obj->prev; + if (obj->prev) + obj->prev->next = obj->next; + obj->prev = obj->next = NULL; +} + +INT32 Go_addref(PGFXOBJECT obj) +{ + return ++(obj->refcnt); +} + +INT32 Go_release(PGFXOBJECT obj) +{ + int rc = --(obj->refcnt); + if (rc == 0) + { + if (obj->dtor) + (*(obj->dtor))(obj); + free(obj); + } + return rc; +} diff --git a/src/gfxobj.h b/src/gfxobj.h new file mode 100755 index 0000000..19d5926 --- /dev/null +++ b/src/gfxobj.h @@ -0,0 +1,23 @@ +#ifndef __GFXOBJ_H_INCLUDED +#define __GFXOBJ_H_INCLUDED + +#include "wintype.h" + +/* type definition for a graphics destructor */ +typedef void (*GFX_DTOR)(PVOID obj); + +/* A graphics object in memory always starts with this. */ +typedef struct tagGFXOBJECT { + UINT32 sig; /* signature so we know what something is */ + UINT32 size; /* size of total allocated memory in block */ + INT32 refcnt; /* reference count */ + GFX_DTOR dtor; /* destructor function called when we're no longer needed */ + struct tagGFXOBJECT *next; /* support double linked lists of obejcts */ + struct tagGFXOBJECT *prev; +} GFXOBJECT, *PGFXOBJECT; + +extern void Go_unchain(PGFXOBJECT obj); +extern INT32 Go_addref(PGFXOBJECT obj); +extern INT32 Go_release(PGFXOBJECT obj); + +#endif /* __GFXOBJ_H_INCLUDED */ diff --git a/src/gfxtype.h b/src/gfxtype.h index e992d9e..efc02db 100755 --- a/src/gfxtype.h +++ b/src/gfxtype.h @@ -18,14 +18,23 @@ typedef struct tagRECT { typedef const POINT *PCPOINT; typedef const RECT *PCRECT; +typedef UINT32 COLORREF; +typedef PUINT32 PCOLORREF; + extern BOOL G_set_rect(PRECT rect, int left, int top, int right, int bottom); extern BOOL G_set_rect_empty(PRECT rect); extern BOOL G_inflate_rect(PRECT rect, int dx, int dy); extern BOOL G_offset_rect(PRECT rect, int dx, int dy); extern BOOL G_is_rect_empty(PCRECT rect); +extern BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y); extern BOOL G_point_in_rect(PCRECT rect, PCPOINT pt); extern BOOL G_rect_equal(PCRECT rect1, PCRECT rect2); extern BOOL G_rect_intersect(PRECT dest, PCRECT src1, PCRECT src2); extern BOOL G_rect_union(PRECT dest, PCRECT src1, PCRECT src2); +#define RGB(r, g, b) ((((UINT32)(r)) & 0xFF) | ((((UINT32)(g)) & 0xFF) << 8) | ((((UINT32)(b)) & 0xFF) << 16)) +#define GetRValue(cr) ((UINT32)((cr) & 0xFF)) +#define GetGValue(cr) ((UINT32)(((cr) >> 8) & 0xFF)) +#define GetBValue(cr) ((UINT32)(((cr) >> 16) & 0xFF)) + #endif /* __GFXTYPE_H_INCLUDED */ diff --git a/src/rect.c b/src/rect.c index 2f1c318..eae408a 100755 --- a/src/rect.c +++ b/src/rect.c @@ -40,9 +40,14 @@ BOOL G_is_rect_empty(PCRECT rect) return (rect->right <= rect->left) || (rect->bottom <= rect->top); } +BOOL G_coords_in_rect(PCRECT rect, INT32 x, INT32 y) +{ + return (rect->left <= x) && (x < rect->right) && (rect->top <= y) && (y < rect->bottom); +} + BOOL G_point_in_rect(PCRECT rect, PCPOINT pt) { - return (rect->left <= pt->x) && (pt->x < rect->right) && (rect->top <= pt->y) && (pt->y < rect->bottom); + return G_coords_in_rect(rect, pt->x, pt->y); } BOOL G_rect_equal(PCRECT rect1, PCRECT rect2) From c3b3e0a3508acd6e36298ea8f4f3f173c4115327 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 12:42:58 -0700 Subject: [PATCH 077/162] first pass at the device-independent drawing system, including the Python representation of a device context --- src/Makefile | 2 +- src/dc_screen.c | 170 +++++++++++++++++++++++++++++++ src/dc_screen.h | 2 + src/devctxt.c | 162 ++++++++++++++++++++++++++++++ src/devctxt.h | 17 ++++ src/ep_devctxt.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++ src/ep_init.h | 2 + src/ep_upiwin.c | 24 +++++ src/gfxobj.c | 9 ++ src/gfxobj.h | 1 + 10 files changed, 641 insertions(+), 1 deletion(-) create mode 100755 src/ep_devctxt.c diff --git a/src/Makefile b/src/Makefile index 1e3d59c..86ff8a0 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_upiwin_tmp.o ep_util.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_upiwin_tmp.o ep_util.o \ fbinit.o rect.o gfxobj.o devctxt.o dc_screen.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 diff --git a/src/dc_screen.c b/src/dc_screen.c index 84fced2..8e37e98 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,5 +1,175 @@ +#include "fbinit.h" +#include "devctxt.h" #include "dc_screen.h" +inline static PUINT16 loc_from_coords(PSCREENPRIVDATA priv, INT32 x, INT32 y) +{ + return priv->pdata + (y * priv->pix_per_row) + x; +} + +inline static UINT16 native_from_COLORREF(COLORREF cr) +{ + return (UINT16)(((cr << 8) & 0xF800) | ((cr >> 5) & 0x7E0) | ((cr >> 19) & 0x1F)); +} + +inline static COLORREF COLORREF_from_native(UINT16 cr) +{ + UINT32 tmp = cr; + return (COLORREF)(((tmp << 19) & 0xF80000) | ((tmp << 5) & 0xFC00) | ((tmp >> 8) & 0xF800)); +} + +static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) +{ + switch (op) + { + case R2_BLACK: + return 0; + case R2_NOTMERGEPEN: + return ~(disp | pen); + case R2_MASKNOTPEN: + return disp & (~pen); + case R2_NOTCOPYPEN: + return ~pen; + case R2_MASKPENNOT; + return (~disp) & pen; + case R2_NOT: + return ~disp; + case R2_XORPEN: + return disp ^ pen; + case R2_NOTMASKPEN: + return ~(disp & pen); + case R2_MASKPEN: + return disp & pen; + case R2_NOTXORPEN: + return ~(disp ^ pen); + case R2_NOP: + return disp; + case R2_MERGENOTPEN: + return disp | (~pen); + case R2_COPYPEN: + return pen; + case R2_MERGEPENNOT: + return (~disp) | pen; + case R2_MERGEPEN: + return disp | pen; + case R2_WHITE: + return (UINT16)(-1); + } +} + static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op) { + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + UINT16 pencolor = native_from_COLORREF(color); + PUINT16 loc = loc_from_coords(priv, x, y); + UINT16 screen = *loc; + *loc = apply_rop2(op, screen, pencolor); + return COLORREF_from_native(screen); +} + +static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op) +{ + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + UINT16 pencolor = native_from_COLORREF(color); + INT32 dx = x2 - x1; + INT32 dy = y2 - y1; + INT32 tmp; + PUINT16 loc; + + if (ABS(dx) < ABS(dy)) + { + if (y1 > y2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + loc = loc_from_coords(priv, x1, y1); + tmp = x1; + x1 << 16; + dx = (dx << 16) / dy; + while (y1 <= y2) + { + *loc = apply_rop2(op, *loc, pencolor); + x1 += dx; + ++y1; + loc += priv->pix_per_row; + if (tmp != (x1 >> 16)) + { + loc += ((x1 >> 16) - tmp); + tmp = x1 >> 16; + } + } + } + else + { + if (x1 > x2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + dx = -dx; + dy = -dy; + } + loc = loc_from_coords(priv, x1, y1); + tmp = y1; + y1 <<= 16; + dy = dx ? (dy << 16) / dx : 0; + while (x1 <= x2) + { + *loc = apply_rop2(op, *loc, pencolor); + y1 += dy; + ++x1; + ++loc; + if (tmp != (y1 >> 16)) + { + loc += ((((y1 >> 16) - tmp) * priv->pix_per_row); + tmp = y1 >> 16; + } + } + } +} + +static const DCFUNTABLE screen_funtable = { + screen_set_pixel, + screen_line +}; + +static void screen_context_destroy(PVOID obj) +{ + PDCTXT pdctxt = (PDCTXT)obj; + _DC_FinalizeCommon(pdctxt); + free(pdctxt->privdata); +} + +PDCTXT DC_CreateScreenContext(void) +{ + PDCTXT rc; + PSCREENPRIVDATA priv; + + priv = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA)); + if (!priv) + return NULL; + priv->pix_per_row = Fb_Info->width; + priv->pdata = Pb_Ptr; + + rc = _DC_Allocate(&screen_funtable, priv); + if (rc) + { + rc->hdr.dtor = screen_context_destroy; + rc->cliprect.left = rc->cliprect.top = 0; + rc->cliprect.right = Fb_Info->width - 1; + rc->cliprect.bottom = Fb_Info->height - 1; + } + else + free(priv); + return rc; } diff --git a/src/dc_screen.h b/src/dc_screen.h index 4c4ad6e..ecd4f31 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -9,4 +9,6 @@ typedef struct tagSCREENPRIVDATA { UINT16 *pdata; } SCREENPRIVDATA, *PSCREENPRIVDATA; +extern PDCTXT DC_CreateScreenContext(void); + #endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c index 982325a..df89755 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,9 +1,171 @@ +#include #include "gfxtype.h" +#include "gfxobj.h" #include "devctxt.h" +inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +{ + BYTE rc = 0; + if (y < ymin) + rc |= 0x8; + else if (y >= ymax) + rc |= 0x4; + if (x < xmin) + rc |= 0x1; + else if (x >= xmax) + rc |= 0x2; + return rc; +} + +static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +{ + BYTE outcode1, outcode2, tmpb; + INT32 tmp; + + /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ + for (;;) + { + outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); + outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); + if ((outcode1 & outcode2) != 0) + return FALSE; /* trivial rejection */ + else if ((outcode1 == 0) && (outcode2 == 0)) + break; /* trivial acceptance */ + if (outcode1 == 0) + { + tmp = x1; + x1 = x2; + x2 = tmp; + tmp = y1; + y1 = y2; + y2 = tmp; + tmpb = outcode1; + outcode1 = outcode2; + outcode2 = tmp; + } + if (outcode1 & 0x8) + { + x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); + y1 = ymin; + } + else if (outcode1 & 0x4) + { + x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); + y1 = ymax; + } + else if (outcode1 & 0x2) + { + y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); + x1 = xmax; + } + else if (outcode1 & 0x1) + { + y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); + x1 = xmin; + } + } + output[0] = x1; + output[1] = y1; + output[2] = x2; + output[3] = y2; + return TRUE; +} + +static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) +{ + INT32 buffer[4]; + if (line_clip(buffer, x1 << 16, y1 << 16, x2 << 16, y2 << 16, pdctxt->cliprect.left << 16, pdctxt->cliprect.top << 16, + pdctxt->cliprect.right << 16, pdctxt->cliprect.bottom << 16)) + return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> 16, buffer[1] >> 16, buffer[2] >> 16, buffer[3] >> 16, pdctxt->color, pdctxt->rop2); + return TRUE; +} + +PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata) +{ + PDCTXT rc = (PDCTXT)malloc(sizeof(DCTXT)); + if (!rc) + return NULL; + memset(rc, 0, sizeof(DCTXT)); + _Go_init(&(rc->hdr), DCTXT_SIG_WORD, sizeof(DCTXT)); + rc->funcs = funcs; + rc->privdata = privdata; + rc->rop2 = R2_COPYPEN; + return rc; +} + +void _DC_FinalizeCommon(PDCTXT pdctxt) +{ + /* nothing here yet */ +} + COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) { if (!G_coords_in_rect(&(pdctxt->cliprect), x, y)) return (COLORREF)(-1); return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, xm, y, colorref, pdctxt->rop2); } + +BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y) +{ + BOOL rc = internal_line(pdctxt, pdctxt->pos.x, pdctxt->pos.y, x, y); + if (rc) + { + pdctxt->pos.x = x; + pdctxt->pos.y = y; + } + return rc; +} + +BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt) +{ + if (oldpt) + memcpy(oldpt, &(pdctxt->pos), sizeof(POINT)); + pdctxt->pos.x = x; + pdctxt->pos.y = y; + return TRUE; +} + +BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom) +{ + internal_line(pdctxt, left, top, right - 1, top); + internal_line(pdctxt, left, top + 1, left, bottom - 2); + internal_line(pdctxt, right - 1, top + 1, right - 1, bottom - 2); + internal_line(pdctxt, left, bottom - 1, right - 1, bottom - 1); + return TRUE; +} + +UINT32 DC_GetROP2(PDCTXT pdctxt) +{ + return pdctxt->rop2; +} + +UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop) +{ + UINT32 rc = pdctxt->rop2; + pdctxt->rop2 = rop; + return rc; +} + +COLORREF DC_GetTextColor(PDCTXT pdctxt) +{ + return pdctxt->color; +} + +COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr) +{ + COLORREF rc = pdctxt->color; + pdctxt->color = cr; + return rc; +} + +BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect) +{ + memcpy(prect, &(pdctxt->cliprect), sizeof(RECT)); + return TRUE; +} + +BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect) +{ + memcpy(&(pdctxt->cliprect), prect, sizeof(RECT)); + return TRUE; +} diff --git a/src/devctxt.h b/src/devctxt.h index 2e8f528..1b8d3a4 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -26,9 +26,11 @@ #define R2_WHITE 16 typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op); +typedef BOOL (*DCtx_Line)(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op); typedef struct tagDCFUNTABLE { DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ + DCtx_Line line; /* draws a line on the display */ } DCFUNTABLE; typedef const DCFUNTABLE *PDCFUNTABLE; @@ -43,6 +45,21 @@ typedef struct tagDCTXT { COLORREF color; /* current drawing color (XXX replace with pens later) */ } DCTXT, *PDCTXT; +extern PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata); +extern void _DC_FinalizeCommon(PDCTXT pdctxt); + extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color); +extern BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y); +extern BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt); +extern BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom); +extern UINT32 DC_GetROP2(PDCTXT pdctxt); +extern UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop); +extern COLORREF DC_GetTextColor(PDCTXT pdctxt); +extern COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr); +extern BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect); +extern BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect); + +#define DC_addref(pdctxt) Go_addref(&(pdctxt->hdr)) +#define DC_release(pdctxt) Go_release(&(pdctxt->hdr)) #endif /* __DEVCTXT_H_INCLUDED */ diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c new file mode 100755 index 0000000..f8b3069 --- /dev/null +++ b/src/ep_devctxt.c @@ -0,0 +1,253 @@ +#include +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "scode.h" +#include "devctxt.h" +#include "dc_screen.h" +#include "ep_init.h" + +typedef struct tagDevCtxtObject { + PyObject_HEAD + PDCTXT pdctxt; +} DevCtxtObject; + +static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args) +{ + INT32 x, y; + COLORREF color, rc; + + if (!PyArg_ParseTuple(args, "iik", &x, &y, &color)) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_SetPixel(self->pdctxt, x, y, color); + return PyLong_FromUnsignedLong(rc); +} + +static PyObject *devctxt_line_to(DevCtxtObject *self, PyObject *args) +{ + INT32 x, y; + BOOL rc; + + if (!PyArg_ParseTuple(args, "ii", &x, &y)) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_LineTo(self->pdctxt, x, y); + return PyBool_FromLong(rc); +} + +static PyObject *devctxt_move_to(DevCtxtObject *self, PyObject *args) +{ + INT32 x, y; + BOOL rc; + + if (!PyArg_ParseTuple(args, "ii", &x, &y)) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_MoveTo(self->pdctxt, x, y, NULL); + return PyBool_FromLong(rc); +} + +static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args) +{ + INT32 left, top, right, bottom; + BOOL rc; + + if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom)) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_Rectangle(self->pdctxt, left, top, right, bottom); + return PyBool_FromLong(rc); +} + +static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args) +{ + RECT rect; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + DC_GetClipRect(self->pdctxt, &rect); + return Py_BuildValue("(i,i,i,i)", rect.left, rect.top, rect.right, rect.bottom); +} + +static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args) +{ + RECT rect; + BOOL rc; + + if (!PyArg_ParseTuple(args, "iiii", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_SetClipRect(self->pdctxt, &rect); + return PyBool_FromLong(rc); +} + +static PyMethodDef DevCtxtMethods[] = { + {"set_pixel", (PyCFunction)devctxt_set_pixel, METH_VARARGS, + "Sets a single pixel on the display."}, + {"line_to", (PyCFunction)devctxt_line_to, METH_VARARGS, + "Draws a line from the current position to the specified location."}, + {"move_to", (PyCFunction)devctxt_move_to, METH_VARARGS, + "Draws a line from the current position to the specified location."}, + {"rectangle", (PyCFunction)devctxt_rectangle, METH_VARARGS, + "Draws a rectangle."}, + {"get_clip_rect", (PyCFunction)devctxt_get_clip_rect, METH_VARARGS, + "Returns the current clipping rectangle of the device context."}, + {"set_clip_rect", (PyCFunction)devctxt_set_clip_rect, METH_VARARGS, + "Sets the current clipping rectangle of the device context."}, + {NULL, NULL, 0, NULL} +}; + + +static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure) +{ + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + return PyLong_FromUnsignedLong(DC_GetROP2(self->pdctxt)); +} + +static int devctxt_set_rop2(DevCtxtObject *self, PyObject *value, void *closure) +{ + UINT32 v; + + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return -1; + } + if (value == NULL) + { + PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); + return -1; + } + v = PyLong_AsUnsignedLong(value); + if (PyErr_Occurred()) + return -1; + DC_SetROP2(self->pdctxt, v); + return 0; +} + +static PyObject *devctxt_get_text_color(DevCtxtObject *self, void *closure) +{ + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + return PyLong_FromUnsignedLong(DC_GetTextColor(self->pdctxt)); +} + +static int devctxt_set_text_color(DevCtxtObject *self, PyObject *value, void *closure) +{ + COLORREF v; + + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return -1; + } + if (value == NULL) + { + PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute"); + return -1; + } + v = PyLong_AsUnsignedLong(value); + if (PyErr_Occurred()) + return -1; + DC_SetTextColor(self->pdctxt, v); + return 0; +} + +static PyGetSetDef DevCtxtProperties[] = { + {"rop2", (getter)devctxt_get_rop2, (setter)devctxt_set_rop2, + "Current raster operation", NULL}, + {"text_color", (getter)devctxt_get_text_color, (setter)devctxt_set_text_color, + "Current text color", NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static void devctxt_dealloc(DevCtxtObject *self) +{ + if (self->pdctxt) + DC_release(self->pdctxt); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = { "type" } + char *type; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) + return -1; + if (stricmp(type, "screen") == 0) + { + self->pdctxt = DC_CreateScreenContext(); + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "unable to create screen context"); + return -1 + } + } + else + { + PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type); + return -1; + } + return 0; +} + +static PyTypeObject DevCtxtType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "upiwin.DevCtxt", + .tp_doc = "Device context object", + .tp_basicsize = sizeof(DevCtxtObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)devctxt_init, + .tp_dealloc = (destructor)devctxt_dealloc, + .tp_methods = DevCtxtMethods, + .tp_getset = DevCtxtProperties, +} + +HRESULT Epython_register_devctxt(PyObject *module) +{ + if (PyType_Ready(&DevCtxtType) < 0) + return E_FAIL; + Py_INCREF(&DevCtxtType); + if (PyModule_AddObject(module, "DevCtxt", (PyObject *)(&DevCtxtType)) < 0) + { + Py_DECREF(&DevCtxtType); + return E_FAIL; + } + return S_OK; +} diff --git a/src/ep_init.h b/src/ep_init.h index 82ec538..e394470 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -14,6 +14,8 @@ extern PyObject *UPIWIN_tmp_module; extern PyObject *Epython_init_upiwin_module(void); extern PyObject *Epython_init_upiwin_tmp_module(void); +extern HRESULT Epython_register_devctxt(PyObject *module); + extern HRESULT Epython_setup(void); extern HRESULT Epython_run(void); diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 4c51e34..9878d3c 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -6,6 +6,7 @@ #include "ep_init.h" #include "ep_upiwin.h" #include "ep_util.h" +#include "devctxt.h" static PyMethodDef UPIWINMethods[] = { /* Backlight control functions */ @@ -46,6 +47,23 @@ BEGIN_CONSTANT_TABLE(UPIWINConstants) CONSTANT_INT_MACRO(WM_TOUCHDOWN) CONSTANT_INT_MACRO(WM_TOUCHMOVE) CONSTANT_INT_MACRO(WM_TOUCHUP) + /* Raster op constants */ + CONSTANT_INT_MACRO(R2_BLACK) + CONSTANT_INT_MACRO(R2_NOTMERGEPEN) + CONSTANT_INT_MACRO(R2_MASKNOTPEN) + CONSTANT_INT_MACRO(R2_NOTCOPYPEN) + CONSTANT_INT_MACRO(R2_MASKPENNOT) + CONSTANT_INT_MACRO(R2_NOT) + CONSTANT_INT_MACRO(R2_XORPEN) + CONSTANT_INT_MACRO(R2_NOTMASKPEN) + CONSTANT_INT_MACRO(R2_MASKPEN) + CONSTANT_INT_MACRO(R2_NOTXORPEN) + CONSTANT_INT_MACRO(R2_NOP) + CONSTANT_INT_MACRO(R2_MERGENOTPEN) + CONSTANT_INT_MACRO(R2_COPYPEN) + CONSTANT_INT_MACRO(R2_MERGEPENNOT) + CONSTANT_INT_MACRO(R2_MERGEPEN) + CONSTANT_INT_MACRO(R2_WHITE) END_CONSTANT_TABLE PyObject *Epython_init_upiwin_module(void) @@ -62,6 +80,12 @@ PyObject *Epython_init_upiwin_module(void) Py_DECREF(module); return NULL; } + + if (FAILED(Epython_register_devctxt(module))) + { + Py_DECREF(module); + return NULL; + } /* set up the module state */ pstate = (PUPIWIN_STATE)PyModule_GetState(module); diff --git a/src/gfxobj.c b/src/gfxobj.c index 882ca1a..c721f43 100755 --- a/src/gfxobj.c +++ b/src/gfxobj.c @@ -1,6 +1,15 @@ #include +#include #include "gfxobj.h" +void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size) +{ + memset(obj, 0, sizeof(GFXOBJECT)); + obj->sig = sig; + obj->size = size; + obj->refcnt = 1; +} + void Go_unchain(PGFXOBJECT obj) { if (!(obj->next || obj->prev)) diff --git a/src/gfxobj.h b/src/gfxobj.h index 19d5926..0f7a6b6 100755 --- a/src/gfxobj.h +++ b/src/gfxobj.h @@ -16,6 +16,7 @@ typedef struct tagGFXOBJECT { struct tagGFXOBJECT *prev; } GFXOBJECT, *PGFXOBJECT; +extern void _Go_init(PGFXOBJECT obj, UINT32 sig, UINT32 size); extern void Go_unchain(PGFXOBJECT obj); extern INT32 Go_addref(PGFXOBJECT obj); extern INT32 Go_release(PGFXOBJECT obj); From 519e58fd779e2cda88da40af7d9442e92ab1cbd9 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 10 Dec 2019 12:55:32 -0700 Subject: [PATCH 078/162] fixed compile errors --- src/dc_screen.c | 11 +++++++---- src/devctxt.c | 5 +++-- src/ep_devctxt.c | 8 ++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index 8e37e98..31b3197 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,3 +1,4 @@ +#include #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" @@ -30,7 +31,7 @@ static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) return disp & (~pen); case R2_NOTCOPYPEN: return ~pen; - case R2_MASKPENNOT; + case R2_MASKPENNOT: return (~disp) & pen; case R2_NOT: return ~disp; @@ -55,6 +56,7 @@ static inline UINT16 apply_rop2(INT32 op, UINT16 disp, UINT16 pen) case R2_WHITE: return (UINT16)(-1); } + return pen; /* last ditch default */ } static COLORREF screen_set_pixel(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op) @@ -91,7 +93,7 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, } loc = loc_from_coords(priv, x1, y1); tmp = x1; - x1 << 16; + x1 <<= 16; dx = (dx << 16) / dy; while (y1 <= y2) { @@ -131,11 +133,12 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, ++loc; if (tmp != (y1 >> 16)) { - loc += ((((y1 >> 16) - tmp) * priv->pix_per_row); + loc += (((y1 >> 16) - tmp) * priv->pix_per_row); tmp = y1 >> 16; } } } + return TRUE; } static const DCFUNTABLE screen_funtable = { @@ -159,7 +162,7 @@ PDCTXT DC_CreateScreenContext(void) if (!priv) return NULL; priv->pix_per_row = Fb_Info->width; - priv->pdata = Pb_Ptr; + priv->pdata = Fb_Ptr; rc = _DC_Allocate(&screen_funtable, priv); if (rc) diff --git a/src/devctxt.c b/src/devctxt.c index df89755..83fc8ab 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,4 +1,5 @@ #include +#include #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" @@ -41,7 +42,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT y2 = tmp; tmpb = outcode1; outcode1 = outcode2; - outcode2 = tmp; + outcode2 = tmpb; } if (outcode1 & 0x8) { @@ -102,7 +103,7 @@ COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) { if (!G_coords_in_rect(&(pdctxt->cliprect), x, y)) return (COLORREF)(-1); - return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, xm, y, colorref, pdctxt->rop2); + return (*(pdctxt->funcs->set_pixel))(pdctxt->privdata, x, y, color, pdctxt->rop2); } BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index f8b3069..ae05cdc 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -203,18 +203,18 @@ static void devctxt_dealloc(DevCtxtObject *self) static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "type" } + static char *kwlist[] = { "type" }; char *type; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) return -1; - if (stricmp(type, "screen") == 0) + if (strcmp(type, "screen") == 0) { self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { PyErr_SetString(PyExc_RuntimeError, "unable to create screen context"); - return -1 + return -1; } } else @@ -237,7 +237,7 @@ static PyTypeObject DevCtxtType = { .tp_dealloc = (destructor)devctxt_dealloc, .tp_methods = DevCtxtMethods, .tp_getset = DevCtxtProperties, -} +}; HRESULT Epython_register_devctxt(PyObject *module) { From eef55f71b3f6f76eefef6c9ae4bdea9644dfca59 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:04:24 -0700 Subject: [PATCH 079/162] added a script to test clipping of drawn lines --- scripts/test_clipping.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100755 scripts/test_clipping.py diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py new file mode 100755 index 0000000..bdbba35 --- /dev/null +++ b/scripts/test_clipping.py @@ -0,0 +1,23 @@ +# Test of line clipping +import upiwin + +hdc = upiwin.DevCtxt(type='screen') +hdc.text_color = 0xFFFFFF # white +hdc.rectangle(100, 100, 199, 199) + +clip = hdc.get_clip_rect() +hdc.set_clip_rect(100, 100, 200, 200) + +hdc.text_color = 0xFF0000 # red +hdc.move_to(0, 200) +hdc.line_to(200, 0) + +hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) + +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_HWBUTTONUP: + bn = msg['attrs'][0] + if bn == 4: + print("Quitting the application.") + upiwin.post_quit_message(0) From f41356cca4bb55cd41e6a9e1ee6a15a2d1f17182 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Tue, 10 Dec 2019 13:10:43 -0700 Subject: [PATCH 080/162] prepare for disco debugging --- scripts/test_clipping.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index bdbba35..651cc47 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,9 +1,12 @@ # Test of line clipping import upiwin +print('**GOT HERE 1') hdc = upiwin.DevCtxt(type='screen') +print('**GOT HERE 2') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) +print('**GOT HERE 3') clip = hdc.get_clip_rect() hdc.set_clip_rect(100, 100, 200, 200) From 9746ad1ab3ad6ec13b977043e72316079b0d14be Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:13:56 -0700 Subject: [PATCH 081/162] disco debugging, yay! --- src/ep_devctxt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index ae05cdc..63250fa 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -3,6 +3,7 @@ #include #include "wintype.h" #include "scode.h" +#include "log.h" #include "devctxt.h" #include "dc_screen.h" #include "ep_init.h" @@ -206,10 +207,13 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = { "type" }; char *type; + Log(LDEBUG, "Creating a new DevCtxt object"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) return -1; + Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) { + Log(LDEBUG, "doing what we expect on screen context"); self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { From 12bd14e1e7140993487c8beb77d5b4fd59af8310 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:17:46 -0700 Subject: [PATCH 082/162] more disco debugging --- src/ep_devctxt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 63250fa..f87bc85 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -204,11 +204,11 @@ static void devctxt_dealloc(DevCtxtObject *self) static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "type" }; - char *type; + static char *kwlist[] = { "type", NULL }; + const char *type; Log(LDEBUG, "Creating a new DevCtxt object"); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", kwlist, &type)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type)) return -1; Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) From 3dd2e037ffe70926ec122886589f232bda686560 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:21:24 -0700 Subject: [PATCH 083/162] finished debugging parameter error, now test drawing without resetting clip --- scripts/test_clipping.py | 9 +++------ src/ep_devctxt.c | 3 --- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 651cc47..2650ed2 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,21 +1,18 @@ # Test of line clipping import upiwin -print('**GOT HERE 1') hdc = upiwin.DevCtxt(type='screen') -print('**GOT HERE 2') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) -print('**GOT HERE 3') -clip = hdc.get_clip_rect() -hdc.set_clip_rect(100, 100, 200, 200) +#clip = hdc.get_clip_rect() +#hdc.set_clip_rect(100, 100, 200, 200) hdc.text_color = 0xFF0000 # red hdc.move_to(0, 200) hdc.line_to(200, 0) -hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) +#hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} while upiwin.get_message(msg): diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index f87bc85..651f317 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -207,13 +207,10 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = { "type", NULL }; const char *type; - Log(LDEBUG, "Creating a new DevCtxt object"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "$s", kwlist, &type)) return -1; - Log(LDEBUG,"type argument is '%s'", type); if (strcmp(type, "screen") == 0) { - Log(LDEBUG, "doing what we expect on screen context"); self->pdctxt = DC_CreateScreenContext(); if (!(self->pdctxt)) { From a14acdb0edbad1b9d5c64192f6305100fe8b93c9 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:25:36 -0700 Subject: [PATCH 084/162] the clipping looks like it worked, my geometry was just off :) --- scripts/test_clipping.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 2650ed2..72df4a1 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -5,14 +5,18 @@ hdc = upiwin.DevCtxt(type='screen') hdc.text_color = 0xFFFFFF # white hdc.rectangle(100, 100, 199, 199) -#clip = hdc.get_clip_rect() -#hdc.set_clip_rect(100, 100, 200, 200) +clip = hdc.get_clip_rect() +hdc.set_clip_rect(100, 100, 200, 200) -hdc.text_color = 0xFF0000 # red -hdc.move_to(0, 200) -hdc.line_to(200, 0) +hdc.text_color = 0x0000FF # red +hdc.move_to(50, 199) +hdc.line_to(199, 50) -#hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) +hdc.text_color = 0x00FF00 # green +hdc.move_to(250, 199) +hdc.line_to(100, 50) + +hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} while upiwin.get_message(msg): From 3d40bb294395ca2548e83d8553e26c072bf1e4d9 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:40:23 -0700 Subject: [PATCH 085/162] now disco debugging the clipping algorithm --- src/dc_screen.c | 10 ++++++++++ src/devctxt.c | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/dc_screen.c b/src/dc_screen.c index 31b3197..37d173e 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,4 +1,5 @@ #include +#include "log.h" #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" @@ -78,6 +79,15 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tmp; PUINT16 loc; + ASSERT(x1 >= 0); + ASSERT(x1 < Fb_Info->width); + ASSERT(y1 >= 0); + ASSERT(y1 < Fb_Info->height); + ASSERT(x2 >= 0); + ASSERT(x2 < Fb_Info->width); + ASSERT(y2 >= 0); + ASSERT(y2 < Fb_Info->height); + if (ABS(dx) < ABS(dy)) { if (y1 > y2) diff --git a/src/devctxt.c b/src/devctxt.c index 83fc8ab..c501005 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,5 +1,6 @@ #include #include +#include "log.h" #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" @@ -23,17 +24,27 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT BYTE outcode1, outcode2, tmpb; INT32 tmp; + Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, + xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); + /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) { outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) + { + Log.debug("*REJECT*"); return FALSE; /* trivial rejection */ + } else if ((outcode1 == 0) && (outcode2 == 0)) + { + Log.debug("*ACCEPT*"); break; /* trivial acceptance */ + } if (outcode1 == 0) { + Log(LDEBUG, "exchange points") tmp = x1; x1 = x2; x2 = tmp; @@ -48,23 +59,28 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); y1 = ymin; + Log.debug("clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); y1 = ymax; + Log.debug("clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); x1 = xmax; + Log.debug("clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); x1 = xmin; + Log.debug("clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } } + Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); output[0] = x1; output[1] = y1; output[2] = x2; From ddc005ed8b0523954c499c817336d973d3b23c3e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:42:40 -0700 Subject: [PATCH 086/162] logging needed work :) --- src/devctxt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c501005..f98c2bb 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -44,7 +44,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 == 0) { - Log(LDEBUG, "exchange points") + Log(LDEBUG, "exchange points"); tmp = x1; x1 = x2; x2 = tmp; @@ -59,25 +59,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); y1 = ymin; - Log.debug("clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); y1 = ymax; - Log.debug("clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); x1 = xmax; - Log.debug("clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); x1 = xmin; - Log.debug("clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 48415ab947ab4855eaf31c4cd3a5ffc012ffb4cc Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:43:30 -0700 Subject: [PATCH 087/162] again... --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index f98c2bb..bff4a34 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -34,12 +34,12 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) { - Log.debug("*REJECT*"); + Log(LDEBUG,"*REJECT*"); return FALSE; /* trivial rejection */ } else if ((outcode1 == 0) && (outcode2 == 0)) { - Log.debug("*ACCEPT*"); + Log(LDEBUG,"*ACCEPT*"); break; /* trivial acceptance */ } if (outcode1 == 0) From 7ed0dea017ea76b611db40129acde24661fd7f66 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:49:21 -0700 Subject: [PATCH 088/162] possible that numeric ordering is b0rking it? --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index bff4a34..e858330 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -57,25 +57,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - x1 += (x2 - x1) * (ymin - y1) / (y2 - y1); + x1 += (x2 - x1) * ((ymin - y1) / (y2 - y1)); y1 = ymin; Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x4) { - x1 += (x2 - x1) * (ymax - y1) / (y2 - y1); + x1 += (x2 - x1) * ((ymax - y1) / (y2 - y1)); y1 = ymax; Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x2) { - y1 += (y2 - y1) * (xmax - x1) / (x2 - x1); + y1 += (y2 - y1) * ((xmax - x1) / (x2 - x1)); x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { - y1 += (y2 - y1) * (xmin - x1) / (x2 - x1); + y1 += (y2 - y1) * ((xmin - x1) / (x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } From 38219886106f8ad55d865be85b280a9004163e55 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:53:33 -0700 Subject: [PATCH 089/162] I think I reversed a sign somewhere --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index e858330..2fd12a4 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -69,13 +69,13 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x2) { - y1 += (y2 - y1) * ((xmax - x1) / (x2 - x1)); + y1 -= (y2 - y1) * ((xmax - x1) / (x2 - x1)); x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); } else if (outcode1 & 0x1) { - y1 += (y2 - y1) * ((xmin - x1) / (x2 - x1)); + y1 -= (y2 - y1) * ((xmin - x1) / (x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); } From 3b7f326768abea95a571208e6a1992438798b3ba Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 13:59:27 -0700 Subject: [PATCH 090/162] more tracing --- src/devctxt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 2fd12a4..dc77110 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -57,27 +57,31 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - x1 += (x2 - x1) * ((ymin - y1) / (y2 - y1)); + tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); + x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x4) { - x1 += (x2 - x1) * ((ymax - y1) / (y2 - y1)); + tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); + x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x2) { - y1 -= (y2 - y1) * ((xmax - x1) / (x2 - x1)); + tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); + y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); } else if (outcode1 & 0x1) { - y1 -= (y2 - y1) * ((xmin - x1) / (x2 - x1)); + tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); + y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> 16, y1 >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 85144de58fe4da83f14d44179a7cf90c83e574a7 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:01:36 -0700 Subject: [PATCH 091/162] look at the unshifted d values --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index dc77110..ed6f0ed 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -60,28 +60,28 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x4) { tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x2) { tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x1) { tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d", x1 >> 16, y1 >> 16, tmp >> 16); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); From 962f13dc1a01662fef0e224f9870216adeefd44e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:06:23 -0700 Subject: [PATCH 092/162] ever closer to a solution --- src/devctxt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index ed6f0ed..6c7bfe9 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -21,7 +21,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { - BYTE outcode1, outcode2, tmpb; + BYTE outcode1, outcode2; INT32 tmp; Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, @@ -51,9 +51,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = y1; y1 = y2; y2 = tmp; - tmpb = outcode1; - outcode1 = outcode2; - outcode2 = tmpb; + outcode1 = outcode2; /* we don't reference outcode2 in the rest of the loop */ } if (outcode1 & 0x8) { @@ -78,6 +76,10 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x1) { + int term1 = y2 - y1; + int term2 = xmin - x1; + int term3 = x2 - x1; + Log(LDEBUG, "term1=%d term2=%d term3=%d", term1 >> 16, term2 >> 16, term3 >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; From 406c4fd85d394db4d8f16e3c6486627b5ab2daca Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:08:20 -0700 Subject: [PATCH 093/162] checking math again --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index 6c7bfe9..d98f96e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -79,7 +79,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT int term1 = y2 - y1; int term2 = xmin - x1; int term3 = x2 - x1; - Log(LDEBUG, "term1=%d term2=%d term3=%d", term1 >> 16, term2 >> 16, term3 >> 16); + Log(LDEBUG, "term1=%d term2=%d term3=%d i1=%d i2=%d", term1 >> 16, term2 >> 16, term3 >> 16, (term1 * term2) >> 16, (term2 / term3) >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; From d66aa4de24b117a587d3744c57c1a3b1fe6adafe Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:13:38 -0700 Subject: [PATCH 094/162] try with higher-precision variables --- src/devctxt.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index d98f96e..323aa5b 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -5,7 +5,7 @@ #include "gfxobj.h" #include "devctxt.h" -inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) { BYTE rc = 0; if (y < ymin) @@ -19,12 +19,12 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) +static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) { BYTE outcode1, outcode2; - INT32 tmp; + INT64 tmp; - Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, + Log(LDEBUG, "clipping line from (%lld, %lld) to (%lld, %lld) against bounding box (%lld, %lld, %lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ @@ -58,39 +58,35 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against top to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x4) { tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against bottom to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x2) { tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against right to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } else if (outcode1 & 0x1) { - int term1 = y2 - y1; - int term2 = xmin - x1; - int term3 = x2 - x1; - Log(LDEBUG, "term1=%d term2=%d term3=%d i1=%d i2=%d", term1 >> 16, term2 >> 16, term3 >> 16, (term1 * term2) >> 16, (term2 / term3) >> 16); tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against left to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); } } - Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); - output[0] = x1; - output[1] = y1; - output[2] = x2; - output[3] = y2; + Log(LDEBUG, "final line is from (%lld, %lld) to (%lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); + output[0] = (INT32)x1; + output[1] = (INT32)y1; + output[2] = (INT32)x2; + output[3] = (INT32)y2; return TRUE; } From 3996501cf086fb08f8ebb9240d660816f1678261 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:30:45 -0700 Subject: [PATCH 095/162] I don't understand fixed point arithmetic - this fixed that, I hope --- src/devctxt.c | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 323aa5b..e2ee2a7 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -5,7 +5,7 @@ #include "gfxobj.h" #include "devctxt.h" -inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) +inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { BYTE rc = 0; if (y < ymin) @@ -19,13 +19,19 @@ inline static BYTE line_clip_outcode(INT64 x, INT64 y, INT64 xmin, INT64 ymin, I return rc; } -static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT64 xmin, INT64 ymin, INT64 xmax, INT64 ymax) +#define CPX 16 /* clipping precision in bits */ + +/* these macros keep the number of bits straight when doing fixed-point multiply & divide */ +#define M(a, b) ((((a) * (b))) >> CPX) +#define D(a, b) (((a) << CPX) / (b)) + +static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { BYTE outcode1, outcode2; - INT64 tmp; + INT32 tmp; - Log(LDEBUG, "clipping line from (%lld, %lld) to (%lld, %lld) against bounding box (%lld, %lld, %lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16, - xmin >> 16, ymin >> 16, xmax >> 16, ymax >> 16); + Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, + xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) @@ -55,47 +61,47 @@ static BOOL line_clip(PINT32 output, INT64 x1, INT64 y1, INT64 x2, INT64 y2, INT } if (outcode1 & 0x8) { - tmp = (x2 - x1) * ((ymin - y1) / (y2 - y1)); + tmp = M(x2 - x1, D(ymin - y1, y2 - y1)); x1 += tmp; y1 = ymin; - Log(LDEBUG, "clipped against top to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x4) { - tmp = (x2 - x1) * ((ymax - y1) / (y2 - y1)); + tmp = M(x2 - x1, D(ymax - y1, y2 - y1)); x1 += tmp; y1 = ymax; - Log(LDEBUG, "clipped against bottom to point (%lld, %lld), dx=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = (y2 - y1) * ((xmax - x1) / (x2 - x1)); + tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); y1 -= tmp; x1 = xmax; - Log(LDEBUG, "clipped against right to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { - tmp = (y2 - y1) * ((xmin - x1) / (x2 - x1)); + tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); y1 -= tmp; x1 = xmin; - Log(LDEBUG, "clipped against left to point (%lld, %lld), dy=%lld/%lld", x1 >> 16, y1 >> 16, tmp >> 16, tmp); + Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } } - Log(LDEBUG, "final line is from (%lld, %lld) to (%lld, %lld)", x1 >> 16, y1 >> 16, x2 >> 16, y2 >> 16); - output[0] = (INT32)x1; - output[1] = (INT32)y1; - output[2] = (INT32)x2; - output[3] = (INT32)y2; + Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); + output[0] = x1; + output[1] = y1; + output[2] = x2; + output[3] = y2; return TRUE; } static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) { INT32 buffer[4]; - if (line_clip(buffer, x1 << 16, y1 << 16, x2 << 16, y2 << 16, pdctxt->cliprect.left << 16, pdctxt->cliprect.top << 16, - pdctxt->cliprect.right << 16, pdctxt->cliprect.bottom << 16)) - return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> 16, buffer[1] >> 16, buffer[2] >> 16, buffer[3] >> 16, pdctxt->color, pdctxt->rop2); + if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, + pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) + return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From da9658408aabb5d0b076d61770effce3fa410ed5 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:32:24 -0700 Subject: [PATCH 096/162] use lesser precision in hope it works --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index e2ee2a7..130b7de 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 16 /* clipping precision in bits */ +#define CPX 4 /* clipping precision in bits */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) From f5cab0010e73fda9a42f87a2b01ed43ef114531b Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:36:38 -0700 Subject: [PATCH 097/162] OK, NOW i think I'm on the right track - re-reverse the signs --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 130b7de..f6fb92b 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -76,14 +76,14 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT else if (outcode1 & 0x2) { tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); - y1 -= tmp; + y1 += tmp; x1 = xmax; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); - y1 -= tmp; + y1 += tmp; x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } From 2b9853fd4c69e8844114e5815fdd1be683041353 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:41:41 -0700 Subject: [PATCH 098/162] boundary condition on right, attempting to bypass --- src/devctxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devctxt.c b/src/devctxt.c index f6fb92b..bafd68e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -100,7 +100,7 @@ static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) { INT32 buffer[4]; if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, - pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) + (pdctxt->cliprect.right - 1) << CPX, (pdctxt->cliprect.bottom - 1) << CPX)) return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From eee409d4e73d9676cbf8bec3aa71c4cd2a83a79a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:45:02 -0700 Subject: [PATCH 099/162] add an infinite loop detector --- src/devctxt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/devctxt.c b/src/devctxt.c index bafd68e..c6a41bb 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -29,6 +29,7 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { BYTE outcode1, outcode2; INT32 tmp; + int nloop = 0; Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); @@ -36,6 +37,11 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) { + if (++nloop == 20) + { + Log(LDEBUG, "POSSIBLE INFINITE LOOP DETECTED - REJECTING"); + return FALSE; + } outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) From ab16513e3a710e173958de4c03ebc6b31d144177 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:48:02 -0700 Subject: [PATCH 100/162] 8-bit precision may be needed here --- src/devctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c6a41bb..e16cbb3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 4 /* clipping precision in bits */ +#define CPX 8 /* clipping precision in bits */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) @@ -106,7 +106,7 @@ static BOOL internal_line(PDCTXT pdctxt, INT32 x1, INT32 y1, INT32 x2, INT32 y2) { INT32 buffer[4]; if (line_clip(buffer, x1 << CPX, y1 << CPX, x2 << CPX, y2 << CPX, pdctxt->cliprect.left << CPX, pdctxt->cliprect.top << CPX, - (pdctxt->cliprect.right - 1) << CPX, (pdctxt->cliprect.bottom - 1) << CPX)) + pdctxt->cliprect.right << CPX, pdctxt->cliprect.bottom << CPX)) return (*pdctxt->funcs->line)(pdctxt->privdata, buffer[0] >> CPX, buffer[1] >> CPX, buffer[2] >> CPX, buffer[3] >> CPX, pdctxt->color, pdctxt->rop2); return TRUE; } From cfc7519727b0bb8ce19c7494c307ba89a3bce72f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:51:53 -0700 Subject: [PATCH 101/162] a fencepost error --- src/devctxt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index e16cbb3..234ac5e 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,9 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 8 /* clipping precision in bits */ +#define CPX 4 /* clipping precision in bits */ + +#define ONE (1 << CPX) /* constant for mathematics */ /* these macros keep the number of bits straight when doing fixed-point multiply & divide */ #define M(a, b) ((((a) * (b))) >> CPX) @@ -74,16 +76,16 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } else if (outcode1 & 0x4) { - tmp = M(x2 - x1, D(ymax - y1, y2 - y1)); + tmp = M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); x1 += tmp; - y1 = ymax; + y1 = ymax - ONE; Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = M(y2 - y1, D(xmax - x1, x2 - x1)); + tmp = M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); y1 += tmp; - x1 = xmax; + x1 = xmax - ONE; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) From d711df60bddac87fe1dc87105ca3c5095ce9abb6 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:55:26 -0700 Subject: [PATCH 102/162] try it with 8-bit precision --- src/devctxt.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 234ac5e..88a1f89 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -19,7 +19,7 @@ inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, I return rc; } -#define CPX 4 /* clipping precision in bits */ +#define CPX 8 /* clipping precision in bits */ #define ONE (1 << CPX) /* constant for mathematics */ @@ -69,29 +69,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT } if (outcode1 & 0x8) { - tmp = M(x2 - x1, D(ymin - y1, y2 - y1)); - x1 += tmp; + x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x4) { - tmp = M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); - x1 += tmp; + x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x2) { - tmp = M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); - y1 += tmp; + y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } else if (outcode1 & 0x1) { - tmp = M(y2 - y1, D(xmin - x1, x2 - x1)); - y1 += tmp; + y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); } From 02c8ede681add977ae0d9d18377441f9625bc737 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 14:56:48 -0700 Subject: [PATCH 103/162] remove use of tmp some places --- src/devctxt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 88a1f89..9971cbc 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -71,25 +71,25 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x4) { x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; - Log(LDEBUG, "clipped against bottom to point (%d, %d), dx=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x2) { y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; - Log(LDEBUG, "clipped against right to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x1) { y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d), dy=%d/%d", x1 >> CPX, y1 >> CPX, tmp >> CPX, tmp); + Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> CPX, y1 >> CPX); } } Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); From 59c8dcc6389de592d6c6e969247d5f1c21f39b57 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 15:00:51 -0700 Subject: [PATCH 104/162] a more extensive clipping test --- scripts/test_clipping.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 72df4a1..083cb9b 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -3,19 +3,27 @@ import upiwin hdc = upiwin.DevCtxt(type='screen') hdc.text_color = 0xFFFFFF # white -hdc.rectangle(100, 100, 199, 199) +hdc.rectangle(99, 99, 200, 200) clip = hdc.get_clip_rect() hdc.set_clip_rect(100, 100, 200, 200) hdc.text_color = 0x0000FF # red -hdc.move_to(50, 199) -hdc.line_to(199, 50) +hdc.move_to(50, 200) +hdc.line_to(200, 50) hdc.text_color = 0x00FF00 # green -hdc.move_to(250, 199) +hdc.move_to(250, 200) hdc.line_to(100, 50) +hdc.text_color = 0xFF0000 # blue +hdc.move_to(50, 100) +hdc.line_to(200, 250) + +hdc.text_color = 0x00FFFF # yellow +hdc.move_to(250, 100) +hdc.line_to(100, 250) + hdc.set_clip_rect(clip[0], clip[1], clip[2], clip[3]) msg = {} From b390886277cf4b4211f3f53038a8d8f5726750da Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Tue, 10 Dec 2019 17:09:16 -0700 Subject: [PATCH 105/162] work in progress - support for bitmaps and BitBlt --- src/Makefile | 2 +- src/bitmap.c | 25 ++++++++++++ src/bitmap.h | 19 +++++++++ src/dc_screen.c | 104 +++++++++++++++++++++++++++++++++++++++++++++-- src/dc_screen.h | 1 + src/devctxt.c | 61 ++++++++++++++++++++++++++- src/devctxt.h | 23 ++++++++++- src/ep_devctxt.c | 52 +++++++++++++++++++++++- 8 files changed, 278 insertions(+), 9 deletions(-) create mode 100755 src/bitmap.c create mode 100755 src/bitmap.h diff --git a/src/Makefile b/src/Makefile index 86ff8a0..df44460 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_upiwin_tmp.o ep_util.o \ - fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o fbprimitive.o \ + fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o bitmap.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/bitmap.c b/src/bitmap.c new file mode 100755 index 0000000..180d3f8 --- /dev/null +++ b/src/bitmap.c @@ -0,0 +1,25 @@ +#include +#include +#include "bitmap.h" + +PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits) +{ + PBITMAP rc; + UINT32 tot_size = sizeof(BITMAP) + (width * height * sizeof(UINT16)); + + rc = (PBITMAP)malloc(tot_size); + if (!rc) + return NULL; + memset(rc, 0, tot_size); + _Go_init(&(rc->hdr), BMP_SIG_WORD, tot_size); + rc->width = width; + rc->height = height; + if (bits) + memcpy(rc->bits, bits, width * height * sizeof(UINT16)); + return rc; +} + +void BMP_Delete(PBITMAP pbmp) +{ + Go_release(&(pbmp->hdr)); +} diff --git a/src/bitmap.h b/src/bitmap.h new file mode 100755 index 0000000..db09917 --- /dev/null +++ b/src/bitmap.h @@ -0,0 +1,19 @@ +#ifndef __BITMAP_H_INCLUDED +#define __BITMAP_H_INCLUDED + +#include "wintype.h" +#include "gfxobj.h" + +#define BMP_SIG_WORD 0x706D4221 /* !Bmp */ + +typedef struct tagBITMAP { + GFXOBJECT hdr; + INT32 width; + INT32 height; + UINT16 bits[0]; +} BITMAP, *PBITMAP; + +extern PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits); +extern void BMP_Delete(PBITMAP pbmp); + +#endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/dc_screen.c b/src/dc_screen.c index 37d173e..caf5595 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -3,6 +3,7 @@ #include "fbinit.h" #include "devctxt.h" #include "dc_screen.h" +#include "bitmap.h" inline static PUINT16 loc_from_coords(PSCREENPRIVDATA priv, INT32 x, INT32 y) { @@ -151,9 +152,97 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, return TRUE; } +static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 op) +{ + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + UINT16 pencolor = native_from_COLORREF(color); + PUINT16 ps, p; + int y, x; + + ps = loc_from_coords(rect->left, rect->top); + for (y = rect->top; y < rect->bottom; y++) + { + p = ps; + for (x = rect->left; x < rect->right; x++) + { + *p = apply_rop2(op, *p, pencolor); + ++p; + } + ps += priv->pix_per_row; + } + return TRUE; +} + +static PDCTXT screen_create_compat(PVOID privdata) +{ + PSCREENPRIVDATA priv_new; + PBITMAP pbmp; + + pbmp = BMP_Create(1, 1, NULL); + if (!pbmp) + return NULL; + priv_new = (PSCREENPRIVDATA)malloc(sizeof(SCREENPRIVDATA)); + if (!priv_new) + { + Go_release(&(pbmp->hdr)); + return NULL; + } + priv_new->pix_per_row = pbmp->width; + priv_new->pdata = pbmp->bits; + + rc = _DC_Allocate(&screen_funtable, priv_new); + if (rc) + { + rc->hdr.dtor = screen_context_destroy; + rc->flags = DCFLG_IS_MEMORY; + rc->baserect.left = rc->baserect.top = 0; + rc->baserect.right = pbmp->width; + rc->baserect.bottom = pbmp->height; + memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); + rc->cur_bitmap = pbmp; + } + else + { + free(priv); + Go_release(&(pbmp->hdr)); + } + return rc; +} + +BOOL screen_new_bitmap(PVOID privdata, PBITMAP pbmp) +{ + PSCREENPRIVDATA priv = (PSCREENPRIVDATA)privdata; + priv->pix_per_row = pbmp->width; + priv->pdata = pbmp->bits; + return TRUE; +} + +BOOL screen_bitblt(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op) +{ + PSCREENPRIVDATA dest = (PSCREENPRIVDATA)p_dest; + PSCREENPRIVDATA src = (PSCREENPRIVDATA)p_src; + PUINT16 pd, ps; + INT32 width, i; + + pd = loc_from_coords(dest, r_dest->left, r_dest->top); + ps = loc_from_coords(src, r_src->left, r_src->top); + width = r_src->right - r_src->left; + for (i = r_src->top; i < r_src->bottom; ++i) + { + memcpy(pd, ps, width * sizeof(UINT16)); + pd += dest->pix_per_row; + ps += src->pix_per_row; + } + return TRUE; +} + static const DCFUNTABLE screen_funtable = { screen_set_pixel, - screen_line + screen_line, + screen_solid_rect, + screen_create_compat, + screen_new_bitmap, + screen_bitblt }; static void screen_context_destroy(PVOID obj) @@ -178,11 +267,18 @@ PDCTXT DC_CreateScreenContext(void) if (rc) { rc->hdr.dtor = screen_context_destroy; - rc->cliprect.left = rc->cliprect.top = 0; - rc->cliprect.right = Fb_Info->width - 1; - rc->cliprect.bottom = Fb_Info->height - 1; + rc->flags = DCFLG_IS_SCREEN; + rc->baserect.left = rc->baserect.top = 0; + rc->baserect.right = Fb_Info->width; + rc->baserect.bottom = Fb_Info->height; + memcpy(&(rc->cliprect), &(rc->baserect), sizeof(RECT)); } else free(priv); return rc; } + +PDCTXT _DC_CreateScreenCompatibleContext(void) +{ + return screen_create_compat(NULL); +} diff --git a/src/dc_screen.h b/src/dc_screen.h index ecd4f31..560187c 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -10,5 +10,6 @@ typedef struct tagSCREENPRIVDATA { } SCREENPRIVDATA, *PSCREENPRIVDATA; extern PDCTXT DC_CreateScreenContext(void); +extern PDCTXT _DC_CreateScreenCompatibleContext(void); #endif /* __DC_SCREEN_H_INCLUDED */ diff --git a/src/devctxt.c b/src/devctxt.c index 9971cbc..9e954d3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -4,6 +4,8 @@ #include "gfxtype.h" #include "gfxobj.h" #include "devctxt.h" +#include "bitmap.h" +#include "dc_screen.h" inline static BYTE line_clip_outcode(INT32 x, INT32 y, INT32 xmin, INT32 ymin, INT32 xmax, INT32 ymax) { @@ -124,7 +126,8 @@ PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata) void _DC_FinalizeCommon(PDCTXT pdctxt) { - /* nothing here yet */ + if (pdctxt->cur_bitmap) + Go_release(&(pdctxt->cur_bitmap->hdr)); } COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color) @@ -163,6 +166,15 @@ BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 botto return TRUE; } +BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom) +{ + RECT rect, actual; + G_set_rect(&rect, left, top, right, bottom); + if (!G_intersect_rect(&actual, &rect, &(pdctxt->cliprect))) + return TRUE; + return (*(pdctxt->funcs-solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); +} + UINT32 DC_GetROP2(PDCTXT pdctxt) { return pdctxt->rop2; @@ -198,3 +210,50 @@ BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect) memcpy(&(pdctxt->cliprect), prect, sizeof(RECT)); return TRUE; } + +PDCTXT DC_CreateCompatible(PDCTXT pdctxt) +{ + if (pdctxt) + return (*(pdctxt->funcs->create_compat))(pdctxt->privdata); + return _DC_CreateScreenCompatibleContext(); +} + +PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) +{ + if (pobj->sig == BMP_SIG_WORD) + { + if ((pdctxt->flags & DCFLG_TYPES) == DCFLG_IS_MEMORY) + { + RECT rtmp; + PBITMAP rbmp = pdctxt->cur_bitmap; + Go_addref(pobj); + if ((*(pdctxt->funcs->new_bitmap))(pdctxt->privdata, (PBITMAP)pobj)) + { + pdctxt->cur_bitmap = (PBITMAP)pobj; + pdctxt->baserect.left = pdctxt->baserect.top = 0; + pdctxt->baserect.right = ((PBITMAP)pobj)->width; + pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; + G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); + memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); + return rbmp; + } + Go_release(pobj); + } + } + return NULL; +} + +BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop) +{ + RECT destrect, actualdest, srcrect, actualsrc; + + G_set_rect(&destrect, x, y, x + width, y + height); + if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect))) + return TRUE; /* no-op */ + G_set_rect(&srcrect, x1, y1, x1 + (actualdest.right - actualdest.left), y1 + (actualdest.bottom - actualdest.top)); + if (!G_rect_intersect(&actualsrc, &srcrect, &(src->baserect))) + return TRUE; + actualdest.right = actualdest.left + (actualsrc.right - actualsrc.left); + actualdest.bottom = actualdest.top + (actualsrc.bottom - actualsrc.top); + return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, src->privdata, &actualsrc, rop); +} diff --git a/src/devctxt.h b/src/devctxt.h index 1b8d3a4..327aab3 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -27,10 +27,18 @@ typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op); typedef BOOL (*DCtx_Line)(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op); +typedef BOOL (*DCtx_SolidRect)(PVOID privdata, PRECT rect, COLORREF color, INT32 op); +typedef PDCTXT (*DCtx_CreateCompat)(PVOID privdata); +typedef BOOL (*DCtx_NewBitmap)(PVOID privdata, PBITMAP pbmp); +typedef BOOL (*DCtx_BitBlt)(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op); typedef struct tagDCFUNTABLE { - DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ - DCtx_Line line; /* draws a line on the display */ + DCtx_SetPixel set_pixel; /* sets a single pixel on the display */ + DCtx_Line line; /* draws a line on the display */ + DCtx_SolidRect solid_rect; /* draws a solid rectangle on the display */ + DCtx_CreateCompat create_compat; /* create a memory DC compatible with this one */ + DCtx_NewBitmap new_bitmap; /* new bitmap selected notification */ + DCtx_BitBlt bitblt; /* bit block transfer */ } DCFUNTABLE; typedef const DCFUNTABLE *PDCFUNTABLE; @@ -39,12 +47,19 @@ typedef struct tagDCTXT { GFXOBJECT hdr; /* the header of all objects */ PDCFUNTABLE funcs; /* device context functions */ PVOID privdata; /* private data for the type of DC */ + UINT32 flags; /* flags for the DC */ + RECT baserect; /* base rectangle */ RECT cliprect; /* clipping rectangle */ POINT pos; /* current position */ UINT32 rop2; /* current raster operation */ COLORREF color; /* current drawing color (XXX replace with pens later) */ + PBITMAP cur_bitmap; /* current selected bitmap */ } DCTXT, *PDCTXT; +#define DCFLG_TYPES 0x03 +#define DCFLG_IS_SCREEN 0x00 +#define DCFLG_IS_MEMORY 0x01 + extern PDCTXT _DC_Allocate(PDCFUNTABLE funcs, PVOID privdata); extern void _DC_FinalizeCommon(PDCTXT pdctxt); @@ -52,12 +67,16 @@ extern COLORREF DC_SetPixel(PDCTXT pdctxt, INT32 x, INT32 y, COLORREF color); extern BOOL DC_LineTo(PDCTXT pdctxt, INT32 x, INT32 y); extern BOOL DC_MoveTo(PDCTXT pdctxt, INT32 x, INT32 y, PPOINT oldpt); extern BOOL DC_Rectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom); +extern BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 bottom); extern UINT32 DC_GetROP2(PDCTXT pdctxt); extern UINT32 DC_SetROP2(PDCTXT pdctxt, UINT32 rop); extern COLORREF DC_GetTextColor(PDCTXT pdctxt); extern COLORREF DC_SetTextColor(PDCTXT pdctxt, COLORREF cr); extern BOOL DC_GetClipRect(PDCTXT pdctxt, PRECT prect); extern BOOL DC_SetClipRect(PDCTXT pdctxt, PRECT prect); +extern PDCTXT DC_CreateCompatible(PDCTXT pdctxt); +extern PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj); +extern BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT source, INT32 x1, INT32 y1, UINT32 rop); #define DC_addref(pdctxt) Go_addref(&(pdctxt->hdr)) #define DC_release(pdctxt) Go_release(&(pdctxt->hdr)) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 651f317..e61611e 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -13,6 +13,8 @@ typedef struct tagDevCtxtObject { PDCTXT pdctxt; } DevCtxtObject; +PyTypeObject DevCtxtType; /* forward declaration */ + static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args) { INT32 x, y; @@ -77,6 +79,41 @@ static PyObject *devctxt_rectangle(DevCtxtObject *self, PyObject *args) return PyBool_FromLong(rc); } +static PyObject *devctxt_solid_rectangle(DevCtxtObject *self, PyObject *args) +{ + INT32 left, top, right, bottom; + BOOL rc; + + if (!PyArg_ParseTuple(args, "iiii", &left, &top, &right, &bottom)) + return NULL; + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + rc = DC_SolidRectangle(self->pdctxt, left, top, right, bottom); + return PyBool_FromLong(rc); +} + +static PyObject *devctxt_bitblt(DevCtxtObject *self, PyObject *args) +{ + INT32 x, y, width, height, x1, y1; + UINT32 rop; + DevCtxtObject *source; + BOOL rc; + + if (!PyArg_ParseTuple(args, "iiiiO!iik", &x, &y, &width, &height, &DevCtxtType, &source, &x1, &y1, &rop)) + return NULL; + if (!(self->pdctxt) || !(source->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "bad device context"); + return NULL; + } + + rc = DC_BitBlt(self->pdctxt, x, y, width, height, source->pdctxt, x1, y1, rop); + return PyBool_FromLong(rc); +} + static PyObject *devctxt_get_clip_rect(DevCtxtObject *self, PyObject *args) { RECT rect; @@ -117,6 +154,10 @@ static PyMethodDef DevCtxtMethods[] = { "Draws a line from the current position to the specified location."}, {"rectangle", (PyCFunction)devctxt_rectangle, METH_VARARGS, "Draws a rectangle."}, + {"solid_rectangle", (PyCFunction)devctxt_solid_rectangle, METH_VARARGS, + "Draws a solid rectangle."}, + {"bitblt", (PyCFunction)devctxt_bitblt, METH_VARARGS, + "Copy bits from one device context to another."}, {"get_clip_rect", (PyCFunction)devctxt_get_clip_rect, METH_VARARGS, "Returns the current clipping rectangle of the device context."}, {"set_clip_rect", (PyCFunction)devctxt_set_clip_rect, METH_VARARGS, @@ -218,6 +259,15 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) return -1; } } + else if (strcmp(type, "memory") == 0) + { + self->pdctxt = _DC_CreateScreenCompatibleContext(); + if (!(self->pdctxt)) + { + PyErr_SetString(PyExc_RuntimeError, "unable to create memory context"); + return -1; + } + } else { PyErr_Format(PyExc_RuntimeError, "invalid type '%s'", type); @@ -226,7 +276,7 @@ static int devctxt_init(DevCtxtObject *self, PyObject *args, PyObject *kwds) return 0; } -static PyTypeObject DevCtxtType = { +PyTypeObject DevCtxtType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "upiwin.DevCtxt", .tp_doc = "Device context object", From 20ed16a9ae7ab900a1ea92e24c0d8759e5913a71 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:45:45 -0700 Subject: [PATCH 106/162] sending over all the bitmap and select_object work for compile check --- src/Makefile | 6 +-- src/dc_screen.c | 1 + src/devctxt.c | 15 ------ src/ep_bitmap.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ src/ep_devctxt.c | 59 +++++++++++++++++++---- src/ep_types.h | 28 +++++++++++ 6 files changed, 202 insertions(+), 26 deletions(-) create mode 100755 src/ep_bitmap.c create mode 100755 src/ep_types.h diff --git a/src/Makefile b/src/Makefile index df44460..eb11555 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,9 +2,9 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_upiwin_tmp.o ep_util.o \ - fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o bitmap.o fbprimitive.o \ - log.o gpio.o msg_queue.o time_func.o config.o splash.o +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o + ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ + bitmap.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 \ -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT diff --git a/src/dc_screen.c b/src/dc_screen.c index caf5595..e6f5149 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -89,6 +89,7 @@ static BOOL screen_line(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, ASSERT(y2 >= 0); ASSERT(y2 < Fb_Info->height); + /* uses Bresenham's line algorithm with 16-bit fixed-point arithmetic */ if (ABS(dx) < ABS(dy)) { if (y1 > y2) diff --git a/src/devctxt.c b/src/devctxt.c index 9e954d3..4d342f7 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -35,9 +35,6 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT INT32 tmp; int nloop = 0; - Log(LDEBUG, "clipping line from (%d, %d) to (%d, %d) against bounding box (%d, %d, %d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX, - xmin >> CPX, ymin >> CPX, xmax >> CPX, ymax >> CPX); - /* Cohen-Sutherland line-clipping algorithm (see Foley & Van Dam, pp. 145-149) */ for (;;) { @@ -49,18 +46,11 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT outcode1 = line_clip_outcode(x1, y1, xmin, ymin, xmax, ymax); outcode2 = line_clip_outcode(x2, y2, xmin, ymin, xmax, ymax); if ((outcode1 & outcode2) != 0) - { - Log(LDEBUG,"*REJECT*"); return FALSE; /* trivial rejection */ - } else if ((outcode1 == 0) && (outcode2 == 0)) - { - Log(LDEBUG,"*ACCEPT*"); break; /* trivial acceptance */ - } if (outcode1 == 0) { - Log(LDEBUG, "exchange points"); tmp = x1; x1 = x2; x2 = tmp; @@ -73,28 +63,23 @@ static BOOL line_clip(PINT32 output, INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT { x1 += M(x2 - x1, D(ymin - y1, y2 - y1)); y1 = ymin; - Log(LDEBUG, "clipped against top to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x4) { x1 += M(x2 - x1, D(ymax - ONE - y1, y2 - y1)); y1 = ymax - ONE; - Log(LDEBUG, "clipped against bottom to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x2) { y1 += M(y2 - y1, D(xmax - ONE - x1, x2 - x1)); x1 = xmax - ONE; - Log(LDEBUG, "clipped against right to point (%d, %d)", x1 >> CPX, y1 >> CPX); } else if (outcode1 & 0x1) { y1 += M(y2 - y1, D(xmin - x1, x2 - x1)); x1 = xmin; - Log(LDEBUG, "clipped against left to point (%d, %d)", x1 >> CPX, y1 >> CPX); } } - Log(LDEBUG, "final line is from (%d, %d) to (%d, %d)", x1 >> CPX, y1 >> CPX, x2 >> CPX, y2 >> CPX); output[0] = x1; output[1] = y1; output[2] = x2; diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c new file mode 100755 index 0000000..9f99ac6 --- /dev/null +++ b/src/ep_bitmap.c @@ -0,0 +1,119 @@ +#include +#define PY_SSIZE_T_CLEAN +#include +#include "gfxobj.h" +#include "bitmap.h" +#include "ep_types.h" + +static PyMethodDef BitmapMethods[] = { + {NULL, NULL, 0, NULL} +}; + +static PyObject *bitmap_get_width(BitmapObject *self, void *closure) +{ + if (!(self->pbmp)) + { + PyErr_SetString(PyExc_RuntimeError, "bad bitmap object"); + return NULL; + } + return PyLong_FromUnsignedLong(self->pbmp->width); +} + +static PyObject *bitmap_get_height(BitmapObject *self, void *closure) +{ + if (!(self->pbmp)) + { + PyErr_SetString(PyExc_RuntimeError, "bad bitmap object"); + return NULL; + } + return PyLong_FromUnsignedLong(self->pbmp->height); +} + +static PyGetSetDef BitmapProperties[] = { + {"width", (getter)bitmap_get_width, NULL, + "Width of this bitmap", NULL}, + {"height", (getter)bitmap_get_height, NULL, + "Height of this bitmap", NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = { "width", "height", NULL }; + int width = 0, height = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$ii", kwlist, &width, &height)) + return -1; + + width = MAX(1, width); + height = MAX(1, height); + self->pbmp = BMP_Create(width, height, NULL); + if (!(self->bmp)) + { + PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); + return -1; + } + return 0; +} + +static void bitmap_dealloc(BitmapObject *self) +{ + if (self->pbmp) + BMP_Delete(self->pbmp); + Py_TYPE(self)->tp_free((PyObject *)self); +} + +PyTypeObject BitmapType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "upiwin.Bitmap", + .tp_doc = "Bitmap object", + .tp_basicsize = sizeof(BitmapObject), + .tp_itemsize = 0, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_new = PyType_GenericNew, + .tp_init = (initproc)bitmap_init, + .tp_dealloc = (destructor)bitmap_dealloc, + .tp_methods = BitmapMethods, + .tp_getset = BitmapProperties, +}; + +HRESULT Epython_register_bitmap(PyObject *module) +{ + if (PyType_Ready(&BitmapType) < 0) + return E_FAIL; + Py_INCREF(&BitmapType); + if (PyModule_AddObject(module, "Bitmap", (PyObject *)(&BitmapType)) < 0) + { + Py_DECREF(&BitmapType); + return E_FAIL; + } + return S_OK; +} + +PyObject *Epython_wrap_bitmap(PBITMAP pbmp) +{ + PyObject *rc = NULL, *args, *kwargs; + BitmapObject *pbitmapobj; + + args = PyTuple_New(0); + if (args) + { + kwargs = PyDict_New(); + if (kwargs) + { + rc = PyType_GenericNew(&BitmapType, args, kwargs); + if (rc) + { + pbitmapobj = (BitmapObject)rc; + BMP_Delete(pbitmapobj->pbmp); + pbitmapobj->pbmp = pbmp; + } + Py_DECREF(kwargs); + } + Py_DECREF(args); + } + + if (!rc) + PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); + return rc; +} diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index e61611e..09c0687 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -7,13 +7,7 @@ #include "devctxt.h" #include "dc_screen.h" #include "ep_init.h" - -typedef struct tagDevCtxtObject { - PyObject_HEAD - PDCTXT pdctxt; -} DevCtxtObject; - -PyTypeObject DevCtxtType; /* forward declaration */ +#include "ep_types.h" static PyObject *devctxt_set_pixel(DevCtxtObject *self, PyObject *args) { @@ -145,6 +139,54 @@ static PyObject *devctxt_set_clip_rect(DevCtxtObject *self, PyObject *args) return PyBool_FromLong(rc); } +static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp) +{ + BitmapObject *old_bitmap = NULL; + PBITMAP old_pbmp; + + if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) + { + PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); + return NULL; + } + old_bitmap = self->selected_bitmap; + old_pbmp = DC_SelectObject(self->pdctxt, newbmp->pbmp); + if (!old_bitmap) + { + old_bitmap = Epython_wrap_bitmap(old_pbmp); + if (!old_bitmap) + { + DC_SelectObject(self->pdctxt, old_pbmp); + return NULL; + } + else + PY_INCREF(old_bitmap); + } + Py_DECREF(self->selected_bitmap); + self->selected_bitmap = newbmp; + Py_INCREF(self->selected_bitmap); + return old_bitmap; +} + +static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) +{ + PyObject *obj; + PBITMAP old_bitmap; + BitmapObject *old_bmp_object, *new_bmp_object; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + if (!obj) + { + PyErr_SetString(PyExc_RuntimeError, "bad object selected"); + return NULL; + } + if (PyObject_TypeCheck(obj, &BitmapType)) + return devctxt_select_bitmap(self, (BitmapObject *)obj); + PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); + return NULL; +} + static PyMethodDef DevCtxtMethods[] = { {"set_pixel", (PyCFunction)devctxt_set_pixel, METH_VARARGS, "Sets a single pixel on the display."}, @@ -158,6 +200,8 @@ static PyMethodDef DevCtxtMethods[] = { "Draws a solid rectangle."}, {"bitblt", (PyCFunction)devctxt_bitblt, METH_VARARGS, "Copy bits from one device context to another."}, + {"select_object", (PyCFunction)devctxt_select_object, METH_VARARGS, + "Selects a graphic object into the device context."}, {"get_clip_rect", (PyCFunction)devctxt_get_clip_rect, METH_VARARGS, "Returns the current clipping rectangle of the device context."}, {"set_clip_rect", (PyCFunction)devctxt_set_clip_rect, METH_VARARGS, @@ -165,7 +209,6 @@ static PyMethodDef DevCtxtMethods[] = { {NULL, NULL, 0, NULL} }; - static PyObject *devctxt_get_rop2(DevCtxtObject *self, void *closure) { if (!(self->pdctxt)) diff --git a/src/ep_types.h b/src/ep_types.h new file mode 100755 index 0000000..55d2eae --- /dev/null +++ b/src/ep_types.h @@ -0,0 +1,28 @@ +#ifndef __EP_TYPES_H_INCLUDED +#define __EP_TYPES_H_INCLUDED + +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "gfxtype.h" +#include "gfxobj.h" +#include "devctxt.h" +#include "bitmap.h" + +typedef struct tagBitmapObject { + PyObject_HEAD + PBITMAP pbmp; +} BitmapObject; + +typedef struct tagDevCtxtObject { + PyObject_HEAD + PDCTXT pdctxt; + BitmapObject *selected_bitmap; +} DevCtxtObject; + +extern PyTypeObject DevCtxtType; +extern PyTypeObject BitmapType; + +extern PyObject *Epython_wrap_bitmap(PBITMAP pbmp); + +#endif /* __EP_TYPES_H_INCLUDED */ From ee3df7bffcfcacbd489ec90cf18c7e21ac680bed Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:47:45 -0700 Subject: [PATCH 107/162] forgot to add the registration of the Bitmap type --- src/ep_upiwin.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 9878d3c..a8e33e9 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -81,6 +81,12 @@ PyObject *Epython_init_upiwin_module(void) return NULL; } + if (FAILED(Epython_register_bitmap(module))) + { + Py_DECREF(module); + return NULL; + } + if (FAILED(Epython_register_devctxt(module))) { Py_DECREF(module); From 76269f51897fdc0dbd9ed9e7bcf4240800a670d1 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Wed, 11 Dec 2019 10:50:59 -0700 Subject: [PATCH 108/162] fix to makefile --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index eb11555..dd7ba89 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.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 From 379bcab8851aee6ec58872d511cf65f0dde38733 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:50:39 -0700 Subject: [PATCH 109/162] fixes to some headers that were missing stuff --- src/devctxt.h | 1 + src/ep_init.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/devctxt.h b/src/devctxt.h index 327aab3..f83fa2b 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -4,6 +4,7 @@ #include "wintype.h" #include "gfxtype.h" #include "gfxobj.h" +#include "bitmap.h" #define DCTXT_SIG_WORD 0x78744344 /* "DCtx */ diff --git a/src/ep_init.h b/src/ep_init.h index e394470..5e68ef4 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -15,6 +15,7 @@ extern PyObject *Epython_init_upiwin_module(void); extern PyObject *Epython_init_upiwin_tmp_module(void); extern HRESULT Epython_register_devctxt(PyObject *module); +extern HRESULT Epython_register_bitmap(PyObject *module); extern HRESULT Epython_setup(void); extern HRESULT Epython_run(void); From 4745d51361d5979688f6bcd3a1fde5d292809509 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:54:09 -0700 Subject: [PATCH 110/162] fix some compile errors --- src/bitmap.c | 2 +- src/bitmap.h | 2 +- src/devctxt.h | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/bitmap.c b/src/bitmap.c index 180d3f8..fa517ea 100755 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -2,7 +2,7 @@ #include #include "bitmap.h" -PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits) +PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits) { PBITMAP rc; UINT32 tot_size = sizeof(BITMAP) + (width * height * sizeof(UINT16)); diff --git a/src/bitmap.h b/src/bitmap.h index db09917..f7500b5 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -13,7 +13,7 @@ typedef struct tagBITMAP { UINT16 bits[0]; } BITMAP, *PBITMAP; -extern PBITMAP BMP_Create(INT32 width, INT32 height, const VOID *bits); +extern PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits); extern void BMP_Delete(PBITMAP pbmp); #endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/devctxt.h b/src/devctxt.h index f83fa2b..017e70a 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -26,10 +26,12 @@ #define R2_MERGEPEN 15 #define R2_WHITE 16 +struct tagDCTXT; /* forward declaration */ + typedef COLORREF (*DCtx_SetPixel)(PVOID privdata, INT32 x, INT32 y, COLORREF color, INT32 op); typedef BOOL (*DCtx_Line)(PVOID privdata, INT32 x1, INT32 y1, INT32 x2, INT32 y2, COLORREF color, INT32 op); typedef BOOL (*DCtx_SolidRect)(PVOID privdata, PRECT rect, COLORREF color, INT32 op); -typedef PDCTXT (*DCtx_CreateCompat)(PVOID privdata); +typedef struct tagDCTXT *(*DCtx_CreateCompat)(PVOID privdata); typedef BOOL (*DCtx_NewBitmap)(PVOID privdata, PBITMAP pbmp); typedef BOOL (*DCtx_BitBlt)(PVOID p_dest, PRECT r_dest, PVOID p_src, PRECT r_src, UINT32 op); From 864360f9faa5680367c9d9cae322af1d6e4892f1 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:57:07 -0700 Subject: [PATCH 111/162] compile errors in new stuff --- src/ep_bitmap.c | 3 ++- src/ep_devctxt.c | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 9f99ac6..4f4f3a6 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -1,6 +1,7 @@ #include #define PY_SSIZE_T_CLEAN #include +#include "scode.h" #include "gfxobj.h" #include "bitmap.h" #include "ep_types.h" @@ -48,7 +49,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); - if (!(self->bmp)) + if (!(self->pbmp)) { PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); return -1; diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 09c0687..1300692 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -165,14 +165,12 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); - return old_bitmap; + return (PyObject *)old_bitmap; } static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - PBITMAP old_bitmap; - BitmapObject *old_bmp_object, *new_bmp_object; if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; From 971826e1189df203f8145415d7f9e17c6b07e55d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 10:59:14 -0700 Subject: [PATCH 112/162] more pushing of errors --- src/ep_bitmap.c | 2 +- src/ep_devctxt.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 4f4f3a6..abb2406 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -105,7 +105,7 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) rc = PyType_GenericNew(&BitmapType, args, kwargs); if (rc) { - pbitmapobj = (BitmapObject)rc; + pbitmapobj = (BitmapObject *)rc; BMP_Delete(pbitmapobj->pbmp); pbitmapobj->pbmp = pbmp; } diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 1300692..4e77134 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -156,11 +156,11 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp old_bitmap = Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { - DC_SelectObject(self->pdctxt, old_pbmp); + DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } else - PY_INCREF(old_bitmap); + Py_INCREF(old_bitmap); } Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; From e59e6e0bae8512d313a0f6ba3f7b210d85cdeb85 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:04:09 -0700 Subject: [PATCH 113/162] more compile errors --- src/devctxt.c | 6 +++--- src/ep_devctxt.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index 4d342f7..c1ea7e3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -220,7 +220,7 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); - return rbmp; + return (PGFXOBJECT)rbmp; } Go_release(pobj); } @@ -236,9 +236,9 @@ BOOL DC_BitBlt(PDCTXT dest, INT32 x, INT32 y, INT32 width, INT32 height, PDCTXT if (!G_rect_intersect(&actualdest, &destrect, &(dest->cliprect))) return TRUE; /* no-op */ G_set_rect(&srcrect, x1, y1, x1 + (actualdest.right - actualdest.left), y1 + (actualdest.bottom - actualdest.top)); - if (!G_rect_intersect(&actualsrc, &srcrect, &(src->baserect))) + if (!G_rect_intersect(&actualsrc, &srcrect, &(source->baserect))) return TRUE; actualdest.right = actualdest.left + (actualsrc.right - actualsrc.left); actualdest.bottom = actualdest.top + (actualsrc.bottom - actualsrc.top); - return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, src->privdata, &actualsrc, rop); + return (*(dest->funcs->bitblt))(dest->privdata, &actualdest, source->privdata, &actualsrc, rop); } diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 4e77134..9449865 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -150,7 +150,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp return NULL; } old_bitmap = self->selected_bitmap; - old_pbmp = DC_SelectObject(self->pdctxt, newbmp->pbmp); + old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); if (!old_bitmap) { old_bitmap = Epython_wrap_bitmap(old_pbmp); From c388dbc1d265625fd3b1519c7b52e8e3d7438da8 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:05:36 -0700 Subject: [PATCH 114/162] more errors --- src/devctxt.c | 4 ++-- src/ep_devctxt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devctxt.c b/src/devctxt.c index c1ea7e3..2830f13 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -155,9 +155,9 @@ BOOL DC_SolidRectangle(PDCTXT pdctxt, INT32 left, INT32 top, INT32 right, INT32 { RECT rect, actual; G_set_rect(&rect, left, top, right, bottom); - if (!G_intersect_rect(&actual, &rect, &(pdctxt->cliprect))) + if (!G_rect_intersect(&actual, &rect, &(pdctxt->cliprect))) return TRUE; - return (*(pdctxt->funcs-solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); + return (*(pdctxt->funcs->solid_rect))(pdctxt->privdata, &actual, pdctxt->color, pdctxt->rop2); } UINT32 DC_GetROP2(PDCTXT pdctxt) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 9449865..87a407c 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -153,7 +153,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); if (!old_bitmap) { - old_bitmap = Epython_wrap_bitmap(old_pbmp); + old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); From d7439be3206265400df7fcaca43e316a4e544bee Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:09:40 -0700 Subject: [PATCH 115/162] still plugging away at errors --- src/dc_screen.c | 6 ++++-- src/devctxt.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index e6f5149..d248013 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,4 +1,5 @@ #include +#inlcude #include "log.h" #include "fbinit.h" #include "devctxt.h" @@ -160,7 +161,7 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 PUINT16 ps, p; int y, x; - ps = loc_from_coords(rect->left, rect->top); + ps = loc_from_coords(priv, rect->left, rect->top); for (y = rect->top; y < rect->bottom; y++) { p = ps; @@ -178,6 +179,7 @@ static PDCTXT screen_create_compat(PVOID privdata) { PSCREENPRIVDATA priv_new; PBITMAP pbmp; + PDCTXT rc; pbmp = BMP_Create(1, 1, NULL); if (!pbmp) @@ -204,7 +206,7 @@ static PDCTXT screen_create_compat(PVOID privdata) } else { - free(priv); + free(priv_new); Go_release(&(pbmp->hdr)); } return rc; diff --git a/src/devctxt.c b/src/devctxt.c index 2830f13..217a0e3 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -218,7 +218,7 @@ PGFXOBJECT DC_SelectObject(PDCTXT pdctxt, PGFXOBJECT pobj) pdctxt->baserect.left = pdctxt->baserect.top = 0; pdctxt->baserect.right = ((PBITMAP)pobj)->width; pdctxt->baserect.bottom = ((PBITMAP)pobj)->height; - G_intersect_rect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); + G_rect_intersect(&rtmp, &(pdctxt->baserect), &(pdctxt->cliprect)); memcpy(&(pdctxt->cliprect), &rtmp, sizeof(RECT)); return (PGFXOBJECT)rbmp; } From 899be01f288eef596949e4db44baab25e985ae0f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:12:15 -0700 Subject: [PATCH 116/162] should be most of it now --- src/dc_screen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dc_screen.c b/src/dc_screen.c index d248013..29c4050 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,5 +1,5 @@ #include -#inlcude +#include #include "log.h" #include "fbinit.h" #include "devctxt.h" @@ -175,6 +175,9 @@ static BOOL screen_solid_rect(PVOID privdata, PRECT rect, COLORREF color, INT32 return TRUE; } +static const DCFUNTABLE screen_funtable; /* forward declaration */ +static void screen_context_destroy(PVOID obj); + static PDCTXT screen_create_compat(PVOID privdata) { PSCREENPRIVDATA priv_new; From 7c844e6b69f18a4978f7888637bff5f47ea993ce Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:13:44 -0700 Subject: [PATCH 117/162] use -Werror to make all warnings into errors (should have done this already) --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index dd7ba89..95a4c9e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,7 +7,7 @@ OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt. bitmap.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 \ - -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT + -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \ -Wl,-Bsymbolic-functions From 65999084c442d6d4334ecc04e2c774e36d0e12bf Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 11:32:19 -0700 Subject: [PATCH 118/162] added "click" events for both buttons and touch --- scripts/tmp_main.py | 4 ++++ src/config.c | 2 ++ src/config.h | 2 ++ src/ep_upiwin.c | 2 ++ src/msg.h | 2 ++ src/sysinput.c | 21 +++++++++++++++++++++ 6 files changed, 33 insertions(+) diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 815aa44..902d767 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -25,6 +25,8 @@ while upiwin.get_message(msg): print("Button {0} was pressed.".format(msg['attrs'][0])) elif msg['message'] == upiwin.WM_HWBUTTONUP: print("Button {0} was released.".format(msg['attrs'][0])) + elif msg['message'] == upiwin.WM_HWBUTTONCLICK: + print("Button {0} was clicked.".format(msg['attrs'][0])) bn = msg['attrs'][0] if bn == 1: print("Backlight ON.") @@ -41,3 +43,5 @@ while upiwin.get_message(msg): log_touch('MOVE', msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_TOUCHUP: log_touch('UP', msg['attrs'][0], msg['attrs'][1]) + elif msg['message'] == upiwin.WM_TOUCHCLICK: + log_touch('CLICK', msg['attrs'][0], msg['attrs'][1]) diff --git a/src/config.c b/src/config.c index cc2b67f..7f5dfe7 100644 --- a/src/config.c +++ b/src/config.c @@ -70,6 +70,8 @@ static void init_defaults(void) Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; + Gconfig.click_time = 200; + Gconfig.click_radius = 2; } static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed) diff --git a/src/config.h b/src/config.h index 0a514a7..22253ac 100644 --- a/src/config.h +++ b/src/config.h @@ -12,6 +12,8 @@ typedef struct tagGLOBAL_CONFIG { PCSTR python_loc; /* location of the Python3 executable */ UINT32 button_debounce; /* minimum time between button up and next button down (ms) */ UINT32 sys_mq_length; /* length of system message queue */ + UINT32 click_time; /* time between button/touch DOWN and UP to be considered a "click" (ms) */ + UINT32 click_radius; /* maximum number of pixels a touch can "drift" to be considered a "click" */ PCSTR script_name; /* script name to be run */ INT32 script_arg_count; /* number of arguments to pass to the script */ PPCSTR script_args; /* arguments to pass to the script */ diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index a8e33e9..1354d06 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -44,9 +44,11 @@ BEGIN_CONSTANT_TABLE(UPIWINConstants) CONSTANT_INT_MACRO(WM_QUIT) CONSTANT_INT_MACRO(WM_HWBUTTONDOWN) CONSTANT_INT_MACRO(WM_HWBUTTONUP) + CONSTANT_INT_MACRO(WM_HWBUTTONCLICK) CONSTANT_INT_MACRO(WM_TOUCHDOWN) CONSTANT_INT_MACRO(WM_TOUCHMOVE) CONSTANT_INT_MACRO(WM_TOUCHUP) + CONSTANT_INT_MACRO(WM_TOUCHCLICK) /* Raster op constants */ CONSTANT_INT_MACRO(R2_BLACK) CONSTANT_INT_MACRO(R2_NOTMERGEPEN) diff --git a/src/msg.h b/src/msg.h index 7778bde..afff6a9 100644 --- a/src/msg.h +++ b/src/msg.h @@ -17,9 +17,11 @@ typedef struct tagMSG { #define WM_HWBUTTONDOWN 0x0020 #define WM_HWBUTTONUP 0x0021 +#define WM_HWBUTTONCLICK 0x0022 #define WM_TOUCHDOWN 0x0030 #define WM_TOUCHMOVE 0x0031 #define WM_TOUCHUP 0x0032 +#define WM_TOUCHCLICK 0x0033 #endif /* __MSG_H_INCLUDED */ diff --git a/src/sysinput.c b/src/sysinput.c index 44335bd..9419d5d 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -28,11 +28,14 @@ static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER; /* condition for /* Local data for poll_buttons() */ static UINT32 last_bstate = 0; /* previous button state */ static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */ +static TIMESTAMP button_down_time[GPIO_BUTTON_COUNT]; /* timestamps for click detection */ /* Local data for poll_touchscreen() */ static UINT_PTR touch_x = 0; /* X coordinate to send with next message */ static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */ static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */ +static UINT_PTR touch_down_x, touch_down_y; /* location of the touch-down event for click detection */ +static TIMESTAMP touch_down_time; /* timestamp for click detection */ static BOOL poll_buttons(void) { @@ -57,11 +60,14 @@ static BOOL poll_buttons(void) /* reset contact bounce timer - only seems to happen after button releases */ button_event_ok[attr - 1] = now + Gconfig.button_debounce; Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr); + if ((now - button_down_time[attr - 1]) <= Gconfig.click_time) + Mq_post1(Sys_Queue, 0, WM_HWBUTTONCLICK, attr); posted = TRUE; } else if (down & mask) { Mq_post1(Sys_Queue, 0, WM_HWBUTTONDOWN, attr); + button_down_time[attr - 1] = now; posted = TRUE; } } @@ -74,6 +80,7 @@ static BOOL poll_touchscreen(void) { BOOL posted = FALSE; int nb, nev, xerrno, i; + TIMESTAMP now; struct input_event buffer[INPUT_EVENT_BATCH]; nb = read(ts_fd, buffer, INPUT_EVENT_BATCH * sizeof(struct input_event)); @@ -102,7 +109,21 @@ static BOOL poll_touchscreen(void) case EV_SYN: if (buffer[i].code == SYN_REPORT) { + now = Time_since_start(); Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y); + if (touch_nextmsg == WM_TOUCHDOWN) + { + touch_down_x = touch_x; + touch_down_y = touch_y; + touch_down_time = now; + } + else if (touch_nextmsg = WM_TOUCHUP) + { + if ( ((now - touch_down_time) <= Gconfig.click_time) + && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) + && (ABS((INT32)touch_y - (INT32)touch_down_y) <= Gconfig.click_radius)) + Mq_post2(Sys_Queue, 0, WM_TOUCHCLICK, touch_x, touch_y); + } touch_nextmsg = WM_TOUCHMOVE; posted = TRUE; } From 1088f630a0e2df70660c6b3a1a41f6ddf39b0b38 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:05:53 -0700 Subject: [PATCH 119/162] added the rgb function to upiwin and started building the demo script --- scripts/demo1.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile | 2 +- src/ep_graphics.c | 13 +++++++++++ src/ep_upiwin.c | 3 +++ src/ep_upiwin.h | 2 ++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100755 scripts/demo1.py create mode 100755 src/ep_graphics.c diff --git a/scripts/demo1.py b/scripts/demo1.py new file mode 100755 index 0000000..1c30f00 --- /dev/null +++ b/scripts/demo1.py @@ -0,0 +1,58 @@ +# Demo script that implements a simple drawing program +import upiwin + +# Save off some color values. +WHITE = upiwin.rgb(255, 255, 255) +LTGRAY = upiwin.rgb(204, 204, 204) +YELLOW = upiwin.rgb(255, 255, 0) + +hdc = upiwin.DevCtxt(type='screen') + +# divide the screen into "drawing" and "command" areas +drawing_rect = hdc.get_clip_rect() +command_rect = drawing_rect +drawing_rect[2] -= 60; +command_rect[0] = drawing_rect[2] + 1 + +# further divide up the "command" area +cmd1_rect = command_rect +cmd2_rect = command_rect +cmd3_rect = command_rect +cmd4_rect = command_rect +cmd1_rect[3] = 60; +cmd2_rect[1] = 60; +cmd2_rect[3] = 120; +cmd3_rect[1] = 120; +cmd3_rect[3] = 180; +cmd4_rect[1] = 180; + +def point_in_rect(rect, x, y): + return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + + + + +# --- Initialize and start message loop --- + +# Draw the basic layout. +hdc.set_text_color(LTGRAY) +hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) +hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) +hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) +hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) + +# Main message loop +msg = {} +while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_TOUCHCLICK: + if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 1") + elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 2") + elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 3") + elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1]): + print("Click command 4") + elif msg['message'] == upiwin.WM_HWBUTTONCLICK: + if msg['attrs'][0] == 4: # Button 4 = Exit app + upiwin.post_quit_message(0) diff --git a/src/Makefile b/src/Makefile index 95a4c9e..e9843a7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png -OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_devctxt.o ep_bitmap.o \ +OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.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 diff --git a/src/ep_graphics.c b/src/ep_graphics.c new file mode 100755 index 0000000..3643889 --- /dev/null +++ b/src/ep_graphics.c @@ -0,0 +1,13 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "wintype.h" +#include "gfxtype.h" + +PyObject *Epython_rgb(PyObject *self, PyObject *args) +{ + UINT32 r, g, b; + + if (!PyArg_ParseTuple(args, "kkk", &r, &g, &b)) + return NULL; + return PyLong_FromUnsignedLong(RGB(r, g, b)); +} diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 1354d06..16ca9ed 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -23,6 +23,9 @@ static PyMethodDef UPIWINMethods[] = { "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."}, + /* Graphics functions */ + {"rgb", Epython_rgb, METH_VARARGS, + "Creates a color value from separate red, green, and blue indexes."}, {NULL, NULL, 0, NULL} }; diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index b6dbe14..b80fd0c 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -22,5 +22,7 @@ extern PyObject *Epython_set_backlight_level(PyObject *self, PyObject *args); extern PyObject *Epython_get_message(PyObject *self, PyObject *args); extern PyObject *Epython_post_quit_message(PyObject *self, PyObject *args); +/* ep_graphics.c */ +extern PyObject *Epython_rgb(PyObject *self, PyObject *args); #endif /* __EP_UPIWIN_H_INCLUDED */ From 0d6b6ba8b40e952e66844dc00f392fda5cd1a121 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Wed, 11 Dec 2019 12:07:17 -0700 Subject: [PATCH 120/162] minor fix to sysinput --- src/sysinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysinput.c b/src/sysinput.c index 9419d5d..a616063 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -117,7 +117,7 @@ static BOOL poll_touchscreen(void) touch_down_y = touch_y; touch_down_time = now; } - else if (touch_nextmsg = WM_TOUCHUP) + else if (touch_nextmsg == WM_TOUCHUP) { if ( ((now - touch_down_time) <= Gconfig.click_time) && (ABS((INT32)touch_x - (INT32)touch_down_x) <= Gconfig.click_radius) From 9fbb7be7172b190a45ea6976aecc1995904f3bf4 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:12:33 -0700 Subject: [PATCH 121/162] I forgot you can't alter the elements of tuples --- scripts/demo1.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 1c30f00..bd59231 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -9,22 +9,15 @@ YELLOW = upiwin.rgb(255, 255, 0) hdc = upiwin.DevCtxt(type='screen') # divide the screen into "drawing" and "command" areas -drawing_rect = hdc.get_clip_rect() -command_rect = drawing_rect -drawing_rect[2] -= 60; -command_rect[0] = drawing_rect[2] + 1 +screen_rect = hdc.get_clip_rect() +drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect[3]) +command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) # further divide up the "command" area -cmd1_rect = command_rect -cmd2_rect = command_rect -cmd3_rect = command_rect -cmd4_rect = command_rect -cmd1_rect[3] = 60; -cmd2_rect[1] = 60; -cmd2_rect[3] = 120; -cmd3_rect[1] = 120; -cmd3_rect[3] = 180; -cmd4_rect[1] = 180; +cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) +cmd2_rect = (command_rect[0], 60, command_rect[2], 120) +cmd3_rect = (command_rect[0], 120, command_rect[2], 180) +cmd3_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) From c309e4dc0f3b755cc91798632e0d2d9275309c6e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:13:35 -0700 Subject: [PATCH 122/162] now I forgot that text_color is an ATTRIBUTE of a DC --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index bd59231..022eb2a 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -28,7 +28,7 @@ def point_in_rect(rect, x, y): # --- Initialize and start message loop --- # Draw the basic layout. -hdc.set_text_color(LTGRAY) +hdc.text_color = LTGRAY hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) From acc7aacf7b16e2859e480bc03f7cf84f8ea9fa06 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:14:55 -0700 Subject: [PATCH 123/162] fixed another typo --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 022eb2a..7eb0e21 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -17,7 +17,7 @@ command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) cmd2_rect = (command_rect[0], 60, command_rect[2], 120) cmd3_rect = (command_rect[0], 120, command_rect[2], 180) -cmd3_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) +cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) From 1ea7a740fec568d062227c9cd1e4e353bdacfbe3 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:19:48 -0700 Subject: [PATCH 124/162] disco debugging the script --- scripts/demo1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 7eb0e21..b1035fc 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -38,6 +38,7 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: + print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): print("Click command 1") elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): From 8441949e3d44d0aa1adae8e8ecc2ba1dd88dd1df Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:21:03 -0700 Subject: [PATCH 125/162] script had a syntax error --- scripts/demo1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index b1035fc..5c83439 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -39,13 +39,13 @@ msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) - if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1]): + if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 1") - elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 2") - elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 3") - elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1]): + elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1])): print("Click command 4") elif msg['message'] == upiwin.WM_HWBUTTONCLICK: if msg['attrs'][0] == 4: # Button 4 = Exit app From 46213020ddc9d263ce280bfec76093074bf4b925 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:26:05 -0700 Subject: [PATCH 126/162] separate out the message handlers for clarity --- scripts/demo1.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 5c83439..fbdf056 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -23,7 +23,22 @@ def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) +# --- Message handlers --- +def on_touchclick(x, y): + print("Click at {0},{1}".format(x, y)) + if point_in_rect(cmd1_rect, x, y): + print("Click command 1") + elif point_in_rect(cmd2_rect, x, y): + print("Click command 2") + elif point_in_rect(cmd3_rect, x, y): + print("Click command 3") + elif point_in_rect(cmd4_rect, x, y): + print("Click command 4") + +def on_button_click(button): + if button == 4: # Button 4 = Exit app + upiwin.post_quit_message(0) # --- Initialize and start message loop --- @@ -38,15 +53,6 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) msg = {} while upiwin.get_message(msg): if msg['message'] == upiwin.WM_TOUCHCLICK: - print("Click at {0},{1}".format(msg['attrs'][0], msg['attrs'][1]) - if point_in_rect(cmd1_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 1") - elif point_in_rect(cmd2_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 2") - elif point_in_rect(cmd3_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 3") - elif point_in_rect(cmd4_rect, msg['attrs'][0], msg['attrs'][1])): - print("Click command 4") + on_touchclick(msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_HWBUTTONCLICK: - if msg['attrs'][0] == 4: # Button 4 = Exit app - upiwin.post_quit_message(0) + on_button_click(msg['attrs'][0]) From a62364082aeec7602401c4cf34011ad8b7402f6a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:31:32 -0700 Subject: [PATCH 127/162] try to fix the coordinates returned by touch events --- src/sysinput.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sysinput.c b/src/sysinput.c index a616063..cdc0d01 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -11,6 +11,7 @@ #include "log.h" #include "msg_queue.h" #include "gpio.h" +#include "fbinit.h" #include "time_func.h" #define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */ @@ -130,10 +131,12 @@ static BOOL poll_touchscreen(void) break; case EV_ABS: + /* Note that the touchscreen driver assumes the screen is "vertical," so swap the x and y axes */ + /* Also it thinks origin is lower left with up = +y */ if (buffer[i].code == ABS_X) - touch_x = buffer[i].value; + touch_y = Fb_Info->height - buffer[i].value; else if (buffer[i].code == ABS_Y) - touch_y = buffer[i].value; + touch_x = buffer[i].value; break; case EV_KEY: From 0dce80f1e3113bbb6809c1a3cb1b5caf01b0e69d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:33:18 -0700 Subject: [PATCH 128/162] lengthen the click time --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 7f5dfe7..02f8c3e 100644 --- a/src/config.c +++ b/src/config.c @@ -70,7 +70,7 @@ static void init_defaults(void) Gconfig.python_loc = "/usr/bin/python3"; Gconfig.button_debounce = 100; Gconfig.sys_mq_length = 64; - Gconfig.click_time = 200; + Gconfig.click_time = 500; Gconfig.click_radius = 2; } From fee3619ee18be030e64be0bc715f9974e5bb38e0 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:46:26 -0700 Subject: [PATCH 129/162] first try at rubberband feedback --- scripts/demo1.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index fbdf056..2e7ae70 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -23,8 +23,45 @@ def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + +# --- Graphic feedback -- + +origin_x = 0 +origin_y = 0 +current_x = 0 +current_y = 0 + +def rubberband_rectangle(x, y, down, up) + hdc.text_color = YELLOW + hdc.rop2 = upiwin.R2_XORPEN + if not down: + hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) + current_x = x; + current_y = y; + if not up: + hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) + + + + + + # --- Message handlers --- +def on_touchdown(x, y): + if point_in_rect(drawing_rect, x, y): + origin_x = x; + origin_y = y; + rubberband_rectangle(x, y, True, False) + +def on_touchmove(x, y): + if point_in_rect(drawing_rect, x, y): + rubberband_rectangle(x, y, False, False) + +def on_touchup(x, y): + if point_in_rect(drawing_rect, x, y): + rubberband_rectangle(x, y, False, True) + def on_touchclick(x, y): print("Click at {0},{1}".format(x, y)) if point_in_rect(cmd1_rect, x, y): @@ -52,6 +89,12 @@ hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) # Main message loop msg = {} while upiwin.get_message(msg): + if msg['message'] == upiwin.WM_TOUCHDOWN: + on_touchdown(msg['attrs'][0], msg['attrs'][1]) + if msg['message'] == upiwin.WM_TOUCHMOVE: + on_touchmove(msg['attrs'][0], msg['attrs'][1]) + if msg['message'] == upiwin.WM_TOUCHUP: + on_touchup(msg['attrs'][0], msg['attrs'][1]) if msg['message'] == upiwin.WM_TOUCHCLICK: on_touchclick(msg['attrs'][0], msg['attrs'][1]) elif msg['message'] == upiwin.WM_HWBUTTONCLICK: From 2c0a1374d962c60f841160a0cd4d00867c3cbdec Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:50:10 -0700 Subject: [PATCH 130/162] guess I need to declare certain things as global --- scripts/demo1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2e7ae70..7e3a5c0 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -31,13 +31,14 @@ origin_y = 0 current_x = 0 current_y = 0 -def rubberband_rectangle(x, y, down, up) +def rubberband_rectangle(x, y, down, up): + global current_x, current_y hdc.text_color = YELLOW hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) - current_x = x; - current_y = y; + current_x = x + current_y = y if not up: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) @@ -49,9 +50,10 @@ def rubberband_rectangle(x, y, down, up) # --- Message handlers --- def on_touchdown(x, y): + global origin_x, origin_y if point_in_rect(drawing_rect, x, y): - origin_x = x; - origin_y = y; + origin_x = x + origin_y = y rubberband_rectangle(x, y, True, False) def on_touchmove(x, y): From b7e9de7d7eb0015cf9b33a9669a7309063e1f905 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 12:59:45 -0700 Subject: [PATCH 131/162] now try rubberbanding lines --- scripts/demo1.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 7e3a5c0..93a7fe7 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -42,6 +42,18 @@ def rubberband_rectangle(x, y, down, up): if not up: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) +def rubberband_line(x, y, down, up): + global current_x, current_y + hdc.text_color = YELLOW + hdc.rop2 = upiwin.R2_XORPEN + if not down: + hdc.move_to(origin_x, origin_y) + hdc_line_to(current_x, current_y) + current_x = x + current_y = y + if not up: + hdc.move_to(origin_x, origin_y) + hdc_line_to(current_x, current_y) @@ -54,15 +66,15 @@ def on_touchdown(x, y): if point_in_rect(drawing_rect, x, y): origin_x = x origin_y = y - rubberband_rectangle(x, y, True, False) + rubberband_line(x, y, True, False) def on_touchmove(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_rectangle(x, y, False, False) + rubberband_line(x, y, False, False) def on_touchup(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_rectangle(x, y, False, True) + rubberband_line(x, y, False, True) def on_touchclick(x, y): print("Click at {0},{1}".format(x, y)) From 8c820221685386261115bc24b2302c2c9cb4ef68 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:00:38 -0700 Subject: [PATCH 132/162] typos --- scripts/demo1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 93a7fe7..5a1c37e 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -48,12 +48,12 @@ def rubberband_line(x, y, down, up): hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.move_to(origin_x, origin_y) - hdc_line_to(current_x, current_y) + hdc.line_to(current_x, current_y) current_x = x current_y = y if not up: hdc.move_to(origin_x, origin_y) - hdc_line_to(current_x, current_y) + hdc.line_to(current_x, current_y) From 2526184dfebe6168275b00d0fddfc3d24140c4ae Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:04:00 -0700 Subject: [PATCH 133/162] rename mksplash to mkgfx because it's really more general than just for splash screen graphics --- buildutils/Makefile | 8 ++++---- buildutils/{mksplash.c => mkgfx.c} | 0 src/Makefile | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename buildutils/{mksplash.c => mkgfx.c} (100%) diff --git a/buildutils/Makefile b/buildutils/Makefile index 296377c..4a3e2d4 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,7 +1,7 @@ -all: mksplash +all: mkgfx -mksplash: mksplash.c - gcc -o mksplash -O -Wall -I/usr/include/libpng mksplash.c -lpng16 -lz +mkgfx: mkgfx.c + gcc -o mkgfx -O -Wall -I/usr/include/libpng mkgfx.c -lpng16 -lz clean: - rm -f *.o mksplash + rm -f *.o mkgfx diff --git a/buildutils/mksplash.c b/buildutils/mkgfx.c similarity index 100% rename from buildutils/mksplash.c rename to buildutils/mkgfx.c diff --git a/src/Makefile b/src/Makefile index e9843a7..3324d2b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,8 +23,8 @@ splash.o: splash.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o -splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mksplash - $(BUILDUTILS)/mksplash $(RESOURCES)/$(SPLASHSCREEN) splash.bin +splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/$(SPLASHSCREEN) splash.bin clean: rm -f upiwin *.o splash.bin *~ From 62204682af643bd0cf20306d0fd21e2d79b5e721 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:20:45 -0700 Subject: [PATCH 134/162] adding the four "tool" icons to bind into the executable (this works for now) --- resources/i_fillrect.png | Bin 0 -> 672 bytes resources/i_freehand.png | Bin 0 -> 813 bytes resources/i_line.png | Bin 0 -> 783 bytes resources/i_rect.png | Bin 0 -> 666 bytes src/Makefile | 19 ++++++++++++++++--- 5 files changed, 16 insertions(+), 3 deletions(-) create mode 100755 resources/i_fillrect.png create mode 100755 resources/i_freehand.png create mode 100755 resources/i_line.png create mode 100755 resources/i_rect.png diff --git a/resources/i_fillrect.png b/resources/i_fillrect.png new file mode 100755 index 0000000000000000000000000000000000000000..5225d17311bb6e82a17343091bf6d1171b78d649 GIT binary patch literal 672 zcmV;R0$=@!P)EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt767mtEr0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zib+I4R9M69*s%?OAQXh*6D{f3#d#Qw0hq*uid7uIj*`M?a+?2@P`oc(AbBjUHQ7|H zHCSmR1uKoDZ7lWP9b`t40s1Ito9yMBU+P*)A+k3j8+F9^NVEMsxn+O=0RjXF5FkK+ z05NskoEC`8A+pH?PGo=p0s8&JIDYmmPRK_iX-z3vMRoz0h#8n6iep&-0000EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3ls|!tn{yz0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbO z7fD1xR9M69m_ZVQAPhw#%?-FZAJiYr&%raPuXEe1&FpH`Nj^7uc5;IeHS!L)T< z0~8Gr1t=OK;@q|GI|3PyWjBznab-+I>My61W&mAs6i?b>8Ca%Yz^G*vUkV5jvC?VD zM@L5F`JzrP% zz6Ldh(QJh-9S>0QxC3?E0vJRXccAWM5kQ>sQfRyaVb`GPNb3P1Zrp=EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt0*1Pv5c0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN z`AI}UR9M69*uf3MAPfaiCuIW`WHb-JDx6p-hgKY#v;kv(xhgqDoSrcH*leW~a`WY! zcUKxB+FfagD72+os|T5*k}c4Wg2Lr$O6mE-%)WN0$sCmoY`O-$RSIePxIHbhNGxA9F1|!TgkklB{*wq0r4c}$fCduV$Y7*Y|cCjgMKa3)3svoj2 z%{FN2v8mHBDw@<|x+el$e%h%ve<*#UwoYj%PME<^wT N002ovPDHLkV1iP&QCt83 literal 0 HcmV?d00001 diff --git a/resources/i_rect.png b/resources/i_rect.png new file mode 100755 index 0000000000000000000000000000000000000000..08ff61c0695cf91377eb1c36444ae41c5d134711 GIT binary patch literal 666 zcmV;L0%iS)P)EX>4Tx04R}tkv&MmKpe$iQ%glF4t5Z6$WUFhAS&W0RV;#q(pG5I!Q|2}Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;i>s5Oi*kx9)Hhl#~v2g@DIN`^{2O&n2Fjq-)8 z%L?Z$&T6H`TKD8H4CS?zG}mbkBaS5`kc0>sHIz|-g($5WDJD|1AM@}JIsPQMWO9|k z$gzMbR7j2={11M2YZj&^-K05bWxZD8-pLEHP9LY~pC=`JAGy0|+FmMa>thv3l_Hp_EWT>m<8{ps& z7%fuvy2rb_JA3>0Osl^iYZP*%unD+S00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-;y3lt4IQGYc_0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbN zgh@m}R9M69*ue?FAP_{+iLnD4v@{E_6;C#lo5x^4VI+T#dhoF$!g{sVWK*@)V5N~1 ztTdA1Sn9ny$c!QbbSNmk?B$#{omxsEvK^7lbof)v+yNp31PBlyK!5-N0tD!fQ^&rE zk;v9YwrV~kGC+U;o%k@0pM8rC`Di5FDJ84O9+&VKn$e5RJOBUy07*qoM6N<$f@nDy Axc~qF literal 0 HcmV?d00001 diff --git a/src/Makefile b/src/Makefile index 3324d2b..0f77f94 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,8 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ - bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o splash.o + bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ + i_freehand.o i_line.o i_rect.o i_fillrect.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 \ -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT @@ -19,12 +20,24 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< -splash.o: splash.bin +.bin.o: objcopy -I binary -O elf32-littlearm -B arm --rename-section \ - .data=.rodata,alloc,load,readonly,data,contents splash.bin splash.o + .data=.rodata,alloc,load,readonly,data,contents $< $@ splash.bin: $(RESOURCES)/$(SPLASHSCREEN) $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/$(SPLASHSCREEN) splash.bin +i_freehand.bin: $(RESOURCES)/i_freehand.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_freehand.png i_freehand.bin + +i_line.bin: $(RESOURCES)/i_line.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_line.png i_line.bin + +i_rect.bin: $(RESOURCES)/i_rect.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_rect.png i_rect.bin + +i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin + clean: rm -f upiwin *.o splash.bin *~ From 1b4cbfae633a4750fc841eee04fe7e2abcd77449 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:22:39 -0700 Subject: [PATCH 135/162] try makefile another way --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 0f77f94..99774fa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ upiwin: $(OBJS) .c.o: gcc -c $(CFLAGS) $< -.bin.o: +%.o: %.bin objcopy -I binary -O elf32-littlearm -B arm --rename-section \ .data=.rodata,alloc,load,readonly,data,contents $< $@ From 51fda759cc5c35b47ee212715119b28e33c12912 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 13:23:53 -0700 Subject: [PATCH 136/162] take out the test for size in mkgfx.c to make it more general --- buildutils/mkgfx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/buildutils/mkgfx.c b/buildutils/mkgfx.c index 62e3edc..68e3ee2 100644 --- a/buildutils/mkgfx.c +++ b/buildutils/mkgfx.c @@ -211,14 +211,6 @@ int do_convert(const char *infilename, const char *outfilename) return -1; } - if ((image_width != 320) || (image_height != 240)) - { - readpng_cleanup(1); - fclose(fpin); - fprintf(stderr, "%s: image is %lux%lu, should be 320x240\n", infilename, image_width, image_height); - return -1; - } - if (readpng_get_bgcolor(infilename, &bg_red, &bg_green, &bg_blue)) { readpng_cleanup(1); From ed9fd9320c97124480a7043032dfb9044d7b4074 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:03:11 -0700 Subject: [PATCH 137/162] added stock bitmap handling and support for it in the demo script --- scripts/demo1.py | 10 ++++++++++ src/Makefile | 2 +- src/bitmap.h | 2 ++ src/ep_bitmap.c | 25 +++++++++++++++++++------ src/stockobj.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 7 deletions(-) create mode 100755 src/stockobj.c diff --git a/scripts/demo1.py b/scripts/demo1.py index 5a1c37e..3c3c5cd 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -6,7 +6,14 @@ WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) +# Get the stock bitmaps. +bmp_freehand = upiwin.Bitmap(stock='freehand') +bmp_line = upiwin.Bitmap(stock='line') +bmp_rect = upiwin.Bitmap(stock='rect') +bmp_fillrect = upiwin.Bitmap(stock='fillrect') + hdc = upiwin.DevCtxt(type='screen') +hdc_bits = upiwin.DevCtxt(type='memory') # divide the screen into "drawing" and "command" areas screen_rect = hdc.get_clip_rect() @@ -100,6 +107,9 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +hdc_bits.select_object(bmp_freehand) +hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + # Main message loop msg = {} while upiwin.get_message(msg): diff --git a/src/Makefile b/src/Makefile index 99774fa..b8289c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ - bitmap.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ + bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ i_freehand.o i_line.o i_rect.o i_fillrect.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/bitmap.h b/src/bitmap.h index f7500b5..4a306e2 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -16,4 +16,6 @@ typedef struct tagBITMAP { extern PBITMAP BMP_Create(INT32 width, INT32 height, const void *bits); extern void BMP_Delete(PBITMAP pbmp); +extern PBITMAP _BMP_GetStock(PCSTR name); + #endif /* __BITMAP_H_INCLUDED */ \ No newline at end of file diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index abb2406..dfeef62 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -40,19 +40,32 @@ static PyGetSetDef BitmapProperties[] = { static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = { "width", "height", NULL }; + static char *kwlist[] = { "stock", "width", "height", NULL }; + const char *stock; int width = 0, height = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "$ii", kwlist, &width, &height)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "$sii", kwlist, &stock, &width, &height)) return -1; - width = MAX(1, width); - height = MAX(1, height); - self->pbmp = BMP_Create(width, height, NULL); - if (!(self->pbmp)) + if (stock) { + self->pbmp = _BMP_GetStock(stock); + if (!(self->pbmp)) + { + PyErr_Format(PyExc_RuntimeError, "no such stock bitmap: '%s'", stock); + return -1; + } + } + else + { + width = MAX(1, width); + height = MAX(1, height); + self->pbmp = BMP_Create(width, height, NULL); + if (!(self->pbmp)) + { PyErr_SetString(PyExc_RuntimeError, "unable to create bitmap"); return -1; + } } return 0; } diff --git a/src/stockobj.c b/src/stockobj.c new file mode 100755 index 0000000..272d390 --- /dev/null +++ b/src/stockobj.c @@ -0,0 +1,46 @@ +#include +#include +#include "wintype.h" +#include "bitmap.h" + +/* references to the icon data */ +extern uint8_t _binary_i_freehand_bin_start[]; +extern uint8_t _binary_i_freehand_bin_end; +extern uint8_t _binary_i_freehand_bin_size; + +extern uint8_t _binary_i_line_bin_start[]; +extern uint8_t _binary_i_line_bin_end; +extern uint8_t _binary_i_line_bin_size; + +extern uint8_t _binary_i_rect_bin_start[]; +extern uint8_t _binary_i_rect_bin_end; +extern uint8_t _binary_i_rect_bin_size; + +extern uint8_t _binary_i_fillrect_bin_start[]; +extern uint8_t _binary_i_fillrect_bin_end; +extern uint8_t _binary_i_fillrect_bin_size; + +typedef struct tagSTOCKBITMAPDESC { + PCSTR name; + INT32 width; + INT32 height; + const void *data; +} STOCKBITMAPDESC; + +static const STOCKBITMAPDESC stock_bitmaps = { + {"freehand", 48, 48, _binary_i_freehand_bin_start }, + {"line", 48, 48, _binary_i_line_bin_start }, + {"rect", 48, 48, _binary_i_rect_bin_start }, + {"fillrect", 48, 48, _binary_i_fillrect_bin_start }, + {NULL, 0, 0, NULL } +}; + +PBITMAP _BMP_GetStock(PCSTR name) +{ + INT32 i; + + for (i = 0; stock_bitmaps[i].name; ++i) + if (strcmp(name, stock_bitmaps[i].name) == 0) + return BMP_Create(stock_bitmaps[i].width, stock_bitmaps[i].height, stock_bitmaps[i].data); + return NULL; +} From b96527139f4c6598ac8eb6cb9cdc30c532344b45 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:04:24 -0700 Subject: [PATCH 138/162] forgot brackets --- src/stockobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stockobj.c b/src/stockobj.c index 272d390..82350d8 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -27,7 +27,7 @@ typedef struct tagSTOCKBITMAPDESC { const void *data; } STOCKBITMAPDESC; -static const STOCKBITMAPDESC stock_bitmaps = { +static const STOCKBITMAPDESC stock_bitmaps[] = { {"freehand", 48, 48, _binary_i_freehand_bin_start }, {"line", 48, 48, _binary_i_line_bin_start }, {"rect", 48, 48, _binary_i_rect_bin_start }, From 79088d4893b09ae336031e8525a52a4a085d827e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:06:26 -0700 Subject: [PATCH 139/162] change spec of arguments to bitmap init --- src/ep_bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index dfeef62..5eac856 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -44,7 +44,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "$sii", kwlist, &stock, &width, &height)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) From c283d06c12a27c5313537d47bdd6594730e17548 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:08:33 -0700 Subject: [PATCH 140/162] disco debugging the demo script --- scripts/demo1.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 3c3c5cd..f8e779b 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -7,10 +7,13 @@ LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. +print('GOT HERE 1') bmp_freehand = upiwin.Bitmap(stock='freehand') +print('GOT HERE 1A') bmp_line = upiwin.Bitmap(stock='line') bmp_rect = upiwin.Bitmap(stock='rect') bmp_fillrect = upiwin.Bitmap(stock='fillrect') +print('GOT HERE 2') hdc = upiwin.DevCtxt(type='screen') hdc_bits = upiwin.DevCtxt(type='memory') @@ -107,8 +110,11 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +print('GOT HERE 3') hdc_bits.select_object(bmp_freehand) +print('GOT HERE 4') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) +print('GOT HERE 5') # Main message loop msg = {} From 0dd8d458980674d40f5504b47d0ee0889f5a3eef Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:14:17 -0700 Subject: [PATCH 141/162] now probing into the Python interface for devctx --- scripts/demo1.py | 9 +++------ src/ep_devctxt.c | 9 ++++++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index f8e779b..767f327 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -7,13 +7,10 @@ LTGRAY = upiwin.rgb(204, 204, 204) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. -print('GOT HERE 1') bmp_freehand = upiwin.Bitmap(stock='freehand') -print('GOT HERE 1A') bmp_line = upiwin.Bitmap(stock='line') bmp_rect = upiwin.Bitmap(stock='rect') bmp_fillrect = upiwin.Bitmap(stock='fillrect') -print('GOT HERE 2') hdc = upiwin.DevCtxt(type='screen') hdc_bits = upiwin.DevCtxt(type='memory') @@ -110,11 +107,11 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -print('GOT HERE 3') +print('GOT HERE 1') hdc_bits.select_object(bmp_freehand) -print('GOT HERE 4') +print('GOT HERE 2') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) -print('GOT HERE 5') +print('GOT HERE 3') # Main message loop msg = {} diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 87a407c..ab4f274 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -144,15 +144,19 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp BitmapObject *old_bitmap = NULL; PBITMAP old_pbmp; + Log(LDEBUG, "select_bitmap entry"); if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) { PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); return NULL; } + Log(LDEBUG, "verified 1"); old_bitmap = self->selected_bitmap; old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); + Log(LDEBUG, "old_bitmap present=%d, old_pbmp present=%d", !!old_bitmap, !!old_pbmp); if (!old_bitmap) { + Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); if (!old_bitmap) { @@ -162,6 +166,7 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp else Py_INCREF(old_bitmap); } + Log(LDEBUG, "replacement sequence"); Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); @@ -171,7 +176,8 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - + + Log(LDEBUG, "select_object entry"); if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; if (!obj) @@ -179,6 +185,7 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "bad object selected"); return NULL; } + Log(LDEBUG, "ready to comb objects"); if (PyObject_TypeCheck(obj, &BitmapType)) return devctxt_select_bitmap(self, (BitmapObject *)obj); PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); From a8a5206b892fd6265d0a12d08580d71551bf427e Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:16:25 -0700 Subject: [PATCH 142/162] is the problem in Epython_wrap_bitmap? --- src/ep_devctxt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index ab4f274..74e99e0 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -158,8 +158,10 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp { Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); + Log(LDEBUG, "wrapper finished"); if (!old_bitmap) { + Log(LDEBUG, "wrapper failed"); DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } From b90c2efe2f33f5714393bfd0ae85ad879a902316 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:19:51 -0700 Subject: [PATCH 143/162] dig into the bitmap creation --- src/ep_bitmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 5eac856..203e784 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -2,6 +2,7 @@ #define PY_SSIZE_T_CLEAN #include #include "scode.h" +#include "log.h" #include "gfxobj.h" #include "bitmap.h" #include "ep_types.h" @@ -44,11 +45,13 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; + Log(LDEBUG, "Bitmap init entry"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) { + Log(LDEBUG, "stock bitmap"); self->pbmp = _BMP_GetStock(stock); if (!(self->pbmp)) { @@ -58,6 +61,7 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) } else { + Log(LDEBUG, "basic bitmap"); width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); @@ -115,11 +119,15 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) kwargs = PyDict_New(); if (kwargs) { + Log(LDEBUG, "gonna create it"); rc = PyType_GenericNew(&BitmapType, args, kwargs); + Log(LDEBUG, "created it"); if (rc) { pbitmapobj = (BitmapObject *)rc; + Log(LDEBUG, "gonna delete bitmap"); BMP_Delete(pbitmapobj->pbmp); + Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } Py_DECREF(kwargs); From 9318d27b2b80cb7e4570cc798bc61e05103eeb08 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:21:27 -0700 Subject: [PATCH 144/162] null check before deleting bitmap? --- src/ep_bitmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 203e784..160ada9 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -126,7 +126,8 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) { pbitmapobj = (BitmapObject *)rc; Log(LDEBUG, "gonna delete bitmap"); - BMP_Delete(pbitmapobj->pbmp); + if (pbitmapobj->pbmp) + BMP_Delete(pbitmapobj->pbmp); Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } From b5fd4c287904c87c01bd277786923e57281b5d5f Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:23:23 -0700 Subject: [PATCH 145/162] OK, another null problem needs fixing --- src/ep_devctxt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 74e99e0..b906ab5 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -166,7 +166,10 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp return NULL; } else + { Py_INCREF(old_bitmap); + self->selected_bitmap = old_bitmap; + } } Log(LDEBUG, "replacement sequence"); Py_DECREF(self->selected_bitmap); From 372f48eab7237447f1c8e50fce8cd338f4e6368a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:25:05 -0700 Subject: [PATCH 146/162] assert that everything is present --- src/ep_devctxt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index b906ab5..33d6913 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -172,6 +172,9 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp } } Log(LDEBUG, "replacement sequence"); + ASSERT(old_bitmap); + ASSERT(self->selected_bitmap); + ASSERT(newbmp); Py_DECREF(self->selected_bitmap); self->selected_bitmap = newbmp; Py_INCREF(self->selected_bitmap); From 6a4938e4ee7070c8603c073fd003204228e93a21 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:27:14 -0700 Subject: [PATCH 147/162] finished disco debugging --- scripts/demo1.py | 3 --- src/ep_bitmap.c | 7 ------- src/ep_devctxt.c | 9 --------- 3 files changed, 19 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 767f327..3c3c5cd 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -107,11 +107,8 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -print('GOT HERE 1') hdc_bits.select_object(bmp_freehand) -print('GOT HERE 2') hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) -print('GOT HERE 3') # Main message loop msg = {} diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index 160ada9..fbc6da6 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -45,13 +45,11 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) const char *stock; int width = 0, height = 0; - Log(LDEBUG, "Bitmap init entry"); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$sii", kwlist, &stock, &width, &height)) return -1; if (stock) { - Log(LDEBUG, "stock bitmap"); self->pbmp = _BMP_GetStock(stock); if (!(self->pbmp)) { @@ -61,7 +59,6 @@ static int bitmap_init(BitmapObject *self, PyObject *args, PyObject *kwds) } else { - Log(LDEBUG, "basic bitmap"); width = MAX(1, width); height = MAX(1, height); self->pbmp = BMP_Create(width, height, NULL); @@ -119,16 +116,12 @@ PyObject *Epython_wrap_bitmap(PBITMAP pbmp) kwargs = PyDict_New(); if (kwargs) { - Log(LDEBUG, "gonna create it"); rc = PyType_GenericNew(&BitmapType, args, kwargs); - Log(LDEBUG, "created it"); if (rc) { pbitmapobj = (BitmapObject *)rc; - Log(LDEBUG, "gonna delete bitmap"); if (pbitmapobj->pbmp) BMP_Delete(pbitmapobj->pbmp); - Log(LDEBUG, "deleted bitmap"); pbitmapobj->pbmp = pbmp; } Py_DECREF(kwargs); diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 33d6913..070a2b6 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -144,24 +144,18 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp BitmapObject *old_bitmap = NULL; PBITMAP old_pbmp; - Log(LDEBUG, "select_bitmap entry"); if ((self->pdctxt->flags & DCFLG_TYPES) != DCFLG_IS_MEMORY) { PyErr_SetString(PyExc_RuntimeError, "must select bitmap into memory device context"); return NULL; } - Log(LDEBUG, "verified 1"); old_bitmap = self->selected_bitmap; old_pbmp = (PBITMAP)DC_SelectObject(self->pdctxt, (PGFXOBJECT)(newbmp->pbmp)); - Log(LDEBUG, "old_bitmap present=%d, old_pbmp present=%d", !!old_bitmap, !!old_pbmp); if (!old_bitmap) { - Log(LDEBUG, "need to wrap old bitmap"); old_bitmap = (BitmapObject *)Epython_wrap_bitmap(old_pbmp); - Log(LDEBUG, "wrapper finished"); if (!old_bitmap) { - Log(LDEBUG, "wrapper failed"); DC_SelectObject(self->pdctxt, (PGFXOBJECT)old_pbmp); return NULL; } @@ -171,7 +165,6 @@ static PyObject *devctxt_select_bitmap(DevCtxtObject *self, BitmapObject *newbmp self->selected_bitmap = old_bitmap; } } - Log(LDEBUG, "replacement sequence"); ASSERT(old_bitmap); ASSERT(self->selected_bitmap); ASSERT(newbmp); @@ -185,7 +178,6 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) { PyObject *obj; - Log(LDEBUG, "select_object entry"); if (!PyArg_ParseTuple(args, "O", &obj)) return NULL; if (!obj) @@ -193,7 +185,6 @@ static PyObject *devctxt_select_object(DevCtxtObject *self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "bad object selected"); return NULL; } - Log(LDEBUG, "ready to comb objects"); if (PyObject_TypeCheck(obj, &BitmapType)) return devctxt_select_bitmap(self, (BitmapObject *)obj); PyErr_SetString(PyExc_RuntimeError, "unknown type of object selected"); From 90da46505edf456f7972306648f14c1933fd8b4d Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:44:35 -0700 Subject: [PATCH 148/162] the basic tool and color selection code --- scripts/demo1.py | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 3c3c5cd..9099847 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -4,6 +4,11 @@ import upiwin # Save off some color values. WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) +RED = upiwin.rgb(255, 0, 0) +GREEN = upiwin.rgb(0, 255, 0) +BLUE = upiwin.rgb(0, 0, 255) +CYAN = upiwin.rgb(0, 255, 255) +MAGENTA = upiwin.rgb(255, 0, 255) YELLOW = upiwin.rgb(255, 255, 0) # Get the stock bitmaps. @@ -29,6 +34,21 @@ cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) +# --- Color selections --- + +color_list = [WHITE, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW] +current_color = 0 + +def draw_current_color(): + hdc.text_color = color_list[current_color] + hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) + +def select_next_color(): + current_color += 1 + if current_color == len(color_list): + current_color = 0 + draw_current_color() + # --- Graphic feedback -- @@ -63,8 +83,26 @@ def rubberband_line(x, y, down, up): hdc.line_to(current_x, current_y) +# --- Tool definitions --- +tool_list = [ + { 'icon': bmp_freehand }, + { 'icon': bmp_line }, + { 'icon': bmp_rect }, + { 'icon': bmp_fillrect } + ] +current_tool = 0 + +def draw_current_tool(): + hdc_bits.select_object(tool_list[current_tool]['icon']) + hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + +def select_next_tool(): + current_tool += 1 + if current_tool == len(tool_list): + current_tool = 0 + draw_current_tool() # --- Message handlers --- @@ -84,11 +122,10 @@ def on_touchup(x, y): rubberband_line(x, y, False, True) def on_touchclick(x, y): - print("Click at {0},{1}".format(x, y)) if point_in_rect(cmd1_rect, x, y): - print("Click command 1") + select_next_tool() elif point_in_rect(cmd2_rect, x, y): - print("Click command 2") + select_next_color() elif point_in_rect(cmd3_rect, x, y): print("Click command 3") elif point_in_rect(cmd4_rect, x, y): @@ -107,8 +144,8 @@ hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) -hdc_bits.select_object(bmp_freehand) -hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) +draw_current_tool() +draw_current_color() # Main message loop msg = {} From 35a12760d7e7e71f7534ce00b596cd6044ae44f2 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:45:59 -0700 Subject: [PATCH 149/162] global variable definitions again --- scripts/demo1.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 9099847..2f4037d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -44,6 +44,7 @@ def draw_current_color(): hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) def select_next_color(): + global current_color current_color += 1 if current_color == len(color_list): current_color = 0 @@ -99,6 +100,7 @@ def draw_current_tool(): hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) def select_next_tool(): + global current_tool current_tool += 1 if current_tool == len(tool_list): current_tool = 0 From b620f55420a72b09e1d4e13b6205bbb63f03a374 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:52:32 -0700 Subject: [PATCH 150/162] adding feedback for each of the tools --- scripts/demo1.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2f4037d..ab1d7a8 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -50,8 +50,6 @@ def select_next_color(): current_color = 0 draw_current_color() - - # --- Graphic feedback -- origin_x = 0 @@ -59,9 +57,17 @@ origin_y = 0 current_x = 0 current_y = 0 +def freehand_draw(x, y, down, up): + global current_x, current_y + hdc.text_color = color_list[current_color] + hdc.move_to(current_x, current_y) + hdc.line_to(x, y) + current_x = x + current_y = y + def rubberband_rectangle(x, y, down, up): global current_x, current_y - hdc.text_color = YELLOW + hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) @@ -72,7 +78,7 @@ def rubberband_rectangle(x, y, down, up): def rubberband_line(x, y, down, up): global current_x, current_y - hdc.text_color = YELLOW + hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_XORPEN if not down: hdc.move_to(origin_x, origin_y) @@ -83,14 +89,13 @@ def rubberband_line(x, y, down, up): hdc.move_to(origin_x, origin_y) hdc.line_to(current_x, current_y) - # --- Tool definitions --- tool_list = [ - { 'icon': bmp_freehand }, - { 'icon': bmp_line }, - { 'icon': bmp_rect }, - { 'icon': bmp_fillrect } + { 'icon': bmp_freehand, 'feedback': freehand_draw }, + { 'icon': bmp_line, 'feedback': rubberband_line }, + { 'icon': bmp_rect, 'feedback': rubberband_rect }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rect } ] current_tool = 0 @@ -113,15 +118,15 @@ def on_touchdown(x, y): if point_in_rect(drawing_rect, x, y): origin_x = x origin_y = y - rubberband_line(x, y, True, False) + tool_list[current_tool]['feedback'](x, y, True, False) def on_touchmove(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_line(x, y, False, False) + tool_list[current_tool]['feedback'](x, y, False, False) def on_touchup(x, y): if point_in_rect(drawing_rect, x, y): - rubberband_line(x, y, False, True) + tool_list[current_tool]['feedback'](x, y, False, True) def on_touchclick(x, y): if point_in_rect(cmd1_rect, x, y): From e7f191a9e02e2aafd4fe5733318402fcaf6c021a Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:53:47 -0700 Subject: [PATCH 151/162] wrong procedure name stored in tool list --- scripts/demo1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index ab1d7a8..69eb17a 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -94,8 +94,8 @@ def rubberband_line(x, y, down, up): tool_list = [ { 'icon': bmp_freehand, 'feedback': freehand_draw }, { 'icon': bmp_line, 'feedback': rubberband_line }, - { 'icon': bmp_rect, 'feedback': rubberband_rect }, - { 'icon': bmp_fillrect, 'feedback': rubberband_rect } + { 'icon': bmp_rect, 'feedback': rubberband_rectangle }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle } ] current_tool = 0 From 85e89eae4cdeb3dd89549b12a6034cf68ae52f1b Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 14:55:34 -0700 Subject: [PATCH 152/162] revised the feedback for freehand --- scripts/demo1.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 69eb17a..31b781d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -59,11 +59,15 @@ current_y = 0 def freehand_draw(x, y, down, up): global current_x, current_y - hdc.text_color = color_list[current_color] - hdc.move_to(current_x, current_y) - hdc.line_to(x, y) - current_x = x - current_y = y + if down: + current_x = origin_x + current_y = origin_y + else: + hdc.text_color = color_list[current_color] + hdc.move_to(current_x, current_y) + hdc.line_to(x, y) + current_x = x + current_y = y def rubberband_rectangle(x, y, down, up): global current_x, current_y From 2a5a6dbe4e1268c042a415037ef65b1bb3085522 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:18:33 -0700 Subject: [PATCH 153/162] now we're actually saving the objects and drawing them properly --- scripts/demo1.py | 73 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 31b781d..955c17d 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -41,6 +41,7 @@ current_color = 0 def draw_current_color(): hdc.text_color = color_list[current_color] + hdc.rop2 = upiwin.R2_COPYPEN hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) def select_next_color(): @@ -50,24 +51,58 @@ def select_next_color(): current_color = 0 draw_current_color() +# --- Object drawing --- + +def draw_freehand(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.move_to(data[0][0], data[0][1]) + for pt in data[1:len(data) - 1]: + hdc.line_to(pt[0], pt[1]) + +def draw_line(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.move_to(data[0][0], data[0][1]) + hdc.line_to(data[1][0], data[1][1]) + +def draw_rectangle(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.rectangle(data[0], data[1], data[2], data[3]) + +def draw_filled_rectangle(color, data): + hdc.text_color = color + hdc.rop2 = upiwin.R2_COPYPEN + hdc.solid_rectangle(data[0], data[1], data[2], data[3]) + +def draw_object(obj): + obj['draw'](obj['color'], obj['data']) + +# --- Master object list --- + +objects_drawn = [] + # --- Graphic feedback -- origin_x = 0 origin_y = 0 current_x = 0 current_y = 0 +freehand_points = [] def freehand_draw(x, y, down, up): - global current_x, current_y + global current_x, current_y, freehand_points if down: - current_x = origin_x - current_y = origin_y + freehand_points = [] else: hdc.text_color = color_list[current_color] + hdc.rop2 = upiwin.R2_COPYPEN hdc.move_to(current_x, current_y) hdc.line_to(x, y) - current_x = x - current_y = y + current_x = x + current_y = y + freehand_points += [(x, y)] def rubberband_rectangle(x, y, down, up): global current_x, current_y @@ -95,11 +130,25 @@ def rubberband_line(x, y, down, up): # --- Tool definitions --- +def save_freehand(): + return { 'draw': draw_freehand, 'color': color_list[current_color], 'data': freehand_points } + +def save_line(): + return { 'draw': draw_line, 'color': color_list[current_color], 'data': [(origin_x, origin_y), (current_x, current_y)] } + +def save_rectangle(): + return { 'draw': draw_rectangle, 'color': color_list[current_color], + 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) } + +def save_filled_rectangle(): + return { 'draw': draw_filled_rectangle, 'color': color_list[current_color], + 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) } + tool_list = [ - { 'icon': bmp_freehand, 'feedback': freehand_draw }, - { 'icon': bmp_line, 'feedback': rubberband_line }, - { 'icon': bmp_rect, 'feedback': rubberband_rectangle }, - { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle } + { 'icon': bmp_freehand, 'feedback': freehand_draw, 'save': save_freehand, 'dodraw': False }, + { 'icon': bmp_line, 'feedback': rubberband_line, 'save': save_line, 'dodraw': True }, + { 'icon': bmp_rect, 'feedback': rubberband_rectangle, 'save': save_rectangle, 'dodraw': True }, + { 'icon': bmp_fillrect, 'feedback': rubberband_rectangle, 'save': save_filled_rectangle, 'dodraw': True } ] current_tool = 0 @@ -129,8 +178,13 @@ def on_touchmove(x, y): tool_list[current_tool]['feedback'](x, y, False, False) def on_touchup(x, y): + global objects_drawn if point_in_rect(drawing_rect, x, y): tool_list[current_tool]['feedback'](x, y, False, True) + object = tool_list[current_tool]['save']() + if tool_list[current_tool]['dodraw']: + draw_object(object) + objects_drawn += [object] def on_touchclick(x, y): if point_in_rect(cmd1_rect, x, y): @@ -150,6 +204,7 @@ def on_button_click(button): # Draw the basic layout. hdc.text_color = LTGRAY +hdc.rop2 = upiwin.R2_COPYPEN hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) From 59ee61200c9bce3b2e977303e034fc4fb6194282 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:27:29 -0700 Subject: [PATCH 154/162] added the backlight control and some code for doing repaints --- scripts/demo1.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/scripts/demo1.py b/scripts/demo1.py index 955c17d..2f71408 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -2,6 +2,7 @@ import upiwin # Save off some color values. +BLACK = upiwin.rgb(0, 0, 0) WHITE = upiwin.rgb(255, 255, 255) LTGRAY = upiwin.rgb(204, 204, 204) RED = upiwin.rgb(255, 0, 0) @@ -33,6 +34,21 @@ cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) def point_in_rect(rect, x, y): return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) + +# --- Backlight control --- + +backlight_level_list = [1023, 768, 512, 256] +current_backlight = 0 + +def do_backlight(): + upiwin.set_backlight_level(backlight_level_list[current_backlight]) + +def select_next_backlight(): + global current_backlight + current_backlight += 1 + if (current_backlight == len(backlight_level_list): + current_backlight = 0 + do_backlight() # --- Color selections --- @@ -83,6 +99,14 @@ def draw_object(obj): objects_drawn = [] +def repaint(): + global drawing_rect, objects_drawn + hdc.text_color = BLACK + hdc.rop2 = upiwin.R2_COPYPEN + hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3]) + for obj in objects_drawn: + draw_object(obj) + # --- Graphic feedback -- origin_x = 0 @@ -197,11 +221,15 @@ def on_touchclick(x, y): print("Click command 4") def on_button_click(button): + if button == 1: # Button 1 = Set backlight level + select_next_backlight() if button == 4: # Button 4 = Exit app upiwin.post_quit_message(0) # --- Initialize and start message loop --- +do_backlight() + # Draw the basic layout. hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN From 416438f6c8d9ba6eaea67ae9ea5eeb575c8f721c Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:28:45 -0700 Subject: [PATCH 155/162] typo --- scripts/demo1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index 2f71408..b6350d8 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -46,7 +46,7 @@ def do_backlight(): def select_next_backlight(): global current_backlight current_backlight += 1 - if (current_backlight == len(backlight_level_list): + if current_backlight == len(backlight_level_list): current_backlight = 0 do_backlight() From 4d5b53fcdca200c93e95b5fbaba3bec08fa5dd57 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:34:12 -0700 Subject: [PATCH 156/162] cleanup of the script elements --- scripts/demo1.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/demo1.py b/scripts/demo1.py index b6350d8..2015ec0 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -27,8 +27,8 @@ drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3]) # further divide up the "command" area -cmd1_rect = (command_rect[0], command_rect[1], command_rect[2], 60) -cmd2_rect = (command_rect[0], 60, command_rect[2], 120) +tool_select_rect = (command_rect[0], command_rect[1], command_rect[2], 60) +color_select_rect = (command_rect[0], 60, command_rect[2], 120) cmd3_rect = (command_rect[0], 120, command_rect[2], 180) cmd4_rect = (command_rect[0], 180, command_rect[2], command_rect[3]) @@ -58,7 +58,7 @@ current_color = 0 def draw_current_color(): hdc.text_color = color_list[current_color] hdc.rop2 = upiwin.R2_COPYPEN - hdc.solid_rectangle(cmd2_rect[0] + 6, cmd2_rect[1] + 6, cmd2_rect[0] + 54, cmd2_rect[1] + 54) + hdc.solid_rectangle(color_select_rect[0] + 6, color_select_rect[1] + 6, color_select_rect[0] + 54, color_select_rect[1] + 54) def select_next_color(): global current_color @@ -73,7 +73,7 @@ def draw_freehand(color, data): hdc.text_color = color hdc.rop2 = upiwin.R2_COPYPEN hdc.move_to(data[0][0], data[0][1]) - for pt in data[1:len(data) - 1]: + for pt in data[1:]: hdc.line_to(pt[0], pt[1]) def draw_line(color, data): @@ -179,7 +179,7 @@ current_tool = 0 def draw_current_tool(): hdc_bits.select_object(tool_list[current_tool]['icon']) - hdc.bitblt(cmd1_rect[0] + 6, cmd1_rect[1] + 6, cmd1_rect[0] + 54, cmd1_rect[1] + 54, hdc_bits, 0, 0, 0) + hdc.bitblt(tool_select_rect[0] + 6, tool_select_rect[1] + 6, tool_select_rect[0] + 54, tool_select_rect[1] + 54, hdc_bits, 0, 0, 0) def select_next_tool(): global current_tool @@ -211,9 +211,9 @@ def on_touchup(x, y): objects_drawn += [object] def on_touchclick(x, y): - if point_in_rect(cmd1_rect, x, y): + if point_in_rect(tool_select_rect, x, y): select_next_tool() - elif point_in_rect(cmd2_rect, x, y): + elif point_in_rect(color_select_rect, x, y): select_next_color() elif point_in_rect(cmd3_rect, x, y): print("Click command 3") @@ -233,8 +233,8 @@ do_backlight() # Draw the basic layout. hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN -hdc.rectangle(cmd1_rect[0], cmd1_rect[1], cmd1_rect[2], cmd1_rect[3]) -hdc.rectangle(cmd2_rect[0], cmd2_rect[1], cmd2_rect[2], cmd2_rect[3]) +hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3]) +hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3]) hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) From cb9ecc89ca3edf6db99ed17c407867ca55dfebca Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:52:49 -0700 Subject: [PATCH 157/162] add the undo and clear commands with their icons --- resources/i_clear.png | Bin 0 -> 3927 bytes resources/i_undo.png | Bin 0 -> 3348 bytes scripts/demo1.py | 36 ++++++++++++++++++++++++++++-------- src/Makefile | 8 +++++++- src/stockobj.c | 10 ++++++++++ 5 files changed, 45 insertions(+), 9 deletions(-) create mode 100755 resources/i_clear.png create mode 100755 resources/i_undo.png diff --git a/resources/i_clear.png b/resources/i_clear.png new file mode 100755 index 0000000000000000000000000000000000000000..3d5a4a2be03ad5fc48f071a273aae2c8d177fd10 GIT binary patch literal 3927 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 literal 0 HcmV?d00001 diff --git a/resources/i_undo.png b/resources/i_undo.png new file mode 100755 index 0000000000000000000000000000000000000000..62b023366ead39554dc0d96223c646d0b9c39adc GIT binary patch literal 3348 zcmV+v4eRoWP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3#rb|fJVg#UAjIRg7~9M<>d26O!RM3S|1+wRR( zb|pn60u)jxNHzcW-=+S;%O&TP4=KkIqvqv{FSgRi`g+y5C8Z?&w+PG_9n zpY~d%V+*dhDn0uXSMeEWd*1RHuhl9bV+pj&@vYTgzCK&MdR_j3{SDSf%Y4#*&{j7J z(VidN4=BaQ^}~J>ZbLu7y0LqiIp)XAZ~Zns0KA-i!zcf1jl9;pc2|95%kgaL-pX!q zUlVWbQIU7jQ4xfhhP(^!Oj>keY3QyS?{12*K)H-J!&I}(+}Cb8OZ0Zy#MRoatlOO# zFpBLPZUNStWfQ;;mjS*L5{_Q`Sc}=ymOWiJSr4U$;Z|!fCb9C@Z}q!3uALLc==|^% z>#`DctU?>$mkYOnh*`&}VLSMK|M(JI9SDZ)=FA4GZt618f_Vm)+dw;R3|y}yHfbCK zxQM9(iy>jW(UFWXkrgFtlQB3l15jn@)_L1Nz=U82i?rUk2sq?0b2BEHeX9-j>V^zq zND?qYm03~~u)Gh%Px6@~qL5 zr<`-iwbbaL*haGN^ z$0Lq3@+hNDGYO^XXP9xOnP-`G5o*gVzrurUz>D zrgWPyLMK5m12O9jfG1D`F#=mK)7f}$1v$Y?7fV(I%OZn-GmIbxf_@qsmU&=zkW+Z^ zTX0h;Z`|y^BBunp-$d?b+&)5WNO|rXu`3P5soIf!%a3X^e^kxSuj*Gf{ON2NKH6)YjKFx{{|k2yx9Xu)ByUqIHzXrLEKN7q)JF?H`SFr4cy)a+9XDm5KOhgZ9|usO4! zKz%V||4qy$DwI^%o(oBwbq+qG zSiGb>4CWB~q&xX*&T1G2Awsi#x^~BPi2*i58OMRvlm&HZZRRD zXcc(Rw>1^in4|-}n-Jk}s%#|T5Q3 zCEu+Pc0(NQ>y6cPzAr7&qs%B_c9RkT#Bar$j8}7~7;`!>%vob&#%0>d&8=l!2vv44 zQn5HA$HlgX`qIUIAVV;ZH#6kCie0f+R|I|=C|Hzx#5F?FsgdcP(FAJ7NX@2h<8~n> ze*#IP{>gXLgzRd`{#r(N_r%76lZ~~2JfcG z8u!|$?bIpMOuJwRR1wNLw|33ZX_PDxtVxUb^!Z$zCOKH7M=%e`0XI%8qdT;>YVKgJ zq(R-mJcN0cxJEC+f$0MZN2d4GGR_l7AeQa+ktmyy4N3sdC}Ih3SEK?CNt58Z!ZB~p zbeJM-k4v@|AqsCj!9`If0}G09yWCY(Oh$E0!D2y%0414lqPLcIM{koE=bG*cUgLk5 zUk!mf%a2Q@Z}!T~ZRyx~v%-BpTfvBW-^OhRwP1~G=i)tBOmd~ni}yru8W0n7MORcv zQgNJ3#Ojhq8##41Vv#hHp_ZXmU`GTJL{JTJ06(EiQx;s3{1Fv0NWBm(qhLy)CA0{N ze20^M@T};+lX=BmyqVp_o2sC2ggE_0oY1I-0&*NXW)MHA#X!oz@5oBgmj&_6+1`l$ zF%osF5ZtPUJ@StBvS9mXu-md1XL9L`eJuiG&O-(lDX6u%0f`8D6{W9+%juLub znL`cXeF${6JmH5eHp1Ac!Zth;K;B zxY4uZu7hO5u7-zIC}{D?D#}s}Ic`%?U_Mgl;X-$cpkJ5QDS}c1tA_&E`L2OcxX4Hi zT*^qjnz8;-s(+B_iW(xd^by3d#@8Soh;{UPx{9}7DQw(Oyz3P+4B7nN@x(AmNi~xp z#?IXIkgzBO_Oqb&o5-?J7n_izJGnLm33X=pU_~fsQ-$HoqnkOZplb%cWfg#l>MDodtAjz9~ zse|R9%t_|29Ga^Ong%5HzS7*4hWV>|s6w@lC}bsD z7Rr;zDH!d7ux;qg=vV#*#hG?XOf1=OJAP?rIL_rL<+HDUT{` zby6{Ixnv*GMQV#s7??p|du}L9v`_i!5TPE2hIQ40TdSRNpl^||%fZ%aQV!1KJ&L^B z38^lqgcmWF z&5p{c>hH?Ny9MppzH!X8#U`z=IAu$tGDbA;7Hk38CvpvEi(F$Ho{=-;N5Z=_T7G{GY;8 z;JRvT-Nhg6v~KyM?h{43P6N|k2MWl`CE<~+Dz+f;FZuu;*;K1f1%@GoefB|f{96rB zpK$-|ryXH_O?$~mBtm^<{mz3jksKN)Ix!@LW>IH-g zg1&c}${#)fP~Y@u682XDR0P33_jl3E9n@1v#tNNx#BVy>)AwK@? z^F!6XNpW!$Tni3F%=a_C-#2dsjo0iUbpE$&dl0tk= zJZ{hhi66NxyZpwv;IP0mLq<9|PaGl^3vDd7F)JD>@icK*Q8mgJGA=8ew>YciDr?@8 zzc857R#IH2IgA*V5Jv(cWK>Z?85Sb6YNVJ*(tgy#KjiomeSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{007`gL_t(o!|j;M z5yT(}h6%BQG?>yXz*anYvYWkSoQyA6vted`ZZX1qfDp+RVJZ(R9K-!mEPjYat>{|%rDs*6 z9oKLBMWJGai{AUb_3GQnP_Z=Bla5xQXPEfW+Ey@e$HbCOGt95D%2xHgp={S|Uk-|` z*p%y1#J+CMSv6pR0000= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3]) @@ -106,6 +108,19 @@ def repaint(): hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3]) for obj in objects_drawn: draw_object(obj) + +def undo_last(): + global objects_drawn + if len(objects_drawn) > 0: + last = len(objects_drawn) - 1 + del objects_drawn[last] + repaint() + +def clear_all(): + global objects_drawn + if len(objects_drawn) > 0: + objects_drawn.clear() + repaint() # --- Graphic feedback -- @@ -215,10 +230,10 @@ def on_touchclick(x, y): select_next_tool() elif point_in_rect(color_select_rect, x, y): select_next_color() - elif point_in_rect(cmd3_rect, x, y): - print("Click command 3") - elif point_in_rect(cmd4_rect, x, y): - print("Click command 4") + elif point_in_rect(undo_rect, x, y): + undo_last() + elif point_in_rect(clear_rect, x, y): + clear_all() def on_button_click(button): if button == 1: # Button 1 = Set backlight level @@ -235,12 +250,17 @@ hdc.text_color = LTGRAY hdc.rop2 = upiwin.R2_COPYPEN hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3]) hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3]) -hdc.rectangle(cmd3_rect[0], cmd3_rect[1], cmd3_rect[2], cmd3_rect[3]) -hdc.rectangle(cmd4_rect[0], cmd4_rect[1], cmd4_rect[2], cmd4_rect[3]) +hdc.rectangle(undo_rect[0], undo_rect[1], undo_rect[2], undo_rect[3]) +hdc.rectangle(clear_rect[0], clear_rect[1], clear_rect[2], clear_rect[3]) draw_current_tool() draw_current_color() +hdc_bits.select_object(bmp_undo) +hdc.bitblt(undo_rect[0] + 6, undo_rect[1] + 6, undo_rect[0] + 54, undo_rect[1] + 54, hdc_bits, 0, 0, 0) +hdc_bits.select_object(bmp_clear) +hdc.bitblt(clear_rect[0] + 6, clear_rect[1] + 6, clear_rect[0] + 54, clear_rect[1] + 54, hdc_bits, 0, 0, 0) + # Main message loop msg = {} while upiwin.get_message(msg): diff --git a/src/Makefile b/src/Makefile index b8289c8..aff9c9b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ SPLASHSCREEN=splash-vmwcblk.png OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_msg.o ep_graphics.o ep_devctxt.o ep_bitmap.o \ ep_upiwin_tmp.o ep_util.o fbinit.o rect.o gfxobj.o devctxt.o dc_screen.o fontengine.o \ bitmap.o stockobj.o fbprimitive.o log.o gpio.o msg_queue.o time_func.o config.o \ - i_freehand.o i_line.o i_rect.o i_fillrect.o splash.o + i_freehand.o i_line.o i_rect.o i_fillrect.o i_undo.o i_clear.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 \ -Wall -Werror -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT @@ -39,5 +39,11 @@ i_rect.bin: $(RESOURCES)/i_rect.png $(BUILDUTILS)/mkgfx i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin +i_undo.bin: $(RESOURCES)/i_undo.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png undo.bin + +i_clear.bin: $(RESOURCES)/i_clear.png $(BUILDUTILS)/mkgfx + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_clear.png i_clear.bin + clean: rm -f upiwin *.o splash.bin *~ diff --git a/src/stockobj.c b/src/stockobj.c index 82350d8..394195a 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -20,6 +20,14 @@ extern uint8_t _binary_i_fillrect_bin_start[]; extern uint8_t _binary_i_fillrect_bin_end; extern uint8_t _binary_i_fillrect_bin_size; +extern uint8_t _binary_i_undo_bin_start[]; +extern uint8_t _binary_i_undo_bin_end; +extern uint8_t _binary_i_undo_bin_size; + +extern uint8_t _binary_i_clear_bin_start[]; +extern uint8_t _binary_i_clear_bin_end; +extern uint8_t _binary_i_clear_bin_size; + typedef struct tagSTOCKBITMAPDESC { PCSTR name; INT32 width; @@ -32,6 +40,8 @@ static const STOCKBITMAPDESC stock_bitmaps[] = { {"line", 48, 48, _binary_i_line_bin_start }, {"rect", 48, 48, _binary_i_rect_bin_start }, {"fillrect", 48, 48, _binary_i_fillrect_bin_start }, + {"undo", 48, 48, _binary_i_undo_bin_start }, + {"clear", 48, 48, _binary_i_clear_bin_start }, {NULL, 0, 0, NULL } }; From 91c466eae7433f83b475dbdff4a6cc90d401bd68 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Wed, 11 Dec 2019 15:54:21 -0700 Subject: [PATCH 158/162] typo in makefile --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index aff9c9b..81342ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -40,7 +40,7 @@ i_fillrect.bin: $(RESOURCES)/i_fillrect.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_fillrect.png i_fillrect.bin i_undo.bin: $(RESOURCES)/i_undo.png $(BUILDUTILS)/mkgfx - $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png undo.bin + $(BUILDUTILS)/mkgfx $(RESOURCES)/i_undo.png i_undo.bin i_clear.bin: $(RESOURCES)/i_clear.png $(BUILDUTILS)/mkgfx $(BUILDUTILS)/mkgfx $(RESOURCES)/i_clear.png i_clear.bin From d1369964d7398ca1ff790fc5b27fda1c17bab7d2 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:24:58 -0700 Subject: [PATCH 159/162] The code has to be GPL'd, because the license of the BCM2835 library requires it. Add the license document and the header on all source files. --- LICENSE.md | 336 +++++++++++++++++++++++++++++++ Makefile | 17 ++ buildutils/Makefile | 17 ++ buildutils/mkgfx.c | 19 ++ docs/templates/license_header.c | 19 ++ docs/templates/license_header.mk | 17 ++ docs/templates/license_header.py | 17 ++ scripts/demo1.py | 19 +- scripts/test_clipping.py | 19 +- scripts/tmp_main.py | 19 +- src/Makefile | 17 ++ src/bitmap.c | 19 ++ src/bitmap.h | 19 ++ src/config.c | 19 ++ src/config.h | 19 ++ src/dc_screen.c | 19 ++ src/dc_screen.h | 19 ++ src/devctxt.c | 19 ++ src/devctxt.h | 19 ++ src/ep_backlight.c | 19 ++ src/ep_bitmap.c | 19 ++ src/ep_devctxt.c | 19 ++ src/ep_graphics.c | 19 ++ src/ep_init.c | 19 ++ src/ep_init.h | 19 ++ src/ep_msg.c | 19 ++ src/ep_types.h | 19 ++ src/ep_upiwin.c | 19 ++ src/ep_upiwin.h | 19 ++ src/ep_upiwin_tmp.c | 19 ++ src/ep_util.c | 19 ++ src/ep_util.h | 19 ++ src/fbinit.c | 19 ++ src/fbinit.h | 19 ++ src/fbprimitive.c | 19 ++ src/fbprimitive.h | 19 ++ src/fontengine.c | 19 ++ src/fontengine.h | 19 ++ src/gfxobj.c | 19 ++ src/gfxobj.h | 19 ++ src/gfxtype.h | 19 ++ src/gpio.c | 19 ++ src/gpio.h | 19 ++ src/log.c | 19 ++ src/log.h | 19 ++ src/main.c | 19 ++ src/msg.h | 19 ++ src/msg_queue.c | 19 ++ src/msg_queue.h | 19 ++ src/rect.c | 19 ++ src/scode.h | 19 ++ src/stockobj.c | 19 ++ src/sysinput.c | 19 ++ src/sysinput.h | 19 ++ src/time_func.c | 19 ++ src/time_func.h | 19 ++ src/wintype.h | 19 ++ 57 files changed, 1387 insertions(+), 3 deletions(-) create mode 100755 LICENSE.md create mode 100755 docs/templates/license_header.c create mode 100755 docs/templates/license_header.mk create mode 100755 docs/templates/license_header.py diff --git a/LICENSE.md b/LICENSE.md new file mode 100755 index 0000000..25f9fd4 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,336 @@ +GNU General Public License +========================== + +_Version 2, June 1991_ +_Copyright © 1989, 1991 Free Software Foundation, Inc.,_ +_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_ + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +### Preamble + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +We protect your rights with two steps: **(1)** copyright the software, and +**(2)** offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +**0.** This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The “Program”, below, +refers to any such program or work, and a “work based on the Program” +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term “modification”.) Each licensee is addressed as “you”. + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +**1.** You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +**2.** You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +* **a)** You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. +* **b)** You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. +* **c)** If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +**3.** You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +* **a)** Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, +* **b)** Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +* **c)** Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +**4.** You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +**5.** You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +**6.** Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +**7.** If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +**8.** If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +**9.** The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and “any +later version”, you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +**10.** If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +### NO WARRANTY + +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +### How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w` and `show c` should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w` and `show c`; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a “copyright disclaimer” for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/Makefile b/Makefile index 1273313..f951f9f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ all: make -C buildutils all make -C src all diff --git a/buildutils/Makefile b/buildutils/Makefile index 4a3e2d4..0a2906f 100644 --- a/buildutils/Makefile +++ b/buildutils/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ all: mkgfx mkgfx: mkgfx.c diff --git a/buildutils/mkgfx.c b/buildutils/mkgfx.c index 68e3ee2..2d7ba04 100644 --- a/buildutils/mkgfx.c +++ b/buildutils/mkgfx.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/docs/templates/license_header.c b/docs/templates/license_header.c new file mode 100755 index 0000000..f15cf34 --- /dev/null +++ b/docs/templates/license_header.c @@ -0,0 +1,19 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ diff --git a/docs/templates/license_header.mk b/docs/templates/license_header.mk new file mode 100755 index 0000000..d1adfbb --- /dev/null +++ b/docs/templates/license_header.mk @@ -0,0 +1,17 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ diff --git a/docs/templates/license_header.py b/docs/templates/license_header.py new file mode 100755 index 0000000..55d4e3d --- /dev/null +++ b/docs/templates/license_header.py @@ -0,0 +1,17 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ diff --git a/scripts/demo1.py b/scripts/demo1.py index 4e9a180..a823860 100755 --- a/scripts/demo1.py +++ b/scripts/demo1.py @@ -1,4 +1,21 @@ -# Demo script that implements a simple drawing program +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Demo script that implements a simple drawing program import upiwin # Save off some color values. diff --git a/scripts/test_clipping.py b/scripts/test_clipping.py index 083cb9b..a9db639 100755 --- a/scripts/test_clipping.py +++ b/scripts/test_clipping.py @@ -1,4 +1,21 @@ -# Test of line clipping +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Test of line clipping import upiwin hdc = upiwin.DevCtxt(type='screen') diff --git a/scripts/tmp_main.py b/scripts/tmp_main.py index 902d767..3fcc94e 100644 --- a/scripts/tmp_main.py +++ b/scripts/tmp_main.py @@ -1,4 +1,21 @@ -# Initial test script +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ +# Initial test script import upiwin import upiwin_tmp diff --git a/src/Makefile b/src/Makefile index 81342ea..1d581ea 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,20 @@ +# UPIWIN - Micro Pi Windowing Framework Kernel +# Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# ------------------------------------------------------------------------ BUILDUTILS=../buildutils RESOURCES=../resources SPLASHSCREEN=splash-vmwcblk.png diff --git a/src/bitmap.c b/src/bitmap.c index fa517ea..1a62055 100755 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "bitmap.h" diff --git a/src/bitmap.h b/src/bitmap.h index 4a306e2..a904868 100755 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __BITMAP_H_INCLUDED #define __BITMAP_H_INCLUDED diff --git a/src/config.c b/src/config.c index 02f8c3e..8199b18 100644 --- a/src/config.c +++ b/src/config.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/config.h b/src/config.h index 22253ac..23e45b6 100644 --- a/src/config.h +++ b/src/config.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __CONFIG_H_INCLUDED #define __CONFIG_H_INCLUDED diff --git a/src/dc_screen.c b/src/dc_screen.c index 29c4050..7ca7790 100755 --- a/src/dc_screen.c +++ b/src/dc_screen.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "log.h" diff --git a/src/dc_screen.h b/src/dc_screen.h index 560187c..575655b 100755 --- a/src/dc_screen.h +++ b/src/dc_screen.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __DC_SCREEN_H_INCLUDED #define __DC_SCREEN_H_INCLUDED diff --git a/src/devctxt.c b/src/devctxt.c index 217a0e3..7c6ea5d 100755 --- a/src/devctxt.c +++ b/src/devctxt.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "log.h" diff --git a/src/devctxt.h b/src/devctxt.h index 017e70a..f714c66 100755 --- a/src/devctxt.h +++ b/src/devctxt.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __DEVCTXT_H_INCLUDED #define __DEVCTXT_H_INCLUDED diff --git a/src/ep_backlight.c b/src/ep_backlight.c index e78cb58..188294f 100644 --- a/src/ep_backlight.c +++ b/src/ep_backlight.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_bitmap.c b/src/ep_bitmap.c index fbc6da6..89e70e0 100755 --- a/src/ep_bitmap.c +++ b/src/ep_bitmap.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #define PY_SSIZE_T_CLEAN #include diff --git a/src/ep_devctxt.c b/src/ep_devctxt.c index 070a2b6..bc58dcd 100755 --- a/src/ep_devctxt.c +++ b/src/ep_devctxt.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #define PY_SSIZE_T_CLEAN #include diff --git a/src/ep_graphics.c b/src/ep_graphics.c index 3643889..a029b08 100755 --- a/src/ep_graphics.c +++ b/src/ep_graphics.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "wintype.h" diff --git a/src/ep_init.c b/src/ep_init.c index 3eba18b..9e23517 100644 --- a/src/ep_init.c +++ b/src/ep_init.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/ep_init.h b/src/ep_init.h index 5e68ef4..340b1bf 100644 --- a/src/ep_init.h +++ b/src/ep_init.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_INIT_H_INCLUDED #define __EP_INIT_H_INCLUDED diff --git a/src/ep_msg.c b/src/ep_msg.c index 9cf072b..c2fbca5 100755 --- a/src/ep_msg.c +++ b/src/ep_msg.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_types.h b/src/ep_types.h index 55d2eae..751cc5a 100755 --- a/src/ep_types.h +++ b/src/ep_types.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_TYPES_H_INCLUDED #define __EP_TYPES_H_INCLUDED diff --git a/src/ep_upiwin.c b/src/ep_upiwin.c index 16ca9ed..91a418a 100644 --- a/src/ep_upiwin.c +++ b/src/ep_upiwin.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_upiwin.h b/src/ep_upiwin.h index b80fd0c..2f5fe99 100644 --- a/src/ep_upiwin.h +++ b/src/ep_upiwin.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_UPIWIN_H_INCLUDED #define __EP_UPIWIN_H_INCLUDED diff --git a/src/ep_upiwin_tmp.c b/src/ep_upiwin_tmp.c index 51adcfb..97a9f62 100644 --- a/src/ep_upiwin_tmp.c +++ b/src/ep_upiwin_tmp.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_util.c b/src/ep_util.c index 44a49c8..a08d5b1 100644 --- a/src/ep_util.c +++ b/src/ep_util.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #define PY_SSIZE_T_CLEAN #include #include "scode.h" diff --git a/src/ep_util.h b/src/ep_util.h index 0406aca..c5d415c 100644 --- a/src/ep_util.h +++ b/src/ep_util.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __EP_UTIL_H_INCLUDED #define __EP_UTIL_H_INCLUDED diff --git a/src/fbinit.c b/src/fbinit.c index 11bbcd3..84491c1 100644 --- a/src/fbinit.c +++ b/src/fbinit.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/fbinit.h b/src/fbinit.h index 66e4f35..1575ce0 100644 --- a/src/fbinit.h +++ b/src/fbinit.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FBINIT_H_INCLUDED #define __FBINIT_H_INCLUDED diff --git a/src/fbprimitive.c b/src/fbprimitive.c index fe3e6ab..fad520f 100644 --- a/src/fbprimitive.c +++ b/src/fbprimitive.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "wintype.h" diff --git a/src/fbprimitive.h b/src/fbprimitive.h index a9c4e52..3e82ddd 100644 --- a/src/fbprimitive.h +++ b/src/fbprimitive.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FBPRIMITIVE_H_INCLUDED #define __FBPRIMITIVE_H_INCLUDED diff --git a/src/fontengine.c b/src/fontengine.c index ddc663d..7bc5c5f 100644 --- a/src/fontengine.c +++ b/src/fontengine.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include FT_FREETYPE_H #include "scode.h" diff --git a/src/fontengine.h b/src/fontengine.h index 5fa9187..841fa36 100644 --- a/src/fontengine.h +++ b/src/fontengine.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __FONTENGINE_H_INCLUDED #define __FONTENGINE_H_INCLUDED diff --git a/src/gfxobj.c b/src/gfxobj.c index c721f43..b701bbc 100755 --- a/src/gfxobj.c +++ b/src/gfxobj.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "gfxobj.h" diff --git a/src/gfxobj.h b/src/gfxobj.h index 0f7a6b6..9b3e3dc 100755 --- a/src/gfxobj.h +++ b/src/gfxobj.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GFXOBJ_H_INCLUDED #define __GFXOBJ_H_INCLUDED diff --git a/src/gfxtype.h b/src/gfxtype.h index efc02db..b969193 100755 --- a/src/gfxtype.h +++ b/src/gfxtype.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GFXTYPE_H_INCLUDED #define __GFXTYPE_H_INCLUDED diff --git a/src/gpio.c b/src/gpio.c index ff877c4..5c8aea3 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "config.h" diff --git a/src/gpio.h b/src/gpio.h index e368291..2a5f833 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __GPIO_H_INCLUDED #define __GPIO_H_INCLUDED diff --git a/src/log.c b/src/log.c index a239fc9..88d8ccf 100644 --- a/src/log.c +++ b/src/log.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/log.h b/src/log.h index a0871ca..c2f82d5 100644 --- a/src/log.h +++ b/src/log.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __LOG_H_INCLUDED #define __LOG_H_INCLUDED diff --git a/src/main.c b/src/main.c index 99b9a63..c9c3456 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/msg.h b/src/msg.h index afff6a9..2733c19 100644 --- a/src/msg.h +++ b/src/msg.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __MSG_H_INCLUDED #define __MSG_H_INCLUDED diff --git a/src/msg_queue.c b/src/msg_queue.c index 566dc0e..62a4124 100644 --- a/src/msg_queue.c +++ b/src/msg_queue.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/msg_queue.h b/src/msg_queue.h index 6ca5f75..99ee867 100644 --- a/src/msg_queue.h +++ b/src/msg_queue.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __MSG_QUEUE_H_INCLUDED #define __MSG_QUEUE_H_INCLUDED diff --git a/src/rect.c b/src/rect.c index eae408a..0a9608f 100755 --- a/src/rect.c +++ b/src/rect.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include "log.h" #include "gfxtype.h" diff --git a/src/scode.h b/src/scode.h index 06cca67..acd472b 100644 --- a/src/scode.h +++ b/src/scode.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __SCODE_H_INCLUDED #define __SCODE_H_INCLUDED diff --git a/src/stockobj.c b/src/stockobj.c index 394195a..cb12205 100755 --- a/src/stockobj.c +++ b/src/stockobj.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "wintype.h" diff --git a/src/sysinput.c b/src/sysinput.c index cdc0d01..0682c49 100644 --- a/src/sysinput.c +++ b/src/sysinput.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include diff --git a/src/sysinput.h b/src/sysinput.h index e191b66..d3ecb20 100644 --- a/src/sysinput.h +++ b/src/sysinput.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __SYSINPUT_H_INCLUDED #define __SYSINPUT_H_INCLUDED diff --git a/src/time_func.c b/src/time_func.c index f7603ff..4c0907e 100644 --- a/src/time_func.c +++ b/src/time_func.c @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #include #include #include "time_func.h" diff --git a/src/time_func.h b/src/time_func.h index 635ca03..2648d85 100644 --- a/src/time_func.h +++ b/src/time_func.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __TIMEFUNC_H_INCLUDED #define __TIMEFUNC_H_INCLUDED diff --git a/src/wintype.h b/src/wintype.h index 19aa6df..9e1d6dc 100644 --- a/src/wintype.h +++ b/src/wintype.h @@ -1,3 +1,22 @@ +/* + * UPIWIN - Micro Pi Windowing Framework Kernel + * Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *------------------------------------------------------------------------- + */ #ifndef __WINTYPE_H_INCLUDED #define __WINTYPE_H_INCLUDED From a7378504163a77865e4de5ccdd83e8fb6ec326aa Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:33:31 -0700 Subject: [PATCH 160/162] And, since we have to include a license, we should include the official Erbosoft Project Code of Conduct. :) --- CODE-OF-CONDUCT.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 CODE-OF-CONDUCT.md diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100755 index 0000000..fd0edab --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,57 @@ +# The Erbosoft Project Code of Conduct +## (Revised December 2019) + +For the purposes of this project, the Owner is Amy G. Bowersox/Erbosoft Metaverse Design Solutions. + +1. *The Owner owns this project.* Not you. The Owner's decisions about any aspect of the project +are *final.* +2. This Code of Conduct contains harsh language. Tough shit. Suck it up, Buttercup. +3. Anyone who is an *asshole* is **banned** *from this project.* **Permanently.** +4. This project has certain objectives. Anything outside of those objectives is *irrelevant,* +unless and until the *Owner* changes the objectives. Not you. In particular, if you’re a Social +Justice Warrior trying to join this project to spread your *bullshit,* you are *automatically +declared an asshole.* And you’re *gone.* +5. The Owner reserves the right to change this Code of Conduct as they see fit. If, however, you try +to force the Owner to change it in ways that are *offensive to them,* or that try to advance +“social justice” ideals in any way, shape, or form, you’re an *asshole.* And you’re *gone.* +6. In particular, this project explicitly *rejects* the “Open Code of Conduct” by the TODO Group, +the “Contributor Code of Merit” by Coraline Ada Ehmke, the “Citizen Code of Conduct” by +Stumptown Syndicate, and any similar “codes of conduct” that may be promulgated. Anyone complaining +about this is an *asshole,* because *who the fuck are you* to tell *the Owner* how *they* should +run *their* goddamn project? And you’re *gone.* +7. The *one and only* criterion that will be used to determine whether a contribution to this project +will be accepted is *the quality of the contribution and how well it solves the problem it was +contributed to solve.* **Period.** (“Contribution” may include code, documentation, testing, or fundraising.) +8. The *one and only* criterion that will be used to judge your worth in relation to this project is +*the quality of your contributions (as defined above) to this project.* **Period.** +9. The Owner hereby does not give *one milli-micro-nano-fraction of a* **fuck** what race you are, +what gender you are or identify as, who you want to sleep with, how old you are, what your height or +weight is, what if anything may be different about your body or brain, what language you speak, +what country you’re from, what God you pray to, where you work, how much money you have, +et fucking cetera. Is your contribution any *good?* That’s all that matters. +10. If your contribution is not accepted, and you start *whining* about how it’s “actually” because you’re +of some-or-other gender/race/religion/nationality/whatthefuckever, you are attempting to have the deck +stacked in your favor because you’re “special.” That makes you an *asshole.* And you’re *gone.* +11. Only those people who have contributed a sufficient quantity of good work to the project, +*as determined in the Owner's sole discretion,* will be allowed to assume any board position, +administrative position, or management-related role. And, any position that the Owner gives, they can +also *take away,* for any reason. Anyone who complains about this is an *asshole.* And they’re *gone.* +12. You will do your own work. If you try to pass off the work of others as your own, you’re a +fucking *plagiarist,* and also an *asshole.* And you’re *gone.* +13. If there’s a discussion that cannot be resolved within the scope of the project, +*take that shit somewhere else.* The Owner does not want your bullshit here. If you continue to spread +your bullshit here, you’re an *asshole.* And you’re *gone.* +14. As noted above, the Owner's decisions about any aspect of the project are *final.* Anyone +*pissing the Owner off* by getting all up in their face about said decisions is an *asshole.* +And they’re *gone.* +15. Any advisory boards, committees, etc., having to do with this project will answer to *the Owner.* +The Owner reserves the right to disband any such whenever the hell they feel like it. As always, anyone +complaining about this is an *asshole.* And they’re *gone.* +16. Anyone who does not approve of the objectives, direction, or attitude of this project is +free to *get the fuck out* at any time. Bye Felicia! + +Acknowlegements: +- [Why Hackers Must Eject the SJWs](http://esr.ibiblio.org/?p=6918), Eric S. Raymond +- [OSS Code of Merit](http://voxday.blogspot.com/2016/01/code-of-merit.html), Vox Day +- [A contribution policy for open source that works](https://medium.com/@jmaynard/a-contribution-policy-for-open-source-that-works-bfc4600c9d83#.dslxcx1fc), Jay Maynard +- [The Code of Merit](https://github.com/rosarior/Code-of-Merit/blob/master/CODE_OF_MERIT.md), Roberto Rosario \ No newline at end of file From cd453f0839207f3b39e5a15aab428277fcf05260 Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 09:37:31 -0700 Subject: [PATCH 161/162] and give VMW/CB a grateful acknowledgement in the README --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22e1f59..357eabc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ # UPIWIN - Micro Pi Windows Kernel -Requirements: -- Raspberry Pi 3 with PiTFT touchscreen +This project involves the development of a framework for running self-contained applications in Python +on a Raspberry Pi with LCD graphical output and touchscreen input. The ultimate goal is to produce a +framework which is flexible enough to serve any number of “appliance” needs, by using different Python +scripts over the same native-code substrate, deployed on an inexpensive embedded platform. + +## Hardware requirements + +- Raspberry Pi 3 with PiTFT touchscreen (Adafruit product ID 2423) + +## Acknowledgements + +A good portion of this code was written during the VMware Carbon Black Hackathon 3.3, December 6-13 2019. +Grateful acknowledgement is provided to VMware Carbon Black for the time to accomplish this coding. From 1e00a73b0817caae9bbf374dcb5b5fa74330b8aa Mon Sep 17 00:00:00 2001 From: Amy Bowersox Date: Thu, 12 Dec 2019 13:58:16 -0700 Subject: [PATCH 162/162] bump the version number (actually establish it for the first time!) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 357eabc..72c1d2e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # UPIWIN - Micro Pi Windows Kernel +*Release 0.1 - December 12, 2019* + This project involves the development of a framework for running self-contained applications in Python on a Raspberry Pi with LCD graphical output and touchscreen input. The ultimate goal is to produce a framework which is flexible enough to serve any number of “appliance” needs, by using different Python