Move lxde-settings into lxde-common.
authorHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Sun, 20 Apr 2008 04:23:00 +0000 (04:23 +0000)
committerHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Sun, 20 Apr 2008 04:23:00 +0000 (04:23 +0000)
16 files changed:
AUTHORS
COPYING
Makefile.am
README
autostart [new file with mode: 0644]
config [new file with mode: 0644]
configure.ac
lxde-settings/Makefile.am [new file with mode: 0644]
lxde-settings/config [new file with mode: 0644]
lxde-settings/lxde-settings.c [new file with mode: 0644]
lxde-settings/xsettings-common.c [new file with mode: 0644]
lxde-settings/xsettings-common.h [new file with mode: 0644]
lxde-settings/xsettings-manager.c [new file with mode: 0644]
lxde-settings/xsettings-manager.h [new file with mode: 0644]
lxde-settings/xutils.c [new file with mode: 0644]
lxde-settings/xutils.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index f6e3201..54890d5 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,3 +4,5 @@ http://lxde.sourceforge.net/
 The nuoveXT2 icon theme included in this package is created by Alexandre Moore.
 http://www.gnome-look.org/content/show.php/nuoveXT+2?content=56625
 
+lxde-settings uses MIT licensed source code from gnome-settings-daemon:
+       Copyright (C) 2001 Owen Taylor, Matthias Clasen, Red Hat, Inc.
diff --git a/COPYING b/COPYING
index f6c0aea..2439e93 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -5,6 +5,8 @@ The nuoveXT2 icon theme included in this package is created by Alexandre Moore.
 http://www.gnome-look.org/content/show.php/nuoveXT+2?content=56625
 It's licensed under GNU LGPL. See icon-theme/COPYING for detail.
 
+lxde-settings uses MIT licensed source code from gnome-settings-daemon:
+       Copyright (C) 2001 Owen Taylor, Matthias Clasen, Red Hat, Inc.
 
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991
index 2519b44..702b74c 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = icon-theme man
+SUBDIRS = lxde-settings icon-theme man
 
 bin_SCRIPTS = startlxde lxde-logout
 
@@ -7,7 +7,7 @@ xsessiondir=$(xsesspath)
 xsession_DATA = LXDE.desktop
 
 defaultsdir=/etc/xdg/lxsession/LXDE
-defaults_DATA = default
+defaults_DATA = default autostart config
 
 wallpapersdir=$(datadir)/lxde/wallpapers
 wallpapers_DATA= \
@@ -33,6 +33,9 @@ pcmanfm_DATA= \
        pcmanfm/main.lxde
 
 EXTRA_DIST = \
+       default \
+       autostart \
+       config \
        LXDE.desktop.in \
        startlxde.in \
        $(wallpapers_DATA) \
diff --git a/README b/README
index e69de29..e664007 100644 (file)
--- a/README
+++ b/README
@@ -0,0 +1,6 @@
+lxde-common package provides a set of default configuration for LXDE.
+
+lxde-settings is the XSettings daemon of LXDE.
+It read config file ~/.config/lxde/config or /usr/share/lxde/config if
+user-specific config file is not available, and presents the config values
+to other programs via XSETTINGS protocol defined by freedesktop.org.
diff --git a/autostart b/autostart
new file mode 100644 (file)
index 0000000..c1c4915
--- /dev/null
+++ b/autostart
@@ -0,0 +1,4 @@
+@lxde-settings
+@xscreensaver -no-splash
+@lxpanel --profile LXDE
+@pcmanfm -d
diff --git a/config b/config
new file mode 100644 (file)
index 0000000..ce11815
--- /dev/null
+++ b/config
@@ -0,0 +1,2 @@
+[Session]
+window_manager=openbox
index 4be0653..4bde348 100644 (file)
@@ -1,23 +1,33 @@
 AC_PREREQ([2.57])
-AC_INIT(lxde-common,[0.3.0.1], [],lxde-common)
+AC_INIT(lxde-common,[0.3.1], [],lxde-common)
 AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
 dnl AC_PROG_INTLTOOL(, [no-xml])
-AM_MAINTAINER_MODE
+dnl AM_MAINTAINER_MODE
 
-dnl AM_CONFIG_HEADER(config.h)
+AC_CONFIG_SRCDIR([lxde-settings/lxde-settings.c])
+AC_CONFIG_HEADER([config.h])
 
+# Checks for programs.
 AC_PROG_INSTALL
 AC_PROG_LN_S
-dnl AM_PROG_CC_C_O
+AM_PROG_CC_C_O
 
-dnl GETTEXT_PACKAGE=lxde
-dnl AM_GNU_GETTEXT([external])
-dnl AM_GNU_GETTEXT_VERSION(0.14.1)
-dnl AC_SUBST(GETTEXT_PACKAGE)
-dnl AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
+# Checks for header files.
+AC_PATH_X
+AC_STDC_HEADERS
+AC_CHECK_HEADERS([locale.h stdlib.h string.h unistd.h])
 
-dnl ALL_LINGUAS="zh_TW hu es sk pl"
-dnl AM_GLIB_GNU_GETTEXT
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([setlocale])
+
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.6.0])
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
 
 # xsessions data of path for GDM
 AC_ARG_WITH([xsession-path],
@@ -28,8 +38,10 @@ AC_ARG_WITH([xsession-path],
         [xsesspath=/usr/share/xsessions])
 AC_SUBST(xsesspath)
 
+
 AC_OUTPUT([
   Makefile
+  lxde-settings/Makefile
   icon-theme/Makefile
   startlxde
   default
diff --git a/lxde-settings/Makefile.am b/lxde-settings/Makefile.am
new file mode 100644 (file)
index 0000000..942edf9
--- /dev/null
@@ -0,0 +1,23 @@
+bin_PROGRAMS=lxde-settings
+
+lxde_settings_CFLAGS = $(GLIB_CFLAGS) \
+                   -DPACKAGE_DATA_DIR=\""$(datadir)/lxde"\" \
+                   -DPACKAGE_LOCALE_DIR=\""$(datadir)/locale"\"
+
+lxde_settings_LDADD = $(GLIB_LIBS) -lX11
+
+lxde_settings_SOURCES = \
+       lxde-settings.c \
+       xsettings-common.h \
+       xsettings-common.c \
+       xsettings-manager.h \
+       xsettings-manager.c \
+       xutils.h \
+       xutils.c
+
+configdir=$(datadir)/lxde
+config_DATA=\
+       config
+
+EXTRA_DIST=\
+       $(config_DATA)
diff --git a/lxde-settings/config b/lxde-settings/config
new file mode 100644 (file)
index 0000000..0ffda6c
--- /dev/null
@@ -0,0 +1,37 @@
+[GTK]
+#iNet/DoubleClickTime=400
+#iNet/DoubleClickDistance
+#iNet/DndDragThreshold
+#iNet/CursorBlink
+#iNet/CursorBlinkTime
+sNet/ThemeName=Clearlooks
+sNet/IconThemeName=nuoveXT2
+#iGtk/CanChangeAccels=0
+#cGtk/ColorPalette
+sGtk/FontName=Sans 10
+#iGtk/IconSizes
+#sGtk/KeyThemeName
+iGtk/ToolbarStyle=3
+#iGtk/ToolbarIconSize
+#iGtk/IMPreeditStyle
+#iGtk/IMStatusStyle
+#sGtk/Modules
+sGtk/FileChooserBackend=
+iGtk/ButtonImages=1
+iGtk/MenuImages=1
+#iGtk/MenuBarAccel=1
+#sGtk/CursorThemeName
+#iGtk/CursorThemeSize
+#iGtk/ShowInputMethodMenu=1
+#iGtk/ShowUnicodeMenu=1
+#iGtk/TimeoutInitial
+#iGtk/TimeoutRepeat
+#cGtk/ColorScheme
+#iGtk/EnableAnimations=1
+iXft/Antialias=1
+#iXft/Hinting
+#iXft/HintStyle
+#iXft/RGBA
+#iXft/DPI
+#sNet/FallbackIconTheme=hicolor
+#iGtk/TouchscreenMode
diff --git a/lxde-settings/lxde-settings.c b/lxde-settings/lxde-settings.c
new file mode 100644 (file)
index 0000000..2a48a96
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *      lxde-settings.c - XSettings daemon of LXDE
+ *      
+ *      Copyright 2008 PCMan <pcman.tw@gmail.com>
+ *      
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *      
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *      
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include "xsettings-manager.h"
+#include "xutils.h"
+
+typedef enum{
+       LXS_RELOAD,
+       LXS_EXIT,
+       LXS_LAST_CMD
+}LXS_CMD;
+
+static Display* dpy;
+static XSettingsManager **managers = NULL;
+
+static Atom CMD_ATOM; /* for private client message */
+
+static void
+terminate_cb (void *data)
+{
+       gboolean *terminated = data;
+
+       if (*terminated)
+               return;
+
+       *terminated = TRUE;
+       exit( 0 );
+//     gtk_main_quit ();
+}
+
+static void load_settings()
+{
+       char* file;
+       GKeyFile* kf = g_key_file_new();
+       gboolean ret;
+
+       file = g_build_filename( g_get_user_config_dir(), "lxde/config", NULL );
+       ret = g_key_file_load_from_file( kf, file, 0, NULL );
+       g_free( file );
+
+       if( ! ret )
+               ret = g_key_file_load_from_file( kf, PACKAGE_DATA_DIR"/config", 0, NULL );
+
+       if( ret )
+       {
+               int i;
+               char** groups = g_key_file_get_groups( kf, NULL), **group;
+
+               for( group = groups; *group; ++group )
+               {
+                       char** keys = g_key_file_get_keys( kf, *group, NULL, NULL ), **key;
+                       for( key = keys; *key; ++key )
+                       {
+                               const char* name = *key + 1;
+
+                               switch( **key )
+                               {
+                                       case 's':       /* string */
+                                       {
+                                               char* str = g_key_file_get_string( kf, *group, *key, NULL );
+                                               if( str )
+                                               {
+                                                       for( i = 0; managers[i]; ++i )
+                                                               xsettings_manager_set_string( managers [i], name, str );
+                                                       g_free( str );
+                                               }
+                                               else
+                                               {
+                                                       for( i = 0; managers[i]; ++i )
+                                                               xsettings_manager_delete_setting( managers[i], name );
+                                               }
+                                               break;
+                                       }
+                                       case 'i':       /* integer */
+                                       {
+                                               int val = g_key_file_get_integer( kf, *group, *key, NULL );
+                                               for( i = 0; managers[i]; ++i )
+                                                       xsettings_manager_set_int( managers [i], name, val );
+                                               break;
+                                       }
+                                       case 'c':       /* color */
+                                       {
+                                               gsize len = 0;
+                                               int* vals = g_key_file_get_integer_list( kf, *group, *key, &len, NULL );
+                                               if( vals && len >= 3 )
+                                               {
+                                                       XSettingsColor color;
+                                                       color.red = (gushort)vals[0];
+                                                       color.green = (gushort)vals[1];
+                                                       color.blue = (gushort)vals[2];
+                                                       color.alpha = (gushort)( len >3 ? vals[3] : 65535 );
+                                                       for( i = 0; managers[i]; ++i )
+                                                               xsettings_manager_set_color( managers [i], name, &color );
+                                               }
+                                               else
+                                               {
+                                                       for( i = 0; managers[i]; ++i )
+                                                               xsettings_manager_delete_setting( managers[i], name );
+                                               }
+                                               g_free( vals );
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               g_strfreev( groups );
+
+               for( i = 0; managers[i]; ++i )
+                       xsettings_manager_notify( managers [i] );
+       }
+       g_key_file_free( kf );
+}
+
+static gboolean create_settings(  )
+{
+       int     n_screens = ScreenCount (dpy);
+       int i;
+       gboolean terminated = FALSE;
+
+       if (xsettings_manager_check_running( dpy, n_screens) )
+       {
+               g_error ("You can only run one xsettings manager at a time; exiting\n");
+               return FALSE;
+       }
+
+       managers = g_new (XSettingsManager *, n_screens + 1);
+       for( i = 0; i < n_screens; ++i )
+       {
+               Screen *screen;
+               screen = ScreenOfDisplay( dpy, i );
+               managers [i] = xsettings_manager_new ( dpy, i, terminate_cb, &terminated);
+               if (!managers [i]) {
+                       g_error ("Could not create xsettings manager for screen %d!\n", i);
+                       return FALSE;
+               }
+               XSelectInput( dpy, RootWindow(dpy, i), SubstructureNotifyMask | PropertyChangeMask );
+       }
+       managers [i] = NULL;
+
+       return TRUE;
+}
+
+static void send_internal_command( int cmd )
+{
+       Window root = DefaultRootWindow(dpy);
+    XEvent ev;
+
+       memset(&ev, 0, sizeof(ev) );
+       ev.xclient.type = ClientMessage;
+       ev.xclient.window = root;
+       ev.xclient.message_type = CMD_ATOM;
+       ev.xclient.format = 8;
+
+       ev.xclient.data.l[0] = cmd;
+
+       XSendEvent(dpy, root, False,
+                          SubstructureRedirectMask|SubstructureNotifyMask, &ev);
+       XSync(dpy, False);
+}
+
+int main(int argc, char** argv)
+{
+       setlocale( LC_ALL, "" );
+
+       /* Currently i18n is not needed */
+/*
+       bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+       textdomain (GETTEXT_PACKAGE);
+*/
+
+       dpy = XOpenDisplay( g_getenv("DISPLAY") );
+       if( ! dpy )
+               return 1;
+
+       CMD_ATOM = XInternAtom( dpy, "LXDE_SETTINGS", False );
+
+       if( argc > 1 )
+       {
+               if(  0 == strcmp( argv[1] , "reload") )
+                       send_internal_command( LXS_RELOAD );
+               else if(  0 == strcmp( argv[1] , "exit") )
+                       send_internal_command( LXS_EXIT );
+               else
+                       goto out;
+               XCloseDisplay( dpy );
+               return 0;
+       }
+       out:
+
+       XGrabServer( dpy );
+       if( XGetSelectionOwner( dpy, CMD_ATOM ) )
+       {
+               g_error( "Only one setting daemon can be executed." );
+               XUngrabServer( dpy );
+               XCloseDisplay( dpy );
+               return 1;
+       }
+       XSetSelectionOwner( dpy, CMD_ATOM, DefaultRootWindow( dpy ), CurrentTime );
+       XUngrabServer( dpy );
+
+       if( ! create_settings( dpy ) )
+               return 1;
+
+       load_settings();
+
+       while( TRUE )
+       {
+               XEvent evt;
+               XSettingsManager**mgr;
+
+               XNextEvent( dpy, &evt );
+               if( evt.type == ClientMessage && evt.xproperty.atom == CMD_ATOM )
+               {
+                       int cmd = evt.xclient.data.b[0];
+                       switch( cmd )
+                       {
+                       case LXS_RELOAD:        /* reload all settings */
+                               load_settings();
+                               break;
+                       case LXS_EXIT:
+                               goto _exit;
+                               break;
+                       }
+               }
+               else if( evt.type ==  SelectionClear )
+               {
+                       for( mgr = managers; *mgr; ++mgr )
+                       {
+                               if( xsettings_manager_get_window( *mgr ) == evt.xany.window )
+                                       xsettings_manager_process_event( *mgr, &evt );
+                       }
+               }
+       }
+
+_exit:
+       XGrabServer( dpy );
+       XSetSelectionOwner( dpy, CMD_ATOM, DefaultRootWindow( dpy ), None );
+       XUngrabServer( dpy );
+
+       XCloseDisplay( dpy );
+
+       return 0;
+}
diff --git a/lxde-settings/xsettings-common.c b/lxde-settings/xsettings-common.c
new file mode 100644 (file)
index 0000000..992175a
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2001 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Owen Taylor, Red Hat, Inc.
+ */
+#include "string.h"
+#include "stdlib.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xmd.h>           /* For CARD32 */
+
+#include "xsettings-common.h"
+
+XSettingsSetting *
+xsettings_setting_copy (XSettingsSetting *setting)
+{
+  XSettingsSetting *result;
+  size_t str_len;
+  
+  result = malloc (sizeof *result);
+  if (!result)
+    return NULL;
+
+  str_len = strlen (setting->name);
+  result->name = malloc (str_len + 1);
+  if (!result->name)
+    goto err;
+
+  memcpy (result->name, setting->name, str_len + 1);
+
+  result->type = setting->type;
+
+  switch (setting->type)
+    {
+    case XSETTINGS_TYPE_INT:
+      result->data.v_int = setting->data.v_int;
+      break;
+    case XSETTINGS_TYPE_COLOR:
+      result->data.v_color = setting->data.v_color;
+      break;
+    case XSETTINGS_TYPE_STRING:
+      str_len = strlen (setting->data.v_string);
+      result->data.v_string = malloc (str_len + 1);
+      if (!result->data.v_string)
+       goto err;
+
+      memcpy (result->data.v_string, setting->data.v_string, str_len + 1);
+      break;
+    }
+
+  result->last_change_serial = setting->last_change_serial;
+
+  return result;
+
+ err:
+  if (result->name)
+    free (result->name);
+  free (result);
+  
+  return NULL;
+}
+
+XSettingsList *
+xsettings_list_copy (XSettingsList *list)
+{
+  XSettingsList *new = NULL;
+  XSettingsList *old_iter = list;
+  XSettingsList *new_iter = NULL;
+
+  while (old_iter)
+    {
+      XSettingsList *new_node;
+
+      new_node = malloc (sizeof *new_node);
+      if (!new_node)
+       goto error;
+
+      new_node->setting = xsettings_setting_copy (old_iter->setting);
+      if (!new_node->setting)
+       {
+         free (new_node);
+         goto error;
+       }
+
+      if (new_iter)
+       new_iter->next = new_node;
+      else
+       new = new_node;
+
+      new_iter = new_node;
+      
+      old_iter = old_iter->next;
+    }
+
+  return new;
+
+ error:
+  xsettings_list_free (new);
+  return NULL;
+}
+
+int
+xsettings_setting_equal (XSettingsSetting *setting_a,
+                        XSettingsSetting *setting_b)
+{
+  if (setting_a->type != setting_b->type)
+    return 0;
+
+  if (strcmp (setting_a->name, setting_b->name) != 0)
+    return 0;
+
+  switch (setting_a->type)
+    {
+    case XSETTINGS_TYPE_INT:
+      return setting_a->data.v_int == setting_b->data.v_int;
+    case XSETTINGS_TYPE_COLOR:
+      return (setting_a->data.v_color.red == setting_b->data.v_color.red &&
+             setting_a->data.v_color.green == setting_b->data.v_color.green &&
+             setting_a->data.v_color.blue == setting_b->data.v_color.blue &&
+             setting_a->data.v_color.alpha == setting_b->data.v_color.alpha);
+    case XSETTINGS_TYPE_STRING:
+      return strcmp (setting_a->data.v_string, setting_b->data.v_string) == 0;
+    }
+
+  return 0;
+}
+
+void
+xsettings_setting_free (XSettingsSetting *setting)
+{
+  if (setting->type == XSETTINGS_TYPE_STRING)
+    free (setting->data.v_string);
+  
+  if (setting->name)
+    free (setting->name);
+
+  free (setting);
+}
+
+void
+xsettings_list_free (XSettingsList *list)
+{
+  while (list)
+    {
+      XSettingsList *next = list->next;
+
+      xsettings_setting_free (list->setting);
+      free (list);
+
+      list = next;
+    }
+}
+
+XSettingsResult
+xsettings_list_insert (XSettingsList    **list,
+                      XSettingsSetting  *setting)
+{
+  XSettingsList *node;
+  XSettingsList *iter;
+  XSettingsList *last = NULL;
+
+  node = malloc (sizeof *node);
+  if (!node)
+    return XSETTINGS_NO_MEM;
+  node->setting = setting;
+
+  iter = *list;
+  while (iter)
+    {
+      int cmp = strcmp (setting->name, iter->setting->name);
+
+      if (cmp < 0)
+       break;
+      else if (cmp == 0)
+       {
+         free (node);
+         return XSETTINGS_DUPLICATE_ENTRY;
+       }
+
+      last = iter;
+      iter = iter->next;
+    }
+  
+  if (last)
+    last->next = node;
+  else
+    *list = node;
+  
+  node->next = iter;
+  
+  return XSETTINGS_SUCCESS;
+}
+
+XSettingsResult
+xsettings_list_delete (XSettingsList **list,
+                      const char     *name)
+{
+  XSettingsList *iter;
+  XSettingsList *last = NULL;
+
+  iter = *list;
+  while (iter)
+    {
+      if (strcmp (name, iter->setting->name) == 0)
+       {
+         if (last)
+           last->next = iter->next;
+         else
+           *list = iter->next;
+  
+         xsettings_setting_free (iter->setting);
+         free (iter);
+
+         return XSETTINGS_SUCCESS;
+       }
+
+      last = iter;
+      iter = iter->next;
+    }
+
+  return XSETTINGS_FAILED;
+}
+
+XSettingsSetting *
+xsettings_list_lookup (XSettingsList *list,
+                      const char    *name)
+{
+  XSettingsList *iter;
+
+  iter = list;
+  while (iter)
+    {
+      if (strcmp (name, iter->setting->name) == 0)
+       return iter->setting;
+
+      iter = iter->next;
+    }
+
+  return NULL;
+}
+
+char
+xsettings_byte_order (void)
+{
+  CARD32 myint = 0x01020304;
+  return (*(char *)&myint == 1) ? MSBFirst : LSBFirst;
+}
diff --git a/lxde-settings/xsettings-common.h b/lxde-settings/xsettings-common.h
new file mode 100644 (file)
index 0000000..e3af4a6
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2001 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Owen Taylor, Red Hat, Inc.
+ */
+#ifndef XSETTINGS_COMMON_H
+#define XSETTINGS_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _XSettingsBuffer  XSettingsBuffer;
+typedef struct _XSettingsColor   XSettingsColor;
+typedef struct _XSettingsList    XSettingsList;
+typedef struct _XSettingsSetting XSettingsSetting;
+
+/* Types of settings possible. Enum values correspond to
+ * protocol values.
+ */
+typedef enum 
+{
+  XSETTINGS_TYPE_INT     = 0,
+  XSETTINGS_TYPE_STRING  = 1,
+  XSETTINGS_TYPE_COLOR   = 2
+} XSettingsType;
+
+typedef enum
+{
+  XSETTINGS_SUCCESS,
+  XSETTINGS_NO_MEM,
+  XSETTINGS_ACCESS,
+  XSETTINGS_FAILED,
+  XSETTINGS_NO_ENTRY,
+  XSETTINGS_DUPLICATE_ENTRY
+} XSettingsResult;
+
+struct _XSettingsBuffer
+{
+  char byte_order;
+  size_t len;
+  unsigned char *data;
+  unsigned char *pos;
+};
+
+struct _XSettingsColor
+{
+  unsigned short red, green, blue, alpha;
+};
+
+struct _XSettingsList
+{
+  XSettingsSetting *setting;
+  XSettingsList *next;
+};
+
+struct _XSettingsSetting
+{
+  char *name;
+  XSettingsType type;
+  
+  union {
+    int v_int;
+    char *v_string;
+    XSettingsColor v_color;
+  } data;
+
+  unsigned long last_change_serial;
+};
+
+XSettingsSetting *xsettings_setting_copy  (XSettingsSetting *setting);
+void              xsettings_setting_free  (XSettingsSetting *setting);
+int               xsettings_setting_equal (XSettingsSetting *setting_a,
+                                          XSettingsSetting *setting_b);
+
+void              xsettings_list_free   (XSettingsList     *list);
+XSettingsList    *xsettings_list_copy   (XSettingsList     *list);
+XSettingsResult   xsettings_list_insert (XSettingsList    **list,
+                                        XSettingsSetting  *setting);
+XSettingsSetting *xsettings_list_lookup (XSettingsList     *list,
+                                        const char        *name);
+XSettingsResult   xsettings_list_delete (XSettingsList    **list,
+                                        const char        *name);
+
+char xsettings_byte_order (void);
+
+#define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1)))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* XSETTINGS_COMMON_H */
diff --git a/lxde-settings/xsettings-manager.c b/lxde-settings/xsettings-manager.c
new file mode 100644 (file)
index 0000000..6578ce1
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Copyright © 2001 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Owen Taylor, Red Hat, Inc.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <X11/Xmd.h>           /* For CARD16 */
+
+#include "xsettings-manager.h"
+
+struct _XSettingsManager
+{
+  Display *display;
+  int screen;
+
+  Window window;
+  Atom manager_atom;
+  Atom selection_atom;
+  Atom xsettings_atom;
+
+  XSettingsTerminateFunc terminate;
+  void *cb_data;
+
+  XSettingsList *settings;
+  unsigned long serial;
+};
+
+static XSettingsList *settings;
+
+typedef struct 
+{
+  Window window;
+  Atom timestamp_prop_atom;
+} TimeStampInfo;
+
+static Bool
+timestamp_predicate (Display *display,
+                    XEvent  *xevent,
+                    XPointer arg)
+{
+  TimeStampInfo *info = (TimeStampInfo *)arg;
+
+  if (xevent->type == PropertyNotify &&
+      xevent->xproperty.window == info->window &&
+      xevent->xproperty.atom == info->timestamp_prop_atom)
+    return True;
+
+  return False;
+}
+
+/**
+ * get_server_time:
+ * @display: display from which to get the time
+ * @window: a #Window, used for communication with the server.
+ *          The window must have PropertyChangeMask in its
+ *          events mask or a hang will result.
+ * 
+ * Routine to get the current X server time stamp. 
+ * 
+ * Return value: the time stamp.
+ **/
+static Time
+get_server_time (Display *display,
+                Window   window)
+{
+  unsigned char c = 'a';
+  XEvent xevent;
+  TimeStampInfo info;
+
+  info.timestamp_prop_atom = XInternAtom  (display, "_TIMESTAMP_PROP", False);
+  info.window = window;
+
+  XChangeProperty (display, window,
+                  info.timestamp_prop_atom, info.timestamp_prop_atom,
+                  8, PropModeReplace, &c, 1);
+
+  XIfEvent (display, &xevent,
+           timestamp_predicate, (XPointer)&info);
+
+  return xevent.xproperty.time;
+}
+
+Bool
+xsettings_manager_check_running (Display *display,
+                                int      screen)
+{
+  char buffer[256];
+  Atom selection_atom;
+  
+  sprintf(buffer, "_XSETTINGS_S%d", screen);
+  selection_atom = XInternAtom (display, buffer, False);
+
+  if (XGetSelectionOwner (display, selection_atom))
+    return True;
+  else
+    return False;
+}
+
+XSettingsManager *
+xsettings_manager_new (Display                *display,
+                      int                     screen,
+                      XSettingsTerminateFunc  terminate,
+                      void                   *cb_data)
+{
+  XSettingsManager *manager;
+  Time timestamp;
+  XClientMessageEvent xev;
+
+  char buffer[256];
+  
+  manager = malloc (sizeof *manager);
+  if (!manager)
+    return NULL;
+
+  manager->display = display;
+  manager->screen = screen;
+
+  sprintf(buffer, "_XSETTINGS_S%d", screen);
+  manager->selection_atom = XInternAtom (display, buffer, False);
+  manager->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False);
+  manager->manager_atom = XInternAtom (display, "MANAGER", False);
+
+  manager->terminate = terminate;
+  manager->cb_data = cb_data;
+
+  manager->settings = NULL;
+  manager->serial = 0;
+
+  manager->window = XCreateSimpleWindow (display,
+                                        RootWindow (display, screen),
+                                        0, 0, 10, 10, 0,
+                                        WhitePixel (display, screen),
+                                        WhitePixel (display, screen));
+
+  XSelectInput (display, manager->window, PropertyChangeMask);
+  timestamp = get_server_time (display, manager->window);
+
+  XSetSelectionOwner (display, manager->selection_atom,
+                     manager->window, timestamp);
+
+  /* Check to see if we managed to claim the selection. If not,
+   * we treat it as if we got it then immediately lost it
+   */
+
+  if (XGetSelectionOwner (display, manager->selection_atom) ==
+      manager->window)
+    {
+      xev.type = ClientMessage;
+      xev.window = RootWindow (display, screen);
+      xev.message_type = manager->manager_atom;
+      xev.format = 32;
+      xev.data.l[0] = timestamp;
+      xev.data.l[1] = manager->selection_atom;
+      xev.data.l[2] = manager->window;
+      xev.data.l[3] = 0;       /* manager specific data */
+      xev.data.l[4] = 0;       /* manager specific data */
+      
+      XSendEvent (display, RootWindow (display, screen),
+                 False, StructureNotifyMask, (XEvent *)&xev);
+    }
+  else
+    {
+      manager->terminate (manager->cb_data);
+    }
+  
+  return manager;
+}
+
+void
+xsettings_manager_destroy (XSettingsManager *manager)
+{
+  XDestroyWindow (manager->display, manager->window);
+  
+  xsettings_list_free (manager->settings);
+  free (manager);
+}
+
+Window
+xsettings_manager_get_window (XSettingsManager *manager)
+{
+  return manager->window;
+}
+
+Bool
+xsettings_manager_process_event (XSettingsManager *manager,
+                                XEvent           *xev)
+{
+  if (xev->xany.window == manager->window &&
+      xev->xany.type == SelectionClear &&
+      xev->xselectionclear.selection == manager->selection_atom)
+    {
+      manager->terminate (manager->cb_data);
+      return True;
+    }
+
+  return False;
+}
+
+XSettingsResult
+xsettings_manager_delete_setting (XSettingsManager *manager,
+                                  const char       *name)
+{
+  return xsettings_list_delete (&settings, name);
+}
+
+XSettingsResult
+xsettings_manager_set_setting (XSettingsManager *manager,
+                              XSettingsSetting *setting)
+{
+  XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name);
+  XSettingsSetting *new_setting;
+  XSettingsResult result;
+
+  if (old_setting)
+    {
+      if (xsettings_setting_equal (old_setting, setting))
+       return XSETTINGS_SUCCESS;
+
+      xsettings_list_delete (&settings, setting->name);
+    }
+
+  new_setting = xsettings_setting_copy (setting);
+  if (!new_setting)
+    return XSETTINGS_NO_MEM;
+  
+  new_setting->last_change_serial = manager->serial;
+  
+  result = xsettings_list_insert (&settings, new_setting);
+  
+  if (result != XSETTINGS_SUCCESS)
+    xsettings_setting_free (new_setting);
+
+  return result;
+}
+
+XSettingsResult
+xsettings_manager_set_int (XSettingsManager *manager,
+                          const char       *name,
+                          int               value)
+{
+  XSettingsSetting setting;
+
+  setting.name = (char *)name;
+  setting.type = XSETTINGS_TYPE_INT;
+  setting.data.v_int = value;
+
+  return xsettings_manager_set_setting (manager, &setting);
+}
+
+XSettingsResult
+xsettings_manager_set_string (XSettingsManager *manager,
+                             const char       *name,
+                             const char       *value)
+{
+  XSettingsSetting setting;
+
+  setting.name = (char *)name;
+  setting.type = XSETTINGS_TYPE_STRING;
+  setting.data.v_string = (char *)value;
+
+  return xsettings_manager_set_setting (manager, &setting);
+}
+
+XSettingsResult
+xsettings_manager_set_color (XSettingsManager *manager,
+                            const char       *name,
+                            XSettingsColor   *value)
+{
+  XSettingsSetting setting;
+
+  setting.name = (char *)name;
+  setting.type = XSETTINGS_TYPE_COLOR;
+  setting.data.v_color = *value;
+
+  return xsettings_manager_set_setting (manager, &setting);
+}
+
+static size_t
+setting_length (XSettingsSetting *setting)
+{
+  size_t length = 8;   /* type + pad + name-len + last-change-serial */
+  length += XSETTINGS_PAD (strlen (setting->name), 4);
+
+  switch (setting->type)
+    {
+    case XSETTINGS_TYPE_INT:
+      length += 4;
+      break;
+    case XSETTINGS_TYPE_STRING:
+      length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4);
+      break;
+    case XSETTINGS_TYPE_COLOR:
+      length += 8;
+      break;
+    }
+
+  return length;
+}
+
+static void
+setting_store (XSettingsSetting *setting,
+              XSettingsBuffer *buffer)
+{
+  size_t string_len;
+  size_t length;
+
+  *(buffer->pos++) = setting->type;
+  *(buffer->pos++) = 0;
+
+  string_len = strlen (setting->name);
+  *(CARD16 *)(buffer->pos) = string_len;
+  buffer->pos += 2;
+
+  length = XSETTINGS_PAD (string_len, 4);
+  memcpy (buffer->pos, setting->name, string_len);
+  length -= string_len;
+  buffer->pos += string_len;
+  
+  while (length > 0)
+    {
+      *(buffer->pos++) = 0;
+      length--;
+    }
+
+  *(CARD32 *)(buffer->pos) = setting->last_change_serial;
+  buffer->pos += 4;
+
+  switch (setting->type)
+    {
+    case XSETTINGS_TYPE_INT:
+      *(CARD32 *)(buffer->pos) = setting->data.v_int;
+      buffer->pos += 4;
+      break;
+    case XSETTINGS_TYPE_STRING:
+      string_len = strlen (setting->data.v_string);
+      *(CARD32 *)(buffer->pos) = string_len;
+      buffer->pos += 4;
+      
+      length = XSETTINGS_PAD (string_len, 4);
+      memcpy (buffer->pos, setting->data.v_string, string_len);
+      length -= string_len;
+      buffer->pos += string_len;
+      
+      while (length > 0)
+       {
+         *(buffer->pos++) = 0;
+         length--;
+       }
+      break;
+    case XSETTINGS_TYPE_COLOR:
+      *(CARD16 *)(buffer->pos) = setting->data.v_color.red;
+      *(CARD16 *)(buffer->pos + 2) = setting->data.v_color.green;
+      *(CARD16 *)(buffer->pos + 4) = setting->data.v_color.blue;
+      *(CARD16 *)(buffer->pos + 6) = setting->data.v_color.alpha;
+      buffer->pos += 8;
+      break;
+    }
+}
+
+XSettingsResult
+xsettings_manager_notify (XSettingsManager *manager)
+{
+  XSettingsBuffer buffer;
+  XSettingsList *iter;
+  int n_settings = 0;
+
+  buffer.len = 12;             /* byte-order + pad + SERIAL + N_SETTINGS */
+
+  iter = settings;
+  while (iter)
+    {
+      buffer.len += setting_length (iter->setting);
+      n_settings++;
+      iter = iter->next;
+    }
+
+  buffer.data = buffer.pos = malloc (buffer.len);
+  if (!buffer.data)
+    return XSETTINGS_NO_MEM;
+
+  *buffer.pos = xsettings_byte_order ();
+
+  buffer.pos += 4;
+  *(CARD32 *)buffer.pos = manager->serial++;
+  buffer.pos += 4;
+  *(CARD32 *)buffer.pos = n_settings;
+  buffer.pos += 4;
+
+  iter = settings;
+  while (iter)
+    {
+      setting_store (iter->setting, &buffer);
+      iter = iter->next;
+    }
+
+  XChangeProperty (manager->display, manager->window,
+                  manager->xsettings_atom, manager->xsettings_atom,
+                  8, PropModeReplace, buffer.data, buffer.len);
+
+  free (buffer.data);
+
+  return XSETTINGS_SUCCESS;
+}
+
diff --git a/lxde-settings/xsettings-manager.h b/lxde-settings/xsettings-manager.h
new file mode 100644 (file)
index 0000000..f309768
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2001 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Owen Taylor, Red Hat, Inc.
+ */
+#ifndef XSETTINGS_MANAGER_H
+#define XSETTINGS_MANAGER_H
+
+#include <X11/Xlib.h>
+#include "xsettings-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _XSettingsManager XSettingsManager;
+
+typedef void (*XSettingsTerminateFunc)  (void *cb_data);
+
+Bool xsettings_manager_check_running (Display *display,
+                                     int      screen);
+
+XSettingsManager *xsettings_manager_new (Display                *display,
+                                        int                     screen,
+                                        XSettingsTerminateFunc  terminate,
+                                        void                   *cb_data);
+
+void   xsettings_manager_destroy       (XSettingsManager *manager);
+Window xsettings_manager_get_window    (XSettingsManager *manager);
+Bool   xsettings_manager_process_event (XSettingsManager *manager,
+                                       XEvent           *xev);
+
+XSettingsResult xsettings_manager_delete_setting (XSettingsManager *manager,
+                                                  const char       *name);
+XSettingsResult xsettings_manager_set_setting    (XSettingsManager *manager,
+                                                  XSettingsSetting *setting);
+XSettingsResult xsettings_manager_set_int        (XSettingsManager *manager,
+                                                  const char       *name,
+                                                  int               value);
+XSettingsResult xsettings_manager_set_string     (XSettingsManager *manager,
+                                                  const char       *name,
+                                                  const char       *value);
+XSettingsResult xsettings_manager_set_color      (XSettingsManager *manager,
+                                                  const char       *name,
+                                                  XSettingsColor   *value);
+XSettingsResult xsettings_manager_notify         (XSettingsManager *manager);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* XSETTINGS_MANAGER_H */
diff --git a/lxde-settings/xutils.c b/lxde-settings/xutils.c
new file mode 100644 (file)
index 0000000..4e48b98
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Matthias Clasen, Red Hat, Inc.
+ */
+
+#include <stdlib.h>
+
+#include "xutils.h"
+
+Atom XA_ATOM_PAIR;
+Atom XA_CLIPBOARD_MANAGER;
+Atom XA_CLIPBOARD;
+Atom XA_DELETE;
+Atom XA_INCR;
+Atom XA_INSERT_PROPERTY;
+Atom XA_INSERT_SELECTION;
+Atom XA_MANAGER;
+Atom XA_MULTIPLE;
+Atom XA_NULL;
+Atom XA_SAVE_TARGETS;
+Atom XA_TARGETS;
+Atom XA_TIMESTAMP;
+
+unsigned long SELECTION_MAX_SIZE = 0;
+
+
+void
+init_atoms (Display *display)
+{
+  unsigned long max_request_size;
+  
+  if (SELECTION_MAX_SIZE > 0)
+    return;
+
+  XA_ATOM_PAIR = XInternAtom (display, "ATOM_PAIR", False);
+  XA_CLIPBOARD_MANAGER = XInternAtom (display, "CLIPBOARD_MANAGER", False);
+  XA_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False);
+  XA_DELETE = XInternAtom (display, "DELETE", False);
+  XA_INCR = XInternAtom (display, "INCR", False);
+  XA_INSERT_PROPERTY = XInternAtom (display, "INSERT_PROPERTY", False);
+  XA_INSERT_SELECTION = XInternAtom (display, "INSERT_SELECTION", False);
+  XA_MANAGER = XInternAtom (display, "MANAGER", False);
+  XA_MULTIPLE = XInternAtom (display, "MULTIPLE", False);
+  XA_NULL = XInternAtom (display, "NULL", False);
+  XA_SAVE_TARGETS = XInternAtom (display, "SAVE_TARGETS", False);
+  XA_TARGETS = XInternAtom (display, "TARGETS", False);
+  XA_TIMESTAMP = XInternAtom (display, "TIMESTAMP", False);
+  
+  max_request_size = XExtendedMaxRequestSize (display);
+  if (max_request_size == 0)
+    max_request_size = XMaxRequestSize (display);
+  
+  SELECTION_MAX_SIZE = max_request_size - 100;
+  if (SELECTION_MAX_SIZE > 262144)
+    SELECTION_MAX_SIZE =  262144;
+}
+
+typedef struct 
+{
+  Window window;
+  Atom timestamp_prop_atom;
+} TimeStampInfo;
+
+static Bool
+timestamp_predicate (Display *display,
+                    XEvent  *xevent,
+                    XPointer arg)
+{
+  TimeStampInfo *info = (TimeStampInfo *)arg;
+
+  if (xevent->type == PropertyNotify &&
+      xevent->xproperty.window == info->window &&
+      xevent->xproperty.atom == info->timestamp_prop_atom)
+    return True;
+
+  return False;
+}
+
+Time
+get_server_time (Display *display,
+                Window   window)
+{
+  unsigned char c = 'a';
+  XEvent xevent;
+  TimeStampInfo info;
+
+  info.timestamp_prop_atom = XInternAtom  (display, "_TIMESTAMP_PROP", False);
+  info.window = window;
+
+  XChangeProperty (display, window,
+                  info.timestamp_prop_atom, info.timestamp_prop_atom,
+                  8, PropModeReplace, &c, 1);
+
+  XIfEvent (display, &xevent,
+           timestamp_predicate, (XPointer)&info);
+
+  return xevent.xproperty.time;
+}
+
diff --git a/lxde-settings/xutils.h b/lxde-settings/xutils.h
new file mode 100644 (file)
index 0000000..143fe44
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2004 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Red Hat makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Matthias Clasen, Red Hat, Inc.
+ */
+#ifndef X_UTILS_H
+#define X_UTILS_H
+
+#include <X11/Xlib.h>
+
+
+extern Atom XA_ATOM_PAIR;
+extern Atom XA_CLIPBOARD_MANAGER;
+extern Atom XA_CLIPBOARD;
+extern Atom XA_DELETE;
+extern Atom XA_INCR;
+extern Atom XA_INSERT_PROPERTY;
+extern Atom XA_INSERT_SELECTION;
+extern Atom XA_MANAGER;
+extern Atom XA_MULTIPLE;
+extern Atom XA_NULL;
+extern Atom XA_SAVE_TARGETS;
+extern Atom XA_TARGETS;
+extern Atom XA_TIMESTAMP;
+
+extern unsigned long SELECTION_MAX_SIZE;
+
+void init_atoms      (Display *display);
+
+Time get_server_time (Display *display,
+                     Window   window);
+
+#endif /* X_UTILS_H */