Add touch support for wl_shell_surface_move
diff --git a/src/shell.c b/src/shell.c
index 8f2be78..564d5be 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -237,11 +237,23 @@
 	struct wl_listener shsurf_destroy_listener;
 };
 
+struct shell_touch_grab {
+	struct weston_touch_grab grab;
+	struct shell_surface *shsurf;
+	struct wl_listener shsurf_destroy_listener;
+	struct weston_touch *touch;
+};
+
 struct weston_move_grab {
 	struct shell_grab base;
 	wl_fixed_t dx, dy;
 };
 
+struct weston_touch_move_grab {
+	struct shell_touch_grab base;
+	wl_fixed_t dx, dy;
+};
+
 struct rotate_grab {
 	struct shell_grab base;
 	struct weston_matrix rotation;
@@ -350,6 +362,36 @@
 }
 
 static void
+shell_touch_grab_start(struct shell_touch_grab *grab,
+		       const struct weston_touch_grab_interface *interface,
+		       struct shell_surface *shsurf,
+		       struct weston_touch *touch)
+{
+	struct desktop_shell *shell = shsurf->shell;
+	
+	grab->grab.interface = interface;
+	grab->shsurf = shsurf;
+	grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf;
+	wl_signal_add(&shsurf->destroy_signal,
+		      &grab->shsurf_destroy_listener);
+
+	grab->touch = touch;
+
+	weston_touch_start_grab(touch, &grab->grab);
+	if (shell->child.desktop_shell)
+		weston_touch_set_focus(touch->seat, shell->grab_surface);
+}
+
+static void
+shell_touch_grab_end(struct shell_touch_grab *grab)
+{
+	if (grab->shsurf)
+		wl_list_remove(&grab->shsurf_destroy_listener.link);
+
+	weston_touch_end_grab(grab->touch);
+}
+
+static void
 center_on_output(struct weston_surface *surface,
 		 struct weston_output *output);
 
@@ -1035,6 +1077,74 @@
 }
 
 static void
+touch_move_grab_down(struct weston_touch_grab *grab, uint32_t time,
+		     int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+}
+
+static void
+touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id)
+{
+	struct shell_touch_grab *shell_grab = container_of(grab, 
+							   struct shell_touch_grab,
+							   grab);
+	shell_touch_grab_end(shell_grab);
+}
+
+static void
+touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time,
+		       int touch_id, wl_fixed_t sx, wl_fixed_t sy)
+{
+	struct weston_touch_move_grab *move = (struct weston_touch_move_grab *) grab;
+	struct shell_surface *shsurf = move->base.shsurf;
+	struct weston_surface *es;
+	int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx);
+	int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy);
+
+	if (!shsurf)
+		return;
+
+	es = shsurf->surface;
+
+	weston_surface_configure(es, dx, dy,
+				 es->geometry.width, es->geometry.height);
+
+	weston_compositor_schedule_repaint(es->compositor);
+}
+
+static const struct weston_touch_grab_interface touch_move_grab_interface = {
+	touch_move_grab_down,
+	touch_move_grab_up,
+	touch_move_grab_motion,
+};
+
+static int
+surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat)
+{
+	struct weston_touch_move_grab *move;
+
+	if (!shsurf)
+		return -1;
+
+	if (shsurf->type == SHELL_SURFACE_FULLSCREEN)
+		return 0;
+
+	move = malloc(sizeof *move);
+	if (!move)
+		return -1;
+
+	move->dx = wl_fixed_from_double(shsurf->surface->geometry.x) -
+			seat->touch->grab_x;
+	move->dy = wl_fixed_from_double(shsurf->surface->geometry.y) -
+			seat->touch->grab_y;
+
+	shell_touch_grab_start(&move->base, &touch_move_grab_interface, shsurf,
+			       seat->touch);
+
+	return 0;
+}
+
+static void
 noop_grab_focus(struct weston_pointer_grab *grab)
 {
 }
@@ -1117,13 +1227,17 @@
 	struct weston_surface *surface;
 
 	surface = weston_surface_get_main_surface(seat->pointer->focus);
-	if (seat->pointer->button_count == 0 ||
-	    seat->pointer->grab_serial != serial ||
-	    surface != shsurf->surface)
-		return;
-
-	if (surface_move(shsurf, seat) < 0)
-		wl_resource_post_no_memory(resource);
+	if (seat->pointer->button_count > 0 && seat->pointer->grab_serial == serial) {
+		surface = weston_surface_get_main_surface(seat->pointer->focus);
+		if ((surface == shsurf->surface) && 
+		    (surface_move(shsurf, seat) < 0))
+			wl_resource_post_no_memory(resource);
+	} else if (seat->touch->grab_serial == serial) {
+		surface = weston_surface_get_main_surface(seat->touch->focus);
+		if ((surface == shsurf->surface) && 
+		    (surface_touch_move(shsurf, seat) < 0))
+			wl_resource_post_no_memory(resource);
+	}
 }
 
 struct weston_resize_grab {