diff options
author | inmarket <andrewh@inmarket.com.au> | 2013-10-24 11:30:17 +1000 |
---|---|---|
committer | inmarket <andrewh@inmarket.com.au> | 2013-10-24 11:30:17 +1000 |
commit | 8c1a37b59eef97c1e713a4ae24459f3af82b65f2 (patch) | |
tree | db8da813ec46a54ffda9c8559757a5f5a1b2f1ab /drivers/multiple | |
parent | 825bbf26a1bf11d7148a16229f6515fae5efb276 (diff) | |
download | uGFX-8c1a37b59eef97c1e713a4ae24459f3af82b65f2.tar.gz uGFX-8c1a37b59eef97c1e713a4ae24459f3af82b65f2.tar.bz2 uGFX-8c1a37b59eef97c1e713a4ae24459f3af82b65f2.zip |
Add functions to the Win32 GDISP driver to enable full testing of the streaming driver interface.
Diffstat (limited to 'drivers/multiple')
-rw-r--r-- | drivers/multiple/Win32/gdisp_lld.c | 260 | ||||
-rw-r--r-- | drivers/multiple/Win32/gdisp_lld_config.h | 22 |
2 files changed, 250 insertions, 32 deletions
diff --git a/drivers/multiple/Win32/gdisp_lld.c b/drivers/multiple/Win32/gdisp_lld.c index 3ce50633..876168c3 100644 --- a/drivers/multiple/Win32/gdisp_lld.c +++ b/drivers/multiple/Win32/gdisp_lld.c @@ -17,38 +17,15 @@ #include "../drivers/multiple/Win32/gdisp_lld_config.h" #include "gdisp/lld/gdisp_lld.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <windows.h> -#include <wingdi.h> -#include <assert.h> - #ifndef GDISP_SCREEN_WIDTH #define GDISP_SCREEN_WIDTH 640 #endif #ifndef GDISP_SCREEN_HEIGHT #define GDISP_SCREEN_HEIGHT 480 #endif - -#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0) -#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1) -#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2) - -#if GINPUT_NEED_TOGGLE - /* Include toggle support code */ - #include "ginput/lld/toggle.h" -#endif - #if GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 #error "GDISP Win32: This driver currently only supports the RGB888 pixel format." #endif - -#if GINPUT_NEED_MOUSE - /* Include mouse support code */ - #include "ginput/lld/mouse.h" -#endif - // Setting this to TRUE delays updating the screen // to the windows paint routine. Due to the // drawing lock this does not add as much speed @@ -57,18 +34,46 @@ // even draw_pixel(). // This is probably due to drawing operations being // combined as the update regions are merged. +// The only time you might want to turn this off is +// if you are debugging drawing and want to see each +// pixel as it is set. #define GDISP_WIN32_USE_INDIRECT_UPDATE TRUE +//#define GDISP_WIN32_USE_INDIRECT_UPDATE FALSE -// How far extra windows should be offset from the first. +// How far extra windows (multiple displays) should be offset from the first. #define DISPLAY_X_OFFSET 50 #define DISPLAY_Y_OFFSET 50 +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <windows.h> +#include <wingdi.h> +#include <assert.h> + +#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0) +#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1) +#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2) +#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ + #define GDISP_FLG_WSTREAM (GDISP_FLG_DRIVER<<3) + #define GDISP_FLG_WRAPPED (GDISP_FLG_DRIVER<<4) +#endif + +#if GINPUT_NEED_TOGGLE + /* Include toggle support code */ + #include "ginput/lld/toggle.h" +#endif + +#if GINPUT_NEED_MOUSE + /* Include mouse support code */ + #include "ginput/lld/mouse.h" +#endif + static DWORD winThreadId; static ATOM winClass; static volatile bool_t QReady; static HANDLE drawMutex; - /*===========================================================================*/ /* Driver local routines . */ /*===========================================================================*/ @@ -96,6 +101,10 @@ typedef struct winPriv { #if GINPUT_NEED_TOGGLE uint8_t toggles; #endif + #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ + coord_t x0, y0, x1, y1; + coord_t x, y; + #endif } winPriv; @@ -441,6 +450,10 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { assert(priv != NULL); memset(priv, 0, sizeof(winPriv)); g->priv = priv; + #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ + // Initialise with an invalid window + g->flags &= ~GDISP_FLG_WSTREAM; + #endif g->board = 0; // no board interface for this controller // Create the window in the message thread @@ -467,6 +480,199 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { } #endif +#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ + void BAD_PARAMETER(const char *msg) { + volatile int a; + // This is really just a point for us to set the debugger + a = 0; + } +#endif + +#if GDISP_HARDWARE_STREAM_WRITE + LLDSPEC void gdisp_lld_write_start(GDisplay *g) { + winPriv * priv; + + if (g->flags & GDISP_FLG_WSTREAM) + BAD_PARAMETER("write_start: already in streaming mode"); + if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height) + BAD_PARAMETER("write_start: bad window parameter"); + + priv = g->priv; + priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1; + priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1; + #if GDISP_HARDWARE_STREAM_POS + priv->x = g->p.x-1; // Make sure these values are invalid (for testing) + priv->y = g->p.y-1; + #else + priv->x = g->p.x; + priv->y = g->p.y; + #endif + g->flags |= GDISP_FLG_WSTREAM; + g->flags &= ~GDISP_FLG_WRAPPED; + } + LLDSPEC void gdisp_lld_write_color(GDisplay *g) { + winPriv * priv; + int x, y; + COLORREF color; + + priv = g->priv; + color = COLOR2BGR(g->p.color); + + if (!(g->flags & GDISP_FLG_WSTREAM)) + BAD_PARAMETER("write_color: not in streaming mode"); + if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1) + BAD_PARAMETER("write_color: cursor outside streaming area"); + if (g->flags & GDISP_FLG_WRAPPED) { + BAD_PARAMETER("write_color: Warning - Area wrapped."); + g->flags &= ~GDISP_FLG_WRAPPED; + } + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + x = priv->x; + y = priv->y; + break; + case GDISP_ROTATE_90: + x = priv->y; + y = g->g.Width - 1 - priv->x; + break; + case GDISP_ROTATE_180: + x = g->g.Width - 1 - priv->x; + y = g->g.Height - 1 - priv->y; + break; + case GDISP_ROTATE_270: + x = g->g.Height - 1 - priv->y; + y = priv->x; + break; + } + #else + x = priv->x; + y = priv->y; + #endif + + // Draw the pixel on the screen and in the buffer. + WaitForSingleObject(drawMutex, INFINITE); + SetPixel(priv->dcBuffer, x, y, color); + #if GDISP_WIN32_USE_INDIRECT_UPDATE + ReleaseMutex(drawMutex); + { + RECT r; + r.left = x; r.right = x+1; + r.top = y; r.bottom = y+1; + InvalidateRect(priv->hwnd, &r, FALSE); + } + #else + { + HDC dc; + dc = GetDC(priv->hwnd); + SetPixel(dc, x, y, color); + ReleaseDC(priv->hwnd, dc); + ReleaseMutex(drawMutex); + } + #endif + + // Update the cursor + if (++priv->x > priv->x1) { + priv->x = priv->x0; + if (++priv->y > priv->y1) { + g->flags |= GDISP_FLG_WRAPPED; + priv->y = priv->y0; + } + } + } + LLDSPEC void gdisp_lld_write_stop(GDisplay *g) { + if (!(g->flags & GDISP_FLG_WSTREAM)) + BAD_PARAMETER("write_stop: not in streaming mode"); + g->flags &= ~GDISP_FLG_WSTREAM; + } + #if GDISP_HARDWARE_STREAM_POS + LLDSPEC void gdisp_lld_write_pos(GDisplay *g) { + winPriv * priv; + + priv = g->priv; + + if (!(g->flags & GDISP_FLG_WSTREAM)) + BAD_PARAMETER("write_pos: not in streaming mode"); + if (g->p.x < priv->x0 || g->p.x > priv->x1 || g->p.y < priv->y0 || g->p.y > priv->y1) + BAD_PARAMETER("write_color: new cursor outside streaming area"); + priv->x = g->p.x; + priv->y = g->p.y; + } + #endif +#endif + +#if GDISP_HARDWARE_STREAM_READ + LLDSPEC void gdisp_lld_read_start(GDisplay *g) { + winPriv * priv; + + if (g->flags & GDISP_FLG_WSTREAM) + BAD_PARAMETER("read_start: already in streaming mode"); + if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height) + BAD_PARAMETER("read_start: bad window parameter"); + + priv = g->priv; + priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1; + priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1; + priv->x = g->p.x; + priv->y = g->p.y; + g->flags |= GDISP_FLG_WSTREAM; + g->flags &= ~GDISP_FLG_WRAPPED; + } + LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) { + winPriv * priv; + COLORREF color; + + priv = g->priv; + + if (!(g->flags & GDISP_FLG_WSTREAM)) + BAD_PARAMETER("read_color: not in streaming mode"); + if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1) + BAD_PARAMETER("read_color: cursor outside streaming area"); + if (g->flags & GDISP_FLG_WRAPPED) { + BAD_PARAMETER("read_color: Warning - Area wrapped."); + g->flags &= ~GDISP_FLG_WRAPPED; + } + + WaitForSingleObject(drawMutex, INFINITE); + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + color = GetPixel(priv->dcBuffer, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + color = GetPixel(priv->dcBuffer, g->p.y, g->g.Width - 1 - g->p.x); + break; + case GDISP_ROTATE_180: + color = GetPixel(priv->dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y); + break; + case GDISP_ROTATE_270: + color = GetPixel(priv->dcBuffer, g->g.Height - 1 - g->p.y, g->p.x); + break; + } + #else + color = GetPixel(priv->dcBuffer, g->p.x, g->p.y); + #endif + ReleaseMutex(drawMutex); + + // Update the cursor + if (++priv->x > priv->x1) { + priv->x = priv->x0; + if (++priv->y > priv->y1) { + g->flags |= GDISP_FLG_WRAPPED; + priv->y = priv->y0; + } + } + + return BGR2COLOR(color); + } + LLDSPEC void gdisp_lld_read_stop(GDisplay *g) { + if (!(g->flags & GDISP_FLG_WSTREAM)) + BAD_PARAMETER("write_stop: not in streaming mode"); + g->flags &= ~GDISP_FLG_WSTREAM; + } +#endif + #if GDISP_HARDWARE_DRAWPIXEL LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { winPriv * priv; @@ -507,8 +713,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { ReleaseMutex(drawMutex); { RECT r; - r.left = g->p.x; r.right = g->p.x+1; - r.top = g->p.y; r.bottom = g->p.y+1; + r.left = x; r.right = x+1; + r.top = y; r.bottom = y+1; InvalidateRect(priv->hwnd, &r, FALSE); } #else diff --git a/drivers/multiple/Win32/gdisp_lld_config.h b/drivers/multiple/Win32/gdisp_lld_config.h index f6544eb4..e2fc3de4 100644 --- a/drivers/multiple/Win32/gdisp_lld_config.h +++ b/drivers/multiple/Win32/gdisp_lld_config.h @@ -26,12 +26,24 @@ // application to force a display update. eg after streaming. #define GDISP_HARDWARE_FLUSH TRUE -#define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_FILLS TRUE -#define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_CONTROL TRUE -#define GDISP_HARDWARE_BITFILLS TRUE -#define GDISP_HARDWARE_SCROLL TRUE + +//#define GDISP_WIN32_STREAMING_TEST +#ifdef GDISP_WIN32_STREAMING_TEST + // These streaming routines are here only to debug the high level gdisp + // code for streaming controllers. They are slow, inefficient and have + // lots of debugging turned on.
+ #define GDISP_HARDWARE_STREAM_WRITE TRUE + #define GDISP_HARDWARE_STREAM_READ TRUE + #define GDISP_HARDWARE_STREAM_POS TRUE +#else + // The proper way on the Win32. These routines are nice and fast. + #define GDISP_HARDWARE_DRAWPIXEL TRUE + #define GDISP_HARDWARE_FILLS TRUE + #define GDISP_HARDWARE_PIXELREAD TRUE + #define GDISP_HARDWARE_BITFILLS TRUE + #define GDISP_HARDWARE_SCROLL TRUE +#endif #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 |