aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/multiple/Win32/gdisp_lld.c739
-rw-r--r--drivers/multiple/Win32/gdisp_lld_config.h7
-rw-r--r--drivers/multiple/Win32/ginput_lld_toggle_config.h15
-rw-r--r--drivers/multiple/X/gdisp_lld_config.h9
-rw-r--r--gfxconf.example.h23
-rw-r--r--include/gdisp/gdisp.h343
-rw-r--r--include/gdisp/lld/gdisp_lld.h319
-rw-r--r--include/gdisp/options.h57
-rw-r--r--include/gfx_rules.h8
-rw-r--r--src/gdisp/gdisp.c1773
-rw-r--r--src/gfx.c1
11 files changed, 1864 insertions, 1430 deletions
diff --git a/drivers/multiple/Win32/gdisp_lld.c b/drivers/multiple/Win32/gdisp_lld.c
index 41141a90..65627e1c 100644
--- a/drivers/multiple/Win32/gdisp_lld.c
+++ b/drivers/multiple/Win32/gdisp_lld.c
@@ -9,12 +9,11 @@
* @file drivers/multiple/Win32/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for Win32.
*/
-
#include "gfx.h"
#if GFX_USE_GDISP
-#define GDISP_LLD_DECLARATIONS
+#define GDISP_DRIVER_VMT GDISPVMT_Win32
#include "gdisp/lld/gdisp_lld.h"
#include <stdio.h>
@@ -31,51 +30,80 @@
#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
+// as might be expected but it is still faster in
+// all tested circumstances and for all operations
+// even draw_pixel().
+// This is probably due to drawing operations being
+// combined as the update regions are merged.
+#define GDISP_WIN32_USE_INDIRECT_UPDATE TRUE
+
+// How far extra windows should be offset from the first.
+#define DISPLAY_X_OFFSET 50
+#define DISPLAY_Y_OFFSET 50
+
+static DWORD winThreadId;
+static ATOM winClass;
+static volatile bool_t QReady;
+static HANDLE drawMutex;
+
+
/*===========================================================================*/
/* Driver local routines . */
/*===========================================================================*/
-#define WIN32_USE_MSG_REDRAW FALSE
#if GINPUT_NEED_TOGGLE
#define WIN32_BUTTON_AREA 16
#else
#define WIN32_BUTTON_AREA 0
#endif
-#define APP_NAME "GDISP"
+#define APP_NAME "uGFX"
#define COLOR2BGR(c) ((((c) & 0xFF)<<16)|((c) & 0xFF00)|(((c)>>16) & 0xFF))
#define BGR2COLOR(c) COLOR2BGR(c)
-static HWND winRootWindow = NULL;
-static HDC dcBuffer = NULL;
-static HBITMAP dcBitmap = NULL;
-static HBITMAP dcOldBitmap;
-static volatile bool_t isReady = FALSE;
-static coord_t wWidth, wHeight;
+typedef struct winPriv {
+ HWND hwnd;
+ HDC dcBuffer;
+ HBITMAP dcBitmap;
+ HBITMAP dcOldBitmap;
+ #if GINPUT_NEED_MOUSE
+ coord_t mousex, mousey;
+ uint16_t mousebuttons;
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ uint8_t toggles;
+ #endif
+} winPriv;
-#if GINPUT_NEED_MOUSE
- static coord_t mousex, mousey;
- static uint16_t mousebuttons;
-#endif
-#if GINPUT_NEED_TOGGLE
- static uint8_t toggles = 0;
-#endif
static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- HDC dc;
- PAINTSTRUCT ps;
+ HDC dc;
+ PAINTSTRUCT ps;
+ GDisplay * g;
+ winPriv * priv;
#if GINPUT_NEED_TOGGLE
HBRUSH hbrOn, hbrOff;
HPEN pen;
@@ -88,86 +116,135 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
switch (Msg) {
case WM_CREATE:
+ // Get our GDisplay structure and attach it to the window
+ g = (GDisplay *)((LPCREATESTRUCT)lParam)->lpCreateParams;
+ priv = (winPriv *)g->priv;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)g);
+
+ // Fill in the private area
+ priv->hwnd = hWnd;
+ dc = GetDC(hWnd);
+ priv->dcBitmap = CreateCompatibleBitmap(dc, g->g.Width, g->g.Height);
+ priv->dcBuffer = CreateCompatibleDC(dc);
+ ReleaseDC(hWnd, dc);
+ priv->dcOldBitmap = SelectObject(priv->dcBuffer, priv->dcBitmap);
+
+ // Mark the window as ready to go
+ g->flags |= GDISP_FLG_READY;
break;
- case WM_LBUTTONDOWN:
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
+
+ #if GINPUT_NEED_MOUSE || GINPUT_NEED_TOGGLE
+ case WM_LBUTTONDOWN:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Handle mouse down on the window
+ #if GINPUT_NEED_MOUSE
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
+ goto mousemove;
+ }
+ #endif
+
+ // Handle mouse down on the toggle area
+ #if GINPUT_NEED_TOGGLE
+ if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
+ bit = 1 << ((coord_t)LOWORD(lParam)*8/g->g.Width);
+ priv->toggles ^= bit;
+ rect.left = 0;
+ rect.right = GDISP_SCREEN_WIDTH;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ InvalidateRect(hWnd, &rect, FALSE);
+ UpdateWindow(hWnd);
+ #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
+ ginputToggleWakeup();
+ #endif
+ }
+ #endif
+ break;
+
+ case WM_LBUTTONUP:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Handle mouse up on the toggle area
+ #if GINPUT_NEED_TOGGLE
+ if ((g->flags & GDISP_FLG_HASTOGGLE)) {
+ if ((priv->toggles & 0x0F)) {
+ priv->toggles &= ~0x0F;
+ rect.left = 0;
+ rect.right = GDISP_SCREEN_WIDTH;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ InvalidateRect(hWnd, &rect, FALSE);
+ UpdateWindow(hWnd);
+ #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
+ ginputToggleWakeup();
+ #endif
+ }
+ }
+ #endif
+
+ // Handle mouse up on the window
+ #if GINPUT_NEED_MOUSE
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
+ goto mousemove;
+ }
+ #endif
+ break;
+ #endif
+
+ #if GINPUT_NEED_MOUSE
+ case WM_MBUTTONDOWN:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
goto mousemove;
}
- #endif
- #if GINPUT_NEED_TOGGLE
- bit = 1 << ((coord_t)LOWORD(lParam)*8/wWidth);
- toggles ^= bit;
- rect.left = 0;
- rect.right = wWidth;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
- #endif
- break;
- case WM_LBUTTONUP:
- #if GINPUT_NEED_TOGGLE
- if ((toggles & 0x0F)) {
- toggles &= ~0x0F;
- rect.left = 0;
- rect.right = wWidth;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
+ break;
+ case WM_MBUTTONUP:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
+ goto mousemove;
}
- #endif
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
+ break;
+ case WM_RBUTTONDOWN:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
goto mousemove;
}
- #endif
- break;
-#if GINPUT_NEED_MOUSE
- case WM_MBUTTONDOWN:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_MBUTTONUP:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_RBUTTONDOWN:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_RBUTTONUP:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_MOUSEMOVE:
- if ((coord_t)HIWORD(lParam) >= wHeight)
break;
- mousemove:
- mousex = (coord_t)LOWORD(lParam);
- mousey = (coord_t)HIWORD(lParam);
- #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
- ginputMouseWakeup();
- #endif
- break;
-#endif
+ case WM_RBUTTONUP:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
+ goto mousemove;
+ }
+ break;
+ case WM_MOUSEMOVE:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT || !(g->flags & GDISP_FLG_HASMOUSE))
+ break;
+ mousemove:
+ priv->mousex = (coord_t)LOWORD(lParam);
+ priv->mousey = (coord_t)HIWORD(lParam);
+ #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
+ ginputMouseWakeup();
+ #endif
+ break;
+ #endif
+
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
case WM_SYSKEYUP:
@@ -178,26 +255,41 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
break;
+
+ case WM_ERASEBKGND:
+ // Pretend we have erased the background.
+ // We know we don't really need to do this as we
+ // redraw the entire surface in the WM_PAINT handler.
+ return TRUE;
+
case WM_PAINT:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Paint the main window area
+ WaitForSingleObject(drawMutex, INFINITE);
dc = BeginPaint(hWnd, &ps);
BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
- (ps.rcPaint.bottom > wHeight ? wHeight : ps.rcPaint.bottom) - ps.rcPaint.top,
- dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
+ (ps.rcPaint.bottom > GDISP_SCREEN_HEIGHT ? GDISP_SCREEN_HEIGHT : ps.rcPaint.bottom) - ps.rcPaint.top,
+ priv->dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
+
+ // Paint the toggle area
#if GINPUT_NEED_TOGGLE
- if (ps.rcPaint.bottom >= wHeight) {
+ if (ps.rcPaint.bottom >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
pen = CreatePen(PS_SOLID, 1, COLOR2BGR(Black));
hbrOn = CreateSolidBrush(COLOR2BGR(Blue));
hbrOff = CreateSolidBrush(COLOR2BGR(Gray));
old = SelectObject(dc, pen);
- MoveToEx(dc, 0, wHeight, &p);
- LineTo(dc, wWidth, wHeight);
+ MoveToEx(dc, 0, GDISP_SCREEN_HEIGHT, &p);
+ LineTo(dc, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
rect.left = pos;
- rect.right = pos + wWidth/8;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- FillRect(dc, &rect, (toggles & bit) ? hbrOn : hbrOff);
+ rect.right = pos + GDISP_SCREEN_WIDTH/8;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ FillRect(dc, &rect, (priv->toggles & bit) ? hbrOn : hbrOff);
if (pos > 0) {
MoveToEx(dc, rect.left, rect.top, &p);
LineTo(dc, rect.left, rect.bottom);
@@ -209,74 +301,75 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
}
#endif
EndPaint(hWnd, &ps);
+ ReleaseMutex(drawMutex);
break;
+
case WM_DESTROY:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Restore the window and free our bitmaps
+ SelectObject(priv->dcBuffer, priv->dcOldBitmap);
+ DeleteDC(priv->dcBuffer);
+ DeleteObject(priv->dcBitmap);
+
+ // Cleanup the private area
+ gfxFree(priv);
+
+ // Quit the application
PostQuitMessage(0);
- SelectObject(dcBuffer, dcOldBitmap);
- DeleteDC(dcBuffer);
- DeleteObject(dcBitmap);
- winRootWindow = NULL;
+
+ // Actually the above doesn't work (who knows why)
+ ExitProcess(0);
break;
+
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
-static void InitWindow(void) {
- HANDLE hInstance;
- WNDCLASS wc;
- RECT rect;
- HDC dc;
-
- hInstance = GetModuleHandle(NULL);
-
- wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
- wc.lpfnWndProc = (WNDPROC)myWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = APP_NAME;
- RegisterClass(&wc);
-
- rect.top = 0; rect.bottom = wHeight+WIN32_BUTTON_AREA;
- rect.left = 0; rect.right = wWidth;
- AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
- winRootWindow = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0, 0,
- rect.right-rect.left, rect.bottom-rect.top, 0, 0, hInstance, NULL);
- assert(winRootWindow != NULL);
-
-
- GetClientRect(winRootWindow, &rect);
- wWidth = rect.right-rect.left;
- wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
-
- dc = GetDC(winRootWindow);
- dcBitmap = CreateCompatibleBitmap(dc, wWidth, wHeight);
- dcBuffer = CreateCompatibleDC(dc);
- ReleaseDC(winRootWindow, dc);
- dcOldBitmap = SelectObject(dcBuffer, dcBitmap);
-
- ShowWindow(winRootWindow, SW_SHOW);
- UpdateWindow(winRootWindow);
- isReady = TRUE;
-}
-
static DECLARE_THREAD_STACK(waWindowThread, 1024);
static DECLARE_THREAD_FUNCTION(WindowThread, param) {
(void)param;
MSG msg;
- InitWindow();
+ // Establish this thread as a message queue thread
+ winThreadId = GetCurrentThreadId();
+ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+ QReady = TRUE;
+
do {
gfxSleepMilliseconds(1);
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+ // Is this our special thread message to create a new window?
+ if (!msg.hwnd && msg.message == WM_USER) {
+ RECT rect;
+ GDisplay *g;
+
+ g = (GDisplay *)msg.lParam;
+
+ // Set the window rectangle
+ rect.top = 0; rect.bottom = g->g.Height;
+ rect.left = 0; rect.right = g->g.Width;
+ #if GINPUT_NEED_TOGGLE
+ if ((g->flags & GDISP_FLG_HASTOGGLE))
+ rect.bottom += WIN32_BUTTON_AREA;
+ #endif
+ AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
+
+ // Create the window
+ msg.hwnd = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER, msg.wParam*DISPLAY_X_OFFSET, msg.wParam*DISPLAY_Y_OFFSET,
+ rect.right-rect.left, rect.bottom-rect.top, 0, 0,
+ GetModuleHandle(NULL), g);
+ assert(msg.hwnd != NULL);
+
+ // Or just a normal window message
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
}
} while (msg.message != WM_QUIT);
ExitProcess(0);
@@ -287,44 +380,89 @@ static DECLARE_THREAD_FUNCTION(WindowThread, param) {
/* Driver exported functions. */
/*===========================================================================*/
-LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
- RECT rect;
- gfxThreadHandle hth;
-
- /* Set the window dimensions */
- GetWindowRect(GetDesktopWindow(), &rect);
- wWidth = rect.right - rect.left;
- wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
- if (wWidth > GDISP_SCREEN_WIDTH)
- wWidth = GDISP_SCREEN_WIDTH;
- if (wHeight > GDISP_SCREEN_HEIGHT)
- wHeight = GDISP_SCREEN_HEIGHT;
-
- /* Initialise the window */
- if (!(hth = gfxThreadCreate(waWindowThread, sizeof(waWindowThread), HIGH_PRIORITY, WindowThread, 0))) {
- fprintf(stderr, "Cannot create window thread\n");
- exit(-1);
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g, unsigned display) {
+ winPriv * priv;
+ char buf[132];
+
+ // Initialise the window thread and the window class (if it hasn't been done already)
+ if (!QReady) {
+ gfxThreadHandle hth;
+ WNDCLASS wc;
+
+ // Create the draw mutex
+ drawMutex = CreateMutex(NULL, FALSE, NULL);
+
+ // Create the thread
+ hth = gfxThreadCreate(waWindowThread, sizeof(waWindowThread), HIGH_PRIORITY, WindowThread, 0);
+ assert(hth != NULL);
+ gfxThreadClose(hth);
+
+ wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC)myWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = APP_NAME;
+ winClass = RegisterClass(&wc);
+ assert(winClass != 0);
+
+ // Wait for our thread to be ready
+ while (!QReady)
+ Sleep(1);
}
- gfxThreadClose(hth);
- while (!isReady)
- Sleep(1);
- /* Initialise the GDISP structure to match */
+ // Initialise the GDISP structure
g->g.Orientation = GDISP_ROTATE_0;
g->g.Powermode = powerOn;
g->g.Backlight = 100;
g->g.Contrast = 50;
- g->g.Width = wWidth;
- g->g.Height = wHeight;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+
+ // Turn on toggles for the first GINPUT_TOGGLE_CONFIG_ENTRIES windows
+ #if GINPUT_NEED_TOGGLE
+ if (display < GINPUT_TOGGLE_CONFIG_ENTRIES)
+ g->flags |= GDISP_FLG_HASTOGGLE;
+ #endif
+
+ // Only turn on mouse on the first window for now
+ #if GINPUT_NEED_MOUSE
+ if (!display)
+ g->flags |= GDISP_FLG_HASMOUSE;
+ #endif
+
+ // Create a private area for this window
+ priv = (winPriv *)gfxAlloc(sizeof(winPriv));
+ assert(priv != NULL);
+ memset(priv, 0, sizeof(winPriv));
+ g->priv = priv;
+
+ // Create the window in the message thread
+ PostThreadMessage(winThreadId, WM_USER, (WPARAM)display, (LPARAM)g);
+
+ // Wait for the window creation to complete (for safety)
+ while(!(((volatile GDisplay *)g)->flags & GDISP_FLG_READY))
+ Sleep(1);
+
+ sprintf(buf, APP_NAME " - %u", display+1);
+ SetWindowText(priv->hwnd, buf);
+ ShowWindow(priv->hwnd, SW_SHOW);
+ UpdateWindow(priv->hwnd);
+
return TRUE;
}
#if GDISP_HARDWARE_DRAWPIXEL
- LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g) {
- HDC dcScreen;
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
+ winPriv * priv;
int x, y;
COLORREF color;
+ priv = g->priv;
color = COLOR2BGR(g->p.color);
#if GDISP_NEED_CONTROL
@@ -352,23 +490,41 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
#endif
// Draw the pixel on the screen and in the buffer.
- dcScreen = GetDC(winRootWindow);
- SetPixel(dcScreen, x, y, color);
- SetPixel(dcBuffer, x, y, color);
- ReleaseDC(winRootWindow, dcScreen);
+ WaitForSingleObject(drawMutex, INFINITE);
+ SetPixel(priv->dcBuffer, x, y, color);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ 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;
+ InvalidateRect(priv->hwnd, &r, FALSE);
+ }
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ SetPixel(dc, x, y, color);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
}
#endif
/* ---- Optional Routines ---- */
#if GDISP_HARDWARE_FILLS
- LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g) {
- HDC dcScreen;
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
+ winPriv * priv;
RECT rect;
HBRUSH hbr;
COLORREF color;
+ priv = g->priv;
color = COLOR2BGR(g->p.color);
+ hbr = CreateSolidBrush(color);
+
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
@@ -403,29 +559,34 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.right = rect.left + g->p.cx;
#endif
- hbr = CreateSolidBrush(color);
- dcScreen = GetDC(winRootWindow);
- FillRect(dcScreen, &rect, hbr);
- FillRect(dcBuffer, &rect, hbr);
- ReleaseDC(winRootWindow, dcScreen);
+ WaitForSingleObject(drawMutex, INFINITE);
+ FillRect(priv->dcBuffer, &rect, hbr);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ FillRect(dc, &rect, hbr);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
DeleteObject(hbr);
}
#endif
#if GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL
- static pixel_t *rotateimg(GDISPDriver *g, const pixel_t *buffer) {
+ static pixel_t *rotateimg(GDisplay *g, const pixel_t *buffer) {
pixel_t *dstbuf;
pixel_t *dst;
const pixel_t *src;
size_t sz;
coord_t i, j;
- // Shortcut.
- if (g->g.Orientation == GDISP_ROTATE_0 && g->p.x1 == 0 && g->p.cx == g->p.x2)
- return (pixel_t *)buffer;
-
// Allocate the destination buffer
sz = (size_t)g->p.cx * (size_t)g->p.cy;
if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
@@ -433,11 +594,6 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
// Copy the bits we need
switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- for(dst = dstbuf, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx)
- for(i = 0; i < g->p.cx; i++)
- *dst++ = *src++;
- break;
case GDISP_ROTATE_90:
for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
dst = dstbuf+sz-g->p.cy+j;
@@ -463,16 +619,14 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
#endif
#if GDISP_HARDWARE_BITFILLS
- LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g) {
- BITMAPV4HEADER bmpInfo;
- HDC dcScreen;
- pixel_t * buffer;
- #if GDISP_NEED_CONTROL
- RECT rect;
- pixel_t * srcimg;
- #endif
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
+ winPriv * priv;
+ pixel_t * buffer;
+ RECT rect;
+ BITMAPV4HEADER bmpInfo;
// Make everything relative to the start of the line
+ priv = g->priv;
buffer = g->p.ptr;
buffer += g->p.x2*g->p.y1;
@@ -492,13 +646,10 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
bmpInfo.bV4CSType = 0; //LCS_sRGB;
#if GDISP_NEED_CONTROL
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
- srcimg = rotateimg(g, buffer);
- if (!srcimg) return;
-
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
- bmpInfo.bV4Width = g->p.cx;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.x2;
bmpInfo.bV4Height = -g->p.cy; /* top-down image */
rect.top = g->p.y;
rect.bottom = rect.top+g->p.cy;
@@ -506,6 +657,8 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.right = rect.left+g->p.cx;
break;
case GDISP_ROTATE_90:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
bmpInfo.bV4Width = g->p.cy;
bmpInfo.bV4Height = -g->p.cx; /* top-down image */
rect.bottom = g->g.Width - g->p.x;
@@ -514,6 +667,8 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.right = rect.left+g->p.cy;
break;
case GDISP_ROTATE_180:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
bmpInfo.bV4Width = g->p.cx;
bmpInfo.bV4Height = -g->p.cy; /* top-down image */
rect.bottom = g->g.Height-1 - g->p.y;
@@ -522,6 +677,8 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.left = rect.right-g->p.cx;
break;
case GDISP_ROTATE_270:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
bmpInfo.bV4Width = g->p.cy;
bmpInfo.bV4Height = -g->p.cx; /* top-down image */
rect.top = g->p.x;
@@ -530,58 +687,78 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.left = rect.right-g->p.cy;
break;
}
- dcScreen = GetDC(winRootWindow);
- SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- SetDIBitsToDevice(dcScreen, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- ReleaseDC(winRootWindow, dcScreen);
- if (srcimg != buffer)
- free(srcimg);
-
#else
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
bmpInfo.bV4Width = g->p.x2;
bmpInfo.bV4Height = -g->p.cy; /* top-down image */
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
- dcScreen = GetDC(winRootWindow);
- SetDIBitsToDevice(dcBuffer, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- SetDIBitsToDevice(dcScreen, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- ReleaseDC(winRootWindow, dcScreen);
+ rect.top = g->p.y;
+ rect.bottom = rect.top+g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left+g->p.cx;
+ #endif
+
+ WaitForSingleObject(drawMutex, INFINITE);
+ SetDIBitsToDevice(priv->dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ SetDIBitsToDevice(dc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+
+ #if GDISP_NEED_CONTROL
+ if (buffer != (pixel_t *)g->p.ptr)
+ free(srcimg);
#endif
}
#endif
#if GDISP_HARDWARE_PIXELREAD
- LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g) {
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ winPriv * priv;
COLORREF color;
+ priv = g->priv;
+
+ WaitForSingleObject(drawMutex, INFINITE);
#if GDISP_NEED_CONTROL
switch(g->g.Orientation) {
case GDISP_ROTATE_0:
- color = GetPixel(dcBuffer, g->p.x, g->p.y);
+ color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
break;
case GDISP_ROTATE_90:
- color = GetPixel(dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
+ color = GetPixel(priv->dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
break;
case GDISP_ROTATE_180:
- color = GetPixel(dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y);
+ 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(dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
+ color = GetPixel(priv->dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
break;
}
#else
- color = GetPixel(dcBuffer, g->p.x, g->p.y);
+ color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
#endif
+ ReleaseMutex(drawMutex);
return BGR2COLOR(color);
}
#endif
#if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
- LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g) {
- HDC dcScreen;
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
+ winPriv * priv;
RECT rect;
coord_t lines;
+ priv = g->priv;
+
#if GDISP_NEED_CONTROL
switch(GC->g.Orientation) {
case GDISP_ROTATE_0:
@@ -611,10 +788,20 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.top -= lines;
}
if (g->p.cy >= lines && g->p.cy >= -lines) {
- dcScreen = GetDC(winRootWindow);
- ScrollDC(dcBuffer, 0, lines, &rect, 0, 0, 0);
- ScrollDC(dcScreen, 0, lines, &rect, 0, 0, 0);
- ReleaseDC(winRootWindow, dcScreen);
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
}
break;
case GDISP_ROTATE_270:
@@ -630,10 +817,20 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.left -= lines;
}
if (g->p.cy >= lines && g->p.cy >= -lines) {
- dcScreen = GetDC(winRootWindow);
- ScrollDC(dcBuffer, lines, 0, &rect, 0, 0, 0);
- ScrollDC(dcScreen, lines, 0, &rect, 0, 0, 0);
- ReleaseDC(winRootWindow, dcScreen);
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, lines, 0, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, lines, 0, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
}
break;
}
@@ -649,17 +846,27 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.top -= lines;
}
if (g->p.cy >= lines && g->p.cy >= -lines) {
- dcScreen = GetDC(winRootWindow);
- ScrollDC(dcBuffer, 0, lines, &rect, 0, 0, 0);
- ScrollDC(dcScreen, 0, lines, &rect, 0, 0, 0);
- ReleaseDC(winRootWindow, dcScreen);
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
}
#endif
}
#endif
#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
- LLDSPEC void gdisp_lld_control(GDISPDriver *g) {
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
switch(g->p.x) {
case GDISP_CONTROL_ORIENTATION:
if (g->g.Orientation == (orientation_t)g->p.ptr)
@@ -667,13 +874,13 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
switch((orientation_t)g->p.ptr) {
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
- g->g.Width = wWidth;
- g->g.Height = wHeight;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270:
- g->g.Height = wWidth;
- g->g.Width = wHeight;
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
@@ -692,20 +899,38 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
#if GINPUT_NEED_MOUSE
void ginput_lld_mouse_init(void) {}
void ginput_lld_mouse_get_reading(MouseReading *pt) {
- pt->x = mousex;
- pt->y = mousey > wHeight ? wHeight : mousey;
- pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
- pt->buttons = mousebuttons;
+ GDisplay *g;
+
+ g = GDISP_WIN32;
+ pt->x = g->priv->mousex;
+ pt->y = g->priv->mousey > g->g.Height ? g->g.Height : mousey;
+ pt->z = (g->priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
+ pt->buttons = g->priv->mousebuttons;
}
#endif /* GINPUT_NEED_MOUSE */
#if GINPUT_NEED_TOGGLE
- const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = {
- {0, 0xFF, 0x00, 0},
- };
- void ginput_lld_toggle_init(const GToggleConfig *ptc) { (void) ptc; }
- unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) { (void) ptc; return toggles; }
-#endif /* GINPUT_NEED_MOUSE */
+ #if GINPUT_TOGGLE_CONFIG_ENTRIES > GDISP_DRIVER_COUNT_WIN32
+ #error "GDISP Win32: GINPUT_TOGGLE_CONFIG_ENTRIES must not be greater than GDISP_DRIVER_COUNT_WIN32"
+ #endif
+
+ GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
+
+ void ginput_lld_toggle_init(const GToggleConfig *ptc) {
+ // Save the associated window struct
+ ptc->id = &GDISP_WIN32[ptc - GInputToggleConfigTable];
+
+ // We have 8 buttons per window.
+ ptc->mask = 0xFF;
+
+ // No inverse or special mode
+ ptc->invert = 0x00;
+ ptc->mode = 0;
+ }
+ unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) {
+ return ((GDisplay *)(ptc->id))->priv->toggles;
+ }
+#endif /* GINPUT_NEED_TOGGLE */
#endif /* GFX_USE_GDISP */
diff --git a/drivers/multiple/Win32/gdisp_lld_config.h b/drivers/multiple/Win32/gdisp_lld_config.h
index b8a030ef..5720eaed 100644
--- a/drivers/multiple/Win32/gdisp_lld_config.h
+++ b/drivers/multiple/Win32/gdisp_lld_config.h
@@ -16,15 +16,12 @@
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
+#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "Win32"
-#define GDISP_DRIVER_STRUCT GDISP_Win32
-
#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
@@ -32,7 +29,7 @@
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
#endif /* GFX_USE_GDISP */
diff --git a/drivers/multiple/Win32/ginput_lld_toggle_config.h b/drivers/multiple/Win32/ginput_lld_toggle_config.h
index 2e61d073..dd0c9b5c 100644
--- a/drivers/multiple/Win32/ginput_lld_toggle_config.h
+++ b/drivers/multiple/Win32/ginput_lld_toggle_config.h
@@ -20,9 +20,16 @@
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
-#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - ether works here)
-#define GINPUT_TOGGLE_NUM_PORTS 8 // The total number of toggle inputs
-#define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
+#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - either works here)
+
+// This driver is unique in that it can support 8 buttons per window across multiple windows.
+// GINPUT_TOGGLE_CONFIG_ENTRIES just must be less than the number of GDISP windows (GDISP_DRIVER_COUNT_WIN32).
+#ifndef GINPUT_TOGGLE_CONFIG_ENTRIES
+ #define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
+#endif
+
+// The total number of toggle inputs
+#define GINPUT_TOGGLE_NUM_PORTS (8 * GINPUT_TOGGLE_CONFIG_ENTRIES)
#define GINPUT_TOGGLE_SW1 0 // Switch 1 - Toggle
#define GINPUT_TOGGLE_SW2 1 // Switch 2 - Toggle
@@ -33,6 +40,8 @@
#define GINPUT_TOGGLE_MOMENTARY2 5 // Switch 6 - Momentary
#define GINPUT_TOGGLE_MOMENTARY3 6 // Switch 7 - Momentary
#define GINPUT_TOGGLE_MOMENTARY4 7 // Switch 8 - Momentary
+
+// This pattern of switch and momentary action is repeated across all windows.
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
diff --git a/drivers/multiple/X/gdisp_lld_config.h b/drivers/multiple/X/gdisp_lld_config.h
index 0bd76a2c..7c04b1b9 100644
--- a/drivers/multiple/X/gdisp_lld_config.h
+++ b/drivers/multiple/X/gdisp_lld_config.h
@@ -22,7 +22,12 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "Linux emulator - X11"
+#ifndef GDISP_DRIVER_COUNT_X11
+ #define GDISP_DRIVER_COUNT_X11 1
+#endif
+#define GDISP_DRIVER_COUNT GDISP_DRIVER_COUNT_X11
+
+#define GDISP_DRIVER_NAME "Linux emulator - X11"
#define GDISP_DRIVER_STRUCT GDISP_X11
#define GDISP_HARDWARE_DRAWPIXEL TRUE
@@ -32,7 +37,7 @@
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL FALSE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
#endif /* GFX_USE_GDISP */
diff --git a/gfxconf.example.h b/gfxconf.example.h
index e6be90db..f3a1e165 100644
--- a/gfxconf.example.h
+++ b/gfxconf.example.h
@@ -141,6 +141,29 @@
#define GMISC_NEED_FIXEDTRIG FALSE
#define GMISC_NEED_INVSQRT FALSE
+/* Optional Multiple Display support */
+/*
+ #define GDISP_TOTAL_DISPLAYS 1
+ #define GDISP_TOTAL_CONTROLLERS 1
+
+ // Extra stuff needed for when GDISP_TOTAL_CONTROLLERS > 1
+ #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_Win32
+ #define GDISP_CONTROLLER_DISPLAYS 1, 1
+ #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+ #define GDISP_HARDWARE_STREAM_WRITE FALSE
+ #define GDISP_HARDWARE_STREAM_READ FALSE
+ #define GDISP_HARDWARE_STREAM_POS FALSE
+ #define GDISP_HARDWARE_DRAWPIXEL FALSE
+ #define GDISP_HARDWARE_CLEARS FALSE
+ #define GDISP_HARDWARE_FILLS FALSE
+ #define GDISP_HARDWARE_BITFILLS FALSE
+ #define GDISP_HARDWARE_SCROLL FALSE
+ #define GDISP_HARDWARE_PIXELREAD FALSE
+ #define GDISP_HARDWARE_CONTROL FALSE
+ #define GDISP_HARDWARE_QUERY FALSE
+ #define GDISP_HARDWARE_CLIP FALSE
+*/
+
/* Optional Parameters for various subsystems */
/*
#define GDISP_LINEBUF_SIZE 128
diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h
index 6b2f5b47..7f0f8012 100644
--- a/include/gdisp/gdisp.h
+++ b/include/gdisp/gdisp.h
@@ -17,6 +17,10 @@
*
* @pre GFX_USE_GDISP must be set to TRUE in gfxconf.h
*
+ * @note Each drawing routine supports a gispXXXX and a gdispGXXXX function. The difference is that the
+ * gdispXXXX function does not require a display to be specified. Note there is a slight anomoly
+ * in the naming with gdispGBlitArea() vs gdispBlitAreaEx() and gdispBlitArea(), the later of
+ * which is now deprecated.
* @{
*/
@@ -79,7 +83,18 @@ typedef struct GDISPControl {
uint8_t Contrast;
} GDISPControl;
-extern GDISPControl *GDISP;
+/*
+ * Our black box display structure. We know only one thing about it...
+ * The first member is a GDISPControl structure.
+ */
+typedef struct GDisplay GDisplay;
+
+/**
+ * @brief The default screen to use for the gdispXXXX calls.
+ * @note This is set by default to the first display in the system. You can change
+ * it by calling @p gdispGSetDisplay().
+ */
+extern GDisplay *GDISP;
/*===========================================================================*/
/* Constants. */
@@ -150,75 +165,69 @@ extern GDISPControl *GDISP;
/* Defines relating to the display hardware */
/*===========================================================================*/
-#if GDISP_MULTIPLE_DRIVERS || defined(__DOXYGEN__)
- /**
- * @name GDISP pixel format choices
- * @{
- */
- /**
- * @brief The pixel format.
- * @default It generally defaults to the hardware pixel format.
- * @note This doesn't need to match the hardware pixel format.
- * It is definitely more efficient when it does.
- * @note When GDISP_MULTIPLE_DRIVERS is defined, this should
- * also be explicitly defined to ensure the best match
- * with your hardware across all devices.
- * @note Should be set to one of the following:
- * GDISP_PIXELFORMAT_RGB565
- * GDISP_PIXELFORMAT_BGR565
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB332
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define
- * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h),
- * RED_OF(c), GREEN_OF(c), BLUE_OF(c),
- * COLOR(c) and MASKCOLOR.
- */
- #ifndef GDISP_PIXELFORMAT
- #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
- #endif
- /**
- * @brief Do pixels require packing for a blit
- * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats:
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills
- * you need to also define @p gdispPackPixels(buf,cx,x,y,c)
- * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel
- * format must not be a packed format as the software blit does
- * not support packed pixels
- * @note Very few cases should actually require packed pixels as the low
- * level driver can also pack on the fly as it is sending it
- * to the graphics device.
- */
- #ifndef GDISP_PACKED_PIXELS
- #define GDISP_PACKED_PIXELS FALSE
- #endif
-
- /**
- * @brief Do lines of pixels require packing for a blit
- * @note Ignored if GDISP_PACKED_PIXELS is FALSE
- */
- #ifndef GDISP_PACKED_LINES
- #define GDISP_PACKED_LINES FALSE
- #endif
- /** @} */
-#else
+#if !defined(GDISP_TOTAL_CONTROLLERS) || GDISP_TOTAL_CONTROLLERS == 1
+ // Pull in the default hardware configuration for a single controller.
+ // If we have multiple controllers the settings must be set in the
+ // users gfxconf.h file.
#include "gdisp_lld_config.h"
+#endif
+
+/**
+ * @name GDISP pixel format choices
+ * @{
+ */
+ /**
+ * @brief The pixel format.
+ * @default It generally defaults to the hardware pixel format.
+ * @note This doesn't need to match the hardware pixel format.
+ * It is definitely more efficient when it does.
+ * @note When GDISP_TOTAL_CONTROLLERS > 1, this should
+ * also be explicitly defined to ensure the best match
+ * with your hardware across all devices.
+ * @note Should be set to one of the following:
+ * GDISP_PIXELFORMAT_RGB565
+ * GDISP_PIXELFORMAT_BGR565
+ * GDISP_PIXELFORMAT_RGB888
+ * GDISP_PIXELFORMAT_RGB444
+ * GDISP_PIXELFORMAT_RGB332
+ * GDISP_PIXELFORMAT_RGB666
+ * GDISP_PIXELFORMAT_CUSTOM
+ * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define
+ * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h),
+ * RED_OF(c), GREEN_OF(c), BLUE_OF(c),
+ * COLOR(c) and MASKCOLOR.
+ */
#ifndef GDISP_PIXELFORMAT
- #define GDISP_PIXELFORMAT GDISP_LLD_PIXELFORMAT
+ #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
#endif
+ /**
+ * @brief Do pixels require packing for a blit
+ * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats:
+ * GDISP_PIXELFORMAT_RGB888
+ * GDISP_PIXELFORMAT_RGB444
+ * GDISP_PIXELFORMAT_RGB666
+ * GDISP_PIXELFORMAT_CUSTOM
+ * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills
+ * you need to also define @p gdispPackPixels(buf,cx,x,y,c)
+ * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel
+ * format must not be a packed format as the software blit does
+ * not support packed pixels
+ * @note Very few cases should actually require packed pixels as the low
+ * level driver can also pack on the fly as it is sending it
+ * to the graphics device.
+ */
#ifndef GDISP_PACKED_PIXELS
#define GDISP_PACKED_PIXELS FALSE
#endif
+
+ /**
+ * @brief Do lines of pixels require packing for a blit
+ * @note Ignored if GDISP_PACKED_PIXELS is FALSE
+ */
#ifndef GDISP_PACKED_LINES
#define GDISP_PACKED_LINES FALSE
#endif
-#endif
+/** @} */
/*===========================================================================*/
/* Defines related to the pixel format */
@@ -356,48 +365,68 @@ extern "C" {
*/
color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
+/**
+ * @brief Set the current default display to the specified display
+ * @note The default display is used for the gdispXxxx functions.
+ * @note Displays are numbered from 0 to GDISP_TOTAL_DISPLAYS - 1
+ * @note If an invalid display number is specified the request is ignored.
+ *
+ * @param[in] display The display number (0..n)
+ *
+ * @api
+ */
+void gdispSetDisplay(unsigned display);
+
/* Drawing Functions */
/**
* @brief Clear the display to the specified color.
*
+ * @param[in] g The display to use
* @param[in] color The color to use when clearing the screen
*
* @api
*/
-void gdispClear(color_t color);
+void gdispGClear(GDisplay *g, color_t color);
+#define gdispClear(c) gdispGClear(GDISP, c)
/**
* @brief Set a pixel in the specified color.
*
+ * @param[in] g The display to use
* @param[in] x,y The position to set the pixel.
* @param[in] color The color to use
*
* @api
*/
-void gdispDrawPixel(coord_t x, coord_t y, color_t color);
+void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color);
+#define gdispDrawPixel(x,y,c) gdispGDrawPixel(GDISP,x,y,c)
/**
* @brief Draw a line.
*
+ * @param[in] g The display to use
* @param[in] x0,y0 The start position
* @param[in] x1,y1 The end position
* @param[in] color The color to use
*
* @api
*/
-void gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+#define gdispDrawLine(x0,y0,x1,y1,c) gdispGDrawLine(GDISP,x0,y0,x1,y1,c)
/**
* @brief Fill an area with a color.
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] color The color to use
*
* @api
*/
-void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispFillArea(x,y,cx,cy,c) gdispGFillArea(GDISP,x,y,cx,cy,c)
/**
* @brief Fill an area using the supplied bitmap.
@@ -409,6 +438,7 @@ void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* or at least retained until this call has finished the blit. You can
* tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the filled area
* @param[in] srcx,srcy The bitmap position to start the fill form
@@ -417,18 +447,21 @@ void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
-void gdispBlitAreaEx(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 gdispGBlitArea(GDisplay *g, 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);
+#define gdispBlitAreaEx(x,y,cx,cy,sx,sy,rx,b) gdispGBlitArea(GDISP,x,y,cx,cy,sx,sy,rx,b)
/**
* @brief Draw a rectangular box.
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] color The color to use
*
* @api
*/
-void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispDrawBox(x,y,cx,cy,c) gdispGDrawBox(GDISP,x,y,cx,cy,c)
/* Streaming Functions */
@@ -450,12 +483,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note A streaming operation may be terminated early (without writing to every location
* in the stream area) by calling @p gdispStreamStop().
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the streamable area
*
* @api
*/
- void gdispStreamStart(coord_t x, coord_t y, coord_t cx, coord_t cy);
+ void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispStreamStart(x,y,cx,cy) gdispGStreamStart(GDISP,x,y,cx,cy)
/**
* @brief Send pixel data to the stream.
@@ -464,11 +499,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note If the gdispStreamStart() has not been called (or failed due to clipping), the
* data provided here is simply thrown away.
*
+ * @param[in] g The display to use
* @param[in] color The color of the pixel to write
*
* @api
*/
- void gdispStreamColor(color_t color);
+ void gdispGStreamColor(GDisplay *g, color_t color);
+ #define gdispStreamColor(c) gdispGStreamColor(GDISP,c)
/**
* @brief Finish the current streaming operation.
@@ -477,9 +514,12 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note If the gdispStreamStart() has not been called (or failed due to clipping), this
* call is simply ignored.
*
+ * @param[in] g The display to use
+ *
* @api
*/
- void gdispStreamStop(void);
+ void gdispGStreamStop(GDisplay *g);
+ #define gdispStreamStop() gdispGStreamStop(GDISP)
#endif
/* Clipping Functions */
@@ -488,12 +528,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Clip all drawing to the defined area.
*
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the clip area
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the clip area
*
* @api
*/
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy);
+ void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispSetClip(x,y,cx,cy) gdispGSetClip(GDISP,x,y,cx,cy)
#endif
/* Circle Functions */
@@ -502,24 +544,28 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw a circle.
*
+ * @param[in] g The display to use
* @param[in] x,y The center of the circle
* @param[in] radius The radius of the circle
* @param[in] color The color to use
*
* @api
*/
- void gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color);
+ void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispDrawCircle(x,y,r,c) gdispGDrawCircle(GDISP,x,y,r,c)
/**
* @brief Draw a filled circle.
*
+ * @param[in] g The display to use
* @param[in] x,y The center of the circle
* @param[in] radius The radius of the circle
* @param[in] color The color to use
*
* @api
*/
- void gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color);
+ void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispFillCircle(x,y,r,c) gdispGFillCircle(GDISP,x,y,r,c)
#endif
/* Ellipse Functions */
@@ -528,24 +574,28 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw an ellipse.
*
- * @param[in] x,y The center of the ellipse
- * @param[in] a,b The dimensions of the ellipse
- * @param[in] color The color to use
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ * @param[in] color The color to use
*
* @api
*/
- void gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispDrawEllipse(x,y,a,b,c) gdispGDrawEllipse(GDISP,x,y,a,b,c)
/**
* @brief Draw a filled ellipse.
*
- * @param[in] x,y The center of the ellipse
- * @param[in] a,b The dimensions of the ellipse
- * @param[in] color The color to use
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ * @param[in] color The color to use
*
* @api
*/
- void gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispFillEllipse(x,y,a,b,c) gdispGFillEllipse(GDISP,x,y,a,b,c)
#endif
/* Arc Functions */
@@ -554,6 +604,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/*
* @brief Draw an arc.
*
+ * @param[in] g The display to use
* @param[in] x0,y0 The center point
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360)
@@ -562,12 +613,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispDrawArc(x,y,r,s,e,c) gdispGDrawArc(GDISP,x,y,r,s,e,c)
/*
* @brief Draw a filled arc.
* @note Not very efficient currently - does lots of overdrawing
*
+ * @param[in] g The display to use
* @param[in] x0,y0 The center point
* @param[in] radius The radius of the arc
* @param[in] start The start angle (0 to 360)
@@ -576,7 +629,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispFillArc(x,y,r,s,e,c) gdispGFillArc(GDISP,x,y,r,s,e,c)
#endif
/* Read a pixel Function */
@@ -586,11 +640,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @brief Get the color of a pixel.
* @return The color of the pixel.
*
- * @param[in] x,y The position of the pixel
+ * @param[in] g The display to use
+ * @param[in] x,y The position of the pixel
*
* @api
*/
- color_t gdispGetPixelColor(coord_t x, coord_t y);
+ color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y);
+ #define gdispGetPixelColor(x,y) gdispGGetPixelColor(GDISP,x,y)
#endif
/* Scrolling Function - clears the area scrolled out */
@@ -602,14 +658,16 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note Optional.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
+ * @param[in] g The display to use
+ * @param[in] x, y The start of the area to be scrolled
+ * @param[in] cx, cy The size of the area to be scrolled
+ * @param[in] lines The number of lines to scroll (Can be positive or negative)
+ * @param[in] bgcolor The color to fill the newly exposed area.
*
* @api
*/
- void gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ #define gdispVerticalScroll(x,y,cx,cy,l,b) gdispGVerticalScroll(GDISP,x,y,cx,cy,l,b)
#endif
/* Set driver specific control */
@@ -620,12 +678,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note Depending on the hardware implementation this function may not
* support some codes. They will be ignored.
*
+ * @param[in] g The display to use
* @param[in] what what you want to control
* @param[in] value The value to be assigned
*
* @api
*/
- void gdispControl(unsigned what, void *value);
+ void gdispGControl(GDisplay *g, unsigned what, void *value);
+ #define gdispControl(w,v) gdispGControl(GDISP,w,v)
#endif
/* Query driver specific data */
@@ -636,17 +696,20 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @note The result must be typecast to the correct type.
* @note An unsupported query will return (void *)-1.
*
+ * @param[in] g The display to use
* @param[in] what What to query
*
* @api
*/
- void *gdispQuery(unsigned what);
+ void *gdispGQuery(GDisplay *g, unsigned what);
+ #define gdispQuery(w) gdispGQuery(GDISP,w)
#endif
#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
/**
* @brief Draw an enclosed polygon (convex, non-convex or complex).
*
+ * @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
@@ -654,12 +717,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispDrawPoly(x,y,p,i,c) gdispGDrawPoly(GDISP,x,y,p,i,c)
/**
* @brief Fill a convex polygon
* @details Doesn't handle non-convex or complex polygons.
*
+ * @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
@@ -675,7 +740,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ void gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispFillConvexPoly(x,y,p,i,c) gdispGFillConvexPoly(GDISP,x,y,p,i,c)
#endif
/* Text Functions */
@@ -684,6 +750,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw a text character.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] c The character to draw
* @param[in] font The font to use
@@ -691,11 +758,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ #define gdispDrawChar(x,y,s,f,c) gdispGDrawChar(GDISP,x,y,s,f,c)
/**
* @brief Draw a text character with a filled background.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] c The character to draw
* @param[in] font The font to use
@@ -704,11 +773,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillChar(x,y,s,f,c,b) gdispGFillChar(GDISP,x,y,s,f,c,b)
/**
* @brief Draw a text string.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] font The font to use
* @param[in] str The string to draw
@@ -716,11 +787,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ #define gdispDrawString(x,y,s,f,c) gdispGDrawString(GDISP,x,y,s,f,c)
/**
* @brief Draw a text string.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] str The string to draw
* @param[in] font The font to use
@@ -729,11 +802,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillString(x,y,s,f,c,b) gdispGFillString(GDISP,x,y,s,f,c,b)
/**
* @brief Draw a text string vertically centered within the specified box.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
@@ -743,12 +818,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ #define gdispDrawStringBox(x,y,cx,cy,s,f,c,j) gdispGDrawStringBox(GDISP,x,y,cx,cy,s,f,c,j)
/**
* @brief Draw a text string vertically centered within the specified box. The box background is filled with the specified background color.
* @note The entire box is filled
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
@@ -759,7 +836,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
+ void gdispGFillStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
+ #define gdispFillStringBox(x,y,cx,cy,s,f,c,b,j) gdispGFillStringBox(GDISP,x,y,cx,cy,s,f,c,b,j)
/**
* @brief Get a metric of a font.
@@ -844,6 +922,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw a rectangular box with rounded corners
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] radius The radius of the rounded corners
@@ -851,11 +930,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispDrawRoundedBox(x,y,cx,cy,r,c) gdispGDrawRoundedBox(GDISP,x,y,cx,cy,r,c)
/**
* @brief Draw a filled rectangular box with rounded corners
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] radius The radius of the rounded corners
@@ -863,7 +944,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispFillRoundedBox(x,y,cx,cy,r,c) gdispGFillRoundedBox(GDISP,x,y,cx,cy,r,c)
#endif
/*
@@ -871,7 +953,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*/
/* Now obsolete functions */
-#define gdispBlitArea(x, y, cx, cy, buffer) gdispBlitAreaEx(x, y, cx, cy, 0, 0, cx, buffer)
+#define gdispBlitArea(x, y, cx, cy, buffer) gdispGBlitArea(GDISP, x, y, cx, cy, 0, 0, cx, buffer)
/* Macro definitions for common gets and sets */
@@ -879,26 +961,31 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
* @brief Set the display power mode.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] powerMode The new power mode
*
* @api
*/
-#define gdispSetPowerMode(powerMode) gdispControl(GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#define gdispGSetPowerMode(g, powerMode) gdispGControl((g), GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#define gdispSetPowerMode(powerMode) gdispGControl(GDISP, GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
/**
* @brief Set the display orientation.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] newOrientation The new orientation
*
* @api
*/
-#define gdispSetOrientation(newOrientation) gdispControl(GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#define gdispGSetOrientation(g, newOrientation) gdispGControl((g), GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#define gdispSetOrientation(newOrientation) gdispGControl(GDISP, GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
/**
* @brief Set the display backlight.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] percent The new brightness (0 - 100%)
*
* @note For displays that only support backlight off and on,
@@ -906,68 +993,92 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
-#define gdispSetBacklight(percent) gdispControl(GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#define gdispGSetBacklight(g, percent) gdispGControl((g), GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#define gdispSetBacklight(percent) gdispGControl(GDISP, GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
/**
* @brief Set the display contrast.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] percent The new contrast (0 - 100%)
*
* @api
*/
-#define gdispSetContrast(percent) gdispControl(GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#define gdispGSetContrast(g, percent) gdispGControl((g), GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#define gdispSetContrast(percent) gdispGControl(GDISP, GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
/**
* @brief Get the display width in pixels.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetWidth() (GDISP->Width)
+#define gdispGGetWidth(g) (((GDISPControl *)(g))->Width)
+#define gdispGetWidth() gdispGGetWidth(GDISP)
/**
* @brief Get the display height in pixels.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetHeight() (GDISP->Height)
+#define gdispGGetHeight(g) (((GDISPControl *)(g))->Height)
+#define gdispGetHeight() gdispGGetHeight(GDISP)
/**
* @brief Get the current display power mode.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetPowerMode() (GDISP->Powermode)
+#define gdispGGetPowerMode(g) (((GDISPControl *)(g))->Powermode)
+#define gdispGetPowerMode() gdispGGetPowerMode(GDISP)
/**
* @brief Get the current display orientation.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetOrientation() (GDISP->Orientation)
+#define gdispGGetOrientation(g) (((GDISPControl *)(g))->Orientation)
+#define gdispGetOrientation() gdispGGetOrientation(GDISP)
/**
* @brief Get the current display backlight brightness.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetBacklight() (GDISP->Backlight)
+#define gdispGGetBacklight(g) (((GDISPControl *)(g))->Backlight)
+#define gdispGetBacklight() gdispGGetBacklight(GDISP)
/**
* @brief Get the current display contrast.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetContrast() (GDISP->Contrast)
+#define gdispGGetContrast(g) (((GDISPControl *)(g))->Contrast)
+#define gdispGetContrast() gdispGGetContrast(GDISP)
/* More interesting macro's */
/**
* @brief Reset the clip area to the full screen
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispUnsetClip() gdispSetClip(0,0,gdispGetWidth(),gdispGetHeight())
+#define gdispGUnsetClip(g) gdispGSetClip((g),0,0,(g)->Width,(g)->Height)
+#define gdispUnsetClip() gdispGUnsetClip(GDISP)
#ifdef __cplusplus
}
diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h
index 4813d828..2a6f90b7 100644
--- a/include/gdisp/lld/gdisp_lld.h
+++ b/include/gdisp/lld/gdisp_lld.h
@@ -18,140 +18,136 @@
#if GFX_USE_GDISP || defined(__DOXYGEN__)
-#if GDISP_MULTIPLE_DRIVERS && defined(GDISP_LLD_DECLARATIONS)
- // include hardware definitions
- #include "gdisp_lld_config.h"
-#endif
-
/*===========================================================================*/
/* Error checks. */
/*===========================================================================*/
-#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS)
+/**
+ * @name GDISP hardware accelerated support
+ * @{
+ */
/**
- * @name GDISP hardware accelerated support
- * @{
+ * @brief Hardware streaming writing is supported.
+ * @details If set to @p FALSE software emulation is used.
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
*/
- /**
- * @brief Hardware streaming writing is supported.
- * @details If set to @p FALSE software emulation is used.
- * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
- */
- #ifndef GDISP_HARDWARE_STREAM_WRITE
- #define GDISP_HARDWARE_STREAM_WRITE FALSE
- #endif
+ #ifndef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE FALSE
+ #endif
- /**
- * @brief Hardware streaming reading of the display surface is supported.
- * @details If set to @p FALSE this routine is not available.
- */
- #ifndef GDISP_HARDWARE_STREAM_READ
- #define GDISP_HARDWARE_STREAM_READ FALSE
- #endif
+ /**
+ * @brief Hardware streaming reading of the display surface is supported.
+ * @details If set to @p FALSE this routine is not available.
+ */
+ #ifndef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ FALSE
+ #endif
- /**
- * @brief Hardware supports setting the cursor position within the stream window.
- * @details If set to @p FALSE this routine is not available.
- * @note This is used to optimise setting of individual pixels within a stream window.
- * It should therefore not be implemented unless it is cheaper than just setting
- * a new window.
- */
- #ifndef GDISP_HARDWARE_STREAM_POS
- #define GDISP_HARDWARE_STREAM_POS FALSE
- #endif
+ /**
+ * @brief Hardware supports setting the cursor position within the stream window.
+ * @details If set to @p FALSE this routine is not available.
+ * @note This is used to optimise setting of individual pixels within a stream window.
+ * It should therefore not be implemented unless it is cheaper than just setting
+ * a new window.
+ */
+ #ifndef GDISP_HARDWARE_STREAM_POS
+ #define GDISP_HARDWARE_STREAM_POS FALSE
+ #endif
- /**
- * @brief Hardware accelerated draw pixel.
- * @details If set to @p FALSE software emulation is used.
- * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
- */
- #ifndef GDISP_HARDWARE_DRAWPIXEL
- #define GDISP_HARDWARE_DRAWPIXEL FALSE
- #endif
+ /**
+ * @brief Hardware accelerated draw pixel.
+ * @details If set to @p FALSE software emulation is used.
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
+ */
+ #ifndef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL FALSE
+ #endif
- /**
- * @brief Hardware accelerated screen clears.
- * @details If set to @p FALSE software emulation is used.
- * @note This clears the entire display surface regardless of the clipping area currently set
- */
- #ifndef GDISP_HARDWARE_CLEARS
- #define GDISP_HARDWARE_CLEARS FALSE
- #endif
+ /**
+ * @brief Hardware accelerated screen clears.
+ * @details If set to @p FALSE software emulation is used.
+ * @note This clears the entire display surface regardless of the clipping area currently set
+ */
+ #ifndef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS FALSE
+ #endif
- /**
- * @brief Hardware accelerated rectangular fills.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_FILLS
- #define GDISP_HARDWARE_FILLS FALSE
- #endif
+ /**
+ * @brief Hardware accelerated rectangular fills.
+ * @details If set to @p FALSE software emulation is used.
+ */
+ #ifndef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS FALSE
+ #endif
- /**
- * @brief Hardware accelerated fills from an image.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_BITFILLS
- #define GDISP_HARDWARE_BITFILLS FALSE
- #endif
+ /**
+ * @brief Hardware accelerated fills from an image.
+ * @details If set to @p FALSE software emulation is used.
+ */
+ #ifndef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS FALSE
+ #endif
- /**
- * @brief Hardware accelerated scrolling.
- * @details If set to @p FALSE there is no support for scrolling.
- */
- #ifndef GDISP_HARDWARE_SCROLL
- #define GDISP_HARDWARE_SCROLL FALSE
- #endif
+ /**
+ * @brief Hardware accelerated scrolling.
+ * @details If set to @p FALSE there is no support for scrolling.
+ */
+ #ifndef GDISP_HARDWARE_SCROLL
+ #define GDISP_HARDWARE_SCROLL FALSE
+ #endif
- /**
- * @brief Reading back of pixel values.
- * @details If set to @p FALSE there is no support for pixel read-back.
- */
- #ifndef GDISP_HARDWARE_PIXELREAD
- #define GDISP_HARDWARE_PIXELREAD FALSE
- #endif
+ /**
+ * @brief Reading back of pixel values.
+ * @details If set to @p FALSE there is no support for pixel read-back.
+ */
+ #ifndef GDISP_HARDWARE_PIXELREAD
+ #define GDISP_HARDWARE_PIXELREAD FALSE
+ #endif
- /**
- * @brief The driver supports one or more control commands.
- * @details If set to @p FALSE there is no support for control commands.
- */
- #ifndef GDISP_HARDWARE_CONTROL
- #define GDISP_HARDWARE_CONTROL FALSE
- #endif
+ /**
+ * @brief The driver supports one or more control commands.
+ * @details If set to @p FALSE there is no support for control commands.
+ */
+ #ifndef GDISP_HARDWARE_CONTROL
+ #define GDISP_HARDWARE_CONTROL FALSE
+ #endif
- /**
- * @brief The driver supports a non-standard query.
- * @details If set to @p FALSE there is no support for non-standard queries.
- */
- #ifndef GDISP_HARDWARE_QUERY
- #define GDISP_HARDWARE_QUERY FALSE
- #endif
+ /**
+ * @brief The driver supports a non-standard query.
+ * @details If set to @p FALSE there is no support for non-standard queries.
+ */
+ #ifndef GDISP_HARDWARE_QUERY
+ #define GDISP_HARDWARE_QUERY FALSE
+ #endif
- /**
- * @brief The driver supports a clipping in hardware.
- * @details If set to @p FALSE there is no support for non-standard queries.
- * @note If this is defined the driver must perform its own clipping on all calls to
- * the driver and respond appropriately if a parameter is outside the display area.
- * @note If this is not defined then the software ensures that all calls to the
- * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
- * has been set).
- */
- #ifndef GDISP_HARDWARE_CLIP
- #define GDISP_HARDWARE_CLIP FALSE
- #endif
- /** @} */
-#endif
+ /**
+ * @brief The driver supports a clipping in hardware.
+ * @details If set to @p FALSE there is no support for non-standard queries.
+ * @note If this is defined the driver must perform its own clipping on all calls to
+ * the driver and respond appropriately if a parameter is outside the display area.
+ * @note If this is not defined then the software ensures that all calls to the
+ * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
+ * has been set).
+ */
+ #ifndef GDISP_HARDWARE_CLIP
+ #define GDISP_HARDWARE_CLIP FALSE
+ #endif
+/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
-typedef struct GDISPDriver {
- GDISPControl g;
+typedef struct GDisplay {
+ GDISPControl g; // The public GDISP stuff - must be the first element
- #if GDISP_MULTIPLE_DRIVERS
- const struct GDISPVMT const * vmt;
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ const struct GDISPVMT const * vmt; // The Virtual Method Table
#endif
+ void * priv; // A private area just for the drivers use.
+
+
uint16_t flags;
#define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
#define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
@@ -163,7 +159,7 @@ typedef struct GDISPDriver {
#endif
// Software clipping
- #if (GDISP_MULTIPLE_DRIVERS || !GDISP_HARDWARE_CLIP) && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ #if !GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
coord_t clipx0, clipy0;
coord_t clipx1, clipy1; /* not inclusive */
#endif
@@ -195,10 +191,10 @@ typedef struct GDISPDriver {
color_t linebuf[GDISP_LINEBUF_SIZE];
#endif
-} GDISPDriver;
+} GDisplay;
-#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) || defined(__DOXYGEN__)
- #if GDISP_MULTIPLE_DRIVERS
+#if GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT) || defined(__DOXYGEN__)
+ #if GDISP_TOTAL_CONTROLLERS > 1
#define LLDSPEC static
#else
#define LLDSPEC
@@ -212,9 +208,10 @@ typedef struct GDISPDriver {
* @brief Initialize the driver.
* @return TRUE if successful.
* @param[in] g The driver structure
+ * @param[in] display The display number for this controller 0..n
* @param[out] g->g The driver must fill in the GDISPControl structure
*/
- LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g);
+ LLDSPEC bool_t gdisp_lld_init(GDisplay *g, unsigned display);
#if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__)
/**
@@ -230,7 +227,7 @@ typedef struct GDISPDriver {
* undefined results.
* @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is TRUE.
*/
- LLDSPEC void gdisp_lld_write_start(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g);
/**
* @brief Send a pixel to the current streaming position and then increment that position
@@ -241,7 +238,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_write_color(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g);
/**
* @brief End the current streaming write operation
@@ -251,7 +248,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_write_stop(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g);
#if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__)
/**
@@ -263,7 +260,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_write_pos(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g);
#endif
#endif
@@ -280,7 +277,7 @@ typedef struct GDISPDriver {
* @note Streaming operations that wrap the defined window have
* undefined results.
*/
- LLDSPEC void gdisp_lld_read_start(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g);
/**
* @brief Read a pixel from the current streaming position and then increment that position
@@ -291,7 +288,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC color_t gdisp_lld_read_color(GDISPDriver *g);
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g);
/**
* @brief End the current streaming operation
@@ -301,7 +298,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_read_stop(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g);
#endif
#if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
@@ -315,7 +312,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g);
#endif
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
@@ -328,7 +325,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_clear(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_clear(GDisplay *g);
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
@@ -343,7 +340,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g);
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
@@ -360,7 +357,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g);
#endif
#if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
@@ -374,7 +371,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g);
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g);
#endif
#if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
@@ -393,7 +390,7 @@ typedef struct GDISPDriver {
* @note Clearing the exposed area on the scroll operation is not
* needed as the high level code handles this.
*/
- LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g);
#endif
#if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
@@ -407,7 +404,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_control(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_control(GDisplay *g);
#endif
#if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
@@ -421,7 +418,7 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void *gdisp_lld_query(GDISPDriver *g); // Uses p.x (=what);
+ LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what);
#endif
#if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
@@ -435,40 +432,39 @@ typedef struct GDISPDriver {
*
* @note The parameter variables must not be altered by the driver.
*/
- LLDSPEC void gdisp_lld_set_clip(GDISPDriver *g);
+ LLDSPEC void gdisp_lld_set_clip(GDisplay *g);
#endif
#ifdef __cplusplus
}
#endif
-#endif // !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS)
+#endif // GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT)
-#if GDISP_MULTIPLE_DRIVERS
+#if GDISP_TOTAL_CONTROLLERS > 1
typedef struct GDISPVMT {
- bool_t (*init)(GDISPDriver *g);
- void (*writestart)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy
- void (*writepos)(GDISPDriver *g); // Uses p.x,p.y
- void (*writecolor)(GDISPDriver *g); // Uses p.color
- void (*writestop)(GDISPDriver *g); // Uses no parameters
- void (*readstart)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy
- color_t (*readcolor)(GDISPDriver *g); // Uses no parameters
- void (*readstop)(GDISPDriver *g); // Uses no parameters
- void (*pixel)(GDISPDriver *g); // Uses p.x,p.y p.color
- void (*clear)(GDISPDriver *g); // Uses p.color
- void (*fill)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy p.color
- void (*blit)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
- color_t (*get)(GDISPDriver *g); // Uses p.x,p.y
- void (*vscroll)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
- void (*control)(GDISPDriver *g); // Uses p.x (=what) p.ptr (=value)
- void *(*query)(GDISPDriver *g); // Uses p.x (=what);
- void (*setclip)(GDISPDriver *g); // Uses p.x,p.y p.cx,p.cy
+ bool_t (*init)(GDisplay *g, unsigned display);
+ void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*writepos)(GDisplay *g); // Uses p.x,p.y
+ void (*writecolor)(GDisplay *g); // Uses p.color
+ void (*writestop)(GDisplay *g); // Uses no parameters
+ void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ color_t (*readcolor)(GDisplay *g); // Uses no parameters
+ void (*readstop)(GDisplay *g); // Uses no parameters
+ void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color
+ void (*clear)(GDisplay *g); // Uses p.color
+ void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color
+ void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
+ color_t (*get)(GDisplay *g); // Uses p.x,p.y
+ void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
+ void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value)
+ void *(*query)(GDisplay *g); // Uses p.x (=what);
+ void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
} GDISPVMT;
- #ifdef GDISP_LLD_DECLARATIONS
- #define GDISP_DRIVER_STRUCT_INIT {{0}, &VMT}
- static const GDISPVMT VMT = {
+ #if defined(GDISP_DRIVER_VMT)
+ const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
gdisp_lld_init,
#if GDISP_HARDWARE_STREAM_WRITE
gdisp_lld_write_start,
@@ -480,7 +476,7 @@ typedef struct GDISPDriver {
gdisp_lld_write_color,
gdisp_lld_write_stop,
#else
- 0, 0, 0,
+ 0, 0, 0, 0,
#endif
#if GDISP_HARDWARE_STREAM_READ
gdisp_lld_read_start,
@@ -534,11 +530,10 @@ typedef struct GDISPDriver {
#else
0,
#endif
- };
- GDISPDriver GDISP_DRIVER_STRUCT = {{0}, &VMT};
+ }};
#else
- #define gdisp_lld_init(g) g->vmt->init(g)
+ #define gdisp_lld_init(g, display) g->vmt->init(g, display)
#define gdisp_lld_write_start(g) g->vmt->writestart(g)
#define gdisp_lld_write_pos(g) g->vmt->writepos(g)
#define gdisp_lld_write_color(g) g->vmt->writecolor(g)
@@ -555,19 +550,9 @@ typedef struct GDISPDriver {
#define gdisp_lld_control(g) g->vmt->control(g)
#define gdisp_lld_query(g) g->vmt->query(g)
#define gdisp_lld_set_clip(g) g->vmt->setclip(g)
-
- extern GDISPDriver GDISP_DRIVER_STRUCT;
-
#endif // GDISP_LLD_DECLARATIONS
-#else // GDISP_MULTIPLE_DRIVERS
- #ifdef GDISP_LLD_DECLARATIONS
- GDISPDriver GDISP_DRIVER_STRUCT;
- #else
- extern GDISPDriver GDISP_DRIVER_STRUCT;
- #endif
-
-#endif // GDISP_MULTIPLE_DRIVERS
+#endif // GDISP_TOTAL_CONTROLLERS > 1
/* Verify information for packed pixels and define a non-packed pixel macro */
#if !GDISP_PACKED_PIXELS
diff --git a/include/gdisp/options.h b/include/gdisp/options.h
index 1a0f6907..9af7788f 100644
--- a/include/gdisp/options.h
+++ b/include/gdisp/options.h
@@ -21,19 +21,6 @@
* @{
*/
/**
- * @brief Should support for multiple displays be provided.
- * @details Defaults to FALSE.
- * @note Setting this to TRUE can significantly increase code size as many
- * optimizations that remove code through conditional compilation can't
- * be done. It may also slow some graphics operations as extra tests must
- * be performed to determine how to do a particular operation. For these
- * reasons do not set it to TRUE unless you really need multiple display
- * support.
- */
- #ifndef GDISP_MULTIPLE_DRIVERS
- #define GDISP_MULTIPLE_DRIVERS FALSE
- #endif
- /**
* @brief Should all operations be clipped to the screen and colors validated.
* @details Defaults to TRUE.
* @note If this is FALSE, any operations that extend beyond the
@@ -158,6 +145,50 @@
/**
* @}
*
+ * @name GDISP Multiple Display Support
+ * @{
+ */
+ /**
+ * @brief The total number of displays.
+ * @note This can be on just one type of controller or spread across several different controllers
+ */
+ #ifndef GDISP_TOTAL_DISPLAYS
+ #define GDISP_TOTAL_DISPLAYS 1
+ #endif
+ /**
+ * @brief The total number of controllers.
+ * @note If this is greater than one, all the hardware acceleration options below
+ * and the pixel format must be manually specified in your gfxconf.h along with
+ * @p GDISP_CONTROLLER_LIST. See the gdisp_lld_config.h in each driver to get a list
+ * of hardware capabilities for each driver in order to work out the common set across
+ * all the controllers you want to use.
+ */
+ #ifndef GDISP_TOTAL_CONTROLLERS
+ #define GDISP_TOTAL_CONTROLLERS 1
+ #endif
+
+ #if defined(__DOXYGEN__)
+ /**
+ * @brief The list of controllers.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note See the gdisp_lld.c in each driver (near the top) to get the name of the VMT for a driver.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_SSD1963
+ /**
+ * @brief The number of displays for each controller.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note The sum of all the display counts must equal @p GDISP_TOTAL_DISPLAYS (3 for this example)
+ * or bad things will happen.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_DISPLAYS 2, 1
+ #endif
+/**
+ * @}
+ *
* @name GDISP Image Options
* @pre GDISP_NEED_IMAGE must be TRUE
* @{
diff --git a/include/gfx_rules.h b/include/gfx_rules.h
index a8dd031e..c58fc5ba 100644
--- a/include/gfx_rules.h
+++ b/include/gfx_rules.h
@@ -134,12 +134,14 @@
#endif
#if GFX_USE_GDISP
- #if GDISP_MULTIPLE_DRIVERS
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ #ifndef GDISP_CONTROLLER_LIST
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_LIST"
+ #endif
#ifndef GDISP_PIXELFORMAT
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GDISP: GDISP_MULTIPLE_DRIVERS requires GDISP_PIXELFORMAT to be set. It has been defaulted to GDISP_PIXELFORMAT_RGB565."
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT"
#endif
- #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif
#endif
#if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD
diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c
index 756d5c1d..41f2f0f9 100644
--- a/src/gdisp/gdisp.c
+++ b/src/gdisp/gdisp.c
@@ -31,81 +31,92 @@
#define INLINE
#endif
+// Number of milliseconds for the startup logo - 0 means disabled.
+#define GDISP_STARTUP_LOGO_TIMEOUT 1000
+
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
-#define GC ((GDISPDriver *)GDISP)
-GDISPControl *GDISP = &GDISP_DRIVER_STRUCT.g;
+// The controller array, the display array and the default display
+#if GDISP_TOTAL_CONTROLLERS > 1
+ typedef const struct GDISPVMT const VMTEL[1];
+ extern VMTEL GDISP_CONTROLLER_LIST;
+ static const struct GDISPVMT const * ControllerList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
+ static const unsigned DisplayCountList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS};
+#endif
+static GDisplay GDisplayArray[GDISP_TOTAL_DISPLAYS];
+GDisplay *GDISP = GDisplayArray;
#if GDISP_NEED_MULTITHREAD
- #define MUTEX_INIT() gfxMutexInit(&GC->mutex)
- #define MUTEX_ENTER() gfxMutexEnter(&GC->mutex)
- #define MUTEX_EXIT() gfxMutexExit(&GC->mutex)
+ #define MUTEX_INIT(g) gfxMutexInit(&(g)->mutex)
+ #define MUTEX_ENTER(g) gfxMutexEnter(&(g)->mutex)
+ #define MUTEX_EXIT(g) gfxMutexExit(&(g)->mutex)
#else
- #define MUTEX_INIT()
- #define MUTEX_ENTER()
- #define MUTEX_EXIT()
+ #define MUTEX_INIT(g)
+ #define MUTEX_ENTER(g)
+ #define MUTEX_EXIT(g)
#endif
#define NEED_CLIPPING (!GDISP_HARDWARE_CLIP && (GDISP_NEED_VALIDATION || GDISP_NEED_CLIP))
+
/*==========================================================================*/
/* Internal functions. */
/*==========================================================================*/
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- static INLINE void setglobalwindow(void) {
+ static INLINE void setglobalwindow(GDisplay *g) {
coord_t x, y;
- x = GC->p.x; y = GC->p.y;
- GC->p.cx = GC->g.Width; GC->p.cy = GC->g.Height;
- gdisp_lld_write_start(GC);
- GC->p.x = x; GC->p.y = y;
- GC->flags |= GDISP_FLG_SCRSTREAM;
+ x = g->p.x; y = g->p.y;
+ g->p.cx = g->g.Width; g->p.cy = g->g.Height;
+ gdisp_lld_write_start(g);
+ g->p.x = x; g->p.y = y;
+ g->flags |= GDISP_FLG_SCRSTREAM;
}
#endif
-// drawpixel_clip()
+// drawpixel_clip(g)
// Parameters: x,y
// Alters: cx, cy (if using streaming)
#if GDISP_HARDWARE_DRAWPIXEL
// Best is hardware accelerated pixel draw
#if NEED_CLIPPING
- static INLINE void drawpixel_clip(void) {
- if (GC->p.x >= GC->clipx0 && GC->p.x < GC->clipx1 && GC->p.y >= GC->clipy0 && GC->p.y < GC->clipy1)
- gdisp_lld_draw_pixel(GC);
+ static INLINE void drawpixel_clip(GDisplay *g) {
+ if (g->p.x >= g->clipx0 && g->p.x < g->clipx1 && g->p.y >= g->clipy0 && g->p.y < g->clipy1)
+ gdisp_lld_draw_pixel(g);
}
#else
- #define drawpixel_clip() gdisp_lld_draw_pixel(GC)
+ #define drawpixel_clip(g) gdisp_lld_draw_pixel(g)
#endif
#elif GDISP_HARDWARE_STREAM_POS
// Next best is cursor based streaming
- static INLINE void drawpixel_clip(void) {
+ static INLINE void drawpixel_clip(GDisplay *g) {
#if NEED_CLIPPING
- if (GC->p.x < GC->clipx0 || GC->p.x >= GC->clipx1 || GC->p.y < GC->clipy0 || GC->p.y >= GC->clipy1)
+ if (g->p.x < g->clipx0 || g->p.x >= g->clipx1 || g->p.y < g->clipy0 || g->p.y >= g->clipy1)
return;
#endif
- if (!(GC->flags & GDISP_FLG_SCRSTREAM))
- setglobalwindow();
- gdisp_lld_write_pos(GC);
- gdisp_lld_write_color(GC);
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ gdisp_lld_write_pos(g);
+ gdisp_lld_write_color(g);
}
#else
// Worst is streaming
- static INLINE void drawpixel_clip(void) {
+ static INLINE void drawpixel_clip(GDisplay *g) {
#if NEED_CLIPPING
- if (GC->p.x < GC->clipx0 || GC->p.x >= GC->clipx1 || GC->p.y < GC->clipy0 || GC->p.y >= GC->clipy1)
+ if (g->p.x < g->clipx0 || g->p.x >= g->clipx1 || g->p.y < g->clipy0 || g->p.y >= g->clipy1)
return;
#endif
- GC->p.cx = GC->p.cy = 1;
- gdisp_lld_write_start(GC);
- gdisp_lld_write_color(GC);
- gdisp_lld_write_stop(GC);
+ g->p.cx = g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
}
#endif
-// fillarea()
+// fillarea(g)
// Parameters: x,y cx,cy and color
// Alters: nothing
// Note: This is not clipped
@@ -113,94 +124,94 @@ GDISPControl *GDISP = &GDISP_DRIVER_STRUCT.g;
// if GDISP_HARDWARE_STREAM_WRITE and GDISP_HARDWARE_STREAM_POS is set.
#if GDISP_HARDWARE_FILLS
// Best is hardware accelerated area fill
- #define fillarea() gdisp_lld_fill_area(GC)
+ #define fillarea(g) gdisp_lld_fill_area(g)
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is hardware streaming
- static INLINE void fillarea(void) {
+ static INLINE void fillarea(GDisplay *g) {
uint32_t area;
- area = (uint32_t)GC->p.cx * GC->p.cy;
+ area = (uint32_t)g->p.cx * g->p.cy;
#if GDISP_HARDWARE_STREAM_POS
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- gdisp_lld_write_start(GC);
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
for(; area; area--)
- gdisp_lld_write_color(GC);
- gdisp_lld_write_stop(GC);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
}
#else
// Worst is drawing pixels
- static INLINE void fillarea(void) {
+ static INLINE void fillarea(GDisplay *g) {
coord_t x0, y0, x1, y1;
- x0 = GC->p.x;
- y0 = GC->p.y;
- x1 = GC->p.x + GC->p.cx;
- y1 = GC->p.y + GC->p.cy;
- for(; GC->p.y < y1; GC->p.y++, GC->p.x = x0)
- for(; GC->p.x < x1; GC->p.x++)
- gdisp_lld_draw_pixel(GC);
- GC->p.y = y0;
+ x0 = g->p.x;
+ y0 = g->p.y;
+ x1 = g->p.x + g->p.cx;
+ y1 = g->p.y + g->p.cy;
+ for(; g->p.y < y1; g->p.y++, g->p.x = x0)
+ for(; g->p.x < x1; g->p.x++)
+ gdisp_lld_draw_pixel(g);
+ g->p.y = y0;
}
#endif
#if NEED_CLIPPING
- #define TEST_CLIP_AREA(x,y,cx,cy) \
- if ((x) < GC->clipx0) { (cx) -= GC->clipx0 - (x); (x) = GC->clipx0; } \
- if ((y) < GC->clipy0) { (cy) -= GC->clipy0 - (y); (y) = GC->clipy0; } \
- if ((x) + (cx) > GC->clipx1) (cx) = GC->clipx1 - (x); \
- if ((y) + (cy) > GC->clipy1) (cy) = GC->clipy1 - (y); \
- if ((cx) > 0 && (cy) > 0)
+ #define TEST_CLIP_AREA(g) \
+ if ((g)->p.x < (g)->clipx0) { (g)->p.cx -= (g)->clipx0 - (g)->p.x; (g)->p.x = (g)->clipx0; } \
+ if ((g)->p.y < (g)->clipy0) { (g)->p.cy -= (g)->clipy0 - (g)->p.y; (g)->p.y = (g)->clipy0; } \
+ if ((g)->p.x + (g)->p.cx > (g)->clipx1) (g)->p.cx = (g)->clipx1 - (g)->p.x; \
+ if ((g)->p.y + (g)->p.cy > (g)->clipy1) (g)->p.cy = (g)->clipy1 - (g)->p.y; \
+ if ((g)->p.cx > 0 && (g)->p.cy > 0)
#else
- #define TEST_CLIP_AREA(x,y,cx,cy)
+ #define TEST_CLIP_AREA(g)
#endif
// Parameters: x,y and x1
// Alters: x,y x1,y1 cx,cy
// Assumes the window covers the screen and a write_stop() will occur later
// if GDISP_HARDWARE_STREAM_WRITE and GDISP_HARDWARE_STREAM_POS is set.
-static void hline_clip(void) {
+static void hline_clip(GDisplay *g) {
// Swap the points if necessary so it always goes from x to x1
- if (GC->p.x1 < GC->p.x) {
- GC->p.cx = GC->p.x; GC->p.x = GC->p.x1; GC->p.x1 = GC->p.cx;
+ if (g->p.x1 < g->p.x) {
+ g->p.cx = g->p.x; g->p.x = g->p.x1; g->p.x1 = g->p.cx;
}
// Clipping
#if NEED_CLIPPING
- if (GC->p.y < GC->clipy0 || GC->p.y >= GC->clipy1) return;
- if (GC->p.x < GC->clipx0) GC->p.x = GC->clipx0;
- if (GC->p.x1 >= GC->clipx1) GC->p.x1 = GC->clipx1 - 1;
- if (GC->p.x1 < GC->p.x) return;
+ if (g->p.y < g->clipy0 || g->p.y >= g->clipy1) return;
+ if (g->p.x < g->clipx0) g->p.x = g->clipx0;
+ if (g->p.x1 >= g->clipx1) g->p.x1 = g->clipx1 - 1;
+ if (g->p.x1 < g->p.x) return;
#endif
// This is an optimization for the point case. It is only worthwhile however if we
// have hardware fills or if we support both hardware pixel drawing and hardware streaming
#if GDISP_HARDWARE_FILLS || (GDISP_HARDWARE_DRAWPIXEL && GDISP_HARDWARE_STREAM_WRITE)
// Is this a point
- if (GC->p.x == GC->p.x1) {
+ if (g->p.x == g->p.x1) {
#if GDISP_HARDWARE_DRAWPIXEL
// Best is hardware accelerated pixel draw
- gdisp_lld_draw_pixel(GC);
+ gdisp_lld_draw_pixel(g);
#elif GDISP_HARDWARE_STREAM_POS
// Next best is cursor based streaming
- if (!(GC->flags & GDISP_FLG_SCRSTREAM))
- setglobalwindow();
- gdisp_lld_write_pos(GC);
- gdisp_lld_write_color(GC);
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ gdisp_lld_write_pos(g);
+ gdisp_lld_write_color(g);
#else
// Worst is streaming
- GC->p.cx = GC->p.cy = 1;
- gdisp_lld_write_start(GC);
- gdisp_lld_write_color(GC);
- gdisp_lld_write_stop(GC);
+ g->p.cx = g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
#endif
return;
}
@@ -208,65 +219,65 @@ static void hline_clip(void) {
#if GDISP_HARDWARE_FILLS
// Best is hardware accelerated area fill
- GC->p.cx = GC->p.x1 - GC->p.x + 1;
- GC->p.cy = 1;
- gdisp_lld_fill_area(GC);
+ g->p.cx = g->p.x1 - g->p.x + 1;
+ g->p.cy = 1;
+ gdisp_lld_fill_area(g);
#elif GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
// Next best is cursor based streaming
- if (!(GC->flags & GDISP_FLG_SCRSTREAM))
- setglobalwindow();
- gdisp_lld_write_pos(GC);
- do { gdisp_lld_write_color(GC); } while(GC->p.cx--);
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ gdisp_lld_write_pos(g);
+ do { gdisp_lld_write_color(g); } while(g->p.cx--);
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is streaming
- GC->p.cx = GC->p.x1 - GC->p.x + 1;
- GC->p.cy = 1;
- gdisp_lld_write_start(GC);
- do { gdisp_lld_write_color(GC); } while(GC->p.cx--);
- gdisp_lld_write_stop(GC);
+ g->p.cx = g->p.x1 - g->p.x + 1;
+ g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ do { gdisp_lld_write_color(g); } while(g->p.cx--);
+ gdisp_lld_write_stop(g);
#else
// Worst is drawing pixels
- for(; GC->p.x <= GC->p.x1; GC->p.x++)
- gdisp_lld_draw_pixel(GC);
+ for(; g->p.x <= g->p.x1; g->p.x++)
+ gdisp_lld_draw_pixel(g);
#endif
}
// Parameters: x,y and y1
// Alters: x,y x1,y1 cx,cy
-static void vline_clip(void) {
+static void vline_clip(GDisplay *g) {
// Swap the points if necessary so it always goes from y to y1
- if (GC->p.y1 < GC->p.y) {
- GC->p.cy = GC->p.y; GC->p.y = GC->p.y1; GC->p.y1 = GC->p.cy;
+ if (g->p.y1 < g->p.y) {
+ g->p.cy = g->p.y; g->p.y = g->p.y1; g->p.y1 = g->p.cy;
}
// Clipping
#if NEED_CLIPPING
- if (GC->p.x < GC->clipx0 || GC->p.x >= GC->clipx1) return;
- if (GC->p.y < GC->clipy0) GC->p.y = GC->clipy0;
- if (GC->p.y1 >= GC->clipy1) GC->p.y1 = GC->clipy1 - 1;
- if (GC->p.y1 < GC->p.y) return;
+ if (g->p.x < g->clipx0 || g->p.x >= g->clipx1) return;
+ if (g->p.y < g->clipy0) g->p.y = g->clipy0;
+ if (g->p.y1 >= g->clipy1) g->p.y1 = g->clipy1 - 1;
+ if (g->p.y1 < g->p.y) return;
#endif
// This is an optimization for the point case. It is only worthwhile however if we
// have hardware fills or if we support both hardware pixel drawing and hardware streaming
#if GDISP_HARDWARE_FILLS || (GDISP_HARDWARE_DRAWPIXEL && GDISP_HARDWARE_STREAM_WRITE) || (GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE)
// Is this a point
- if (GC->p.y == GC->p.y1) {
+ if (g->p.y == g->p.y1) {
#if GDISP_HARDWARE_DRAWPIXEL
// Best is hardware accelerated pixel draw
- gdisp_lld_draw_pixel(GC);
+ gdisp_lld_draw_pixel(g);
#elif GDISP_HARDWARE_STREAM_POS
// Next best is cursor based streaming
- if (!(GC->flags & GDISP_FLG_SCRSTREAM))
- setglobalwindow();
- gdisp_lld_write_pos(GC);
- gdisp_lld_write_color(GC);
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ gdisp_lld_write_pos(g);
+ gdisp_lld_write_color(g);
#else
// Worst is streaming
- GC->p.cx = GC->p.cy = 1;
- gdisp_lld_write_start(GC);
- gdisp_lld_write_color(GC);
- gdisp_lld_write_stop(GC);
+ g->p.cx = g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
#endif
return;
}
@@ -274,48 +285,48 @@ static void vline_clip(void) {
#if GDISP_HARDWARE_FILLS
// Best is hardware accelerated area fill
- GC->p.cy = GC->p.y1 - GC->p.y + 1;
- GC->p.cx = 1;
- gdisp_lld_fill_area(GC);
+ g->p.cy = g->p.y1 - g->p.y + 1;
+ g->p.cx = 1;
+ gdisp_lld_fill_area(g);
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is streaming
#if GDISP_HARDWARE_STREAM_POS
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- GC->p.cy = GC->p.y1 - GC->p.y + 1;
- GC->p.cx = 1;
- gdisp_lld_write_start(GC);
+ g->p.cy = g->p.y1 - g->p.y + 1;
+ g->p.cx = 1;
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
- do { gdisp_lld_write_color(GC); } while(GC->p.cy--);
- gdisp_lld_write_stop(GC);
+ do { gdisp_lld_write_color(g); } while(g->p.cy--);
+ gdisp_lld_write_stop(g);
#else
// Worst is drawing pixels
- for(; GC->p.y <= GC->p.y1; GC->p.y++)
- gdisp_lld_draw_pixel(GC);
+ for(; g->p.y <= g->p.y1; g->p.y++)
+ gdisp_lld_draw_pixel(g);
#endif
}
// Parameters: x,y and x1,y1
// Alters: x,y x1,y1 cx,cy
-static void line_clip(void) {
+static void line_clip(GDisplay *g) {
int16_t dy, dx;
int16_t addx, addy;
int16_t P, diff, i;
// Is this a horizontal line (or a point)
- if (GC->p.y == GC->p.y1) {
- hline_clip();
+ if (g->p.y == g->p.y1) {
+ hline_clip(g);
return;
}
// Is this a vertical line (or a point)
- if (GC->p.x == GC->p.x1) {
- vline_clip();
+ if (g->p.x == g->p.x1) {
+ vline_clip(g);
return;
}
@@ -327,18 +338,18 @@ static void line_clip(void) {
// When clipping is needed, all the clipping could also be done up front
// instead of on each pixel.
- if (GC->p.x1 >= GC->p.x) {
- dx = GC->p.x1 - GC->p.x;
+ if (g->p.x1 >= g->p.x) {
+ dx = g->p.x1 - g->p.x;
addx = 1;
} else {
- dx = GC->p.x - GC->p.x1;
+ dx = g->p.x - g->p.x1;
addx = -1;
}
- if (GC->p.y1 >= GC->p.y) {
- dy = GC->p.y1 - GC->p.y;
+ if (g->p.y1 >= g->p.y) {
+ dy = g->p.y1 - g->p.y;
addy = 1;
} else {
- dy = GC->p.y - GC->p.y1;
+ dy = g->p.y - g->p.y1;
addy = -1;
}
@@ -348,14 +359,14 @@ static void line_clip(void) {
diff = P - dx;
for(i=0; i<=dx; ++i) {
- drawpixel_clip();
+ drawpixel_clip(g);
if (P < 0) {
P += dy;
- GC->p.x += addx;
+ g->p.x += addx;
} else {
P += diff;
- GC->p.x += addx;
- GC->p.y += addy;
+ g->p.x += addx;
+ g->p.y += addy;
}
}
} else {
@@ -364,90 +375,126 @@ static void line_clip(void) {
diff = P - dy;
for(i=0; i<=dy; ++i) {
- drawpixel_clip();
+ drawpixel_clip(g);
if (P < 0) {
P += dx;
- GC->p.y += addy;
+ g->p.y += addy;
} else {
P += diff;
- GC->p.x += addx;
- GC->p.y += addy;
+ g->p.x += addx;
+ g->p.y += addy;
}
}
}
}
+#if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ static void StatupLogoDisplay(GDisplay *g) {
+ gdispGClear(g, Black);
+ gdispGFillArea(g, g->g.Width/4, g->g.Height/4, g->g.Width/2, g->g.Height/2, Blue);
+ }
+#endif
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* Our module initialiser */
void _gdispInit(void) {
- MUTEX_INIT();
+ GDisplay *g;
+ unsigned i;
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ unsigned j;
+ #endif
+
/* Initialise driver */
- MUTEX_ENTER();
- GC->flags = 0;
- gdisp_lld_init(GC);
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- #if GDISP_HARDWARE_CLIP
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- gdisp_lld_set_clip(GC);
- #else
- GC->clipx0 = 0;
- GC->clipy0 = 0;
- GC->clipx1 = GC->g.Width;
- GC->clipy1 = GC->g.Height;
- #endif
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ for(g = GDisplayArray, j=0; j < GDISP_TOTAL_CONTROLLERS; j++)
+ for(i = 0; i < DisplayCountList[j]; g++, i++) {
+ g->vmt = ControllerList[j];
+ #else
+ for(g = GDisplayArray, i = 0; i < GDISP_TOTAL_DISPLAYS; g++, i++) {
+ #endif
+ MUTEX_INIT(g);
+ MUTEX_ENTER(g);
+ g->flags = 0;
+ gdisp_lld_init(g, i);
+ #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
+ #if GDISP_HARDWARE_CLIP
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_set_clip(g);
+ #else
+ g->clipx0 = 0;
+ g->clipy0 = 0;
+ g->clipx1 = g->g.Width;
+ g->clipy1 = g->g.Height;
+ #endif
+ #endif
+ MUTEX_EXIT(g);
+ #if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ StatupLogoDisplay(g);
+ #else
+ gdispGClear(g, Black);
+ #endif
+ }
+ #if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT);
+ for(g = GDisplayArray, i = 0; i < GDISP_TOTAL_DISPLAYS; g++, i++)
+ gdispGClear(g, Black);
#endif
- MUTEX_EXIT();
+}
+
+void gdispSetDisplay(unsigned display) {
+ if (display < GDISP_TOTAL_DISPLAYS)
+ GDISP = &GDisplayArray[display];
}
#if GDISP_NEED_STREAMING
- void gdispStreamStart(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- MUTEX_ENTER();
+ void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy) {
+ MUTEX_ENTER(g);
#if NEED_CLIPPING
// Test if the area is valid - if not then exit
- if (x < GC->clipx0 || x+cx > GC->clipx1 || y < GC->clipy0 || y+cy > GC->clipy1) {
- MUTEX_EXIT();
+ if (x < g->clipx0 || x+cx > g->clipx1 || y < g->clipy0 || y+cy > g->clipy1) {
+ MUTEX_EXIT(g);
return;
}
#endif
- GC->flags |= GDISP_FLG_INSTREAM;
+ g->flags |= GDISP_FLG_INSTREAM;
#if GDISP_HARDWARE_STREAM_WRITE
// Best is hardware streaming
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- gdisp_lld_write_start(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
#else
// Worst - save the parameters and use pixel drawing
// Use x,y as the current position, x1,y1 as the save position and x2,y2 as the end position, cx = bufpos
- GC->p.x1 = GC->p.x = x;
- GC->p.y1 = GC->p.y = y;
- GC->p.x2 = x + cx;
- GC->p.y2 = y + cy;
+ g->p.x1 = g->p.x = x;
+ g->p.y1 = g->p.y = y;
+ g->p.x2 = x + cx;
+ g->p.y2 = y + cy;
#if (GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS) || GDISP_HARDWARE_FILLS
- GC->p.cx = 0;
- GC->p.cy = 1;
+ g->p.cx = 0;
+ g->p.cy = 1;
#endif
#endif
// Don't release the mutex as gdispStreamEnd() will do that.
}
- void gdispStreamColor(color_t color) {
+ void gdispGStreamColor(GDisplay *g, color_t color) {
#if !GDISP_HARDWARE_STREAM_WRITE && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
coord_t sx1, sy1;
#endif
@@ -455,224 +502,224 @@ void _gdispInit(void) {
// Don't touch the mutex as we should already own it
// Ignore this call if we are not streaming
- if (!(GC->flags & GDISP_FLG_INSTREAM))
+ if (!(g->flags & GDISP_FLG_INSTREAM))
return;
#if GDISP_HARDWARE_STREAM_WRITE
// Best is hardware streaming
- GC->p.color = color;
- gdisp_lld_write_color(GC);
+ g->p.color = color;
+ gdisp_lld_write_color(g);
#elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
- GC->linebuf[GC->p.cx++] = color;
- if (GC->p.cx >= GDISP_LINEBUF_SIZE) {
- sx1 = GC->p.x1;
- sy1 = GC->p.y1;
- GC->p.x1 = 0;
- GC->p.y1 = 0;
- GC->p.ptr = (void *)GC->linebuf;
- gdisp_lld_blit_area(GC);
- GC->p.x1 = sx1;
- GC->p.y1 = sy1;
- GC->p.x += GC->p.cx;
- GC->p.cx = 0;
+ g->linebuf[g->p.cx++] = color;
+ if (g->p.cx >= GDISP_LINEBUF_SIZE) {
+ sx1 = g->p.x1;
+ sy1 = g->p.y1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ g->p.x1 = sx1;
+ g->p.y1 = sy1;
+ g->p.x += g->p.cx;
+ g->p.cx = 0;
}
// Just wrap at end-of-line and end-of-buffer
- if (GC->p.x+GC->p.cx >= GC->p.x2) {
- if (GC->p.cx) {
- sx1 = GC->p.x1;
- sy1 = GC->p.y1;
- GC->p.x1 = 0;
- GC->p.y1 = 0;
- GC->p.ptr = (void *)GC->linebuf;
- gdisp_lld_blit_area(GC);
- GC->p.x1 = sx1;
- GC->p.y1 = sy1;
- GC->p.cx = 0;
+ if (g->p.x+g->p.cx >= g->p.x2) {
+ if (g->p.cx) {
+ sx1 = g->p.x1;
+ sy1 = g->p.y1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ g->p.x1 = sx1;
+ g->p.y1 = sy1;
+ g->p.cx = 0;
}
- GC->p.x = GC->p.x1;
- if (++GC->p.y >= GC->p.y2)
- GC->p.y = GC->p.y1;
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
}
#elif GDISP_HARDWARE_FILLS
// Only slightly better than drawing pixels is to look for runs and use fill area
- if (!GC->p.cx || GC->p.color == color) {
- GC->p.cx++;
- GC->p.color = color;
+ if (!g->p.cx || g->p.color == color) {
+ g->p.cx++;
+ g->p.color = color;
} else {
- if (GC->p.cx == 1)
- gdisp_lld_draw_pixel(GC);
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
else
- gdisp_lld_fill_area(GC);
- GC->p.x += GC->p.cx;
- GC->p.color = color;
- GC->p.cx = 1;
+ gdisp_lld_fill_area(g);
+ g->p.x += g->p.cx;
+ g->p.color = color;
+ g->p.cx = 1;
}
// Just wrap at end-of-line and end-of-buffer
- if (GC->p.x+GC->p.cx >= GC->p.x2) {
- if (GC->p.cx) {
- if (GC->p.cx == 1)
- gdisp_lld_draw_pixel(GC);
+ if (g->p.x+g->p.cx >= g->p.x2) {
+ if (g->p.cx) {
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
else
- gdisp_lld_fill_area(GC);
- GC->p.cx = 0;
+ gdisp_lld_fill_area(g);
+ g->p.cx = 0;
}
- GC->p.x = GC->p.x1;
- if (++GC->p.y >= GC->p.y2)
- GC->p.y = GC->p.y1;
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
}
#else
// Worst is using pixel drawing
- GC->p.color = color;
- gdisp_lld_draw_pixel(GC);
+ g->p.color = color;
+ gdisp_lld_draw_pixel(g);
// Just wrap at end-of-line and end-of-buffer
- if (++GC->p.x >= GC->p.x2) {
- GC->p.x = GC->p.x1;
- if (++GC->p.y >= GC->p.y2)
- GC->p.y = GC->p.y1;
+ if (++g->p.x >= g->p.x2) {
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
}
#endif
}
- void gdispStreamStop(void) {
+ void gdispGStreamStop(GDisplay *g) {
// Only release the mutex and end the stream if we are actually streaming.
- if (!(GC->flags & GDISP_FLG_INSTREAM))
+ if (!(g->flags & GDISP_FLG_INSTREAM))
return;
#if GDISP_HARDWARE_STREAM_WRITE
- gdisp_lld_write_stop(GC);
+ gdisp_lld_write_stop(g);
#elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
- if (GC->p.cx) {
- GC->p.x1 = 0;
- GC->p.y1 = 0;
- GC->p.ptr = (void *)GC->linebuf;
- gdisp_lld_blit_area(GC);
+ if (g->p.cx) {
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
}
#elif GDISP_HARDWARE_FILLS
- if (GC->p.cx) {
- if (GC->p.cx == 1)
- gdisp_lld_draw_pixel(GC);
+ if (g->p.cx) {
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
else
- gdisp_lld_fill_area(GC);
+ gdisp_lld_fill_area(g);
}
#endif
- GC->flags &= ~GDISP_FLG_INSTREAM;
- MUTEX_EXIT();
+ g->flags &= ~GDISP_FLG_INSTREAM;
+ MUTEX_EXIT(g);
}
#endif
-void gdispDrawPixel(coord_t x, coord_t y, color_t color) {
- MUTEX_ENTER();
- GC->p.x = x;
- GC->p.y = y;
- GC->p.color = color;
- drawpixel_clip();
+void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.color = color;
+ drawpixel_clip(g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
-void gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- MUTEX_ENTER();
- GC->p.x = x0;
- GC->p.y = y0;
- GC->p.x1 = x1;
- GC->p.y1 = y1;
- GC->p.color = color;
- line_clip();
+void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x0;
+ g->p.y = y0;
+ g->p.x1 = x1;
+ g->p.y1 = y1;
+ g->p.color = color;
+ line_clip(g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
-void gdispClear(color_t color) {
+void gdispGClear(GDisplay *g, color_t color) {
// Note - clear() ignores the clipping area. It clears the screen.
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
#if GDISP_HARDWARE_CLEARS
// Best is hardware accelerated clear
- GC->p.color = color;
- gdisp_lld_clear(GC);
+ g->p.color = color;
+ gdisp_lld_clear(g);
#elif GDISP_HARDWARE_FILLS
// Next best is hardware accelerated area fill
- GC->p.x = GC->p.y = 0;
- GC->p.cx = GC->g.Width;
- GC->p.cy = GC->g.Height;
- GC->p.color = color;
- gdisp_lld_fill_area(GC);
+ g->p.x = g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ g->p.color = color;
+ gdisp_lld_fill_area(g);
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is streaming
uint32_t area;
- GC->p.x = GC->p.y = 0;
- GC->p.cx = GC->g.Width;
- GC->p.cy = GC->g.Height;
- GC->p.color = color;
- area = (uint32_t)GC->p.cx * GC->p.cy;
+ g->p.x = g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ g->p.color = color;
+ area = (uint32_t)g->p.cx * g->p.cy;
- gdisp_lld_write_start(GC);
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
for(; area; area--)
- gdisp_lld_write_color(GC);
- gdisp_lld_write_stop(GC);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
#else
// Worst is drawing pixels
- GC->p.color = color;
- for(GC->p.y = 0; GC->p.y < GC->g.Height; GC->p.y++)
- for(GC->p.x = 0; GC->p.x < GC->g.Width; GC->p.x++)
- gdisp_lld_draw_pixel(GC);
+ g->p.color = color;
+ for(g->p.y = 0; g->p.y < g->g.Height; g->p.y++)
+ for(g->p.x = 0; g->p.x < g->g.Width; g->p.x++)
+ gdisp_lld_draw_pixel(g);
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
-void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- MUTEX_ENTER();
- TEST_CLIP_AREA(x,y,cx,cy) {
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- GC->p.color = color;
- fillarea();
+void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.color = color;
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
}
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
-void gdispBlitAreaEx(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) {
- MUTEX_ENTER();
+void gdispGBlitArea(GDisplay *g, 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) {
+ MUTEX_ENTER(g);
#if NEED_CLIPPING
- // This is a different cliping to fillarea() as it needs to take into account srcx,srcy
- if (x < GC->clipx0) { cx -= GC->clipx0 - x; srcx += GC->clipx0 - x; x = GC->clipx0; }
- if (y < GC->clipy0) { cy -= GC->clipy0 - y; srcy += GC->clipy0 - x; y = GC->clipy0; }
- if (x+cx > GC->clipx1) cx = GC->clipx1 - x;
- if (y+cy > GC->clipy1) cy = GC->clipy1 - y;
+ // This is a different cliping to fillarea(g) as it needs to take into account srcx,srcy
+ if (x < g->clipx0) { cx -= g->clipx0 - x; srcx += g->clipx0 - x; x = g->clipx0; }
+ if (y < g->clipy0) { cy -= g->clipy0 - y; srcy += g->clipy0 - x; y = g->clipy0; }
+ if (x+cx > g->clipx1) cx = g->clipx1 - x;
+ if (y+cy > g->clipy1) cy = g->clipy1 - y;
if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0) { MUTEX_EXIT(); return; }
+ if (cx <= 0 || cy <= 0) { MUTEX_EXIT(g); return; }
#endif
#if GDISP_HARDWARE_BITFILLS
// Best is hardware bitfills
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- GC->p.x1 = srcx;
- GC->p.y1 = srcy;
- GC->p.x2 = srccx;
- GC->p.ptr = (void *)buffer;
- gdisp_lld_blit_area(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.x1 = srcx;
+ g->p.y1 = srcy;
+ g->p.x2 = srccx;
+ g->p.ptr = (void *)buffer;
+ gdisp_lld_blit_area(g);
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is hardware streaming
@@ -682,21 +729,21 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
srcy = y + cy;
srccx -= cx;
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- gdisp_lld_write_start(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
- for(GC->p.y = y; GC->p.y < srcy; GC->p.y++, buffer += srccx) {
- for(GC->p.x = x; GC->p.x < srcx; GC->p.x++) {
- GC->p.color = *buffer++;
- gdisp_lld_write_color(GC);
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x = x; g->p.x < srcx; g->p.x++) {
+ g->p.color = *buffer++;
+ gdisp_lld_write_color(g);
}
}
- gdisp_lld_write_stop(GC);
+ gdisp_lld_write_stop(g);
#elif GDISP_HARDWARE_FILLS
// Only slightly better than drawing pixels is to look for runs and use fill area
@@ -706,19 +753,19 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
srcy = y + cy;
srccx -= cx;
- GC->p.cy = 1;
- for(GC->p.y = y; GC->p.y < srcy; GC->p.y++, buffer += srccx) {
- for(GC->p.x=x; GC->p.x < srcx; GC->p.x += GC->p.cx) {
- GC->p.cx=1;
- GC->p.color = *buffer++;
- while(GC->p.x+GC->p.cx < srcx && *buffer == GC->p.color) {
- GC->p.cx++;
+ g->p.cy = 1;
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x=x; g->p.x < srcx; g->p.x += g->p.cx) {
+ g->p.cx=1;
+ g->p.color = *buffer++;
+ while(g->p.x+g->p.cx < srcx && *buffer == g->p.color) {
+ g->p.cx++;
buffer++;
}
- if (GC->p.cx == 1) {
- gdisp_lld_draw_pixel(GC);
+ if (g->p.cx == 1) {
+ gdisp_lld_draw_pixel(g);
} else {
- gdisp_lld_fill_area(GC);
+ gdisp_lld_fill_area(g);
}
}
}
@@ -731,135 +778,135 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
srcy = y + cy;
srccx -= cx;
- for(GC->p.y = y; GC->p.y < srcy; GC->p.y++, buffer += srccx) {
- for(GC->p.x=x; GC->p.x < srcx; GC->p.x++) {
- GC->p.color = *buffer++;
- gdisp_lld_draw_pixel(GC);
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x=x; g->p.x < srcx; g->p.x++) {
+ g->p.color = *buffer++;
+ gdisp_lld_draw_pixel(g);
}
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#if GDISP_NEED_CLIP
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- MUTEX_ENTER();
+ void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy) {
+ MUTEX_ENTER(g);
#if GDISP_HARDWARE_CLIP
// Best is using hardware clipping
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- gdisp_lld_set_clip(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_set_clip(g);
#else
// Worst is using software clipping
if (x < 0) { cx += x; x = 0; }
if (y < 0) { cy += y; y = 0; }
- if (cx <= 0 || cy <= 0 || x >= GC->g.Width || y >= GC->g.Height) { MUTEX_EXIT(); return; }
- GC->clipx0 = x;
- GC->clipy0 = y;
- GC->clipx1 = x+cx; if (GC->clipx1 > GC->g.Width) GC->clipx1 = GC->g.Width;
- GC->clipy1 = y+cy; if (GC->clipy1 > GC->g.Height) GC->clipy1 = GC->g.Height;
+ if (cx <= 0 || cy <= 0 || x >= g->g.Width || y >= g->g.Height) { MUTEX_EXIT(g); return; }
+ g->clipx0 = x;
+ g->clipy0 = y;
+ g->clipx1 = x+cx; if (g->clipx1 > g->g.Width) g->clipx1 = g->g.Width;
+ g->clipy1 = y+cy; if (g->clipy1 > g->g.Height) g->clipy1 = g->g.Height;
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_CIRCLE
- void gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
+ void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color) {
coord_t a, b, P;
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
// Calculate intermediates
a = 1;
b = radius;
P = 4 - radius;
- GC->p.color = color;
+ g->p.color = color;
// Away we go using Bresenham's circle algorithm
// Optimized to prevent double drawing
- GC->p.x = x; GC->p.y = y + b; drawpixel_clip();
- GC->p.x = x; GC->p.y = y - b; drawpixel_clip();
- GC->p.x = x + b; GC->p.y = y; drawpixel_clip();
- GC->p.x = x - b; GC->p.y = y; drawpixel_clip();
+ g->p.x = x; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y; drawpixel_clip(g);
do {
- GC->p.x = x + a; GC->p.y = y + b; drawpixel_clip();
- GC->p.x = x + a; GC->p.y = y - b; drawpixel_clip();
- GC->p.x = x + b; GC->p.y = y + a; drawpixel_clip();
- GC->p.x = x - b; GC->p.y = y + a; drawpixel_clip();
- GC->p.x = x - a; GC->p.y = y + b; drawpixel_clip();
- GC->p.x = x - a; GC->p.y = y - b; drawpixel_clip();
- GC->p.x = x + b; GC->p.y = y - a; drawpixel_clip();
- GC->p.x = x - b; GC->p.y = y - a; drawpixel_clip();
+ g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y + a; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y + a; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y - a; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y - a; drawpixel_clip(g);
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
- GC->p.x = x + a; GC->p.y = y + b; drawpixel_clip();
- GC->p.x = x + a; GC->p.y = y - b; drawpixel_clip();
- GC->p.x = x - a; GC->p.y = y + b; drawpixel_clip();
- GC->p.x = x - a; GC->p.y = y - b; drawpixel_clip();
+ g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_CIRCLE
- void gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
+ void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color) {
coord_t a, b, P;
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
// Calculate intermediates
a = 1;
b = radius;
P = 4 - radius;
- GC->p.color = color;
+ g->p.color = color;
// Away we go using Bresenham's circle algorithm
// This is optimized to prevent overdrawing by drawing a line only when a variable is about to change value
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip();
- GC->p.y = y+b; GC->p.x = x; drawpixel_clip();
- GC->p.y = y-b; GC->p.x = x; drawpixel_clip();
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y+b; g->p.x = x; drawpixel_clip(g);
+ g->p.y = y-b; g->p.x = x; drawpixel_clip(g);
do {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip();
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip();
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
if (P < 0) {
P += 3 + 2*a++;
} else {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip();
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip();
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g);
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g);
P += 5 + 2*(a++ - b--);
}
} while(a < b);
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip();
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip();
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ELLIPSE
- void gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
+ void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
coord_t dx, dy;
int32_t a2, b2;
int32_t err, e2;
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
// Calculate intermediates
dx = 0;
@@ -867,14 +914,14 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
a2 = a*a;
b2 = b*b;
err = b2-(2*b-1)*a2;
- GC->p.color = color;
+ g->p.color = color;
// Away we go using Bresenham's ellipse algorithm
do {
- GC->p.x = x + dx; GC->p.y = y + dy; drawpixel_clip();
- GC->p.x = x - dx; GC->p.y = y + dy; drawpixel_clip();
- GC->p.x = x - dx; GC->p.y = y - dy; drawpixel_clip();
- GC->p.x = x + dx; GC->p.y = y - dy; drawpixel_clip();
+ g->p.x = x + dx; g->p.y = y + dy; drawpixel_clip(g);
+ g->p.x = x - dx; g->p.y = y + dy; drawpixel_clip(g);
+ g->p.x = x - dx; g->p.y = y - dy; drawpixel_clip(g);
+ g->p.x = x + dx; g->p.y = y - dy; drawpixel_clip(g);
e2 = 2*err;
if(e2 < (2*dx+1)*b2) {
@@ -888,22 +935,22 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
} while(dy >= 0);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ELLIPSE
- void gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
+ void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
coord_t dx, dy;
int32_t a2, b2;
int32_t err, e2;
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
// Calculate intermediates
dx = 0;
@@ -911,7 +958,7 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
a2 = a*a;
b2 = b*b;
err = b2-(2*b-1)*a2;
- GC->p.color = color;
+ g->p.color = color;
// Away we go using Bresenham's ellipse algorithm
// This is optimized to prevent overdrawing by drawing a line only when a y is about to change value
@@ -922,20 +969,20 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
err += (2*dx+1)*b2;
}
if(e2 > -(2*dy-1)*a2) {
- GC->p.y = y + dy; GC->p.x = x - dx; GC->p.x1 = x + dx; hline_clip();
- if (y) { GC->p.y = y - dy; GC->p.x = x - dx; GC->p.x1 = x + dx; hline_clip(); }
+ g->p.y = y + dy; g->p.x = x - dx; g->p.x1 = x + dx; hline_clip(g);
+ if (y) { g->p.y = y - dy; g->p.x = x - dx; g->p.x1 = x + dx; hline_clip(g); }
dy--;
err -= (2*dy-1)*a2;
}
} while(dy >= 0);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
@@ -944,7 +991,7 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
#include <math.h>
#endif
- void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
+ void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
coord_t a, b, P, sedge, eedge;
uint8_t full, sbit, ebit, tbit;
@@ -970,8 +1017,8 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
for(tbit=sbit<<1; tbit < ebit; tbit<<=1) full |= tbit;
}
- MUTEX_ENTER();
- GC->p.color = color;
+ MUTEX_ENTER(g);
+ g->p.color = color;
if (full) {
// Draw full sectors
@@ -979,33 +1026,33 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
a = 1;
b = radius;
P = 4 - radius;
- if (full & 0x60) { GC->p.y = y+b; GC->p.x = x; drawpixel_clip(); }
- if (full & 0x06) { GC->p.y = y-b; GC->p.x = x; drawpixel_clip(); }
- if (full & 0x81) { GC->p.y = y; GC->p.x = x+b; drawpixel_clip(); }
- if (full & 0x18) { GC->p.y = y; GC->p.x = x-b; drawpixel_clip(); }
+ if (full & 0x60) { g->p.y = y+b; g->p.x = x; drawpixel_clip(g); }
+ if (full & 0x06) { g->p.y = y-b; g->p.x = x; drawpixel_clip(g); }
+ if (full & 0x81) { g->p.y = y; g->p.x = x+b; drawpixel_clip(g); }
+ if (full & 0x18) { g->p.y = y; g->p.x = x-b; drawpixel_clip(g); }
do {
- if (full & 0x01) { GC->p.x = x+b; GC->p.y = y-a; drawpixel_clip(); }
- if (full & 0x02) { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
- if (full & 0x04) { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
- if (full & 0x08) { GC->p.x = x-b; GC->p.y = y-a; drawpixel_clip(); }
- if (full & 0x10) { GC->p.x = x-b; GC->p.y = y+a; drawpixel_clip(); }
- if (full & 0x20) { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
- if (full & 0x40) { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
- if (full & 0x80) { GC->p.x = x+b; GC->p.y = y+a; drawpixel_clip(); }
+ if (full & 0x01) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (full & 0x02) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x04) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x08) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (full & 0x10) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (full & 0x20) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x40) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x80) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
- if (full & 0xC0) { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
- if (full & 0x0C) { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
- if (full & 0x03) { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
- if (full & 0x30) { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
+ if (full & 0xC0) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x0C) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x03) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x30) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
if (full == 0xFF) {
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
MUTEX_EXIT;
@@ -1032,116 +1079,116 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
a = 1;
b = radius;
P = 4 - radius;
- if ((sbit & 0x20) || (ebit & 0x40)) { GC->p.x = x; GC->p.y = y+b; drawpixel_clip(); }
- if ((sbit & 0x02) || (ebit & 0x04)) { GC->p.x = x; GC->p.y = y-b; drawpixel_clip(); }
- if ((sbit & 0x80) || (ebit & 0x01)) { GC->p.x = x+b; GC->p.y = y; drawpixel_clip(); }
- if ((sbit & 0x08) || (ebit & 0x10)) { GC->p.x = x-b; GC->p.y = y; drawpixel_clip(); }
+ if ((sbit & 0x20) || (ebit & 0x40)) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x02) || (ebit & 0x04)) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x80) || (ebit & 0x01)) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if ((sbit & 0x08) || (ebit & 0x10)) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
do {
- if (((sbit & 0x01) && a >= sedge) || ((ebit & 0x01) && a <= eedge)) { GC->p.x = x+b; GC->p.y = y-a; drawpixel_clip(); }
- if (((sbit & 0x02) && a <= sedge) || ((ebit & 0x02) && a >= eedge)) { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
- if (((sbit & 0x04) && a >= sedge) || ((ebit & 0x04) && a <= eedge)) { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
- if (((sbit & 0x08) && a <= sedge) || ((ebit & 0x08) && a >= eedge)) { GC->p.x = x-b; GC->p.y = y-a; drawpixel_clip(); }
- if (((sbit & 0x10) && a >= sedge) || ((ebit & 0x10) && a <= eedge)) { GC->p.x = x-b; GC->p.y = y+a; drawpixel_clip(); }
- if (((sbit & 0x20) && a <= sedge) || ((ebit & 0x20) && a >= eedge)) { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
- if (((sbit & 0x40) && a >= sedge) || ((ebit & 0x40) && a <= eedge)) { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
- if (((sbit & 0x80) && a <= sedge) || ((ebit & 0x80) && a >= eedge)) { GC->p.x = x+b; GC->p.y = y+a; drawpixel_clip(); }
+ if (((sbit & 0x01) && a >= sedge) || ((ebit & 0x01) && a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x02) && a <= sedge) || ((ebit & 0x02) && a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x04) && a >= sedge) || ((ebit & 0x04) && a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x08) && a <= sedge) || ((ebit & 0x08) && a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge) || ((ebit & 0x10) && a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (((sbit & 0x20) && a <= sedge) || ((ebit & 0x20) && a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && a >= sedge) || ((ebit & 0x40) && a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && a <= sedge) || ((ebit & 0x80) && a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
if (((sbit & 0x40) && a >= sedge) || ((ebit & 0x40) && a <= eedge) || ((sbit & 0x80) && a <= sedge) || ((ebit & 0x80) && a >= eedge))
- { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
if (((sbit & 0x04) && a >= sedge) || ((ebit & 0x04) && a <= eedge) || ((sbit & 0x08) && a <= sedge) || ((ebit & 0x08) && a >= eedge))
- { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x01) && a >= sedge) || ((ebit & 0x01) && a <= eedge) || ((sbit & 0x02) && a <= sedge) || ((ebit & 0x02) && a >= eedge))
- { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x10) && a >= sedge) || ((ebit & 0x10) && a <= eedge) || ((sbit & 0x20) && a <= sedge) || ((ebit & 0x20) && a >= eedge))
- { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
} else if (end < start) {
// Draw start/end sector where it is a non-internal angle
// Optimized to prevent double drawing
a = 1;
b = radius;
P = 4 - radius;
- if (sbit & 0x60) { GC->p.x = x; GC->p.y = y+b; drawpixel_clip(); }
- if (sbit & 0x06) { GC->p.x = x; GC->p.y = y-b; drawpixel_clip(); }
- if (sbit & 0x81) { GC->p.x = x+b; GC->p.y = y; drawpixel_clip(); }
- if (sbit & 0x18) { GC->p.x = x-b; GC->p.y = y; drawpixel_clip(); }
+ if (sbit & 0x60) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if (sbit & 0x06) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if (sbit & 0x81) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if (sbit & 0x18) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
do {
- if ((sbit & 0x01) && (a >= sedge || a <= eedge)) { GC->p.x = x+b; GC->p.y = y-a; drawpixel_clip(); }
- if ((sbit & 0x02) && (a <= sedge || a >= eedge)) { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
- if ((sbit & 0x04) && (a >= sedge || a <= eedge)) { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
- if ((sbit & 0x08) && (a <= sedge || a >= eedge)) { GC->p.x = x-b; GC->p.y = y-a; drawpixel_clip(); }
- if ((sbit & 0x10) && (a >= sedge || a <= eedge)) { GC->p.x = x-b; GC->p.y = y+a; drawpixel_clip(); }
- if ((sbit & 0x20) && (a <= sedge || a >= eedge)) { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
- if ((sbit & 0x40) && (a >= sedge || a <= eedge)) { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
- if ((sbit & 0x80) && (a <= sedge || a >= eedge)) { GC->p.x = x+b; GC->p.y = y+a; drawpixel_clip(); }
+ if ((sbit & 0x01) && (a >= sedge || a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if ((sbit & 0x02) && (a <= sedge || a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x04) && (a >= sedge || a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x08) && (a <= sedge || a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if ((sbit & 0x10) && (a >= sedge || a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if ((sbit & 0x20) && (a <= sedge || a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x40) && (a >= sedge || a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x80) && (a <= sedge || a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
if (((sbit & 0x04) && (a >= sedge || a <= eedge)) || ((sbit & 0x08) && (a <= sedge || a >= eedge)))
- { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x40) && (a >= sedge || a <= eedge)) || ((sbit & 0x80) && (a <= sedge || a >= eedge)))
- { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
if (((sbit & 0x01) && (a >= sedge || a <= eedge)) || ((sbit & 0x02) && (a <= sedge || a >= eedge)))
- { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x10) && (a >= sedge || a <= eedge)) || ((sbit & 0x20) && (a <= sedge || a >= eedge)))
- { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
} else {
// Draw start/end sector where it is a internal angle
// Optimized to prevent double drawing
a = 1;
b = radius;
P = 4 - radius;
- if (((sbit & 0x20) && !eedge) || ((sbit & 0x40) && !sedge)) { GC->p.x = x; GC->p.y = y+b; drawpixel_clip(); }
- if (((sbit & 0x02) && !eedge) || ((sbit & 0x04) && !sedge)) { GC->p.x = x; GC->p.y = y-b; drawpixel_clip(); }
- if (((sbit & 0x80) && !eedge) || ((sbit & 0x01) && !sedge)) { GC->p.x = x+b; GC->p.y = y; drawpixel_clip(); }
- if (((sbit & 0x08) && !eedge) || ((sbit & 0x10) && !sedge)) { GC->p.x = x-b; GC->p.y = y; drawpixel_clip(); }
+ if (((sbit & 0x20) && !eedge) || ((sbit & 0x40) && !sedge)) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x02) && !eedge) || ((sbit & 0x04) && !sedge)) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && !eedge) || ((sbit & 0x01) && !sedge)) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if (((sbit & 0x08) && !eedge) || ((sbit & 0x10) && !sedge)) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
do {
- if (((sbit & 0x01) && a >= sedge && a <= eedge)) { GC->p.x = x+b; GC->p.y = y-a; drawpixel_clip(); }
- if (((sbit & 0x02) && a <= sedge && a >= eedge)) { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
- if (((sbit & 0x04) && a >= sedge && a <= eedge)) { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
- if (((sbit & 0x08) && a <= sedge && a >= eedge)) { GC->p.x = x-b; GC->p.y = y-a; drawpixel_clip(); }
- if (((sbit & 0x10) && a >= sedge && a <= eedge)) { GC->p.x = x-b; GC->p.y = y+a; drawpixel_clip(); }
- if (((sbit & 0x20) && a <= sedge && a >= eedge)) { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
- if (((sbit & 0x40) && a >= sedge && a <= eedge)) { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
- if (((sbit & 0x80) && a <= sedge && a >= eedge)) { GC->p.x = x+b; GC->p.y = y+a; drawpixel_clip(); }
+ if (((sbit & 0x01) && a >= sedge && a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x02) && a <= sedge && a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x04) && a >= sedge && a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x08) && a <= sedge && a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge && a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (((sbit & 0x20) && a <= sedge && a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && a >= sedge && a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && a <= sedge && a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
if (((sbit & 0x04) && a >= sedge && a <= eedge) || ((sbit & 0x08) && a <= sedge && a >= eedge))
- { GC->p.x = x-a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x40) && a >= sedge && a <= eedge) || ((sbit & 0x80) && a <= sedge && a >= eedge))
- { GC->p.x = x+a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
if (((sbit & 0x01) && a >= sedge && a <= eedge) || ((sbit & 0x02) && a <= sedge && a >= eedge))
- { GC->p.x = x+a; GC->p.y = y-b; drawpixel_clip(); }
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
if (((sbit & 0x10) && a >= sedge && a <= eedge) || ((sbit & 0x20) && a <= sedge && a >= eedge))
- { GC->p.x = x-a; GC->p.y = y+b; drawpixel_clip(); }
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARC
- void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
+ void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
coord_t a, b, P;
coord_t sy, ey;
fixed sxa, sxb, sxd, exa, exb, exd;
uint8_t qtr;
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
// Do the trig to get the formulas for the start and end lines.
sxa = exa = FIXED(x)+FIXED0_5;
@@ -1170,7 +1217,7 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
a = 1;
b = radius;
P = 4 - radius;
- GC->p.color = color;
+ g->p.color = color;
sxb += sxa;
exb += exa;
@@ -1181,50 +1228,50 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
case 0: // S2E2 sy <= ey
case 1: // S1E2 sy <= ey
if (ey && sy) {
- GC->p.x = x; GC->p.x1 = x; // E2S
+ g->p.x = x; g->p.x1 = x; // E2S
sxa -= sxd; exa -= exd;
} else if (sy) {
- GC->p.x = x-b; GC->p.x1 = x; // C2S
+ g->p.x = x-b; g->p.x1 = x; // C2S
sxa -= sxd;
} else if (ey) {
- GC->p.x = x; GC->p.x1 = x+b; // E2C
+ g->p.x = x; g->p.x1 = x+b; // E2C
exa -= exd;
} else {
- GC->p.x = x-b; GC->p.x1 = x+b; // C2C
+ g->p.x = x-b; g->p.x1 = x+b; // C2C
}
- GC->p.y = y;
- hline_clip();
+ g->p.y = y;
+ hline_clip(g);
do {
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = NONFIXED(sxa); hline_clip(); // E2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
sxa -= sxd; exa -= exd;
} else if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
sxa -= sxd;
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= ey) {
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = NONFIXED(sxb); hline_clip(); // E2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = NONFIXED(sxb); hline_clip(g); // E2S
sxb += sxd; exb += exd;
} else if (-b >= sy) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = NONFIXED(sxb); hline_clip(); // C2S
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
sxb += sxd;
} else if (qtr & 1) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = NONFIXED(sxa); hline_clip(); // E2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
} else if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
@@ -1236,92 +1283,92 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
case 19: // S4E2 sy > ey
case 22: // S3E1 sy > ey
case 23: // S4E1 sy > ey
- GC->p.y = y; GC->p.x = x; GC->p.x1 = x+b; hline_clip(); // SE2C
+ g->p.y = y; g->p.x = x; g->p.x1 = x+b; hline_clip(g); // SE2C
sxa += sxd; exa -= exd;
do {
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
exa -= exd;
} else if (!(qtr & 4)) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
sxa += sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= ey) {
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = x+a; hline_clip(); // E2C
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
exb += exd;
} else if (!(qtr & 4)) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
if (b <= sy) {
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
sxb -= sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
} else if (!(qtr & 4)) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+a; hline_clip(g); // S2C
} else if (!(qtr & 1)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+a; hline_clip(g); // C2C
}
break;
case 4: // S2E1 sy <= ey
case 5: // S1E1 sy <= ey
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
do {
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
sxa -= sxd; exa -= exd;
} else if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
sxa -= sxd;
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= ey) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = NONFIXED(sxb); hline_clip(); // C2S
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = x+a; hline_clip(); // E2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
sxb += sxd; exb += exd;
} else if (-b >= sy) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = NONFIXED(sxb); hline_clip(); // C2S
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
sxb += sxd;
} else if (qtr & 1) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
} else if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
break;
case 8: // S2E3 sy <= ey
@@ -1332,261 +1379,261 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
case 25: // S1E3 sy > ey
case 28: // S2E3 sy > ey
case 29: // S1E3 sy > ey
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x; hline_clip(); // C2SE
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x; hline_clip(g); // C2SE
sxa -= sxd; exa += exd;
do {
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
sxa -= sxd;
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
exa += exd;
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= sy) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = NONFIXED(sxb); hline_clip(); // C2S
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
sxb += sxd;
} else if (qtr & 1) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
if (b <= ey) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = NONFIXED(exb); hline_clip(); // C2E
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
exb -= exd;
} else if (qtr & 4) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
} else if (qtr & 1) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+a; hline_clip(g); // C2C
}
break;
case 10: // S3E3 sy <= ey
case 14: // S3E4 sy <= ey
- GC->p.y = y; GC->p.x = x; drawpixel_clip(); // S2E
+ g->p.y = y; g->p.x = x; drawpixel_clip(g); // S2E
sxa += sxd; exa += exd;
do {
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = NONFIXED(exa); hline_clip(); // S2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
sxa += sxd; exa += exd;
} else if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
exa += exd;
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (b <= sy) {
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = NONFIXED(exb); hline_clip(); // S2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = NONFIXED(exb); hline_clip(g); // S2E
sxb -= sxd; exb -= exd;
} else if (b <= ey) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = NONFIXED(exb); hline_clip(); // C2E
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
exb -= exd;
} else if (qtr & 4) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = NONFIXED(exa); hline_clip(); // S2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
} else if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
case 11: // S4E3 sy <= ey
case 15: // S4E4 sy <= ey
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
do {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
sxa += sxd; exa += exd;
} else if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
exa += exd;
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
if (b <= sy) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = NONFIXED(exb); hline_clip(); // C2E
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
sxb -= sxd; exb -= exd;
} else if (b <= ey) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = NONFIXED(exb); hline_clip(); // C2E
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
exb -= exd;
} else if (qtr & 4) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (a <= sy) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
} else if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
} else if (qtr & 4) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
case 16: // S2E2 sy > ey
case 20: // S2E1 sy > ey
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
sxa -= sxd; exa -= exd;
do {
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
sxa -= sxd; exa -= exd;
} else if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
exa -= exd;
} else if (!(qtr & 4)){
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= sy) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = NONFIXED(sxb); hline_clip(); // C2S
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = x+a; hline_clip(); // E2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
sxb += sxd; exb += exd;
} else if (-b >= ey) {
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = x+a; hline_clip(); // E2C
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
exb += exd;
} else if (!(qtr & 4)){
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = NONFIXED(sxa); hline_clip(); // C2S
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
} else if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
} else if (!(qtr & 4)){
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
break;
case 17: // S1E2 sy > ey
case 21: // S1E1 sy > ey
if (sy) {
- GC->p.x = x; GC->p.x1 = x; // E2S
+ g->p.x = x; g->p.x1 = x; // E2S
sxa -= sxd; exa -= exd;
} else {
- GC->p.x = x; GC->p.x1 = x+b; // E2C
+ g->p.x = x; g->p.x1 = x+b; // E2C
exa -= exd;
}
- GC->p.y = y;
- hline_clip();
+ g->p.y = y;
+ hline_clip(g);
do {
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = NONFIXED(sxa); hline_clip(); // E2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
sxa -= sxd; exa -= exd;
} else if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
exa -= exd;
} else if (!(qtr & 4)) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (-b >= sy) {
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = NONFIXED(sxb); hline_clip(); // E2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = NONFIXED(sxb); hline_clip(g); // E2S
sxb += sxd; exb += exd;
} else if (-b >= ey) {
- GC->p.y = y-b; GC->p.x = NONFIXED(exb); GC->p.x1 = x+a; hline_clip(); // E2C
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
exb += exd;
} else if (!(qtr & 4)) {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (-a >= sy) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = NONFIXED(sxa); hline_clip(); // E2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
} else if (-a >= ey) {
- GC->p.y = y-a; GC->p.x = NONFIXED(exa); GC->p.x1 = x+b; hline_clip(); // E2C
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
} else if (!(qtr & 4)) {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
case 26: // S3E3 sy > ey
case 27: // S4E3 sy > ey
- GC->p.y = y; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
do {
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
sxa += sxd; exa += exd;
} else if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
sxa += sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
- GC->p.y = y-b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
if (b <= ey) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = NONFIXED(exb); hline_clip(); // C2E
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
sxb -= sxd; exb -= exd;
} else if (b <= sy) {
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
sxb -= sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
- GC->p.y = y-a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = NONFIXED(exa); hline_clip(); // C2E
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
} else if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
} else if (!(qtr & 4)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
@@ -1594,52 +1641,52 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
case 31: // S4E4 sy > ey
do {
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = NONFIXED(exa); hline_clip(); // S2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
sxa += sxd; exa += exd;
} else if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
sxa += sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
if (P < 0) {
P += 3 + 2*a++;
} else {
if (b <= ey) {
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = NONFIXED(exb); hline_clip(); // S2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = NONFIXED(exb); hline_clip(g); // S2E
sxb -= sxd; exb -= exd;
} else if (b <= sy) {
- GC->p.y = y+b; GC->p.x = NONFIXED(sxb); GC->p.x1 = x+a; hline_clip(); // S2C
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
sxb -= sxd;
} else if (!(qtr & 1)) {
- GC->p.y = y+b; GC->p.x = x-a; GC->p.x1 = x+a; hline_clip(); // C2C
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
}
P += 5 + 2*(a++ - b--);
}
} while(a < b);
if (a <= ey) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
} else if (a <= sy) {
- GC->p.y = y+a; GC->p.x = NONFIXED(sxa); GC->p.x1 = x+b; hline_clip(); // S2C
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
} else if (!(qtr & 4)) {
- GC->p.y = y+a; GC->p.x = x-b; GC->p.x1 = x+b; hline_clip(); // C2C
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
}
break;
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARC
- void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
+ void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
if (2*radius > cx || 2*radius > cy) {
gdispDrawBox(x, y, cx, cy, color);
return;
@@ -1656,7 +1703,7 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
#endif
#if GDISP_NEED_ARC
- void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
+ void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
coord_t radius2;
radius2 = radius*2;
@@ -1675,49 +1722,49 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
#endif
#if GDISP_NEED_PIXELREAD
- color_t gdispGetPixelColor(coord_t x, coord_t y) {
+ color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y) {
color_t c;
/* Always synchronous as it must return a value */
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
#if GDISP_HARDWARE_PIXELREAD
// Best is direct pixel read
- GC->p.x = x;
- GC->p.y = y;
- c = gdisp_lld_get_pixel_color(GC);
+ g->p.x = x;
+ g->p.y = y;
+ c = gdisp_lld_get_pixel_color(g);
#elif GDISP_HARDWARE_STREAM_READ
// Next best is hardware streaming
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = 1;
- GC->p.cy = 1;
- gdisp_lld_read_start(GC);
- c = gdisp_lld_read_color(GC);
- gdisp_lld_read_stop(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = 1;
+ g->p.cy = 1;
+ gdisp_lld_read_start(g);
+ c = gdisp_lld_read_color(g);
+ gdisp_lld_read_stop(g);
#else
// Worst is "not possible"
#error "GDISP: GDISP_NEED_PIXELREAD has been set but there is no hardware support for reading the display"
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
return c;
}
#endif
#if GDISP_NEED_SCROLL
- void gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
+ void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
coord_t abslines;
#if !GDISP_HARDWARE_SCROLL
coord_t fy, dy, ix, fx, i, j;
#endif
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
#if NEED_CLIPPING
- if (x < GC->clipx0) { cx -= GC->clipx0 - x; x = GC->clipx0; }
- if (y < GC->clipy0) { cy -= GC->clipy0 - y; y = GC->clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GC->clipx1 || y >= GC->clipy1) { MUTEX_EXIT(); return; }
- if (x+cx > GC->clipx1) cx = GC->clipx1 - x;
- if (y+cy > GC->clipy1) cy = GC->clipy1 - y;
+ if (x < g->clipx0) { cx -= g->clipx0 - x; x = g->clipx0; }
+ if (y < g->clipy0) { cy -= g->clipy0 - y; y = g->clipy0; }
+ if (!lines || cx <= 0 || cy <= 0 || x >= g->clipx1 || y >= g->clipy1) { MUTEX_EXIT(g); return; }
+ if (x+cx > g->clipx1) cx = g->clipx1 - x;
+ if (y+cy > g->clipy1) cy = g->clipy1 - y;
#endif
abslines = lines < 0 ? -lines : lines;
@@ -1726,13 +1773,13 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
cy = 0;
} else {
#if GDISP_HARDWARE_SCROLL
- GC->p.x = x;
- GC->p.y = y;
- GC->p.cx = cx;
- GC->p.cy = cy;
- GC->p.y1 = lines;
- GC->p.color = bgcolor;
- gdisp_lld_vertical_scroll(GC);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.y1 = lines;
+ g->p.color = bgcolor;
+ gdisp_lld_vertical_scroll(g);
cy -= abslines;
#elif GDISP_LINEBUF_SIZE == 0
#error "GDISP: GDISP_NEED_SCROLL is set but there is no hardware support and GDISP_LINEBUF_SIZE is zero."
@@ -1759,20 +1806,20 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
// Read one line of data from the screen
#if GDISP_HARDWARE_STREAM_READ
// Best is hardware streaming
- GC->p.x = x+ix;
- GC->p.y = fy+lines;
- GC->p.cx = fx;
- GC->p.cy = 1;
- gdisp_lld_read_start(GC);
+ g->p.x = x+ix;
+ g->p.y = fy+lines;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ gdisp_lld_read_start(g);
for(j=0; j < fx; j++)
- GC->linebuf[j] = gdisp_lld_read_color(GC);
- gdisp_lld_read_stop(GC);
+ g->linebuf[j] = gdisp_lld_read_color(g);
+ gdisp_lld_read_stop(g);
#elif GDISP_HARDWARE_PIXELREAD
// Next best is single pixel reads
for(j=0; j < fx; j++) {
- GC->p.x = x+ix+j;
- GC->p.y = fy+lines;
- GC->linebuf[j] = gdisp_lld_get_pixel_color(GC);
+ g->p.x = x+ix+j;
+ g->p.y = fy+lines;
+ g->linebuf[j] = gdisp_lld_get_pixel_color(g);
}
#else
// Worst is "not possible"
@@ -1782,36 +1829,36 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
// Write that line to the new location
#if GDISP_HARDWARE_BITFILLS
// Best is hardware bitfills
- GC->p.x = x+ix;
- GC->p.y = fy;
- GC->p.cx = fx;
- GC->p.cy = 1;
- GC->p.x1 = 0;
- GC->p.y1 = 0;
- GC->p.x2 = fx;
- GC->p.ptr = (void *)GC->linebuf;
- gdisp_lld_blit_area(GC);
+ g->p.x = x+ix;
+ g->p.y = fy;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.x2 = fx;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
#elif GDISP_HARDWARE_STREAM_WRITE
// Next best is hardware streaming
- GC->p.x = x+ix;
- GC->p.y = fy;
- GC->p.cx = fx;
- GC->p.cy = 1;
- gdisp_lld_write_start(GC);
+ g->p.x = x+ix;
+ g->p.y = fy;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ gdisp_lld_write_start(g);
#if GDISP_HARDWARE_STREAM_POS
- gdisp_lld_write_pos(GC);
+ gdisp_lld_write_pos(g);
#endif
for(j = 0; j < fx; j++) {
- GC->p.color = GC->linebuf[j];
- gdisp_lld_write_color(GC);
+ g->p.color = g->linebuf[j];
+ gdisp_lld_write_color(g);
}
- gdisp_lld_write_stop(GC);
+ gdisp_lld_write_stop(g);
#else
// Worst is drawing pixels
- GC->p.y = fy;
- for(GC->p.x = x+ix, j = 0; j < fx; GC->p.x++, j++) {
- GC->p.color = GC->linebuf[j];
- gdisp_lld_draw_pixel(GC);
+ g->p.y = fy;
+ for(g->p.x = x+ix, j = 0; j < fx; g->p.x++, j++) {
+ g->p.color = g->linebuf[j];
+ gdisp_lld_draw_pixel(g);
}
#endif
}
@@ -1820,45 +1867,45 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
}
/* fill the remaining gap */
- GC->p.x = x;
- GC->p.y = lines > 0 ? (y+cy) : y;
- GC->p.cx = cx;
- GC->p.cy = abslines;
- GC->p.color = bgcolor;
- fillarea();
- MUTEX_EXIT();
+ g->p.x = x;
+ g->p.y = lines > 0 ? (y+cy) : y;
+ g->p.cx = cx;
+ g->p.cy = abslines;
+ g->p.color = bgcolor;
+ fillarea(g);
+ MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_CONTROL
#if GDISP_HARDWARE_CONTROL
- void gdispControl(unsigned what, void *value) {
- MUTEX_ENTER();
- GC->p.x = what;
- GC->p.ptr = value;
- gdisp_lld_control(GC);
+ void gdispGControl(GDisplay *g, unsigned what, void *value) {
+ MUTEX_ENTER(g);
+ g->p.x = what;
+ g->p.ptr = value;
+ gdisp_lld_control(g);
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
if (what == GDISP_CONTROL_ORIENTATION) {
#if GDISP_HARDWARE_CLIP
// Best is hardware clipping
- GC->p.x = 0;
- GC->p.y = 0;
- GC->p.cx = GC->g.Width;
- GC->p.cy = GC->g.Height;
- gdisp_lld_set_clip(GC);
+ g->p.x = 0;
+ g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ gdisp_lld_set_clip(g);
#else
// Worst is software clipping
- GC->clipx0 = 0;
- GC->clipy0 = 0;
- GC->clipx1 = GC->g.Width;
- GC->clipy1 = GC->g.Height;
+ g->clipx0 = 0;
+ g->clipy0 = 0;
+ g->clipx1 = g->g.Width;
+ g->clipy1 = g->g.Height;
#endif
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#else
- void gdispControl(unsigned what, void *value) {
+ void gdispGControl(GDisplay *g, unsigned what, void *value) {
(void)what;
(void)value;
/* Ignore everything */
@@ -1868,17 +1915,17 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
#if GDISP_NEED_QUERY
#if GDISP_HARDWARE_QUERY
- void *gdispQuery(unsigned what) {
+ void *gdispGQuery(GDisplay *g, unsigned what) {
void *res;
- MUTEX_ENTER();
- GC->p.x = (coord_t)what;
- res = gdisp_lld_query(GC);
- MUTEX_EXIT();
+ MUTEX_ENTER(g);
+ g->p.x = (coord_t)what;
+ res = gdisp_lld_query(g);
+ MUTEX_EXIT(g);
return res;
}
#else
- void *gdispQuery(unsigned what) {
+ void *gdispGQuery(GDisplay *g, unsigned what) {
(void) what;
return (void *)-1;
}
@@ -1889,63 +1936,63 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
/* High Level Driver Routines. */
/*===========================================================================*/
-void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
+void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
if (cx <= 0 || cy <= 0) return;
cx = x+cx-1; cy = y+cy-1; // cx, cy are now the end point.
- MUTEX_ENTER();
+ MUTEX_ENTER(g);
- GC->p.color = color;
+ g->p.color = color;
if (cx - x > 2) {
- GC->p.x = x; GC->p.y = y; GC->p.x1 = cx; hline_clip();
+ g->p.x = x; g->p.y = y; g->p.x1 = cx; hline_clip(g);
if (y != cy) {
- GC->p.x = x; GC->p.y = cy; GC->p.x1 = cx; hline_clip();
+ g->p.x = x; g->p.y = cy; g->p.x1 = cx; hline_clip(g);
if (cy - y > 2) {
y++; cy--;
- GC->p.x = x; GC->p.y = y; GC->p.y1 = cy; vline_clip();
- GC->p.x = cx; GC->p.y = y; GC->p.y1 = cy; vline_clip();
+ g->p.x = x; g->p.y = y; g->p.y1 = cy; vline_clip(g);
+ g->p.x = cx; g->p.y = y; g->p.y1 = cy; vline_clip(g);
}
}
} else {
- GC->p.x = x; GC->p.y = y; GC->p.y1 = cy; vline_clip();
+ g->p.x = x; g->p.y = y; g->p.y1 = cy; vline_clip(g);
if (x != cx) {
- GC->p.x = cx; GC->p.y = y; GC->p.y1 = cy; vline_clip();
+ g->p.x = cx; g->p.y = y; g->p.y1 = cy; vline_clip(g);
}
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
#if GDISP_NEED_CONVEX_POLYGON
- void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
+ void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *epnt, *p;
epnt = &pntarray[cnt-1];
- MUTEX_ENTER();
- GC->p.color = color;
+ MUTEX_ENTER(g);
+ g->p.color = color;
for(p = pntarray; p < epnt; p++) {
- GC->p.x=tx+p->x; GC->p.y=ty+p->y; GC->p.x1=tx+p[1].x; GC->p.y1=ty+p[1].y; line_clip();
+ g->p.x=tx+p->x; g->p.y=ty+p->y; g->p.x1=tx+p[1].x; g->p.y1=ty+p[1].y; line_clip(g);
}
- GC->p.x=tx+p->x; GC->p.y=ty+p->y; GC->p.x1=tx+pntarray->x; GC->p.y1=ty+pntarray->y; line_clip();
+ g->p.x=tx+p->x; g->p.y=ty+p->y; g->p.x1=tx+pntarray->x; g->p.y1=ty+pntarray->y; line_clip(g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
+ void gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *lpnt, *rpnt, *epnts;
fixed lx, rx, lk, rk;
coord_t y, ymax, lxc, rxc;
@@ -1975,8 +2022,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
lk = (FIXED(lpnt->x) - lx) / (lpnt->y - y);
rk = (FIXED(rpnt->x) - rx) / (rpnt->y - y);
- MUTEX_ENTER();
- GC->p.color = color;
+ MUTEX_ENTER(g);
+ g->p.color = color;
while(1) {
/* Determine our boundary */
ymax = rpnt->y < lpnt->y ? rpnt->y : lpnt->y;
@@ -1991,9 +2038,9 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
* of pixels.
*/
if (lxc < rxc) {
- GC->p.x=tx+lxc; GC->p.y=ty+y; GC->p.x1=tx+rxc-1; hline_clip();
+ g->p.x=tx+lxc; g->p.y=ty+y; g->p.x1=tx+rxc-1; hline_clip(g);
} else if (lxc > rxc) {
- GC->p.x=tx+rxc; GC->p.y=ty+y; GC->p.x1=tx+lxc-1; hline_clip();
+ g->p.x=tx+rxc; g->p.y=ty+y; g->p.x1=tx+lxc-1; hline_clip(g);
}
lx += lk;
@@ -2002,12 +2049,12 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
if (!cnt) {
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
return;
}
cnt--;
@@ -2017,12 +2064,12 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
for (lpnt = lpnt <= pntarray ? epnts : lpnt-1; lpnt->y == y; cnt--) {
if (!cnt) {
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
return;
}
lx = FIXED(lpnt->x);
@@ -2033,12 +2080,12 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
for (rpnt = rpnt >= epnts ? pntarray : rpnt+1; rpnt->y == y; cnt--) {
if (!cnt) {
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
return;
}
rx = FIXED(rpnt->x);
@@ -2055,27 +2102,27 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_ANTIALIAS && GDISP_HARDWARE_PIXELREAD
static void drawcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
- #define GD ((GDISPDriver *)state)
+ #define GD ((GDisplay *)state)
if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha == 255) {
GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1; GD->p.color = GD->t.color;
- hline_clip();
+ hline_clip(g);
} else {
for (; count; count--, x++) {
GD->p.x = x; GD->p.y = y;
GD->p.color = gdispBlendColor(GD->t.color, gdisp_lld_get_pixel_color(GD), alpha);
- drawpixel_clip();
+ drawpixel_clip(g);
}
}
#undef GD
}
#else
static void drawcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
- #define GD ((GDISPDriver *)state)
+ #define GD ((GDisplay *)state)
if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha > 0x80) { // A best approximation when using anti-aliased fonts but we can't actually draw them anti-aliased
GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1; GD->p.color = GD->t.color;
- hline_clip();
+ hline_clip(g);
}
#undef GD
}
@@ -2083,7 +2130,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_ANTIALIAS
static void fillcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
- #define GD ((GDISPDriver *)state)
+ #define GD ((GDisplay *)state)
if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha == 255) {
GD->p.color = GD->t.color;
@@ -2091,7 +2138,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
GD->p.color = gdispBlendColor(GD->t.color, GD->t.bgcolor, alpha);
}
GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1;
- hline_clip();
+ hline_clip(g);
#undef GD
}
#else
@@ -2100,110 +2147,110 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
/* Callback to render characters. */
static uint8_t drawcharglyph(int16_t x, int16_t y, mf_char ch, void *state) {
- return mf_render_character(GC->t.font, x, y, ch, drawcharline, state);
+ return mf_render_character(g->t.font, x, y, ch, drawcharline, state);
}
/* Callback to render characters. */
static uint8_t fillcharglyph(int16_t x, int16_t y, mf_char ch, void *state) {
- return mf_render_character(GC->t.font, x, y, ch, fillcharline, state);
+ return mf_render_character(g->t.font, x, y, ch, fillcharline, state);
}
- void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) {
- MUTEX_ENTER();
- GC->t.font = font;
- GC->t.clipx0 = x;
- GC->t.clipy0 = y;
- GC->t.clipx1 = x + mf_character_width(font, c) + font->baseline_x;
- GC->t.clipy1 = y + font->height;
- GC->t.color = color;
- mf_render_character(font, x, y, c, drawcharline, GC);
+ void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x + mf_character_width(font, c) + font->baseline_x;
+ g->t.clipy1 = y + font->height;
+ g->t.color = color;
+ mf_render_character(font, x, y, c, drawcharline, g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) {
- MUTEX_ENTER();
- GC->p.cx = mf_character_width(font, c) + font->baseline_x;
- GC->p.cy = font->height;
- GC->t.font = font;
- GC->t.clipx0 = GC->p.x = x;
- GC->t.clipy0 = GC->p.y = y;
- GC->t.clipx1 = GC->p.x+GC->p.cx;
- GC->t.clipy1 = GC->p.y+GC->p.cy;
- GC->t.color = color;
- GC->t.bgcolor = GC->p.color = bgcolor;
-
- TEST_CLIP_AREA(GC->p.x, GC->p.y, GC->p.cx, GC->p.cy) {
- fillarea();
- mf_render_character(font, x, y, c, fillcharline, GC);
+ void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) {
+ MUTEX_ENTER(g);
+ g->p.cx = mf_character_width(font, c) + font->baseline_x;
+ g->p.cy = font->height;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = g->p.x+g->p.cx;
+ g->t.clipy1 = g->p.y+g->p.cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
+
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
+ mf_render_character(font, x, y, c, fillcharline, g);
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color) {
- MUTEX_ENTER();
- GC->t.font = font;
- GC->t.clipx0 = x;
- GC->t.clipy0 = y;
- GC->t.clipx1 = x + mf_get_string_width(font, str, 0, 0);
- GC->t.clipy1 = y + font->height;
- GC->t.color = color;
+ void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x + mf_get_string_width(font, str, 0, 0);
+ g->t.clipy1 = y + font->height;
+ g->t.color = color;
- mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, drawcharglyph, GC);
+ mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, drawcharglyph, g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor) {
- MUTEX_ENTER();
- GC->p.cx = mf_get_string_width(font, str, 0, 0);
- GC->p.cy = font->height;
- GC->t.font = font;
- GC->t.clipx0 = GC->p.x = x;
- GC->t.clipy0 = GC->p.y = y;
- GC->t.clipx1 = GC->p.x+GC->p.cx;
- GC->t.clipy1 = GC->p.y+GC->p.cy;
- GC->t.color = color;
- GC->t.bgcolor = GC->p.color = bgcolor;
-
- TEST_CLIP_AREA(GC->p.x, GC->p.y, GC->p.cx, GC->p.cy) {
- fillarea();
- mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, fillcharglyph, GC);
+ void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor) {
+ MUTEX_ENTER(g);
+ g->p.cx = mf_get_string_width(font, str, 0, 0);
+ g->p.cy = font->height;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = g->p.x+g->p.cx;
+ g->t.clipy1 = g->p.y+g->p.cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
+
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
+ mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, fillcharglyph, g);
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) {
- MUTEX_ENTER();
- GC->t.font = font;
- GC->t.clipx0 = x;
- GC->t.clipy0 = y;
- GC->t.clipx1 = x+cx;
- GC->t.clipy1 = y+cy;
- GC->t.color = color;
+ void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x+cx;
+ g->t.clipy1 = y+cy;
+ g->t.color = color;
/* Select the anchor position */
switch(justify) {
@@ -2219,33 +2266,33 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
}
y += (cy+1 - font->height)/2;
- mf_render_aligned(font, x, y, justify, str, 0, drawcharglyph, GC);
+ mf_render_aligned(font, x, y, justify, str, 0, drawcharglyph, g);
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
- void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) {
- MUTEX_ENTER();
- GC->p.cx = cx;
- GC->p.cy = cy;
- GC->t.font = font;
- GC->t.clipx0 = GC->p.x = x;
- GC->t.clipy0 = GC->p.y = y;
- GC->t.clipx1 = x+cx;
- GC->t.clipy1 = y+cy;
- GC->t.color = color;
- GC->t.bgcolor = GC->p.color = bgcolor;
+ void gdispGFillStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) {
+ MUTEX_ENTER(g);
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = x+cx;
+ g->t.clipy1 = y+cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
- TEST_CLIP_AREA(GC->p.x, GC->p.y, GC->p.cx, GC->p.cy) {
+ TEST_CLIP_AREA(g) {
// background fill
- fillarea();
+ fillarea(g);
/* Select the anchor position */
switch(justify) {
@@ -2262,16 +2309,16 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
y += (cy+1 - font->height)/2;
/* Render */
- mf_render_aligned(font, x, y, justify, str, 0, fillcharglyph, GC);
+ mf_render_aligned(font, x, y, justify, str, 0, fillcharglyph, g);
}
#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
- if ((GC->flags & GDISP_FLG_SCRSTREAM)) {
- gdisp_lld_write_stop(GC);
- GC->flags &= ~GDISP_FLG_SCRSTREAM;
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
#endif
- MUTEX_EXIT();
+ MUTEX_EXIT(g);
}
coord_t gdispGetFontMetric(font_t font, fontmetric_t metric) {
diff --git a/src/gfx.c b/src/gfx.c
index 92533937..09d0798b 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -71,7 +71,6 @@ void gfxInit(void) {
#endif
#if GFX_USE_GDISP
_gdispInit();
- gdispClear(Black);
#endif
#if GFX_USE_GWIN
_gwinInit();