upload tizen1.0 source
[framework/appfw/app-core.git] / src / appcore-X.c
1 /*
2  *  app-core
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <signal.h>
28
29 #include <X11/Xlib.h>
30 #include <X11/Xatom.h>
31
32 #include "appcore-internal.h"
33
34 static Atom a_pid;
35 static Atom a_active_win;
36
37 static pid_t __get_win_pid(Display *d, Window win)
38 {
39         int r;
40         pid_t pid;
41
42         Atom a_type;
43         int format;
44         unsigned long nitems;
45         unsigned long bytes_after;
46         unsigned char *prop_ret;
47         XWindowAttributes attr;
48
49         _retv_if(d == NULL || !a_pid, -1);
50
51         if (!XGetWindowAttributes(d, win, &attr))
52                 return -1;
53
54         if (attr.override_redirect || attr.class == InputOnly)
55                 return -1;
56
57         prop_ret = NULL;
58         r = XGetWindowProperty(d, win, a_pid, 0, 1, False, XA_CARDINAL,
59                                &a_type, &format, &nitems, &bytes_after,
60                                &prop_ret);
61         if (r != Success || prop_ret == NULL)
62                 return -1;
63
64         if (a_type == XA_CARDINAL && format == 32)
65                 pid = *(unsigned long *)prop_ret;
66         else
67                 pid = -1;
68
69         XFree(prop_ret);
70
71         return pid;
72 }
73
74 static int __find_win(Display *d, Window *win, pid_t pid)
75 {
76         int r;
77         pid_t p;
78         unsigned int n;
79         Window root, parent, *child;
80
81         p = __get_win_pid(d, *win);
82         if (p == pid)
83                 return 1;
84
85         r = XQueryTree(d, *win, &root, &parent, &child, &n);
86         if (r) {
87                 int i;
88                 int found = 0;
89
90                 for (i = 0; i < n; i++) {
91                         found = __find_win(d, &child[i], pid);
92                         if (found) {
93                                 *win = child[i];
94                                 break;
95                         }
96                 }
97                 XFree(child);
98
99                 if (found)
100                         return 1;
101         }
102
103         return 0;
104 }
105
106 static int __raise_win(Display *d, Window win)
107 {
108         XEvent xev;
109         Window root;
110
111         if (!a_active_win)
112                 a_active_win = XInternAtom(d, "_NET_ACTIVE_WINDOW", False);
113
114         root = XDefaultRootWindow(d);
115
116         xev.xclient.type = ClientMessage;
117         xev.xclient.display = d;
118         xev.xclient.window = win;
119         xev.xclient.message_type = a_active_win;
120         xev.xclient.format = 32;
121         xev.xclient.data.l[0] = 1;
122         xev.xclient.data.l[1] = CurrentTime;
123         xev.xclient.data.l[2] = 0;
124         xev.xclient.data.l[3] = 0;
125         xev.xclient.data.l[4] = 0;
126         XSendEvent(d, root, False,
127                    SubstructureRedirectMask | SubstructureNotifyMask, &xev);
128
129         return 0;
130 }
131
132 int x_raise_win(pid_t pid)
133 {
134
135         int r;
136         int found;
137         Display *d;
138         Window win;
139
140         if (pid < 1) {
141                 errno = EINVAL;
142                 return -1;
143         }
144
145         r = kill(pid, 0);
146         if (r == -1) {
147                 errno = ESRCH;  /* No such process */
148                 return -1;
149         }
150
151         d = XOpenDisplay(NULL);
152         _retv_if(d == NULL, -1);
153
154         win = XDefaultRootWindow(d);
155
156         if (!a_pid)
157                 a_pid = XInternAtom(d, "_NET_WM_PID", True);
158
159         found = __find_win(d, &win, pid);
160         if (!found) {
161                 XCloseDisplay(d);
162                 errno = ENOENT;
163                 return -1;
164         }
165
166         r = __raise_win(d, win);
167
168         XCloseDisplay(d);
169
170         return r;
171 }