commit c7adc9b6911c825a5850c9229534618b02c3b70d
Author: Andrzej <ndrwrdck@gmail.com>
Date:   Sun Nov 27 00:01:58 2011 +0900

    screen, xutils: added orientation and starting corner setters; deprecated _wnck_set_desktop_layout in favor of _wnck_set_desktop_layout_all.

diff --git a/libwnck/screen.c b/libwnck/screen.c
index f8fb026..f00e0eb 100644
--- a/libwnck/screen.c
+++ b/libwnck/screen.c
@@ -2678,7 +2678,9 @@ _wnck_screen_get_workspace_layout (WnckScreen             *screen,
  * wnck_screen_release_workspace_layout() when you do not need it anymore.
  *
  * Return value: a token to use for future calls to
- * wnck_screen_try_set_workspace_layout() and to
+ * wnck_screen_try_set_workspace_layout(),
+ * wnck_screen_try_set_workspace_orientation(),
+ * wnck_screen_try_set_workspace_corner() and to
  * wnck_screen_release_workspace_layout(), or 0 if the layout could not be set.
  */
 int
@@ -2687,8 +2689,9 @@ wnck_screen_try_set_workspace_layout (WnckScreen *screen,
                                       int         rows,
                                       int         columns)
 {
-  int retval;
-  
+  int                    retval;
+  _WnckLayoutOrientation orientation;
+
   g_return_val_if_fail (WNCK_IS_SCREEN (screen),
                         WNCK_NO_MANAGER_TOKEN);
   g_return_val_if_fail (rows != 0 || columns != 0,
@@ -2698,7 +2701,126 @@ wnck_screen_try_set_workspace_layout (WnckScreen *screen,
 
   if (retval != WNCK_NO_MANAGER_TOKEN)
     {
-      _wnck_set_desktop_layout (screen->priv->xscreen, rows, columns);
+      orientation = screen->priv->vertical_workspaces ?
+        WNCK_LAYOUT_ORIENTATION_VERTICAL :
+        WNCK_LAYOUT_ORIENTATION_HORIZONTAL;
+
+      _wnck_set_desktop_layout_all (screen->priv->xscreen,
+                                    orientation, rows, columns, screen->priv->starting_corner);
+    }
+
+  return retval;
+}
+
+/**
+ * wnck_screen_try_set_workspace_orientation:
+ * @screen: a #WnckScreen.
+ * @current_token: a token. Use 0 if you do not called
+ * wnck_screen_try_set_workspace_orientation() before, or if you did not keep the
+ * old token.
+ * @orientation: the orientation to use for the #WnckWorkspace layout.
+ *
+ * Tries to modify the layout orientation of #WnckWorkspace on @screen. To do this, tries
+ * to acquire ownership of the layout. If the current process is the owner of
+ * the layout, @current_token is used to determine if the caller is the owner
+ * (there might be more than one part of the same process trying to set the
+ * layout orientation). Since no more than one application should set this property of
+ * @screen at a time, setting the layout orientation is not guaranteed to work.
+ *
+ * If @orientation is %WNCK_LAYOUT_ORIENTATION_HORIZONTAL, the #WnckWorkspace will be
+ * laid out in rows.
+ *
+ * If @orientation is %WNCK_LAYOUT_ORIENTATION_HORIZONTAL, the #WnckWorkspace will be
+ * laid out in columns.
+ *
+ * You have to release the ownership of the layout with
+ * wnck_screen_release_workspace_layout() when you do not need it anymore.
+ *
+ * Return value: a token to use for future calls to
+ * wnck_screen_try_set_workspace_layout(),
+ * wnck_screen_try_set_workspace_orientation(),
+ * wnck_screen_try_set_workspace_corner() and to
+ * wnck_screen_release_workspace_layout(), or 0 if the layout could not be set.
+ */
+int
+wnck_screen_try_set_workspace_orientation (WnckScreen             *screen,
+                                           int                     current_token,
+                                           _WnckLayoutOrientation  orientation)
+{
+  int                    retval;
+
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen),
+                        WNCK_NO_MANAGER_TOKEN);
+  
+  retval = _wnck_try_desktop_layout_manager (screen->priv->xscreen, current_token);
+
+  if (retval != WNCK_NO_MANAGER_TOKEN)
+    {
+      _wnck_set_desktop_layout_all (screen->priv->xscreen,
+                                    orientation,
+                                    screen->priv->rows_of_workspaces,
+                                    screen->priv->columns_of_workspaces,
+                                    screen->priv->starting_corner);
+    }
+
+  return retval;
+}
+
+/**
+ * wnck_screen_try_set_workspace_corner:
+ * @screen: a #WnckScreen.
+ * @current_token: a token. Use 0 if you do not called
+ * wnck_screen_try_set_workspace_corner() before, or if you did not keep the
+ * old token.
+ * @starting_corner: the starting corner to use for the #WnckWorkspace layout.
+ *
+ * Tries to modify the layout starting corner of #WnckWorkspace on @screen. To do this, tries
+ * to acquire ownership of the layout. If the current process is the owner of
+ * the layout, @current_token is used to determine if the caller is the owner
+ * (there might be more than one part of the same process trying to set the
+ * layout starting corner). Since no more than one application should set this property of
+ * @screen at a time, setting the layout starting corner is not guaranteed to work.
+ *
+ * The @starting_corner is an enum, which may have four values:
+ * 
+ * %WNCK_LAYOUT_CORNER_TOPLEFT,
+ * %WNCK_LAYOUT_CORNER_TOPRIGHT,
+ * %WNCK_LAYOUT_CORNER_BOTTOMRIGHT,
+ * %WNCK_LAYOUT_CORNER_BOTTOMLEFT
+ *
+ * You have to release the ownership of the layout with
+ * wnck_screen_release_workspace_layout() when you do not need it anymore.
+ *
+ * Return value: a token to use for future calls to
+ * wnck_screen_try_set_workspace_layout(),
+ * wnck_screen_try_set_workspace_orientation(),
+ * wnck_screen_try_set_workspace_corner() and to
+ * wnck_screen_release_workspace_layout(), or 0 if the layout could not be set.
+ */
+int
+wnck_screen_try_set_workspace_corner (WnckScreen        *screen,
+                                      int                current_token,
+                                      _WnckLayoutCorner  starting_corner)
+{
+  int                    retval;
+  _WnckLayoutOrientation orientation;
+
+  g_return_val_if_fail (WNCK_IS_SCREEN (screen),
+                        WNCK_NO_MANAGER_TOKEN);
+  
+  retval = _wnck_try_desktop_layout_manager (screen->priv->xscreen, current_token);
+
+  if (retval != WNCK_NO_MANAGER_TOKEN)
+    {
+      orientation = screen->priv->vertical_workspaces ?
+        WNCK_LAYOUT_ORIENTATION_VERTICAL :
+        WNCK_LAYOUT_ORIENTATION_HORIZONTAL;
+
+      _wnck_set_desktop_layout_all (screen->priv->xscreen,
+                                    orientation,
+                                    screen->priv->rows_of_workspaces,
+                                    screen->priv->columns_of_workspaces,
+                                    starting_corner);
     }
 
   return retval;
diff --git a/libwnck/screen.h b/libwnck/screen.h
index ee95a17..63411df 100644
--- a/libwnck/screen.h
+++ b/libwnck/screen.h
@@ -260,6 +260,12 @@ int            wnck_screen_try_set_workspace_layout (WnckScreen *screen,
                                                      int         current_token,
                                                      int         rows,
                                                      int         columns);
+int            wnck_screen_try_set_workspace_orientation (WnckScreen             *screen,
+                                                          int                     current_token,
+                                                          _WnckLayoutOrientation  orientation);
+int            wnck_screen_try_set_workspace_corner (WnckScreen        *screen,
+                                                     int                current_token,
+                                                     _WnckLayoutCorner  starting_corner);
 void           wnck_screen_release_workspace_layout (WnckScreen *screen,
                                                      int         current_token);
 #ifndef WNCK_DISABLE_DEPRECATED
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 92b9201..950ed0b 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -2471,6 +2471,60 @@ _wnck_set_desktop_layout (Screen *xscreen,
   _wnck_error_trap_pop ();
 }
 
+void
+_wnck_set_desktop_layout_all (Screen                 *xscreen,
+                              _WnckLayoutOrientation  orientation,
+                              int                     rows,
+                              int                     columns,
+                              _WnckLayoutCorner       starting_corner)
+{
+  Display *display;
+  Window   root;
+  gulong   data[4];
+
+  g_assert ((rows == 0) || (columns == 0));
+
+  display = DisplayOfScreen (xscreen);
+  root = RootWindowOfScreen (xscreen);
+
+  data[1] = columns;
+  data[2] = rows;
+
+  if (orientation == WNCK_LAYOUT_ORIENTATION_HORIZONTAL)
+    data[0] = _NET_WM_ORIENTATION_HORZ;
+  else
+    data[0] = _NET_WM_ORIENTATION_VERT;
+
+  switch (starting_corner)
+    {
+    case WNCK_LAYOUT_CORNER_TOPLEFT:
+      data[3] = _NET_WM_TOPLEFT;
+      break;
+      
+    case WNCK_LAYOUT_CORNER_TOPRIGHT:
+      data[3] = _NET_WM_TOPRIGHT;
+      break;
+      
+    case WNCK_LAYOUT_CORNER_BOTTOMLEFT:
+      data[3] = _NET_WM_BOTTOMLEFT;
+      break;
+      
+    case WNCK_LAYOUT_CORNER_BOTTOMRIGHT:
+      data[3] = _NET_WM_BOTTOMRIGHT;
+      break;
+    };
+
+  _wnck_error_trap_push ();
+
+  XChangeProperty (display,
+                   root,
+		   _wnck_atom_get ("_NET_DESKTOP_LAYOUT"),
+		   XA_CARDINAL, 32, PropModeReplace,
+		   (guchar *)&data, 4);
+
+  _wnck_error_trap_pop ();
+}
+
 typedef struct 
 {
   Window window;
diff --git a/libwnck/xutils.h b/libwnck/xutils.h
index b25b6b8..c95db75 100644
--- a/libwnck/xutils.h
+++ b/libwnck/xutils.h
@@ -29,6 +29,7 @@
 #include <X11/Xatom.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
+#include <libwnck/screen.h>
 
 G_BEGIN_DECLS
 
@@ -194,6 +195,12 @@ void _wnck_set_desktop_layout (Screen *xscreen,
                                int     rows,
                                int     columns);
 
+void _wnck_set_desktop_layout_all (Screen                 *xscreen,
+                                   _WnckLayoutOrientation  orientation,
+                                   int                     rows,
+                                   int                     columns,
+                                   _WnckLayoutCorner       starting_corner);
+
 GdkPixbuf* _wnck_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
                                              Pixmap       xpixmap,
                                              int          src_x,
