merged with private
[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
48         _retv_if(d == NULL || !a_pid, -1);
49
50         prop_ret = NULL;
51         r = XGetWindowProperty(d, win, a_pid, 0, 1, False, XA_CARDINAL,
52                                &a_type, &format, &nitems, &bytes_after,
53                                &prop_ret);
54         if (r != Success || prop_ret == NULL)
55                 return -1;
56
57         if (a_type == XA_CARDINAL && format == 32)
58                 pid = *(unsigned long *)prop_ret;
59         else
60                 pid = -1;
61
62         XFree(prop_ret);
63
64         return pid;
65 }
66
67 static int __find_win(Display *d, Window *win, pid_t pid)
68 {
69         int r;
70         pid_t p;
71         unsigned int n;
72         Window root, parent, *child;
73
74         p = __get_win_pid(d, *win);
75         if (p == pid)
76                 return 1;
77
78         r = XQueryTree(d, *win, &root, &parent, &child, &n);
79         if (r) {
80                 int i;
81                 int found = 0;
82
83                 for (i = 0; i < n; i++) {
84                         found = __find_win(d, &child[i], pid);
85                         if (found) {
86                                 *win = child[i];
87                                 break;
88                         }
89                 }
90                 XFree(child);
91
92                 if (found)
93                         return 1;
94         }
95
96         return 0;
97 }
98
99 static int __raise_win(Display *d, Window win)
100 {
101         XEvent xev;
102         Window root;
103
104         if (!a_active_win)
105                 a_active_win = XInternAtom(d, "_NET_ACTIVE_WINDOW", False);
106
107         root = XDefaultRootWindow(d);
108
109         xev.xclient.type = ClientMessage;
110         xev.xclient.display = d;
111         xev.xclient.window = win;
112         xev.xclient.message_type = a_active_win;
113         xev.xclient.format = 32;
114         xev.xclient.data.l[0] = 1;
115         xev.xclient.data.l[1] = CurrentTime;
116         xev.xclient.data.l[2] = 0;
117         xev.xclient.data.l[3] = 0;
118         xev.xclient.data.l[4] = 0;
119         XSendEvent(d, root, False,
120                    SubstructureRedirectMask | SubstructureNotifyMask, &xev);
121
122         return 0;
123 }
124
125 int x_raise_win(pid_t pid)
126 {
127
128         int r;
129         int found;
130         Display *d;
131         Window win;
132
133         if (pid < 1) {
134                 errno = EINVAL;
135                 return -1;
136         }
137
138         r = kill(pid, 0);
139         if (r == -1) {
140                 errno = ESRCH;  /* No such process */
141                 return -1;
142         }
143
144         d = XOpenDisplay(NULL);
145         _retv_if(d == NULL, -1);
146
147         win = XDefaultRootWindow(d);
148
149         if (!a_pid)
150                 a_pid = XInternAtom(d, "_NET_WM_PID", True);
151
152         found = __find_win(d, &win, pid);
153         if (!found) {
154                 XCloseDisplay(d);
155                 errno = ENOENT;
156                 return -1;
157         }
158
159         r = __raise_win(d, win);
160
161         XCloseDisplay(d);
162
163         return r;
164 }