Merge pull request #25 from inmarket/master

Bug fixes + new driver + extend touch demo
ugfx_release_2.6
Tectu 2012-12-02 03:05:21 -08:00
commit 24e75d96e1
8 changed files with 477 additions and 175 deletions

View File

@ -26,18 +26,22 @@
#include "gwin.h"
static GConsoleObject gc;
static GButtonObject gNext;
static GButtonObject gPrev;
static GListener gl;
/*------------------------------------------------------------------------*
* GINPUT Touch Driver Calibrator. *
*------------------------------------------------------------------------*/
int main(void) {
GSourceHandle gs;
GSourceHandle gs, gsNext, gsPrev;
GEvent *pe;
GEventMouse *pem;
GEventGWinButton *peb;
coord_t swidth, sheight;
GHandle ghc;
GHandle ghc, ghNext, ghPrev;
BaseSequentialStream *gp;
unsigned testnum;
GEventType deviceType;
halInit(); // Initialise the Hardware
chSysInit(); // Initialize the OS
@ -46,7 +50,7 @@ int main(void) {
// Get the display dimensions
swidth = gdispGetWidth();
sheight = gdispGetHeight();
testnum = 0;
ghNext = ghPrev = 0;
// Create our title
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", &fontUI2, Red, White, justifyCenter);
@ -65,52 +69,87 @@ int main(void) {
* Test: Device Type
*/
StepDeviceType:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. DEVICE TYPE\n\n", ++testnum);
chprintf(gp, "\n1. DEVICE TYPE\n\n");
pem = (GEventMouse *)&gl.event;
ginputGetMouseStatus(0, pem);
deviceType = pem->type;
gwinSetColor(ghc, White);
chprintf(gp, "This is detected as a %s device\n\n",
pem->type == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
chprintf(gp, "Press and release your finger (or mouse button) to move on to the next test.\n");
if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to move on to the next test.\n");
else
chprintf(gp, "Press and release your finger to move on to the next test.\n");
do {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
} while (!(pem->meta & GMETA_MOUSE_UP));
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepClickJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
/*
* Test: Mouse raw reading jitter
*/
StepRawJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. GINPUT_MOUSE_READ_CYCLES\n\n", ++testnum);
chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press on the surface (or press and hold the mouse button).\n\n");
if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button.\n\n");
else
chprintf(gp, "Press and hold on the surface.\n\n");
chprintf(gp, "Numbers will display in this window.\n"
"Ensure that values don't jump around very much when your finger is stationary.\n\n"
"Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n"
"Releasing your finger (or mouse button) will move on to the next test.\n\n");
"Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n");
if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Release the mouse button to move on to the next test.\n");
else
chprintf(gp, "Release your finger to move on to the next test.\n");
// For this test turn on ALL mouse movement events
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
do {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, "%u:%u\n", pem->x, pem->y);
} while (!(pem->meta & GMETA_MOUSE_UP));
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepDeviceType;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, "%u:%u\n", pem->x, pem->y);
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
// Reset to just changed movements.
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
@ -119,60 +158,124 @@ int main(void) {
* Test: Calibration
*/
StepCalibrate:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. GINPUT_MOUSE_CALIBRATION_ERROR\n\n", ++testnum);
chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n");
gwinSetColor(ghc, Gray);
chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "When you press and release the surface, calibration will start.\n");
chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n"
"If the calibration repeatedly fails increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n");
"If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n");
do {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
if (ghNext)
chprintf(gp, "Press Next to start the calibration.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to start the calibration.\n");
else
chprintf(gp, "Press and release your finger to start the calibration.\n");
} while (!(pem->meta & GMETA_MOUSE_UP));
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepRawJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
// Calibrate
ginputCalibrateMouse(0);
// Calibration uses the whole screen - re-establish our title
/* From now on we can use Next and Previous Buttons */
if (!ghNext) {
ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, &fontUI2, GBTN_NORMAL);
gwinSetButtonText(ghNext, "Next", FALSE);
gsNext = gwinGetButtonSource(ghNext);
geventAttachSource(&gl, gsNext, 0);
gwinAttachButtonMouseSource(ghNext, gs);
ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, &fontUI2, GBTN_NORMAL);
gwinSetButtonText(ghPrev, "Back", FALSE);
gsPrev = gwinGetButtonSource(ghPrev);
geventAttachSource(&gl, gsPrev, 0);
gwinAttachButtonMouseSource(ghPrev, gs);
#if 0
{
GSourceHandle gsButton1, gsButton2;
// Attach a couple of hardware toggle buttons to our Next and Back buttons as well.
// We can always use the mouse to trigger the buttons if you don't want to use hardware toggles.
// This code depends on your hardware. Turn it on only if you have
// defined a board definition for your toggle driver. Then change
// the next two lines to be correct for your hardware. The values
// below are correct for the Win32 toggle driver.
gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1);
gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2);
gwinAttachButtonToggleSource(ghNext, gsButton2);
gwinAttachButtonToggleSource(ghPrev, gsButton1);
}
#endif
}
// Calibration used the whole screen - re-establish our title
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", &fontUI2, Green, White, justifyCenter);
gwinButtonDraw(ghNext);
gwinButtonDraw(ghPrev);
/*
* Test: Mouse movement jitter
*/
StepJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. GINPUT_MOUSE_MOVE_JITTER\n\n", ++testnum);
chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n");
else
chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n");
chprintf(gp, "Dots will display in this window. Ensure that when you stop moving your finger that "
"new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n"
"Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n"
"Releasing your finger (or mouse button) will move on to the next test.\n\n");
"Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n");
chprintf(gp, "Press Next or Back to continue.\n\n");
do {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, ".");
} while (!(pem->meta & GMETA_MOUSE_UP));
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepCalibrate;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, ".");
}
}
/*
* Test: Polling frequency
*/
StepPolling:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. GINPUT_MOUSE_POLL_PERIOD\n\n", ++testnum);
chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
@ -180,26 +283,33 @@ int main(void) {
"Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without "
"gaps that are too big.\nDecreasing the value increases CPU usage.\n"
"About 25 (millisecs) normally produces good results."
"This test can be ignored for interrupt driven drivers.\n\n"
"Releasing your finger (or mouse button) will move on to the next test.\n");
do {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
gdispDrawPixel(pem->x, pem->y, Green);
} while (!(pem->meta & GMETA_MOUSE_UP));
"This test can be ignored for interrupt driven drivers.\n\n");
chprintf(gp, "Press Next or Back to continue.\n\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
gdispDrawPixel(pem->x, pem->y, Green);
}
}
/*
* Test: Click Jitter
*/
StepClickJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n%u. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n", ++testnum);
chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n");
@ -209,21 +319,31 @@ int main(void) {
"Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n"
"Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n"
"TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n"
"Note: moving your finger (mouse) during a click cancels it."
"This test does not end.\n\n");
"Note: moving your finger (mouse) during a click cancels it.\n\n");
chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n");
while(1) {
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
if (pem->type != GEVENT_MOUSE && pem->type != GEVENT_TOUCH) // Safety Check
continue;
if ((pem->meta & GMETA_MOUSE_CLICK)) {
gwinSetColor(ghc, Yellow);
chprintf(gp, "-");
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepPolling;
if (peb->button == ghNext)
break;
}
if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
gwinSetColor(ghc, Red);
chprintf(gp, "x");
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->meta & GMETA_MOUSE_CLICK)) {
gwinSetColor(ghc, Yellow);
chprintf(gp, "-");
}
if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
gwinSetColor(ghc, Red);
chprintf(gp, "x");
}
}
}
// Can't let this really exit
goto StepDeviceType;
}

View File

@ -32,12 +32,6 @@
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include mouse support code */
#include "lld/ginput/mouse.h"
/* Include the emulation code for things we don't support */
#include "lld/gdisp/emulation.c"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -45,11 +39,41 @@
#include <wingdi.h>
#include <assert.h>
#ifndef GINPUT_NEED_TOGGLE
#define GINPUT_NEED_TOGGLE FALSE
#endif
#ifndef GINPUT_NEED_MOUSE
#define GINPUT_NEED_MOUSE FALSE
#endif
#if GINPUT_NEED_TOGGLE
/* Include toggle support code */
#include "lld/ginput/toggle.h"
const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = {
{0, 0xFF, 0x00, PAL_MODE_INPUT},
};
#endif
#if GINPUT_NEED_MOUSE
/* Include mouse support code */
#include "ginput.h"
#include "lld/ginput/mouse.h"
#endif
/* Include the emulation code for things we don't support */
#include "lld/gdisp/emulation.c"
/*===========================================================================*/
/* Driver local routines . */
/*===========================================================================*/
#define WIN32_USE_MSG_REDRAW FALSE
#if GINPUT_NEED_TOGGLE
#define WIN32_BUTTON_AREA 16
#else
#define WIN32_BUTTON_AREA 0
#endif
#define APP_NAME "GDISP"
@ -61,37 +85,104 @@ static HDC dcBuffer = NULL;
static HBITMAP dcBitmap = NULL;
static HBITMAP dcOldBitmap;
static volatile bool_t isReady = FALSE;
static coord_t mousex, mousey;
static uint16_t mousebuttons;
static coord_t wWidth, wHeight;
#if GINPUT_NEED_MOUSE
static coord_t mousex, mousey;
static uint16_t mousebuttons;
#endif
#if GINPUT_NEED_TOGGLE
static uint8_t toggles = 0;
#endif
static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
HDC dc;
PAINTSTRUCT ps;
HDC dc;
PAINTSTRUCT ps;
#if GINPUT_NEED_TOGGLE
HBRUSH hbrOn, hbrOff;
HPEN pen;
RECT rect;
HGDIOBJ old;
POINT p;
coord_t pos;
uint8_t bit;
#endif
switch (Msg) {
case WM_CREATE:
break;
#if GINPUT_NEED_MOUSE
case WM_LBUTTONDOWN:
mousebuttons = 0x0001;
goto mousemove;
#if GINPUT_NEED_MOUSE
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
goto mousemove;
}
#endif
#if GINPUT_NEED_TOGGLE
bit = 1 << ((coord_t)LOWORD(lParam)*8/wWidth);
toggles ^= bit;
rect.left = 0;
rect.right = wWidth;
rect.top = wHeight;
rect.bottom = wHeight + WIN32_BUTTON_AREA;
InvalidateRect(hWnd, &rect, FALSE);
UpdateWindow(hWnd);
#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
ginputToggleWakeup();
#endif
#endif
break;
case WM_LBUTTONUP:
mousebuttons &= ~0x0001;
goto mousemove;
#if GINPUT_NEED_TOGGLE
if ((toggles & 0xF0)) {
toggles &= 0x0F;
rect.left = 0;
rect.right = wWidth;
rect.top = wHeight;
rect.bottom = wHeight + WIN32_BUTTON_AREA;
InvalidateRect(hWnd, &rect, FALSE);
UpdateWindow(hWnd);
#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
ginputToggleWakeup();
#endif
}
#endif
#if GINPUT_NEED_MOUSE
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
goto mousemove;
}
#endif
break;
#if GINPUT_NEED_MOUSE
case WM_MBUTTONDOWN:
mousebuttons = 0x0004;
goto mousemove;
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
goto mousemove;
}
break;
case WM_MBUTTONUP:
mousebuttons &= ~0x0004;
goto mousemove;
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
goto mousemove;
}
break;
case WM_RBUTTONDOWN:
mousebuttons = 0x0002;
goto mousemove;
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
goto mousemove;
}
break;
case WM_RBUTTONUP:
mousebuttons &= ~0x0002;
goto mousemove;
if ((coord_t)HIWORD(lParam) < wHeight) {
mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
goto mousemove;
}
break;
case WM_MOUSEMOVE:
if ((coord_t)HIWORD(lParam) >= wHeight)
break;
mousemove:
mousex = (coord_t)LOWORD(lParam);
mousey = (coord_t)HIWORD(lParam);
@ -114,8 +205,32 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
dc = BeginPaint(hWnd, &ps);
BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
(ps.rcPaint.bottom > wHeight ? wHeight : ps.rcPaint.bottom) - ps.rcPaint.top,
dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
#if GINPUT_NEED_TOGGLE
if (ps.rcPaint.bottom >= wHeight) {
pen = CreatePen(PS_SOLID, 1, COLOR2BGR(Black));
hbrOn = CreateSolidBrush(COLOR2BGR(Blue));
hbrOff = CreateSolidBrush(COLOR2BGR(Gray));
old = SelectObject(dc, pen);
MoveToEx(dc, 0, wHeight, &p);
LineTo(dc, wWidth, wHeight);
for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
rect.left = pos;
rect.right = pos + wWidth/8;
rect.top = wHeight;
rect.bottom = wHeight + WIN32_BUTTON_AREA;
FillRect(dc, &rect, (toggles & bit) ? hbrOn : hbrOff);
if (pos > 0) {
MoveToEx(dc, rect.left, rect.top, &p);
LineTo(dc, rect.left, rect.bottom);
}
}
DeleteObject(hbrOn);
DeleteObject(hbrOff);
SelectObject(dc, old);
}
#endif
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
@ -154,8 +269,8 @@ static DWORD WINAPI WindowThread(LPVOID lpParameter) {
wc.lpszClassName = APP_NAME;
RegisterClass(&wc);
rect.top = 0; rect.bottom = GDISP.Height;
rect.left = 0; rect.right = GDISP.Width;
rect.top = 0; rect.bottom = wHeight+WIN32_BUTTON_AREA;
rect.left = 0; rect.right = wWidth;
AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
winRootWindow = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0, 0,
rect.right-rect.left, rect.bottom-rect.top, 0, 0, hInstance, NULL);
@ -163,11 +278,11 @@ static DWORD WINAPI WindowThread(LPVOID lpParameter) {
GetClientRect(winRootWindow, &rect);
GDISP.Width = rect.right-rect.left;
GDISP.Height = rect.bottom - rect.top;
wWidth = rect.right-rect.left;
wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
dc = GetDC(winRootWindow);
dcBitmap = CreateCompatibleBitmap(dc, GDISP.Width, GDISP.Height);
dcBitmap = CreateCompatibleBitmap(dc, wWidth, wHeight);
dcBuffer = CreateCompatibleDC(dc);
ReleaseDC(winRootWindow, dc);
dcOldBitmap = SelectObject(dcBuffer, dcBitmap);
@ -205,12 +320,12 @@ bool_t GDISP_LLD(init)(void) {
/* Set the window dimensions */
GetWindowRect(GetDesktopWindow(), &rect);
GDISP.Width = rect.right - rect.left;
GDISP.Height = rect.bottom - rect.top;
if (GDISP.Width > GDISP_SCREEN_WIDTH)
GDISP.Width = GDISP_SCREEN_WIDTH;
if (GDISP.Height > GDISP_SCREEN_HEIGHT)
GDISP.Height = GDISP_SCREEN_HEIGHT;
wWidth = rect.right - rect.left;
wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
if (wWidth > GDISP_SCREEN_WIDTH)
wWidth = GDISP_SCREEN_WIDTH;
if (wHeight > GDISP_SCREEN_HEIGHT)
wHeight = GDISP_SCREEN_HEIGHT;
/* Initialise the window */
CreateThread(0, 0, WindowThread, 0, 0, 0);
@ -222,6 +337,8 @@ bool_t GDISP_LLD(init)(void) {
GDISP.Powermode = powerOn;
GDISP.Backlight = 100;
GDISP.Contrast = 50;
GDISP.Width = wWidth;
GDISP.Height = wHeight;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
@ -841,33 +958,26 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @notapi
*/
void GDISP_LLD(control)(unsigned what, void *value) {
RECT rect;
switch(what) {
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
GetClientRect(winRootWindow, &rect);
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
/* Code here */
GDISP.Width = rect.right-rect.left;
GDISP.Height = rect.bottom - rect.top;
GDISP.Width = wWidth;
GDISP.Height = wHeight;
break;
case GDISP_ROTATE_90:
/* Code here */
GDISP.Height = rect.right-rect.left;
GDISP.Width = rect.bottom - rect.top;
GDISP.Height = wWidth;
GDISP.Width = wHeight;
break;
case GDISP_ROTATE_180:
/* Code here */
GDISP.Width = rect.right-rect.left;
GDISP.Height = rect.bottom - rect.top;
GDISP.Width = wWidth;
GDISP.Height = wHeight;
break;
case GDISP_ROTATE_270:
/* Code here */
GDISP.Height = rect.right-rect.left;
GDISP.Width = rect.bottom - rect.top;
GDISP.Height = wWidth;
GDISP.Width = wHeight;
break;
default:
return;
@ -892,16 +1002,21 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#if GINPUT_NEED_MOUSE
#include "lld/ginput/mouse.h"
void ginput_lld_mouse_init(void) {}
void ginput_lld_mouse_init(void) {}
void ginput_lld_mouse_get_reading(MouseReading *pt) {
pt->x = mousex;
pt->y = mousey > wHeight ? wHeight : mousey;
pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
pt->buttons = mousebuttons;
}
void ginput_lld_mouse_get_reading(MouseReading *pt) {
pt->x = mousex;
pt->y = mousey;
pt->z = (mousebuttons & 0x0001) ? 100 : 0;
pt->buttons = mousebuttons; // We auto-magicaly know that the mousebutton bits match the MouseReading bits.
}
#endif /* GINPUT_NEED_MOUSE */
#if GINPUT_NEED_TOGGLE
void ginput_lld_toggle_init(const GToggleConfig *ptc) { (void) ptc; }
unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) { (void) ptc; return toggles; }
#endif /* GINPUT_NEED_MOUSE */

View File

@ -0,0 +1,51 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX 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 3 of the License, or
(at your option) any later version.
ChibiOS/GFX 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, see <http://www.gnu.org/licenses/>.
*/
/**
* @file drivers/multiple/Win32/ginput_lld_toggle_config.h
* @brief GINPUT Toggle Driver configuration header.
*
* @addtogroup GINPUT_TOGGLE
* @{
*/
#ifndef _GINPUT_LLD_TOGGLE_CONFIG_H
#define _GINPUT_LLD_TOGGLE_CONFIG_H
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - ether works here)
#define GINPUT_TOGGLE_NUM_PORTS 8 // The total number of toggle inputs
#define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
#define GINPUT_TOGGLE_SW1 0 // Switch 1 - Toggle
#define GINPUT_TOGGLE_SW2 1 // Switch 2 - Toggle
#define GINPUT_TOGGLE_SW3 2 // Switch 3 - Toggle
#define GINPUT_TOGGLE_SW4 3 // Switch 4 - Toggle
#define GINPUT_TOGGLE_MOMENTARY1 4 // Switch 5 - Momentary
#define GINPUT_TOGGLE_MOMENTARY2 5 // Switch 6 - Momentary
#define GINPUT_TOGGLE_MOMENTARY3 6 // Switch 7 - Momentary
#define GINPUT_TOGGLE_MOMENTARY4 7 // Switch 8 - Momentary
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
#endif /* _GINPUT_LLD_TOGGLE_CONFIG_H */
/** @} */

View File

@ -129,8 +129,15 @@ extern "C" {
// Get the source handle so the application can listen for events
#define gwinGetButtonSource(gh) ((GSourceHandle)(gh))
// Attach a source to this button. Sources recognised: Mouse, Touch and Toggle - others are ignored (returns false).
bool_t gwinAttachButtonSource(GHandle gh, GSourceHandle gsh, GEventType type);
#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE
// Attach a mouse source to this button.
bool_t gwinAttachButtonMouseSource(GHandle gh, GSourceHandle gsh);
#endif
#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE
// Attach a toggle source to this button.
bool_t gwinAttachButtonToggleSource(GHandle gh, GSourceHandle gsh);
#endif
#ifdef __cplusplus
}

View File

@ -65,7 +65,7 @@
// n - Millisecs between poll's
#ifndef GINPUT_MOUSE_POLL_PERIOD
#define GINPUT_MOUSE_POLL_PERIOD 100
#define GINPUT_MOUSE_POLL_PERIOD 25
#endif
// n - Movement allowed without discarding the CLICK or CLICKCXT event (+/- pixels)

View File

@ -30,22 +30,28 @@
#ifndef GFX_USE_GINPUT
#define GFX_USE_GINPUT FALSE
#endif
#if GFX_USE_GINPUT || defined(__DOXYGEN__)
#if GINPUT_NEED_TOGGLE
// Describes how the toggle bits are obtained
typedef struct GToggleConfig_t {
void *id;
unsigned mask;
unsigned invert;
iomode_t mode;
} GToggleConfig;
#ifndef GINPUT_NEED_TOGGLE
#define GINPUT_NEED_TOGGLE FALSE
#endif
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) || defined(__DOXYGEN__)
// Describes how the toggle bits are obtained
typedef struct GToggleConfig_t {
void *id;
unsigned mask;
unsigned invert;
iomode_t mode;
} GToggleConfig;
// This must be included after the above type definition
#include "ginput.h"
// n - Millisecs between poll's
#ifndef GINPUT_TOGGLE_POLL_PERIOD
#define GINPUT_TOGGLE_POLL_PERIOD 200
#endif
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@ -54,18 +60,26 @@
extern "C" {
#endif
#if GINPUT_NEED_TOGGLE
extern const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
void ginput_lld_toggle_init(const GToggleConfig *ptc);
unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc);
#endif
/* This routine is provided to low level drivers to wakeup a value read from a thread context.
* Particularly useful if GINPUT_TOGGLE_POLL_PERIOD = TIME_INFINITE
*/
void ginputToggleWakeup(void);
/* This routine is provided to low level drivers to wakeup a value read from an ISR
* Particularly useful if GINPUT_TOGGLE_POLL_PERIOD = TIME_INFINITE
*/
void ginputToggleWakeupI(void);
#ifdef __cplusplus
}
#endif
#endif /* GFX_USE_GINPUT */
#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */
#endif /* _LLD_GINPUT_TOGGLE_H */
/** @} */

View File

@ -34,10 +34,6 @@
#include "lld/ginput/toggle.h"
#ifndef GINPUT_TOGGLE_POLL_PERIOD
#define GINPUT_TOGGLE_POLL_PERIOD 250
#endif
#define GINPUT_TOGGLE_ISON 0x01
#define GINPUT_TOGGLE_INVERT 0x02
@ -157,5 +153,15 @@ bool_t ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle) {
return TRUE;
}
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
void ginputToggleWakeup(void) {
gtimerJab(&ToggleTimer);
}
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
void ginputToggleWakeupI(void) {
gtimerJabI(&ToggleTimer);
}
#endif /* GINPUT_NEED_TOGGLE */
/** @} */

View File

@ -297,34 +297,23 @@ void gwinButtonDraw(GHandle gh) {
#undef gbw
}
// Attach a source to this button. Sources recognised: Mouse, Touch and Toggle - others are ignored (returns false).
bool_t gwinAttachButtonSource(GHandle gh, GSourceHandle gsh, GEventType type) {
#define gbw ((GButtonObject *)gh)
unsigned flags;
#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE
bool_t gwinAttachButtonMouseSource(GHandle gh, GSourceHandle gsh) {
if (gh->type != GW_BUTTON)
return FALSE;
switch (type) {
#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE
case GEVENT_MOUSE:
flags = 0;
break;
#endif
#if defined(GINPUT_NEED_TOUCH) && GINPUT_NEED_TOUCH
case GEVENT_TOUCH:
flags = 0;
break;
#endif
#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE
case GEVENT_TOGGLE:
flags = GLISTEN_TOGGLE_OFF|GLISTEN_TOGGLE_ON;
break;
#endif
default:
return FALSE;
return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA);
}
return geventAttachSource(&gbw->listener, gsh, flags);
#endif
#undef gbw
}
#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE
bool_t gwinAttachButtonToggleSource(GHandle gh, GSourceHandle gsh) {
if (gh->type != GW_BUTTON)
return FALSE;
return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_TOGGLE_OFF|GLISTEN_TOGGLE_ON);
}
#endif
#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
/** @} */