clipboard.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00040 #include <clipboard.h>
00041 #include <ipc/ns.h>
00042 #include <ipc/services.h>
00043 #include <ipc/clipboard.h>
00044 #include <async.h>
00045 #include <str.h>
00046 #include <errno.h>
00047 #include <malloc.h>
00048 
00049 static int clip_phone = -1;
00050 
00054 static void clip_connect(void)
00055 {
00056         while (clip_phone < 0)
00057                 clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
00058 }
00059 
00070 int clipboard_put_str(const char *str)
00071 {
00072         size_t size = str_size(str);
00073         
00074         if (size == 0) {
00075                 async_serialize_start();
00076                 clip_connect();
00077                 
00078                 sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
00079                 
00080                 async_serialize_end();
00081                 
00082                 return (int) rc;
00083         } else {
00084                 async_serialize_start();
00085                 clip_connect();
00086                 
00087                 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
00088                 sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
00089                 if (rc != EOK) {
00090                         sysarg_t rc_orig;
00091                         async_wait_for(req, &rc_orig);
00092                         async_serialize_end();
00093                         if (rc_orig == EOK)
00094                                 return (int) rc;
00095                         else
00096                                 return (int) rc_orig;
00097                 }
00098                 
00099                 async_wait_for(req, &rc);
00100                 async_serialize_end();
00101                 
00102                 return (int) rc;
00103         }
00104 }
00105 
00115 int clipboard_get_str(char **str)
00116 {
00117         /* Loop until clipboard read succesful */
00118         while (true) {
00119                 async_serialize_start();
00120                 clip_connect();
00121                 
00122                 sysarg_t size;
00123                 sysarg_t tag;
00124                 sysarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
00125                 
00126                 async_serialize_end();
00127                 
00128                 if (rc != EOK)
00129                         return (int) rc;
00130                 
00131                 char *sbuf;
00132                 
00133                 switch (tag) {
00134                 case CLIPBOARD_TAG_NONE:
00135                         sbuf = malloc(1);
00136                         if (sbuf == NULL)
00137                                 return ENOMEM;
00138                         
00139                         sbuf[0] = 0;
00140                         *str = sbuf;
00141                         return EOK;
00142                 case CLIPBOARD_TAG_DATA:
00143                         sbuf = malloc(size + 1);
00144                         if (sbuf == NULL)
00145                                 return ENOMEM;
00146                         
00147                         async_serialize_start();
00148                         
00149                         aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
00150                         rc = async_data_read_start(clip_phone, (void *) sbuf, size);
00151                         if ((int) rc == EOVERFLOW) {
00152                                 /*
00153                                  * The data in the clipboard has changed since
00154                                  * the last call of CLIPBOARD_CONTENT
00155                                  */
00156                                 async_serialize_end();
00157                                 break;
00158                         }
00159                         
00160                         if (rc != EOK) {
00161                                 sysarg_t rc_orig;
00162                                 async_wait_for(req, &rc_orig);
00163                                 async_serialize_end();
00164                                 if (rc_orig == EOK)
00165                                         return (int) rc;
00166                                 else
00167                                         return (int) rc_orig;
00168                         }
00169                         
00170                         async_wait_for(req, &rc);
00171                         async_serialize_end();
00172                         
00173                         if (rc == EOK) {
00174                                 sbuf[size] = 0;
00175                                 *str = sbuf;
00176                         }
00177                         
00178                         return rc;
00179                 default:
00180                         return EINVAL;
00181                 }
00182         }
00183 }
00184 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7