PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/libgxim/gximmisc.c

https://bitbucket.org/tagoh/libgxim
C | 3748 lines | 3086 code | 568 blank | 94 comment | 427 complexity | 9ea8c823d030f144d3f31c6845184b52 MD5 | raw file
Possible License(s): LGPL-2.1

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

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