2 * notion/ioncore/property.c
4 * Copyright (c) The Notion Team 2011.
5 * Copyright (c) Tuomo Valkonen 1999-2009.
7 * See the included file LICENSE for details.
21 static ulong
xwindow_get_property_(Window win
, Atom atom
, Atom type
,
22 ulong n32expected
, bool more
, uchar
**p
,
30 status
=XGetWindowProperty(ioncore_g
.dpy
, win
, atom
, 0L, n32expected
,
31 False
, type
, &real_type
, format
, &n
,
34 if(status
!=Success
|| *p
==NULL
)
41 n32expected
+=(extra
+4)/4;
55 ulong
xwindow_get_property(Window win
, Atom atom
, Atom type
,
56 ulong n32expected
, bool more
, uchar
**p
)
59 return xwindow_get_property_(win
, atom
, type
, n32expected
, more
, p
,
67 /*{{{ String property stuff */
70 char *xwindow_get_string_property(Window win
, Atom a
, int *nret
)
75 n
=xwindow_get_property(win
, a
, XA_STRING
, 64L, TRUE
, (uchar
**)&p
);
80 return (n
<=0 ? NULL
: p
);
84 void xwindow_set_string_property(Window win
, Atom a
, const char *value
)
87 XDeleteProperty(ioncore_g
.dpy
, win
, a
);
89 XChangeProperty(ioncore_g
.dpy
, win
, a
, XA_STRING
,
90 8, PropModeReplace
, (uchar
*)value
, strlen(value
));
98 /*{{{ Integer property stuff */
101 bool xwindow_get_integer_property(Window win
, Atom a
, int *vret
)
106 n
=xwindow_get_property(win
, a
, XA_INTEGER
, 1L, FALSE
, (uchar
**)&p
);
118 void xwindow_set_integer_property(Window win
, Atom a
, int value
)
124 XChangeProperty(ioncore_g
.dpy
, win
, a
, XA_INTEGER
,
125 32, PropModeReplace
, (uchar
*)data
, 1);
132 bool xwindow_get_state_property(Window win
, int *state
)
136 if(xwindow_get_property(win
, ioncore_g
.atom_wm_state
,
137 ioncore_g
.atom_wm_state
,
138 2L, FALSE
, (uchar
**)&p
)<=0)
149 void xwindow_set_state_property(Window win
, int state
)
156 XChangeProperty(ioncore_g
.dpy
, win
,
157 ioncore_g
.atom_wm_state
, ioncore_g
.atom_wm_state
,
158 32, PropModeReplace
, (uchar
*)data
, 2);
165 /*{{{ Text property stuff */
168 char **xwindow_get_text_property(Window win
, Atom a
, int *nret
)
176 st
=XGetTextProperty(ioncore_g
.dpy
, win
, &prop
, a
);
179 *nret
=(!st
? 0 : -1);
184 #ifdef CF_XFREE86_TEXTPROP_BUG_WORKAROUND
185 while(prop
.nitems
>0){
186 if(prop
.value
[prop
.nitems
-1]=='\0')
193 if(!ioncore_g
.use_mb
){
194 Status st
=XTextPropertyToStringList(&prop
, &list
, &n
);
197 int st
=XmbTextPropertyToTextList(ioncore_g
.dpy
, &prop
, &list
, &n
);
203 if(!ok
|| n
==0 || list
==NULL
)
213 void xwindow_set_text_property(Window win
, Atom a
, const char **ptr
, int n
)
218 if(ioncore_g
.use_mb
){
220 #ifdef X_HAVE_UTF8_STRING
221 if (ioncore_g
.enc_utf8
)
222 st
=Xutf8TextListToTextProperty(ioncore_g
.dpy
, (char **)ptr
, n
,
223 XUTF8StringStyle
, &prop
);
226 st
=XmbTextListToTextProperty(ioncore_g
.dpy
, (char **)ptr
, n
,
230 Status st
=XStringListToTextProperty((char **)ptr
, n
, &prop
);
237 XSetTextProperty(ioncore_g
.dpy
, win
, &prop
, a
);
241 void xwindow_set_utf8_property(Window win
, Atom a
, const char **ptr
, int n
)
243 #ifndef X_HAVE_UTF8_STRING
244 xwindow_set_text_property(win
, a
, ptr
, n
);
249 int st
=XmbTextListToTextProperty(ioncore_g
.dpy
, (char **)ptr
, n
,
250 XUTF8StringStyle
, &prop
);
256 XSetTextProperty(ioncore_g
.dpy
, win
, &prop
, a
);
269 * Create a new atom. See \code{XInternAtom}(3) manual page for details.
272 int ioncore_x_intern_atom(const char *name
, bool only_if_exists
)
274 return XInternAtom(ioncore_g
.dpy
, name
, only_if_exists
);
279 * Get the name of an atom. See \code{XGetAtomName}(3) manual page for
283 char *ioncore_x_get_atom_name(int atom
)
285 char *xatomname
, *atomname
;
287 xatomname
= XGetAtomName(ioncore_g
.dpy
, atom
);
288 atomname
= scopy(xatomname
);
298 for(i=0; i<n; i++) extl_table_seti_i(tab, i+1, d[i]); \
303 * Get a property \var{atom} of type \var{atom_type} for window \var{win}.
304 * The \var{n32expected} parameter indicates the expected number of 32bit
305 * words, and \var{more} indicates whether all or just this amount of data
306 * should be fetched. Each 8, 16 or 32bit element of the property, as
307 * deciphered from \var{atom_type} is a field in the returned table.
308 * See \code{XGetWindowProperty}(3) manual page for more information.
312 ExtlTab
ioncore_x_get_window_property(int win
, int atom
, int atom_type
,
313 int n32expected
, bool more
)
320 n
=xwindow_get_property_(win
, atom
, atom_type
, n32expected
, more
, &p
,
324 return extl_table_none();
326 if(n
<=0 || (format
!=8 && format
!=16 && format
!=32)){
328 return extl_table_none();
331 tab
=extl_create_table();
334 case 8: CP(char); break;
335 case 16: CP(short); break;
336 case 32: CP(long); break;
345 TYPE *d=ALLOC_N(TYPE, n); \
346 if(d==NULL) return; \
347 for(i=0; i<n; i++) { \
348 if(!extl_table_geti_i(tab, i+1, &tmp)) return; \
355 static bool get_mode(const char *mode
, int *m
)
357 if(strcmp(mode
, "replace")==0)
359 else if(strcmp(mode
, "prepend")==0)
361 else if(strcmp(mode
, "append")==0)
371 * Modify a window property. The \var{mode} is one of
372 * \codestr{replace}, \codestr{prepend} or \codestr{append}, and format
373 * is either 8, 16 or 32. Also see \fnref{ioncore.x_get_window_property}
374 * and the \code{XChangeProperty}(3) manual page.
377 void ioncore_x_change_property(int win
, int atom
, int atom_type
,
378 int format
, const char *mode
, ExtlTab tab
)
380 int tmp
, m
, i
, n
=extl_table_get_n(tab
);
383 if(n
<0 || !get_mode(mode
, &m
)){
384 warn(TR("Invalid arguments."));
389 case 8: GET(char); break;
390 case 16: GET(short); break;
391 case 32: GET(long); break;
393 warn(TR("Invalid arguments."));
397 XChangeProperty(ioncore_g
.dpy
, win
, atom
, atom_type
, format
, m
, p
, n
);
404 * Delete a window property.
407 void ioncore_x_delete_property(int win
, int atom
)
409 XDeleteProperty(ioncore_g
.dpy
, win
, atom
);
414 * Get a text property for a window. The fields in the returned
415 * table (starting from 1) are the null-separated parts of the property.
416 * See the \code{XGetTextProperty}(3) manual page for more information.
420 ExtlTab
ioncore_x_get_text_property(int win
, int atom
)
424 ExtlTab tab
=extl_table_none();
426 list
=xwindow_get_text_property(win
, atom
, &n
);
430 tab
=extl_create_table();
432 extl_table_seti_s(tab
, i
+1, list
[i
]);
434 XFreeStringList(list
);
442 * Set a text property for a window. The fields of \var{tab} starting from
443 * 1 should be the different null-separated parts of the property.
444 * See the \code{XSetTextProperty}(3) manual page for more information.
447 void ioncore_x_set_text_property(int win
, int atom
, ExtlTab tab
)
450 int i
, n
=extl_table_get_n(tab
);
452 list
=ALLOC_N(char*, n
);
459 extl_table_geti_s(tab
, i
+1, &(list
[i
]));
462 xwindow_set_text_property(win
, atom
, (const char **)list
, n
);
464 XFreeStringList(list
);
468 * Set a \code{UTF8\_STRING} property for a window. The fields of \var{tab} starting
469 * from 1 should be the different null-separated parts of the property.
470 * See the \code{XSetTextProperty}(3) manual page for more information.
473 void ioncore_x_set_utf8_property(int win
, int atom
, ExtlTab tab
)
476 int i
, n
=extl_table_get_n(tab
);
478 list
=ALLOC_N(char*, n
);
485 extl_table_geti_s(tab
, i
+1, &(list
[i
]));
488 xwindow_set_utf8_property(win
, atom
, (const char **)list
, n
);
490 XFreeStringList(list
);
501 bool xwindow_get_cardinal_property(Window win
, Atom a
, CARD32
*vret
)
506 n
=xwindow_get_property(win
, a
, XA_CARDINAL
, 1L, FALSE
, (uchar
**)&p
);