main.c
来自「Wine-20031016」· C语言 代码 · 共 1,149 行 · 第 1/3 页
C
1,149 行
int i; TRACE("(this=%p,%p)\n",This,df); TRACE("(df.dwSize=%ld)\n",df->dwSize); TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize); TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags); TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize); TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs); for (i=0;i<df->dwNumObjs;i++) { TRACE("df.rgodf[%d].guid %s (%p)\n",i, debugstr_guid(df->rgodf[i].pguid), df->rgodf[i].pguid); TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs); TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType)); TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags); } /* Tests under windows show that a call to SetDataFormat always sets the mouse in relative mode whatever the dwFlags value (DIDF_ABSAXIS/DIDF_RELAXIS). To switch in absolute mode, SetProperty must be used. */ This->absolute = 0; /* Store the new data format */ This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize); memcpy(This->df, df, df->dwSize); This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize); memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize); /* Prepare all the data-conversion filters */ This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array); return DI_OK;}/* low-level mouse hook */static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lparam ){ LRESULT ret; MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam; SysMouseImpl* This = (SysMouseImpl*) current_lock; DWORD dwCoop; static long last_event = 0; int wdata; if (code != HC_ACTION) return CallNextHookEx( This->hook, code, wparam, lparam ); EnterCriticalSection(&(This->crit)); dwCoop = This->dwCoopLevel; /* Only allow mouse events every 10 ms. * This is to allow the cursor to start acceleration before * the warps happen. But if it involves a mouse button event we * allow it since we dont want to loose the clicks. */ if (((GetCurrentTime() - last_event) < 10) && wparam == WM_MOUSEMOVE) goto end; else last_event = GetCurrentTime(); /* Mouse moved -> send event if asked */ if (This->hEvent) SetEvent(This->hEvent); if (wparam == WM_MOUSEMOVE) { if (This->absolute) { if (hook->pt.x != This->prevX) GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x, hook->time, 0); if (hook->pt.y != This->prevY) GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y, hook->time, 0); } else { /* Now, warp handling */ if ((This->need_warp == WARP_STARTED) && (hook->pt.x == This->mapped_center.x) && (hook->pt.y == This->mapped_center.y)) { /* Warp has been done... */ This->need_warp = WARP_DONE; goto end; } /* Relative mouse input with absolute mouse event : the real fun starts here... */ if ((This->need_warp == WARP_NEEDED) || (This->need_warp == WARP_STARTED)) { if (hook->pt.x != This->prevX) GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->prevX, hook->time, (This->dinput->evsequence)++); if (hook->pt.y != This->prevY) GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->prevY, hook->time, (This->dinput->evsequence)++); } else { /* This is the first time the event handler has been called after a GetDeviceData or GetDeviceState. */ if (hook->pt.x != This->mapped_center.x) { GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->mapped_center.x, hook->time, (This->dinput->evsequence)++); This->need_warp = WARP_NEEDED; } if (hook->pt.y != This->mapped_center.y) { GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->mapped_center.y, hook->time, (This->dinput->evsequence)++); This->need_warp = WARP_NEEDED; } } } This->prevX = hook->pt.x; This->prevY = hook->pt.y; if (This->absolute) { This->m_state.lX = hook->pt.x; This->m_state.lY = hook->pt.y; } else { This->m_state.lX = hook->pt.x - This->mapped_center.x; This->m_state.lY = hook->pt.y - This->mapped_center.y; } } TRACE(" msg %x pt %ld %ld (W=%d)\n", wparam, hook->pt.x, hook->pt.y, (!This->absolute) && This->need_warp ); switch(wparam) { case WM_LBUTTONDOWN: GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[0] = 0xFF; break; case WM_LBUTTONUP: GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[0] = 0x00; break; case WM_RBUTTONDOWN: GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[1] = 0xFF; break; case WM_RBUTTONUP: GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[1] = 0x00; break; case WM_MBUTTONDOWN: GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[2] = 0xFF; break; case WM_MBUTTONUP: GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00, hook->time, This->dinput->evsequence++); This->m_state.rgbButtons[2] = 0x00; break; case WM_MOUSEWHEEL: wdata = (short)HIWORD(hook->mouseData); GEN_EVENT(This->offset_array[WINE_MOUSE_Z_POSITION], wdata, hook->time, This->dinput->evsequence++); This->m_state.lZ += wdata; break; } TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", This->m_state.lX, This->m_state.lY, This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);end: LeaveCriticalSection(&(This->crit)); if (dwCoop & DISCL_NONEXCLUSIVE) { /* pass the events down to previous handlers (e.g. win32 input) */ ret = CallNextHookEx( This->hook, code, wparam, lparam ); } else ret = 1; /* ignore message */ return ret;}static void dinput_window_check(SysMouseImpl* This){ RECT rect; DWORD centerX, centerY; /* make sure the window hasn't moved */ GetWindowRect(This->win, &rect); centerX = (rect.right - rect.left) / 2; centerY = (rect.bottom - rect.top ) / 2; if (This->win_centerX != centerX || This->win_centerY != centerY) { This->win_centerX = centerX; This->win_centerY = centerY; } This->mapped_center.x = This->win_centerX; This->mapped_center.y = This->win_centerY; MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);}/****************************************************************************** * Acquire : gets exclusive control of the mouse */static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface){ ICOM_THIS(SysMouseImpl,iface); RECT rect; TRACE("(this=%p)\n",This); if (This->acquired == 0) { POINT point; /* Store (in a global variable) the current lock */ current_lock = (IDirectInputDevice8A*)This; /* Init the mouse state */ if (This->absolute) { GetCursorPos( &point ); This->m_state.lX = point.x; This->m_state.lY = point.y; This->prevX = point.x; This->prevY = point.y; } else { This->m_state.lX = 0; This->m_state.lY = 0; } This->m_state.lZ = 0; This->m_state.rgbButtons[0] = (GetKeyState(VK_LBUTTON) ? 0xFF : 0x00); This->m_state.rgbButtons[1] = (GetKeyState(VK_MBUTTON) ? 0xFF : 0x00); This->m_state.rgbButtons[2] = (GetKeyState(VK_RBUTTON) ? 0xFF : 0x00); /* Install our mouse hook */ if (This->dwCoopLevel & DISCL_EXCLUSIVE) ShowCursor(FALSE); /* hide cursor */ This->hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 ); /* Get the window dimension and find the center */ GetWindowRect(This->win, &rect); This->win_centerX = (rect.right - rect.left) / 2; This->win_centerY = (rect.bottom - rect.top ) / 2; /* Warp the mouse to the center of the window */ if (This->absolute == 0) { This->mapped_center.x = This->win_centerX; This->mapped_center.y = This->win_centerY; MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1); TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y); SetCursorPos( This->mapped_center.x, This->mapped_center.y );#ifdef MOUSE_HACK This->need_warp = WARP_DONE;#else This->need_warp = WARP_STARTED;#endif } This->acquired = 1; return DI_OK; } return S_FALSE;}/****************************************************************************** * Unacquire : frees the mouse */static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface){ ICOM_THIS(SysMouseImpl,iface); TRACE("(this=%p)\n",This); if (This->acquired) { /* Reinstall previous mouse event handler */ if (This->hook) { UnhookWindowsHookEx( This->hook ); This->hook = 0; if (This->dwCoopLevel & DISCL_EXCLUSIVE) ShowCursor(TRUE); /* show cursor */ } /* No more locks */ current_lock = NULL; /* Unacquire device */ This->acquired = 0; } else ERR("Unacquiring a not-acquired device !!!\n"); return DI_OK;}/****************************************************************************** * GetDeviceState : returns the "state" of the mouse. * * For the moment, only the "standard" return structure (DIMOUSESTATE) is * supported. */static HRESULT WINAPI SysMouseAImpl_GetDeviceState( LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr) { ICOM_THIS(SysMouseImpl,iface); EnterCriticalSection(&(This->crit)); TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr); /* Copy the current mouse state */ fill_DataFormat(ptr, &(This->m_state), This->wine_df); /* Initialize the buffer when in relative mode */ if (This->absolute == 0) { This->m_state.lX = 0; This->m_state.lY = 0; This->m_state.lZ = 0; } /* Check if we need to do a mouse warping */ if (This->need_warp == WARP_NEEDED) { dinput_window_check(This); TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y); SetCursorPos( This->mapped_center.x, This->mapped_center.y );#ifdef MOUSE_HACK This->need_warp = WARP_DONE;#else This->need_warp = WARP_STARTED;#endif } LeaveCriticalSection(&(This->crit)); TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n", This->m_state.lX, This->m_state.lY, This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]); return DI_OK;}/****************************************************************************** * GetDeviceState : gets buffered input data. */static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, LPDWORD entries, DWORD flags) { ICOM_THIS(SysMouseImpl,iface); DWORD len, nqtail; TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags); if (This->acquired == 0) { WARN(" application tries to get data from an unacquired device !\n"); return DIERR_NOTACQUIRED; } EnterCriticalSection(&(This->crit)); len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0) + (This->queue_head - This->queue_tail); if (len > *entries) len = *entries; if (dod == NULL) { if (len) TRACE("Application discarding %ld event(s).\n", len); *entries = len; nqtail = This->queue_tail + len; while (nqtail >= This->queue_len) nqtail -= This->queue_len; } else { if (dodsize < sizeof(DIDEVICEOBJECTDATA)) { ERR("Wrong structure size !\n"); LeaveCriticalSection(&(This->crit)); return DIERR_INVALIDPARAM; } if (len) TRACE("Application retrieving %ld event(s).\n", len); *entries = 0; nqtail = This->queue_tail; while (len) { DWORD span = ((This->queue_head < nqtail) ? This->queue_len : This->queue_head) - nqtail; if (span > len) span = len; /* Copy the buffered data into the application queue */ memcpy(dod + *entries, This->data_queue + nqtail, span * dodsize); /* Advance position */ nqtail += span; if (nqtail >= This->queue_len) nqtail -= This->queue_len;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?