source: mainline/uspace/srv/clip/clip.c@ 9c81703

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9c81703 was 007e6efa, checked in by Martin Decky <martin@…>, 15 years ago
  • libc routines for registering services and connecting to services via NS
  • async_connect_to_me()
  • Property mode set to 100644
File size: 4.7 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 <async.h>
32#include <ipc/ipc.h>
33#include <ipc/ns.h>
34#include <ipc/services.h>
35#include <ipc/clipboard.h>
36#include <malloc.h>
37#include <fibril_synch.h>
38#include <errno.h>
39
40#define NAME "clip"
41
42static char *clip_data = NULL;
43static size_t clip_size = 0;
44static clipboard_tag_t clip_tag = CLIPBOARD_TAG_NONE;
45static FIBRIL_MUTEX_INITIALIZE(clip_mtx);
46
47static void clip_put_data(ipc_callid_t rid, ipc_call_t *request)
48{
49 char *data;
50 int rc;
51 size_t size;
52
53 switch (IPC_GET_ARG1(*request)) {
54 case CLIPBOARD_TAG_NONE:
55 fibril_mutex_lock(&clip_mtx);
56
57 if (clip_data)
58 free(clip_data);
59
60 clip_data = NULL;
61 clip_size = 0;
62 clip_tag = CLIPBOARD_TAG_NONE;
63
64 fibril_mutex_unlock(&clip_mtx);
65 ipc_answer_0(rid, EOK);
66 break;
67 case CLIPBOARD_TAG_DATA:
68 rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size);
69 if (rc != EOK) {
70 ipc_answer_0(rid, rc);
71 break;
72 }
73
74 fibril_mutex_lock(&clip_mtx);
75
76 if (clip_data)
77 free(clip_data);
78
79 clip_data = data;
80 clip_size = size;
81 clip_tag = CLIPBOARD_TAG_DATA;
82
83 fibril_mutex_unlock(&clip_mtx);
84 ipc_answer_0(rid, EOK);
85 break;
86 default:
87 ipc_answer_0(rid, EINVAL);
88 }
89}
90
91static void clip_get_data(ipc_callid_t rid, ipc_call_t *request)
92{
93 fibril_mutex_lock(&clip_mtx);
94
95 ipc_callid_t callid;
96 size_t size;
97
98 /* Check for clipboard data tag compatibility */
99 switch (IPC_GET_ARG1(*request)) {
100 case CLIPBOARD_TAG_DATA:
101 if (!async_data_read_receive(&callid, &size)) {
102 ipc_answer_0(callid, EINVAL);
103 ipc_answer_0(rid, EINVAL);
104 break;
105 }
106
107 if (clip_tag != CLIPBOARD_TAG_DATA) {
108 /* So far we only understand binary data */
109 ipc_answer_0(callid, EOVERFLOW);
110 ipc_answer_0(rid, EOVERFLOW);
111 break;
112 }
113
114 if (clip_size != size) {
115 /* The client expects different size of data */
116 ipc_answer_0(callid, EOVERFLOW);
117 ipc_answer_0(rid, EOVERFLOW);
118 break;
119 }
120
121 sysarg_t retval = async_data_read_finalize(callid, clip_data, size);
122 if (retval != EOK) {
123 ipc_answer_0(rid, retval);
124 break;
125 }
126
127 ipc_answer_0(rid, EOK);
128 default:
129 /*
130 * Sorry, we don't know how to get unknown or NONE
131 * data from the clipbard
132 */
133 ipc_answer_0(rid, EINVAL);
134 break;
135 }
136
137 fibril_mutex_unlock(&clip_mtx);
138}
139
140static void clip_content(ipc_callid_t rid, ipc_call_t *request)
141{
142 fibril_mutex_lock(&clip_mtx);
143
144 size_t size = clip_size;
145 clipboard_tag_t tag = clip_tag;
146
147 fibril_mutex_unlock(&clip_mtx);
148 ipc_answer_2(rid, EOK, (sysarg_t) size, (sysarg_t) tag);
149}
150
151static void clip_connection(ipc_callid_t iid, ipc_call_t *icall)
152{
153 /* Accept connection */
154 ipc_answer_0(iid, EOK);
155
156 bool cont = true;
157 while (cont) {
158 ipc_call_t call;
159 ipc_callid_t callid = async_get_call(&call);
160
161 switch (IPC_GET_IMETHOD(call)) {
162 case IPC_M_PHONE_HUNGUP:
163 cont = false;
164 continue;
165 case CLIPBOARD_PUT_DATA:
166 clip_put_data(callid, &call);
167 break;
168 case CLIPBOARD_GET_DATA:
169 clip_get_data(callid, &call);
170 break;
171 case CLIPBOARD_CONTENT:
172 clip_content(callid, &call);
173 break;
174 default:
175 ipc_answer_0(callid, ENOENT);
176 }
177 }
178}
179
180int main(int argc, char *argv[])
181{
182 printf(NAME ": HelenOS clipboard service\n");
183
184 async_set_client_connection(clip_connection);
185
186 if (service_register(SERVICE_CLIPBOARD) != EOK)
187 return -1;
188
189 printf(NAME ": Accepting connections\n");
190 async_manager();
191
192 /* Never reached */
193 return 0;
194}
Note: See TracBrowser for help on using the repository browser.