summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2006-04-01 21:53:29 +0000
committerSergey Udaltsov <svu@gnome.org>2006-04-01 21:53:29 +0000
commit8929d3d6760e3bc4c9f352180d60acab5a604f0c (patch)
treeaa5b6d2bf8ae15626cd8fadfbd49e73ec3fc2134
parentd8339126d5036eb7751b97207afed1eabbd5114c (diff)
downloadlibxklavier-8929d3d6760e3bc4c9f352180d60acab5a604f0c.tar.gz
tiny memleak
-rw-r--r--ChangeLog11
-rw-r--r--libxklavier/xklavier_props.c778
2 files changed, 375 insertions, 414 deletions
diff --git a/ChangeLog b/ChangeLog
index 7156654..42f87f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,14 @@
-2006-02-28 svu
+2006-04-01 svu
- * libxklavier/xklavier_config_xkb.c: libxklavier/xklavier_evt.c:
+ * libxklavier/xklavier_props.c:
+ fixing tiny memleak (thanks to kmaaras)
+
+2006-03-28 svu
+
+ * libxklavier/xklavier_config_xkb.c, libxklavier/xklavier_evt.c:
making XKB configuration loading more robust (ignoring ALL xkb errors)
-2006-02-16 svu
+2006-03-16 svu
* libxklavier/xklavier_evt_xmm.c: fixing GCC 2.95 compilation,
thanks to Jens Granseuer
diff --git a/libxklavier/xklavier_props.c b/libxklavier/xklavier_props.c
index b18d142..47445ff 100644
--- a/libxklavier/xklavier_props.c
+++ b/libxklavier/xklavier_props.c
@@ -1,6 +1,6 @@
#include <errno.h>
-#include <locale.h>
#include <string.h>
+#include <locale.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@@ -9,465 +9,421 @@
#include "config.h"
+#include "xklavier.h"
+#include "xklavier_config.h"
#include "xklavier_private.h"
-static GObjectClass *parent_class = NULL;
-
-static void xkl_config_rec_destroy(XklConfigRec * data);
-
-G_DEFINE_TYPE(XklConfigItem, xkl_config_item, G_TYPE_OBJECT)
-
-static void
-xkl_config_item_init(XklConfigItem * this)
-{
-}
-
-static void
-xkl_config_item_class_init(XklConfigItemClass * klass)
+void XklConfigRecInit( XklConfigRecPtr data )
{
+ /* clear the structure VarDefsPtr... */
+ memset( ( void * ) data, 0, sizeof( XklConfigRec ) );
}
-XklConfigItem *
-xkl_config_item_new(void)
+static Bool PtrsEqual( char* p1, char* p2 )
{
- return
- XKL_CONFIG_ITEM(g_object_new
- (xkl_config_item_get_type(), NULL));
+ if ( p1 == p2 )
+ return True;
+ if ( ( p1 == NULL && p2 != NULL ) ||
+ ( p1 != NULL && p2 == NULL ) )
+ return False;
+ return !strcmp( p1, p2 );
}
-G_DEFINE_TYPE(XklConfigRec, xkl_config_rec, G_TYPE_OBJECT)
-
-static void
-xkl_config_rec_finalize(GObject * obj)
+static Bool ListsEqual( int numItems1, char** items1,
+ int numItems2, char** items2 )
{
- XklConfigRec *this = (XklConfigRec *) obj;
- xkl_config_rec_destroy(this);
- G_OBJECT_CLASS(parent_class)->finalize(obj);
+ int i;
+ if ( numItems1 != numItems2 )
+ return False;
+ if ( items1 == items2 )
+ return True;
+ for( i = numItems1; --i >= 0; )
+ if ( !PtrsEqual( *items1++ , *items2++ ) )
+ return False;
+ return True;
}
-static void
-xkl_config_rec_class_init(XklConfigRecClass * klass)
+static Bool _XklGetDefaultNamesProp( char **rulesFileOut, XklConfigRecPtr data )
{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) klass;
- parent_class = g_type_class_peek_parent(object_class);
- object_class->finalize = xkl_config_rec_finalize;
-}
-
-XklConfigRec *
-xkl_config_rec_new(void)
-{
- return
- XKL_CONFIG_REC(g_object_new(xkl_config_rec_get_type(), NULL));
-}
-
-static gboolean
-xkl_strings_equal(gchar * p1, gchar * p2)
-{
- if (p1 == p2)
- return TRUE;
- if ((p1 == NULL && p2 != NULL) || (p1 != NULL && p2 == NULL))
- return FALSE;
- return !g_ascii_strcasecmp(p1, p2);
+ if ( rulesFileOut != NULL )
+ *rulesFileOut = strdup( XKB_DEFAULT_RULESET );
+ data->model = strdup( xklVTable->defaultModel );
+/* keeping Nvariants = Nlayouts */
+ data->numLayouts = data->numVariants = 1;
+ data->layouts = malloc( sizeof( char * ) );
+ data->layouts[0] = strdup( xklVTable->defaultLayout );
+ data->variants = malloc( sizeof( char * ) );
+ data->variants[0] = strdup( "" );
+ data->numOptions = 0;
+ data->options = NULL;
+ return True;
}
-static gboolean
-xkl_lists_equal(gchar ** items1, gchar ** items2)
+Bool _XklConfigGetFullFromServer( char **rulesFileOut, XklConfigRecPtr data )
{
- if (items1 == items2)
- return TRUE;
-
- if ((items1 == NULL && items2 != NULL) ||
- (items1 != NULL && items2 == NULL))
- return FALSE;
+ Bool rv =
+ XklGetNamesProp( xklVTable->baseConfigAtom, rulesFileOut, data );
- while (*items1 != NULL && *items2 != NULL)
- if (!xkl_strings_equal(*items1++, *items2++))
- return FALSE;
+ if( !rv )
+ rv = _XklGetDefaultNamesProp( rulesFileOut, data );
- return (*items1 == NULL && *items2 == NULL);
+ return rv;
}
-static gboolean
-xkl_engine_get_default_names_prop(XklEngine * engine,
- char **rules_file_out,
- XklConfigRec * data)
+Bool XklConfigRecEquals( XklConfigRecPtr data1, XklConfigRecPtr data2 )
{
- if (rules_file_out != NULL)
- *rules_file_out = g_strdup(XKB_DEFAULT_RULESET);
- data->model = g_strdup(xkl_engine_priv(engine, default_model));
-/* keeping Nvariants = Nlayouts */
- data->layouts = g_new0(char *, 2);
- data->layouts[0] =
- g_strdup(xkl_engine_priv(engine, default_layout));
- data->variants = g_new0(char *, 2);
- data->variants[0] = g_strdup("");
- data->options = NULL;
- return TRUE;
+ if ( data1 == data2 )
+ return True;
+ if ( !PtrsEqual( data1->model, data2->model ) )
+ return False;
+ if ( !ListsEqual( data1->numLayouts, data1->layouts,
+ data2->numLayouts, data2->layouts ) )
+ return False;
+ if ( !ListsEqual( data1->numVariants, data1->variants,
+ data2->numVariants, data2->variants ) )
+ return False;
+ return ListsEqual( data1->numOptions, data1->options,
+ data2->numOptions, data2->options );
}
-gboolean
-xkl_config_rec_get_full_from_server(char **rules_file_out,
- XklConfigRec * data,
- XklEngine * engine)
+void XklConfigRecDestroy( XklConfigRecPtr data )
{
- gboolean rv = xkl_config_rec_get_from_root_window_property(data,
- xkl_engine_priv
- (engine,
- base_config_atom),
- rules_file_out,
- engine);
-
- if (!rv)
- rv = xkl_engine_get_default_names_prop(engine,
- rules_file_out,
- data);
-
- return rv;
+ int i;
+ char **p;
+
+ if( data->model != NULL )
+ free( data->model );
+
+ if( ( p = data->layouts ) != NULL )
+ {
+ for( i = data->numLayouts; --i >= 0; )
+ free( *p++ );
+ free( data->layouts );
+ }
+
+ if( ( p = data->variants ) != NULL )
+ {
+ for( i = data->numVariants; --i >= 0; )
+ free( *p++ );
+ free( data->variants );
+ }
+
+ if( ( p = data->options ) != NULL )
+ {
+ for( i = data->numOptions; --i >= 0; )
+ free( *p++ );
+ free( data->options );
+ }
}
-gboolean
-xkl_config_rec_equals(XklConfigRec * data1, XklConfigRec * data2)
+void XklConfigRecReset( XklConfigRecPtr data )
{
- if (data1 == data2)
- return TRUE;
- if (!xkl_strings_equal(data1->model, data2->model))
- return FALSE;
- if (!xkl_lists_equal(data1->layouts, data2->layouts))
- return FALSE;
- if (!xkl_lists_equal(data1->variants, data2->variants))
- return FALSE;
- return xkl_lists_equal(data1->options, data2->options);
+ XklConfigRecDestroy( data );
+ XklConfigRecInit( data );
}
-void
-xkl_config_rec_init(XklConfigRec * data)
+Bool XklConfigGetFromServer( XklConfigRecPtr data )
{
- /* clear the structure VarDefsPtr... */
- data->model = NULL;
- data->layouts = data->variants = data->options = NULL;
+ return _XklConfigGetFullFromServer( NULL, data );
}
-void
-xkl_config_rec_destroy(XklConfigRec * data)
+Bool XklConfigGetFromBackup( XklConfigRecPtr data )
{
- if (data->model != NULL)
- g_free(data->model);
+ Bool rv =
+ XklGetNamesProp( xklVTable->backupConfigAtom, NULL, data );
- g_strfreev(data->layouts);
- g_strfreev(data->variants);
- g_strfreev(data->options);
- data->layouts = data->variants = data->options = NULL;
+ return rv;
}
-void
-xkl_config_rec_reset(XklConfigRec * data)
+Bool XklBackupNamesProp( void )
{
- xkl_config_rec_destroy(data);
- xkl_config_rec_init(data);
-}
+ Bool rv = True;
+ char *rf = NULL;
+ XklConfigRec data;
+ Bool cgp = False;
+
+ XklConfigRecInit( &data );
+ if( XklGetNamesProp
+ ( xklVTable->backupConfigAtom, NULL, &data ) )
+ {
+ XklConfigRecDestroy( &data );
+ return True;
+ }
+ /* "backup" property is not defined */
+ XklConfigRecReset( &data );
+ cgp = _XklConfigGetFullFromServer( &rf, &data );
+
+ if ( cgp )
+ {
+#if 0
+ int i;
+ XklDebug( 150, "Original model: [%s]\n", data.model );
-gboolean
-xkl_config_rec_get_from_server(XklConfigRec * data, XklEngine * engine)
-{
- return xkl_config_rec_get_full_from_server(NULL, data, engine);
-}
+ XklDebug( 150, "Original layouts(%d):\n", data.numLayouts );
+ for( i = data.numLayouts; --i >= 0; )
+ XklDebug( 150, "%d: [%s]\n", i, data.layouts[i] );
-gboolean
-xkl_config_rec_get_from_backup(XklConfigRec * data, XklEngine * engine)
-{
- return xkl_config_rec_get_from_root_window_property(data,
- xkl_engine_priv
- (engine,
- backup_config_atom),
- NULL, engine);
-}
+ XklDebug( 150, "Original variants(%d):\n", data.numVariants );
+ for( i = data.numVariants; --i >= 0; )
+ XklDebug( 150, "%d: [%s]\n", i, data.variants[i] );
-gboolean
-xkl_backup_names_prop(XklEngine * engine)
-{
- gboolean rv = TRUE;
- gchar *rf = NULL;
- XklConfigRec data;
- gboolean cgp = FALSE;
-
- xkl_config_rec_init(&data);
- if (xkl_config_rec_get_from_root_window_property
- (&data, xkl_engine_priv(engine, backup_config_atom), NULL,
- engine)) {
- xkl_config_rec_destroy(&data);
- return TRUE;
- }
- /* "backup" property is not defined */
- xkl_config_rec_reset(&data);
- cgp = xkl_config_rec_get_full_from_server(&rf, &data, engine);
-
- if (cgp) {
- if (!xkl_config_rec_set_to_root_window_property
- (&data, xkl_engine_priv(engine, backup_config_atom),
- rf, engine)) {
- xkl_debug(150,
- "Could not backup the configuration");
- rv = FALSE;
- }
- if (rf != NULL)
- g_free(rf);
- } else {
- xkl_debug(150,
- "Could not get the configuration for backup");
- rv = FALSE;
- }
- xkl_config_rec_destroy(&data);
- return rv;
+ XklDebug( 150, "Original options(%d):\n", data.numOptions );
+ for( i = data.numOptions; --i >= 0; )
+ XklDebug( 150, "%d: [%s]\n", i, data.options[i] );
+#endif
+ if( !XklSetNamesProp( xklVTable->backupConfigAtom, rf, &data ) )
+ {
+ XklDebug( 150, "Could not backup the configuration" );
+ rv = False;
+ }
+ if( rf != NULL )
+ free( rf );
+ } else
+ {
+ XklDebug( 150, "Could not get the configuration for backup" );
+ rv = False;
+ }
+ XklConfigRecDestroy( &data );
+ return rv;
}
-gboolean
-xkl_restore_names_prop(XklEngine * engine)
+Bool XklRestoreNamesProp( void )
{
- gboolean rv = TRUE;
- gchar *rf = NULL;
- XklConfigRec data;
-
- xkl_config_rec_init(&data);
- if (!xkl_config_rec_get_from_root_window_property
- (&data, xkl_engine_priv(engine, backup_config_atom), NULL,
- engine)) {
- xkl_config_rec_destroy(&data);
- return FALSE;
- }
-
- if (!xkl_config_rec_set_to_root_window_property
- (&data, xkl_engine_priv(engine, base_config_atom), rf,
- engine)) {
- xkl_debug(150, "Could not backup the configuration");
- rv = FALSE;
- }
- xkl_config_rec_destroy(&data);
- return rv;
+ Bool rv = True;
+ char *rf = NULL;
+ XklConfigRec data;
+
+ XklConfigRecInit( &data );
+ if( !XklGetNamesProp( xklVTable->backupConfigAtom, NULL, &data ) )
+ {
+ XklConfigRecDestroy( &data );
+ return False;
+ }
+
+ if( !XklSetNamesProp( xklVTable->baseConfigAtom, rf, &data ) )
+ {
+ XklDebug( 150, "Could not backup the configuration" );
+ rv = False;
+ }
+ XklConfigRecDestroy( &data );
+ return rv;
}
-gboolean
-xkl_config_rec_get_from_root_window_property(XklConfigRec * data,
- Atom rules_atom,
- gchar ** rules_file_out,
- XklEngine * engine)
+Bool XklGetNamesProp( Atom rulesAtom,
+ char **rulesFileOut, XklConfigRecPtr data )
{
- Atom real_prop_type;
- int fmt;
- unsigned long nitems, extra_bytes;
- char *prop_data = NULL, *out;
- Status rtrn;
-
- /* no such atom! */
- if (rules_atom == None) { /* property cannot exist */
- xkl_last_error_message = "Could not find the atom";
- return FALSE;
- }
-
- rtrn =
- XGetWindowProperty(xkl_engine_get_display(engine),
- xkl_engine_priv(engine, root_window),
- rules_atom, 0L, XKB_RF_NAMES_PROP_MAXLEN,
- False, XA_STRING, &real_prop_type, &fmt,
- &nitems, &extra_bytes,
- (unsigned char **) (void *) &prop_data);
- /* property not found! */
- if (rtrn != Success) {
- xkl_last_error_message = "Could not get the property";
- return FALSE;
- }
- /* set rules file to "" */
- if (rules_file_out)
- *rules_file_out = NULL;
-
- /* has to be array of strings */
- if ((extra_bytes > 0) || (real_prop_type != XA_STRING)
- || (fmt != 8)) {
- if (prop_data)
- XFree(prop_data);
- xkl_last_error_message = "Wrong property format";
- return FALSE;
- }
-
- if (!prop_data) {
- xkl_last_error_message = "No properties returned";
- return FALSE;
- }
-
- /* rules file */
- out = prop_data;
- if (out && (*out) && rules_file_out)
- *rules_file_out = g_strdup(out);
- out += strlen(out) + 1;
-
- /* if user is interested in rules only - don't waste the time */
- if (!data) {
- XFree(prop_data);
- return TRUE;
- }
-
- if ((out - prop_data) < nitems) {
- if (*out)
- data->model = g_strdup(out);
- out += strlen(out) + 1;
- }
-
- if ((out - prop_data) < nitems) {
- xkl_config_rec_split_layouts(data, out);
- out += strlen(out) + 1;
- }
-
- if ((out - prop_data) < nitems) {
- gint nv, nl;
- gchar **layout, **variant;
- xkl_config_rec_split_variants(data, out);
- /*
- Now have to ensure that number of variants matches the number of layouts
- The 'remainder' is filled with NULLs (not ""s!)
- */
-
- nv = g_strv_length(data->variants);
- nl = g_strv_length(data->layouts);
- if (nv < nl) {
- data->variants = g_realloc(data->variants,
- (nl +
- 1) * sizeof(char *));
- memset(data->variants + nv + 1, 0,
- (nl - nv) * sizeof(char *));
- }
- /* take variants from layouts like ru(winkeys) */
- layout = data->layouts;
- variant = data->variants;
- while (*layout != NULL && *variant != NULL) {
- gchar *varstart = g_strstr_len(*layout, -1, "(");
- if (varstart != NULL) {
- gchar *varend =
- g_strstr_len(varstart, -1, ")");
- if (varend != NULL) {
- gint varlen = varend - varstart;
- gint laylen = varstart - *layout;
- /* I am not sure - but I assume variants in layout have priority */
- gchar *var = *variant =
- (*variant !=
- NULL) ? g_realloc(*variant,
- varlen) :
- g_new(gchar, varlen);
- memcpy(var, varstart + 1,
- --varlen);
- var[varlen] = '\0';
- /* Resize the original layout */
- ((char *)
- g_realloc(*layout,
- laylen + 1))[laylen] =
- '\0';
- }
- }
- layout++;
- variant++;
- }
- out += strlen(out) + 1;
- }
-
- if ((out - prop_data) < nitems) {
- xkl_config_rec_split_options(data, out);
- }
- XFree(prop_data);
- return TRUE;
+ Atom realPropType;
+ int fmt;
+ unsigned long nitems, extraBytes;
+ char *propData = NULL, *out;
+ Status rtrn;
+
+ /* no such atom! */
+ if( rulesAtom == None ) /* property cannot exist */
+ {
+ _xklLastErrorMsg = "Could not find the atom";
+ return False;
+ }
+
+ rtrn =
+ XGetWindowProperty( _xklDpy, _xklRootWindow, rulesAtom, 0L,
+ _XKB_RF_NAMES_PROP_MAXLEN, False, XA_STRING,
+ &realPropType, &fmt, &nitems, &extraBytes,
+ ( unsigned char ** ) ( void * ) &propData );
+ /* property not found! */
+ if( rtrn != Success )
+ {
+ _xklLastErrorMsg = "Could not get the property";
+ return False;
+ }
+ /* set rules file to "" */
+ if( rulesFileOut )
+ *rulesFileOut = NULL;
+
+ /* has to be array of strings */
+ if( ( extraBytes > 0 ) || ( realPropType != XA_STRING ) || ( fmt != 8 ) )
+ {
+ if( propData )
+ XFree( propData );
+ _xklLastErrorMsg = "Wrong property format";
+ return False;
+ }
+
+ if( !propData )
+ {
+ _xklLastErrorMsg = "No properties returned";
+ return False;
+ }
+
+ /* rules file */
+ out = propData;
+ if( out && ( *out ) && rulesFileOut )
+ *rulesFileOut = strdup( out );
+ out += strlen( out ) + 1;
+
+ /* if user is interested in rules only - don't waste the time */
+ if( !data )
+ {
+ XFree( propData );
+ return True;
+ }
+
+ if( ( out - propData ) < nitems )
+ {
+ if( *out )
+ data->model = strdup( out );
+ out += strlen( out ) + 1;
+ }
+
+ if( ( out - propData ) < nitems )
+ {
+ _XklConfigRecSplitLayouts( data, out );
+ out += strlen( out ) + 1;
+ }
+
+ if( ( out - propData ) < nitems )
+ {
+ int i;
+ char **theLayout, **theVariant;
+ _XklConfigRecSplitVariants( data, out );
+ /*
+ Now have to ensure that number of variants matches the number of layouts
+ The 'remainder' is filled with NULLs (not ""s!)
+ */
+ if( data->numVariants < data->numLayouts )
+ {
+ data->variants =
+ realloc( data->variants, data->numLayouts * sizeof( char * ) );
+ memset( data->variants + data->numVariants, 0,
+ ( data->numLayouts - data->numVariants ) * sizeof( char * ) );
+ data->numVariants = data->numLayouts;
+ }
+ /* take variants from layouts like ru(winkeys) */
+ theLayout = data->layouts;
+ theVariant = data->variants;
+ for( i = data->numLayouts; --i >= 0; theLayout++, theVariant++ )
+ {
+ if( *theLayout != NULL )
+ {
+ char *varstart = strchr( *theLayout, '(' );
+ if( varstart != NULL )
+ {
+ char *varend = strchr( varstart, ')' );
+ if( varend != NULL )
+ {
+ int varlen = varend - varstart;
+ int laylen = varstart - *theLayout;
+ /* I am not sure - but I assume variants in layout have priority */
+ char *var = *theVariant = ( *theVariant != NULL ) ?
+ realloc( *theVariant, varlen ) : malloc( varlen );
+ memcpy( var, varstart + 1, --varlen );
+ var[varlen] = '\0';
+
+ ( (char*)realloc( *theLayout, laylen + 1 ) )[laylen] = '\0';
+ }
+ }
+ }
+ }
+ out += strlen( out ) + 1;
+ }
+
+ if( ( out - propData ) < nitems )
+ {
+ _XklConfigRecSplitOptions( data, out );
+/* out += strlen( out ) + 1; */
+ }
+ XFree( propData );
+ return True;
}
/* taken from XFree86 maprules.c */
-gboolean
-xkl_config_rec_set_to_root_window_property(const XklConfigRec * data,
- Atom rules_atom,
- gchar * rules_file,
- XklEngine * engine)
+Bool XklSetNamesProp( Atom rulesAtom,
+ char *rulesFile, const XklConfigRecPtr data )
{
- gint len, rv;
- gchar *pval;
- gchar *next;
- gchar *all_layouts = xkl_config_rec_merge_layouts(data);
- gchar *all_variants = xkl_config_rec_merge_variants(data);
- gchar *all_options = xkl_config_rec_merge_options(data);
-
- len = (rules_file ? strlen(rules_file) : 0);
- len += (data->model ? strlen(data->model) : 0);
- len += (all_layouts ? strlen(all_layouts) : 0);
- len += (all_variants ? strlen(all_variants) : 0);
- len += (all_options ? strlen(all_options) : 0);
- if (len < 1)
- return TRUE;
-
- len += 5; /* trailing NULs */
-
- pval = next = g_new(char, len + 1);
- if (!pval) {
- xkl_last_error_message = "Could not allocate buffer";
- if (all_layouts != NULL)
- g_free(all_layouts);
- if (all_variants != NULL)
- g_free(all_variants);
- if (all_options != NULL)
- g_free(all_options);
- return FALSE;
- }
- if (rules_file) {
- strcpy(next, rules_file);
- next += strlen(rules_file);
- }
- *next++ = '\0';
- if (data->model) {
- strcpy(next, data->model);
- next += strlen(data->model);
- }
- *next++ = '\0';
- if (data->layouts) {
- strcpy(next, all_layouts);
- next += strlen(all_layouts);
- }
- *next++ = '\0';
- if (data->variants) {
- strcpy(next, all_variants);
- next += strlen(all_variants);
- }
- *next++ = '\0';
- if (data->options) {
- strcpy(next, all_options);
- next += strlen(all_options);
- }
- *next++ = '\0';
- if ((next - pval) != len) {
- xkl_debug(150, "Illegal final position: %d/%d\n",
- (next - pval), len);
- if (all_layouts != NULL)
- g_free(all_layouts);
- if (all_variants != NULL)
- g_free(all_variants);
- if (all_options != NULL)
- g_free(all_options);
- g_free(pval);
- xkl_last_error_message = "Internal property parsing error";
- return FALSE;
- }
-
- Display *display = xkl_engine_get_display(engine);
- rv = XChangeProperty(display, xkl_engine_priv(engine, root_window),
- rules_atom, XA_STRING, 8, PropModeReplace,
- (unsigned char *) pval, len);
- XSync(display, False);
+ int len, rv;
+ char *pval;
+ char *next;
+ char *allLayouts = _XklConfigRecMergeLayouts( data );
+ char *allVariants = _XklConfigRecMergeVariants( data );
+ char *allOptions = _XklConfigRecMergeOptions( data );
+
+ len = ( rulesFile ? strlen( rulesFile ) : 0 );
+ len += ( data->model ? strlen( data->model ) : 0 );
+ len += ( allLayouts ? strlen( allLayouts ) : 0 );
+ len += ( allVariants ? strlen( allVariants ) : 0 );
+ len += ( allOptions ? strlen( allOptions ) : 0 );
+ if( len < 1 ) {
+ if( allLayouts ) free( allLayouts );
+ if( allVariants ) free( allVariants );
+ if( allOptions ) free( allOptions );
+ return True;
+ }
+
+ len += 5; /* trailing NULs */
+
+ pval = next = ( char * ) malloc( len + 1 );
+ if( !pval )
+ {
+ _xklLastErrorMsg = "Could not allocate buffer";
+ if ( allLayouts != NULL ) free( allLayouts );
+ if ( allVariants != NULL ) free( allVariants );
+ if ( allOptions != NULL ) free( allOptions );
+ return False;
+ }
+ if( rulesFile )
+ {
+ strcpy( next, rulesFile );
+ next += strlen( rulesFile );
+ }
+ *next++ = '\0';
+ if( data->model )
+ {
+ strcpy( next, data->model );
+ next += strlen( data->model );
+ }
+ *next++ = '\0';
+ if( data->layouts )
+ {
+ strcpy( next, allLayouts );
+ next += strlen( allLayouts );
+ }
+ *next++ = '\0';
+ if( data->variants )
+ {
+ strcpy( next, allVariants );
+ next += strlen( allVariants );
+ }
+ *next++ = '\0';
+ if( data->options )
+ {
+ strcpy( next, allOptions );
+ next += strlen( allOptions );
+ }
+ *next++ = '\0';
+ if( ( next - pval ) != len )
+ {
+ XklDebug( 150, "Illegal final position: %d/%d\n", ( next - pval ), len );
+ if ( allLayouts != NULL ) free( allLayouts );
+ if ( allVariants != NULL ) free( allVariants );
+ if ( allOptions != NULL ) free( allOptions );
+ free( pval );
+ _xklLastErrorMsg = "Internal property parsing error";
+ return False;
+ }
+
+ rv = XChangeProperty( _xklDpy, _xklRootWindow, rulesAtom, XA_STRING, 8,
+ PropModeReplace, ( unsigned char * ) pval, len );
+ XSync( _xklDpy, False );
#if 0
- for (i = len - 1; --i >= 0;)
- if (pval[i] == '\0')
- pval[i] = '?';
- XklDebug(150, "Stored [%s] of length %d to [%s] of %X: %d\n", pval,
- len, propName, _xklRootWindow, rv);
+ for( i = len - 1; --i >= 0; )
+ if( pval[i] == '\0' )
+ pval[i] = '?';
+ XklDebug( 150, "Stored [%s] of length %d to [%s] of %X: %d\n", pval, len,
+ propName, _xklRootWindow, rv );
#endif
- if (all_layouts != NULL)
- g_free(all_layouts);
- if (all_variants != NULL)
- g_free(all_variants);
- if (all_options != NULL)
- g_free(all_options);
- g_free(pval);
- return TRUE;
+ if ( allLayouts != NULL ) free( allLayouts );
+ if ( allVariants != NULL ) free( allVariants );
+ if ( allOptions != NULL ) free( allOptions );
+ free( pval );
+ return True;
}