示例#1
0
void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
{
  /*
   * Zero timeout.
   */

  static struct timeval zero;

  /*
   * Current timestamp.
   */

  static int now;

  /*
   * Pending bytes to write to the
   * network.
   */

  static int flushable;

  /*
   * Set if we need to synchronize
   * any drawable.
   */

  static int synchronize;

  #ifdef BLOCKS
  fprintf(stderr, "[Begin block]\n");
  #endif

  now = GetTimeInMillis();

  #ifdef NX_DEBUG_INPUT

  if (nxagentDebugInputDevices == 1 &&
        now - nxagentLastInputDevicesDumpTime > 5000)
  {
    nxagentLastInputDevicesDumpTime = now;

    nxagentDumpInputDevicesState();
  }

  #endif

  if (nxagentNeedConnectionChange() == 1)
  {
    #ifdef TEST
    fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionChanges "
                "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
    #endif

    nxagentHandleConnectionChanges();
  }

  if (nxagentOption(Rootless) &&
          nxagentLastWindowDestroyed && nxagentRootlessDialogPid == 0 &&
              now > nxagentLastWindowDestroyedTime + 30 * 1000 && !nxagentOption(NoRootlessExit))
  {
    #ifdef WARNING
    fprintf(stderr, "nxagentBlockHandler: No application running. Closing the session.\n");
    #endif

    nxagentTerminateSession();
  }

  #ifdef TEST

  if (nxagentLastWindowDestroyed == 1)
  {
    fprintf(stderr, "nxagentBlockHandler: Elapsed time [%lu].\n",
                now - nxagentLastWindowDestroyedTime);
  }

  #endif

  /*
   * Slow down the agent if the session is
   * not connected to a valid display.
   */

  if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0)
  {
    usleep(LOOP_DELAY_IF_DOWN * 1000);

    now = GetTimeInMillis();
  }

  /*
   * Update the shadow display. This is
   * only for test purposes.
   */

  #ifdef DUMP

  nxagentPixmapOnShadowDisplay(NULL);

  nxagentFbOnShadowDisplay();

  #endif

  /*
   * We need this here because some window
   * configuration changes can be generated
   * by the X server outside the control of
   * the DIX.
   */

  nxagentFlushConfigureWindow();

  /*
   * Check whether there is any drawable to
   * synchronize.
   */

  #ifdef TEST
  fprintf(stderr, "nxagentBlockHandler: Checking synchronization at %s with "
              "[%d][%d][%d].\n", GetTimeInMillisAsString(), nxagentCorruptedWindows,
                  nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps);
  #endif

  synchronize = (nxagentCorruptedWindows > 0 ||
                     nxagentCorruptedBackgrounds > 0 ||
                         nxagentCorruptedPixmaps > 0);

  /*
   * The synchronization function requires a mask as
   * parameter:
   *
   * EVENT_BREAK       Breaks if an user input, like
   *                   a key press or a mouse move,
   *                   is detected.
   *
   * CONGESTION_BREAK  Breaks if the congestion beco-
   *                   mes greater than 4.
   *
   * BLOCKING_BREAK    Breaks if the display descript-
   *                   or becomes blocked for write
   *                   during the loop.
   *
   * ALWAYS_BREAK      Any of the previous conditions
   *                   is met.
   *
   * NEVER_BREAK       The loop continues until all
   *                   the drawables are synchronized.
   */

  if (synchronize == 1)
  {
    /*
     * We should not enter the synchronization
     * loop if there is any user input pending,
     * i.e. if we are in the middle of a scroll
     * operation.
     */

    if (nxagentForceSynchronization == 1)
    {
      #ifdef TEST
      fprintf(stderr, "nxagentBlockHandler: Going to force a synchronization at %s.\n",
                GetTimeInMillisAsString());
      #endif

      nxagentSynchronizationLoop(NEVER_BREAK);

      nxagentForceSynchronization = 0;
    }
    else if (nxagentUserInput(NULL) == 0 &&
                 nxagentBlocking == 0 &&
                     nxagentCongestion <= 4)
    {
      #ifdef TEST
      fprintf(stderr, "nxagentBlockHandler: Going to synchronize at %s.\n",
                GetTimeInMillisAsString());
      #endif

      nxagentSynchronizationLoop(ALWAYS_BREAK);
    }
    #ifdef TEST
    else
    {
      fprintf(stderr, "nxagentBlockHandler: Not synchronizing with [%d][%d].\n",
                  nxagentBlocking, nxagentCongestion);
    }
    #endif

    /*
     * Check if we have more corrupted resources
     * and whether the conditions are satisfied
     * to continue with the synchronization.
     */

    synchronize = (nxagentCongestion <= 4 &&
                       (nxagentCorruptedWindows > 0 ||
                           nxagentCorruptedBackgrounds > 0 ||
                               nxagentCorruptedPixmaps > 0));

    if (nxagentSkipImage == 0 && synchronize == 1)
    {
      #ifdef TEST
      fprintf(stderr, "nxagentBlockHandler: Setting a zero timeout with [%d][%d][%d] and "
                  "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
                      nxagentCorruptedPixmaps, nxagentCongestion);
      #endif

      zero.tv_sec  = 0;
      zero.tv_usec = 0;

      *timeout = &zero;
    }
    #ifdef TEST
    else
    {
      if (nxagentCorruptedWindows == 0 &&
              nxagentCorruptedBackgrounds == 0 &&
                  nxagentCorruptedPixmaps == 0)
      {
        fprintf(stderr, "nxagentBlockHandler: Nothing more to synchronize at %s.\n",
                    GetTimeInMillisAsString());
      }
      else
      {
        fprintf(stderr, "nxagentBlockHandler: Delaying synchronization with [%d][%d][%d] and "
                  "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
                      nxagentCorruptedPixmaps, nxagentCongestion);
      }
    }
    #endif
  }

  /*
   * If the remote X server is blocking, reduce the
   * amount of data sent in a single display update
   * by reducing the size of the display buffer.
   */

  #ifdef DYNAMIC_DISPLAY_BUFFER

  if (nxagentBlocking == 1 &&
          nxagentBuffer > MINIMUM_DISPLAY_BUFFER)
  {
    nxagentBuffer >>= 1;

    if (nxagentBuffer < MINIMUM_DISPLAY_BUFFER)
    {
      nxagentBuffer = MINIMUM_DISPLAY_BUFFER;
    }

    #ifdef TEST
    fprintf(stderr, "nxagentDispatchHandler: Reducing the display buffer to [%d] bytes.\n",
                nxagentBuffer);
    #endif

    NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer);
  }
示例#2
0
int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
{
  KeySym sym;
  int index = 0;

  *result = doNothing;

  /*
   * I don't know how much hard work is doing this operation.
   * Do we need a cache ?
   */

  sym = XKeycodeToKeysym(nxagentDisplay, X -> keycode, index);

  if (sym == XK_VoidSymbol || sym == NoSymbol)
  {
    return 0;
  }

  #ifdef TEST
  fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - sym %lx\n",
              X -> keycode, X -> state, sym);
  #endif

  /*
   * Check special keys.
   */

  /*
   * FIXME: We should use the keysym instead that the keycode
   *        here.
   */

  if (X -> keycode == 130 && nxagentIpaq)
  {
    *result = doStartKbd;

    return 1;
  }

  if ((X -> state & nxagentAltMetaMask) &&
          ((X -> state & (ControlMask | ShiftMask)) == ControlMask))
  {
    switch (sym)
    {
      #ifdef DEBUG_TREE

      case XK_q:
      case XK_Q:
      {
        *result = doDebugTree;

        break;
      }

      #endif /* DEBUG_TREE */

      case XK_t:
      case XK_T:
      {
        *result = doCloseSession;

        break;
      }
      case XK_f:
      case XK_F:
      {
        if (nxagentOption(Rootless) == False)
        {
          *result = doSwitchAllScreens;
        }

        break;
      }
      case XK_m:
      case XK_M:
      {
        if (nxagentOption(Rootless) == False)
        {
          *result = doMinimize;
        }

        break;
      }
      case XK_Left:
      case XK_KP_Left:
      {
        if (nxagentOption(Rootless) == False &&
                nxagentOption(DesktopResize) == False)
        {
          *result = doViewportLeft;
        }

        break;
      }
      case XK_Up:
      case XK_KP_Up:
      {
        if (nxagentOption(Rootless) == False &&
                nxagentOption(DesktopResize) == False)
        {
          *result = doViewportUp;
        }

        break;
      }
      case XK_Right:
      case XK_KP_Right:
      {
        if (nxagentOption(Rootless) == False &&
                nxagentOption(DesktopResize) == False)
        {
          *result = doViewportRight;
        }

        break;
      }
      case XK_Down:
      case XK_KP_Down:
      {
        if (nxagentOption(Rootless) == 0 &&
                nxagentOption(DesktopResize) == 0)
        {
          *result = doViewportDown;
        }

        break;
      }
      case XK_R:
      case XK_r:
      {
        if (nxagentOption(Rootless) == 0)
        {
          *result = doSwitchResizeMode;
        }

        break;
      }
      case XK_E:
      case XK_e:
      {
        *result = doSwitchDeferMode;

        break;
      }
      case XK_BackSpace:
      case XK_Terminate_Server:
      {
        /*
         * Discard Ctrl-Alt-BackSpace key.
         */

        return 1;

        break;
      }

      case XK_J:
      case XK_j:
      {
        nxagentForceSynchronization = 1;

        return 1;
      }

      #ifdef DUMP

      case XK_A:
      case XK_a:
      {
        /*
         * Used to test the lazy encoding.
         */

        nxagentRegionsOnScreen();

        return 1;
      }

      #endif

      #ifdef NX_DEBUG_INPUT

      case XK_X:
      case XK_x:
      {
        /*
         * Used to test the input devices state.
         */

        if (X -> type == KeyPress)
        {
          if (nxagentDebugInputDevices == 0)
          {
            fprintf(stderr, "Info: Turning input devices debug ON.\n");
    
            nxagentDebugInputDevices = 1;
          }
          else
          {
            fprintf(stderr, "Info: Turning input devices debug OFF.\n");
    
            nxagentDebugInputDevices = 0;
    
            nxagentLastInputDevicesDumpTime = 0;
          }
        }

        return 1;
      }

      case XK_Y:
      case XK_y:
      {
        /*
         * Used to deactivate input devices grab.
         */

        if (X -> type == KeyPress)
        {
          nxagentDeactivateInputDevicesGrabs();
        }

        return 1;
      }

      #endif
    }
  }
  else if ((X -> state & nxagentAltMetaMask) &&
               ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
                   ShiftMask)))
  {
    switch (sym)
    {
      case XK_f:
      case XK_F:
      {
        if (nxagentOption(Rootless) == 0)
        {
          *result = doSwitchFullscreen;
        }

        break;
      }
      case XK_Left:
      case XK_KP_Left:
      {
        if (nxagentOption(Rootless) == 0 &&
                nxagentOption(DesktopResize) == 0)
        {
          *result = doViewportMoveLeft;
        }

        break;
      }
      case XK_Up:
      case XK_KP_Up:
      {
        if (nxagentOption(Rootless) == 0 &&
                nxagentOption(DesktopResize) == 0)
        {
          *result = doViewportMoveUp;
        }

        break;
      }
      case XK_Right:
      case XK_KP_Right:
      {
        if (nxagentOption(Rootless) == 0 &&
                nxagentOption(DesktopResize) == 0)
        {
          *result = doViewportMoveRight;
        }

        break;
      }
      case XK_Down:
      case XK_KP_Down:
      {
        if (nxagentOption(Rootless) == 0 &&
                nxagentOption(DesktopResize) == 0)
        {
          *result = doViewportMoveDown;
        }

        break;
      }
    }
  }

  return (*result == doNothing) ? 0 : 1;
}