source: mainline/uspace/srv/clipboard/clipboard.c@ e503517a

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

gradually introduce async ports, initial phase

The initial phase is to reimplement the traditional async client connections as an untyped fallback port. This creates the possibility to introduce ports typed by interface type gradually in later changesets.

  • Property mode set to 100644
File size: 4.8 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 <stdbool.h>
31#include <async.h>
32#include <ns.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 "clipboard"
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 char *data;
49 int rc;
50 size_t size;
51
52 switch (IPC_GET_ARG1(*request)) {
53 case CLIPBOARD_TAG_NONE:
54 fibril_mutex_lock(&clip_mtx);
55
56 if (clip_data)
57 free(clip_data);
58
59 clip_data = NULL;
60 clip_size = 0;
61 clip_tag = CLIPBOARD_TAG_NONE;
62
63 fibril_mutex_unlock(&clip_mtx);
64 async_answer_0(rid, EOK);
65 break;
66 case CLIPBOARD_TAG_DATA:
67 rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size);
68 if (rc != EOK) {
69 async_answer_0(rid, rc);
70 break;
71 }
72
73 fibril_mutex_lock(&clip_mtx);
74
75 if (clip_data)
76 free(clip_data);
77
78 clip_data = data;
79 clip_size = size;
80 clip_tag = CLIPBOARD_TAG_DATA;
81
82 fibril_mutex_unlock(&clip_mtx);
83 async_answer_0(rid, EOK);
84 break;
85 default:
86 async_answer_0(rid, EINVAL);
87 }
88}
89
90static void clip_get_data(ipc_callid_t rid, ipc_call_t *request)
91{
92 fibril_mutex_lock(&clip_mtx);
93
94 ipc_callid_t callid;
95 size_t size;
96
97 /* Check for clipboard data tag compatibility */
98 switch (IPC_GET_ARG1(*request)) {
99 case CLIPBOARD_TAG_DATA:
100 if (!async_data_read_receive(&callid, &size)) {
101 async_answer_0(callid, EINVAL);
102 async_answer_0(rid, EINVAL);
103 break;
104 }
105
106 if (clip_tag != CLIPBOARD_TAG_DATA) {
107 /* So far we only understand binary data */
108 async_answer_0(callid, EOVERFLOW);
109 async_answer_0(rid, EOVERFLOW);
110 break;
111 }
112
113 if (clip_size != size) {
114 /* The client expects different size of data */
115 async_answer_0(callid, EOVERFLOW);
116 async_answer_0(rid, EOVERFLOW);
117 break;
118 }
119
120 sysarg_t retval = async_data_read_finalize(callid, clip_data, size);
121 if (retval != EOK) {
122 async_answer_0(rid, retval);
123 break;
124 }
125
126 async_answer_0(rid, EOK);
127 default:
128 /*
129 * Sorry, we don't know how to get unknown or NONE
130 * data from the clipbard
131 */
132 async_answer_0(rid, EINVAL);
133 break;
134 }
135
136 fibril_mutex_unlock(&clip_mtx);
137}
138
139static void clip_content(ipc_callid_t rid, ipc_call_t *request)
140{
141 fibril_mutex_lock(&clip_mtx);
142
143 size_t size = clip_size;
144 clipboard_tag_t tag = clip_tag;
145
146 fibril_mutex_unlock(&clip_mtx);
147 async_answer_2(rid, EOK, (sysarg_t) size, (sysarg_t) tag);
148}
149
150static void clip_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
151{
152 /* Accept connection */
153 async_answer_0(iid, EOK);
154
155 while (true) {
156 ipc_call_t call;
157 ipc_callid_t callid = async_get_call(&call);
158
159 if (!IPC_GET_IMETHOD(call))
160 break;
161
162 switch (IPC_GET_IMETHOD(call)) {
163 case CLIPBOARD_PUT_DATA:
164 clip_put_data(callid, &call);
165 break;
166 case CLIPBOARD_GET_DATA:
167 clip_get_data(callid, &call);
168 break;
169 case CLIPBOARD_CONTENT:
170 clip_content(callid, &call);
171 break;
172 default:
173 async_answer_0(callid, ENOENT);
174 }
175 }
176}
177
178int main(int argc, char *argv[])
179{
180 printf("%s: HelenOS clipboard service\n", NAME);
181
182 async_set_fallback_port_handler(clip_connection, NULL);
183 int rc = service_register(SERVICE_CLIPBOARD);
184 if (rc != EOK)
185 return rc;
186
187 printf("%s: Accepting connections\n", NAME);
188 task_retval(0);
189 async_manager();
190
191 /* Never reached */
192 return 0;
193}
Note: See TracBrowser for help on using the repository browser.