void WIN_InitMouse(_THIS) { int index = 0; RAWINPUTDEVICELIST *deviceList = NULL; int devCount = 0; int i; int tmp = 0; char *buffer = NULL; char *tab = "wacom"; /* since windows does't give us handles to tablets, we have to detect a tablet by it's name */ const char *rdp = "rdp_mou"; SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; /* WinCE has no RawInputDeviceList */ #ifdef _WIN32_WCE SDL_Mouse mouse; SDL_zero(mouse); mouse.id = 0; SDL_AddMouse(&mouse, "Stylus", 0, 0, 1); #else /* we're checking for the number of rawinput devices */ if (GetRawInputDeviceList(NULL, &devCount, sizeof(RAWINPUTDEVICELIST))) { return; } deviceList = SDL_malloc(sizeof(RAWINPUTDEVICELIST) * devCount); /* we're getting the raw input device list */ GetRawInputDeviceList(deviceList, &devCount, sizeof(RAWINPUTDEVICELIST)); mice = SDL_malloc(devCount * sizeof(HANDLE)); /* we're getting the details of the devices */ for (i = 0; i < devCount; ++i) { int is_rdp = 0; int j; int k; char *default_device_name = "Pointing device xx"; const char *reg_key_root = "System\\CurrentControlSet\\Enum\\"; char *device_name = SDL_malloc(256 * sizeof(char)); char *key_name = NULL; char *tmp_name = NULL; LONG rc = 0; HKEY hkey; DWORD regtype = REG_SZ; DWORD out = 256 * sizeof(char); SDL_Mouse mouse; int l; if (deviceList[i].dwType != RIM_TYPEMOUSE) { /* if a device isn't a mouse type we don't want it */ continue; } if (GetRawInputDeviceInfoA (deviceList[i].hDevice, RIDI_DEVICENAME, NULL, &tmp) < 0) { continue; } buffer = SDL_malloc((tmp + 1) * sizeof(char)); key_name = SDL_malloc((tmp + SDL_strlen(reg_key_root) + 1) * sizeof(char)); /* we're getting the device registry path and polishing it to get it's name, surely there must be an easier way, but we haven't found it yet */ if (GetRawInputDeviceInfoA (deviceList[i].hDevice, RIDI_DEVICENAME, buffer, &tmp) < 0) { continue; } buffer += 4; tmp -= 4; tmp_name = buffer; for (j = 0; j < tmp; ++j) { if (*tmp_name == '#') { *tmp_name = '\\'; } else if (*tmp_name == '{') { break; } ++tmp_name; } *tmp_name = '\0'; SDL_memcpy(key_name, reg_key_root, SDL_strlen(reg_key_root)); SDL_memcpy(key_name + (SDL_strlen(reg_key_root)), buffer, j + 1); l = SDL_strlen(key_name); is_rdp = 0; if (l >= 7) { for (j = 0; j < l - 7; ++j) { for (k = 0; k < 7; ++k) { if (rdp[k] != SDL_tolower((unsigned char) key_name[j + k])) { break; } } if (k == 7) { is_rdp = 1; break; } } } buffer -= 4; if (is_rdp == 1) { SDL_free(buffer); SDL_free(key_name); SDL_free(device_name); is_rdp = 0; continue; } /* we're opening the registry key to get the mouse name */ rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &hkey); if (rc != ERROR_SUCCESS) { SDL_memcpy(device_name, default_device_name, SDL_strlen(default_device_name)); } rc = RegQueryValueExA(hkey, "DeviceDesc", NULL, ®type, device_name, &out); RegCloseKey(hkey); if (rc != ERROR_SUCCESS) { SDL_memcpy(device_name, default_device_name, SDL_strlen(default_device_name)); } /* we're saving the handle to the device */ mice[index] = deviceList[i].hDevice; SDL_zero(mouse); mouse.id = index; l = SDL_strlen(device_name); /* we're checking if the device isn't by any chance a tablet */ if (data->wintabDLL && tablet == -1) { for (j = 0; j < l - 5; ++j) { for (k = 0; k < 5; ++k) { if (tab[k] != SDL_tolower((unsigned char) device_name[j + k])) { break; } } if (k == 5) { tablet = index; break; } } } /* if it's a tablet, let's read it's maximum and minimum pressure */ if (tablet == index) { AXIS pressure; int cursors; data->WTInfoA(WTI_DEVICES, DVC_NPRESSURE, &pressure); data->WTInfoA(WTI_DEVICES, DVC_NCSRTYPES, &cursors); SDL_AddMouse(&mouse, device_name, pressure.axMax, pressure.axMin, cursors); } else { SDL_AddMouse(&mouse, device_name, 0, 0, 1); } ++index; SDL_free(buffer); SDL_free(key_name); } total_mice = index; SDL_free(deviceList); #endif /*_WIN32_WCE*/ }
int WIN_CreateWindow(_THIS, SDL_Window * window) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); RAWINPUTDEVICE Rid; AXIS TabX, TabY; LOGCONTEXTA lc; HWND hwnd; HWND top; RECT rect; SDL_Rect bounds; DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); int x, y; int w, h; if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) { style |= WS_POPUP; } else { style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); } if ((window->flags & SDL_WINDOW_RESIZABLE) && !(window->flags & SDL_WINDOW_FULLSCREEN)) { style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); } /* Figure out what the window area will be */ if (window->flags & SDL_WINDOW_FULLSCREEN) { top = HWND_TOPMOST; } else { top = HWND_NOTOPMOST; } rect.left = 0; rect.top = 0; rect.right = window->w; rect.bottom = window->h; AdjustWindowRectEx(&rect, style, FALSE, 0); w = (rect.right - rect.left); h = (rect.bottom - rect.top); WIN_GetDisplayBounds(_this, display, &bounds); if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) { x = bounds.x + (bounds.w - window->w) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { if (bounds.x == 0) { x = CW_USEDEFAULT; } else { x = bounds.x; } } else { x = bounds.x + window->x + rect.left; } if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) { y = bounds.y + (bounds.h - window->h) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { if (bounds.x == 0) { y = CW_USEDEFAULT; } else { y = bounds.y; } } else { y = bounds.y + window->y + rect.top; } hwnd = CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL, SDL_Instance, NULL); if (!hwnd) { WIN_SetError("Couldn't create window"); return -1; } /* we're configuring the tablet data. See Wintab reference for more info */ if (videodata->wintabDLL && videodata->WTInfoA(WTI_DEFSYSCTX, 0, &lc) != 0) { lc.lcPktData = PACKETDATA; lc.lcPktMode = PACKETMODE; lc.lcOptions |= CXO_MESSAGES; lc.lcOptions |= CXO_SYSTEM; lc.lcMoveMask = PACKETDATA; lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA; videodata->WTInfoA(WTI_DEVICES, DVC_X, &TabX); videodata->WTInfoA(WTI_DEVICES, DVC_Y, &TabY); lc.lcInOrgX = 0; lc.lcInOrgY = 0; lc.lcInExtX = TabX.axMax; lc.lcInExtY = TabY.axMax; lc.lcOutOrgX = 0; lc.lcOutOrgY = 0; lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN); lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN); if (window->id > highestId) { HCTX *tmp_hctx; highestId = window->id; tmp_hctx = (HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX)); if (!tmp_hctx) { SDL_OutOfMemory(); DestroyWindow(hwnd); return -1; } g_hCtx = tmp_hctx; } g_hCtx[window->id] = videodata->WTOpenA(hwnd, &lc, TRUE); } #ifndef _WIN32_WCE /* has no RawInput */ /* we're telling the window, we want it to report raw input events from mice */ Rid.usUsagePage = 0x01; Rid.usUsage = 0x02; Rid.dwFlags = RIDEV_INPUTSINK; Rid.hwndTarget = hwnd; RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); #endif WIN_PumpEvents(_this); if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) { DestroyWindow(hwnd); return -1; } #ifdef SDL_VIDEO_OPENGL_WGL if (window->flags & SDL_WINDOW_OPENGL) { if (WIN_GL_SetupWindow(_this, window) < 0) { WIN_DestroyWindow(_this, window); return -1; } } #endif return 0; }