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 "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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue