Use grab object for motion grabs too

Now all grabs use grab objects, so drop the grab enum.
diff --git a/compositor/compositor.c b/compositor/compositor.c
index e989838..a3127b0 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -509,7 +509,7 @@
 
 static void
 wlsc_input_device_start_grab(struct wlsc_input_device *device,
-			     enum wlsc_grab_type grab,
+			     struct wl_grab *grab,
 			     uint32_t button, uint32_t time)
 {
 	struct wlsc_surface *focus =
@@ -520,12 +520,12 @@
 	device->grab_time = time;
 	device->grab_x = device->x;
 	device->grab_y = device->y;
-	device->grab_dx = focus->x - device->grab_x;
-	device->grab_dy = focus->y - device->grab_y;
 
 	device->grab_listener.func = lose_grab_surface;
 	wl_list_insert(focus->surface.destroy_listener_list.prev,
 		       &device->grab_listener.link);
+
+	grab->input_device = &device->input_device;
 }
 
 static int
@@ -533,12 +533,13 @@
 			      struct wl_grab *grab,
 			      struct wl_surface *surface, uint32_t time)
 {
-	if (device->grab != WLSC_DEVICE_GRAB_MOTION ||
+	if (device->grab != &device->motion_grab ||
 	    device->grab_time != time ||
 	    device->input_device.pointer_focus != surface)
 		return -1;
 
-	device->grab_object = grab;
+	device->grab = grab;
+	grab->input_device = &device->input_device;
 
 	return 0;
 }
@@ -597,7 +598,6 @@
 	}
 
 	move->grab.interface = &move_grab_interface;
-	move->grab.input_device = device;
 	move->dx = es->x - wd->grab_x;
 	move->dy = es->y - wd->grab_y;
 
@@ -605,7 +605,6 @@
 		return;
 
 	wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
-	wd->grab_object = &move->grab;
 }
 
 struct wlsc_resize_grab {
@@ -681,7 +680,6 @@
 	}
 
 	resize->grab.interface = &resize_grab_interface;
-	resize->grab.input_device = device;
 	resize->edges = edges;
 	resize->dx = es->x - wd->grab_x;
 	resize->dy = es->y - wd->grab_y;
@@ -735,8 +733,12 @@
 {
 	struct wl_drag *drag =
 		container_of(resource, struct wl_drag, resource);
+	struct wlsc_input_device *device;
 
 	wl_list_remove(&drag->drag_focus_listener.link);
+	device = (struct wlsc_input_device *) drag->grab.input_device;
+	if (device)
+		wlsc_input_device_end_grab(device, get_time());
 
 	free(drag);
 }
@@ -842,6 +844,34 @@
 	return NULL;
 }
 
+
+static void
+motion_grab_motion(struct wl_grab *grab,
+		   uint32_t time, int32_t x, int32_t y)
+{
+	struct wlsc_input_device *device =
+		(struct wlsc_input_device *) grab->input_device;
+	struct wlsc_surface *es =
+		(struct wlsc_surface *) device->input_device.pointer_focus;
+	int32_t sx, sy;
+
+	wlsc_surface_transform(es, x, y, &sx, &sy);
+	wl_client_post_event(es->surface.client,
+			     &device->input_device.object,
+			     WL_INPUT_DEVICE_MOTION,
+			     time, x, y, sx, sy);
+}
+
+static void
+motion_grab_end(struct wl_grab *grab, uint32_t time)
+{
+}
+
+static const struct wl_grab_interface motion_grab_interface = {
+	motion_grab_motion,
+	motion_grab_end
+};
+
 void
 notify_motion(struct wlsc_input_device *device, uint32_t time, int x, int y)
 {
@@ -865,13 +895,10 @@
 	device->x = x;
 	device->y = y;
 
-	if (device->grab_object) {
-		interface = device->grab_object->interface;
-		interface->motion(device->grab_object, time, x, y);
-	}
-
-	switch (device->grab) {
-	case WLSC_DEVICE_GRAB_NONE:
+	if (device->grab) {
+		interface = device->grab->interface;
+		interface->motion(device->grab, time, x, y);
+	} else {
 		es = pick_surface(device, &sx, &sy);
 		wl_input_device_set_pointer_focus(&device->input_device,
 						  &es->surface,
@@ -881,20 +908,6 @@
 					     &device->input_device.object,
 					     WL_INPUT_DEVICE_MOTION,
 					     time, x, y, sx, sy);
-		break;
-
-	case WLSC_DEVICE_GRAB_MOTION:
-		es = (struct wlsc_surface *) device->input_device.pointer_focus;
-		wlsc_surface_transform(es, x, y, &sx, &sy);
-		wl_client_post_event(es->surface.client,
-				     &device->input_device.object,
-				     WL_INPUT_DEVICE_MOTION,
-				     time, x, y, sx, sy);
-		break;
-
-	default:
-		/* Other grabs are handled as grab objects. */
-		break;
 	}
 
 	device->sprite->x = device->x - device->hotspot_x;
@@ -911,14 +924,12 @@
 	const struct wl_grab_interface *interface;
 	int32_t sx, sy;
 
-	if (device->grab_object) {
-		interface = device->grab_object->interface;
-		interface->end(device->grab_object, time);
-		device->grab_object = NULL;
-	}
+	interface = device->grab->interface;
+	interface->end(device->grab, time);
+	device->grab->input_device = NULL;
+	device->grab = NULL;
 
 	wl_list_remove(&device->grab_listener.link);
-	device->grab = WLSC_DEVICE_GRAB_NONE;
 	es = pick_surface(device, &sx, &sy);
 	wl_input_device_set_pointer_focus(&device->input_device,
 					  &es->surface, time,
@@ -936,11 +947,11 @@
 	if (!surface)
 		return;
 
-	if (state && device->grab == WLSC_DEVICE_GRAB_NONE) {
+	if (state && device->grab == NULL) {
 		wlsc_surface_raise(surface);
 
 		wlsc_input_device_start_grab(device,
-					     WLSC_DEVICE_GRAB_MOTION,
+					     &device->motion_grab,
 					     button, time);
 		wl_input_device_set_keyboard_focus(&device->input_device,
 						   &surface->surface,
@@ -948,36 +959,26 @@
 	}
 
 	if (state && button == BTN_LEFT &&
-	    device->grab == WLSC_DEVICE_GRAB_MOTION &&
 	    (device->modifier_state & MODIFIER_SUPER))
 		shell_move(NULL,
 			   (struct wl_shell *) &compositor->shell,
 			   &surface->surface,
 			   &device->input_device, time);
 	else if (state && button == BTN_MIDDLE &&
-		 device->grab == WLSC_DEVICE_GRAB_MOTION &&
 		 (device->modifier_state & MODIFIER_SUPER))
 		shell_resize(NULL,
 			     (struct wl_shell *) &compositor->shell,
 			     &surface->surface,
 			     &device->input_device, time,
 			     WLSC_DEVICE_GRAB_RESIZE_BOTTOM_RIGHT);
-	else if (device->grab == WLSC_DEVICE_GRAB_NONE ||
-		 device->grab == WLSC_DEVICE_GRAB_MOTION)
+	else if (device->grab == NULL || device->grab == &device->motion_grab)
 		wl_client_post_event(surface->surface.client,
 				     &device->input_device.object,
 				     WL_INPUT_DEVICE_BUTTON,
 				     time, button, state);
 
-	if (!state &&
-	    device->grab_object &&
-	    device->grab_button == button) {
+	if (!state && device->grab && device->grab_button == button)
 		wlsc_input_device_end_grab(device, time);
-	} else if (!state &&
-		   device->grab != WLSC_DEVICE_GRAB_NONE &&
-		   device->grab_button == button) {
-		wlsc_input_device_end_grab(device, time);
-	}
 }
 
 void
@@ -1234,7 +1235,6 @@
 		return;
 
 	drag->grab.interface = &drag_grab_interface;
-	drag->grab.input_device = input_device;
 
 	drag->source = surface;
 
@@ -1252,15 +1252,6 @@
 static void
 drag_destroy(struct wl_client *client, struct wl_drag *drag)
 {
-	struct wlsc_input_device *device =
-		(struct wlsc_input_device *) drag->grab.input_device;
-	uint32_t time;
-
-	if (drag->source == NULL || drag->source->client != client)
-		return;
-
-	time = get_time();
-	wlsc_input_device_end_grab(device, time);
 	wl_resource_destroy(&drag->resource, client);
 }
 
@@ -1290,6 +1281,8 @@
 	device->hotspot_x = 16;
 	device->hotspot_y = 16;
 
+	device->motion_grab.interface = &motion_grab_interface;
+
 	wl_list_insert(ec->input_device_list.prev, &device->link);
 
 	wlsc_input_device_set_pointer_image(device, WLSC_POINTER_LEFT_PTR);