Add functions to the Win32 GDISP driver to enable full testing of the streaming driver interface.
This commit is contained in:
parent
825bbf26a1
commit
8c1a37b59e
2 changed files with 250 additions and 32 deletions
|
@ -17,38 +17,15 @@
|
||||||
#include "../drivers/multiple/Win32/gdisp_lld_config.h"
|
#include "../drivers/multiple/Win32/gdisp_lld_config.h"
|
||||||
#include "gdisp/lld/gdisp_lld.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
|
#ifndef GDISP_SCREEN_WIDTH
|
||||||
#define GDISP_SCREEN_WIDTH 640
|
#define GDISP_SCREEN_WIDTH 640
|
||||||
#endif
|
#endif
|
||||||
#ifndef GDISP_SCREEN_HEIGHT
|
#ifndef GDISP_SCREEN_HEIGHT
|
||||||
#define GDISP_SCREEN_HEIGHT 480
|
#define GDISP_SCREEN_HEIGHT 480
|
||||||
#endif
|
#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
|
#if GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888
|
||||||
#error "GDISP Win32: This driver currently only supports the RGB888 pixel format."
|
#error "GDISP Win32: This driver currently only supports the RGB888 pixel format."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GINPUT_NEED_MOUSE
|
|
||||||
/* Include mouse support code */
|
|
||||||
#include "ginput/lld/mouse.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setting this to TRUE delays updating the screen
|
// Setting this to TRUE delays updating the screen
|
||||||
// to the windows paint routine. Due to the
|
// to the windows paint routine. Due to the
|
||||||
// drawing lock this does not add as much speed
|
// drawing lock this does not add as much speed
|
||||||
|
@ -57,18 +34,46 @@
|
||||||
// even draw_pixel().
|
// even draw_pixel().
|
||||||
// This is probably due to drawing operations being
|
// This is probably due to drawing operations being
|
||||||
// combined as the update regions are merged.
|
// 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 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_X_OFFSET 50
|
||||||
#define DISPLAY_Y_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 DWORD winThreadId;
|
||||||
static ATOM winClass;
|
static ATOM winClass;
|
||||||
static volatile bool_t QReady;
|
static volatile bool_t QReady;
|
||||||
static HANDLE drawMutex;
|
static HANDLE drawMutex;
|
||||||
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local routines . */
|
/* Driver local routines . */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -96,6 +101,10 @@ typedef struct winPriv {
|
||||||
#if GINPUT_NEED_TOGGLE
|
#if GINPUT_NEED_TOGGLE
|
||||||
uint8_t toggles;
|
uint8_t toggles;
|
||||||
#endif
|
#endif
|
||||||
|
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
|
||||||
|
coord_t x0, y0, x1, y1;
|
||||||
|
coord_t x, y;
|
||||||
|
#endif
|
||||||
} winPriv;
|
} winPriv;
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,6 +450,10 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
assert(priv != NULL);
|
assert(priv != NULL);
|
||||||
memset(priv, 0, sizeof(winPriv));
|
memset(priv, 0, sizeof(winPriv));
|
||||||
g->priv = priv;
|
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
|
g->board = 0; // no board interface for this controller
|
||||||
|
|
||||||
// Create the window in the message thread
|
// Create the window in the message thread
|
||||||
|
@ -467,6 +480,199 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#if GDISP_HARDWARE_DRAWPIXEL
|
||||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||||
winPriv * priv;
|
winPriv * priv;
|
||||||
|
@ -507,8 +713,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
ReleaseMutex(drawMutex);
|
ReleaseMutex(drawMutex);
|
||||||
{
|
{
|
||||||
RECT r;
|
RECT r;
|
||||||
r.left = g->p.x; r.right = g->p.x+1;
|
r.left = x; r.right = x+1;
|
||||||
r.top = g->p.y; r.bottom = g->p.y+1;
|
r.top = y; r.bottom = y+1;
|
||||||
InvalidateRect(priv->hwnd, &r, FALSE);
|
InvalidateRect(priv->hwnd, &r, FALSE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -26,12 +26,24 @@
|
||||||
// application to force a display update. eg after streaming.
|
// application to force a display update. eg after streaming.
|
||||||
|
|
||||||
#define GDISP_HARDWARE_FLUSH TRUE
|
#define GDISP_HARDWARE_FLUSH TRUE
|
||||||
|
#define GDISP_HARDWARE_CONTROL 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_DRAWPIXEL TRUE
|
||||||
#define GDISP_HARDWARE_FILLS TRUE
|
#define GDISP_HARDWARE_FILLS TRUE
|
||||||
#define GDISP_HARDWARE_PIXELREAD TRUE
|
#define GDISP_HARDWARE_PIXELREAD TRUE
|
||||||
#define GDISP_HARDWARE_CONTROL TRUE
|
|
||||||
#define GDISP_HARDWARE_BITFILLS TRUE
|
#define GDISP_HARDWARE_BITFILLS TRUE
|
||||||
#define GDISP_HARDWARE_SCROLL TRUE
|
#define GDISP_HARDWARE_SCROLL TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
|
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue