xref: /haiku/src/tests/kits/storage/testapps/clipboard.cpp (revision f31e9e37d912d2610d47e50360a2524af2792b66)
1902c72f6SIngo Weinhold // clipboard.cpp
2902c72f6SIngo Weinhold 
3902c72f6SIngo Weinhold #include <stdio.h>
4902c72f6SIngo Weinhold #include <string.h>
5902c72f6SIngo Weinhold #include <sys/utsname.h>
6902c72f6SIngo Weinhold 
7902c72f6SIngo Weinhold #include <Application.h>
8902c72f6SIngo Weinhold #include <Clipboard.h>
9902c72f6SIngo Weinhold #include <Message.h>
10902c72f6SIngo Weinhold 
11902c72f6SIngo Weinhold // usage
12902c72f6SIngo Weinhold static const char *kUsage =
13902c72f6SIngo Weinhold "Usage: %s [ <options> ] clear\n"
14902c72f6SIngo Weinhold "       %s [ <options> ] dump\n"
15902c72f6SIngo Weinhold "       %s [ <options> ] set <value>\n"
16902c72f6SIngo Weinhold "\n"
17902c72f6SIngo Weinhold "Manipulates or dump the contents of the clipboard.\n"
18902c72f6SIngo Weinhold "\n"
19902c72f6SIngo Weinhold "Commands:\n"
20902c72f6SIngo Weinhold "  clear          - Clears the contents of the clipboard.\n"
21902c72f6SIngo Weinhold "  dump           - Prints the contents of the clipboard.\n"
22902c72f6SIngo Weinhold "  set            - Clears the clipboard and adds <value> as \"text/plain\".\n"
23902c72f6SIngo Weinhold "\n"
24902c72f6SIngo Weinhold "Options:\n"
25902c72f6SIngo Weinhold "  -h, --help     - Print this text.\n"
26902c72f6SIngo Weinhold "  -c <clipboard> - The name of the clipboard to be used. Default is the\n"
27902c72f6SIngo Weinhold "                   system clipboard.\n"
28902c72f6SIngo Weinhold ;
29902c72f6SIngo Weinhold 
30902c72f6SIngo Weinhold // command line args
31902c72f6SIngo Weinhold static int sArgc;
32902c72f6SIngo Weinhold static const char *const *sArgv;
33902c72f6SIngo Weinhold 
34902c72f6SIngo Weinhold // print_usage
35902c72f6SIngo Weinhold void
print_usage(bool error)36902c72f6SIngo Weinhold print_usage(bool error)
37902c72f6SIngo Weinhold {
38902c72f6SIngo Weinhold 	// get nice program name
39902c72f6SIngo Weinhold 	const char *programName = (sArgc > 0 ? sArgv[0] : "resattr");
40902c72f6SIngo Weinhold 	if (const char *lastSlash = strrchr(programName, '/'))
41902c72f6SIngo Weinhold 		programName = lastSlash + 1;
42902c72f6SIngo Weinhold 
43902c72f6SIngo Weinhold 	// print usage
44902c72f6SIngo Weinhold 	fprintf((error ? stderr : stdout), kUsage, programName, programName,
45902c72f6SIngo Weinhold 		programName, programName);
46902c72f6SIngo Weinhold }
47902c72f6SIngo Weinhold 
48902c72f6SIngo Weinhold // print_usage_and_exit
49902c72f6SIngo Weinhold static
50902c72f6SIngo Weinhold void
print_usage_and_exit(bool error)51902c72f6SIngo Weinhold print_usage_and_exit(bool error)
52902c72f6SIngo Weinhold {
53902c72f6SIngo Weinhold 	print_usage(error);
54902c72f6SIngo Weinhold 	exit(error ? 1 : 0);
55902c72f6SIngo Weinhold }
56902c72f6SIngo Weinhold 
57902c72f6SIngo Weinhold // next_arg
58902c72f6SIngo Weinhold static
59902c72f6SIngo Weinhold const char*
next_arg(int argc,const char * const * argv,int & argi,bool dontFail=false)60902c72f6SIngo Weinhold next_arg(int argc, const char* const* argv, int& argi, bool dontFail = false)
61902c72f6SIngo Weinhold {
62902c72f6SIngo Weinhold 	if (argi + 1 >= argc) {
63902c72f6SIngo Weinhold 		if (dontFail)
64902c72f6SIngo Weinhold 			return NULL;
65902c72f6SIngo Weinhold 		print_usage_and_exit(true);
66902c72f6SIngo Weinhold 	}
67902c72f6SIngo Weinhold 
68902c72f6SIngo Weinhold 	return argv[++argi];
69902c72f6SIngo Weinhold }
70902c72f6SIngo Weinhold 
71902c72f6SIngo Weinhold // clipboard_clear
72902c72f6SIngo Weinhold static
73902c72f6SIngo Weinhold void
clipboard_clear(BClipboard & clipboard)74902c72f6SIngo Weinhold clipboard_clear(BClipboard &clipboard)
75902c72f6SIngo Weinhold {
76902c72f6SIngo Weinhold 	// clear the data
77902c72f6SIngo Weinhold 	status_t error = clipboard.Clear();
78902c72f6SIngo Weinhold 	if (error != B_OK) {
79902c72f6SIngo Weinhold 		fprintf(stderr, "Failed to clear clipboard data: %s\n",
80902c72f6SIngo Weinhold 			strerror(error));
81902c72f6SIngo Weinhold 		exit(1);
82902c72f6SIngo Weinhold 	}
83902c72f6SIngo Weinhold }
84902c72f6SIngo Weinhold 
85902c72f6SIngo Weinhold // clipboard_dump
86902c72f6SIngo Weinhold static
87902c72f6SIngo Weinhold void
clipboard_dump(BClipboard & clipboard)88902c72f6SIngo Weinhold clipboard_dump(BClipboard &clipboard)
89902c72f6SIngo Weinhold {
90902c72f6SIngo Weinhold 	const char *data;
91*f31e9e37SJaroslaw Pelczar 	ssize_t size;
92902c72f6SIngo Weinhold 	if (clipboard.Data()->FindData("text/plain", B_MIME_TYPE,
93902c72f6SIngo Weinhold 		(const void**)&data, &size) == B_OK) {
94902c72f6SIngo Weinhold 		printf("%.*s\n", (int)size, data);
95902c72f6SIngo Weinhold 	} else
96902c72f6SIngo Weinhold 		clipboard.Data()->PrintToStream();
97902c72f6SIngo Weinhold }
98902c72f6SIngo Weinhold 
99902c72f6SIngo Weinhold // clipboard_set
100902c72f6SIngo Weinhold static
101902c72f6SIngo Weinhold void
clipboard_set(BClipboard & clipboard,const char * value)102902c72f6SIngo Weinhold clipboard_set(BClipboard &clipboard, const char *value)
103902c72f6SIngo Weinhold {
104902c72f6SIngo Weinhold 	// clear clipboard
105902c72f6SIngo Weinhold 	clipboard_clear(clipboard);
106902c72f6SIngo Weinhold 
107902c72f6SIngo Weinhold 	// add data
108902c72f6SIngo Weinhold 	status_t error = clipboard.Data()->AddData("text/plain", B_MIME_TYPE, value,
109902c72f6SIngo Weinhold 		strlen(value) + 1);
110902c72f6SIngo Weinhold 	if (error != B_OK) {
111902c72f6SIngo Weinhold 		fprintf(stderr, "Failed to add clipboard data: %s\n", strerror(error));
112902c72f6SIngo Weinhold 		exit(1);
113902c72f6SIngo Weinhold 	}
114902c72f6SIngo Weinhold }
115902c72f6SIngo Weinhold 
116902c72f6SIngo Weinhold // main
117902c72f6SIngo Weinhold int
main(int argc,const char * const * argv)118902c72f6SIngo Weinhold main(int argc, const char *const *argv)
119902c72f6SIngo Weinhold {
120902c72f6SIngo Weinhold 	sArgc = argc;
121902c72f6SIngo Weinhold 	sArgv = argv;
122902c72f6SIngo Weinhold 
123902c72f6SIngo Weinhold 	// parameters
124902c72f6SIngo Weinhold 	const char *clipboardName = NULL;
125902c72f6SIngo Weinhold 	const char *command = NULL;
126902c72f6SIngo Weinhold 	const char *value = NULL;
127902c72f6SIngo Weinhold 
128902c72f6SIngo Weinhold 	// parse arguments
129902c72f6SIngo Weinhold 	for (int argi = 1; argi < argc; argi++) {
130902c72f6SIngo Weinhold 		const char *arg = argv[argi];
131902c72f6SIngo Weinhold 		if (arg[0] == '-') {
132902c72f6SIngo Weinhold 			if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
133902c72f6SIngo Weinhold 				print_usage_and_exit(false);
134902c72f6SIngo Weinhold 			} else if (strcmp(arg, "-c") == 0) {
135902c72f6SIngo Weinhold 				clipboardName = next_arg(argc, argv, argi);
136902c72f6SIngo Weinhold 			} else {
137902c72f6SIngo Weinhold 				print_usage_and_exit(true);
138902c72f6SIngo Weinhold 			}
139902c72f6SIngo Weinhold 		} else {
140902c72f6SIngo Weinhold 			command = arg;
141902c72f6SIngo Weinhold 			value = next_arg(argc, argv, argi, true);
142902c72f6SIngo Weinhold 		}
143902c72f6SIngo Weinhold 	}
144902c72f6SIngo Weinhold 
145902c72f6SIngo Weinhold 	// check parameters
146902c72f6SIngo Weinhold 	if (!command)
147902c72f6SIngo Weinhold 		print_usage_and_exit(true);
148902c72f6SIngo Weinhold 
149902c72f6SIngo Weinhold 	// create a BApplication on BeOS
150902c72f6SIngo Weinhold 	struct utsname unameInfo;
151902c72f6SIngo Weinhold 	if (uname(&unameInfo) < 0 || strcmp(unameInfo.sysname, "Haiku") != 0)
152902c72f6SIngo Weinhold 		new BApplication("application/x-vnd.haiku.clipboard");
153902c72f6SIngo Weinhold 
154902c72f6SIngo Weinhold 	// init clipboard
155902c72f6SIngo Weinhold 	BClipboard clipboard(clipboardName ? clipboardName : "system");
156902c72f6SIngo Weinhold 
157902c72f6SIngo Weinhold 	// lock clipboard
158902c72f6SIngo Weinhold 	if (!clipboard.Lock()) {
159902c72f6SIngo Weinhold 		fprintf(stderr, "Failed to lock clipboard `%s'\n", clipboard.Name());
160902c72f6SIngo Weinhold 		exit(1);
161902c72f6SIngo Weinhold 	}
162902c72f6SIngo Weinhold 
163902c72f6SIngo Weinhold 	// check, if data exist
164902c72f6SIngo Weinhold 	if (!clipboard.Data()) {
165902c72f6SIngo Weinhold 		fprintf(stderr, "Failed to get data from clipboard `%s'.",
166902c72f6SIngo Weinhold 			clipboard.Name());
167902c72f6SIngo Weinhold 		exit(1);
168902c72f6SIngo Weinhold 	}
169902c72f6SIngo Weinhold 
170902c72f6SIngo Weinhold 	// execute the command
171902c72f6SIngo Weinhold 	bool needsCommit = true;
172902c72f6SIngo Weinhold 	if (strcmp(command, "clear") == 0) {
173902c72f6SIngo Weinhold 		// clear
174902c72f6SIngo Weinhold 		if (value)
175902c72f6SIngo Weinhold 			print_usage_and_exit(true);
176902c72f6SIngo Weinhold 		clipboard_clear(clipboard);
177902c72f6SIngo Weinhold 	} else if (strcmp(command, "dump") == 0) {
178902c72f6SIngo Weinhold 		// dump
179902c72f6SIngo Weinhold 		if (value)
180902c72f6SIngo Weinhold 			print_usage_and_exit(true);
181902c72f6SIngo Weinhold 		clipboard_dump(clipboard);
182902c72f6SIngo Weinhold 		needsCommit = false;
183902c72f6SIngo Weinhold 	} else if (strcmp(command, "set") == 0) {
184902c72f6SIngo Weinhold 		// set
185902c72f6SIngo Weinhold 		if (!value)
186902c72f6SIngo Weinhold 			print_usage_and_exit(true);
187902c72f6SIngo Weinhold 		clipboard_set(clipboard, value);
188902c72f6SIngo Weinhold 	} else
189902c72f6SIngo Weinhold 		print_usage_and_exit(true);
190902c72f6SIngo Weinhold 
191902c72f6SIngo Weinhold 	// commit the change
192902c72f6SIngo Weinhold 	if (needsCommit) {
193902c72f6SIngo Weinhold 		status_t error = clipboard.Commit();
194902c72f6SIngo Weinhold 		if (error != B_OK) {
195902c72f6SIngo Weinhold 			fprintf(stderr, "Failed to commit clipboard data: %s\n",
196902c72f6SIngo Weinhold 				strerror(error));
197902c72f6SIngo Weinhold 			exit(1);
198902c72f6SIngo Weinhold 		}
199902c72f6SIngo Weinhold 	}
200902c72f6SIngo Weinhold 
201902c72f6SIngo Weinhold 	// unlock the clipboard (just for completeness :-)
202902c72f6SIngo Weinhold 	clipboard.Unlock();
203902c72f6SIngo Weinhold 
204902c72f6SIngo Weinhold 	return 0;
205902c72f6SIngo Weinhold }
206