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 12 static 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 31 static int sArgc; 32 static const char *const *sArgv; 33 34 // print_usage 35 void 36 print_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 49 static 50 void 51 print_usage_and_exit(bool error) 52 { 53 print_usage(error); 54 exit(error ? 1 : 0); 55 } 56 57 // next_arg 58 static 59 const char* 60 next_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 72 static 73 void 74 clipboard_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 86 static 87 void 88 clipboard_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 100 static 101 void 102 clipboard_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 117 int 118 main(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