void gdispImageFree(gdispImage *img, void *ptr, size_t sz) { #if GDISP_NEED_IMAGE_ACCOUNTING gfxFree(ptr); img->memused -= sz; #else (void) img; (void) sz; gfxFree(ptr); #endif }
static bool_t fatfsOpen(GFILE* f, const char* fname) { FIL* fd; #if !GFILE_NEED_NOAUTOMOUNT if (!fatfs_mounted && !fatfsMount("")) return FALSE; #endif if (!(fd = gfxAlloc(sizeof(FIL)))) return FALSE; if (f_open(fd, fname, fatfs_flags2mode(f)) != FR_OK) { gfxFree(fd); f->obj = 0; return FALSE; } f->obj = (void*)fd; #if !GFILE_NEED_NOAUTOSYNC // no need to sync when not opening for write if (f->flags & GFILEFLG_WRITE) { f_sync( (FIL*)f->obj ); } #endif return TRUE; }
// Internal routine for use by GWIN components only // Initialise a window creating it dynamically if required. GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) { // Allocate the structure if necessary if (!pgw) { if (!(pgw = (GWindowObject *)gfxAlloc(vmt->size))) return 0; pgw->flags = flags|GWIN_FLG_DYNAMIC; } else pgw->flags = flags; // Initialise all basic fields pgw->vmt = vmt; pgw->color = defaultFgColor; pgw->bgcolor = defaultBgColor; #if GDISP_NEED_TEXT pgw->font = defaultFont; #endif #if GWIN_NEED_WINDOWMANAGER if (!_GWINwm->vmt->Add(pgw, pInit)) { if ((pgw->flags & GWIN_FLG_DYNAMIC)) gfxFree(pgw); return 0; } #else _gwm_redim(pgw, pInit->x, pInit->y, pInit->width, pInit->height); #endif return (GHandle)pgw; }
static void fatfsClose(GFILE* f) { if ((FIL*)f->obj != 0) { f_close( (FIL*)f->obj ); gfxFree( (FIL*)f->obj ); } }
void gwinSetText(GHandle gh, const char *text, bool_t useAlloc) { if (!(gh->flags & GWIN_FLG_WIDGET)) return; // Dispose of the old string if ((gh->flags & GWIN_FLG_ALLOCTXT)) { gh->flags &= ~GWIN_FLG_ALLOCTXT; if (gw->text) { gfxFree((void *)gw->text); gw->text = ""; } } // Alloc the new text if required if (!text || !*text) gw->text = ""; else if (useAlloc) { char *str; if ((str = gfxAlloc(strlen(text)+1))) { gh->flags |= GWIN_FLG_ALLOCTXT; strcpy(str, text); } gw->text = (const char *)str; } else gw->text = text; _gwinUpdate(gh); }
void gdriverUnRegister(GDriver *driver) { GDriver *pd; // Safety if (!driver) return; // Remove it from the list of drivers if (dhead == driver) dhead = driver->driverchain; else { for(pd = dhead; pd->driverchain; pd = pd->driverchain) { if (pd->driverchain == driver) { pd->driverchain = driver->driverchain; break; } } } // Call the deinit() if (driver->vmt->deinit) driver->vmt->deinit(driver); // Cleanup gfxFree(driver); }
static void ListDestroy(GHandle gh) { const gfxQueueASyncItem* qi; while((qi = gfxQueueASyncGet(&gh2obj->list_head))) gfxFree((void *)qi); _gwidgetDestroy(gh); }
void gdispCloseFont(font_t font) { if ((font->flags & (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) == (FONT_FLAG_DYNAMIC|FONT_FLAG_UNLISTED)) { /* Make sure that no-one can successfully use font after closing */ ((struct mf_font_s *)font)->render_character = 0; /* Release the allocated memory */ gfxFree((void *)font); } }
static void HistoryDestroy(GWindowObject *gh) { #define gcw ((GConsoleObject *)gh) // Deallocate the history buffer if required. if (gcw->buffer) { gfxFree(gcw->buffer); gcw->buffer = 0; } #undef gcw }
GSourceHandle ginputGetMouse(uint16_t instance) { #if GINPUT_MOUSE_NEED_CALIBRATION Calibration *pc; #endif // We only support a single mouse instance currently // Instance 9999 is the same as instance 0 except that it installs // a special "raw" calibration if there isn't one we can load. if (instance && instance != 9999) return 0; // Make sure we have a valid mouse display if (!MouseConfig.display) MouseConfig.display = GDISP; // Do we need to initialise the mouse subsystem? if (!(MouseConfig.flags & FLG_INIT_DONE)) { ginput_lld_mouse_init(); #if GINPUT_MOUSE_NEED_CALIBRATION #if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE if (!MouseConfig.fnloadcal) { MouseConfig.fnloadcal = ginput_lld_mouse_calibration_load; MouseConfig.flags &= ~FLG_CAL_FREE; } if (!MouseConfig.fnsavecal) MouseConfig.fnsavecal = ginput_lld_mouse_calibration_save; #endif if (MouseConfig.fnloadcal && (pc = (Calibration *)MouseConfig.fnloadcal(instance))) { memcpy(&MouseConfig.caldata, pc, sizeof(MouseConfig.caldata)); MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED); if ((MouseConfig.flags & FLG_CAL_FREE)) gfxFree((void *)pc); } else if (instance == 9999) { _tsSetIdentity(&MouseConfig.caldata); MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW); } else ginputCalibrateMouse(instance); #endif // Get the first reading MouseConfig.last_buttons = 0; get_calibrated_reading(&MouseConfig.t); // Mark init as done and start the Poll timer MouseConfig.flags |= FLG_INIT_DONE; gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD); } // Return our structure as the handle return (GSourceHandle)&MouseConfig; }
static gfileList *fatfsFlOpen(const char *path, bool_t dirs) { fatfsList *p; (void) dirs; if (!(p = gfxAlloc(sizeof(fatfsList)))) return 0; if (f_opendir(&p->dir, path) != FR_OK) { gfxFree(p); return 0; } return &p->fl; }
void _gmousePostInitDriver(GDriver *g) { #define m ((GMouse *)g) #if !GINPUT_TOUCH_STARTRAW m->flags |= GMOUSE_FLG_CLIP; #endif #if !GINPUT_TOUCH_NOCALIBRATE && !GINPUT_TOUCH_STARTRAW if ((gmvmt(m)->d.flags & GMOUSE_VFLG_CALIBRATE)) { GMouseCalibration *pc; #if GINPUT_TOUCH_USER_CALIBRATION_LOAD if ((pc = (GMouseCalibration *)LoadMouseCalibration(gdriverGetDriverInstanceNumber((GDriver *)m), sizeof(GMouseCalibration)))) { memcpy(&m->caldata, pc, sizeof(GMouseCalibration)); #if GINPUT_TOUCH_USER_CALIBRATION_FREE gfxFree(pc); #endif m->flags |= GMOUSE_FLG_CALIBRATE; } else #endif if (gmvmt(m)->calload && (pc = (GMouseCalibration *)gmvmt(m)->calload(m, sizeof(GMouseCalibration)))) { memcpy(&m->caldata, pc, sizeof(GMouseCalibration)); if ((gmvmt(m)->d.flags & GMOUSE_VFLG_CAL_LOADFREE)) gfxFree(pc); m->flags |= GMOUSE_FLG_CALIBRATE; } #if !GINPUT_TOUCH_NOCALIBRATE_GUI else while (CalibrateMouse(m)); #endif } #endif // Get the first reading GetMouseReading(m); #undef m }
void gwinListDeleteAll(GHandle gh) { gfxQueueASyncItem* qi; // is it a valid handle? if (gh->vmt != (gwinVMT *)&listVMT) return; while((qi = gfxQueueASyncGet(&gh2obj->list_head))) gfxFree(qi); gh->flags &= ~GLIST_FLG_HASIMAGES; gh2obj->cnt = 0; gh2obj->top = 0; _gwinUpdate(gh); }
void gwinDestroy(GHandle gh) { // Remove from the window manager #if GWIN_NEED_WINDOWMANAGER _GWINwm->vmt->Delete(gh); #endif // Class destroy routine if (gh->vmt->Destroy) gh->vmt->Destroy(gh); // Clean up the structure if (gh->flags & GWIN_FLG_DYNAMIC) { gh->flags = 0; // To be sure, to be sure gfxFree((void *)gh); } else gh->flags = 0; // To be sure, to be sure }
void _gwidgetDestroy(GHandle gh) { #if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL) uint16_t role, instance; #endif // Make the window is invisible so it is not eligible for focus gh->flags &= ~GWIN_FLG_VISIBLE; _gwinFixFocus(gh); // Deallocate the text (if necessary) if ((gh->flags & GWIN_FLG_ALLOCTXT)) { gh->flags &= ~GWIN_FLG_ALLOCTXT; gfxFree((void *)gw->text); } #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE // Detach any toggles from this object for(role = 0; role < wvmt->toggleroles; role++) { instance = wvmt->ToggleGet(gw, role); if (instance != GWIDGET_NO_INSTANCE) { wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE); if (!FindToggleUser(instance)) geventDetachSource(&gl, ginputGetToggle(instance)); } } #endif #if GFX_USE_GINPUT && GINPUT_NEED_DIAL // Detach any dials from this object for(role = 0; role < wvmt->dialroles; role++) { instance = wvmt->DialGet(gw, role); if (instance != GWIDGET_NO_INSTANCE) { wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE); if (!FindDialUser(instance)) geventDetachSource(&gl, ginputGetDial(instance)); } } #endif // Remove any listeners on this object. geventDetachSourceListeners((GSourceHandle)gh); }
bool_t gwinConsoleSetBuffer(GHandle gh, bool_t onoff) { #define gcw ((GConsoleObject *)gh) if (gh->vmt != &consoleVMT) return FALSE; // Do we want the buffer turned off? if (!onoff) { if (gcw->buffer) { gfxFree(gcw->buffer); gcw->buffer = 0; } return FALSE; } // Is the buffer already on? if (gcw->buffer) return TRUE; // Get the number of characters that fit in the x direction #if GWIN_CONSOLE_HISTORY_AVERAGING gcw->bufsize = gh->width / ((2*gdispGetFontMetric(gh->font, fontMinWidth)+gdispGetFontMetric(gh->font, fontMaxWidth))/3); #else gcw->bufsize = gh->width / gdispGetFontMetric(gh->font, fontMinWidth); #endif gcw->bufsize++; // Allow space for a newline on each line. // Multiply by the number of lines gcw->bufsize *= gh->height / gdispGetFontMetric(gh->font, fontHeight); // Allocate the buffer if (!(gcw->buffer = gfxAlloc(gcw->bufsize))) return FALSE; // All good! gh->flags &= ~GCONSOLE_FLG_OVERRUN; gcw->bufpos = 0; return TRUE; #undef gcw }
void gwinListItemDelete(GHandle gh, int item) { const gfxQueueASyncItem * qi; int i; // is it a valid handle? if (gh->vmt != (gwinVMT *)&listVMT) return; // watch out for an invalid item if (item < 0 || item >= gh2obj->cnt) return; for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) { if (i == item) { gfxQueueASyncRemove(&gh2obj->list_head, (gfxQueueASyncItem*)qi); gfxFree((void *)qi); if (gh2obj->top >= item && gh2obj->top) gh2obj->top--; _gwinUpdate(gh); break; } } }
GDriver *gdriverRegister(const GDriverVMT *vmt, void *param) { GDriver * pd; unsigned dinstance, sinstance; // Loop to find the driver instance and the system instance numbers dinstance = sinstance = 0; for(pd = dhead; pd; pd = pd->driverchain) { if (pd->vmt == vmt) dinstance++; if (pd->vmt->type == vmt->type) sinstance++; } // Get a new driver instance of the correct size and initialize it pd = gfxAlloc(vmt->objsize); if (!pd) return 0; memset(pd, 0, vmt->objsize); pd->vmt = vmt; if (vmt->init && !vmt->init(pd, param, dinstance, sinstance)) { gfxFree(pd); return 0; } // Add it to the driver chain if (dhead) dtail->driverchain = pd; else dhead = dtail = pd; // Do the post init if (vmt->postinit) vmt->postinit(pd); return pd; }
static void fatfsFlClose(gfileList *pfl) { f_closedir(&((fatfsList *)pfl)->dir); gfxFree(pfl); }
static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { HDC dc; PAINTSTRUCT ps; GDisplay * g; winPriv * priv; #if GINPUT_NEED_TOGGLE HBRUSH hbrOn, hbrOff; HPEN pen; RECT rect; HGDIOBJ old; POINT p; coord_t pos; uint8_t bit; #endif 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; #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) { 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) { 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) { priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; goto mousemove; } break; case WM_MBUTTONUP: g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; goto mousemove; } break; case WM_RBUTTONDOWN: g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; goto mousemove; } break; case WM_RBUTTONUP: g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA); priv = (winPriv *)g->priv; if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) { 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) break; mousemove: priv->mousex = (coord_t)LOWORD(lParam); priv->mousey = (coord_t)HIWORD(lParam); if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE _gmouseWakeup(priv->mouse); break; #endif case WM_SYSKEYDOWN: case WM_KEYDOWN: case WM_SYSKEYUP: case WM_KEYUP: break; case WM_CHAR: case WM_DEADCHAR: 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 > 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 >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) { pen = CreatePen(PS_SOLID, 1, gdispColor2Native(Black)); hbrOn = CreateSolidBrush(gdispColor2Native(Blue)); hbrOff = CreateSolidBrush(gdispColor2Native(Gray)); old = SelectObject(dc, pen); 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 + 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); } } DeleteObject(hbrOn); DeleteObject(hbrOff); SelectObject(dc, old); } #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); // Actually the above doesn't work (who knows why) ExitProcess(0); break; default: return DefWindowProc(hWnd, Msg, wParam, lParam); } return 0; }
static void ROMFlClose(gfileList *pfl) { gfxFree(pfl); }