Index: configure.in
===================================================================
RCS file: /cvs/gnome/metacity/configure.in,v
retrieving revision 1.187
diff -u -r1.187 configure.in
--- configure.in	11 Apr 2005 22:29:44 -0000	1.187
+++ configure.in	21 Jun 2005 19:41:46 -0000
@@ -258,6 +258,20 @@
   AC_DEFINE(HAVE_RENDER, , [Building with Render extension support])
 fi
 
+AC_MSG_CHECKING([Xcursor])
+if $PKG_CONFIG xcursor; then
+     have_xcursor=yes
+  else
+     have_xcursor=no
+  fi
+  AC_MSG_RESULT($have_xcursor)
+
+if test x$have_xcursor = xyes; then
+  echo "Building with Xcursor"
+  METACITY_PC_MODULES="$METACITY_PC_MODULES xcursor"
+  AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support]) 
+fi
+
 PKG_CHECK_MODULES(METACITY, $METACITY_PC_MODULES)
 
 AC_PATH_XTRA
@@ -498,6 +512,7 @@
 	Resize-and-rotate:        ${found_randr}
 	Xsync:                    ${found_xsync}
 	Render:                   ${have_xrender}
+	Xcursor:                  ${have_xcursor}
 "
 #echo "This is the UNSTABLE branch of metacity"
 #echo "Use 2.8.x (where x > 5) for stable (gnome-2-8 branch in CVS)"
Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.257
diff -u -r1.257 display.c
--- src/display.c	26 May 2005 19:58:17 -0000	1.257
+++ src/display.c	21 Jun 2005 19:41:47 -0000
@@ -59,6 +59,9 @@
 #ifdef HAVE_XKB
 #include <X11/XKBlib.h>
 #endif
+#ifdef HAVE_XCURSOR
+#include <X11/Xcursor/Xcursor.h>
+#endif
 #include <string.h>
 
 #define USE_GDK_DISPLAY
@@ -609,7 +612,16 @@
 #else  /* HAVE_RENDER */
   meta_verbose ("Not compiled with Render support\n");
 #endif /* !HAVE_RENDER */
-  
+
+#ifdef HAVE_XCURSOR
+  {
+    XcursorSetTheme (display->xdisplay, meta_prefs_get_cursor_theme ());
+    XcursorSetDefaultSize (display->xdisplay, meta_prefs_get_cursor_size ());
+  }
+#else /* HAVE_XCURSOR */
+  meta_verbose ("Not compiled with Xcursor support\n");
+#endif /* !HAVE_XCURSOR */
+
   /* Create the leader window here. Set its properties and
    * use the timestamp from one of the PropertyNotify events
    * that will follow.
@@ -3760,6 +3772,36 @@
       meta_display_queue_retheme_all_windows (display);
       tmp = tmp->next;
     }
+}
+
+void 
+meta_display_set_cursor_theme (const char *theme, 
+			       int         size)
+{
+#ifdef HAVE_XCURSOR     
+  GSList *tmp, *tmp2;
+  
+  tmp = meta_displays_list ();
+  while (tmp != NULL)
+    {
+      MetaDisplay *display = tmp->data;
+
+      XcursorSetTheme (display->xdisplay, theme);
+      XcursorSetDefaultSize (display->xdisplay, size);
+
+      tmp2 = display->screens;
+      while (tmp2 != NULL)
+	{
+	  MetaScreen *screen = tmp2->data;
+	  	  
+	  meta_screen_update_cursor (screen);
+
+	  tmp2 = tmp2->next;
+	}
+      
+      tmp = tmp->next;
+    }
+#endif
 }
 
 static gboolean is_syncing = FALSE;
Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.132
diff -u -r1.132 display.h
--- src/display.h	26 May 2005 19:58:17 -0000	1.132
+++ src/display.h	21 Jun 2005 19:41:47 -0000
@@ -471,6 +471,9 @@
 void meta_display_queue_retheme_all_windows (MetaDisplay *display);
 void meta_display_retheme_all (void);
 
+void meta_display_set_cursor_theme (const char *theme, 
+				    int         size);
+
 void     meta_display_ping_window              (MetaDisplay        *display,
 						MetaWindow         *window,
 						Time                timestamp,
Index: src/main.c
===================================================================
RCS file: /cvs/gnome/metacity/src/main.c,v
retrieving revision 1.55
diff -u -r1.55 main.c
--- src/main.c	16 Sep 2004 23:18:22 -0000	1.55
+++ src/main.c	21 Jun 2005 19:41:47 -0000
@@ -561,6 +561,11 @@
       meta_display_retheme_all ();
       break;
 
+    case META_PREF_CURSOR_THEME:
+    case META_PREF_CURSOR_SIZE:
+      meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
+				     meta_prefs_get_cursor_size ());
+      break;
     default:
       /* handled elsewhere or otherwise */
       break;
Index: src/prefs.c
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.c,v
retrieving revision 1.50
diff -u -r1.50 prefs.c
--- src/prefs.c	26 Jan 2005 08:43:38 -0000	1.50
+++ src/prefs.c	21 Jun 2005 19:41:47 -0000
@@ -66,6 +66,8 @@
 #define KEY_VISUAL_BELL "/apps/metacity/general/visual_bell"
 #define KEY_AUDIBLE_BELL "/apps/metacity/general/audible_bell"
 #define KEY_VISUAL_BELL_TYPE "/apps/metacity/general/visual_bell_type"
+#define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme"
+#define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size"
 
 #ifdef HAVE_GCONF
 static GConfClient *default_client = NULL;
@@ -90,6 +92,8 @@
 static gboolean bell_is_audible = TRUE;
 static gboolean reduced_resources = FALSE;
 static gboolean gnome_accessibility = FALSE;
+static char *cursor_theme = NULL;
+static int   cursor_size = 24;
 
 static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID;
 static MetaButtonLayout button_layout = {
@@ -142,6 +146,8 @@
                                            const char  *value);
 static gboolean update_reduced_resources  (gboolean     value);
 static gboolean update_gnome_accessibility  (gboolean     value);
+static gboolean update_cursor_theme       (const char *value);
+static gboolean update_cursor_size        (int size);
 
 static void change_notify (GConfClient    *client,
                            guint           cnxn_id,
@@ -323,6 +329,11 @@
                         &err);
   cleanup_error (&err);
 
+  gconf_client_add_dir (default_client, "/desktop/gnome/peripherals/mouse",
+                        GCONF_CLIENT_PRELOAD_RECURSIVE,
+                        &err);
+  cleanup_error (&err);
+
   str_val = gconf_client_get_string (default_client, KEY_MOUSE_BUTTON_MODS,
                                      &err);
   cleanup_error (&err);
@@ -426,6 +437,17 @@
   
   cleanup_error (&err);
   update_gnome_accessibility (bool_val);
+
+  str_val = gconf_client_get_string (default_client, KEY_CURSOR_THEME,
+                                     &err);
+  cleanup_error (&err);
+  update_cursor_theme (str_val);
+  g_free (str_val);
+
+  int_val = gconf_client_get_int (default_client, KEY_CURSOR_SIZE,
+                                  &err);
+  cleanup_error (&err);
+  update_cursor_size (int_val);
 #endif /* HAVE_GCONF */
   
   /* Load keybindings prefs */
@@ -453,6 +475,11 @@
                            NULL,
                            NULL,
                            &err);
+  gconf_client_notify_add (default_client, "/desktop/gnome/peripherals/mouse",
+                           change_notify,
+                           NULL,
+                           NULL,
+                           &err);
 
   cleanup_error (&err);  
 #endif /* HAVE_GCONF */
@@ -846,6 +873,38 @@
       if (update_gnome_accessibility (b))
         queue_changed (META_PREF_GNOME_ACCESSIBILITY);
     }
+  else if (strcmp (key, KEY_CURSOR_THEME) == 0)
+    {
+      const char *str;
+
+      if (value && value->type != GCONF_VALUE_STRING)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                       KEY_CURSOR_THEME);
+          goto out;
+        }
+
+      str = value ? gconf_value_get_string (value) : NULL;
+
+      if (update_cursor_theme (str))
+	queue_changed (META_PREF_CURSOR_THEME);
+    }
+  else if (strcmp (key, KEY_CURSOR_SIZE) == 0)
+    {
+      int d;
+
+      if (value && value->type != GCONF_VALUE_INT)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                       KEY_CURSOR_SIZE);
+          goto out;
+        }
+
+      d = value ? gconf_value_get_int (value) : 24;
+
+      if (update_cursor_size (d))
+	queue_changed (META_PREF_CURSOR_SIZE);
+    }
   else
     {
       meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@@ -963,6 +1022,57 @@
 meta_prefs_get_theme (void)
 {
   return current_theme;
+}
+
+#ifdef HAVE_GCONF
+static gboolean
+update_cursor_theme (const char *value)
+{
+  char *old_theme;
+  gboolean changed;
+  
+  old_theme = cursor_theme;
+  
+  if (value != NULL && *value)
+    {
+      cursor_theme = g_strdup (value);
+    }
+
+  changed = TRUE;
+  if ((old_theme && cursor_theme &&
+       strcmp (old_theme, cursor_theme) == 0) ||
+      (old_theme == NULL && cursor_theme == NULL))
+    changed = FALSE;
+
+  if (old_theme != cursor_theme)
+    g_free (old_theme);
+
+  return changed;
+}
+#endif /* HAVE_GCONF */
+
+const char*
+meta_prefs_get_cursor_theme (void)
+{
+  return cursor_theme;
+}
+
+#ifdef HAVE_GCONF
+static gboolean
+update_cursor_size (int value)
+{
+  int old = cursor_size;
+
+  cursor_size = value;
+
+  return old != value;
+}
+#endif
+
+int
+meta_prefs_get_cursor_size (void)
+{
+  return cursor_size;
 }
 
 #ifdef HAVE_GCONF
Index: src/prefs.h
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.h,v
retrieving revision 1.36
diff -u -r1.36 prefs.h
--- src/prefs.h	26 Jan 2005 08:43:38 -0000	1.36
+++ src/prefs.h	21 Jun 2005 19:41:47 -0000
@@ -48,7 +48,9 @@
   META_PREF_AUDIBLE_BELL,
   META_PREF_VISUAL_BELL_TYPE,
   META_PREF_REDUCED_RESOURCES,
-  META_PREF_GNOME_ACCESSIBILITY
+  META_PREF_GNOME_ACCESSIBILITY,
+  META_PREF_CURSOR_THEME,
+  META_PREF_CURSOR_SIZE
 } MetaPreference;
 
 typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -90,6 +92,9 @@
 const char* meta_prefs_get_workspace_name    (int         i);
 void        meta_prefs_change_workspace_name (int         i,
                                               const char *name);
+
+const char* meta_prefs_get_cursor_theme      (void);
+int         meta_prefs_get_cursor_size       (void);
 
 /* Screen bindings */
 #define META_KEYBINDING_WORKSPACE_1              "switch_to_workspace_1"
Index: src/screen.c
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.c,v
retrieving revision 1.139
diff -u -r1.139 screen.c
--- src/screen.c	7 Jun 2005 15:52:56 -0000	1.139
+++ src/screen.c	21 Jun 2005 19:41:47 -0000
@@ -1153,6 +1153,18 @@
 }
 
 void
+meta_screen_update_cursor (MetaScreen *screen)
+{
+  Cursor xcursor;
+
+  xcursor = meta_display_create_x_cursor (screen->display, 
+					  screen->current_cursor);
+  XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
+  XFlush (screen->display->xdisplay);
+  XFreeCursor (screen->display->xdisplay, xcursor);
+}
+
+void
 meta_screen_ensure_tab_popup (MetaScreen *screen,
                               MetaTabList type)
 {
Index: src/screen.h
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.h,v
retrieving revision 1.59
diff -u -r1.59 screen.h
--- src/screen.h	20 Dec 2004 02:46:42 -0000	1.59
+++ src/screen.h	21 Jun 2005 19:41:47 -0000
@@ -141,6 +141,7 @@
 
 void          meta_screen_set_cursor          (MetaScreen                 *screen,
                                                MetaCursor                  cursor);
+void          meta_screen_update_cursor       (MetaScreen                 *screen);
 
 void          meta_screen_ensure_tab_popup    (MetaScreen                 *screen,
                                                MetaTabList                 type);
