xref: /haiku/src/tests/kits/storage/testapps/clipboard.cpp (revision 902c72f6bbb2f0298bc7be3f7068a0d28a3dced6)
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