예제 #1
0
파일: ddinit.c 프로젝트: antrik/libggi
int
GGI_directx_DDChangeMode(struct ggi_visual *vis, ggi_mode *mode)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	/* destroy any existing surface */
	DDDestroySurface(priv);

	/* recreate the primary surface and back storage */
	if (!DDCreateSurface(priv, mode))
		return 0;

	if (!priv->fullscreen)
		/* set the new window size */
		DDChangeWindow(priv, mode->visible.x, mode->visible.y);

	/* set a timer to have the window refreshed at regular intervals,
	   and show the window */
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC))
		priv->timer_id = SetTimer(priv->hWnd, 1, 33, NULL);
	ShowWindow(priv->hWnd, SW_SHOWNORMAL);
	if (priv->hParent == NULL)
		SetForegroundWindow(priv->hWnd);

	return 1;
}
예제 #2
0
파일: ddinit.c 프로젝트: antrik/libggi
static int
DDCreateThread(struct ggi_visual *vis)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	priv->hInit = CreateEvent(NULL, FALSE, FALSE, NULL);
#ifdef __CYGWIN__
	if (pthread_create((pthread_t *)&priv->hThread, NULL, DDEventLoop, vis))
		priv->nThreadID = 0;
	/*
	priv->hThread = CreateThread(NULL, 0,
				     (LPTHREAD_START_ROUTINE) DDEventLoop,
				     vis, 0, &priv->nThreadID);
	*/
#else
	priv->hThread =
	    (HANDLE) _beginthreadex(NULL, 0, DDEventLoop, vis, 0,
				    (unsigned) &priv->nThreadID);
#endif
	if (priv->hThread) {
		WaitForSingleObject(priv->hInit, INFINITE);
		return 1;
	} else {
		CloseHandle(priv->hInit);
		priv->hInit = NULL;
		return 0;
	}
}
예제 #3
0
파일: ddinit.c 프로젝트: antrik/libggi
int
GGI_directx_DDMatchMode(struct ggi_visual *vis, ggi_mode *mode,
	    int *depth, int *defwidth, int *defheight)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	HRESULT hr;
	matchmode mm;
	int result = 1;

	mm.vis = vis;
	mm.mode = mode;
	mm.bestx = mm.besty = mm.bits = 0;
	mm.x = mode->visible.x;
	mm.y = mode->visible.y;
	if (mm.x == GGI_AUTO)
		mm.x = mode->virt.x;
	if (mm.y == GGI_AUTO)
		mm.y = mode->virt.y;

	hr = IDirectDraw2_EnumDisplayModes(priv->lpddext,
		0, NULL, &mm, ModeCallback);

	*depth = mm.bits;
	*defwidth = mm.bestx;
	*defheight = mm.besty;

	return result;
}
예제 #4
0
파일: ddinit.c 프로젝트: antrik/libggi
static int
DDCreateWindow(struct ggi_visual *vis)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	int w = 640, h = 480;	/* default window size */
	int ws_flags = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
	/* toplevel flags */

	if (priv->hParent) {
		/* determine the parent window size */
		RECT r;
		GetWindowRect(priv->hParent, &r);
		w = r.right - r.left;
		h = r.bottom - r.top;
		/* flags for a child window */
		ws_flags = WS_CHILD;
	} else if (priv->fullscreen)
		ws_flags = WS_VISIBLE | WS_POPUP;
	else {
		/* adjust the window size to accommodate for
		 * the client area
		 */
		RECT r;
		r.left = r.top = 0;
		r.right = w;
		r.bottom = h;
		AdjustWindowRectEx(&r, ws_flags, 0, 0);
		w = r.right - r.left;
		h = r.bottom - r.top;
	}

	/* create the window */
	priv->hWnd = CreateWindowEx(0, NAME, TITLE, ws_flags,
				    CW_USEDEFAULT, 0, w, h,
				    priv->hParent, NULL,
				    priv->hInstance, vis);
	if (!priv->hWnd) {
		if (priv->hCursor)
			DestroyCursor(priv->hCursor);
		priv->hCursor = NULL;
		return 0;
	}

	/* make sure the window is initially hidden */
	ShowWindow(priv->hWnd, SW_HIDE);

	/* initialize the DirectDraw interface */
	DirectDrawCreate(NULL, &priv->lpdd, NULL);
	IDirectDraw_QueryInterface(priv->lpdd, &IID_IDirectDraw2,
				   (LPVOID *) & priv->lpddext);

	return 1;
}
예제 #5
0
파일: ddinit.c 프로젝트: antrik/libggi
static void
DDNotifyResize(struct ggi_visual *vis, int xsize, int ysize)
{
	gii_event ev;
	ggi_cmddata_switchrequest *swreq;
	directx_priv *priv = GGIDIRECTX_PRIV(vis);

	DPRINT_DRAW("DDNotifyResize(%p, %dx%d) called\n",
		       vis, xsize, ysize);

	if (!priv->inp)
		return;

	/* This is racy, what if window is resized and
	 * resized back before the app gets to react
	 * to the first resize notification?
	 */
	if (!LIBGGI_X(vis) || !LIBGGI_Y(vis)) {
		DPRINT_DRAW("DDNotifyResize: No old size, ignore\n");
		return;
	}
	if ((LIBGGI_X(vis) == xsize) &&
	    (LIBGGI_Y(vis) == ysize))
	{
		DPRINT_DRAW("DDNotifyResize: Same size, ignore\n");
		return;
	}
	DPRINT_DRAW("DDNotifyResize: Old size %ux%u\n",
		LIBGGI_X(vis), LIBGGI_Y(vis));

	ev.any.size=	sizeof(gii_cmd_nodata_event) +
			sizeof(ggi_cmddata_switchrequest);
	ev.any.type=	evCommand;
	ev.cmd.code=	GGICMD_REQUEST_SWITCH;

	swreq = (ggi_cmddata_switchrequest *) ev.cmd.data;
	swreq->request = GGI_REQSW_MODE;
	swreq->mode = *LIBGGI_MODE(vis);

	swreq->mode.visible.x = xsize;
	swreq->mode.visible.y = ysize;
	if (swreq->mode.virt.x < xsize)
		swreq->mode.virt.x = xsize;
	if (swreq->mode.virt.y < ysize)
		swreq->mode.virt.y = ysize;
	swreq->mode.size.x = GGI_AUTO;
	swreq->mode.size.y = GGI_AUTO;

	ggControl(priv->inp->channel, GII_CMDCODE_RESIZE, &ev);
}
예제 #6
0
파일: visual.c 프로젝트: Nekrofage/DoomRPi
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;
}
예제 #7
0
파일: visual.c 프로젝트: Nekrofage/DoomRPi
static int
GGI_directx_setflags(ggi_visual *vis, ggi_flags flags)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);

	if ((LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC) && !(flags & GGIFLAG_ASYNC))
		ggiFlush(vis);
	/* Clear out unknown flags */
	LIBGGI_FLAGS(vis) = flags & GGIFLAG_ASYNC;

	if(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC) {
		if (priv->timer_id)
			KillTimer(priv->hWnd, priv->timer_id);
		priv->timer_id = 0;
	}
	else
		priv->timer_id = SetTimer(priv->hWnd, 1, 33, NULL);
	return GGI_OK;
}
예제 #8
0
파일: ddinit.c 프로젝트: antrik/libggi
void
GGI_directx_DDRedraw(struct ggi_visual *vis, int x, int y, int w, int h)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	RECT SrcWinPos, DestWinPos;
	HRESULT hr;

	hr = IDirectDrawSurface_IsLost(priv->lppdds);
	if (FAILED(hr))
		return;

	SrcWinPos.left   = x;
	SrcWinPos.right  = x + w;
	SrcWinPos.top    = y;
	SrcWinPos.bottom = y + h;
	DestWinPos = SrcWinPos;
	DestWinPos.right -= vis->origin_x;
	if (DestWinPos.right <= 0)
		return;
	DestWinPos.bottom -= vis->origin_y;
	if (DestWinPos.bottom <= 0)
		return;
	DestWinPos.left -= vis->origin_x;
	if (DestWinPos.left < 0) {
		SrcWinPos.left -= DestWinPos.left;
		DestWinPos.left = 0;
	}
	DestWinPos.top -= vis->origin_y;
	if (DestWinPos.top < 0) {
		SrcWinPos.top -= DestWinPos.top;
		DestWinPos.top = 0;
	}
	ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.left);
	ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.right);
	/* draw the stored image on the primary surface */
	IDirectDrawSurface_Blt(priv->lppdds, &DestWinPos,
			       priv->lpbdds[vis->d_frame_num], &SrcWinPos,
			       DDBLT_WAIT, NULL);
}
예제 #9
0
파일: ddinit.c 프로젝트: antrik/libggi
int
GGI_directx_DDInit(struct ggi_visual *vis)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	/* get the application instance */
	priv->hInstance = GetModuleHandle(NULL);

	/* create and register the window class */
	DDCreateClass(priv);

	if (priv->hParent) {
		/* create the window */
		if (!DDCreateWindow(vis))
			return 0;
	} else {
		/* start the event loop here */
		if (!DDCreateThread(vis)) {
			GGI_directx_DDShutdown(priv);
			return 0;
		}
	}
	return 1;
}
예제 #10
0
파일: ddinit.c 프로젝트: antrik/libggi
void
GGI_directx_DDRedrawAll(struct ggi_visual *vis)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	RECT SrcWinPos, DestWinPos;
	HRESULT hr;

	hr = IDirectDrawSurface_IsLost(priv->lppdds);
	if (FAILED(hr))
		return;

	GetClientRect(priv->hWnd, &SrcWinPos);
	SrcWinPos.left   += vis->origin_x;
	SrcWinPos.top    += vis->origin_y;
	SrcWinPos.right  += vis->origin_x;
	SrcWinPos.bottom += vis->origin_y;
	GetClientRect(priv->hWnd, &DestWinPos);
	ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.left);
	ClientToScreen(priv->hWnd, (POINT *) & DestWinPos.right);
	/* draw the stored image on the primary surface */
	IDirectDrawSurface_Blt(priv->lppdds, &DestWinPos,
			       priv->lpbdds[vis->d_frame_num], &SrcWinPos,
			       DDBLT_WAIT, NULL);
}
예제 #11
0
파일: ddinit.c 프로젝트: antrik/libggi
static unsigned __stdcall
DDEventLoop(void *lpParm)
{
	MSG msg;
	struct ggi_visual *vis = (struct ggi_visual *) lpParm;
	directx_priv *priv = GGIDIRECTX_PRIV(vis);

	priv->nThreadID = GetCurrentThreadId();

	/* create the window */
	if (!DDCreateWindow(vis)) {
		SetEvent(priv->hInit);
		return 0;
	}

	SetEvent(priv->hInit);

	while (GetMessage(&msg, NULL, 0, 0)) {
		if (msg.hwnd == NULL && msg.message == WM_DDEND) {
			/* Use PostThreadMessage to get here */
			DPRINT("Ending session, "
				  "destroying window.\n");
			DestroyWindow(priv->hWnd);
			break;
		}
		if (msg.hwnd == NULL && msg.message == WM_DDFULLSCREEN) {
			directx_fullscreen *dxfull =
				(directx_fullscreen *)msg.lParam;
			if (!dxfull) {
				fprintf(stderr, "Aieee! "
					"No lParam for WM_DDFULLSCREEN\n");
				exit(1);
			}
			DPRINT_MODE("Set coop level\n");
			dxfull->hr = IDirectDraw2_SetCooperativeLevel(
				dxfull->priv->lpddext, dxfull->priv->hWnd,
				DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
			if (FAILED(dxfull->hr))
				DPRINT_MODE("SetCooperativeLevel failed %x\n",
					dxfull->hr);
			DPRINT_MODE("Set fullscreen mode "
				"(%i,%i) size %d\n",
				dxfull->mode->visible.x,
				dxfull->mode->visible.y,
				GT_SIZE(dxfull->mode->graphtype));
			dxfull->hr = IDirectDraw2_SetDisplayMode(
				dxfull->priv->lpddext,
				dxfull->mode->visible.x,
				dxfull->mode->visible.y,
				GT_SIZE(dxfull->mode->graphtype), 0, 0);
			if (FAILED(dxfull->hr))
				DPRINT_MODE("SetDisplayMode failed %x\n",
					dxfull->hr);
			SetEvent(dxfull->event);
			continue;
		}
		if (msg.hwnd == NULL && msg.message == WM_DDHOTKEY) {
			if (msg.wParam) {
				DPRINT("Grab hotkeys\n");
				RegisterHotKey(priv->hWnd, 0x0000,
					MOD_ALT, VK_TAB);
				RegisterHotKey(priv->hWnd, 0x0001,
					MOD_ALT | MOD_SHIFT, VK_TAB);
				RegisterHotKey(priv->hWnd, 0x0002,
					MOD_ALT, VK_F4);
			}
			else {
				DPRINT("Ungrab hotkeys\n");
				UnregisterHotKey(priv->hWnd, 0x0000);
				UnregisterHotKey(priv->hWnd, 0x0001);
				UnregisterHotKey(priv->hWnd, 0x0002);
			}
			continue;
		}

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	DPRINT("Helper thread terminating\n");

#ifndef __CYGWIN__
	_endthreadex(msg.wParam);
#endif
	return msg.wParam;
}
예제 #12
0
파일: ddinit.c 프로젝트: antrik/libggi
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);
}
예제 #13
0
파일: ddinit.c 프로젝트: antrik/libggi
static void
DDSizing(struct ggi_visual *vis, WPARAM wParam, LPRECT rect)
{
	directx_priv *priv = GGIDIRECTX_PRIV(vis);
	int xsize, ysize;
	RECT diff, test1, test2;
	DWORD ws_style = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;

	/* Calculate diff between client and window coords */
	test1.top    = 200;
	test1.left   = 200;
	test1.right  = 400;
	test1.bottom = 400;
	test2 = test1;
	AdjustWindowRectEx(&test2, ws_style, FALSE, 0);
	diff.top    = test1.top    - test2.top;
	diff.bottom = test1.bottom - test2.bottom;
	diff.left   = test1.left   - test2.left;
	diff.right  = test1.right  - test2.right;

	/* Adjust to client coords */
	rect->top    += diff.top;
	rect->bottom += diff.bottom;
	rect->left   += diff.left;
	rect->right  += diff.right;

	/* Calculate new size, with regard to max/min/step */
	xsize = rect->right  - rect->left;
	ysize = rect->bottom - rect->top;
	DPRINT_DRAW("Wants resize to %ux%u\n", xsize, ysize);
	if (xsize < priv->xmin)
		xsize = priv->xmin;
	if (xsize > priv->xmax)
		xsize = priv->xmax;
	if (ysize < priv->ymin)
		ysize = priv->ymin;
	if (ysize > priv->ymax)
		ysize = priv->ymax;
	xsize -= (xsize - priv->xmin) % priv->xstep;
	ysize -= (ysize - priv->ymin) % priv->ystep;

	/* Move the appropriate edge(s) */
	switch (wParam) {
	case WMSZ_LEFT:
	case WMSZ_BOTTOMLEFT:
	case WMSZ_TOPLEFT:
		rect->left = rect->right - xsize;
		break;
	case WMSZ_RIGHT:
	case WMSZ_BOTTOMRIGHT:
	case WMSZ_TOPRIGHT:
		rect->right = rect->left + xsize;
		break;
	}
	switch (wParam) {
	case WMSZ_TOP:
	case WMSZ_TOPRIGHT:
	case WMSZ_TOPLEFT:
		rect->top = rect->bottom - ysize;
		break;
	case WMSZ_BOTTOM:
	case WMSZ_BOTTOMRIGHT:
	case WMSZ_BOTTOMLEFT:
		rect->bottom = rect->top + ysize;
		break;
	}

	/* Adjust back to window coords */
	rect->top    -= diff.top;
	rect->bottom -= diff.bottom;
	rect->left   -= diff.left;
	rect->right  -= diff.right;

	DPRINT_DRAW("Gets resize to %ux%u\n", xsize, ysize);
	DDNotifyResize(vis, xsize, ysize);
}