source: mainline/uspace/srv/clip/clip.c@ 1e4cada

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1e4cada was 1e4cada, checked in by Martin Decky <martin@…>, 16 years ago

rename fibril_sync.[ch] to fibril_synch.[ch]

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2009 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <stdio.h>
30#include <bool.h>
31#include <ipc/ipc.h>
32#include <async.h>
33#include <ipc/services.h>
34#include <ipc/clipboard.h>
35#include <malloc.h>
36#include <fibril_synch.h>
37#include <errno.h>
38
39#define NAME "clip"
40
41static char *clip_data = NULL;
42static size_t clip_size = 0;
43static clipboard_tag_t clip_tag = CLIPBOARD_TAG_NONE;
44static FIBRIL_MUTEX_INITIALIZE(clip_mtx);
45
46static void clip_put_data(ipc_callid_t rid, ipc_call_t *request)
47{
48 ipc_callid_t callid;
49 size_t size;
50
51 switch (IPC_GET_ARG1(*request)) {
52 case CLIPBOARD_TAG_NONE:
53 fibril_mutex_lock(&clip_mtx);
54
55 if (clip_data)
56 free(clip_data);
57
58 clip_data = NULL;
59 clip_size = 0;
60 clip_tag = CLIPBOARD_TAG_NONE;
61
62 fibril_mutex_unlock(&clip_mtx);
63 ipc_answer_0(rid, EOK);
64 break;
65 case CLIPBOARD_TAG_BLOB:
66 if (!async_data_write_receive(&callid, &size)) {
67 ipc_answer_0(callid, EINVAL);
68 ipc_answer_0(rid, EINVAL);
69 break;
70 }
71
72 char *data = malloc(size);
73 if (!data) {
74 ipc_answer_0(callid, ENOMEM);
75 ipc_answer_0(rid, ENOMEM);
76 break;
77 }
78
79 ipcarg_t retval = async_data_write_finalize(callid, data, size);
80 if (retval != EOK) {
81 ipc_answer_0(rid, retval);
82 free(data);
83 break;
84 }
85
86 fibril_mutex_lock(&clip_mtx);
87
88 if (clip_data)
89 free(clip_data);
90
91 clip_data = data;
92 clip_size = size;
93 clip_tag = CLIPBOARD_TAG_BLOB;
94
95 fibril_mutex_unlock(&clip_mtx);
96 ipc_answer_0(rid, EOK);
97 break;
98 default:
99 ipc_answer_0(rid, EINVAL);
100 }
101}
102
103static void clip_get_data(ipc_callid_t rid, ipc_call_t *request)
104{
105 fibril_mutex_lock(&clip_mtx);
106
107 ipc_callid_t callid;
108 size_t size;
109
110 /* Check for clipboard data tag compatibility */
111 switch (IPC_GET_ARG1(*request)) {
112 case CLIPBOARD_TAG_BLOB:
113 if (!async_data_read_receive(&callid, &size)) {
114 ipc_answer_0(callid, EINVAL);
115 ipc_answer_0(rid, EINVAL);
116 break;
117 }
118
119 if (clip_tag != CLIPBOARD_TAG_BLOB) {
120 /* So far we only understand BLOB */
121 ipc_answer_0(callid, EOVERFLOW);
122 ipc_answer_0(rid, EOVERFLOW);
123 break;
124 }
125
126 if (clip_size != size) {
127 /* The client expects different size of data */
128 ipc_answer_0(callid, EOVERFLOW);
129 ipc_answer_0(rid, EOVERFLOW);
130 break;
131 }
132
133 ipcarg_t retval = async_data_read_finalize(callid, clip_data, size);
134 if (retval != EOK) {
135 ipc_answer_0(rid, retval);
136 break;
137 }
138
139 ipc_answer_0(rid, EOK);
140 default:
141 /*
142 * Sorry, we don't know how to get unknown or NONE
143 * data from the clipbard
144 */
145 ipc_answer_0(rid, EINVAL);
146 break;
147 }
148
149 fibril_mutex_unlock(&clip_mtx);
150}
151
152static void clip_content(ipc_callid_t rid, ipc_call_t *request)
153{
154 fibril_mutex_lock(&clip_mtx);
155
156 size_t size = clip_size;
157 clipboard_tag_t tag = clip_tag;
158
159 fibril_mutex_unlock(&clip_mtx);
160 ipc_answer_2(rid, EOK, (ipcarg_t) size, (ipcarg_t) clip_tag);
161}
162
163static void clip_connection(ipc_callid_t iid, ipc_call_t *icall)
164{
165 /* Accept connection */
166 ipc_answer_0(iid, EOK);
167
168 bool cont = true;
169 while (cont) {
170 ipc_call_t call;
171 ipc_callid_t callid = async_get_call(&call);
172
173 switch (IPC_GET_METHOD(call)) {
174 case IPC_M_PHONE_HUNGUP:
175 cont = false;
176 continue;
177 case CLIPBOARD_PUT_DATA:
178 clip_put_data(callid, &call);
179 break;
180 case CLIPBOARD_GET_DATA:
181 clip_get_data(callid, &call);
182 break;
183 case CLIPBOARD_CONTENT:
184 clip_content(callid, &call);
185 break;
186 default:
187 if (!(callid & IPC_CALLID_NOTIFICATION))
188 ipc_answer_0(callid, ENOENT);
189 }
190 }
191}
192
193int main(int argc, char *argv[])
194{
195 printf(NAME ": HelenOS clipboard service\n");
196
197 async_set_client_connection(clip_connection);
198
199 ipcarg_t phonead;
200 if (ipc_connect_to_me(PHONE_NS, SERVICE_CLIPBOARD, 0, 0, &phonead) != 0)
201 return -1;
202
203 printf(NAME ": Accepting connections\n");
204 async_manager();
205
206 /* Never reached */
207 return 0;
208}
Note: See TracBrowser for help on using the repository browser.