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; } }
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 gboolean fetch_string (XSettingsBuffer *buffer, guint length, char **result) { guint pad_len; pad_len = XSETTINGS_PAD (length, 4); if (pad_len < length) /* guard against overflow */ { g_warning ("Invalid XSETTINGS property (overflow in string length)"); return FALSE; } return_if_fail_bytes (buffer, pad_len); *result = g_strndup ((char *) buffer->pos, length); buffer->pos += pad_len; return TRUE; }
static void xfce_xsettings_helper_setting_append (const gchar *name, XfceXSetting *setting, XfceXSettingsNotify *notify) { gsize buf_len, new_len; gsize name_len, name_len_pad; gsize value_len, value_len_pad; const gchar *str = NULL; guchar *needle; guchar type = 0; gint num; name_len = strlen (name) - 1 /* -1 for the xfconf slash */; name_len_pad = XSETTINGS_PAD (name_len, 4); buf_len = 8 + name_len_pad; value_len_pad = value_len = 0; /* get the total size of this setting */ switch (G_VALUE_TYPE (setting->value)) { case G_TYPE_INT: case G_TYPE_BOOLEAN: type = XSettingsTypeInteger; buf_len += 4; break; case G_TYPE_STRING: type = XSettingsTypeString; buf_len += 4; str = g_value_get_string (setting->value); if (str != NULL) { value_len = strlen (str); value_len_pad = XSETTINGS_PAD (value_len, 4); buf_len += value_len_pad; } break; case G_TYPE_INT64 /* TODO */: type = XSettingsTypeColor; buf_len += 8; break; default: g_assert_not_reached (); break; } /* additional length for this setting */ new_len = notify->buf_len + buf_len; /* resize the buffer to fit this setting */ notify->buf = g_renew (guchar, notify->buf, new_len); if (G_UNLIKELY (notify->buf == NULL)) return; needle = notify->buf + notify->buf_len; notify->buf_len = new_len; /* setting record: * * 1 SETTING_TYPE type * 1 unused * 2 n name-len * n STRING8 name * P unused, p=pad(n) * 4 CARD32 last-change-serial */ /* setting type */ *needle++ = type; /* unused */ *needle++ = 0; /* name length */ *(CARD16 *)needle = name_len; needle += 2; /* name */ memcpy (needle, name + 1 /* +1 for the xfconf slash */, name_len); needle += name_len; /* zero the padding */ for (; name_len_pad > name_len; name_len_pad--) *needle++ = 0; /* setting's last change serial */ *(CARD32 *)needle = setting->last_change_serial; needle += 4; /* set setting value */ switch (type) { case XSettingsTypeString: /* body for XSettingsTypeString: * * 4 n value-len * n STRING8 value * P unused, p=pad(n) */ if (G_LIKELY (value_len > 0 && str != NULL)) { /* value length */ *(CARD32 *)needle = value_len; needle += 4; /* value */ memcpy (needle, str, value_len); needle += value_len; /* zero the padding */ for (; value_len_pad > value_len; value_len_pad--) *needle++ = 0; } else { /* value length */ *(CARD32 *)needle = 0; needle += 4; } break; case XSettingsTypeInteger: /* Body for XSettingsTypeInteger: * * 4 INT32 value */ if (G_VALUE_TYPE (setting->value) == G_TYPE_INT) { num = g_value_get_int (setting->value); /* special case handling for DPI */ if (strcmp (name, "/Xft/DPI") == 0) { /* remember the offset for screen dependend dpi * or clamp the value and set 1/1024ths of an inch * for Xft */ if (num < 1) notify->dpi_offset = needle - notify->buf; else num = CLAMP (num, DPI_LOW_REASONABLE, DPI_HIGH_REASONABLE) * 1024; } } else { num = g_value_get_boolean (setting->value); } *(INT32 *)needle = num; needle += 4; break; /* TODO */ case XSettingsTypeColor: /* body for XSettingsTypeColor: * * 2 CARD16 red * 2 CARD16 blue * 2 CARD16 green * 2 CARD16 alpha */ *(CARD16 *)needle = 0; *(CARD16 *)(needle + 2) = 0; *(CARD16 *)(needle + 4) = 0; *(CARD16 *)(needle + 6) = 0; needle += 8; break; default: g_assert_not_reached (); break; } notify->n_settings++; }