aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/multiple
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-10-24 11:30:17 +1000
committerinmarket <andrewh@inmarket.com.au>2013-10-24 11:30:17 +1000
commit8c1a37b59eef97c1e713a4ae24459f3af82b65f2 (patch)
treedb8da813ec46a54ffda9c8559757a5f5a1b2f1ab /drivers/multiple
parent825bbf26a1bf11d7148a16229f6515fae5efb276 (diff)
downloaduGFX-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.c260
-rw-r--r--drivers/multiple/Win32/gdisp_lld_config.h22
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