[PATCH weston 3/6] xwm: set appropriate cursors for the frame window

Tiago Vignatti tiago.vignatti at intel.com
Wed Jul 11 14:46:12 PDT 2012


based on xcb-cursor.

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
 src/xwayland/window-manager.c |  132 +++++++++++++++++++++++++++++++++++++++++
 src/xwayland/xwayland.h       |    2 +
 2 files changed, 134 insertions(+)

diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 6e032ea..0f2b24d 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -497,6 +497,8 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
 		XCB_EVENT_MASK_KEY_RELEASE |
 		XCB_EVENT_MASK_BUTTON_PRESS |
 		XCB_EVENT_MASK_BUTTON_RELEASE |
+		XCB_EVENT_MASK_POINTER_MOTION |
+		XCB_EVENT_MASK_LEAVE_WINDOW |
 		XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
 		XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
 
@@ -852,6 +854,95 @@ weston_wm_handle_client_message(struct weston_wm *wm,
 		weston_wm_window_handle_moveresize(window, client_message);
 }
 
+enum cursor_type {
+	XWM_CURSOR_TOP,
+	XWM_CURSOR_BOTTOM,
+	XWM_CURSOR_LEFT,
+	XWM_CURSOR_RIGHT,
+	XWM_CURSOR_TOP_LEFT,
+	XWM_CURSOR_TOP_RIGHT,
+	XWM_CURSOR_BOTTOM_LEFT,
+	XWM_CURSOR_BOTTOM_RIGHT,
+	XWM_CURSOR_LEFT_PTR,
+};
+
+static const char *cursors[] = {
+	"top_side",
+	"bottom_side",
+	"left_side",
+	"right_side",
+	"top_left_corner",
+	"top_right_corner",
+	"bottom_left_corner",
+	"bottom_right_corner",
+	"left_ptr"
+};
+
+static void
+weston_wm_create_cursors(struct weston_wm *wm)
+{
+	int i, count = ARRAY_LENGTH(cursors);
+
+	wm->cursors = malloc(count * sizeof(xcb_cursor_t));
+	for (i = 0; i < count; i++) {
+		wm->cursors[i] =
+			xcb_cursor_library_load_cursor(wm->conn, cursors[i]);
+	}
+
+	wm->last_cursor = -1;
+}
+
+static int
+get_cursor_for_location(struct theme *t, int width, int height,
+			     int x, int y)
+{
+	int location = theme_get_location(t, x, y, width, height);
+
+	switch (location) {
+		case THEME_LOCATION_RESIZING_TOP:
+			return XWM_CURSOR_TOP;
+		case THEME_LOCATION_RESIZING_BOTTOM:
+			return XWM_CURSOR_BOTTOM;
+		case THEME_LOCATION_RESIZING_LEFT:
+			return XWM_CURSOR_LEFT;
+		case THEME_LOCATION_RESIZING_RIGHT:
+			return XWM_CURSOR_RIGHT;
+		case THEME_LOCATION_RESIZING_TOP_LEFT:
+			return XWM_CURSOR_TOP_LEFT;
+		case THEME_LOCATION_RESIZING_TOP_RIGHT:
+			return XWM_CURSOR_TOP_RIGHT;
+		case THEME_LOCATION_RESIZING_BOTTOM_LEFT:
+			return XWM_CURSOR_BOTTOM_LEFT;
+		case THEME_LOCATION_RESIZING_BOTTOM_RIGHT:
+			return XWM_CURSOR_BOTTOM_RIGHT;
+		case THEME_LOCATION_EXTERIOR:
+		case THEME_LOCATION_TITLEBAR:
+		default:
+			return XWM_CURSOR_LEFT_PTR;
+	}
+}
+
+static void
+weston_wm_frame_set_cursor(struct weston_wm *wm,
+			   struct weston_wm_window *window, int cursor)
+{
+	uint32_t cursor_value_list;
+
+	if (!window->frame_id)
+		return;
+
+	if (wm->last_cursor == cursor)
+		return;
+
+	wm->last_cursor = cursor;
+
+	cursor_value_list = wm->cursors[cursor];
+	xcb_change_window_attributes (wm->conn, window->frame_id,
+				      XCB_CW_CURSOR, &cursor_value_list);
+	xcb_flush(wm->conn);
+	weston_log("%s: %s\n", __func__, cursors[cursor]);
+}
+
 static void
 weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
 {
@@ -900,6 +991,38 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
 	}
 }
 
+static void
+weston_wm_handle_motion(struct weston_wm *wm, xcb_generic_event_t *event)
+{
+	xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *) event;
+	struct weston_wm_window *window;
+	int cursor, width, height;
+
+	window = hash_table_lookup(wm->window_hash, motion->event);
+	if (!window->frame_id)
+		return;
+
+	weston_wm_window_get_frame_size(window, &width, &height);
+	cursor = get_cursor_for_location(wm->theme, width, height,
+					 motion->event_x, motion->event_y);
+
+	weston_wm_frame_set_cursor(wm, window, cursor);
+}
+
+static void
+weston_wm_handle_leave(struct weston_wm *wm, xcb_generic_event_t *event)
+{
+	xcb_leave_notify_event_t *leave_notify =
+				(xcb_leave_notify_event_t *) event;
+	struct weston_wm_window *window;
+
+	window = hash_table_lookup(wm->window_hash, leave_notify->event);
+	if (!window)
+		return;
+
+	weston_wm_frame_set_cursor(wm, window, XWM_CURSOR_LEFT_PTR);
+}
+
 static int
 weston_wm_handle_event(int fd, uint32_t mask, void *data)
 {
@@ -919,6 +1042,12 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data)
 		case XCB_BUTTON_RELEASE:
 			weston_wm_handle_button(wm, event);
 			break;
+		case XCB_LEAVE_NOTIFY:
+			weston_wm_handle_leave(wm, event);
+			break;
+		case XCB_MOTION_NOTIFY:
+			weston_wm_handle_motion(wm, event);
+			break;
 		case XCB_CREATE_NOTIFY:
 			weston_wm_handle_create_notify(wm, event);
 			break;
@@ -1204,6 +1333,8 @@ weston_wm_create(struct weston_xserver *wxs)
 	wl_signal_add(&wxs->compositor->activate_signal,
 		      &wm->activate_listener);
 
+	weston_wm_create_cursors(wm);
+
 	weston_log("created wm\n");
 
 	return wm;
@@ -1219,6 +1350,7 @@ weston_wm_destroy(struct weston_wm *wm)
 	wl_list_remove(&wm->selection_listener.link);
 	wl_list_remove(&wm->activate_listener.link);
 
+	free(wm->cursors);
 	free(wm);
 }
 
diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h
index 1a022d0..f9f4f93 100644
--- a/src/xwayland/xwayland.h
+++ b/src/xwayland/xwayland.h
@@ -58,6 +58,8 @@ struct weston_wm {
 	xcb_window_t wm_window;
 	struct weston_wm_window *focus_window;
 	struct theme *theme;
+	xcb_cursor_t *cursors;
+	int last_cursor;
 	xcb_render_pictforminfo_t render_format;
 	struct wl_listener activate_listener;
 
-- 
1.7.9.5



More information about the wayland-devel mailing list