Beispiel #1
0
    MotionEvent generateAbsMotion(
        InputDevice device,
        long curTime,
        long curTimeNano,
        Display display,
        int orientation,
        int metaState) {
      boolean isMouse = ((device.classes & RawInputEvent.CLASS_MOUSE) == RawInputEvent.CLASS_MOUSE);
      if (mSkipLastPointers) {
        mSkipLastPointers = false;
        mLastNumPointers = 0;
      }

      if (!isMouse && (mNextNumPointers <= 0 && mLastNumPointers <= 0)) {
        return null;
      }

      final int lastNumPointers = mLastNumPointers;
      final int nextNumPointers = mNextNumPointers;
      if (mNextNumPointers > MAX_POINTERS) {
        Slog.w(
            "InputDevice",
            "Number of pointers " + mNextNumPointers + " exceeded maximum of " + MAX_POINTERS);
        mNextNumPointers = MAX_POINTERS;
      }

      /*
       * This is not used for mouse
       */
      int upOrDownPointer = isMouse ? 0 : updatePointerIdentifiers();

      final float[] reportData = mReportData;
      final int[] rawData;
      if (!isMouse && KeyInputQueue.BAD_TOUCH_HACK) {
        rawData = generateAveragedData(upOrDownPointer, lastNumPointers, nextNumPointers);
      } else {
        rawData = isMouse ? mNextData : mLastData;
      }

      final int numPointers = isMouse ? 1 : mLastNumPointers;

      if (DEBUG_POINTERS)
        Slog.v(
            "InputDevice",
            "Processing "
                + numPointers
                + " pointers (going from "
                + lastNumPointers
                + " to "
                + nextNumPointers
                + ")");

      for (int i = 0; i < numPointers; i++) {
        final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
        reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
        reportData[pos + MotionEvent.SAMPLE_Y] = rawData[pos + MotionEvent.SAMPLE_Y];
        reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
        reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
      }

      int action;
      int edgeFlags = 0;
      if (!isMouse) {
        if (nextNumPointers != lastNumPointers) {
          if (nextNumPointers > lastNumPointers) {
            if (lastNumPointers == 0) {
              action = MotionEvent.ACTION_DOWN;
              mDownTime = curTime;
            } else {
              action =
                  MotionEvent.ACTION_POINTER_DOWN
                      | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
            }
          } else {
            if (numPointers == 1) {
              action = MotionEvent.ACTION_UP;
            } else {
              action =
                  MotionEvent.ACTION_POINTER_UP
                      | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
            }
          }
          currentMove = null;
        } else {
          action = MotionEvent.ACTION_MOVE;
        }
      } else {
        if (mNextNumPointers != mLastNumPointers) {
          if (mNextNumPointers == 1) {
            action = MotionEvent.ACTION_DOWN;
            mDownTime = curTime;
          } else if (mNextNumPointers == 2) {
            action = MotionEvent.ACTION_UP;
          } else {
            action = MotionEvent.ACTION_MOVE;
          }
          mLastNumPointers = mNextNumPointers;
          currentMove = null;
        } else {
          action = MotionEvent.ACTION_MOVE;
        }
      }
      final int dispW = display.getWidth() - 1;
      final int dispH = display.getHeight() - 1;
      int w = dispW;
      int h = dispH;
      if (orientation == Surface.ROTATION_90 || orientation == Surface.ROTATION_270) {
        int tmp = w;
        w = h;
        h = tmp;
      }

      final AbsoluteInfo absX = device.absX;
      final AbsoluteInfo absY = device.absY;
      final AbsoluteInfo absPressure = device.absPressure;
      final AbsoluteInfo absSize = device.absSize;
      for (int i = 0; i < numPointers; i++) {
        final int j = i * MotionEvent.NUM_SAMPLE_DATA;

        if (absX != null) {
          reportData[j + MotionEvent.SAMPLE_X] =
              ((reportData[j + MotionEvent.SAMPLE_X] - absX.minValue) / absX.range) * w;
        }
        if (absY != null) {
          reportData[j + MotionEvent.SAMPLE_Y] =
              ((reportData[j + MotionEvent.SAMPLE_Y] - absY.minValue) / absY.range) * h;
        }
        if (absPressure != null) {
          reportData[j + MotionEvent.SAMPLE_PRESSURE] =
              ((reportData[j + MotionEvent.SAMPLE_PRESSURE] - absPressure.minValue)
                  / (float) absPressure.range);
        }
        if (absSize != null) {
          reportData[j + MotionEvent.SAMPLE_SIZE] =
              ((reportData[j + MotionEvent.SAMPLE_SIZE] - absSize.minValue)
                  / (float) absSize.range);
        }

        switch (orientation) {
          case Surface.ROTATION_90:
            {
              final float temp = reportData[j + MotionEvent.SAMPLE_X];
              reportData[j + MotionEvent.SAMPLE_X] = reportData[j + MotionEvent.SAMPLE_Y];
              reportData[j + MotionEvent.SAMPLE_Y] = w - temp;
              break;
            }
          case Surface.ROTATION_180:
            {
              reportData[j + MotionEvent.SAMPLE_X] = w - reportData[j + MotionEvent.SAMPLE_X];
              reportData[j + MotionEvent.SAMPLE_Y] = h - reportData[j + MotionEvent.SAMPLE_Y];
              break;
            }
          case Surface.ROTATION_270:
            {
              final float temp = reportData[j + MotionEvent.SAMPLE_X];
              reportData[j + MotionEvent.SAMPLE_X] = h - reportData[j + MotionEvent.SAMPLE_Y];
              reportData[j + MotionEvent.SAMPLE_Y] = temp;
              break;
            }
        }
      }

      // We only consider the first pointer when computing the edge
      // flags, since they are global to the event.
      if (action == MotionEvent.ACTION_DOWN) {
        if (reportData[MotionEvent.SAMPLE_X] <= 0) {
          edgeFlags |= MotionEvent.EDGE_LEFT;
        } else if (reportData[MotionEvent.SAMPLE_X] >= dispW) {
          edgeFlags |= MotionEvent.EDGE_RIGHT;
        }
        if (reportData[MotionEvent.SAMPLE_Y] <= 0) {
          edgeFlags |= MotionEvent.EDGE_TOP;
        } else if (reportData[MotionEvent.SAMPLE_Y] >= dispH) {
          edgeFlags |= MotionEvent.EDGE_BOTTOM;
        }
      }

      if (currentMove != null) {
        if (false)
          Slog.i(
              "InputDevice",
              "Adding batch x="
                  + reportData[MotionEvent.SAMPLE_X]
                  + " y="
                  + reportData[MotionEvent.SAMPLE_Y]
                  + " to "
                  + currentMove);
        currentMove.addBatch(curTime, reportData, metaState);
        if (WindowManagerPolicy.WATCH_POINTER) {
          Slog.i("KeyInputQueue", "Updating: " + currentMove);
        }
        return null;
      }

      MotionEvent me =
          MotionEvent.obtainNano(
              mDownTime,
              curTime,
              curTimeNano,
              action,
              numPointers,
              mPointerIds,
              reportData,
              metaState,
              xPrecision,
              yPrecision,
              device.id,
              edgeFlags);
      if (action == MotionEvent.ACTION_MOVE) {
        currentMove = me;
      }

      if (nextNumPointers < lastNumPointers) {
        removeOldPointer(upOrDownPointer);
      }

      return me;
    }
Beispiel #2
0
    MotionEvent generateRelMotion(
        InputDevice device, long curTime, long curTimeNano, int orientation, int metaState) {

      final float[] scaled = mReportData;

      // For now we only support 1 pointer with relative motions.
      scaled[MotionEvent.SAMPLE_X] = mNextData[MotionEvent.SAMPLE_X];
      scaled[MotionEvent.SAMPLE_Y] = mNextData[MotionEvent.SAMPLE_Y];
      scaled[MotionEvent.SAMPLE_PRESSURE] = 1.0f;
      scaled[MotionEvent.SAMPLE_SIZE] = 0;
      int edgeFlags = 0;

      int action;
      if (mNextNumPointers != mLastNumPointers) {
        mNextData[MotionEvent.SAMPLE_X] = mNextData[MotionEvent.SAMPLE_Y] = 0;
        if (mNextNumPointers > 0 && mLastNumPointers == 0) {
          action = MotionEvent.ACTION_DOWN;
          mDownTime = curTime;
        } else if (mNextNumPointers == 0) {
          action = MotionEvent.ACTION_UP;
        } else {
          action = MotionEvent.ACTION_MOVE;
        }
        mLastNumPointers = mNextNumPointers;
        currentMove = null;
      } else {
        action = MotionEvent.ACTION_MOVE;
      }

      scaled[MotionEvent.SAMPLE_X] *= xMoveScale;
      scaled[MotionEvent.SAMPLE_Y] *= yMoveScale;
      switch (orientation) {
        case Surface.ROTATION_90:
          {
            final float temp = scaled[MotionEvent.SAMPLE_X];
            scaled[MotionEvent.SAMPLE_X] = scaled[MotionEvent.SAMPLE_Y];
            scaled[MotionEvent.SAMPLE_Y] = -temp;
            break;
          }
        case Surface.ROTATION_180:
          {
            scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_X];
            scaled[MotionEvent.SAMPLE_Y] = -scaled[MotionEvent.SAMPLE_Y];
            break;
          }
        case Surface.ROTATION_270:
          {
            final float temp = scaled[MotionEvent.SAMPLE_X];
            scaled[MotionEvent.SAMPLE_X] = -scaled[MotionEvent.SAMPLE_Y];
            scaled[MotionEvent.SAMPLE_Y] = temp;
            break;
          }
      }

      if (currentMove != null) {
        if (false)
          Slog.i(
              "InputDevice",
              "Adding batch x="
                  + scaled[MotionEvent.SAMPLE_X]
                  + " y="
                  + scaled[MotionEvent.SAMPLE_Y]
                  + " to "
                  + currentMove);
        currentMove.addBatch(curTime, scaled, metaState);
        if (WindowManagerPolicy.WATCH_POINTER) {
          Slog.i("KeyInputQueue", "Updating: " + currentMove);
        }
        return null;
      }

      MotionEvent me =
          MotionEvent.obtainNano(
              mDownTime,
              curTime,
              curTimeNano,
              action,
              1,
              mPointerIds,
              scaled,
              metaState,
              xPrecision,
              yPrecision,
              device.id,
              edgeFlags);
      if (action == MotionEvent.ACTION_MOVE) {
        currentMove = me;
      }
      return me;
    }