1// clipboard.cpp 2 3#include <stdio.h> 4#include <string.h> 5#include <sys/utsname.h> 6 7#include <Application.h> 8#include <Clipboard.h> 9#include <Message.h> 10 11// usage 12static const char *kUsage = 13"Usage: %s [ <options> ] clear\n" 14" %s [ <options> ] dump\n" 15" %s [ <options> ] set <value>\n" 16"\n" 17"Manipulates or dump the contents of the clipboard.\n" 18"\n" 19"Commands:\n" 20" clear - Clears the contents of the clipboard.\n" 21" dump - Prints the contents of the clipboard.\n" 22" set - Clears the clipboard and adds <value> as \"text/plain\".\n" 23"\n" 24"Options:\n" 25" -h, --help - Print this text.\n" 26" -c <clipboard> - The name of the clipboard to be used. Default is the\n" 27" system clipboard.\n" 28; 29 30// command line args 31static int sArgc; 32static const char *const *sArgv; 33 34// print_usage 35void 36print_usage(bool error) 37{ 38 // get nice program name 39 const char *programName = (sArgc > 0 ? sArgv[0] : "resattr"); 40 if (const char *lastSlash = strrchr(programName, '/')) 41 programName = lastSlash + 1; 42 43 // print usage 44 fprintf((error ? stderr : stdout), kUsage, programName, programName, 45 programName, programName); 46} 47 48// print_usage_and_exit 49static 50void 51print_usage_and_exit(bool error) 52{ 53 print_usage(error); 54 exit(error ? 1 : 0); 55} 56 57// next_arg 58static 59const char* 60next_arg(int argc, const char* const* argv, int& argi, bool dontFail = false) 61{ 62 if (argi + 1 >= argc) { 63 if (dontFail) 64 return NULL; 65 print_usage_and_exit(true); 66 } 67 68 return argv[++argi]; 69} 70 71// clipboard_clear 72static 73void 74clipboard_clear(BClipboard &clipboard) 75{ 76 // clear the data 77 status_t error = clipboard.Clear(); 78 if (error != B_OK) { 79 fprintf(stderr, "Failed to clear clipboard data: %s\n", 80 strerror(error)); 81 exit(1); 82 } 83} 84 85// clipboard_dump 86static 87void 88clipboard_dump(BClipboard &clipboard) 89{ 90 const char *data; 91 ssize_t size; 92 if (clipboard.Data()->FindData("text/plain", B_MIME_TYPE, 93 (const void**)&data, &size) == B_OK) { 94 printf("%.*s\n", (int)size, data); 95 } else 96 clipboard.Data()->PrintToStream(); 97} 98 99// clipboard_set 100static 101void 102clipboard_set(BClipboard &clipboard, const char *value) 103{ 104 // clear clipboard 105 clipboard_clear(clipboard); 106 107 // add data 108 status_t error = clipboard.Data()->AddData("text/plain", B_MIME_TYPE, value, 109 strlen(value) + 1); 110 if (error != B_OK) { 111 fprintf(stderr, "Failed to add clipboard data: %s\n", strerror(error)); 112 exit(1); 113 } 114} 115 116// main 117int 118main(int argc, const char *const *argv) 119{ 120 sArgc = argc; 121 sArgv = argv; 122 123 // parameters 124 const char *clipboardName = NULL; 125 const char *command = NULL; 126 const char *value = NULL; 127 128 // parse arguments 129 for (int argi = 1; argi < argc; argi++) { 130 const char *arg = argv[argi]; 131 if (arg[0] == '-') { 132 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { 133 print_usage_and_exit(false); 134 } else if (strcmp(arg, "-c") == 0) { 135 clipboardName = next_arg(argc, argv, argi); 136 } else { 137 print_usage_and_exit(true); 138 } 139 } else { 140 command = arg; 141 value = next_arg(argc, argv, argi, true); 142 } 143 } 144 145 // check parameters 146 if (!command) 147 print_usage_and_exit(true); 148 149 // create a BApplication on BeOS 150 struct utsname unameInfo; 151 if (uname(&unameInfo) < 0 || strcmp(unameInfo.sysname, "Haiku") != 0) 152 new BApplication("application/x-vnd.haiku.clipboard"); 153 154 // init clipboard 155 BClipboard clipboard(clipboardName ? clipboardName : "system"); 156 157 // lock clipboard 158 if (!clipboard.Lock()) { 159 fprintf(stderr, "Failed to lock clipboard `%s'\n", clipboard.Name()); 160 exit(1); 161 } 162 163 // check, if data exist 164 if (!clipboard.Data()) { 165 fprintf(stderr, "Failed to get data from clipboard `%s'.", 166 clipboard.Name()); 167 exit(1); 168 } 169 170 // execute the command 171 bool needsCommit = true; 172 if (strcmp(command, "clear") == 0) { 173 // clear 174 if (value) 175 print_usage_and_exit(true); 176 clipboard_clear(clipboard); 177 } else if (strcmp(command, "dump") == 0) { 178 // dump 179 if (value) 180 print_usage_and_exit(true); 181 clipboard_dump(clipboard); 182 needsCommit = false; 183 } else if (strcmp(command, "set") == 0) { 184 // set 185 if (!value) 186 print_usage_and_exit(true); 187 clipboard_set(clipboard, value); 188 } else 189 print_usage_and_exit(true); 190 191 // commit the change 192 if (needsCommit) { 193 status_t error = clipboard.Commit(); 194 if (error != B_OK) { 195 fprintf(stderr, "Failed to commit clipboard data: %s\n", 196 strerror(error)); 197 exit(1); 198 } 199 } 200 201 // unlock the clipboard (just for completeness :-) 202 clipboard.Unlock(); 203 204 return 0; 205} 206