source: mainline/uspace/lib/c/generic/clipboard.c@ 76c8209

Last change on this file since 76c8209 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2009 Jiri Svoboda
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/** @addtogroup libc
30 * @{
31 */
32/** @file
33 * @brief System clipboard API.
34 *
35 * The clipboard data is managed by the clipboard service and it is shared by
36 * the entire system.
37 *
38 */
39
40#include <async.h>
41#include <clipboard.h>
42#include <errno.h>
43#include <fibril_synch.h>
44#include <ipc/clipboard.h>
45#include <ipc/services.h>
46#include <loc.h>
47#include <stdlib.h>
48#include <str.h>
49
50static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
51static async_sess_t *clip_sess = NULL;
52
53/** Start an async exchange on the clipboard session.
54 *
55 * @return New exchange.
56 *
57 */
58static async_exch_t *clip_exchange_begin(void)
59{
60 service_id_t sid;
61 errno_t rc;
62
63 fibril_mutex_lock(&clip_mutex);
64
65 while (clip_sess == NULL) {
66 rc = loc_service_get_id(SERVICE_NAME_CLIPBOARD, &sid,
67 IPC_FLAG_BLOCKING);
68 if (rc != EOK)
69 continue;
70
71 clip_sess = loc_service_connect(sid, INTERFACE_CLIPBOARD,
72 IPC_FLAG_BLOCKING);
73 }
74
75 fibril_mutex_unlock(&clip_mutex);
76
77 return async_exchange_begin(clip_sess);
78}
79
80/** Finish an async exchange on the clipboard session.
81 *
82 * @param exch Exchange to be finished.
83 *
84 */
85static void clip_exchange_end(async_exch_t *exch)
86{
87 async_exchange_end(exch);
88}
89
90/** Copy string to clipboard.
91 *
92 * Sets the clipboard contents to @a str. Passing an empty string or NULL
93 * makes the clipboard empty.
94 *
95 * @param str String to put to clipboard or NULL.
96 *
97 * @return Zero on success or an error code.
98 *
99 */
100errno_t clipboard_put_str(const char *str)
101{
102 size_t size = str_size(str);
103
104 if (size == 0) {
105 async_exch_t *exch = clip_exchange_begin();
106 errno_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
107 CLIPBOARD_TAG_NONE);
108 clip_exchange_end(exch);
109
110 return (errno_t) rc;
111 } else {
112 async_exch_t *exch = clip_exchange_begin();
113 aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
114 NULL);
115 errno_t rc = async_data_write_start(exch, (void *) str, size);
116 clip_exchange_end(exch);
117
118 if (rc != EOK) {
119 errno_t rc_orig;
120 async_wait_for(req, &rc_orig);
121 if (rc_orig == EOK)
122 return (errno_t) rc;
123 else
124 return (errno_t) rc_orig;
125 }
126
127 async_wait_for(req, &rc);
128
129 return (errno_t) rc;
130 }
131}
132
133/** Get a copy of clipboard contents.
134 *
135 * Returns a new string that can be deallocated with free().
136 *
137 * @param str Here pointer to the newly allocated string is stored.
138 *
139 * @return Zero on success or an error code.
140 *
141 */
142errno_t clipboard_get_str(char **str)
143{
144 /* Loop until clipboard read succesful */
145 while (true) {
146 async_exch_t *exch = clip_exchange_begin();
147
148 sysarg_t size;
149 sysarg_t tag;
150 errno_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
151
152 clip_exchange_end(exch);
153
154 if (rc != EOK)
155 return (errno_t) rc;
156
157 char *sbuf;
158
159 switch (tag) {
160 case CLIPBOARD_TAG_NONE:
161 sbuf = malloc(1);
162 if (sbuf == NULL)
163 return ENOMEM;
164
165 sbuf[0] = 0;
166 *str = sbuf;
167 return EOK;
168 case CLIPBOARD_TAG_DATA:
169 sbuf = malloc(size + 1);
170 if (sbuf == NULL)
171 return ENOMEM;
172
173 exch = clip_exchange_begin();
174 aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
175 rc = async_data_read_start(exch, (void *) sbuf, size);
176 clip_exchange_end(exch);
177
178 if ((errno_t) rc == EOVERFLOW) {
179 /*
180 * The data in the clipboard has changed since
181 * the last call of CLIPBOARD_CONTENT
182 */
183 break;
184 }
185
186 if (rc != EOK) {
187 errno_t rc_orig;
188 async_wait_for(req, &rc_orig);
189 if (rc_orig == EOK)
190 return (errno_t) rc;
191 else
192 return (errno_t) rc_orig;
193 }
194
195 async_wait_for(req, &rc);
196
197 if (rc == EOK) {
198 sbuf[size] = 0;
199 *str = sbuf;
200 }
201
202 return rc;
203 default:
204 return EINVAL;
205 }
206 }
207}
208
209/** @}
210 */
Note: See TracBrowser for help on using the repository browser.