Fixes to gdisp Win32 driver

Fixes to gdisp Win32 driver. This is now fully operational.
ugfx_release_2.6
Andrew Hannam 2012-10-28 16:24:13 +10:00
parent c5f9012fd6
commit 9fcff16f7e
2 changed files with 101 additions and 66 deletions

View File

@ -2,14 +2,14 @@
ChibiOS/RT - Copyright (C) 2012 ChibiOS/RT - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS-LCD-Driver. This file is part of ChibiOS/GFX.
ChibiOS-LCD-Driver is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS-LCD-Driver is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
@ -55,9 +55,9 @@ static HWND winRootWindow = NULL;
static HDC dcBuffer = NULL; static HDC dcBuffer = NULL;
static HBITMAP dcBitmap = NULL; static HBITMAP dcBitmap = NULL;
static HBITMAP dcOldBitmap; static HBITMAP dcOldBitmap;
static volatile bool_t isReady = FALSE;
static LRESULT static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{ {
HDC dc; HDC dc;
PAINTSTRUCT ps; PAINTSTRUCT ps;
@ -107,42 +107,15 @@ myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
/*===========================================================================*/ static DWORD WINAPI WindowThread(LPVOID lpParameter) {
/* Driver exported functions. */ (void)lpParameter;
/*===========================================================================*/
MSG msg;
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialisation.
* @return TRUE if successful, FALSE on error.
*
* @notapi
*/
bool_t GDISP_LLD(init)(void) {
/* Initialise the window */
HANDLE hInstance; HANDLE hInstance;
HDC rootDC;
int depth;
RECT rect;
PSUBDRIVER subdriver;
WNDCLASS wc; WNDCLASS wc;
RECT rect;
hInstance = GetModuleHandle(NULL); hInstance = GetModuleHandle(NULL);
rootDC = CreateDC("DISPLAY", NULL, NULL, NULL);
depth = GetDeviceCaps(rootDC, BITSPIXEL);
DeleteDC(rootDC);
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;
wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC; wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)myWindowProc; wc.lpfnWndProc = (WNDPROC)myWindowProc;
@ -167,11 +140,54 @@ bool_t GDISP_LLD(init)(void) {
dcBuffer = CreateCompatibleDC(dc); dcBuffer = CreateCompatibleDC(dc);
dcOldBitmap = SelectObject(dcBuffer, dcBitmap); dcOldBitmap = SelectObject(dcBuffer, dcBitmap);
ReleaseDC(winRootWindow, dc); ReleaseDC(winRootWindow, dc);
ShowWindow(winRootWindow, SW_SHOW); ShowWindow(winRootWindow, SW_SHOW);
UpdateWindow(winRootWindow); UpdateWindow(winRootWindow);
isReady = TRUE;
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ExitProcess(0);
return msg.wParam;
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialisation.
* @return TRUE if successful, FALSE on error.
*
* @notapi
*/
bool_t GDISP_LLD(init)(void) {
RECT rect;
/* 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;
/* Initialise the window */
CreateThread(0, 0, WindowThread, 0, 0, 0);
while (!isReady)
Sleep(1);
/* Initialise the GDISP structure to match */ /* Initialise the GDISP structure to match */
GDISP.Orientation = GDISP.Width > GDISP.Height ? landscape : portrait; GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn; GDISP.Powermode = powerOn;
GDISP.Backlight = 100; GDISP.Backlight = 100;
GDISP.Contrast = 50; GDISP.Contrast = 50;
@ -200,11 +216,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
#endif #endif
// Draw the pixel in the buffer
color = COLOR2BGR(color); color = COLOR2BGR(color);
SetPixel(dcBuffer, x, y, color);
// Draw the pixel again directly on the screen.
// This is cheaper than invalidating a single pixel in the window
dc = GetDC(winRootWindow); dc = GetDC(winRootWindow);
SetPixel(dc, x, y, color); SetPixel(dc, x, y, color);
ReleaseDC(winRootWindow, dc); ReleaseDC(winRootWindow, dc);
SetPixel(dcBuffer, x, y, color);
} }
/* ---- Optional Routines ---- */ /* ---- Optional Routines ---- */
@ -234,8 +254,22 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#endif #endif
color = COLOR2BGR(color); color = COLOR2BGR(color);
pen = CreatePen(PS_SOLID, 1, c); pen = CreatePen(PS_SOLID, 1, color);
if (pen) { if (pen) {
// Draw the line in the buffer
#if GDISP_NEED_CLIP
if (clip) SelectClipRgn(dcBuffer, clip);
#endif
old = SelectObject(dcBuffer, pen);
MoveToEx(dcBuffer, x0, y0, &p);
LineTo(dcBuffer, x1, y1);
SelectObject(dcBuffer, old);
SetPixel(dcBuffer, x1, y1, color);
#if GDISP_NEED_CLIP
if (clip) SelectClipRgn(dcBuffer, NULL);
#endif
// Redrawing the line on the screen is cheaper than invalidating the whole rectangular area
dc = GetDC(winRootWindow); dc = GetDC(winRootWindow);
#if GDISP_NEED_CLIP #if GDISP_NEED_CLIP
if (clip) SelectClipRgn(dc, clip); if (clip) SelectClipRgn(dc, clip);
@ -250,18 +284,6 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#endif #endif
ReleaseDC(winRootWindow, dc); ReleaseDC(winRootWindow, dc);
#if GDISP_NEED_CLIP
if (clip) SelectClipRgn(dcBuffer, clip);
#endif
old = SelectObject(dcBuffer, pen);
MoveToEx(dcBuffer, x0, y0, &p);
LineTo(dcBuffer, x1, y1);
SelectObject(dcBuffer, old);
SetPixel(dcBuffer, x1, y1, color);
#if GDISP_NEED_CLIP
if (clip) SelectClipRgn(dcBuffer, NULL);
#endif
DeleteObject(pen); DeleteObject(pen);
} }
} }
@ -279,8 +301,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @notapi * @notapi
*/ */
void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
RECT rect;
HDC dc; HDC dc;
RECT rect;
HBRUSH hbr; HBRUSH hbr;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
@ -295,14 +317,19 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
hbr = CreateSolidBrush(color); hbr = CreateSolidBrush(color);
if (hbr) { if (hbr) {
rect.bottom = y+cy-1; rect.bottom = y+cy;
rect.top = y; rect.top = y;
rect.left = x; rect.left = x;
rect.right = x+cx-1; rect.right = x+cx;
// Fill the area
FillRect(dcBuffer, &rect, hbr);
// Filling the area directly on the screen is likely to be cheaper than invalidating it
dc = GetDC(winRootWindow); dc = GetDC(winRootWindow);
FillRect(dc, &rect, hbr); FillRect(dc, &rect, hbr);
ReleaseDC(winRootWindow, dc); ReleaseDC(winRootWindow, dc);
FillRect(dcBuffer, &rect, hbr);
DeleteObject(hbr); DeleteObject(hbr);
} }
} }
@ -322,8 +349,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @notapi * @notapi
*/ */
void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
HDC dc;
BITMAPV4HEADER bmpInfo; BITMAPV4HEADER bmpInfo;
RECT rect;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
@ -334,14 +361,13 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif #endif
dc = GetDC(winRootWindow);
memset(&bmpInfo, 0, sizeof(bmpInfo)); memset(&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bV4Size = sizeof(bmpInfo); bmpInfo.bV4Size = sizeof(bmpInfo);
bmpInfo.bV4Width = srccx; bmpInfo.bV4Width = srccx;
bmpInfo.bV4Height = -(srcy+cy); /* top-down image */ bmpInfo.bV4Height = -(srcy+cy); /* top-down image */
bmpInfo.bV4Planes = 1; bmpInfo.bV4Planes = 1;
bmpInfo.bV4BitCount = BITSPERPIXEL; bmpInfo.bV4BitCount = 32;
bmpInfo.bV4SizeImage = ((srcy+cy)*srccx * BITSPERPIXEL)/8; bmpInfo.bV4SizeImage = ((srcy+cy)*srccx * 32)/8;
bmpInfo.bV4AlphaMask = 0; bmpInfo.bV4AlphaMask = 0;
bmpInfo.bV4RedMask = RGB2COLOR(255,0,0); bmpInfo.bV4RedMask = RGB2COLOR(255,0,0);
bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0); bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0);
@ -351,13 +377,18 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
bmpInfo.bV4YPelsPerMeter = 3078; bmpInfo.bV4YPelsPerMeter = 3078;
bmpInfo.bV4ClrUsed = 0; bmpInfo.bV4ClrUsed = 0;
bmpInfo.bV4ClrImportant = 0; bmpInfo.bV4ClrImportant = 0;
bmpInfo.bV4CSType = LCS_sRGB; bmpInfo.bV4CSType = 0; //LCS_sRGB;
SetDIBitsToDevice(dc, x, y, cx, cy, srcx, srcy, 0, cy+srcy, buffer, // Draw the bitmap
(BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, srcy, 0, cy+srcy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, srcy, 0, cy+srcy, buffer,
(BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); // Invalidate the region to get it on the screen.
ReleaseDC(winRootWindow, dc); rect.bottom = y+cy;
rect.top = y;
rect.left = x;
rect.right = x+cx;
InvalidateRect(winRootWindow, &rect, FALSE);
UpdateWindow(winRootWindow);
} }
#endif #endif

View File

@ -11,3 +11,7 @@ To use this driver:
2. To your makefile add the following lines: 2. To your makefile add the following lines:
include $(GFXLIB)/gfx.mk include $(GFXLIB)/gfx.mk
include $(GFXLIB)/drivers/gdisp/Win32/gdisp_lld.mk include $(GFXLIB)/drivers/gdisp/Win32/gdisp_lld.mk
3. Modify your makefile to add -lgdi32 to the DLIBS line. i.e.
DLIBS = -lws2_32 -lgdi32