Exemplo n.º 1
0
static Bool
xf86RandRSetConfig (ScreenPtr		pScreen,
		    Rotation		rotation,
		    int			rate,
		    RRScreenSizePtr	pSize)
{
    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
    DisplayModePtr	    mode;
    int			    px, py;
    Bool		    useVirtual = FALSE;

    randrp->rotation = rotation;

    miPointerPosition (&px, &py);
    for (mode = scrp->modes; ; mode = mode->next)
    {
	if (mode->HDisplay == pSize->width && 
	    mode->VDisplay == pSize->height &&
	    (rate == 0 || xf86RandRModeRefresh (mode) == rate))
	    break;
	if (mode->next == scrp->modes)
	{
	    if (pSize->width == randrp->virtualX &&
		pSize->height == randrp->virtualY)
	    {
		mode = scrp->modes;
		useVirtual = TRUE;
		break;
	    }
	    return FALSE;
	}
    }

    /* Have the driver do its thing. */
    if (scrp->RRFunc) {
	xorgRRRotation RRRotation;
	RRRotation.RRConfig.rotation = rotation;
	RRRotation.RRConfig.rate = rate;
	RRRotation.RRConfig.width = pSize->width;
	RRRotation.RRConfig.height = pSize->height;
	
        if (!(*scrp->RRFunc)(scrp, RR_SET_CONFIG, &RRRotation))
			  return FALSE;
    }

    if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight))
	return FALSE;
    /*
     * Move the cursor back where it belongs; SwitchMode repositions it
     */
    if (pScreen == miPointerCurrentScreen ())
    {
	if (px < pSize->width && py < pSize->height)
	    (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
    }

    return TRUE;
}
Exemplo n.º 2
0
_X_EXPORT Bool
xf86RandR12SetConfig (ScreenPtr		pScreen,
		    Rotation		rotation,
		    int			rate,
		    RRScreenSizePtr	pSize)
{
    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
    DisplayModePtr	mode;
    int			px, py;
    Bool		useVirtual = FALSE;
    int			maxX = 0, maxY = 0;
    Rotation		oldRotation = randrp->rotation;

    randrp->rotation = rotation;

    if (randrp->virtualX == -1 || randrp->virtualY == -1)
    {
	randrp->virtualX = scrp->virtualX;
	randrp->virtualY = scrp->virtualY;
    }

    miPointerPosition (&px, &py);
    for (mode = scrp->modes; ; mode = mode->next)
    {
	if (randrp->maxX == 0 || randrp->maxY == 0)
	{
		if (maxX < mode->HDisplay)
			maxX = mode->HDisplay;
		if (maxY < mode->VDisplay)
			maxY = mode->VDisplay;
	}
	if (mode->HDisplay == pSize->width &&
	    mode->VDisplay == pSize->height &&
	    (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
	    break;
	if (mode->next == scrp->modes)
	{
	    if (pSize->width == randrp->virtualX &&
		pSize->height == randrp->virtualY)
	    {
		mode = scrp->modes;
		useVirtual = TRUE;
		break;
	    }
    	    if (randrp->maxX == 0 || randrp->maxY == 0)
    	    {
		randrp->maxX = maxX;
		randrp->maxY = maxY;
    	    }
	    return FALSE;
	}
    }

    if (randrp->maxX == 0 || randrp->maxY == 0)
    {
	randrp->maxX = maxX;
	randrp->maxY = maxY;
    }

    if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
			   pSize->mmHeight)) {
        randrp->rotation = oldRotation;
	return FALSE;
    }

    /*
     * Move the cursor back where it belongs; SwitchMode repositions it
     */
    if (pScreen == miPointerCurrentScreen ())
    {
        px = (px >= pScreen->width ? (pScreen->width - 1) : px);
        py = (py >= pScreen->height ? (pScreen->height - 1) : py);

	xf86SetViewport(pScreen, px, py);

	(*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
    }

    return TRUE;
}
Exemplo n.º 3
0
	       int		v2,
	       int		v3,
	       int		v4,
	       int		v5,
	       int*		x,
	       int*		y)
{
    TekDevicePtr	priv = (TekDevicePtr) local->private;
    int W,H;
    ScreenPtr SP;

    DBG(6,xf86Msg(X_INFO,"Tek4957:TekConvert (%d,%d)\n",v0,v1));

    /* Gets current screen size. It can change dynamically in the case of
    a multi-head configuration with different screen sizes ... */
    SP=miPointerCurrentScreen();
    W=SP->width;
    H=SP->height;

    if (first != 0 || num == 1) return (FALSE);

    *x = ((long)v0 * (long)W) / (long)priv->XSize;
    *y = ((long)v1 * (long)H) / (long)priv->YSize;

    DBG(7,xf86Msg(X_INFO,"Tek4957:TekConvert ->(%d,%d)\n",*x,*y));

    return (TRUE);
}

/*
 * TekReadInput
LRESULT CALLBACK
winMWExtWMWindowProc (HWND hwnd, UINT message, 
			    WPARAM wParam, LPARAM lParam)
{
  WindowPtr		pWin = NULL;
  win32RootlessWindowPtr pRLWinPriv = NULL;
  ScreenPtr		pScreen = NULL;
  winPrivScreenPtr	pScreenPriv = NULL;
  winScreenInfo		*pScreenInfo = NULL;
  HWND			hwndScreen = NULL;
  POINT			ptMouse;
  static Bool		s_fTracking = FALSE;
  HDC			hdcUpdate;
  PAINTSTRUCT		ps;
  LPWINDOWPOS		pWinPos = NULL;
  RECT			rcClient;
  winWMMessageRec	wmMsg;
  Bool			fWMMsgInitialized = FALSE;

  /* Check if the Windows window property for our X window pointer is valid */
  if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
    {
      pWin = pRLWinPriv->pFrame->win;
      pScreen				= pWin->drawable.pScreen;
      if (pScreen) pScreenPriv		= winGetScreenPriv(pScreen);
      if (pScreenPriv) pScreenInfo	= pScreenPriv->pScreenInfo;
      if (pScreenPriv) hwndScreen	= pScreenPriv->hwndScreen;

      wmMsg.msg		= 0;
      wmMsg.hwndWindow	= hwnd;
      wmMsg.iWindow	= (Window)pWin->drawable.id;

      wmMsg.iX		= pRLWinPriv->pFrame->x;
      wmMsg.iY		= pRLWinPriv->pFrame->y;
      wmMsg.iWidth	= pRLWinPriv->pFrame->width;
      wmMsg.iHeight	= pRLWinPriv->pFrame->height;

      fWMMsgInitialized = TRUE;
#if CYGDEBUG
      winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);

      winDebug ("\thWnd %08X\n", hwnd);
      winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
      winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
      winDebug ("\thwndScreen %08X\n", hwndScreen);
      winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
	      pRLWinPriv, message, wParam, lParam);
#endif
    }
  /* Branch on message type */
  switch (message)
    {
    case WM_CREATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
#endif
      /* */
      SetProp (hwnd,
	       WIN_WINDOW_PROP,
	       (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
      return 0;

    case WM_CLOSE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
#endif
      /* Tell window-manager to close window */
      if (pRLWinPriv->fClose)
	{
	  DestroyWindow (hwnd);
	}
      else
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	      /* Tell our Window Manager thread to kill the window */
	      wmMsg.msg = WM_WM_KILL;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMCloseWindow,
				pWin->drawable.id,
				0, 0, 0, 0);
	}
      return 0;

    case WM_DESTROY:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
#endif
      /* Free the shaodw DC; which allows the bitmap to be freed */
      DeleteDC (pRLWinPriv->hdcShadow);
      pRLWinPriv->hdcShadow = NULL;
      
      /* Free the shadow bitmap */
      DeleteObject (pRLWinPriv->hbmpShadow);
      pRLWinPriv->hbmpShadow = NULL;
      
      /* Free the screen DC */
      ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
      pRLWinPriv->hdcScreen = NULL;

      /* Free shadow buffer info header */
      free (pRLWinPriv->pbmihShadow);
      pRLWinPriv->pbmihShadow = NULL;
      
      pRLWinPriv->fResized = FALSE;
      pRLWinPriv->pfb = NULL;
      free (pRLWinPriv);
      RemoveProp (hwnd, WIN_WINDOW_PROP);
      break;

    case WM_MOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
      winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
#endif
      /* Unpack the client area mouse coordinates */
      ptMouse.x = GET_X_LPARAM(lParam);
      ptMouse.y = GET_Y_LPARAM(lParam);

      /* Translate the client area mouse coordinates to screen coordinates */
      ClientToScreen (hwnd, &ptMouse);

      /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
      ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
      ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);

      /* We can't do anything without privates */
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;

      /* Has the mouse pointer crossed screens? */
      if (pScreen != miPointerCurrentScreen ())
	miPointerSetNewScreen (pScreenInfo->dwScreen,
			       ptMouse.x - pScreenInfo->dwXOffset,
			       ptMouse.y - pScreenInfo->dwYOffset);

      /* Are we tracking yet? */
      if (!s_fTracking)
	{
	  TRACKMOUSEEVENT		tme;
	  
	  /* Setup data structure */
	  ZeroMemory (&tme, sizeof (tme));
	  tme.cbSize = sizeof (tme);
	  tme.dwFlags = TME_LEAVE;
	  tme.hwndTrack = hwnd;

	  /* Call the tracking function */
	  if (!(*g_fpTrackMouseEvent) (&tme))
	    ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");

	  /* Flag that we are tracking now */
	  s_fTracking = TRUE;
	}
      
      /* Kill the timer used to poll mouse events */
      if (g_uipMousePollingTimerID != 0)
	{
	  KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
	  g_uipMousePollingTimerID = 0;
	}

      /* Deliver absolute cursor position to X Server */
      miPointerAbsoluteCursor (ptMouse.x - pScreenInfo->dwXOffset,
			       ptMouse.y - pScreenInfo->dwYOffset,
			       g_c32LastInputEventTime = GetTickCount ());
      return 0;
      
    case WM_NCMOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
      winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
#endif
      /*
       * We break instead of returning 0 since we need to call
       * DefWindowProc to get the mouse cursor changes
       * and min/max/close button highlighting in Windows XP.
       * The Platform SDK says that you should return 0 if you
       * process this message, but it fails to mention that you
       * will give up any default functionality if you do return 0.
       */
      
      /* We can't do anything without privates */
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;

      /*
       * Timer to poll mouse events.  This is needed to make
       * programs like xeyes follow the mouse properly.
       */
      if (g_uipMousePollingTimerID == 0)
	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
					     WIN_POLLING_MOUSE_TIMER_ID,
					     MOUSE_POLLING_INTERVAL,
					     NULL);
      break;

    case WM_MOUSELEAVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
#endif
      /* Mouse has left our client area */

      /* Flag that we are no longer tracking */
      s_fTracking = FALSE;

      /*
       * Timer to poll mouse events.  This is needed to make
       * programs like xeyes follow the mouse properly.
       */
      if (g_uipMousePollingTimerID == 0)
	g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
					     WIN_POLLING_MOUSE_TIMER_ID,
					     MOUSE_POLLING_INTERVAL,
					     NULL);
      return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
      
    case WM_LBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
      
    case WM_MBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
      
    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
      
    case WM_RBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
#endif
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);

    case WM_XBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      SetCapture (hwnd);
      return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
    case WM_XBUTTONUP:
      if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
	break;
      ReleaseCapture ();
      return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);

    case WM_MOUSEWHEEL:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
#endif
      
      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_MOUSEACTIVATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
#endif
#if 1
      /* Check if this window needs to be made active when clicked */
      if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
	{
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
		    "MA_NOACTIVATE\n");
#endif

	  /* */
	  return MA_NOACTIVATE;
	}
#endif
      if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
	return MA_NOACTIVATE;

      break;

    case WM_KILLFOCUS:
      /* Pop any pressed keys since we are losing keyboard focus */
      winKeybdReleaseKeys ();
      return 0;

    case WM_SYSDEADCHAR:
    case WM_DEADCHAR:
      /*
       * NOTE: We do nothing with WM_*CHAR messages,
       * nor does the root window, so we can just toss these messages.
       */
      return 0;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
#endif

      /*
       * Don't pass Alt-F4 key combo to root window,
       * let Windows translate to WM_CLOSE and close this top-level window.
       *
       * NOTE: We purposely don't check the fUseWinKillKey setting because
       * it should only apply to the key handling for the root window,
       * not for top-level window-manager windows.
       *
       * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
       * because that is a key combo that no X app should be expecting to
       * receive, since it has historically been used to shutdown the X server.
       * Passing Ctrl-Alt-Backspace to the root window preserves that
       * behavior, assuming that -unixkill has been passed as a parameter.
       */
      if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
	  break;

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:

#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
#endif

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_HOTKEY:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
#endif

      /* Pass the message to the root window */
      SendMessage (hwndScreen, message, wParam, lParam);
      return 0;

    case WM_PAINT:
    
      /* BeginPaint gives us an hdc that clips to the invalidated region */
      hdcUpdate = BeginPaint (hwnd, &ps);

      /* Try to copy from the shadow buffer */
      if (!BitBlt (hdcUpdate,
		   ps.rcPaint.left, ps.rcPaint.top,
		   ps.rcPaint.right - ps.rcPaint.left,
		   ps.rcPaint.bottom - ps.rcPaint.top,
		   pRLWinPriv->hdcShadow,
		   ps.rcPaint.left, ps.rcPaint.top,
		   SRCCOPY))
	{
	  LPVOID lpMsgBuf;
	  
	  /* Display a fancy error message */
	  FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			 FORMAT_MESSAGE_FROM_SYSTEM | 
			 FORMAT_MESSAGE_IGNORE_INSERTS,
			 NULL,
			 GetLastError (),
			 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			 (LPTSTR) &lpMsgBuf,
			 0, NULL);

	  ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
		  (LPSTR)lpMsgBuf);
	  LocalFree (lpMsgBuf);
	}

      /* EndPaint frees the DC */
      EndPaint (hwnd, &ps);
      break;

    case WM_ACTIVATE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
#endif
      if (LOWORD(wParam) != WA_INACTIVE)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
#if 0
	      /* Raise the window to the top in Z order */
	      wmMsg.msg = WM_WM_RAISE;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
#endif
	      /* Tell our Window Manager thread to activate the window */
	      wmMsg.msg = WM_WM_ACTIVATE;
	      if (fWMMsgInitialized)
		if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMActivateWindow,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      return 0;

#if 1
    case WM_WINDOWPOSCHANGING:
      pWinPos = (LPWINDOWPOS)lParam;
      if (!(pWinPos->flags & SWP_NOZORDER))
	{
	  if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
	    {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
#endif
	      break;
	    }

	  if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
	    {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
#endif
	      break;
	    }

#if CYGMULTIWINDOW_DEBUG
	  winDebug ("Win %08x forbid to change z order (%08x).\n",
		    (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
#endif
	  pWinPos->flags |= SWP_NOZORDER;
	}
      break;
#endif

    case WM_MOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      if (g_fNoConfigureWindow) break;
#if 0
      /* Bail if Windows window is not actually moving */
      if (pRLWinPriv->dwX == (short) LOWORD(lParam)
	  && pRLWinPriv->dwY == (short) HIWORD(lParam))
	break;

      /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
      {
	WINDOWPLACEMENT windPlace;
	windPlace.length = sizeof (WINDOWPLACEMENT);

	/* Get current window placement */
	GetWindowPlacement (hwnd, &windPlace);

	/* Bail if maximizing */
	if (windPlace.showCmd == SW_MAXIMIZE
	    || windPlace.showCmd == SW_SHOWMAXIMIZED)
	  break;
      }
#endif

#if CYGMULTIWINDOW_DEBUG
      winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
#endif
      if (!pRLWinPriv->fMovingOrSizing)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    winAdjustXWindow (pWin, hwnd);

	  winMWExtWMMoveXWindow (pWin,
				 (LOWORD(lParam) - wBorderWidth (pWin)
				  - GetSystemMetrics (SM_XVIRTUALSCREEN)),
				 (HIWORD(lParam) - wBorderWidth (pWin)
				  - GetSystemMetrics (SM_YVIRTUALSCREEN)));
	}
      return 0;

    case WM_SHOWWINDOW:
#if CYGMULTIWINDOW_DEBUG || TRUE
      winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      /* Bail out if the window is being hidden */
      if (!wParam)
	return 0;

      if (!pScreenInfo->fInternalWM)//XXXX
	return 0;

      winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);

      if (winIsInternalWMRunning(pScreenInfo))
	{
#if CYGMULTIWINDOW_DEBUG || TRUE
	  winDebug ("\tMapWindow\n");
#endif
	  /* Tell X to map the window */
	   MapWindow (pWin, wClient(pWin));

	  if (!pRLWinPriv->pFrame->win->overrideRedirect)
	    /* Bring the Windows window to the foreground */
	    SetForegroundWindow (hwnd);

	  /* Setup the Window Manager message */
	  wmMsg.msg = WM_WM_MAP;
	  wmMsg.iWidth = pRLWinPriv->pFrame->width;
	  wmMsg.iHeight = pRLWinPriv->pFrame->height;

	  /* Tell our Window Manager thread to map the window */
	  if (fWMMsgInitialized)
	    winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	}
      break;

    case WM_SIZING:
      /* Need to legalize the size according to WM_NORMAL_HINTS */
      /* for applications like xterm */
      return ValidateSizing (hwnd, pWin, wParam, lParam);

    case WM_WINDOWPOSCHANGED:
      {
	pWinPos = (LPWINDOWPOS) lParam;
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
	winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
	(pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
	(pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
	(pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
	(pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
	(pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
	(pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
	(pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
	(pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
	(pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
	(pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
	(pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
	(pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
	winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
	winDebug("\textend: (%d, %d, %d, %d)\n",
            pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);

#endif
	if (pWinPos->flags & SWP_HIDEWINDOW) break;

	/* Reorder if window z order was changed */
	if ((pScreenPriv != NULL)
	    && !(pWinPos->flags & SWP_NOZORDER)
	    && !(pWinPos->flags & SWP_SHOWWINDOW)
	    && winIsInternalWMRunning(pScreenInfo))
	  {
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\twindow z order was changed\n");
#endif
	    if (pWinPos->hwndInsertAfter == HWND_TOP
		||pWinPos->hwndInsertAfter == HWND_TOPMOST
		||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
	      {
#if CYGMULTIWINDOW_DEBUG
		winDebug ("\traise to top\n");
#endif
		/* Raise the window to the top in Z order */
		wmMsg.msg = WM_WM_RAISE;
		if (fWMMsgInitialized)
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	      }
#if 1
	    else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
	      {
	      }
	    else
	      {
		/* Check if this window is top of X windows. */
		HWND hWndAbove = NULL;
		DWORD dwCurrentProcessID = GetCurrentProcessId ();
		DWORD dwWindowProcessID = 0;

		for (hWndAbove = pWinPos->hwndInsertAfter;
		     hWndAbove != NULL;
		     hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
		  {
		    /* Ignore other XWin process's window */
		    GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);

		    if ((dwWindowProcessID == dwCurrentProcessID)
			&& GetProp (hWndAbove, WIN_WINDOW_PROP)
			&& !IsWindowVisible (hWndAbove)
			&& !IsIconic (hWndAbove) ) /* ignore minimized windows */
		      break;
		  }
		/* If this is top of X windows in Windows stack,
		   raise it in X stack. */
		if (hWndAbove == NULL)
		  {
#if CYGMULTIWINDOW_DEBUG
		    winDebug ("\traise to top\n");
#endif
		    /* Raise the window to the top in Z order */
		    wmMsg.msg = WM_WM_RAISE;
		    if (fWMMsgInitialized)
		      winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
		  }
	      }
#endif
	  }

	if (!(pWinPos->flags & SWP_NOSIZE)) {
	  if (IsIconic(hwnd)){
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tIconic -> MINIMIZED\n");
#endif
	    if (winIsInternalWMRunning(pScreenInfo))
	      {
	      /* Raise the window to the top in Z order */
		wmMsg.msg = WM_WM_LOWER;
		if (fWMMsgInitialized)
		  winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	      }
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMMinimizeWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  } else if (IsZoomed(hwnd)){
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tZoomed -> MAXIMIZED\n");
#endif
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMMaximizeWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  } else {
#if CYGMULTIWINDOW_DEBUG
	    winDebug ("\tnone -> RESTORED\n");
#endif
	    winWindowsWMSendEvent(WindowsWMControllerNotify,
				  WindowsWMControllerNotifyMask,
				  1,
				  WindowsWMRestoreWindow,
				  pWin->drawable.id,
				  0, 0, 0, 0);
	  }
	}
	if (!g_fNoConfigureWindow ) {

	  if (!pRLWinPriv->fMovingOrSizing
	      /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
	    GetClientRect (hwnd, &rcClient);
	    MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);

	    if (!(pWinPos->flags & SWP_NOMOVE)
		&&!(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove & resize\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd);

	      winMWExtWMMoveResizeXWindow (pWin,
					   rcClient.left - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
					   rcClient.top - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
					   rcClient.right - rcClient.left
					   - wBorderWidth (pWin)*2,
					   rcClient.bottom - rcClient.top
					   - wBorderWidth (pWin)*2);
	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd);

	      winMWExtWMMoveResizeXWindow (pWin,
					   rcClient.left - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_XVIRTUALSCREEN),
					   rcClient.top - wBorderWidth (pWin)
					   - GetSystemMetrics (SM_YVIRTUALSCREEN),
					   rcClient.right - rcClient.left
					   - wBorderWidth (pWin)*2,
					   rcClient.bottom - rcClient.top
					   - wBorderWidth (pWin)*2);
	    } else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tmove\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd); 

	      winMWExtWMMoveXWindow (pWin,
				     rcClient.left - wBorderWidth (pWin)
				     - GetSystemMetrics (SM_XVIRTUALSCREEN),
				     rcClient.top - wBorderWidth (pWin)
				     - GetSystemMetrics (SM_YVIRTUALSCREEN));
	    } else if (!(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
	      winDebug ("\tresize\n");
#endif
	      if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow (pWin, hwnd); 

	      winMWExtWMResizeXWindow (pWin,
				       rcClient.right - rcClient.left
				       - wBorderWidth (pWin)*2,
				       rcClient.bottom - rcClient.top
				       - wBorderWidth (pWin)*2);
	    }
	  }
	}
      }
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
#endif
      return 0;

    case WM_SIZE:
      /* see dix/window.c */
      /* FIXME: Maximize/Restore? */
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
#if CYGMULTIWINDOW_DEBUG
      winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
#endif
      if (g_fNoConfigureWindow) break;

      /* Branch on type of resizing occurring */
      switch (wParam)
	{
	case SIZE_MINIMIZED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_MINIMIZED\n");
#endif
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	      /* Raise the window to the top in Z order */
	      wmMsg.msg = WM_WM_LOWER;
	      if (fWMMsgInitialized)
		winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
	    }
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMMinimizeWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;

	case SIZE_RESTORED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_RESTORED\n");
#endif
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMRestoreWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;

	case SIZE_MAXIMIZED:
#if CYGMULTIWINDOW_DEBUG
	  winDebug ("\tSIZE_MAXIMIZED\n");
#endif
	  winWindowsWMSendEvent(WindowsWMControllerNotify,
				WindowsWMControllerNotifyMask,
				1,
				WindowsWMMaximizeWindow,
				pWin->drawable.id,
				0, 0,
				LOWORD(lParam), HIWORD(lParam));
	  break;
	}

      /* Perform the resize and notify the X client */
      if (!pRLWinPriv->fMovingOrSizing)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
            winAdjustXWindow (pWin, hwnd);

	  winMWExtWMResizeXWindow (pWin,
				   (short) LOWORD(lParam)
				   - wBorderWidth (pWin)*2,
				   (short) HIWORD(lParam)
				   - wBorderWidth (pWin)*2);
	}
      break;

    case WM_ACTIVATEAPP:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      if (wParam)
	{
	  if (winIsInternalWMRunning(pScreenInfo))
	    {
	    }
	  else
	    {
	    }
	  winWindowsWMSendEvent(WindowsWMActivationNotify,
				WindowsWMActivationNotifyMask,
				1,
				WindowsWMIsActive,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      else
	{
	  winWindowsWMSendEvent(WindowsWMActivationNotify,
				WindowsWMActivationNotifyMask,
				1,
				WindowsWMIsInactive,
				pWin->drawable.id,
				0, 0,
				0, 0);
	}
      break;

    case WM_SETCURSOR:
      if (LOWORD(lParam) == HTCLIENT)
	{
	  if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
	  return TRUE;
	}
      break;

    case WM_ENTERSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      pRLWinPriv->fMovingOrSizing = TRUE;
      break;

    case WM_EXITSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
      winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
		(unsigned int)GetTickCount ());
#endif
      pRLWinPriv->fMovingOrSizing = FALSE;

      GetClientRect (hwnd, &rcClient);

      MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);

      if (winIsInternalWMRunning(pScreenInfo))
        winAdjustXWindow (pWin, hwnd); 

      winMWExtWMMoveResizeXWindow (pWin,
				   rcClient.left - wBorderWidth (pWin)
				   - GetSystemMetrics (SM_XVIRTUALSCREEN),
				   rcClient.top - wBorderWidth (pWin)
				   - GetSystemMetrics (SM_YVIRTUALSCREEN),
				   rcClient.right - rcClient.left
				   - wBorderWidth (pWin)*2,
				   rcClient.bottom - rcClient.top
				   - wBorderWidth (pWin)*2);
      break;

    case WM_MANAGE:
      ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
      break;

    case WM_UNMANAGE:
      ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
      break;

    default:
      break;
    }

  return DefWindowProc (hwnd, message, wParam, lParam);
}
Exemplo n.º 5
0
LRESULT CALLBACK
winWindowProc (HWND hwnd, UINT message, 
	       WPARAM wParam, LPARAM lParam)
{
  static winPrivScreenPtr	s_pScreenPriv = NULL;
  static winScreenInfo		*s_pScreenInfo = NULL;
  static ScreenPtr		s_pScreen = NULL;
  static HWND			s_hwndLastPrivates = NULL;
  static HINSTANCE		s_hInstance;
  static Bool			s_fTracking = FALSE;
  static unsigned long		s_ulServerGeneration = 0;
  int				iScanCode;
  int				i;

  /* Watch for server regeneration */
  if (g_ulServerGeneration != s_ulServerGeneration)
    {
      /* Store new server generation */
      s_ulServerGeneration = g_ulServerGeneration;
    }

  /* Only retrieve new privates pointers if window handle is null or changed */
  if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates)
      && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL)
    {
#if CYGDEBUG
      ErrorF ("winWindowProc - Setting privates handle\n");
#endif
      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
      s_pScreen = s_pScreenInfo->pScreen;
      s_hwndLastPrivates = hwnd;
    }
  else if (s_pScreenPriv == NULL)
    {
      /* For safety, handle case that should never happen */
      s_pScreenInfo = NULL;
      s_pScreen = NULL;
      s_hwndLastPrivates = NULL;
    }

  /* Branch on message type */
  switch (message)
    {
    case WM_TRAYICON:
      return winHandleIconMessage (hwnd, message, wParam, lParam,
				   s_pScreenPriv);

    case WM_CREATE:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_CREATE\n");
#endif
      
      /*
       * Add a property to our display window that references
       * this screens' privates.
       *
       * This allows the window procedure to refer to the
       * appropriate window DC and shadow DC for the window that
       * it is processing.  We use this to repaint exposed
       * areas of our display window.
       */
      s_pScreenPriv = ((LPCREATESTRUCT) lParam)->lpCreateParams;
      s_hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
      s_pScreenInfo = s_pScreenPriv->pScreenInfo;
      s_pScreen = s_pScreenInfo->pScreen;
      s_hwndLastPrivates = hwnd;
      SetProp (hwnd, WIN_SCR_PROP, s_pScreenPriv);

      /* Store the mode key states so restore doesn't try to restore them */
      winStoreModeKeyStates (s_pScreen);

      /* Setup tray icon */
      if (!s_pScreenInfo->fNoTrayIcon)
	{
	  /*
	   * NOTE: The WM_CREATE message is processed before CreateWindowEx
	   * returns, so s_pScreenPriv->hwndScreen is invalid at this point.
	   * We go ahead and copy our hwnd parameter over top of the screen
	   * privates hwndScreen so that we have a valid value for
	   * that member.  Otherwise, the tray icon will disappear
	   * the first time you move the mouse over top of it.
	   */
	  
	  s_pScreenPriv->hwndScreen = hwnd;

	  winInitNotifyIcon (s_pScreenPriv);
	}
      return 0;

    case WM_DISPLAYCHANGE:
      /* We cannot handle a display mode change during initialization */
      if (s_pScreenInfo == NULL)
	FatalError ("winWindowProc - WM_DISPLAYCHANGE - The display "
		    "mode changed while we were intializing.  This is "
		    "very bad and unexpected.  Exiting.\n");

      /*
       * We do not care about display changes with
       * fullscreen DirectDraw engines, because those engines set
       * their own mode when they become active.
       */
      if (s_pScreenInfo->fFullScreen
	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD))
	{
	  /* 
	   * Store the new display dimensions and depth.
	   * We do this here for future compatibility in case we
	   * ever allow switching from fullscreen to windowed mode.
	   */
	  s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
	  s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
	  s_pScreenPriv->dwLastWindowsBitsPixel
	    = GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);	  
	  break;
	}
      
      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, "
	      "new bpp: %d\n",
	      s_pScreenInfo->dwBPP,
	      s_pScreenPriv->dwLastWindowsBitsPixel,
	      wParam);

      ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d "
	      "new height: %d\n",
	      LOWORD (lParam), HIWORD (lParam));

      /*
       * TrueColor --> TrueColor depth changes are disruptive for:
       *	Windowed:
       *		Shadow DirectDraw
       *		Shadow DirectDraw Non-Locking
       *		Primary DirectDraw
       *
       * TrueColor --> TrueColor depth changes are non-optimal for:
       *	Windowed:
       *		Shadow GDI
       *
       *	FullScreen:
       *		Shadow GDI
       *
       * TrueColor --> PseudoColor or vice versa are disruptive for:
       *	Windowed:
       *		Shadow DirectDraw
       *		Shadow DirectDraw Non-Locking
       *		Primary DirectDraw
       *		Shadow GDI
       */

      /*
       * Check for a disruptive change in depth.
       * We can only display a message for a disruptive depth change,
       * we cannot do anything to correct the situation.
       */
      if ((s_pScreenInfo->dwBPP != wParam)
	  && (s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
	      || s_pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
	      || s_pScreenInfo->dwEngine == WIN_SERVER_PRIMARY_DD))
	{
	  /* Cannot display the visual until the depth is restored */
	  ErrorF ("winWindowProc - Disruptive change in depth\n");

	  /* Display Exit dialog */
	  winDisplayDepthChangeDialog (s_pScreenPriv);

	  /* Flag that we have an invalid screen depth */
	  s_pScreenPriv->fBadDepth = TRUE;

	  /* Minimize the display window */
	  ShowWindow (hwnd, SW_MINIMIZE);
	}
      else
	{
	  /* Flag that we have a valid screen depth */
	  s_pScreenPriv->fBadDepth = FALSE;
	}
      
      /*
       * Check for a change in display dimensions.
       * We can simply recreate the same-sized primary surface when
       * the display dimensions change.
       */
      if (s_pScreenPriv->dwLastWindowsWidth != LOWORD (lParam)
	  || s_pScreenPriv->dwLastWindowsHeight != HIWORD (lParam))
	{
	  /*
	   * NOTE: The non-DirectDraw engines set the ReleasePrimarySurface
	   * and CreatePrimarySurface function pointers to point
	   * to the no operation function, NoopDDA.  This allows us
	   * to blindly call these functions, even if they are not
	   * relevant to the current engine (e.g., Shadow GDI).
	   */

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n");
#endif
	  
	  /* Release the old primary surface */
	  (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen);

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Released "
		  "primary surface\n");
#endif

	  /* Create the new primary surface */
	  (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen);

#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Recreated "
		  "primary surface\n");
#endif
	}
      else
	{
#if CYGDEBUG
	  ErrorF ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not "
		  "change\n");
#endif
	}

      /* Store the new display dimensions and depth */
      s_pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
      s_pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
      s_pScreenPriv->dwLastWindowsBitsPixel
	= GetDeviceCaps (s_pScreenPriv->hdcScreen, BITSPIXEL);
      break;

    case WM_SIZE:
      {
	SCROLLINFO		si;
	RECT			rcWindow;
	int			iWidth, iHeight;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_SIZE\n");
#endif

	/* Break if we do not use scrollbars */
	if (!s_pScreenInfo->fScrollbars
	    || !s_pScreenInfo->fDecoration
	    || s_pScreenInfo->fRootless
	    || s_pScreenInfo->fMultiWindow
	    || s_pScreenInfo->fFullScreen)
	  break;

	/* No need to resize if we get minimized */
	if (wParam == SIZE_MINIMIZED)
	  return 0;

	/*
	 * Get the size of the whole window, including client area,
	 * scrollbars, and non-client area decorations (caption, borders).
	 * We do this because we need to check if the client area
	 * without scrollbars is large enough to display the whole visual.
	 * The new client area size passed by lParam already subtracts
	 * the size of the scrollbars if they are currently displayed.
	 * So checking is LOWORD(lParam) == visual_width and
	 * HIWORD(lParam) == visual_height will never tell us to hide
	 * the scrollbars because the client area would always be too small.
	 * GetClientRect returns the same sizes given by lParam, so we
	 * cannot use GetClientRect either.
	 */
	GetWindowRect (hwnd, &rcWindow);
	iWidth = rcWindow.right - rcWindow.left;
	iHeight = rcWindow.bottom - rcWindow.top;

	ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, "
		"new client area w: %d h: %d\n",
		iWidth, iHeight, LOWORD (lParam), HIWORD (lParam));

	/* Subtract the frame size from the window size. */
	iWidth -= 2 * GetSystemMetrics (SM_CXSIZEFRAME);
	iHeight -= (2 * GetSystemMetrics (SM_CYSIZEFRAME)
		    + GetSystemMetrics (SM_CYCAPTION));

	/*
	 * Update scrollbar page sizes.
	 * NOTE: If page size == range, then the scrollbar is
	 * automatically hidden.
	 */

	/* Is the naked client area large enough to show the whole visual? */
	if (iWidth < s_pScreenInfo->dwWidth
	    || iHeight < s_pScreenInfo->dwHeight)
	  {
	    /* Client area too small to display visual, use scrollbars */
	    iWidth -= GetSystemMetrics (SM_CXVSCROLL);
	    iHeight -= GetSystemMetrics (SM_CYHSCROLL);
	  }
	
	/* Set the horizontal scrollbar page size */
	si.cbSize = sizeof (si);
	si.fMask = SIF_PAGE | SIF_RANGE;
	si.nMin = 0;
	si.nMax = s_pScreenInfo->dwWidth - 1;
	si.nPage = iWidth;
	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
	
	/* Set the vertical scrollbar page size */
	si.cbSize = sizeof (si);
	si.fMask = SIF_PAGE | SIF_RANGE;
	si.nMin = 0;
	si.nMax = s_pScreenInfo->dwHeight - 1;
	si.nPage = iHeight;
	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);

	/*
	 * NOTE: Scrollbars may have moved if they were at the 
	 * far right/bottom, so we query their current position.
	 */
	
	/* Get the horizontal scrollbar position and set the offset */
	si.cbSize = sizeof (si);
	si.fMask = SIF_POS;
	GetScrollInfo (hwnd, SB_HORZ, &si);
	s_pScreenInfo->dwXOffset = -si.nPos;
	
	/* Get the vertical scrollbar position and set the offset */
	si.cbSize = sizeof (si);
	si.fMask = SIF_POS;
	GetScrollInfo (hwnd, SB_VERT, &si);
	s_pScreenInfo->dwYOffset = -si.nPos;
      }
      return 0;

    case WM_VSCROLL:
      {
	SCROLLINFO		si;
	int			iVertPos;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_VSCROLL\n");
#endif
      
	/* Get vertical scroll bar info */
	si.cbSize = sizeof (si);
	si.fMask = SIF_ALL;
	GetScrollInfo (hwnd, SB_VERT, &si);

	/* Save the vertical position for comparison later */
	iVertPos = si.nPos;

	/*
	 * Don't forget:
	 * moving the scrollbar to the DOWN, scroll the content UP
	 */
	switch (LOWORD(wParam))
	  {
	  case SB_TOP:
	    si.nPos = si.nMin;
	    break;
	  
	  case SB_BOTTOM:
	    si.nPos = si.nMax - si.nPage + 1;
	    break;

	  case SB_LINEUP:
	    si.nPos -= 1;
	    break;
	  
	  case SB_LINEDOWN:
	    si.nPos += 1;
	    break;
	  
	  case SB_PAGEUP:
	    si.nPos -= si.nPage;
	    break;
	  
	  case SB_PAGEDOWN:
	    si.nPos += si.nPage;
	    break;

	  case SB_THUMBTRACK:
	    si.nPos = si.nTrackPos;
	    break;

	  default:
	    break;
	  }

	/*
	 * We retrieve the position after setting it,
	 * because Windows may adjust it.
	 */
	si.fMask = SIF_POS;
	SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
	GetScrollInfo (hwnd, SB_VERT, &si);
      
	/* Scroll the window if the position has changed */
	if (si.nPos != iVertPos)
	  {
	    /* Save the new offset for bit block transfers, etc. */
	    s_pScreenInfo->dwYOffset = -si.nPos;

	    /* Change displayed region in the window */
	    ScrollWindowEx (hwnd,
			    0,
			    iVertPos - si.nPos,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    SW_INVALIDATE);
	  
	    /* Redraw the window contents */
	    UpdateWindow (hwnd);
	  }
      }
      return 0;

    case WM_HSCROLL:
      {
	SCROLLINFO		si;
	int			iHorzPos;

#if CYGDEBUG
	ErrorF ("winWindowProc - WM_HSCROLL\n");
#endif
      
	/* Get horizontal scroll bar info */
	si.cbSize = sizeof (si);
	si.fMask = SIF_ALL;
	GetScrollInfo (hwnd, SB_HORZ, &si);

	/* Save the horizontal position for comparison later */
	iHorzPos = si.nPos;

	/*
	 * Don't forget:
	 * moving the scrollbar to the RIGHT, scroll the content LEFT
	 */
	switch (LOWORD(wParam))
	  {
	  case SB_LEFT:
	    si.nPos = si.nMin;
	    break;
	  
	  case SB_RIGHT:
	    si.nPos = si.nMax - si.nPage + 1;
	    break;

	  case SB_LINELEFT:
	    si.nPos -= 1;
	    break;
	  
	  case SB_LINERIGHT:
	    si.nPos += 1;
	    break;
	  
	  case SB_PAGELEFT:
	    si.nPos -= si.nPage;
	    break;
	  
	  case SB_PAGERIGHT:
	    si.nPos += si.nPage;
	    break;

	  case SB_THUMBTRACK:
	    si.nPos = si.nTrackPos;
	    break;

	  default:
	    break;
	  }

	/*
	 * We retrieve the position after setting it,
	 * because Windows may adjust it.
	 */
	si.fMask = SIF_POS;
	SetScrollInfo (hwnd, SB_HORZ, &si, TRUE);
	GetScrollInfo (hwnd, SB_HORZ, &si);
      
	/* Scroll the window if the position has changed */
	if (si.nPos != iHorzPos)
	  {
	    /* Save the new offset for bit block transfers, etc. */
	    s_pScreenInfo->dwXOffset = -si.nPos;

	    /* Change displayed region in the window */
	    ScrollWindowEx (hwnd,
			    iHorzPos - si.nPos,
			    0,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    SW_INVALIDATE);
	  
	    /* Redraw the window contents */
	    UpdateWindow (hwnd);
	  }
      }
      return 0;

    case WM_GETMINMAXINFO:
      {
	MINMAXINFO		*pMinMaxInfo = (MINMAXINFO *) lParam;
	int			iCaptionHeight;
	int			iBorderHeight, iBorderWidth;

#if CYGDEBUG	
	ErrorF ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n",
		s_pScreenInfo);
#endif

	/* Can't do anything without screen info */
	if (s_pScreenInfo == NULL
	    || !s_pScreenInfo->fScrollbars
	    || s_pScreenInfo->fFullScreen
	    || !s_pScreenInfo->fDecoration
	    || s_pScreenInfo->fRootless
	    || s_pScreenInfo->fMultiWindow)
	  break;

	/*
	 * Here we can override the maximum tracking size, which
	 * is the largest size that can be assigned to our window
	 * via the sizing border.
	 */

	/*
	 * FIXME: Do we only need to do this once, since our visual size
	 * does not change?  Does Windows store this value statically
	 * once we have set it once?
	 */

	/* Get the border and caption sizes */
	iCaptionHeight = GetSystemMetrics (SM_CYCAPTION);
	iBorderWidth = 2 * GetSystemMetrics (SM_CXSIZEFRAME);
	iBorderHeight = 2 * GetSystemMetrics (SM_CYSIZEFRAME);
	
	/* Allow the full visual to be displayed */
	pMinMaxInfo->ptMaxTrackSize.x
	  = s_pScreenInfo->dwWidth + iBorderWidth;
	pMinMaxInfo->ptMaxTrackSize.y
	  = s_pScreenInfo->dwHeight + iBorderHeight + iCaptionHeight;
      }
      return 0;

    case WM_ERASEBKGND:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ERASEBKGND\n");
#endif
      /*
       * Pretend that we did erase the background but we don't care,
       * the application uses the full window estate. This avoids some
       * flickering when resizing.
       */
      return TRUE;

    case WM_PAINT:
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_PAINT\n");
#endif
      /* Only paint if we have privates and the server is enabled */
      if (s_pScreenPriv == NULL
	  || !s_pScreenPriv->fEnabled
	  || (s_pScreenInfo->fFullScreen && !s_pScreenPriv->fActive)
	  || s_pScreenPriv->fBadDepth)
	{
	  /* We don't want to paint */
	  break;
	}

      /* Break out here if we don't have a valid paint routine */
      if (s_pScreenPriv->pwinBltExposedRegions == NULL)
	break;
      
      /* Call the engine dependent repainter */
      (*s_pScreenPriv->pwinBltExposedRegions) (s_pScreen);
      return 0;

    case WM_PALETTECHANGED:
      {
#if CYGDEBUG
	ErrorF ("winWindowProc - WM_PALETTECHANGED\n");
#endif
	/*
	 * Don't process if we don't have privates or a colormap,
	 * or if we have an invalid depth.
	 */
	if (s_pScreenPriv == NULL
	    || s_pScreenPriv->pcmapInstalled == NULL
	    || s_pScreenPriv->fBadDepth)
	  break;

	/* Return if we caused the palette to change */
	if ((HWND) wParam == hwnd)
	  {
	    /* Redraw the screen */
	    (*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
	    return 0;
	  }
	
	/* Reinstall the windows palette */
	(*s_pScreenPriv->pwinRealizeInstalledPalette) (s_pScreen);
	
	/* Redraw the screen */
	(*s_pScreenPriv->pwinRedrawScreen) (s_pScreen);
	return 0;
      }

    case WM_MOUSEMOVE:
      /* We can't do anything without privates */
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Has the mouse pointer crossed screens? */
      if (s_pScreen != miPointerCurrentScreen ())
	miPointerSetNewScreen (s_pScreenInfo->dwScreen,
			       GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset);

      /* Are we tracking yet? */
      if (!s_fTracking)
	{
	  TRACKMOUSEEVENT		tme;
	  
	  /* Setup data structure */
	  ZeroMemory (&tme, sizeof (tme));
	  tme.cbSize = sizeof (tme);
	  tme.dwFlags = TME_LEAVE;
	  tme.hwndTrack = hwnd;

	  /* Call the tracking function */
	  if (!(*g_fpTrackMouseEvent) (&tme))
	    ErrorF ("winWindowProc - _TrackMouseEvent failed\n");

	  /* Flag that we are tracking now */
	  s_fTracking = TRUE;
	}

      /* Hide or show the Windows mouse cursor */
      if (g_fCursor && (s_pScreenPriv->fActive || s_pScreenInfo->fLessPointer))
	{
	  /* Hide Windows cursor */
	  g_fCursor = FALSE;
	  ShowCursor (FALSE);
	}
      else if (!g_fCursor && !s_pScreenPriv->fActive
	       && !s_pScreenInfo->fLessPointer)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      
      /* Deliver absolute cursor position to X Server */
      miPointerAbsoluteCursor (GET_X_LPARAM(lParam)-s_pScreenInfo->dwXOffset,
			       GET_Y_LPARAM(lParam)-s_pScreenInfo->dwYOffset,
			       g_c32LastInputEventTime = GetTickCount ());
      return 0;

    case WM_NCMOUSEMOVE:
      /*
       * We break instead of returning 0 since we need to call
       * DefWindowProc to get the mouse cursor changes
       * and min/max/close button highlighting in Windows XP.
       * The Platform SDK says that you should return 0 if you
       * process this message, but it fails to mention that you
       * will give up any default functionality if you do return 0.
       */
      
      /* We can't do anything without privates */
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      
      /* Non-client mouse movement, show Windows cursor */
      if (!g_fCursor)
	{
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      break;

    case WM_MOUSELEAVE:
      /* Mouse has left our client area */

      /* Flag that we are no longer tracking */
      s_fTracking = FALSE;

      /* Show the mouse cursor, if necessary */
      if (!g_fCursor)
	{
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button1, wParam);
      
    case WM_LBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button2, wParam);
      
    case WM_MBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button2, wParam);
      
    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) SetCapture (hwnd);
      return winMouseButtonsHandle (s_pScreen, ButtonPress, Button3, wParam);
      
    case WM_RBUTTONUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
      if (s_pScreenInfo->fRootless) ReleaseCapture ();
      return winMouseButtonsHandle (s_pScreen, ButtonRelease, Button3, wParam);

    case WM_TIMER:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Branch on the timer id */
      switch (wParam)
	{
	case WIN_E3B_TIMER_ID:
	  /* Send delayed button press */
	  winMouseButtonsSendEvent (ButtonPress,
				    s_pScreenPriv->iE3BCachedPress);

	  /* Kill this timer */
	  KillTimer (s_pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);

	  /* Clear screen privates flags */
	  s_pScreenPriv->iE3BCachedPress = 0;
	  break;

	case WIN_POLLING_MOUSE_TIMER_ID:
	  {
	    POINT		point;
	    
	    /* Get the current position of the mouse cursor */
	    GetCursorPos (&point);
	    
	    /* Map from screen (-X, -Y) to root (0, 0) */
	    point.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
	    point.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
	    
	    /* Deliver absolute cursor position to X Server */
	    miPointerAbsoluteCursor (point.x, point.y,
				     g_c32LastInputEventTime = GetTickCount());
	  }
	}
      return 0;

    case WM_CTLCOLORSCROLLBAR:
      FatalError ("winWindowProc - WM_CTLCOLORSCROLLBAR - We are not "
		  "supposed to get this message.  Exiting.\n");
      return 0;

    case WM_MOUSEWHEEL:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;
#if CYGDEBUG
      ErrorF ("winWindowProc - WM_MOUSEWHEEL\n");
#endif
      winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam));
      break;

    case WM_SETFOCUS:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Restore the state of all mode keys */
      winRestoreModeKeyStates (s_pScreen);
      return 0;

    case WM_KILLFOCUS:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Store the state of all mode keys */
      winStoreModeKeyStates (s_pScreen);

      /* Release any pressed keys */
      winKeybdReleaseKeys ();
      return 0;

#if WIN_NEW_KEYBOARD_SUPPORT
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
    case WM_SYSKEYUP:
    case WM_KEYUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /* Don't process keys if we are not active */
      if (!s_pScreenPriv->fActive)
	return 0;

      winProcessKeyEvent ((DWORD)wParam, (DWORD) lParam);
      return 0;

    case WM_DEADCHAR:
    case WM_SYSDEADCHAR:
      return 0;

#else /* WIN_NEW_KEYBOARD_SUPPORT */
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /*
       * FIXME: Catching Alt-F4 like this is really terrible.  This should
       * be generalized to handle other Windows keyboard signals.  Actually,
       * the list keys to catch and the actions to perform when caught should
       * be configurable; that way user's can customize the keys that they
       * need to have passed through to their window manager or apps, or they
       * can remap certain actions to new key codes that do not conflict
       * with the X apps that they are using.  Yeah, that'll take awhile.
       */
      if ((s_pScreenInfo->fUseWinKillKey && wParam == VK_F4
	   && (GetKeyState (VK_MENU) & 0x8000))
	  || (s_pScreenInfo->fUseUnixKillKey && wParam == VK_BACK
	      && (GetKeyState (VK_MENU) & 0x8000)
	      && (GetKeyState (VK_CONTROL) & 0x8000)))
	{
	  /*
	   * Better leave this message here, just in case some unsuspecting
	   * user enters Alt + F4 and is surprised when the application
	   * quits.
	   */
	  ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n");
	  
	  /* Display Exit dialog */
	  winDisplayExitDialog (s_pScreenPriv);
	  return 0;
	}
      
      /*
       * Don't do anything for the Windows keys, as focus will soon
       * be returned to Windows.  We may be able to trap the Windows keys,
       * but we should determine if that is desirable before doing so.
       */
      if (wParam == VK_LWIN || wParam == VK_RWIN)
	break;

      /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */
      if (winIsFakeCtrl_L (message, wParam, lParam))
	return 0;
      
      /* Send the key event(s) */
      winTranslateKey (wParam, lParam, &iScanCode);
      for (i = 0; i < LOWORD(lParam); ++i)
	winSendKeyEvent (iScanCode, TRUE);
      return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:
      if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
	break;

      /*
       * Don't do anything for the Windows keys, as focus will soon
       * be returned to Windows.  We may be able to trap the Windows keys,
       * but we should determine if that is desirable before doing so.
       */
      if (wParam == VK_LWIN || wParam == VK_RWIN)
	break;

      /* Ignore the fake Ctrl_L that follows an AltGr release */
      if (winIsFakeCtrl_L (message, wParam, lParam))
	return 0;

      /* Enqueue a keyup event */
      winTranslateKey (wParam, lParam, &iScanCode);
      winSendKeyEvent (iScanCode, FALSE);
      return 0;
#endif /* WIN_NEW_KEYBOARD_SUPPORT */

    case WM_HOTKEY:
      if (s_pScreenPriv == NULL)
	break;

      /* Call the engine-specific hot key handler */
      (*s_pScreenPriv->pwinHotKeyAltTab) (s_pScreen);
      return 0;

    case WM_ACTIVATE:
      if (s_pScreenPriv == NULL
	  || s_pScreenInfo->fIgnoreInput)
	break;

      /* TODO: Override display of window when we have a bad depth */
      if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth)
	{
	  ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying "
		  "to override window activation\n");

	  /* Minimize the window */
	  ShowWindow (hwnd, SW_MINIMIZE);

	  /* Display dialog box */
	  if (g_hDlgDepthChange != NULL)
	    {
	      /* Make the existing dialog box active */
	      SetActiveWindow (g_hDlgDepthChange);
	    }
	  else
	    {
	      /* TODO: Recreate the dialog box and bring to the top */
	      ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT);
	    }

	  /* Don't do any other processing of this message */
	  return 0;
	}

#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ACTIVATE\n");
#endif

      /*
       * Focus is being changed to another window.
       * The other window may or may not belong to
       * our process.
       */

      /* Clear any lingering wheel delta */
      s_pScreenPriv->iDeltaZ = 0;

      /* Reshow the Windows mouse cursor if we are being deactivated */
      if (LOWORD(wParam) == WA_INACTIVE
	  && !g_fCursor)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}
      return 0;

    case WM_ACTIVATEAPP:
      if (s_pScreenPriv == NULL
	  || s_pScreenInfo->fIgnoreInput)
	break;

#if CYGDEBUG
      ErrorF ("winWindowProc - WM_ACTIVATEAPP\n");
#endif

      /* Activate or deactivate */
      s_pScreenPriv->fActive = wParam;

      /* Reshow the Windows mouse cursor if we are being deactivated */
      if (!s_pScreenPriv->fActive
	  && !g_fCursor)
	{
	  /* Show Windows cursor */
	  g_fCursor = TRUE;
	  ShowCursor (TRUE);
	}

      /* Call engine specific screen activation/deactivation function */
      (*s_pScreenPriv->pwinActivateApp) (s_pScreen);
      return 0;

    case WM_COMMAND:
      switch (LOWORD (wParam))
	{
	case ID_APP_EXIT:
	  /* Display Exit dialog */
	  winDisplayExitDialog (s_pScreenPriv);
	  return 0;

	case ID_APP_HIDE_ROOT:
	  ShowWindow (s_pScreenPriv->hwndScreen, SW_HIDE);
	  s_pScreenPriv->fRootWindowShown = FALSE;
	  return 0;

	case ID_APP_SHOW_ROOT:
	  ShowWindow (s_pScreenPriv->hwndScreen, SW_SHOW);
	  s_pScreenPriv->fRootWindowShown = TRUE;
	  return 0;

	default:
	  /* It's probably one of the custom menus... */
	  return HandleCustomWM_COMMAND (0, LOWORD (wParam));
	  
	}
      break;

    case WM_GIVEUP:
       /* Tell X that we are giving up */
      winDeinitClipboard ();
      winDeinitMultiWindowWM ();
      GiveUp (0);
      return 0;

    case WM_CLOSE:
      /* Display Exit dialog */
      winDisplayExitDialog (s_pScreenPriv);
      return 0;
    }

  return DefWindowProc (hwnd, message, wParam, lParam);
}
Exemplo n.º 6
0
/*
 * ProcessInputEvents
 *  Read and process events from the event queue until it is empty.
 */
void ProcessInputEvents(void)
{
    EventRec *e;
    int     x, y;
    xEvent  xe;
    static int  old_flags = 0;  // last known modifier state
    // button number and modifier mask of currently pressed fake button
    static int darwinFakeMouseButtonDown = 0;
    static int darwinFakeMouseButtonMask = 0;

    // Empty the signaling pipe
    x = sizeof(xe);
    while (x == sizeof(xe)) {
        x = read(darwinEventReadFD, &xe, sizeof(xe));
    }

    while (darwinEventQueue.head != darwinEventQueue.tail)
    {
        if (screenIsSaved == SCREEN_SAVER_ON)
            SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);

        e = &darwinEventQueue.events[darwinEventQueue.head];
        xe = e->event;

        // Shift from global screen coordinates to coordinates relative to
        // the origin of the current screen.
        xe.u.keyButtonPointer.rootX -= darwinMainScreenX +
                dixScreenOrigins[miPointerCurrentScreen()->myNum].x;
        xe.u.keyButtonPointer.rootY -= darwinMainScreenY +
                dixScreenOrigins[miPointerCurrentScreen()->myNum].y;

        /*
         * Assumption - screen switching can only occur on motion events
         */
        if (e->pScreen != darwinEventQueue.pDequeueScreen)
        {
            darwinEventQueue.pDequeueScreen = e->pScreen;
            x = xe.u.keyButtonPointer.rootX;
            y = xe.u.keyButtonPointer.rootY;
            if (darwinEventQueue.head == QUEUE_SIZE - 1)
                darwinEventQueue.head = 0;
            else
                ++darwinEventQueue.head;
            NewCurrentScreen (darwinEventQueue.pDequeueScreen, x, y);
        }
        else
        {
            if (darwinEventQueue.head == QUEUE_SIZE - 1)
                darwinEventQueue.head = 0;
            else
                ++darwinEventQueue.head;
            switch (xe.u.u.type)
            {
            case KeyPress:
                if (old_flags == 0
                    && darwinSyncKeymap && darwinKeymapFile == NULL)
                {
                    /* See if keymap has changed. */

                    static unsigned int last_seed;
                    unsigned int this_seed;

                    this_seed = DarwinModeSystemKeymapSeed();
                    if (this_seed != last_seed)
                    {
                        last_seed = this_seed;
                        DarwinKeyboardReload(darwinKeyboard);
                    }
                }
                /* fall through */

            case KeyRelease:
                xe.u.u.detail += MIN_KEYCODE;
                (*darwinEventQueue.pKbd->processInputProc)
                    (&xe, (DeviceIntPtr)darwinEventQueue.pKbd, 1);
                break;

            case ButtonPress:
                miPointerAbsoluteCursor(xe.u.keyButtonPointer.rootX,
                                        xe.u.keyButtonPointer.rootY,
                                        xe.u.keyButtonPointer.time);
                if (darwinFakeButtons && xe.u.u.detail == 1) {
                    // Mimic multi-button mouse with modifier-clicks
                    // If both sets of modifiers are pressed,
                    // button 2 is clicked.
                    if ((old_flags & darwinFakeMouse2Mask) ==
                        darwinFakeMouse2Mask)
                    {
                        DarwinSimulateMouseClick(&xe, 2, darwinFakeMouse2Mask);
                        darwinFakeMouseButtonDown = 2;
                        darwinFakeMouseButtonMask = darwinFakeMouse2Mask;
                        break;
                    }
                    else if ((old_flags & darwinFakeMouse3Mask) ==
                             darwinFakeMouse3Mask)
                    {
                        DarwinSimulateMouseClick(&xe, 3, darwinFakeMouse3Mask);
                        darwinFakeMouseButtonDown = 3;
                        darwinFakeMouseButtonMask = darwinFakeMouse3Mask;
                        break;
                    }
                }
                (*darwinEventQueue.pPtr->processInputProc)
                        (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
                break;

            case ButtonRelease:
                miPointerAbsoluteCursor(xe.u.keyButtonPointer.rootX,
                                        xe.u.keyButtonPointer.rootY,
                                        xe.u.keyButtonPointer.time);
                if (darwinFakeButtons && xe.u.u.detail == 1 &&
                    darwinFakeMouseButtonDown)
                {
                    // If last mousedown was a fake click, don't check for
                    // mouse modifiers here. The user may have released the
                    // modifiers before the mouse button.
                    xe.u.u.detail = darwinFakeMouseButtonDown;
                    darwinFakeMouseButtonDown = 0;
                    (*darwinEventQueue.pPtr->processInputProc)
                            (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);

                    // Bring modifiers back up to date
                    DarwinUpdateModifiers(&xe, KeyPress,
                            darwinFakeMouseButtonMask & old_flags);
                    darwinFakeMouseButtonMask = 0;
                } else {
                    (*darwinEventQueue.pPtr->processInputProc)
                            (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
                }
                break;

            case MotionNotify:
                miPointerAbsoluteCursor(xe.u.keyButtonPointer.rootX,
                                        xe.u.keyButtonPointer.rootY,
                                        xe.u.keyButtonPointer.time);
                break;

            case kXDarwinUpdateModifiers:
            {
                // Update modifier state.
                // Any amount of modifiers may have changed.
                int flags = xe.u.clientMessage.u.l.longs0;
                DarwinUpdateModifiers(&xe, KeyRelease,
                                      old_flags & ~flags);
                DarwinUpdateModifiers(&xe, KeyPress,
                                      ~old_flags & flags);
                old_flags = flags;
                break;
            }

            case kXDarwinUpdateButtons:
            {
                long hwDelta = xe.u.clientMessage.u.l.longs0;
                long hwButtons = xe.u.clientMessage.u.l.longs1;
                int i;

                for (i = 1; i < 5; i++) {
                    if (hwDelta & (1 << i)) {
                        // IOKit and X have different numbering for the
                        // middle and right mouse buttons.
                        if (i == 1) {
                            xe.u.u.detail = 3;
                        } else if (i == 2) {
                            xe.u.u.detail = 2;
                        } else {
                            xe.u.u.detail = i + 1;
                        }
                        if (hwButtons & (1 << i)) {
                            xe.u.u.type = ButtonPress;
                        } else {
                            xe.u.u.type = ButtonRelease;
                        }
                        (*darwinEventQueue.pPtr->processInputProc)
                    (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
                    }
                }
                break;
            }

            case kXDarwinScrollWheel:
            {
                short count = xe.u.clientMessage.u.s.shorts0;

                if (count > 0) {
                    xe.u.u.detail = SCROLLWHEELUPFAKE;
                } else {
                    xe.u.u.detail = SCROLLWHEELDOWNFAKE;
                    count = -count;
                }

                for (; count; --count) {
                    xe.u.u.type = ButtonPress;
                    (*darwinEventQueue.pPtr->processInputProc)
                            (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
                    xe.u.u.type = ButtonRelease;
                    (*darwinEventQueue.pPtr->processInputProc)
                            (&xe, (DeviceIntPtr)darwinEventQueue.pPtr, 1);
                }
                break;
            }

            default:
                // Check for mode specific event
                DarwinModeProcessEvent(&xe);
            }
        }
    }

    miPointerUpdate();
}
Exemplo n.º 7
0
static Bool
xf86RandRSetConfig (ScreenPtr		pScreen,
		    Rotation		rotation,
		    int			rate,
		    RRScreenSizePtr	pSize)
{
    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
    DisplayModePtr	    mode;
    int			    px, py;
    Bool		    useVirtual = FALSE;
    Rotation		    oldRotation = randrp->rotation;

    miPointerPosition (&px, &py);
    for (mode = scrp->modes; ; mode = mode->next)
    {
	if (mode->HDisplay == pSize->width &&
	    mode->VDisplay == pSize->height &&
	    (rate == 0 || xf86RandRModeRefresh (mode) == rate))
	    break;
	if (mode->next == scrp->modes)
	{
	    if (pSize->width == randrp->virtualX &&
		pSize->height == randrp->virtualY)
	    {
		mode = scrp->modes;
		useVirtual = TRUE;
		break;
	    }
	    return FALSE;
	}
    }

    if (randrp->rotation != rotation) {

        /* Have the driver do its thing. */
	if (scrp->DriverFunc) {
	    xorgRRRotation RRRotation;
	    RRRotation.RRConfig.rotation = rotation;
	    RRRotation.RRConfig.rate = rate;
	    RRRotation.RRConfig.width = pSize->width;
	    RRRotation.RRConfig.height = pSize->height;

	    /*
	     * Currently we need to rely on HW support for rotation.
	     */
	    if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
		return FALSE;
	} else
	    return FALSE;

	randrp->rotation = rotation;
    }

    if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
	if(randrp->rotation != oldRotation) {
	   /* Have the driver undo its thing. */
	   if (scrp->DriverFunc) {
	       xorgRRRotation RRRotation;
	       RRRotation.RRConfig.rotation = oldRotation;
	       RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
	       RRRotation.RRConfig.width = pScreen->width;
	       RRRotation.RRConfig.height = pScreen->height;
	       (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
	   }

	   randrp->rotation = oldRotation;
	}
	return FALSE;
    }
    /*
     * Move the cursor back where it belongs; SwitchMode repositions it
     */
    if (pScreen == miPointerCurrentScreen ())
    {
	px = (px >= pScreen->width ? (pScreen->width - 1) : px);
	py = (py >= pScreen->height ? (pScreen->height - 1) : py);

        xf86SetViewport(pScreen, px, py);

        (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
    }

    return TRUE;
}