PageRenderTime 118ms CodeModel.GetById 4ms app.highlight 100ms RepoModel.GetById 1ms app.codeStats 1ms

/libgxim/gximmisc.c

https://bitbucket.org/tagoh/libgxim
C | 3748 lines | 3086 code | 568 blank | 94 comment | 427 complexity | 9ea8c823d030f144d3f31c6845184b52 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
   2/* 
   3 * gximmisc.c
   4 * Copyright (C) 2008-2011 Akira TAGOH
   5 * 
   6 * Authors:
   7 *   Akira TAGOH  <akira@tagoh.org>
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation; either
  12 * version 2 of the License, or (at your option) any later version.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the
  21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth
  22 * Floor, Boston, MA  02110-1301  USA
  23 */
  24#ifdef HAVE_CONFIG_H
  25#include "config.h"
  26#endif
  27
  28#ifdef HAVE_STRING_H
  29#include <string.h>
  30#endif
  31#ifdef HAVE_STDINT_H
  32#include <stdint.h>
  33#endif
  34#include <gdk/gdkprivate.h>
  35#include <gdk/gdkkeysyms.h>
  36#include <gdk/gdkx.h>
  37#include "gximattr.h"
  38#include "gximerror.h"
  39#include "gximmessages.h"
  40#include "gximmisc.h"
  41#include "gximprotocol.h"
  42
  43#define N_REALLOC_NESTED_LIST	16
  44
  45static GXimMessages *master_message = NULL;
  46
  47/*
  48 * Private functions
  49 */
  50static gint
  51g_xim_gdkevent_translate_event_type(GdkEvent *event)
  52{
  53	switch (event->type) {
  54	    case GDK_NOTHING:
  55	    case GDK_DELETE:
  56		    goto unsupported;
  57	    case GDK_DESTROY:
  58		    return DestroyNotify;
  59	    case GDK_EXPOSE:
  60		    return Expose;
  61	    case GDK_MOTION_NOTIFY:
  62		    return MotionNotify;
  63	    case GDK_BUTTON_PRESS:
  64	    case GDK_2BUTTON_PRESS:
  65	    case GDK_3BUTTON_PRESS:
  66		    return ButtonPress;
  67	    case GDK_BUTTON_RELEASE:
  68		    return ButtonRelease;
  69	    case GDK_KEY_PRESS:
  70		    return KeyPress;
  71	    case GDK_KEY_RELEASE:
  72		    return KeyRelease;
  73	    case GDK_ENTER_NOTIFY:
  74		    return EnterNotify;
  75	    case GDK_LEAVE_NOTIFY:
  76		    return LeaveNotify;
  77	    case GDK_FOCUS_CHANGE:
  78		    if (event->focus_change.in)
  79			    return FocusIn;
  80		    else
  81			    return FocusOut;
  82	    case GDK_CONFIGURE:
  83		    return ConfigureNotify;
  84	    case GDK_MAP:
  85		    return MapNotify;
  86	    case GDK_UNMAP:
  87		    return UnmapNotify;
  88	    case GDK_PROPERTY_NOTIFY:
  89		    return PropertyNotify;
  90	    case GDK_SELECTION_CLEAR:
  91		    return SelectionClear;
  92	    case GDK_SELECTION_REQUEST:
  93		    return SelectionRequest;
  94	    case GDK_SELECTION_NOTIFY:
  95		    return SelectionNotify;
  96	    case GDK_PROXIMITY_IN:
  97	    case GDK_PROXIMITY_OUT:
  98	    case GDK_DRAG_ENTER:
  99	    case GDK_DRAG_LEAVE:
 100	    case GDK_DRAG_MOTION:
 101	    case GDK_DRAG_STATUS:
 102	    case GDK_DROP_START:
 103	    case GDK_DROP_FINISHED:
 104		    goto unsupported;
 105	    case GDK_CLIENT_EVENT:
 106		    return ClientMessage;
 107	    case GDK_VISIBILITY_NOTIFY:
 108		    return VisibilityNotify;
 109	    case GDK_NO_EXPOSE:
 110		    return NoExpose;
 111	    case GDK_SCROLL:
 112		    return ButtonPress;
 113	    case GDK_WINDOW_STATE:
 114	    case GDK_SETTING:
 115	    case GDK_OWNER_CHANGE:
 116	    case GDK_GRAB_BROKEN:
 117	    default:
 118	    unsupported:
 119		    break;
 120	}
 121
 122	return 0;
 123}
 124
 125static GdkEventType
 126g_xim_xevent_translate_event_type(gint type)
 127{
 128	switch (type & 0x7f) {
 129	    case KeyPress:
 130		    return GDK_KEY_PRESS;
 131	    case KeyRelease:
 132		    return GDK_KEY_RELEASE;
 133	    case ButtonPress:
 134		    return GDK_BUTTON_PRESS;
 135	    case ButtonRelease:
 136		    return GDK_BUTTON_RELEASE;
 137	    case MotionNotify:
 138		    return GDK_MOTION_NOTIFY;
 139	    case EnterNotify:
 140		    return GDK_ENTER_NOTIFY;
 141	    case LeaveNotify:
 142		    return GDK_LEAVE_NOTIFY;
 143	    case FocusIn:
 144	    case FocusOut:
 145		    return GDK_FOCUS_CHANGE;
 146	    case KeymapNotify:
 147		    goto unsupported;
 148	    case Expose:
 149	    case GraphicsExpose:
 150		    return GDK_EXPOSE;
 151	    case NoExpose:
 152		    return GDK_NO_EXPOSE;
 153	    case VisibilityNotify:
 154		    return GDK_VISIBILITY_NOTIFY;
 155	    case CreateNotify:
 156		    goto unsupported;
 157	    case DestroyNotify:
 158		    return GDK_DESTROY;
 159	    case UnmapNotify:
 160		    return GDK_UNMAP;
 161	    case MapNotify:
 162		    return GDK_MAP;
 163	    case MapRequest:
 164	    case ReparentNotify:
 165		    goto unsupported;
 166	    case ConfigureNotify:
 167		    return GDK_CONFIGURE;
 168	    case ConfigureRequest:
 169	    case GravityNotify:
 170	    case ResizeRequest:
 171	    case CirculateNotify:
 172	    case CirculateRequest:
 173		    goto unsupported;
 174	    case PropertyNotify:
 175		    return GDK_PROPERTY_NOTIFY;
 176	    case SelectionClear:
 177		    return GDK_SELECTION_CLEAR;
 178	    case SelectionRequest:
 179		    return GDK_SELECTION_REQUEST;
 180	    case SelectionNotify:
 181		    return GDK_SELECTION_NOTIFY;
 182	    case ColormapNotify:
 183		    goto unsupported;
 184	    case ClientMessage:
 185		    return GDK_CLIENT_EVENT;
 186	    case MappingNotify:
 187		    goto unsupported;
 188	    default:
 189	    unsupported:
 190		    break;
 191	}
 192
 193	return GDK_NOTHING;
 194}
 195
 196static const gchar *
 197g_xim_gdkevent_type_name(gint type)
 198{
 199	static const gchar *event_names =
 200		"\0"
 201		"KeyPress\0"
 202		"KeyRelease\0"
 203		"ButtonPress\0"
 204		"ButtonRelease\0"
 205		"MotionNotify\0"
 206		"EnterNotify\0"
 207		"LeaveNotify\0"
 208		"FocusIn\0"
 209		"FocusOut\0"
 210		"KeymapNotify\0"
 211		"Expose\0"
 212		"GraphicsExpose\0"
 213		"NoExpose\0"
 214		"VisibilityNotify\0"
 215		"CreateNotify\0"
 216		"DestroyNotify\0"
 217		"UnmapNotify\0"
 218		"MapNotify\0"
 219		"ReparentNotify\0"
 220		"ConfigureNotify\0"
 221		"ConfigureRequest\0"
 222		"GravityNotify\0"
 223		"ResizeRequest\0"
 224		"CirculateNotify\0"
 225		"CirculateRequest\0"
 226		"PropertyNotify\0"
 227		"SelectionClear\0"
 228		"SelectionRequest\0"
 229		"SelectionNotify\0"
 230		"ColormapNotify\0"
 231		"ClientMessage\0"
 232		"MappingNotify\0";
 233	static guint type2pos[LASTEvent];
 234	static gboolean initialized = FALSE;
 235
 236	if (!initialized) {
 237		memset(type2pos, 0, sizeof (guint) * (LASTEvent - 1));
 238		type2pos[KeyPress] = 1;
 239		type2pos[KeyRelease] = 10;
 240		type2pos[ButtonPress] = 21;
 241		type2pos[ButtonRelease] = 33;
 242		type2pos[MotionNotify] = 47;
 243		type2pos[EnterNotify] = 60;
 244		type2pos[LeaveNotify] = 72;
 245		type2pos[FocusIn] = 84;
 246		type2pos[FocusOut] = 92;
 247		type2pos[KeymapNotify] = 101;
 248		type2pos[Expose] = 114;
 249		type2pos[GraphicsExpose] = 121;
 250		type2pos[NoExpose] = 136;
 251		type2pos[VisibilityNotify] = 145;
 252		type2pos[CreateNotify] = 162;
 253		type2pos[DestroyNotify] = 175;
 254		type2pos[UnmapNotify] = 189;
 255		type2pos[MapNotify] = 201;
 256		type2pos[MapRequest] = 211;
 257		type2pos[ReparentNotify] = 226;
 258		type2pos[ConfigureNotify] = 242;
 259		type2pos[ConfigureRequest] = 259;
 260		type2pos[GravityNotify] = 273;
 261		type2pos[ResizeRequest] = 287;
 262		type2pos[CirculateNotify] = 303;
 263		type2pos[CirculateRequest] = 320;
 264		type2pos[PropertyNotify] = 335;
 265		type2pos[SelectionClear] = 350;
 266		type2pos[SelectionRequest] = 367;
 267		type2pos[SelectionNotify] = 383;
 268		type2pos[ColormapNotify] = 398;
 269		type2pos[ClientMessage] = 412;
 270		type2pos[MappingNotify] = 426;
 271
 272		initialized = TRUE;
 273	}
 274
 275	return (&event_names[type2pos[type]])[0] == 0 ? "<UnknownEvent>" : &event_names[type2pos[type]];
 276}
 277
 278static GXimNestedListNode *
 279g_xim_nested_list_node_new(void)
 280{
 281	GXimNestedListNode *retval;
 282
 283	retval = g_new0(GXimNestedListNode, 1);
 284	G_XIM_CHECK_ALLOC (retval, NULL);
 285
 286	retval->vtype = G_XIM_TYPE_INVALID;
 287
 288	return retval;
 289}
 290
 291static GXimNestedListNode *
 292g_xim_nested_list_node_copy(GXimNestedListNode *node)
 293{
 294	GXimNestedListNode *retval;
 295	GType gtype;
 296
 297	g_return_val_if_fail (node != NULL, NULL);
 298
 299	gtype = g_xim_value_type_to_gtype(node->vtype);
 300	g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL);
 301
 302	retval = g_xim_nested_list_node_new();
 303	retval->vtype = node->vtype;
 304	retval->name = g_strdup(node->name);
 305	retval->value = g_xim_copy_by_gtype(gtype, node->value);
 306
 307	return retval;
 308}
 309
 310static void
 311g_xim_nested_list_node_free(GXimNestedListNode *node)
 312{
 313	GType gtype;
 314
 315	if (node == NULL)
 316		return;
 317
 318	gtype = g_xim_value_type_to_gtype(node->vtype);
 319	if (gtype == G_TYPE_INVALID)
 320		g_warning("Invalid NestedList node for %s to be freed", node->name);
 321	g_free(node->name);
 322	g_xim_free_by_gtype(gtype, node->value);
 323
 324	g_free(node);
 325}
 326
 327/*
 328 * Public functions
 329 */
 330void
 331g_xim_init(void)
 332{
 333	const gchar *env;
 334	gchar **tokens;
 335	gint i;
 336
 337	if (master_message == NULL) {
 338		master_message = g_xim_messages_new();
 339		G_XIM_CHECK_ALLOC_WITH_NO_RET (master_message);
 340
 341		g_object_set(G_OBJECT (master_message), "master", TRUE, NULL);
 342	}
 343	env = g_getenv("LIBGXIM_DEBUG");
 344	if (env) {
 345		tokens = g_strsplit(env, ",", 0);
 346		for (i = 0; tokens && tokens[i] != NULL; i++) {
 347			g_xim_messages_enable_filter(master_message, tokens[i]);
 348		}
 349		g_xim_messages_activate(master_message, TRUE);
 350	}
 351}
 352
 353void
 354g_xim_finalize(void)
 355{
 356	g_object_unref(master_message);
 357}
 358
 359GDataStreamByteOrder
 360g_xim_get_byte_order(void)
 361{
 362	gint i = 1;
 363	gchar *p = (gchar *)&i;
 364
 365	if (*p == 1)
 366		return G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
 367
 368	return G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
 369}
 370
 371GXimValueType
 372g_xim_gtype_to_value_type(GType gtype)
 373{
 374	switch (gtype) {
 375	    case G_TYPE_CHAR:
 376	    case G_TYPE_UCHAR:
 377		    return G_XIM_TYPE_BYTE;
 378	    case G_TYPE_INT:
 379	    case G_TYPE_UINT:
 380		    return G_XIM_TYPE_WORD;
 381	    case G_TYPE_LONG:
 382	    case G_TYPE_ULONG:
 383		    return G_XIM_TYPE_LONG;
 384	    case G_TYPE_STRING:
 385		    return G_XIM_TYPE_CHAR;
 386	    case G_TYPE_BOXED:
 387	    default:
 388		    if (g_type_is_a(gtype, G_TYPE_XIM_STYLES)) {
 389			    return G_XIM_TYPE_XIMSTYLES;
 390		    } else if (g_type_is_a(gtype, GDK_TYPE_WINDOW)) {
 391			    return G_XIM_TYPE_WINDOW;
 392		    } else if (g_type_is_a(gtype, G_TYPE_XIM_NESTEDLIST)) {
 393			    return G_XIM_TYPE_NESTEDLIST;
 394		    } else if (g_type_is_a(gtype, G_TYPE_XIM_RECTANGLE)) {
 395			    return G_XIM_TYPE_XRECTANGLE;
 396		    } else if (g_type_is_a(gtype, G_TYPE_XIM_POINT)) {
 397			    return G_XIM_TYPE_XPOINT;
 398		    } else if (g_type_is_a(gtype, G_TYPE_XIM_FONTSET)) {
 399			    return G_XIM_TYPE_XFONTSET;
 400		    } else if (g_type_is_a(gtype, G_TYPE_XIM_SEP_NESTEDLIST)) {
 401			    return G_XIM_TYPE_SEPARATOR;
 402		    }
 403
 404		    g_warning("Unsupported object type: %s",
 405			      g_type_name(gtype));
 406		    break;
 407	}
 408
 409	return G_XIM_TYPE_INVALID;
 410}
 411
 412GType
 413g_xim_value_type_to_gtype(GXimValueType vtype)
 414{
 415	switch (vtype) {
 416	    case G_XIM_TYPE_SEPARATOR:
 417		    return G_TYPE_XIM_SEP_NESTEDLIST;
 418	    case G_XIM_TYPE_BYTE:
 419		    return G_TYPE_UCHAR;
 420	    case G_XIM_TYPE_WORD:
 421		    return G_TYPE_UINT;
 422	    case G_XIM_TYPE_LONG:
 423		    return G_TYPE_ULONG;
 424	    case G_XIM_TYPE_CHAR:
 425		    return G_TYPE_STRING;
 426	    case G_XIM_TYPE_WINDOW:
 427		    return GDK_TYPE_WINDOW;
 428	    case G_XIM_TYPE_XIMSTYLES:
 429		    return G_TYPE_XIM_STYLES;
 430	    case G_XIM_TYPE_XRECTANGLE:
 431		    return G_TYPE_XIM_RECTANGLE;
 432	    case G_XIM_TYPE_XPOINT:
 433		    return G_TYPE_XIM_POINT;
 434	    case G_XIM_TYPE_XFONTSET:
 435		    return G_TYPE_XIM_FONTSET;
 436	    case G_XIM_TYPE_HOTKEYTRIGGERS:
 437	    case G_XIM_TYPE_HOTKEYSTATE:
 438	    case G_XIM_TYPE_STRINGCONVERSION:
 439	    case G_XIM_TYPE_PREEDITSTATE:
 440	    case G_XIM_TYPE_RESETSTATE:
 441		    break;
 442	    case G_XIM_TYPE_NESTEDLIST:
 443		    return G_TYPE_XIM_NESTEDLIST;
 444	    case G_XIM_TYPE_INVALID:
 445		    break;
 446	    case G_XIM_TYPE_PADDING:
 447	    case G_XIM_TYPE_AUTO_PADDING:
 448	    case G_XIM_TYPE_MARKER_N_BYTES_1:
 449	    case G_XIM_TYPE_MARKER_N_BYTES_2:
 450	    case G_XIM_TYPE_MARKER_N_BYTES_4:
 451	    case G_XIM_TYPE_MARKER_N_ITEMS_2:
 452		    break;
 453	    case G_XIM_TYPE_STR:
 454		    return G_TYPE_XIM_STR;
 455	    case G_XIM_TYPE_GSTRING:
 456		    return G_TYPE_GSTRING;
 457	    case G_XIM_TYPE_PREEDIT_CARET:
 458		    return G_TYPE_XIM_PREEDIT_CARET;
 459	    case G_XIM_TYPE_PREEDIT_DRAW:
 460		    return G_TYPE_XIM_PREEDIT_DRAW;
 461	    case G_XIM_TYPE_GDKEVENT:
 462		    return GDK_TYPE_EVENT;
 463	    case G_XIM_TYPE_XIMTEXT:
 464		    return G_TYPE_XIM_TEXT;
 465	    case G_XIM_TYPE_HOTKEY_TRIGGER:
 466		    return G_TYPE_XIM_HOTKEY_TRIGGER;
 467	    case G_XIM_TYPE_PIXMAP:
 468		    return GDK_TYPE_PIXMAP;
 469	    case G_XIM_TYPE_STATUS_DRAW:
 470		    return G_TYPE_XIM_STATUS_DRAW;
 471	    case G_XIM_TYPE_LIST_OF_IMATTR:
 472	    case G_XIM_TYPE_LIST_OF_ICATTR:
 473	    case G_XIM_TYPE_LIST_OF_IMATTRIBUTE:
 474	    case G_XIM_TYPE_LIST_OF_ICATTRIBUTE:
 475	    case G_XIM_TYPE_LIST_OF_EXT:
 476	    case G_XIM_TYPE_LIST_OF_STRING:
 477	    case G_XIM_TYPE_LIST_OF_STR:
 478	    case G_XIM_TYPE_LIST_OF_ENCODINGINFO:
 479	    case G_XIM_TYPE_LIST_OF_BYTE:
 480	    case G_XIM_TYPE_LIST_OF_CARD16:
 481	    case G_XIM_TYPE_LIST_OF_HOTKEY_TRIGGER:
 482	    default:
 483		    break;
 484	}
 485
 486	return G_TYPE_INVALID;
 487}
 488
 489const gchar *
 490g_xim_value_type_name(GXimValueType vtype)
 491{
 492	static const gchar vtype_name[] =
 493		"\0"
 494		"SeparatorofNestedList\0"
 495		"CARD8\0"
 496		"CARD16\0"
 497		"CARD32\0"
 498		"STRING8\0"
 499		"Window\0"
 500		"XIMStyles\0"
 501		"XRectangle\0"
 502		"XPoint\0"
 503		"XFontSet\0"
 504		"XIMHotKeyTriggers\0"
 505		"XIMHotKeyState\0"
 506		"XIMStringConversion\0"
 507		"XIMPreeditState\0"
 508		"XIMResetState\0"
 509		"NestedList\0"
 510		"<Invalid>\0"
 511		"Padding\0"
 512		"AutoPadding\0"
 513		"n-bytes-marker[CARD8]\0"
 514		"n-bytes-marker[CARD16]\0"
 515		"n-bytes-marker[CARD32]\0"
 516		"n-items-marker[CARD16]\0"
 517		"STR\0"
 518		"GString\0"
 519		"GXimPreeditCaret\0"
 520		"GXimPreeditDraw\0"
 521		"GdkEvent\0"
 522		"GXimText\0"
 523		"GXimHotkeyTrigger\0"
 524		"Pixmap\0"
 525		"GXimStatusDraw\0"
 526		"LISTofXIMATTR\0"
 527		"LISTofXICATTR\0"
 528		"LISTofXIMATTRIBUTE\0"
 529		"LISTofXICATTRIBUTE\0"
 530		"LISTofEXT\0"
 531		"LISTofSTRING\0"
 532		"LISTofSTR\0"
 533		"LISTofENCODINGINFO\0"
 534		"LISTofBYTE\0"
 535		"LISTofCARD16\0"
 536		"LISTofXIMTRIGGERKEY\0";
 537	static guint type2pos[LAST_VALUE_TYPE];
 538	static gboolean initialized = FALSE;
 539	static gchar tmp[256];
 540
 541	if (!initialized) {
 542		memset(type2pos, 0, sizeof (guint) * (LAST_VALUE_TYPE - 1));
 543		type2pos[G_XIM_TYPE_SEPARATOR] = 1;
 544		type2pos[G_XIM_TYPE_BYTE] = 23;
 545		type2pos[G_XIM_TYPE_WORD] = 29;
 546		type2pos[G_XIM_TYPE_LONG] = 36;
 547		type2pos[G_XIM_TYPE_CHAR] = 43;
 548		type2pos[G_XIM_TYPE_WINDOW] = 51;
 549		type2pos[G_XIM_TYPE_XIMSTYLES] = 58;
 550		type2pos[G_XIM_TYPE_XRECTANGLE] = 68;
 551		type2pos[G_XIM_TYPE_XPOINT] = 79;
 552		type2pos[G_XIM_TYPE_XFONTSET] = 86;
 553		type2pos[G_XIM_TYPE_HOTKEYTRIGGERS] = 95;
 554		type2pos[G_XIM_TYPE_HOTKEYSTATE] = 113;
 555		type2pos[G_XIM_TYPE_STRINGCONVERSION] = 128;
 556		type2pos[G_XIM_TYPE_PREEDITSTATE] = 148;
 557		type2pos[G_XIM_TYPE_RESETSTATE] = 164;
 558		type2pos[G_XIM_TYPE_NESTEDLIST] = 178;
 559		type2pos[G_XIM_TYPE_INVALID] = 189;
 560		type2pos[G_XIM_TYPE_PADDING] = 199;
 561		type2pos[G_XIM_TYPE_AUTO_PADDING] = 207;
 562		type2pos[G_XIM_TYPE_MARKER_N_BYTES_1] = 219;
 563		type2pos[G_XIM_TYPE_MARKER_N_BYTES_2] = 241;
 564		type2pos[G_XIM_TYPE_MARKER_N_BYTES_4] = 264;
 565		type2pos[G_XIM_TYPE_MARKER_N_ITEMS_2] = 287;
 566		type2pos[G_XIM_TYPE_STR] = 310;
 567		type2pos[G_XIM_TYPE_GSTRING] = 314;
 568		type2pos[G_XIM_TYPE_PREEDIT_CARET] = 322;
 569		type2pos[G_XIM_TYPE_PREEDIT_DRAW] = 339;
 570		type2pos[G_XIM_TYPE_GDKEVENT] = 355;
 571		type2pos[G_XIM_TYPE_XIMTEXT] = 364;
 572		type2pos[G_XIM_TYPE_HOTKEY_TRIGGER] = 373;
 573		type2pos[G_XIM_TYPE_PIXMAP] = 391;
 574		type2pos[G_XIM_TYPE_STATUS_DRAW] = 398;
 575		type2pos[G_XIM_TYPE_LIST_OF_IMATTR] = 413;
 576		type2pos[G_XIM_TYPE_LIST_OF_ICATTR] = 427;
 577		type2pos[G_XIM_TYPE_LIST_OF_IMATTRIBUTE] = 441;
 578		type2pos[G_XIM_TYPE_LIST_OF_ICATTRIBUTE] = 460;
 579		type2pos[G_XIM_TYPE_LIST_OF_EXT] = 479;
 580		type2pos[G_XIM_TYPE_LIST_OF_STRING] = 489;
 581		type2pos[G_XIM_TYPE_LIST_OF_STR] = 502;
 582		type2pos[G_XIM_TYPE_LIST_OF_ENCODINGINFO] = 512;
 583		type2pos[G_XIM_TYPE_LIST_OF_BYTE] = 531;
 584		type2pos[G_XIM_TYPE_LIST_OF_CARD16] = 542;
 585		type2pos[G_XIM_TYPE_LIST_OF_HOTKEY_TRIGGER] = 555;
 586	}
 587
 588	if (vtype >= LAST_VALUE_TYPE ||
 589	    type2pos[vtype] == 0) {
 590		snprintf(tmp, 255, "0x%x", vtype);
 591
 592		return tmp;
 593	}
 594
 595	return &vtype_name[type2pos[vtype]];
 596}
 597
 598const gchar *
 599g_xim_protocol_name(guint16 major_opcode)
 600{
 601	static const gchar op2str[] = {
 602		"\0"
 603		"XIM_CONNECT\0"
 604		"XIM_CONNECT_REPLY\0"
 605		"XIM_DISCONNECT\0"
 606		"XIM_DISCONNECT_REPLY\0"
 607		"\0"
 608		"\0"
 609		"\0"
 610		"\0"
 611		"\0"
 612		"XIM_AUTH_REQUIRED\0"
 613		"XIM_AUTH_REPLY\0"
 614		"XIM_AUTH_NEXT\0"
 615		"XIM_AUTH_SETUP\0"
 616		"XIM_AUTH_NG\0"
 617		"\0"
 618		"\0"
 619		"\0"
 620		"\0"
 621		"\0"
 622		"XIM_ERROR\0"
 623		"\0"
 624		"\0"
 625		"\0"
 626		"\0"
 627		"\0"
 628		"\0"
 629		"\0"
 630		"\0"
 631		"\0"
 632		"XIM_OPEN\0"
 633		"XIM_OPEN_REPLY\0"
 634		"XIM_CLOSE\0"
 635		"XIM_CLOSE_REPLY\0"
 636		"XIM_REGISTER_TRIGGERKEYS\0"
 637		"XIM_TRIGGER_NOTIFY\0"
 638		"XIM_TRIGGER_NOTIFY_REPLY\0"
 639		"XIM_SET_EVENT_MASK\0"
 640		"XIM_ENCODING_NEGOTIATION\0"
 641		"XIM_ENCODING_NEGOTIATION_REPLY\0"
 642		"XIM_QUERY_EXTENSION\0"
 643		"XIM_QUERY_EXTENSION_REPLY\0"
 644		"XIM_SET_IM_VALUES\0"
 645		"XIM_SET_IM_VALUES_REPLY\0"
 646		"XIM_GET_IM_VALUES\0"
 647		"XIM_GET_IM_VALUES_REPLY\0"
 648		"\0"
 649		"\0"
 650		"\0"
 651		"\0"
 652		"XIM_CREATE_IC\0"
 653		"XIM_CREATE_IC_REPLY\0"
 654		"XIM_DESTROY_IC\0"
 655		"XIM_DESTROY_IC_REPLY\0"
 656		"XIM_SET_IC_VALUES\0"
 657		"XIM_SET_IC_VALUES_REPLY\0"
 658		"XIM_GET_IC_VALUES\0"
 659		"XIM_GET_IC_VALUES_REPLY\0"
 660		"XIM_SET_IC_FOCUS\0"
 661		"XIM_UNSET_IC_FOCUS\0"
 662		"XIM_FORWARD_EVENT\0"
 663		"XIM_SYNC\0"
 664		"XIM_SYNC_REPLY\0"
 665		"XIM_COMMIT\0"
 666		"XIM_RESET_IC\0"
 667		"XIM_RESET_IC_REPLY\0"
 668		"\0"
 669		"\0"
 670		"\0"
 671		"\0"
 672		"XIM_GEOMETRY\0"
 673		"XIM_STR_CONVERSION\0"
 674		"XIM_STR_CONVERSION_REPLY\0"
 675		"XIM_PREEDIT_START\0"
 676		"XIM_PREEDIT_START_REPLY\0"
 677		"XIM_PREEDIT_DRAW\0"
 678		"XIM_PREEDIT_CARET\0"
 679		"XIM_PREEDIT_CARET_REPLY\0"
 680		"XIM_PREEDIT_DONE\0"
 681		"XIM_STATUS_START\0"
 682		"XIM_STATUS_DRAW\0"
 683		"XIM_STATUS_DONE\0"
 684		"XIM_PREEDITSTATE\0"
 685	};
 686	static gsize opindexes[] = {
 687		0, 1, 13, 31, 46, 67, 68, 69, 70, 71,
 688		72, 90, 105, 119, 134, 146, 147, 148, 149, 150,
 689		151, 161, 162, 163, 164, 165, 166, 167, 168, 169,
 690		170, 179, 194, 204, 220, 245, 264, 289, 308, 333,
 691		364, 384, 410, 428, 452, 470, 494, 495, 496, 497,
 692		498, 512, 532, 547, 568, 586, 610, 628, 652, 669,
 693		688, 706, 715, 730, 741, 754, 773, 774, 775, 776,
 694		777, 790, 809, 834, 852, 876, 893, 911, 935, 952,
 695		969, 985, 1001, 1018,
 696	};
 697
 698	if (major_opcode >= LAST_XIM_EVENTS)
 699		return NULL;
 700
 701	return &op2str[opindexes[major_opcode]];
 702}
 703
 704GdkWindow *
 705g_xim_get_window(GdkDisplay      *dpy,
 706		 GdkNativeWindow  window)
 707{
 708	GdkWindow *retval;
 709	guint32 error_code;
 710
 711	g_xim_error_push();
 712
 713	retval = gdk_window_lookup_for_display(dpy, window);
 714	if (retval == NULL ||
 715	    !GDK_IS_WINDOW (retval) ||
 716	    GDK_WINDOW_DESTROYED (retval)) {
 717		if (retval)
 718			gdk_window_destroy(retval);
 719		retval = gdk_window_foreign_new_for_display(dpy, window);
 720	}
 721
 722	error_code = g_xim_error_pop();
 723	if (G_XIM_ERROR_DECODE_X_ERROR_CODE (error_code) != 0) {
 724		g_printerr("Unable to convert the native window to GdkWindow: %p",
 725			   G_XIM_NATIVE_WINDOW_TO_POINTER (window));
 726	}
 727
 728	return retval != NULL ? g_object_ref(retval) : NULL;
 729}
 730
 731GdkPixmap *
 732g_xim_get_pixmap(GdkDisplay      *dpy,
 733		 GdkNativeWindow  window)
 734{
 735	GdkPixmap *retval;
 736
 737	retval = gdk_pixmap_lookup_for_display(dpy, window);
 738	if (retval == NULL ||
 739	    !GDK_IS_PIXMAP (retval)) {
 740		if (retval)
 741			g_object_unref(retval);
 742		retval = gdk_pixmap_foreign_new_for_display(dpy, window);
 743	}
 744
 745	return retval;
 746}
 747
 748GdkWindow *
 749g_xim_get_selection_owner(GdkDisplay *display,
 750			  GdkAtom     selection)
 751{
 752	Window xwindow;
 753	GdkWindow *retval;
 754
 755	g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
 756	g_return_val_if_fail (selection != GDK_NONE, NULL);
 757
 758	if (display->closed)
 759		return NULL;
 760
 761	xwindow = XGetSelectionOwner(GDK_DISPLAY_XDISPLAY (display),
 762				     gdk_x11_atom_to_xatom_for_display(display,
 763								       selection));
 764	if (xwindow == None)
 765		return NULL;
 766
 767	retval = g_xim_get_window(display, (GdkNativeWindow)xwindow);
 768	/* just decrease a counter to not mind unref outside this function */
 769	g_object_unref(retval);
 770
 771	return retval;
 772}
 773
 774GdkWindow *
 775g_xim_lookup_xim_server(GdkDisplay *dpy,
 776			GdkAtom     atom_server,
 777			gboolean   *is_valid)
 778{
 779	GdkAtom atom_xim_servers, atom_type, *atom_prop = NULL;
 780	gint format, bytes, i;
 781	GdkWindow *retval = NULL;
 782	guint32 error_code;
 783
 784	g_return_val_if_fail (atom_server != GDK_NONE, NULL);
 785	g_return_val_if_fail (is_valid != NULL, NULL);
 786
 787	atom_xim_servers = gdk_atom_intern_static_string("XIM_SERVERS");
 788
 789	g_xim_error_push();
 790	gdk_property_get(gdk_screen_get_root_window(gdk_display_get_default_screen(dpy)),
 791			 atom_xim_servers, GDK_SELECTION_TYPE_ATOM,
 792			 0, 8192, FALSE,
 793			 &atom_type, &format, &bytes,
 794			 (guchar **)(uintptr_t)&atom_prop);
 795	error_code = g_xim_error_pop();
 796	if (error_code != 0) {
 797		*is_valid = FALSE;
 798		return NULL;
 799	}
 800	if (atom_type != GDK_SELECTION_TYPE_ATOM ||
 801	    format != 32) {
 802		*is_valid = FALSE;
 803		return NULL;
 804	}
 805
 806	for (i = 0; i < (bytes / sizeof (gulong)); i++) {
 807		if (atom_prop[i] == atom_server) {
 808			retval = g_xim_get_selection_owner(dpy, atom_server);
 809			break;
 810		}
 811	}
 812	g_free(atom_prop);
 813	*is_valid = TRUE;
 814
 815	return retval;
 816}
 817
 818GdkWindow *
 819g_xim_lookup_xim_server_from_string(GdkDisplay  *dpy,
 820				    const gchar *server_name,
 821				    gboolean    *is_valid)
 822{
 823	GdkWindow *retval;
 824	GdkAtom atom_server;
 825
 826	g_return_val_if_fail (server_name != NULL, NULL);
 827
 828	atom_server = g_xim_get_server_atom(server_name);
 829	retval = g_xim_lookup_xim_server(dpy, atom_server, is_valid);
 830
 831	return retval;
 832}
 833
 834GdkAtom
 835g_xim_get_server_atom(const gchar *server_name)
 836{
 837	gchar *s;
 838	GdkAtom retval;
 839
 840	s = g_strdup_printf("@server=%s", server_name);
 841	retval = gdk_atom_intern(s, FALSE);
 842	g_free(s);
 843
 844	return retval;
 845}
 846
 847gpointer
 848g_xim_copy_by_gtype(GType    gtype,
 849		    gpointer value)
 850{
 851	gpointer retval;
 852
 853	if (G_TYPE_IS_BOXED (gtype))
 854		retval = g_boxed_copy(gtype, value);
 855	else if (G_TYPE_IS_OBJECT (gtype))
 856		retval = g_object_ref(value);
 857	else if (gtype == G_TYPE_STRING)
 858		retval = g_strdup(value);
 859	else
 860		retval = value;
 861
 862	return retval;
 863}
 864
 865void
 866g_xim_free_by_gtype(GType    gtype,
 867		    gpointer value)
 868{
 869	if (G_TYPE_IS_BOXED (gtype))
 870		g_boxed_free(gtype, value);
 871	else if (G_TYPE_IS_OBJECT (gtype))
 872		g_object_unref(value);
 873	else if (gtype == G_TYPE_STRING)
 874		g_free(value);
 875}
 876
 877#if 0
 878/* GXimStrConv */
 879GXimStrConvText *
 880g_xim_str_conv_text_new(const gchar *string,
 881			guint16      length)
 882{
 883	GXimStrConvText *retval;
 884
 885	g_return_val_if_fail (string != NULL, NULL);
 886
 887	retval = g_new0(GXimStrConvText, 1);
 888	G_XIM_CHECK_ALLOC (retval, NULL);
 889
 890	retval->string = g_strndup(string, length);
 891	retval->length = length;
 892
 893	return retval;
 894}
 895
 896GXimStrConvText *
 897g_xim_str_conv_text_new_full(const gchar *string,
 898			     guint16      length,
 899			     guint16      feedback)
 900{
 901	GXimStrConvText *retval = g_xim_str_conv_text_new(string, length);
 902
 903	if (retval)
 904		g_xim_str_conv_set_feedback(retval, feedback);
 905
 906	return retval;
 907}
 908
 909void
 910g_xim_str_conv_text_free(GXimStrConvText *text)
 911{
 912	g_return_if_fail (text != NULL);
 913
 914	g_free(text->string);
 915	g_free(text);
 916}
 917
 918void
 919g_xim_str_conv_set_feedback(GXimStrConvText *text,
 920			    guint16          feedback)
 921{
 922	g_return_if_fail (text != NULL);
 923
 924	text->feedback = feedback;
 925}
 926
 927guint16
 928g_xim_str_conv_get_feedback(GXimStrConvText *text)
 929{
 930	g_return_val_if_fail (text != NULL, 0);
 931
 932	return text->feedback;
 933}
 934#endif
 935
 936/* XIMStyles */
 937GType
 938g_xim_styles_get_type(void)
 939{
 940	static volatile gsize type_id_volatile = 0;
 941
 942	if (g_once_init_enter(&type_id_volatile)) {
 943		GType type_id;
 944
 945		type_id = g_boxed_type_register_static(g_intern_static_string("GXimStyles"),
 946						       g_xim_styles_copy,
 947						       g_xim_styles_free);
 948		g_once_init_leave(&type_id_volatile, type_id);
 949	}
 950
 951	return type_id_volatile;
 952}
 953
 954GQuark
 955g_xim_styles_get_error_quark(void)
 956{
 957	static GQuark quark = 0;
 958
 959	if (!quark)
 960		quark = g_quark_from_static_string("g-xim-styles-error");
 961
 962	return quark;
 963}
 964
 965GXimStyles *
 966g_xim_styles_new(void)
 967{
 968	GXimStyles *retval = g_new0(GXimStyles, 1);
 969
 970	G_XIM_CHECK_ALLOC (retval, NULL);
 971
 972	retval->count_styles = 0;
 973	retval->supported_styles = NULL;
 974
 975	return retval;
 976}
 977
 978gboolean
 979g_xim_styles_append(GXimStyles  *styles,
 980		    GXimStyle    style,
 981		    GError     **error)
 982{
 983	g_return_val_if_fail (styles != NULL, FALSE);
 984
 985	return g_xim_styles_insert(styles, styles->count_styles, style, error);
 986}
 987
 988gboolean
 989g_xim_styles_insert(GXimStyles  *styles,
 990		    guint        index_,
 991		    GXimStyle    style,
 992		    GError     **error)
 993{
 994	gboolean retval = TRUE;
 995
 996	g_return_val_if_fail (styles != NULL, FALSE);
 997	g_return_val_if_fail (error != NULL, FALSE);
 998
 999	if (styles->count_styles <= index_) {
1000		gpointer data;
1001
1002		data = g_realloc(styles->supported_styles,
1003				 sizeof (GXimStyle) * (index_ + 1));
1004		G_XIM_GERROR_CHECK_ALLOC (data,
1005					  error, G_XIM_STYLES_ERROR,
1006					  FALSE);
1007
1008		styles->supported_styles = data;
1009		styles->count_styles = index_ + 1;
1010	}
1011	styles->supported_styles[index_] = style;
1012
1013	return retval;
1014}
1015
1016gpointer
1017g_xim_styles_copy(gpointer boxed)
1018{
1019	GXimStyles *retval, *orig = boxed;
1020
1021	if (boxed == NULL)
1022		return NULL;
1023
1024	retval = g_new(GXimStyles, 1);
1025	G_XIM_CHECK_ALLOC (retval, NULL);
1026
1027	retval->count_styles = orig->count_styles;
1028	retval->supported_styles = g_new(GXimStyle, sizeof (GXimStyle) * retval->count_styles);
1029	G_XIM_CHECK_ALLOC (retval->supported_styles, NULL);
1030
1031	memcpy(retval->supported_styles,
1032	       orig->supported_styles,
1033	       sizeof (GXimStyle) * retval->count_styles);
1034
1035	return retval;
1036}
1037
1038void
1039g_xim_styles_free(gpointer boxed)
1040{
1041	GXimStyles *s = boxed;
1042
1043	if (boxed == NULL)
1044		return;
1045
1046	g_free(s->supported_styles);
1047	g_free(s);
1048}
1049
1050gsize
1051g_xim_styles_put_to_stream(GXimStyles    *styles,
1052			   GXimProtocol  *proto,
1053			   GCancellable  *cancellable,
1054			   GError       **error)
1055{
1056	gsize retval = 0;
1057	guint16 i;
1058
1059	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
1060	g_return_val_if_fail (styles != NULL, 0);
1061	g_return_val_if_fail (error != NULL, 0);
1062
1063	retval = g_xim_protocol_send_format(proto, cancellable, error, 2,
1064					    G_XIM_TYPE_WORD, styles->count_styles,
1065					    G_XIM_TYPE_PADDING, 2);
1066	if (*error)
1067		return 0;
1068	/* XIMStyle */
1069	for (i = 0; i < styles->count_styles; i++) {
1070		retval += g_xim_protocol_send_format(proto, cancellable, error, 1,
1071						     G_XIM_TYPE_LONG, styles->supported_styles[i]);
1072		if (*error)
1073			return 0;
1074	}
1075
1076	return retval;
1077}
1078
1079gpointer
1080g_xim_styles_get_from_stream(GXimProtocol      *proto,
1081			     GDataInputStream  *stream,
1082			     GCancellable      *cancellable,
1083			     GError           **error)
1084{
1085	GXimStyles *retval;
1086	guint16 i;
1087	GXimStyle style;
1088
1089	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), NULL);
1090	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1091	g_return_val_if_fail (error != NULL, NULL);
1092
1093	retval = g_xim_styles_new();
1094	G_XIM_CHECK_ALLOC (retval, NULL);
1095
1096	if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
1097					2,
1098					G_XIM_TYPE_WORD, &retval->count_styles,
1099					G_XIM_TYPE_PADDING, 2)) {
1100		g_xim_styles_free(retval);
1101		return NULL;
1102	}
1103	retval->supported_styles = g_new0(GXimStyle, retval->count_styles);
1104	G_XIM_GERROR_CHECK_ALLOC (retval->supported_styles, error,
1105				  G_XIM_PROTOCOL_ERROR, NULL);
1106
1107	for (i = 0; i < retval->count_styles; i++) {
1108		if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
1109						1,
1110						G_XIM_TYPE_LONG, &style)) {
1111			/* keep the values as much as possible */
1112			retval->count_styles = i;
1113			G_XIM_GERROR_RESET_NOTICE_FLAG (*error);
1114			G_XIM_GERROR_SET_NOTICE_FLAG (*error,
1115						      G_XIM_NOTICE_WARNING);
1116			break;
1117		}
1118		if (!g_xim_styles_insert(retval, i, style, error)) {
1119			retval->count_styles = i;
1120			G_XIM_GERROR_RESET_NOTICE_FLAG (*error);
1121			G_XIM_GERROR_SET_NOTICE_FLAG (*error,
1122						      G_XIM_NOTICE_WARNING);
1123			break;
1124		}
1125	}
1126
1127	return retval;
1128}
1129
1130/* XRectangle */
1131GType
1132g_xim_rectangle_get_type(void)
1133{
1134	static volatile gsize type_id_volatile = 0;
1135
1136	if (g_once_init_enter(&type_id_volatile)) {
1137		GType type_id;
1138
1139		type_id = g_boxed_type_register_static(g_intern_static_string("GXimRectangle"),
1140						       g_xim_rectangle_copy,
1141						       g_xim_rectangle_free);
1142		g_once_init_leave(&type_id_volatile, type_id);
1143	}
1144
1145	return type_id_volatile;
1146}
1147
1148gpointer
1149g_xim_rectangle_new(void)
1150{
1151	return g_new0(GXimRectangle, 1);
1152}
1153
1154gpointer
1155g_xim_rectangle_copy(gpointer boxed)
1156{
1157	GXimRectangle *retval, *val = boxed;
1158
1159	if (boxed == NULL)
1160		return NULL;
1161
1162	retval = g_xim_rectangle_new();
1163	G_XIM_CHECK_ALLOC (retval, NULL);
1164
1165	retval->x = val->x;
1166	retval->y = val->y;
1167	retval->width = val->width;
1168	retval->height = val->height;
1169
1170	return retval;
1171}
1172
1173void
1174g_xim_rectangle_free(gpointer boxed)
1175{
1176	g_free(boxed);
1177}
1178
1179gsize
1180g_xim_rectangle_put_to_stream(GXimRectangle  *rectangle,
1181			      GXimProtocol   *proto,
1182			      GCancellable   *cancellable,
1183			      GError        **error)
1184{
1185	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
1186	g_return_val_if_fail (rectangle != NULL, 0);
1187	g_return_val_if_fail (error != NULL, 0);
1188
1189	return g_xim_protocol_send_format(proto, cancellable, error, 4,
1190					  G_XIM_TYPE_WORD, rectangle->x,
1191					  G_XIM_TYPE_WORD, rectangle->y,
1192					  G_XIM_TYPE_WORD, rectangle->width,
1193					  G_XIM_TYPE_WORD, rectangle->height);
1194}
1195
1196gpointer
1197g_xim_rectangle_get_from_stream(GXimProtocol      *proto,
1198				GDataInputStream  *stream,
1199				GCancellable      *cancellable,
1200				GError           **error)
1201{
1202	GXimRectangle *retval;
1203	guint16 x, y, width, height;
1204
1205	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), NULL);
1206	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1207	g_return_val_if_fail (error != NULL, NULL);
1208
1209	if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
1210					4,
1211					G_XIM_TYPE_WORD, &x,
1212					G_XIM_TYPE_WORD, &y,
1213					G_XIM_TYPE_WORD, &width,
1214					G_XIM_TYPE_WORD, &height))
1215		return NULL;
1216
1217	retval = g_xim_rectangle_new();
1218	G_XIM_GERROR_CHECK_ALLOC (retval, error,
1219				  G_XIM_PROTOCOL_ERROR, NULL);
1220
1221	retval->x = x;
1222	retval->y = y;
1223	retval->width = width;
1224	retval->height = height;
1225
1226	return retval;
1227}
1228
1229/* XPoint */
1230GType
1231g_xim_point_get_type(void)
1232{
1233	static volatile gsize type_id_volatile = 0;
1234
1235	if (g_once_init_enter(&type_id_volatile)) {
1236		GType type_id;
1237
1238		type_id = g_boxed_type_register_static(g_intern_static_string("GXimPoint"),
1239						       g_xim_point_copy,
1240						       g_xim_point_free);
1241		g_once_init_leave(&type_id_volatile, type_id);
1242	}
1243
1244	return type_id_volatile;
1245}
1246
1247gpointer
1248g_xim_point_new(void)
1249{
1250	return g_new0(GXimPoint, 1);
1251}
1252
1253gpointer
1254g_xim_point_copy(gpointer boxed)
1255{
1256	GXimPoint *retval, *val = boxed;
1257
1258	if (boxed == NULL)
1259		return NULL;
1260
1261	retval = g_xim_point_new();
1262	G_XIM_CHECK_ALLOC (retval, NULL);
1263
1264	retval->x = val->x;
1265	retval->y = val->y;
1266
1267	return retval;
1268}
1269
1270void
1271g_xim_point_free(gpointer boxed)
1272{
1273	g_free(boxed);
1274}
1275
1276gsize
1277g_xim_point_put_to_stream(GXimPoint     *point,
1278			  GXimProtocol  *proto,
1279			  GCancellable  *cancellable,
1280			  GError       **error)
1281{
1282	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
1283	g_return_val_if_fail (point != NULL, 0);
1284	g_return_val_if_fail (error != NULL, 0);
1285
1286	return g_xim_protocol_send_format(proto, cancellable, error, 2,
1287					  G_XIM_TYPE_WORD, point->x,
1288					  G_XIM_TYPE_WORD, point->y);
1289}
1290
1291gpointer
1292g_xim_point_get_from_stream(GXimProtocol      *proto,
1293			    GDataInputStream  *stream,
1294			    GCancellable      *cancellable,
1295			    GError           **error)
1296{
1297	GXimPoint *retval;
1298	guint16 x, y;
1299
1300	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), NULL);
1301	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1302	g_return_val_if_fail (error != NULL, NULL);
1303
1304	if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
1305					2,
1306					G_XIM_TYPE_WORD, &x,
1307					G_XIM_TYPE_WORD, &y))
1308		return NULL;
1309
1310	retval = g_xim_point_new();
1311	G_XIM_GERROR_CHECK_ALLOC (retval, error,
1312				  G_XIM_PROTOCOL_ERROR, NULL);
1313
1314	retval->x = x;
1315	retval->y = y;
1316
1317	return retval;
1318}
1319
1320/* XFontSet */
1321GType
1322g_xim_fontset_get_type(void)
1323{
1324	static volatile gsize type_id_volatile = 0;
1325
1326	if (g_once_init_enter(&type_id_volatile)) {
1327		GType type_id;
1328
1329		type_id = g_boxed_type_register_static(g_intern_static_string("GXimFontSet"),
1330						       g_xim_fontset_copy,
1331						       g_xim_fontset_free);
1332		g_once_init_leave(&type_id_volatile, type_id);
1333	}
1334
1335	return type_id_volatile;
1336}
1337
1338gpointer
1339g_xim_fontset_copy(gpointer boxed)
1340{
1341	GString *retval, *val = boxed;
1342
1343	if (boxed == NULL)
1344		return NULL;
1345
1346	retval = g_string_sized_new(val->len);
1347	G_XIM_CHECK_ALLOC (retval, NULL);
1348
1349	g_string_append(retval, val->str);
1350
1351	return retval;
1352}
1353
1354void
1355g_xim_fontset_free(gpointer boxed)
1356{
1357	if (boxed == NULL)
1358		return;
1359
1360	g_string_free(boxed, TRUE);
1361}
1362
1363gsize
1364g_xim_fontset_put_to_stream(GXimFontSet   *fontset,
1365			    GXimProtocol  *proto,
1366			    GCancellable  *cancellable,
1367			    GError       **error)
1368{
1369	g_return_val_if_fail (fontset != NULL, 0);
1370	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
1371	g_return_val_if_fail (error != NULL, 0);
1372
1373	return g_xim_protocol_send_format(proto, cancellable, error, 1,
1374					  G_XIM_TYPE_GSTRING, fontset);
1375}
1376
1377gpointer
1378g_xim_fontset_get_from_stream(GXimProtocol      *proto,
1379			      GDataInputStream  *stream,
1380			      GCancellable      *cancellable,
1381			      GError           **error)
1382{
1383	GXimFontSet *retval = NULL;
1384
1385	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), NULL);
1386	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1387	g_return_val_if_fail (error != NULL, NULL);
1388
1389	if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
1390					1,
1391					G_XIM_TYPE_GSTRING, &retval))
1392		return NULL;
1393
1394	return retval;
1395}
1396
1397/* GString */
1398gsize
1399g_xim_gstring_put_to_stream(GString            *string,
1400			    GDataOutputStream  *stream,
1401			    GCancellable       *cancellable,
1402			    GError            **error)
1403{
1404	gint i;
1405	gsize retval = 2;
1406
1407	g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), 0);
1408	g_return_val_if_fail (string != NULL, 0);
1409	g_return_val_if_fail (string->len <= 0xffff, 0);
1410	g_return_val_if_fail (error != NULL, 0);
1411
1412	g_data_output_stream_put_uint16(stream, string->len, cancellable, error);
1413	if (*error)
1414		return 0;
1415	for (i = 0; i < string->len; i++) {
1416		g_data_output_stream_put_byte(stream, string->str[i], cancellable, error);
1417		if (*error)
1418			return 0;
1419		retval++;
1420	}
1421
1422	return retval;
1423}
1424
1425gpointer
1426g_xim_gstring_get_from_stream(GDataInputStream  *stream,
1427			      GCancellable      *cancellable,
1428			      GError           **error)
1429{
1430	GString *retval = NULL;
1431	gsize size, avail, read = 2, i;
1432
1433	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1434	g_return_val_if_fail (error != NULL, NULL);
1435
1436	size = g_data_input_stream_read_uint16(stream, cancellable, error);
1437	if (*error)
1438		return NULL;
1439	if ((avail = g_buffered_input_stream_get_buffer_size(G_BUFFERED_INPUT_STREAM (stream))) < size) {
1440		g_set_error(error, G_XIM_PROTOCOL_ERROR,
1441			    G_XIM_PROTOCOL_ERROR_INVALID_PACKETS_RECEIVED | G_XIM_NOTICE_ERROR,
1442			    "Unable to compose a string with the remaining packets: %" G_GSIZE_FORMAT " for %" G_GSIZE_FORMAT,
1443			    size, avail);
1444		return NULL;
1445	}
1446	retval = g_string_sized_new(size);
1447	G_XIM_GERROR_CHECK_ALLOC (retval, error,
1448				  G_XIM_PROTOCOL_ERROR, NULL);
1449
1450	for (i = 0; i < size; i++) {
1451		gchar c;
1452
1453		c = g_data_input_stream_read_byte(stream, cancellable, error);
1454		if (*error)
1455			goto fail;
1456		g_string_append_c(retval, c);
1457		read++;
1458	}
1459
1460	return retval;
1461  fail:
1462	if (retval)
1463		g_string_free(retval, TRUE);
1464
1465	return NULL;
1466}
1467
1468/* STRING */
1469GType
1470g_xim_string_get_type(void)
1471{
1472	static volatile gsize type_id_volatile = 0;
1473
1474	if (g_once_init_enter(&type_id_volatile)) {
1475		GType type_id;
1476
1477		type_id = g_boxed_type_register_static(g_intern_static_string("GXimString"),
1478						       g_xim_string_copy,
1479						       g_xim_string_free);
1480		g_once_init_leave(&type_id_volatile, type_id);
1481	}
1482
1483	return type_id_volatile;
1484}
1485
1486gpointer
1487g_xim_string_new(void)
1488{
1489	GString *retval = g_string_new(NULL);
1490
1491	return retval;
1492}
1493
1494gpointer
1495g_xim_string_copy(gpointer boxed)
1496{
1497	GString *retval, *orig = boxed;
1498
1499	if (boxed == NULL)
1500		return NULL;
1501
1502	retval = g_string_sized_new(orig->len);
1503	G_XIM_CHECK_ALLOC (retval, NULL);
1504
1505	g_string_append(retval, orig->str);
1506
1507	return retval;
1508}
1509
1510void
1511g_xim_string_free(gpointer boxed)
1512{
1513	if (boxed == NULL)
1514		return;
1515
1516	g_string_free(boxed, TRUE);
1517}
1518
1519const gchar *
1520g_xim_string_get_string(const GXimString *string)
1521{
1522	g_return_val_if_fail (string != NULL, NULL);
1523
1524	return ((GString *)string)->str;
1525}
1526
1527gsize
1528g_xim_string_get_length(GXimString *string)
1529{
1530	GString *str = (GString *)string;
1531
1532	g_return_val_if_fail (string != NULL, 0);
1533
1534	return str->len;
1535}
1536
1537gsize
1538g_xim_string_put_to_stream(GXimString         *string,
1539			   GDataOutputStream  *stream,
1540			   GCancellable       *cancellable,
1541			   GError            **error)
1542{
1543	gsize retval = 2, i;
1544	GString *str = (GString *)string;
1545
1546	g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), 0);
1547	g_return_val_if_fail (string != NULL, 0);
1548	g_return_val_if_fail (error != NULL, 0);
1549
1550	/* length of string in bytes */
1551	g_data_output_stream_put_uint16(stream,
1552					str->len,
1553					cancellable,
1554					error);
1555	if (*error)
1556		return 0;
1557	/* LIST of LPCE */
1558	for (i = 0; i < str->len; i++) {
1559		g_data_output_stream_put_byte(stream,
1560					      str->str[i],
1561					      cancellable,
1562					      error);
1563		if (*error)
1564			return 0;
1565
1566		retval++;
1567	}
1568	/* padding */
1569	for (i = 0; i < g_xim_protocol_n_pad4 (2 + str->len); i++) {
1570		g_data_output_stream_put_byte(stream, 0, cancellable, error);
1571		if (*error)
1572			return 0;
1573		retval++;
1574	}
1575
1576	return retval;
1577}
1578
1579gpointer
1580g_xim_string_get_from_stream(GDataInputStream  *stream,
1581			     GCancellable      *cancellable,
1582			     GError           **error)
1583{
1584	guint16 n, i;
1585	GString *str = NULL;
1586	GInputStream *base_stream;
1587
1588	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1589	g_return_val_if_fail (error != NULL, NULL);
1590
1591	n = g_data_input_stream_read_uint16(stream, cancellable, error);
1592	if (*error)
1593		return NULL;
1594	str = g_string_sized_new(n);
1595	G_XIM_GERROR_CHECK_ALLOC (str, error,
1596				  G_XIM_PROTOCOL_ERROR, NULL);
1597
1598	for (i = 0; i < n; i++) {
1599		guint8 c;
1600
1601		c = g_data_input_stream_read_byte(stream, cancellable, error);
1602		if (*error)
1603			goto fail;
1604		g_string_append_c(str, c);
1605	}
1606	/* skip padding */
1607	base_stream = g_filter_input_stream_get_base_stream(G_FILTER_INPUT_STREAM (stream));
1608	g_seekable_seek(G_SEEKABLE (base_stream),
1609			g_xim_protocol_n_pad4 (2 + n),
1610			G_SEEK_CUR, cancellable, error);
1611
1612	return str;
1613  fail:
1614	if (str)
1615		g_string_free(str, TRUE);
1616
1617	return NULL;
1618}
1619
1620/* STR */
1621GType
1622g_xim_str_get_type(void)
1623{
1624	static volatile gsize type_id_volatile = 0;
1625
1626	if (g_once_init_enter(&type_id_volatile)) {
1627		GType type_id;
1628
1629		type_id = g_boxed_type_register_static(g_intern_static_string("GXimStr"),
1630						       g_xim_str_copy,
1631						       g_xim_str_free);
1632		g_once_init_leave(&type_id_volatile, type_id);
1633	}
1634
1635	return type_id_volatile;
1636}
1637
1638gpointer
1639g_xim_str_new(void)
1640{
1641	GString *retval = g_string_new(NULL);
1642
1643	return retval;
1644}
1645
1646gpointer
1647g_xim_str_copy(gpointer boxed)
1648{
1649	GString *retval, *orig = boxed;
1650
1651	g_return_val_if_fail (boxed != NULL, NULL);
1652
1653	retval = g_string_sized_new(orig->len);
1654	G_XIM_CHECK_ALLOC (retval, NULL);
1655
1656	g_string_append(retval, orig->str);
1657
1658	return retval;
1659}
1660
1661void
1662g_xim_str_free(gpointer boxed)
1663{
1664	if (boxed == NULL)
1665		return;
1666
1667	g_string_free(boxed, TRUE);
1668}
1669
1670const gchar *
1671g_xim_str_get_string(const GXimStr *string)
1672{
1673	g_return_val_if_fail (string != NULL, NULL);
1674
1675	return ((GString *)string)->str;
1676}
1677
1678gsize
1679g_xim_str_get_length(const GXimStr *string)
1680{
1681	const GString *str = (const GString *)string;
1682
1683	g_return_val_if_fail (string != NULL, 0);
1684
1685	return str->len;
1686}
1687
1688GXimStr *
1689g_xim_str_append(GXimStr     *string,
1690		 const gchar *val)
1691{
1692	g_return_val_if_fail (string != NULL, NULL);
1693	g_return_val_if_fail (val != NULL, string);
1694
1695	return g_xim_str_append_len(string, val, strlen(val));
1696}
1697
1698GXimStr *
1699g_xim_str_append_len(GXimStr     *string,
1700		     const gchar *val,
1701		     gssize       len)
1702{
1703	g_return_val_if_fail (string != NULL, NULL);
1704	g_return_val_if_fail (val != NULL, string);
1705
1706	if (len < 0)
1707		len = strlen(val);
1708
1709	return (GXimStr *)g_string_append_len((GString *)string,
1710					      val,
1711					      len);
1712}
1713
1714gsize
1715g_xim_str_put_to_stream(GXimStr            *string,
1716			GDataOutputStream  *stream,
1717			GCancellable       *cancellable,
1718			GError            **error)
1719{
1720	gsize retval = 1, i;
1721	GString *str = (GString *)string;
1722
1723	g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), 0);
1724	g_return_val_if_fail (string != NULL, 0);
1725	g_return_val_if_fail (str->len < 0x100, 0);
1726	g_return_val_if_fail (error != NULL, 0);
1727
1728	/* length of string in bytes */
1729	g_data_output_stream_put_byte(stream,
1730				      str->len,
1731				      cancellable,
1732				      error);
1733	if (*error)
1734		return 0;
1735	/* STRING8 */
1736	for (i = 0; i < str->len; i++) {
1737		g_data_output_stream_put_byte(stream,
1738					      str->str[i],
1739					      cancellable,
1740					      error);
1741		if (*error)
1742			return 0;
1743
1744		retval++;
1745	}
1746
1747	return retval;
1748}
1749
1750gpointer
1751g_xim_str_get_from_stream(GDataInputStream  *stream,
1752			  GCancellable      *cancellable,
1753			  GError           **error)
1754{
1755	guint8 n, i;
1756	GString *str = NULL;
1757
1758	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1759	g_return_val_if_fail (error != NULL, NULL);
1760
1761	n = g_data_input_stream_read_byte(stream, cancellable, error);
1762	if (*error)
1763		return NULL;
1764	str = g_string_sized_new(n);
1765	G_XIM_GERROR_CHECK_ALLOC (str, error,
1766				  G_XIM_PROTOCOL_ERROR, NULL);
1767
1768	for (i = 0; i < n; i++) {
1769		guint8 c;
1770
1771		c = g_data_input_stream_read_byte(stream, cancellable, error);
1772		if (*error)
1773			goto fail;
1774		g_string_append_c(str, c);
1775	}
1776
1777	return str;
1778  fail:
1779	if (str)
1780		g_string_free(str, TRUE);
1781
1782	return NULL;
1783}
1784
1785/* ENCODINGINFO */
1786GType
1787g_xim_encodinginfo_get_type(void)
1788{
1789	static volatile gsize type_id_volatile = 0;
1790
1791	if (g_once_init_enter(&type_id_volatile)) {
1792		GType type_id;
1793
1794		type_id = g_boxed_type_register_static(g_intern_static_string("ENCODINGINFO"),
1795						       g_xim_encodinginfo_copy,
1796						       g_xim_encodinginfo_free);
1797		g_once_init_leave(&type_id_volatile, type_id);
1798	}
1799
1800	return type_id_volatile;
1801}
1802
1803gpointer
1804g_xim_encodinginfo_new(void)
1805{
1806	GString *retval = g_string_new(NULL);
1807
1808	return retval;
1809}
1810
1811gpointer
1812g_xim_encodinginfo_copy(gpointer boxed)
1813{
1814	GString *retval, *orig = boxed;
1815
1816	g_return_val_if_fail (boxed != NULL, NULL);
1817
1818	retval = g_string_sized_new(orig->len);
1819	G_XIM_CHECK_ALLOC (retval, NULL);
1820
1821	g_string_append(retval, orig->str);
1822
1823	return retval;
1824}
1825
1826void
1827g_xim_encodinginfo_free(gpointer boxed)
1828{
1829	if (boxed == NULL)
1830		return;
1831
1832	g_string_free(boxed, TRUE);
1833}
1834
1835const gchar *
1836g_xim_encodinginfo_get_string(const GXimEncodingInfo *encoding)
1837{
1838	g_return_val_if_fail (encoding != NULL, NULL);
1839
1840	return ((GString *)encoding)->str;
1841}
1842
1843gsize
1844g_xim_encodinginfo_get_length(GXimEncodingInfo *encoding)
1845{
1846	GString *str = (GString *)encoding;
1847
1848	g_return_val_if_fail (encoding != NULL, 0);
1849
1850	return str->len;
1851}
1852
1853gsize
1854g_xim_encodinginfo_put_to_stream(GXimEncodingInfo   *encoding,
1855				 GDataOutputStream  *stream,
1856				 GCancellable       *cancellable,
1857				 GError            **error)
1858{
1859	gsize retval = 2, i;
1860	GString *str = (GString *)encoding;
1861
1862	g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), 0);
1863	g_return_val_if_fail (encoding != NULL, 0);
1864	g_return_val_if_fail (error != NULL, 0);
1865
1866	/* length of string in bytes */
1867	g_data_output_stream_put_uint16(stream,
1868					str->len,
1869					cancellable,
1870					error);
1871	if (*error)
1872		return 0;
1873	/* STRING8 */
1874	for (i = 0; i < str->len; i++) {
1875		g_data_output_stream_put_byte(stream,
1876					      str->str[i],
1877					      cancellable,
1878					      error);
1879		if (*error)
1880			return 0;
1881
1882		retval++;
1883	}
1884	/* padding */
1885	for (i = 0; i < g_xim_protocol_n_pad4 (2 + str->len); i++) {
1886		g_data_output_stream_put_byte(stream, 0, cancellable, error);
1887		if (*error)
1888			return 0;
1889		retval++;
1890	}
1891
1892	return retval;
1893}
1894
1895gpointer
1896g_xim_encodinginfo_get_from_stream(GDataInputStream  *stream,
1897				   GCancellable      *cancellable,
1898				   GError           **error)
1899{
1900	guint16 n, i;
1901	GString *str = NULL;
1902	GInputStream *base_stream;
1903
1904	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1905	g_return_val_if_fail (error != NULL, NULL);
1906
1907	n = g_data_input_stream_read_uint16(stream, cancellable, error);
1908	if (*error)
1909		return NULL;
1910	str = g_string_sized_new(n);
1911	G_XIM_GERROR_CHECK_ALLOC (str, error,
1912				  G_XIM_PROTOCOL_ERROR, NULL);
1913
1914	for (i = 0; i < n; i++) {
1915		guint8 c;
1916
1917		c = g_data_input_stream_read_byte(stream, cancellable, error);
1918		if (*error)
1919			goto fail;
1920		g_string_append_c(str, c);
1921	}
1922	/* skip padding */
1923	base_stream = g_filter_input_stream_get_base_stream(G_FILTER_INPUT_STREAM (stream));
1924	g_seekable_seek(G_SEEKABLE (base_stream),
1925			g_xim_protocol_n_pad4 (2 + n),
1926			G_SEEK_CUR, cancellable, error);
1927
1928	return str;
1929  fail:
1930	if (str)
1931		g_string_free(str, TRUE);
1932
1933	return NULL;
1934}
1935
1936/* ATTR */
1937GType
1938g_xim_raw_attr_get_type(void)
1939{
1940	static volatile gsize type_id_volatile = 0;
1941
1942	if (g_once_init_enter(&type_id_volatile)) {
1943		GType type_id;
1944
1945		type_id = g_boxed_type_register_static(g_intern_static_string("GXimRawAttr"),
1946						       g_xim_raw_attr_copy,
1947						       g_xim_raw_attr_free);
1948		g_once_init_leave(&type_id_volatile, type_id);
1949	}
1950
1951	return type_id_volatile;
1952}
1953
1954gpointer
1955g_xim_raw_attr_new(void)
1956{
1957	GXimRawAttr *retval;
1958
1959	retval = g_new0(GXimRawAttr, 1);
1960	G_XIM_CHECK_ALLOC (retval, NULL);
1961
1962	retval->base.vtype = G_XIM_TYPE_INVALID;
1963
1964	return retval;
1965}
1966
1967gpointer
1968g_xim_raw_attr_new_with_value(guint16        id,
1969			      GString       *name,
1970			      GXimValueType  vtype)
1971{
1972	GXimRawAttr *retval;
1973
1974	g_return_val_if_fail (vtype != G_XIM_TYPE_INVALID, NULL);
1975	g_return_val_if_fail (name != NULL, NULL);
1976
1977	retval = g_xim_raw_attr_new();
1978	G_XIM_CHECK_ALLOC (retval, NULL);
1979
1980	g_xim_raw_attr_set_name(retval, name);
1981	retval->base.id = id;
1982	retval->base.vtype = vtype;
1983
1984	return retval;
1985}
1986
1987void
1988g_xim_raw_attr_set_name(GXimRawAttr *attr,
1989			GString     *name)
1990{
1991	g_return_if_fail (attr != NULL);
1992	g_return_if_fail (name != NULL);
1993	g_return_if_fail (name->len > 0);
1994
1995	if (attr->attribute_name)
1996		g_string_free(attr->attribute_name, TRUE);
1997
1998	attr->attribute_name = g_string_sized_new(name->len);
1999	G_XIM_CHECK_ALLOC_WITH_NO_RET (attr->attribute_name);
2000
2001	g_string_append(attr->attribute_name, name->str);
2002}
2003
2004void
2005g_xim_raw_attr_clear(GXimRawAttr *attr)
2006{
2007	g_return_if_fail (attr != NULL);
2008
2009	attr->base.vtype = G_XIM_TYPE_INVALID;
2010	g_string_free(attr->attribute_name, TRUE);
2011	attr->attribute_name = NULL;
2012}
2013
2014gpointer
2015g_xim_raw_attr_copy(gpointer boxed)
2016{
2017	GXimRawAttr *retval, *orig;
2018
2019	if (boxed == NULL)
2020		return NULL;
2021
2022	orig = boxed;
2023	retval = g_xim_raw_attr_new_with_value(orig->base.id,
2024					       orig->attribute_name,
2025					       orig->base.vtype);
2026
2027	return retval;
2028}
2029
2030void
2031g_xim_raw_attr_free(gpointer boxed)
2032{
2033	if (boxed == NULL)
2034		return;
2035
2036	g_xim_raw_attr_clear(boxed);
2037	g_free(boxed);
2038}
2039
2040gsize
2041g_xim_raw_attr_put_to_stream(GXimRawAttr   *attr,
2042			     GXimProtocol  *proto,
2043			     GCancellable  *cancellable,
2044			     GError       **error)
2045{
2046	g_return_val_if_fail (attr != NULL, 0);
2047	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
2048	g_return_val_if_fail (error != NULL, 0);
2049
2050	return g_xim_protocol_send_format(proto, cancellable, error, 4,
2051					  G_XIM_TYPE_WORD, attr->base.id,
2052					  G_XIM_TYPE_WORD, attr->base.vtype,
2053					  /* G_XIM_TYPE_GSTRING puts the size as CARD16 first then STRING8 */
2054					  G_XIM_TYPE_GSTRING, attr->attribute_name,
2055					  G_XIM_TYPE_AUTO_PADDING, 2);
2056}
2057
2058gpointer
2059g_xim_raw_attr_get_from_stream(GXimProtocol      *proto,
2060			       GDataInputStream  *stream,
2061			       GCancellable      *cancellable,
2062			       GError           **error)
2063{
2064	GXimRawAttr *retval;
2065	guint16 id;
2066	GXimValueType vtype = 0;
2067	GString *name = NULL;
2068
2069	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), NULL);
2070	g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
2071	g_return_val_if_fail (error != NULL, NULL);
2072
2073	if (!g_xim_protocol_read_format(proto, stream, cancellable, error,
2074					4,
2075					G_XIM_TYPE_WORD, &id,
2076					G_XIM_TYPE_WORD, &vtype,
2077					G_XIM_TYPE_GSTRING, &name,
2078					G_XIM_TYPE_AUTO_PADDING, 2))
2079		return NULL;
2080	retval = g_xim_raw_attr_new_with_value(id, name, vtype);
2081
2082	return retval;
2083}
2084
2085/* ATTRIBUTE */
2086GType
2087g_xim_attribute_get_type(void)
2088{
2089	static volatile gsize type_id_volatile = 0;
2090
2091	if (g_once_init_enter(&type_id_volatile)) {
2092		GType type_id;
2093
2094		type_id = g_boxed_type_register_static(g_intern_static_string("GXimAttribute"),
2095						       g_xim_attribute_copy,
2096						       g_xim_attribute_free);
2097		g_once_init_leave(&type_id_volatile, type_id);
2098	}
2099
2100	return type_id_volatile;
2101}
2102
2103gpointer
2104g_xim_attribute_new(void)
2105{
2106	GXimAttribute *retval;
2107
2108	retval = g_new0(GXimAttribute, 1);
2109	G_XIM_CHECK_ALLOC (retval, NULL);
2110
2111	retval->vtype = G_XIM_TYPE_INVALID;
2112
2113	return retval;
2114}
2115
2116gpointer
2117g_xim_attribute_new_with_value(guint16       id,
2118			       GXimValueType vtype,
2119			       gpointer      value)
2120{
2121	GXimAttribute *retval;
2122
2123	g_return_val_if_fail (vtype != G_XIM_TYPE_INVALID, NULL);
2124
2125	retval = g_xim_attribute_new();
2126	G_XIM_CHECK_ALLOC (retval, NULL);
2127
2128	g_xim_attribute_set(retval, id, vtype, value);
2129
2130	return retval;
2131}
2132
2133void
2134g_xim_attribute_set(GXimAttribute *attr,
2135		    guint16        id,
2136		    GXimValueType  vtype,
2137		    gpointer       value)
2138{
2139	GType gtype;
2140
2141	g_return_if_fail (attr != NULL);
2142	g_return_if_fail (vtype != G_XIM_TYPE_INVALID);
2143
2144	gtype = g_xim_value_type_to_gtype(vtype);
2145	g_return_if_fail (gtype != G_TYPE_INVALID);
2146
2147	g_xim_attribute_clear(attr);
2148	attr->id = id;
2149	attr->vtype = vtype;
2150	if (vtype == G_XIM_TYPE_WORD)
2151		attr->v.i = GPOINTER_TO_UINT (value);
2152	else if (vtype == G_XIM_TYPE_LONG)
2153		attr->v.l = (gulong)value;
2154	else
2155		attr->v.pointer = g_xim_copy_by_gtype(gtype, value);
2156}
2157
2158void
2159g_xim_attribute_clear(GXimAttribute *attr)
2160{
2161	GType gtype;
2162
2163	g_return_if_fail (attr != NULL);
2164
2165	if (attr->vtype == G_XIM_TYPE_INVALID)
2166		return;
2167
2168	gtype = g_xim_value_type_to_gtype(attr->vtype);
2169	g_return_if_fail (gtype != G_TYPE_INVALID);
2170
2171	g_xim_free_by_gtype(gtype, attr->v.pointer);
2172	attr->v.pointer = NULL;
2173	attr->vtype = G_XIM_TYPE_INVALID;
2174}
2175
2176gpointer
2177g_xim_attribute_copy(gpointer boxed)
2178{
2179	GXimAttribute *retval, *orig;
2180
2181	if (boxed == NULL)
2182		return NULL;
2183
2184	orig = boxed;
2185	retval = g_xim_attribute_new();
2186	G_XIM_CHECK_ALLOC (retval, NULL);
2187
2188	g_xim_attribute_set(retval, orig->id, orig->vtype, orig->v.pointer);
2189
2190	return retval;
2191}
2192
2193void
2194g_xim_attribute_free(gpointer boxed)
2195{
2196	if (boxed == NULL)
2197		return;
2198
2199	g_xim_attribute_clear(boxed);
2200	g_free(boxed);
2201}
2202
2203gsize
2204g_xim_attribute_put_to_stream(GXimAttribute *attr,
2205			      GXimProtocol  *proto,
2206			      GCancellable  *cancellable,
2207			      GError       **error)
2208{
2209	g_return_val_if_fail (G_IS_XIM_PROTOCOL (proto), 0);
2210	g_return_val_if_fail (attr != NULL, 0);
2211	g_return_val_if_fail (error != NULL, 0);
2212
2213	return g_xim_protocol_send_format(proto, cancellable, error, 4,
2214					  G_XIM_TYPE_WORD, attr->id,
2215					  G_XIM_TYPE_MARKER_N_BYTES_2, attr->vtype,
2216					  attr->vtype, attr->v.pointer,
2217					  G_XIM_TYPE_AUTO_PADDING, 0);
2218}
2219
2220/* NESTEDLIST */
2221GType
2222g_xim_nested_list_get_type(void)
2223{
2224	static volatile gsize type_id_volatile =

Large files files are truncated, but you can click here to view the full file