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