Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

425 lines
11 KiB

  1. /*------------------------------------------------------------------------------
  2. SysPress - using pressure input with a system context.
  3. RICO 6/7/93
  4. ------------------------------------------------------------------------------*/
  5. #include <windows.h>
  6. #include "msgpack.h"
  7. #include <wintab.h>
  8. #define PACKETDATA (PK_CURSOR | PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE)
  9. #define PACKETMODE 0
  10. #include <pktdef.h>
  11. #include "syspress.h"
  12. #ifdef USE_X_LIB
  13. #include <wintabx.h>
  14. #endif
  15. HANDLE hInst;
  16. #define NPACKETQSIZE 32 /* set as needed for your app. */
  17. PACKET localPacketBuf[NPACKETQSIZE];
  18. static HCTX hTab = NULL;
  19. /* -------------------------------------------------------------------------- */
  20. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  21. HANDLE hInstance;
  22. HANDLE hPrevInstance;
  23. LPSTR lpCmdLine;
  24. int nCmdShow;
  25. {
  26. MSG msg;
  27. if (!hPrevInstance)
  28. if (!InitApplication(hInstance))
  29. return (FALSE);
  30. /* Perform initializations that apply to a specific instance */
  31. if (!InitInstance(hInstance, nCmdShow))
  32. return (FALSE);
  33. /* Acquire and dispatch messages until a WM_QUIT message is received. */
  34. while (GetMessage(&msg,
  35. NULL,
  36. 0,
  37. 0))
  38. {
  39. TranslateMessage(&msg);
  40. DispatchMessage(&msg);
  41. }
  42. return (msg.wParam);
  43. }
  44. /* -------------------------------------------------------------------------- */
  45. BOOL InitApplication(hInstance)
  46. HANDLE hInstance;
  47. {
  48. WNDCLASS wc;
  49. /* Fill in window class structure with parameters that describe the */
  50. /* main window. */
  51. wc.style = 0;
  52. wc.lpfnWndProc = MainWndProc;
  53. wc.cbClsExtra = 0;
  54. wc.cbWndExtra = 0;
  55. wc.hInstance = hInstance;
  56. wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  57. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  58. wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
  59. wc.lpszMenuName = "SysPressMenu";
  60. wc.lpszClassName = "SysPressWClass";
  61. /* Register the window class and return success/failure code. */
  62. return (RegisterClass(&wc));
  63. }
  64. /* -------------------------------------------------------------------------- */
  65. BOOL InitInstance(hInstance, nCmdShow)
  66. HANDLE hInstance;
  67. int nCmdShow;
  68. {
  69. HWND hWnd;
  70. char buf[50];
  71. /* Save the instance handle in static variable, which will be used in */
  72. /* many subsequence calls from this application to Windows. */
  73. hInst = hInstance;
  74. /* check if WinTab available. */
  75. if (!WTInfo(0, 0, NULL)) {
  76. MessageBox(NULL, "WinTab Services Not Available.", "WinTab",
  77. MB_OK | MB_ICONHAND);
  78. return FALSE;
  79. }
  80. /* Create a main window for this application instance. */
  81. wsprintf(buf, "SysPress:%x", hInst);
  82. hWnd = CreateWindow(
  83. "SysPressWClass",
  84. buf,
  85. WS_OVERLAPPEDWINDOW,
  86. CW_USEDEFAULT,
  87. CW_USEDEFAULT,
  88. CW_USEDEFAULT,
  89. CW_USEDEFAULT,
  90. NULL,
  91. NULL,
  92. hInstance,
  93. NULL
  94. );
  95. /* If window could not be created, return "failure" */
  96. if (!hWnd)
  97. return (FALSE);
  98. /* Make the window visible; update its client area; and return "success" */
  99. ShowWindow(hWnd, nCmdShow);
  100. UpdateWindow(hWnd);
  101. return (TRUE);
  102. }
  103. /* -------------------------------------------------------------------------- */
  104. HCTX static NEAR TabletInit(HWND hWnd)
  105. {
  106. LOGCONTEXT lcMine;
  107. HCTX hResult;
  108. /* get default system context. */
  109. WTInfo(WTI_DEFSYSCTX, 0, &lcMine);
  110. /* modify the digitizing context */
  111. wsprintf(lcMine.lcName, "SysPress Digitizing %x", hInst);
  112. /* same define constants from top of file used in context definition. */
  113. lcMine.lcPktData = PACKETDATA;
  114. lcMine.lcPktMode = PACKETMODE;
  115. lcMine.lcMoveMask = PACKETDATA;
  116. /* inherit default button down mask. */
  117. /* allows tablet control panel to reserve some buttons for special */
  118. /* functions. */
  119. /* make sure we get button up AND down reports for all buttons we watch. */
  120. lcMine.lcBtnUpMask = lcMine.lcBtnDnMask;
  121. /* x & y match mouse points. */
  122. lcMine.lcOutOrgX = 0;
  123. lcMine.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
  124. lcMine.lcOutOrgY = 0;
  125. /* the negative sign here reverses the sense of the Y axis. */
  126. /* WinTab uses a lower-left origin; MM_TEXT uses upper left. */
  127. lcMine.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
  128. /* open the context */
  129. hResult = WTOpen(hWnd, &lcMine, TRUE);
  130. /* Q size set needs error-checking, but skipped here for */
  131. /* simplicity's sake. */
  132. WTQueueSizeSet(hResult, NPACKETQSIZE);
  133. return hResult;
  134. }
  135. /*------------------------------------------------------------------------------
  136. The functions PrsInit and PrsAdjust make sure that our pressure out can always
  137. reach the full 0-255 range we desire, regardless of the button pressed or the
  138. "pressure button marks" settings.
  139. ------------------------------------------------------------------------------*/
  140. /* pressure adjuster local state. */
  141. /* need wOldCsr = -1, so PrsAdjust will call PrsInit first time */
  142. static UINT wActiveCsr = 0, wOldCsr = (UINT)-1;
  143. static BYTE wPrsBtn;
  144. static UINT prsYesBtnOrg, prsYesBtnExt, prsNoBtnOrg, prsNoBtnExt;
  145. /* -------------------------------------------------------------------------- */
  146. void PrsInit(void)
  147. {
  148. /* browse WinTab's many info items to discover pressure handling. */
  149. AXIS np;
  150. LOGCONTEXT lc;
  151. BYTE logBtns[32];
  152. UINT btnMarks[2];
  153. UINT size;
  154. /* discover the LOGICAL button generated by the pressure channel. */
  155. /* get the PHYSICAL button from the cursor category and run it */
  156. /* through that cursor's button map (usually the identity map). */
  157. wPrsBtn = (BYTE)-1;
  158. WTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBUTTON, &wPrsBtn);
  159. size = WTInfo(WTI_CURSORS + wActiveCsr, CSR_BUTTONMAP, &logBtns);
  160. if ((UINT)wPrsBtn < size)
  161. wPrsBtn = logBtns[wPrsBtn];
  162. /* get the current context for its device variable. */
  163. WTGet(hTab, &lc);
  164. /* get the size of the pressure axis. */
  165. WTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np);
  166. prsNoBtnOrg = (UINT)np.axMin;
  167. prsNoBtnExt = (UINT)np.axMax - (UINT)np.axMin;
  168. /* get the button marks (up & down generation thresholds) */
  169. /* and calculate what pressure range we get when pressure-button is down. */
  170. btnMarks[1] = 0; /* default if info item not present. */
  171. WTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBTNMARKS, btnMarks);
  172. prsYesBtnOrg = btnMarks[1];
  173. prsYesBtnExt = (UINT)np.axMax - btnMarks[1];
  174. }
  175. /* -------------------------------------------------------------------------- */
  176. UINT PrsAdjust(PACKET p)
  177. {
  178. UINT wResult;
  179. wActiveCsr = p.pkCursor;
  180. if (wActiveCsr != wOldCsr) {
  181. /* re-init on cursor change. */
  182. PrsInit();
  183. wOldCsr = wActiveCsr;
  184. }
  185. /* scaling output range is 0-255 */
  186. if (p.pkButtons & (1 << wPrsBtn)) {
  187. /* if pressure-activated button is down, */
  188. /* scale pressure output to compensate btn marks */
  189. wResult = p.pkNormalPressure - prsYesBtnOrg;
  190. wResult = MulDiv(wResult, 255, prsYesBtnExt);
  191. }
  192. else {
  193. /* if pressure-activated button is not down, */
  194. /* scale pressure output directly */
  195. wResult = p.pkNormalPressure - prsNoBtnOrg;
  196. wResult = MulDiv(wResult, 255, prsNoBtnExt);
  197. }
  198. return wResult;
  199. }
  200. /* -------------------------------------------------------------------------- */
  201. LRESULT FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
  202. HWND hWnd;
  203. unsigned message;
  204. WPARAM wParam;
  205. LPARAM lParam;
  206. {
  207. FARPROC lpProcAbout;
  208. static POINT ptOrg;
  209. static POINT ptOld, ptNew;
  210. static UINT prsOld, prsNew;
  211. static DWORD btnOld, btnNew;
  212. HDC hDC;
  213. int nPackets;
  214. BOOL fHandled = TRUE;
  215. LRESULT lResult = 0L;
  216. switch (message) {
  217. case WM_CREATE:
  218. hTab = TabletInit(hWnd);
  219. if (!hTab) {
  220. MessageBox(NULL, " Could Not Open Tablet Context.", "WinTab",
  221. MB_OK | MB_ICONHAND);
  222. SendMessage(hWnd, WM_DESTROY, 0, 0L);
  223. }
  224. break;
  225. case WM_SIZE:
  226. case WM_MOVE:
  227. ptOrg.x = ptOrg.y = 0;
  228. ClientToScreen(hWnd, &ptOrg);
  229. InvalidateRect(hWnd, NULL, TRUE);
  230. break;
  231. case WM_ACTIVATE:
  232. /* This call puts your context (active area) on top the */
  233. /* context overlap order. */
  234. if (hTab && GET_WM_ACTIVATE_STATE(wParam, lParam))
  235. WTOverlap(hTab, TRUE);
  236. break;
  237. case WM_MOUSEMOVE:
  238. case WM_LBUTTONDOWN:
  239. case WM_LBUTTONUP:
  240. case WM_LBUTTONDBLCLK:
  241. case WM_MBUTTONDOWN:
  242. case WM_MBUTTONUP:
  243. case WM_MBUTTONDBLCLK:
  244. case WM_RBUTTONDOWN:
  245. case WM_RBUTTONUP:
  246. case WM_RBUTTONDBLCLK:
  247. /* ANY mouse msg */
  248. if (IsIconic(hWnd))
  249. break;
  250. /* empty the queue to a local buffer. */
  251. if (nPackets = WTPacketsGet(hTab, NPACKETQSIZE, &localPacketBuf)) {
  252. int i;
  253. if (hDC = GetDC(hWnd)) {
  254. HBRUSH hBrOld = NULL;
  255. HPEN hPenOld;
  256. hPenOld = SelectObject(hDC, GetStockObject(NULL_PEN));
  257. for (i = 0; i < nPackets; i++) {
  258. DWORD btnChange;
  259. btnOld = btnNew;
  260. btnNew = localPacketBuf[i].pkButtons;
  261. btnChange = btnOld ^ btnNew;
  262. if (btnNew & btnChange) {
  263. /* a button went down. */
  264. MessageBeep(0);
  265. }
  266. if (btnNew) {
  267. /* save last packet's data. */
  268. ptOld = ptNew;
  269. prsOld = prsNew;
  270. /* get new point. */
  271. ptNew.x = (UINT)localPacketBuf[i].pkX;
  272. ptNew.y = (UINT)localPacketBuf[i].pkY;
  273. /* translate coordinates to client area. */
  274. ptNew.x -= ptOrg.x;
  275. ptNew.y -= ptOrg.y;
  276. prsNew = PrsAdjust(localPacketBuf[i]);
  277. if (hBrOld == NULL) {
  278. hBrOld = SelectObject(hDC,
  279. CreateSolidBrush(
  280. RGB(prsNew, prsNew, prsNew)));
  281. }
  282. else if (prsNew != prsOld) {
  283. DeleteObject(SelectObject(hDC, hBrOld));
  284. hBrOld = SelectObject(hDC,
  285. CreateSolidBrush(
  286. RGB(prsNew, prsNew, prsNew)));
  287. }
  288. if (ptNew.x != ptOld.x ||
  289. ptNew.y != ptOld.y ||
  290. prsNew != prsOld) {
  291. Ellipse(hDC, ptNew.x - 3, ptNew.y - 3,
  292. ptNew.x + 3, ptNew.y + 3);
  293. }
  294. }
  295. }
  296. SelectObject(hDC, hPenOld);
  297. if (hBrOld)
  298. DeleteObject(SelectObject(hDC, hBrOld));
  299. ReleaseDC(hWnd, hDC);
  300. }
  301. }
  302. break;
  303. case WM_COMMAND:
  304. if (GET_WM_COMMAND_ID(wParam, lParam) == IDM_ABOUT) {
  305. lpProcAbout = MakeProcInstance(About, hInst);
  306. DialogBox(hInst,
  307. "AboutBox",
  308. hWnd,
  309. lpProcAbout);
  310. FreeProcInstance(lpProcAbout);
  311. }
  312. else
  313. fHandled = FALSE;
  314. break;
  315. case WT_INFOCHANGE: /* IF some info item changed */
  316. PrsInit(); /* update the pressure mapping state vars. */
  317. break;
  318. case WM_DESTROY:
  319. if (hTab)
  320. WTClose(hTab);
  321. #ifdef USE_X_LIB
  322. _UnlinkWintab();
  323. #endif
  324. PostQuitMessage(0);
  325. break;
  326. default:
  327. fHandled = FALSE;
  328. break;
  329. }
  330. if (fHandled)
  331. return (lResult);
  332. else
  333. return (DefWindowProc(hWnd, message, wParam, lParam));
  334. }
  335. /* -------------------------------------------------------------------------- */
  336. BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
  337. HWND hDlg;
  338. unsigned message;
  339. WPARAM wParam;
  340. LPARAM lParam;
  341. {
  342. switch (message) {
  343. case WM_INITDIALOG:
  344. return (TRUE);
  345. case WM_COMMAND:
  346. if (GET_WM_COMMAND_ID(wParam, lParam) == IDOK
  347. || GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL) {
  348. EndDialog(hDlg, TRUE);
  349. return (TRUE);
  350. }
  351. break;
  352. }
  353. return (FALSE);
  354. }
  355. /* -------------------------------------------------------------------------- */