Git init
[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
36 static pid_t __get_win_pid(Display *d, Window win)
37 {
38         int r;
39         pid_t pid;
40
41         Atom a_type;
42         int format;
43         unsigned long nitems;
44         unsigned long bytes_after;
45         unsigned char *prop_ret;
46
47         _retv_if(d == NULL || !a_pid, -1);
48
49         prop_ret = NULL;
50         r = XGetWindowProperty(d, win, a_pid, 0, 1, False, XA_CARDINAL,
51                                &a_type, &format, &nitems, &bytes_after,
52                                &prop_ret);
53         if (r != Success || prop_ret == NULL)
54                 return -1;
55
56         if (a_type == XA_CARDINAL && format == 32)
57                 pid = *(unsigned long *)prop_ret;
58         else
59                 pid = -1;
60
61         XFree(prop_ret);
62
63         return pid;
64 }
65
66 static int __find_win(Display *d, Window *win, pid_t pid)
67 {
68         int r;
69         pid_t p;
70         unsigned int n;
71         Window root, parent, *child;
72
73         p = __get_win_pid(d, *win);
74         if (p == pid)
75                 return 1;
76
77         r = XQueryTree(d, *win, &root, &parent, &child, &n);
78         if (r) {
79                 int i;
80                 int found = 0;
81
82                 for (i = 0; i < n; i++) {
83                         found = __find_win(d, &child[i], pid);
84                         if (found) {
85                                 *win = child[i];
86                                 break;
87                         }
88                 }
89                 XFree(child);
90
91                 if (found)
92                         return 1;
93         }
94
95         return 0;
96 }
97
98 static int __raise_win(Display *d, Window win)
99 {
100         XWindowAttributes attr;
101
102         XMapRaised(d, win);
103         XGetWindowAttributes(d, win, &attr);
104         _retv_if(attr.map_state != IsViewable, -1);
105
106         /*
107          * Window Manger sets the Input Focus. 
108          * Appcore does not need to enforce this anymore.
109          *
110          * XSetInputFocus(d, win, RevertToPointerRoot, CurrentTime);
111          *
112          */
113
114         return 0;
115 }
116
117 int x_raise_win(pid_t pid)
118 {
119
120         int r;
121         int found;
122         Display *d;
123         Window win;
124
125         if (pid < 1) {
126                 errno = EINVAL;
127                 return -1;
128         }
129
130         r = kill(pid, 0);
131         if (r == -1) {
132                 errno = ESRCH;  /* No such process */
133                 return -1;
134         }
135
136         d = XOpenDisplay(NULL);
137         _retv_if(d == NULL, -1);
138
139         win = XDefaultRootWindow(d);
140
141         if (!a_pid)
142                 a_pid = XInternAtom(d, "_NET_WM_PID", True);
143
144         found = __find_win(d, &win, pid);
145         if (!found) {
146                 XCloseDisplay(d);
147                 errno = ENOENT;
148                 return -1;
149         }
150
151         r = __raise_win(d, win);
152
153         XCloseDisplay(d);
154
155         return r;
156 }