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 + -
显示快捷键?