예제 #1
0
static void
handle_pointer_axis(struct libinput_device *libinput_device,
		    struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	double value;
	enum libinput_pointer_axis axis;

	axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
	if (libinput_event_pointer_has_axis(pointer_event, axis)) {
		value = normalize_scroll(pointer_event, axis);
		notify_axis(device->seat,
			    libinput_event_pointer_get_time(pointer_event),
			    WL_POINTER_AXIS_VERTICAL_SCROLL,
			    wl_fixed_from_double(value));
	}

	axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
	if (libinput_event_pointer_has_axis(pointer_event, axis)) {
		value = normalize_scroll(pointer_event, axis);
		notify_axis(device->seat,
			    libinput_event_pointer_get_time(pointer_event),
			    WL_POINTER_AXIS_HORIZONTAL_SCROLL,
			    wl_fixed_from_double(value));
	}
}
예제 #2
0
static void
handle_pointer_motion_absolute(
	struct libinput_device *libinput_device,
	struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	struct weston_output *output = device->output;
	uint32_t time;
	wl_fixed_t x, y;
	uint32_t width, height;

	if (!output)
		return;

	time = libinput_event_pointer_get_time(pointer_event);
	width = device->output->current_mode->width;
	height = device->output->current_mode->height;

	x = wl_fixed_from_double(
		libinput_event_pointer_get_absolute_x_transformed(pointer_event,
								  width));
	y = wl_fixed_from_double(
		libinput_event_pointer_get_absolute_y_transformed(pointer_event,
								  height));

	weston_output_transform_coordinate(device->output, x, y, &x, &y);
	notify_motion_absolute(device->seat, time, x, y);
}
예제 #3
0
static void
handle_touch_with_coords(struct libinput_device *libinput_device,
			 struct libinput_event_touch *touch_event,
			 int touch_type)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	wl_fixed_t x;
	wl_fixed_t y;
	uint32_t width, height;
	uint32_t time;
	int32_t slot;

	if (!device->output)
		return;

	time = libinput_event_touch_get_time(touch_event);
	slot = libinput_event_touch_get_seat_slot(touch_event);

	width = device->output->current_mode->width;
	height = device->output->current_mode->height;
	x = wl_fixed_from_double(
		libinput_event_touch_get_x_transformed(touch_event, width));
	y = wl_fixed_from_double(
		libinput_event_touch_get_y_transformed(touch_event, height));

	weston_output_transform_coordinate(device->output,
					   x, y, &x, &y);

	notify_touch(device->seat, time, slot, x, y, touch_type);
}
예제 #4
0
static void
send_state(int fd, struct display* display)
{
	char buf[64];
	int len;
	int visible = display->surface->output != NULL;
	wl_fixed_t x = wl_fixed_from_int(-1);
	wl_fixed_t y = wl_fixed_from_int(-1);

	if (display->input->pointer_focus != NULL) {
		assert(display->input->pointer_focus == display->surface);
		x = wl_fixed_from_double(display->input->x);
		y = wl_fixed_from_double(display->input->y);
	}

	if (visible) {
		/* FIXME: this fails on multi-display setup */
		/* assert(display->surface->output == display->output); */
	}

	wl_display_flush(display->display);

	len = snprintf(buf, sizeof buf, "%d %d %d\n", x, y, visible);
	assert(write(fd, buf, len) == len);

	wl_display_roundtrip(display->display);
}
예제 #5
0
void Touch::sendMotion(int touch_id, const QPointF &position)
{
    if (!m_focusResource)
        return;

    send_motion(m_focusResource->handle, Compositor::currentTimeMsecs(), touch_id,
                wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
}
예제 #6
0
void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF &position)
{
    if (!focusResource)
        return;

    wl_touch_send_motion(focusResource->handle, time, touch_id,
                         wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
}
예제 #7
0
void Touch::sendDown(int touch_id, const QPointF &position)
{
    if (!m_focusResource || !m_focus)
        return;

    uint32_t serial = wl_display_next_serial(m_compositor->wl_display());

    send_down(m_focusResource->handle, serial, Compositor::currentTimeMsecs(), m_focus->resource()->handle, touch_id,
              wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
}
예제 #8
0
void QWaylandTouchPrivate::sendDown(uint32_t time, int touch_id, const QPointF &position)
{
    Q_Q(QWaylandTouch);
    if (!focusResource || !seat->mouseFocus())
        return;

    uint32_t serial = q->compositor()->nextSerial();

    wl_touch_send_down(focusResource->handle, serial, time, seat->mouseFocus()->surfaceResource(), touch_id,
                       wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
}
예제 #9
0
static void
set_my_viewport(struct box *box)
{
	wl_fixed_t src_x, src_y, src_width, src_height;
	int32_t dst_width = SURFACE_WIDTH;
	int32_t dst_height = SURFACE_HEIGHT;

	if (box->mode == MODE_NO_VIEWPORT)
		return;

	/* Cut the green border in half, take white border fully in,
	 * and black border fully out. The borders are 1px wide in buffer.
	 *
	 * The gl-renderer uses linear texture sampling, this means the
	 * top and left edges go to 100% green, bottom goes to 50% blue/black,
	 * right edge has thick white sliding to 50% red.
	 */
	src_x = wl_fixed_from_double((RECT_X + 0.5) / BUFFER_SCALE);
	src_y = wl_fixed_from_double((RECT_Y + 0.5) / BUFFER_SCALE);
	src_width = wl_fixed_from_double((RECT_W - 0.5) / BUFFER_SCALE);
	src_height = wl_fixed_from_double((RECT_H - 0.5) / BUFFER_SCALE);

	if (box->scaler_version < 2 && box->mode != MODE_SRC_DST) {
		fprintf(stderr, "Error: server's wl_scaler interface version "
			"%d does not support this mode.\n",
			box->scaler_version);
		exit(1);
	}

	switch (box->mode){
	case MODE_SRC_ONLY:
		wl_viewport_set_source(box->viewport, src_x, src_y,
				       src_width, src_height);
		break;
	case MODE_DST_ONLY:
		wl_viewport_set_destination(box->viewport,
					    dst_width, dst_height);
		break;
	case MODE_SRC_DST:
		if (box->scaler_version < 2) {
			wl_viewport_set(box->viewport,
					src_x, src_y, src_width, src_height,
					dst_width, dst_height);
		} else {
			wl_viewport_set_source(box->viewport, src_x, src_y,
					       src_width, src_height);
			wl_viewport_set_destination(box->viewport,
						    dst_width, dst_height);
		}
		break;
	default:
		assert(!"not reached");
	}
}
예제 #10
0
static void
handle_pointer_motion(struct libinput_device *libinput_device,
		      struct libinput_event_pointer *pointer_event)
{
	struct evdev_device *device =
		libinput_device_get_user_data(libinput_device);
	wl_fixed_t dx, dy;

	dx = wl_fixed_from_double(libinput_event_pointer_get_dx(pointer_event));
	dy = wl_fixed_from_double(libinput_event_pointer_get_dy(pointer_event));
	notify_motion(device->seat,
		      libinput_event_pointer_get_time(pointer_event),
		      dx,
		      dy);
}
예제 #11
0
/*!
 * Sets the current mouse focus to \a view and sends a mouse move event to it with the
 * local position \a localPos and output space position \a outputSpacePos.
 */
void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos)
{
    Q_D(QWaylandPointer);
    if (view && (!view->surface() || view->surface()->isCursorSurface()))
        view = Q_NULLPTR;
    d->seat->setMouseFocus(view);
    d->localPosition = localPos;
    d->spacePosition = outputSpacePos;

    //we adjust if the mouse position is on the edge
    //to work around Qt's event propagation
    if (view && view->surface()) {
        QSizeF size(view->surface()->size());
        if (d->localPosition.x() ==  size.width())
            d->localPosition.rx() -= 0.01;

        if (d->localPosition.y() == size.height())
            d->localPosition.ry() -= 0.01;
    }

    QWaylandPointerPrivate::Resource *resource = view ? d->resourceMap().value(view->surface()->waylandClient()) : 0;
    if (resource && !d->hasSentEnter) {
        uint32_t serial = d->compositor()->nextSerial();
        QWaylandKeyboard *keyboard = d->seat->keyboard();
        if (keyboard) {
            keyboard->sendKeyModifiers(view->surface()->client(), serial);
        }
        d->send_enter(resource->handle, serial, view->surface()->resource(),
                   wl_fixed_from_double(d->localPosition.x()), wl_fixed_from_double(d->localPosition.y()));

        d->focusDestroyListener.listenForDestruction(view->surface()->resource());
        d->hasSentEnter = true;
    }

    d->focusResource = resource ? resource->handle : 0;

    if (view && view->output())
        setOutput(view->output());

    uint32_t time = d->compositor()->currentTimeMsecs();

    if (d->focusResource) {
        wl_fixed_t x = wl_fixed_from_double(currentLocalPosition().x());
        wl_fixed_t y = wl_fixed_from_double(currentLocalPosition().y());
        wl_pointer_send_motion(d->focusResource, time, x, y);
    }
}
예제 #12
0
static void
transform_stage_point_fixed (ClaylandSurface *surface,
                             wl_fixed_t x,
                             wl_fixed_t y,
                             wl_fixed_t *sx,
                             wl_fixed_t *sy)
{
  float xf, yf;

  clutter_actor_transform_stage_point (surface->actor,
                                       wl_fixed_to_double (x),
                                       wl_fixed_to_double (y),
                                       &xf, &yf);

  *sx = wl_fixed_from_double (xf);
  *sy = wl_fixed_from_double (yf);
}
예제 #13
0
static void
notify_motion (ClaylandSeat *seat,
               const ClutterEvent *event)
{
  ClaylandPointer *pointer = &seat->pointer;
  float x, y;

  clutter_event_get_coords (event, &x, &y);
  pointer->x = wl_fixed_from_double (x);
  pointer->y = wl_fixed_from_double (y);

  clayland_seat_repick (seat,
                        clutter_event_get_time (event),
                        clutter_event_get_source (event));

  pointer->grab->interface->motion (pointer->grab,
                                    clutter_event_get_time (event),
                                    pointer->grab->x,
                                    pointer->grab->y);
}
예제 #14
0
/* The actor argument can be NULL in which case a Clutter pick will be
   performed to determine the right actor. An actor should only be
   passed if the repick is being performed due to an event in which
   case Clutter will have already performed a pick so we can avoid
   redundantly doing another one */
void
clayland_seat_repick (ClaylandSeat *seat,
                      uint32_t time,
                      ClutterActor *actor)
{
  ClaylandPointer *pointer = &seat->pointer;
  ClaylandSurface *surface;
  ClaylandSurface *focus;

  if (actor == NULL && seat->current_stage)
    {
      ClutterStage *stage = CLUTTER_STAGE (seat->current_stage);
      actor = clutter_stage_get_actor_at_pos (stage,
                                              CLUTTER_PICK_REACTIVE,
                                              wl_fixed_to_double (pointer->x),
                                              wl_fixed_to_double (pointer->y));
    }

  if (actor)
    seat->current_stage = clutter_actor_get_stage (actor);
  else
    seat->current_stage = NULL;

  if (CLUTTER_WAYLAND_IS_SURFACE (actor))
    {
      ClutterWaylandSurface *wl_surface = CLUTTER_WAYLAND_SURFACE (actor);
      float ax, ay;

      clutter_actor_transform_stage_point (actor,
                                           wl_fixed_to_double (pointer->x),
                                           wl_fixed_to_double (pointer->y),
                                           &ax, &ay);
      pointer->current_x = wl_fixed_from_double (ax);
      pointer->current_y = wl_fixed_from_double (ay);

      surface = ((ClaylandSurface *)
                 clutter_wayland_surface_get_surface (wl_surface));
    }
  else
    surface = NULL;

  if (surface != pointer->current)
    {
      const ClaylandPointerGrabInterface *interface =
        pointer->grab->interface;
      interface->focus (pointer->grab,
                        surface,
                        pointer->current_x, pointer->current_y);
      pointer->current = surface;
    }

  focus = (ClaylandSurface *) pointer->grab->focus;
  if (focus)
    {
      float ax, ay;

      clutter_actor_transform_stage_point (focus->actor,
                                           wl_fixed_to_double (pointer->x),
                                           wl_fixed_to_double (pointer->y),
                                           &ax, &ay);
      pointer->grab->x = wl_fixed_from_double (ax);
      pointer->grab->y = wl_fixed_from_double (ay);
    }
}