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 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; }
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 } }