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