1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
17 Atoms
Property::atoms
;
19 static Atom
create(char *name
) { return XInternAtom(**display
, name
, false); }
21 void Property::initialize()
25 // make sure asserts fire if there is a problem
26 memset(&atoms
, 0, sizeof(Atoms
));
28 atoms
.cardinal
= XA_CARDINAL
;
29 atoms
.window
= XA_WINDOW
;
30 atoms
.pixmap
= XA_PIXMAP
;
32 atoms
.string
= XA_STRING
;
33 atoms
.utf8
= create("UTF8_STRING");
35 atoms
.openbox_pid
= create("_OPENBOX_PID");
37 atoms
.wm_colormap_windows
= create("WM_COLORMAP_WINDOWS");
38 atoms
.wm_protocols
= create("WM_PROTOCOLS");
39 atoms
.wm_state
= create("WM_STATE");
40 atoms
.wm_change_state
= create("WM_CHANGE_STATE");
41 atoms
.wm_delete_window
= create("WM_DELETE_WINDOW");
42 atoms
.wm_take_focus
= create("WM_TAKE_FOCUS");
43 atoms
.wm_name
= create("WM_NAME");
44 atoms
.wm_icon_name
= create("WM_ICON_NAME");
45 atoms
.wm_class
= create("WM_CLASS");
46 atoms
.wm_window_role
= create("WM_WINDOW_ROLE");
47 atoms
.motif_wm_hints
= create("_MOTIF_WM_HINTS");
49 atoms
.openbox_show_root_menu
= create("_OPENBOX_SHOW_ROOT_MENU");
50 atoms
.openbox_show_workspace_menu
= create("_OPENBOX_SHOW_WORKSPACE_MENU");
52 atoms
.net_supported
= create("_NET_SUPPORTED");
53 atoms
.net_client_list
= create("_NET_CLIENT_LIST");
54 atoms
.net_client_list_stacking
= create("_NET_CLIENT_LIST_STACKING");
55 atoms
.net_number_of_desktops
= create("_NET_NUMBER_OF_DESKTOPS");
56 atoms
.net_desktop_geometry
= create("_NET_DESKTOP_GEOMETRY");
57 atoms
.net_desktop_viewport
= create("_NET_DESKTOP_VIEWPORT");
58 atoms
.net_current_desktop
= create("_NET_CURRENT_DESKTOP");
59 atoms
.net_desktop_names
= create("_NET_DESKTOP_NAMES");
60 atoms
.net_active_window
= create("_NET_ACTIVE_WINDOW");
61 atoms
.net_workarea
= create("_NET_WORKAREA");
62 atoms
.net_supporting_wm_check
= create("_NET_SUPPORTING_WM_CHECK");
63 // atoms.net_virtual_roots = create("_NET_VIRTUAL_ROOTS");
64 atoms
.net_desktop_layout
= create("_NET_DESKTOP_LAYOUT");
65 atoms
.net_showing_desktop
= create("_NET_SHOWING_DESKTOP");
67 atoms
.net_close_window
= create("_NET_CLOSE_WINDOW");
68 atoms
.net_wm_moveresize
= create("_NET_WM_MOVERESIZE");
70 // atoms.net_properties = create("_NET_PROPERTIES");
71 atoms
.net_wm_name
= create("_NET_WM_NAME");
72 atoms
.net_wm_visible_name
= create("_NET_WM_VISIBLE_NAME");
73 atoms
.net_wm_icon_name
= create("_NET_WM_ICON_NAME");
74 atoms
.net_wm_visible_icon_name
= create("_NET_WM_VISIBLE_ICON_NAME");
75 atoms
.net_wm_desktop
= create("_NET_WM_DESKTOP");
76 atoms
.net_wm_window_type
= create("_NET_WM_WINDOW_TYPE");
77 atoms
.net_wm_state
= create("_NET_WM_STATE");
78 atoms
.net_wm_strut
= create("_NET_WM_STRUT");
79 // atoms.net_wm_icon_geometry = create("_NET_WM_ICON_GEOMETRY");
80 atoms
.net_wm_icon
= create("_NET_WM_ICON");
81 // atoms.net_wm_pid = create("_NET_WM_PID");
82 // atoms.net_wm_handled_icons = create("_NET_WM_HANDLED_ICONS");
83 atoms
.net_wm_allowed_actions
= create("_NET_WM_ALLOWED_ACTIONS");
85 // atoms.net_wm_ping = create("_NET_WM_PING");
87 atoms
.net_wm_window_type_desktop
= create("_NET_WM_WINDOW_TYPE_DESKTOP");
88 atoms
.net_wm_window_type_dock
= create("_NET_WM_WINDOW_TYPE_DOCK");
89 atoms
.net_wm_window_type_toolbar
= create("_NET_WM_WINDOW_TYPE_TOOLBAR");
90 atoms
.net_wm_window_type_menu
= create("_NET_WM_WINDOW_TYPE_MENU");
91 atoms
.net_wm_window_type_utility
= create("_NET_WM_WINDOW_TYPE_UTILITY");
92 atoms
.net_wm_window_type_splash
= create("_NET_WM_WINDOW_TYPE_SPLASH");
93 atoms
.net_wm_window_type_dialog
= create("_NET_WM_WINDOW_TYPE_DIALOG");
94 atoms
.net_wm_window_type_normal
= create("_NET_WM_WINDOW_TYPE_NORMAL");
96 atoms
.net_wm_moveresize_size_topleft
=
97 create("_NET_WM_MOVERESIZE_SIZE_TOPLEFT");
98 atoms
.net_wm_moveresize_size_topright
=
99 create("_NET_WM_MOVERESIZE_SIZE_TOPRIGHT");
100 atoms
.net_wm_moveresize_size_bottomleft
=
101 create("_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT");
102 atoms
.net_wm_moveresize_size_bottomright
=
103 create("_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT");
104 atoms
.net_wm_moveresize_move
=
105 create("_NET_WM_MOVERESIZE_MOVE");
107 atoms
.net_wm_action_move
= create("_NET_WM_ACTION_MOVE");
108 atoms
.net_wm_action_resize
= create("_NET_WM_ACTION_RESIZE");
109 atoms
.net_wm_action_minimize
= create("_NET_WM_ACTION_MINIMIZE");
110 atoms
.net_wm_action_shade
= create("_NET_WM_ACTION_SHADE");
111 atoms
.net_wm_action_stick
= create("_NET_WM_ACTION_STICK");
112 atoms
.net_wm_action_maximize_horz
= create("_NET_WM_ACTION_MAXIMIZE_HORZ");
113 atoms
.net_wm_action_maximize_vert
= create("_NET_WM_ACTION_MAXIMIZE_VERT");
114 atoms
.net_wm_action_fullscreen
= create("_NET_WM_ACTION_FULLSCREEN");
115 atoms
.net_wm_action_change_desktop
=
116 create("_NET_WM_ACTION_CHANGE_DESKTOP");
117 atoms
.net_wm_action_close
= create("_NET_WM_ACTION_CLOSE");
119 atoms
.net_wm_state_modal
= create("_NET_WM_STATE_MODAL");
120 atoms
.net_wm_state_sticky
= create("_NET_WM_STATE_STICKY");
121 atoms
.net_wm_state_maximized_vert
= create("_NET_WM_STATE_MAXIMIZED_VERT");
122 atoms
.net_wm_state_maximized_horz
= create("_NET_WM_STATE_MAXIMIZED_HORZ");
123 atoms
.net_wm_state_shaded
= create("_NET_WM_STATE_SHADED");
124 atoms
.net_wm_state_skip_taskbar
= create("_NET_WM_STATE_SKIP_TASKBAR");
125 atoms
.net_wm_state_skip_pager
= create("_NET_WM_STATE_SKIP_PAGER");
126 atoms
.net_wm_state_hidden
= create("_NET_WM_STATE_HIDDEN");
127 atoms
.net_wm_state_fullscreen
= create("_NET_WM_STATE_FULLSCREEN");
128 atoms
.net_wm_state_above
= create("_NET_WM_STATE_ABOVE");
129 atoms
.net_wm_state_below
= create("_NET_WM_STATE_BELOW");
131 atoms
.net_wm_state_add
= 1;
132 atoms
.net_wm_state_remove
= 0;
133 atoms
.net_wm_state_toggle
= 2;
135 atoms
.kde_net_system_tray_windows
= create("_KDE_NET_SYSTEM_TRAY_WINDOWS");
136 atoms
.kde_net_wm_system_tray_window_for
=
137 create("_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR");
138 atoms
.kde_net_wm_window_type_override
=
139 create("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
141 atoms
.kwm_win_icon
= create("KWM_WIN_ICON");
143 atoms
.rootpmapid
= create("_XROOTPMAP_ID");
144 atoms
.esetrootid
= create("ESETROOT_PMAP_ID");
146 atoms
.openbox_premax
= create("_OPENBOX_PREMAX");
147 atoms
.openbox_active_window
= create("_OPENBOX_ACTIVE_WINDOW");
148 atoms
.openbox_restack_window
= create("_OPENBOX_RESTACK_WINDOW");
151 void Property::set(Window win
, Atom atom
, Atom type
, unsigned char* data
,
152 int size
, int nelements
, bool append
)
154 assert(win
!= None
); assert(atom
!= None
); assert(type
!= None
);
155 assert(nelements
== 0 || (nelements
> 0 && data
!= (unsigned char *) 0));
156 assert(size
== 8 || size
== 16 || size
== 32);
157 XChangeProperty(**display
, win
, atom
, type
, size
,
158 (append
? PropModeAppend
: PropModeReplace
),
162 void Property::set(Window win
, Atom atom
, Atom type
, unsigned long value
)
164 set(win
, atom
, type
, (unsigned char*) &value
, 32, 1, false);
167 void Property::set(Window win
, Atom atom
, Atom type
, unsigned long value
[],
170 set(win
, atom
, type
, (unsigned char*) value
, 32, elements
, false);
173 void Property::set(Window win
, Atom atom
, StringType type
,
174 const ustring
&value
)
178 case ascii
: t
= atoms
.string
; assert(!value
.utf8()); break;
179 case utf8
: t
= atoms
.utf8
; assert(value
.utf8()); break;
180 default: assert(false); return; // unhandled StringType
183 // add 1 to the size to include the trailing null
184 set(win
, atom
, t
, (unsigned char*) value
.c_str(), 8, value
.bytes() + 1,
188 void Property::set(Window win
, Atom atom
, StringType type
,
189 const StringVect
&strings
)
192 bool u
; // utf8 encoded?
194 case ascii
: t
= atoms
.string
; u
= false; break;
195 case utf8
: t
= atoms
.utf8
; u
= true; break;
196 default: assert(false); return; // unhandled StringType
201 StringVect::const_iterator it
= strings
.begin();
202 const StringVect::const_iterator end
= strings
.end();
203 for (; it
!= end
; ++it
) {
204 assert(it
->utf8() == u
); // the ustring is encoded correctly?
209 // add 1 to the size to include the trailing null
210 set(win
, atom
, t
, (unsigned char*)value
.c_str(), 8,
211 value
.bytes() + 1, false);
214 bool Property::get(Window win
, Atom atom
, Atom type
, unsigned long *nelements
,
215 unsigned char **value
, int size
)
217 assert(win
!= None
); assert(atom
!= None
); assert(type
!= None
);
218 assert(size
== 8 || size
== 16 || size
== 32);
219 unsigned char *c_val
= 0; // value alloc'd in Xlib, must be XFree()d
222 unsigned long ret_bytes
;
226 // try get the first element
227 result
= XGetWindowProperty(**display
, win
, atom
, 0l, 1l,
228 false, AnyPropertyType
, &ret_type
, &ret_size
,
229 nelements
, &ret_bytes
, &c_val
);
230 ret
= (result
== Success
&& ret_type
== type
&& ret_size
== size
&&
233 if (ret_bytes
== 0) {
234 // we got the whole property's value
235 *value
= new unsigned char[*nelements
* size
/8 + 1];
236 memcpy(*value
, c_val
, *nelements
* size
/8 + 1);
238 // get the entire property since it is larger than one long
240 // the number of longs that need to be retreived to get the property's
241 // entire value. The last + 1 is the first long that we retrieved above.
242 long remain
= (ret_bytes
- 1)/sizeof(long) + 1 + 1;
243 result
= XGetWindowProperty(**display
, win
, atom
, 0l,
244 remain
, false, type
, &ret_type
, &ret_size
,
245 nelements
, &ret_bytes
, &c_val
);
246 ret
= (result
== Success
&& ret_type
== type
&& ret_size
== size
);
248 If the property has changed type/size, or has grown since our first
249 read of it, then stop here and try again. If it shrank, then this will
253 return get(win
, atom
, type
, nelements
, value
, size
);
256 *value
= new unsigned char[*nelements
* size
/8 + 1];
257 memcpy(*value
, c_val
, *nelements
* size
/8 + 1);
260 if (c_val
) XFree(c_val
);
264 bool Property::get(Window win
, Atom atom
, Atom type
, unsigned long *nelements
,
265 unsigned long **value
)
267 return get(win
, atom
, type
, nelements
, (unsigned char**) value
, 32);
270 bool Property::get(Window win
, Atom atom
, Atom type
, unsigned long *value
)
274 if (! get(win
, atom
, type
, &num
, (unsigned char **) &temp
, 32))
284 bool Property::get(Window win
, Atom atom
, StringType type
, ustring
*value
)
289 if (get(win
, atom
, type
, &n
, &s
) && n
> 0) {
296 bool Property::get(Window win
, Atom atom
, StringType type
,
297 unsigned long *nelements
, StringVect
*strings
)
300 bool u
; // utf8 encoded?
302 case ascii
: t
= atoms
.string
; u
= false; break;
303 case utf8
: t
= atoms
.utf8
; u
= true; break;
304 default: assert(false); return false; // unhandled StringType
307 unsigned char *value
;
308 unsigned long elements
;;
309 if (!get(win
, atom
, t
, &elements
, &value
, 8) || elements
< 1)
312 std::string
s((char*)value
, elements
);
315 std::string::const_iterator it
= s
.begin(), end
= s
.end();
316 unsigned long num
= 0;
318 std::string::const_iterator tmp
= it
; // current string.begin()
319 it
= std::find(tmp
, end
, '\0'); // look for null between tmp and end
320 strings
->push_back(std::string(tmp
, it
)); // s[tmp:it)
321 strings
->back().setUtf8(u
);
323 if (it
== end
) break;
325 if (it
== end
) break;
335 * Removes a property entirely from a window.
337 void Property::erase(Window win
, Atom atom
)
339 XDeleteProperty(**display
, win
, atom
);