6 #include "proc-winstate.h"
8 #include "proc-process.h"
9 #include "proc-monitor.h"
13 #include <X11/Xatom.h>
16 #include <Ecore_Evas.h>
17 #include <Ecore_Input_Evas.h>
21 typedef struct _ProcWininfo {
22 struct _ProcWininfo *prev, *next;
26 } ProcWininfo, *ProcWininfoPtr;
28 static pid_t __get_win_pid(Display *d, Window win)
36 unsigned long bytes_after;
37 unsigned char *prop_ret;
38 XWindowAttributes attr;
40 //_retv_if(d == NULL || !a_pid, -1);
42 if (!XGetWindowAttributes(d, win, &attr))
45 if (attr.override_redirect || attr.class == InputOnly)
49 r = XGetWindowProperty(d, win, a_pid, 0, 1, False, XA_CARDINAL,
50 &a_type, &format, &nitems, &bytes_after,
52 if (r != Success || prop_ret == NULL)
55 if (a_type == XA_CARDINAL && format == 32)
56 pid = *(unsigned long *)prop_ret;
65 static Window get_window(Display *d, Window win)
68 int ret, size_ret = 0;
69 unsigned long num_ret = 0, bytes = 0;
70 unsigned char *prop_ret = NULL;
72 Atom prop_user_created_win;
74 prop_user_created_win = XInternAtom(d, "_E_USER_CREATED_WINDOW", False);
76 ret = XGetWindowProperty(d, win, prop_user_created_win, 0L, 1L,
77 False, XA_WINDOW, &type_ret, &size_ret,
78 &num_ret, &bytes, &prop_ret);
82 if( prop_ret ) XFree( (void*)prop_ret );
90 memcpy( &xid, prop_ret, sizeof(unsigned int) );
91 XFree( (void *)prop_ret );
96 static void free_procwininfo(ProcWininfoPtr procwininfo)
99 /* TODO : free winname and appname map_state*/
127 static int __find_win(Display *d, pid_t pid)
132 int win_index = 0, winid = 0;
133 Window root, parent, *child;
135 ProcWininfoPtr prev_wininfo = NULL;
136 ProcWininfoPtr cur_wininfo = NULL;
137 ProcWininfoPtr origin_wininfo = NULL;
138 XWindowAttributes attr;
140 win = XDefaultRootWindow(d);
142 r = XQueryTree(d, win, &root, &parent, &child, &n);
144 _E("Can't query window tree.");
148 for (i = (int)n - 1; i >= 0; i--)
150 if (!XGetWindowAttributes(d, child[i], &attr)) {
151 _E("Can't get window tree.");
154 if (attr.map_state) {
155 cur_wininfo = (ProcWininfoPtr) malloc(sizeof(ProcWininfo));
156 cur_wininfo->idx = win_index++;
157 cur_wininfo->next = NULL;
158 cur_wininfo->prev = NULL;
159 cur_wininfo->winid = child[i];
164 prev_wininfo->next = cur_wininfo;
165 cur_wininfo->prev = prev_wininfo;
167 origin_wininfo = cur_wininfo;
169 /* set the pre_wininfo is the cur_wininfo now */
170 prev_wininfo = cur_wininfo;
172 if (!origin_wininfo) {
173 _E("Can't get valid window info");
175 XFree((char *)child);
179 ProcWininfoPtr w = origin_wininfo;
180 for(i = 0; i < win_index; i++)
182 winid = get_window(d, w->winid);
184 p = __get_win_pid(d, w->winid);
187 _D("__find_win : pid %d, win %x", pid, w->winid);
188 ecore_x_window_client_sniff(w->winid);
193 XFree((char *)child);
194 free_procwininfo(origin_wininfo);
198 static inline int _get_pid(Ecore_X_Window win)
202 unsigned char *in_pid = NULL;
205 atom = ecore_x_atom_get("X_CLIENT_PID");
206 if (ecore_x_window_prop_property_get(win, atom, ECORE_X_ATOM_CARDINAL,
207 sizeof(int), &in_pid, &num) == EINA_FALSE) {
212 if (ecore_x_netwm_pid_get(win, &pid) == EINA_FALSE) {
213 _E("Failed to get PID from a window 0x%X", win);
217 pid = *(int *)in_pid;
224 static Eina_Bool __proc_deiconify_cb(void *data, int type, void *event)
226 Ecore_X_Event_Client_Message *ev;
227 int pid, oom_score_adj;
231 if (ev->format != 32)
232 return ECORE_CALLBACK_RENEW;
233 if (ev->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
235 pid = _get_pid(ev->win);
237 _D("pid : %d received ediconify approve", pid);
239 if (proc_get_oom_score_adj(pid, &oom_score_adj) < 0) {
240 _E("Failed to get oom_score_adj");
241 return ECORE_CALLBACK_RENEW;
244 if (oom_score_adj >= OOMADJ_BACKGRD_UNLOCKED) {
245 /* init oom_score_value */
246 proc_set_oom_score_adj(pid, OOMADJ_INIT);
250 return ECORE_CALLBACK_RENEW;
254 static Eina_Bool __proc_visibility_cb(void *data, int type, void *event)
256 Ecore_X_Event_Window_Visibility_Change *ev;
257 int pid, oom_score_adj;
261 pid = _get_pid(ev->win);
263 _D("pid : %d, bvisibility : %d", pid, ev->fully_obscured);
265 if (proc_get_oom_score_adj(pid, &oom_score_adj) < 0) {
266 _E("Failed to get oom_score_adj");
267 return ECORE_CALLBACK_RENEW;
270 if (oom_score_adj >= OOMADJ_BACKGRD_UNLOCKED) {
271 /* init oom_score_value */
272 proc_set_oom_score_adj(pid, OOMADJ_INIT);
275 return ECORE_CALLBACK_RENEW;
279 int proc_add_visibiliry(int pid)
284 if (proc_get_dbus_proc_state())
285 return RESOURCED_ERROR_NO_DATA;
286 d = XOpenDisplay(NULL);
289 _E("XOpenDisplay return NULL, pid = %d", pid);
290 return RESOURCED_ERROR_FAIL;
294 a_pid = XInternAtom(d, "_NET_WM_PID", True);
296 found = __find_win(d, pid);
301 return RESOURCED_ERROR_FAIL;
303 _D("%d window added for pid = %d", found, pid);
305 return RESOURCED_ERROR_NONE;
309 int proc_win_status_init(void)
312 ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
313 __proc_deiconify_cb, NULL);
315 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE,
316 __proc_visibility_cb, NULL);
317 return RESOURCED_ERROR_NONE;