Пример #1
0
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;
}
Пример #2
0
static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
{
	#if GMOUSE_STMPE811_TEST_MODE
		static GMouseReading n;
	#endif
	uint8_t		status;

	// Button information will be regenerated
	pdr->buttons = 0;

	#if GMOUSE_STMPE811_TEST_MODE
		aquire_bus(m);

		// Set the buttons to match various touch signals
		if ((read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80))
			pdr->buttons |= 0x02;

		status = read_byte(m, STMPE811_REG_FIFO_STA);
		if (!(status & 0x20))
			pdr->buttons |= 0x04;

		#if GMOUSE_STMPE811_GPIO_IRQPIN
			if (getpin_irq(m))
				pdr->buttons |= 0x08;
		#endif

		if ((status & 0x20)) {
			// Nothing in the fifo - just return the last position and pressure
			pdr->x = n.x;
			pdr->y = n.y;
			pdr->z = n.z;
			#if GMOUSE_STMPE811_GPIO_IRQPIN
				write_reg(m, STMPE811_REG_INT_STA, 0xFF);
			#endif
			release_bus(m);
			return TRUE;
		}

	#else
		// Is there a new sample or a touch transition
		#if GMOUSE_STMPE811_GPIO_IRQPIN
			if(!getpin_irq(m))
				return FALSE;
		#endif

		// Is there something in the fifo
		status = read_byte(m, STMPE811_REG_FIFO_STA);
		if ((status & 0x20)) {

			// Nothing in the fifo.

			// If not touched return the pseudo result
			if (!(read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80)) {

				pdr->z = gmvmt(m)->z_min;
				#if GMOUSE_STMPE811_GPIO_IRQPIN
					write_reg(m, STMPE811_REG_INT_STA, 0xFF);
				#endif
				release_bus(m);
				return TRUE;
			}

			// No new result
			#if GMOUSE_STMPE811_GPIO_IRQPIN
				write_reg(m, STMPE811_REG_INT_STA, 0xFF);
			#endif
			release_bus(m);
			return FALSE;
		}

	#endif

	// Time to get some readings
	pdr->x = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_X);
	pdr->y = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_Y);
	#if GMOUSE_STMPE811_READ_PRESSURE
		pdr->z = (coord_t)read_byte(m, STMPE811_REG_TSC_DATA_Z);
	#else
		pdr->z = gmvmt(m)->z_max;
	#endif

	#if !GMOUSE_STMPE811_SLOW_CPU
		if (!(status & 0xC0)) {
			// Is there more data to come
			if (!(read_byte(m, STMPE811_REG_FIFO_STA) & 0x20))
				_gmouseWakeup(m);
		} else
	#endif

	// Clear the rest of the fifo
	{
		write_reg(m, STMPE811_REG_FIFO_STA, 0x01);		// FIFO reset enable
		write_reg(m, STMPE811_REG_FIFO_STA, 0x00);		// FIFO reset disable
	}

	// All done
	#if GMOUSE_STMPE811_GPIO_IRQPIN
		write_reg(m, STMPE811_REG_INT_STA, 0xFF);
	#endif
	release_bus(m);

	#if GMOUSE_STMPE811_TEST_MODE
		// Save the result for later
		n.x = pdr->x;
		n.y = pdr->y;
		n.z = pdr->z;
	#endif

	// Rescale X,Y if we are using self-calibration
	#if GMOUSE_STMPE811_SELF_CALIBRATE
		#if GDISP_NEED_CONTROL
			switch(gdispGGetOrientation(m->display)) {
			default:
			case GDISP_ROTATE_0:
			case GDISP_ROTATE_180:
				pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
				pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
				break;
			case GDISP_ROTATE_90:
			case GDISP_ROTATE_270:
				pdr->x = gdispGGetHeight(m->display) - pdr->x / (4096/gdispGGetHeight(m->display));
				pdr->y = pdr->y / (4096/gdispGGetWidth(m->display));
				break;
			}
		#else
			pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
			pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
		#endif
	#endif

	return TRUE;
}
Пример #3
0
static void ProcessEvent(GDisplay *g, xPriv *priv) {
	switch(evt.type) {
	case MapNotify:
		XSelectInput(dis, evt.xmap.window,
				StructureNotifyMask|ExposureMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|KeymapStateMask);
		g->flags |= GDISP_FLG_READY;
		break;
	case UnmapNotify:
		XCloseDisplay(dis);
		exit(0);
		break;
	case ClientMessage:
		if ((Atom)evt.xclient.data.l[0] == wmDelete) {
			XCloseDisplay(dis);
			exit(0);
		}
		break;
	case Expose:
		XCopyArea(dis, priv->pix, evt.xexpose.window, priv->gc,
			evt.xexpose.x, evt.xexpose.y,
			evt.xexpose.width, evt.xexpose.height,
			evt.xexpose.x, evt.xexpose.y);
		break;
	#if GINPUT_NEED_MOUSE
		case ButtonPress:
			priv->mousex = evt.xbutton.x;
			priv->mousey = evt.xbutton.y;
			switch(evt.xbutton.button){
			case 1:	priv->buttons |= GINPUT_MOUSE_BTN_LEFT;		break;
			case 2:	priv->buttons |= GINPUT_MOUSE_BTN_MIDDLE;	break;
			case 3:	priv->buttons |= GINPUT_MOUSE_BTN_RIGHT;	break;
			case 4:	priv->buttons |= GINPUT_MOUSE_BTN_4;		break;
			}
			_gmouseWakeup(priv->mouse);
			break;
		case ButtonRelease:
			priv->mousex = evt.xbutton.x;
			priv->mousey = evt.xbutton.y;
			switch(evt.xbutton.button){
			case 1:	priv->buttons &= ~GINPUT_MOUSE_BTN_LEFT;	break;
			case 2:	priv->buttons &= ~GINPUT_MOUSE_BTN_MIDDLE;	break;
			case 3:	priv->buttons &= ~GINPUT_MOUSE_BTN_RIGHT;	break;
			case 4:	priv->buttons &= ~GINPUT_MOUSE_BTN_4;		break;
			}
			_gmouseWakeup(priv->mouse);
			break;
		case MotionNotify:
			priv->mousex = evt.xmotion.x;
			priv->mousey = evt.xmotion.y;
			_gmouseWakeup(priv->mouse);
			break;
	#endif
	#if GINPUT_NEED_KEYBOARD
		case KeymapNotify:
			XRefreshKeyboardMapping(&evt.xmapping);
			break;
		case KeyPress:
			#if !GKEYBOARD_X_NO_LAYOUT
				// TODO
				#error "The code to do keyboard layouts in X is not complete."
			#endif
			 /* ignore these when there is no layout engine */
			break;
		case KeyRelease:
			#if !GKEYBOARD_X_NO_LAYOUT
				// TODO
				#error "The code to do keyboard layouts in X is not complete."
			#endif
			if (keyboard && !keyboard->pLayout && keypos < (int)sizeof(keybuffer)) {
				int		len;

				len = XLookupString(&evt.xkey, (char *)(keybuffer+keypos), sizeof(keybuffer)-keypos, /*&keysym*/0, NULL);
				if (len > 0) {
					keypos += len;
					_gkeyboardWakeup(keyboard);
				}
			}
			break;
	#endif
	}
}