static int GGIclose(ggi_visual * vis, struct ggi_dlhandle *dlh) { directx_priv *priv = GGIDIRECTX_PRIV(vis); GGI_directx_Lock(priv->cs); DDShutdown(priv); GGI_directx_Unlock(priv->cs); GGI_directx_LockDestroy(priv->cs); GGI_directx_LockDestroy(priv->spincs); GGI_directx_LockDestroy(priv->sizingcs); free(priv); if (LIBGGI_GC(vis)) free(LIBGGI_GC(vis)); return 0; }
static void DDChangeWindow(directx_priv *priv, DWORD width, DWORD height) { int ws_style = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; RECT r1, r2; if (priv->hParent) return; GGI_directx_Lock(priv->sizingcs); priv->xmin = width; priv->ymin = height; priv->xmax = width; priv->ymax = height; priv->xstep = 1; priv->ystep = 1; GGI_directx_Unlock(priv->sizingcs); GetWindowRect(priv->hWnd, &r1); r2 = r1; AdjustWindowRectEx(&r2, ws_style, FALSE, 0); MoveWindow(priv->hWnd, r1.left, r1.top, width + (r2.right - r2.left) - (r1.right - r1.left), height + (r2.bottom - r2.top) - (r1.bottom - r1.top), TRUE); }
static long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LPCREATESTRUCT lpcs; PAINTSTRUCT ps; RECT dirty; HDC hdc; struct ggi_visual *vis = (struct ggi_visual *) GetWindowLong(hWnd, GWL_USERDATA); directx_priv *priv = NULL; HRESULT hr; if (vis) priv = GGIDIRECTX_PRIV(vis); switch (message) { case WM_DDSETPALETTE: { int setpalette; GGI_directx_Lock(priv->spincs); setpalette = priv->setpalette; GGI_directx_Unlock(priv->spincs); if(setpalette) /* setpalette canceled */ return 0; } if(GGI_directx_TryLock(priv->cs)) { /* spin */ PostMessage(hWnd, message, wParam, lParam); return 0; } if(priv->lpddp) GGI_directx_DDChangePalette(vis); GGI_directx_Lock(priv->spincs); priv->setpalette = 1; GGI_directx_Unlock(priv->spincs); GGI_directx_Unlock(priv->cs); return 0; case WM_TIMER: if (wParam != 1) break; if (GGI_directx_TryLock(priv->cs)) { int redraw = 0; GGI_directx_Lock(priv->spincs); redraw = priv->redraw; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if (redraw) /* spin */ PostMessage(hWnd, WM_USER, wParam, lParam); return 0; } GGI_directx_DDRedrawAll(vis); GGI_directx_Unlock(priv->cs); return 0; case WM_PAINT: if (GGI_directx_TryLock(priv->cs)) { int redraw = 0; GGI_directx_Lock(priv->spincs); redraw = priv->redraw; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if (redraw) /* spin */ InvalidateRect(hWnd, NULL, 0); return 0; } if (GetUpdateRect(hWnd, &dirty, FALSE)) { /* I have a back buffer to update from, * no need to involve the application... if (priv->inp) { gii_event ev; ev.any.size = sizeof(gii_expose_event); ev.any.type = evExpose; ev.any.target = priv->inp->origin; ev.expose.x = vis->origin_x + dirty.left; ev.expose.y = vis->origin_y + dirty.top; ev.expose.w = dirty.right - dirty.left; ev.expose.h = dirty.bottom - dirty.top; giiEventSend(priv->inp, &ev); } */ hr = IDirectDrawSurface_IsLost(priv->lppdds); if (hr == DDERR_SURFACELOST) hr = IDirectDrawSurface_Restore( priv->lppdds); hdc = BeginPaint(hWnd, &ps); GGI_directx_DDRedraw( vis, vis->origin_x + ps.rcPaint.left, vis->origin_y + ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); EndPaint(hWnd, &ps); } GGI_directx_Unlock(priv->cs); return 0; case WM_SIZING: GGI_directx_Lock(priv->sizingcs); if (priv->xstep < 0) { GGI_directx_Unlock(priv->sizingcs); break; } DDSizing(vis, wParam, (LPRECT) lParam); GGI_directx_Unlock(priv->sizingcs); return TRUE; case WM_SIZE: switch(wParam) { case SIZE_MAXIMIZED: case SIZE_RESTORED: break; default: return 0; } GGI_directx_Lock(priv->sizingcs); if (priv->xstep < 0) { GGI_directx_Unlock(priv->sizingcs); break; } DDNotifyResize(vis, LOWORD(lParam), HIWORD(lParam)); GGI_directx_Unlock(priv->sizingcs); return 0; case WM_QUERYNEWPALETTE: if(GGI_directx_TryLock(priv->cs)) { int setpalette = 0; GGI_directx_Lock(priv->spincs); setpalette = priv->setpalette; priv->redraw = 0; GGI_directx_Unlock(priv->spincs); if(setpalette) /* spin */ PostMessage(hWnd, WM_DDSETPALETTE, wParam, lParam); return 0; } if(!priv->lpddp) { GGI_directx_Unlock(priv->cs); break; } GGI_directx_DDChangePalette(vis); GGI_directx_Unlock(priv->cs); return TRUE; case WM_CREATE: lpcs = (LPCREATESTRUCT) lParam; SetWindowLong(hWnd, GWL_USERDATA, (DWORD) lpcs->lpCreateParams); return 0; case WM_CLOSE: DPRINT_EVENTS("WM_CLOSE\n"); if (priv->hParent) break; ggBroadcast(vis->instance.channel, GGI_CMDCODE_CLOSE, NULL); if (priv->exit_on_close_window) exit(0); return 0; case WM_RENDERFORMAT: case WM_RENDERALLFORMATS: { struct ggi_directx_cmddata_render_cb format; format.format = wParam; ggBroadcast(vis->instance.channel, GGI_DIRECTX_RENDERCLIPBOARD, &format); return 0; } case WM_DESTROYCLIPBOARD: ggBroadcast(vis->instance.channel, GGI_DIRECTX_DESTROYCLIPBOARD, NULL); return 0; #if 0 /* WM_CLIPBOARDUPDATE is >= Vista :-( */ case WM_CLIPBOARDUPDATE: ggBroadcast(vis->instance.channel, GGI_DIRECTX_CLIPBOARDUPDATE, NULL); return 0; #endif case WM_SETTINGCHANGE: GGI_directx_Lock(priv->cs); if (priv->settings_changed) { DPRINT("tell inputlib about " "new system parameters\n"); priv->settings_changed(priv->settings_changed_arg); GGI_directx_Unlock(priv->cs); return 0; } GGI_directx_Unlock(priv->cs); break; case WM_SETFOCUS: if (priv->grab_hotkeys) { DPRINT("Grab hotkeys (focus)\n"); PostThreadMessage(priv->nThreadID, WM_DDHOTKEY, 1, 0); } priv->focus = 1; break; case WM_KILLFOCUS: if (priv->grab_hotkeys) { DPRINT("Ungrab hotkeys (unfocus)\n"); PostThreadMessage(priv->nThreadID, WM_DDHOTKEY, 0, 0); } priv->focus = 0; break; case WM_HOTKEY: if (priv->grab_hotkeys && priv->inp) { gii_inputdx_hotkey hotkey; hotkey.id = wParam; hotkey.mod = LOWORD(lParam); hotkey.vk = HIWORD(lParam); DPRINT("WM_HOTKEY id=%d, mod=%04x, vk=%d\n", hotkey.id, hotkey.mod, hotkey.vk); ggControl(priv->inp->channel, GII_INPUTDX_HOTKEY, &hotkey); } break; } return DefWindowProc(hWnd, message, wParam, lParam); }