input: Rename weston_device_repick() to weston_seat_repick()
[platform/upstream/weston.git] / src / launcher-util.c
1 /*
2  * Copyright © 2012 Benjamin Franzke
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <errno.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/uio.h>
32 #include <fcntl.h>
33
34 #include <xf86drm.h>
35
36 #include "compositor.h"
37 #include "launcher-util.h"
38 #include "weston-launch.h"
39
40 union cmsg_data { unsigned char b[4]; int fd; };
41
42 int
43 weston_launcher_open(struct weston_compositor *compositor,
44                      const char *path, int flags)
45 {
46         int sock = compositor->launcher_sock;
47         int n, ret = -1;
48         struct msghdr msg;
49         struct cmsghdr *cmsg;
50         struct iovec iov;
51         union cmsg_data *data;
52         char control[CMSG_SPACE(sizeof data->fd)];
53         ssize_t len;
54         struct weston_launcher_open *message;
55
56         if (sock == -1)
57                 return open(path, flags | O_CLOEXEC);
58
59         n = sizeof(*message) + strlen(path) + 1;
60         message = malloc(n);
61         if (!message)
62                 return -1;
63
64         message->header.opcode = WESTON_LAUNCHER_OPEN;
65         message->flags = flags;
66         strcpy(message->path, path);
67
68         do {
69                 len = send(sock, message, n, 0);
70         } while (len < 0 && errno == EINTR);
71         free(message);
72
73         memset(&msg, 0, sizeof msg);
74         iov.iov_base = &ret;
75         iov.iov_len = sizeof ret;
76         msg.msg_iov = &iov;
77         msg.msg_iovlen = 1;
78         msg.msg_control = control;
79         msg.msg_controllen = sizeof control;
80         
81         do {
82                 len = recvmsg(sock, &msg, MSG_CMSG_CLOEXEC);
83         } while (len < 0 && errno == EINTR);
84
85         if (len != sizeof ret ||
86             ret < 0)
87                 return -1;
88
89         cmsg = CMSG_FIRSTHDR(&msg);
90         if (!cmsg ||
91             cmsg->cmsg_level != SOL_SOCKET ||
92             cmsg->cmsg_type != SCM_RIGHTS) {
93                 fprintf(stderr, "invalid control message\n");
94                 return -1;
95         }
96
97         data = (union cmsg_data *) CMSG_DATA(cmsg);
98         if (data->fd == -1) {
99                 fprintf(stderr, "missing drm fd in socket request\n");
100                 return -1;
101         }
102
103         return data->fd;
104 }
105
106 int
107 weston_launcher_drm_set_master(struct weston_compositor *compositor,
108                                int drm_fd, char master)
109 {
110         struct msghdr msg;
111         struct cmsghdr *cmsg;
112         struct iovec iov;
113         char control[CMSG_SPACE(sizeof(drm_fd))];
114         int ret;
115         ssize_t len;
116         struct weston_launcher_set_master message;
117         union cmsg_data *data;
118
119         if (compositor->launcher_sock == -1) {
120                 if (master)
121                         return drmSetMaster(drm_fd);
122                 else
123                         return drmDropMaster(drm_fd);
124         }
125
126         memset(&msg, 0, sizeof msg);
127         msg.msg_iov = &iov;
128         msg.msg_iovlen = 1;
129         msg.msg_control = control;
130         msg.msg_controllen = sizeof control;
131         cmsg = CMSG_FIRSTHDR(&msg);
132         cmsg->cmsg_level = SOL_SOCKET;
133         cmsg->cmsg_type = SCM_RIGHTS;
134         cmsg->cmsg_len = CMSG_LEN(sizeof(drm_fd));
135
136         data = (union cmsg_data *) CMSG_DATA(cmsg);
137         data->fd = drm_fd;
138         msg.msg_controllen = cmsg->cmsg_len;
139
140         iov.iov_base = &message;
141         iov.iov_len = sizeof message;
142
143         message.header.opcode = WESTON_LAUNCHER_DRM_SET_MASTER;
144         message.set_master = master;
145
146         do {
147                 len = sendmsg(compositor->launcher_sock, &msg, 0);
148         } while (len < 0 && errno == EINTR);
149         if (len < 0)
150                 return -1;
151
152         do {
153                 len = recv(compositor->launcher_sock, &ret, sizeof ret, 0);
154         } while (len < 0 && errno == EINTR);
155         if (len < 0)
156                 return -1;
157
158         return ret;
159 }
160