added the rectangle functions and a "wait for input" mechanism to the system
input thread
This commit is contained in:
		
							parent
							
								
									cc00d7a5ef
								
							
						
					
					
						commit
						69a4c42d68
					
				@ -2,7 +2,7 @@ BUILDUTILS=../buildutils
 | 
				
			|||||||
RESOURCES=../resources
 | 
					RESOURCES=../resources
 | 
				
			||||||
SPLASHSCREEN=splash-vmwcblk.png
 | 
					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
 | 
					     log.o gpio.o msg_queue.o time_func.o config.o splash.o
 | 
				
			||||||
LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm
 | 
					LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm
 | 
				
			||||||
CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \
 | 
					CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										31
									
								
								src/gfxtype.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								src/gfxtype.h
									
									
									
									
									
										Executable file
									
								
							@ -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 */
 | 
				
			||||||
@ -93,3 +93,12 @@ BOOL Mq_peek(PMSG_QUEUE queue, PMSG msg, UINT32 flags)
 | 
				
			|||||||
  pthread_mutex_unlock(&(queue->mutex));
 | 
					  pthread_mutex_unlock(&(queue->mutex));
 | 
				
			||||||
  return rc;
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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_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 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_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_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)
 | 
					#define Mq_post1(q, tgt, msg, attr)   Mq_post2(q, tgt, msg, attr, 0)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										91
									
								
								src/rect.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										91
									
								
								src/rect.c
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -21,6 +21,9 @@ static int ts_fd = 0;          /* file descriptor for touchscreen */
 | 
				
			|||||||
static pthread_t ithread;                    /* input thread handle */
 | 
					static pthread_t ithread;                    /* input thread handle */
 | 
				
			||||||
static volatile sig_atomic_t running = 1;    /* "running" flag for input thread */
 | 
					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() */
 | 
					/* Local data for poll_buttons() */
 | 
				
			||||||
static UINT32 last_bstate = 0;                        /* previous button state */
 | 
					static UINT32 last_bstate = 0;                        /* previous button state */
 | 
				
			||||||
static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT];  /* timestamps to debounce events */
 | 
					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 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 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;
 | 
					  UINT32 st, down, up, mask;
 | 
				
			||||||
  UINT_PTR attr;
 | 
					  UINT_PTR attr;
 | 
				
			||||||
  TIMESTAMP now;
 | 
					  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)
 | 
					    for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      if (now < button_event_ok[attr - 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)
 | 
					      if (up & mask)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
	/* reset contact bounce timer - only seems to happen after button releases */
 | 
							/* reset contact bounce timer - only seems to happen after button releases */
 | 
				
			||||||
	button_event_ok[attr - 1] = now + Gconfig.button_debounce;
 | 
							button_event_ok[attr - 1] = now + Gconfig.button_debounce;
 | 
				
			||||||
	Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
 | 
							Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
 | 
				
			||||||
 | 
							posted = TRUE;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else if (down & mask)
 | 
					      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;
 | 
					    last_bstate = st;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  return posted;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void poll_touchscreen(void)
 | 
					static BOOL poll_touchscreen(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  BOOL posted = FALSE;
 | 
				
			||||||
  int nb, nev, xerrno, i;
 | 
					  int nb, nev, xerrno, i;
 | 
				
			||||||
  struct input_event buffer[INPUT_EVENT_BATCH];
 | 
					  struct input_event buffer[INPUT_EVENT_BATCH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,33 +99,37 @@ static void poll_touchscreen(void)
 | 
				
			|||||||
    switch (buffer[i].type)
 | 
					    switch (buffer[i].type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      case EV_SYN:
 | 
					      case EV_SYN:
 | 
				
			||||||
	if (buffer[i].code == SYN_REPORT)
 | 
							if (buffer[i].code == SYN_REPORT)
 | 
				
			||||||
	{
 | 
							{
 | 
				
			||||||
	  Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y);
 | 
							  Mq_post2(Sys_Queue, 0, touch_nextmsg, touch_x, touch_y);
 | 
				
			||||||
	  touch_nextmsg = WM_TOUCHMOVE;
 | 
						      touch_nextmsg = WM_TOUCHMOVE;
 | 
				
			||||||
	}
 | 
						      posted = TRUE;
 | 
				
			||||||
	break;
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
      case EV_ABS:
 | 
					      case EV_ABS:
 | 
				
			||||||
	if (buffer[i].code == ABS_X)
 | 
							if (buffer[i].code == ABS_X)
 | 
				
			||||||
	  touch_x = buffer[i].value;
 | 
							  touch_x = buffer[i].value;
 | 
				
			||||||
	else if (buffer[i].code == ABS_Y)
 | 
							else if (buffer[i].code == ABS_Y)
 | 
				
			||||||
	  touch_y = buffer[i].value;
 | 
							  touch_y = buffer[i].value;
 | 
				
			||||||
	break;
 | 
							break;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
      case EV_KEY:
 | 
					      case EV_KEY:
 | 
				
			||||||
	if (buffer[i].code == BTN_TOUCH)
 | 
							if (buffer[i].code == BTN_TOUCH)
 | 
				
			||||||
	  touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
 | 
							  touch_nextmsg = (buffer[i].value ? WM_TOUCHDOWN : WM_TOUCHUP);
 | 
				
			||||||
	break;
 | 
							break;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
	break;
 | 
							break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  return posted;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *input_thread(void *arg)
 | 
					static void *input_thread(void *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  BOOL gotinput;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  /* clear all state at startup */
 | 
					  /* clear all state at startup */
 | 
				
			||||||
  last_bstate = 0;
 | 
					  last_bstate = 0;
 | 
				
			||||||
  memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
 | 
					  memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
 | 
				
			||||||
@ -124,8 +138,14 @@ static void *input_thread(void *arg)
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  while (running)
 | 
					  while (running)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    poll_buttons();
 | 
						gotinput = poll_buttons();
 | 
				
			||||||
    poll_touchscreen();
 | 
					    gotinput = poll_touchscreen() || gotinput;
 | 
				
			||||||
 | 
						if (gotinput)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  pthread_mutex_lock(&wait_mutex);
 | 
				
			||||||
 | 
						  pthread_cond_signal(&wait_cond);
 | 
				
			||||||
 | 
						  pthread_mutex_unlock(&wait_mutex);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -178,4 +198,15 @@ HRESULT Sys_enable_input(void)
 | 
				
			|||||||
      do_disable_input();
 | 
					      do_disable_input();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return rc;
 | 
					  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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,5 +7,6 @@
 | 
				
			|||||||
extern PMSG_QUEUE Sys_Queue;
 | 
					extern PMSG_QUEUE Sys_Queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern HRESULT Sys_enable_input(void);
 | 
					extern HRESULT Sys_enable_input(void);
 | 
				
			||||||
 | 
					extern void Sys_wait_for_input(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __SYSINPUT_H_INCLUDED */
 | 
					#endif /* __SYSINPUT_H_INCLUDED */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user