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