This source file includes following definitions.
- get_clipboard_object
- be_find_clipboard_data_1
- be_set_clipboard_data_1
- be_update_clipboard_count
- be_find_clipboard_data
- be_set_clipboard_data
- clipboard_owner_p
- primary_owner_p
- secondary_owner_p
- be_clipboard_owner_p
- be_clipboard_init
- be_enum_message
- be_get_refs_data
- be_get_point_data
- be_get_message_data
- be_get_message_type
- be_set_message_type
- be_get_message_message
- be_create_simple_message
- be_add_message_data
- be_add_refs_data
- be_add_point_data
- be_add_message_message
- be_lock_clipboard_message
- be_unlock_clipboard
- be_handle_clipboard_changed_message
- be_start_watching_selection
- be_selection_outdated_p
- be_get_clipboard_count
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #include <Application.h>
22 #include <Clipboard.h>
23 #include <Message.h>
24 #include <Path.h>
25 #include <Entry.h>
26
27 #include <cstdlib>
28 #include <cstring>
29
30 #include "haikuselect.h"
31
32
33 static BClipboard *primary = NULL;
34
35
36 static BClipboard *secondary = NULL;
37
38
39
40 static BClipboard *system_clipboard = NULL;
41
42
43 static int64 count_clipboard = -1;
44
45
46 static int64 count_primary = -1;
47
48
49 static int64 count_secondary = -1;
50
51
52
53 static bool owned_primary;
54
55
56 static bool owned_secondary;
57
58
59 static bool owned_clipboard;
60
61 static BClipboard *
62 get_clipboard_object (enum haiku_clipboard clipboard)
63 {
64 switch (clipboard)
65 {
66 case CLIPBOARD_PRIMARY:
67 return primary;
68
69 case CLIPBOARD_SECONDARY:
70 return secondary;
71
72 case CLIPBOARD_CLIPBOARD:
73 return system_clipboard;
74 }
75
76 abort ();
77 }
78
79 static char *
80 be_find_clipboard_data_1 (BClipboard *cb, const char *type, ssize_t *len)
81 {
82 BMessage *data;
83 const char *ptr;
84 ssize_t nbytes;
85 void *value;
86
87 if (!cb->Lock ())
88 return NULL;
89
90 data = cb->Data ();
91
92 if (!data)
93 {
94 cb->Unlock ();
95 return NULL;
96 }
97
98 data->FindData (type, B_MIME_TYPE, (const void **) &ptr,
99 &nbytes);
100
101 if (!ptr)
102 {
103 cb->Unlock ();
104 return NULL;
105 }
106
107 if (len)
108 *len = nbytes;
109
110 value = malloc (nbytes);
111
112 if (!data)
113 {
114 cb->Unlock ();
115 return NULL;
116 }
117
118 memcpy (value, ptr, nbytes);
119 cb->Unlock ();
120
121 return (char *) value;
122 }
123
124 static void
125 be_set_clipboard_data_1 (BClipboard *cb, const char *type, const char *data,
126 ssize_t len, bool clear)
127 {
128 BMessage *message_data;
129
130 if (!cb->Lock ())
131 return;
132
133 if (clear)
134 cb->Clear ();
135
136 message_data = cb->Data ();
137
138 if (!message_data)
139 {
140 cb->Unlock ();
141 return;
142 }
143
144 if (data)
145 {
146 if (message_data->ReplaceData (type, B_MIME_TYPE, data, len)
147 == B_NAME_NOT_FOUND)
148 message_data->AddData (type, B_MIME_TYPE, data, len);
149 }
150 else
151 message_data->RemoveName (type);
152
153 cb->Commit ();
154 cb->Unlock ();
155 }
156
157 void
158 be_update_clipboard_count (enum haiku_clipboard id)
159 {
160 switch (id)
161 {
162 case CLIPBOARD_CLIPBOARD:
163 count_clipboard = system_clipboard->SystemCount ();
164 owned_clipboard = true;
165 break;
166
167 case CLIPBOARD_PRIMARY:
168 count_primary = primary->SystemCount ();
169 owned_primary = true;
170 break;
171
172 case CLIPBOARD_SECONDARY:
173 count_secondary = secondary->SystemCount ();
174 owned_secondary = true;
175 break;
176 }
177 }
178
179 char *
180 be_find_clipboard_data (enum haiku_clipboard id, const char *type,
181 ssize_t *len)
182 {
183 return be_find_clipboard_data_1 (get_clipboard_object (id),
184 type, len);
185 }
186
187 void
188 be_set_clipboard_data (enum haiku_clipboard id, const char *type,
189 const char *data, ssize_t len, bool clear)
190 {
191 be_update_clipboard_count (id);
192
193 be_set_clipboard_data_1 (get_clipboard_object (id), type,
194 data, len, clear);
195 }
196
197 static bool
198 clipboard_owner_p (void)
199 {
200 return (count_clipboard >= 0
201 && (count_clipboard + 1
202 == system_clipboard->SystemCount ()));
203 }
204
205 static bool
206 primary_owner_p (void)
207 {
208 return (count_primary >= 0
209 && (count_primary + 1
210 == primary->SystemCount ()));
211 }
212
213 static bool
214 secondary_owner_p (void)
215 {
216 return (count_secondary >= 0
217 && (count_secondary + 1
218 == secondary->SystemCount ()));
219 }
220
221 bool
222 be_clipboard_owner_p (enum haiku_clipboard clipboard)
223 {
224 switch (clipboard)
225 {
226 case CLIPBOARD_PRIMARY:
227 return primary_owner_p ();
228
229 case CLIPBOARD_SECONDARY:
230 return secondary_owner_p ();
231
232 case CLIPBOARD_CLIPBOARD:
233 return clipboard_owner_p ();
234 }
235
236 abort ();
237 }
238
239 void
240 be_clipboard_init (void)
241 {
242 system_clipboard = new BClipboard ("system");
243 primary = new BClipboard ("primary");
244 secondary = new BClipboard ("secondary");
245 }
246
247 int
248 be_enum_message (void *message, int32 *tc, int32 index,
249 int32 *count, const char **name_return)
250 {
251 BMessage *msg = (BMessage *) message;
252 type_code type;
253 char *name;
254 status_t rc;
255
256 rc = msg->GetInfo (B_ANY_TYPE, index, &name, &type, count);
257
258 if (rc != B_OK)
259 return 1;
260
261 *tc = type;
262 *name_return = name;
263 return 0;
264 }
265
266 int
267 be_get_refs_data (void *message, const char *name,
268 int32 index, char **path_buffer)
269 {
270 status_t rc;
271 BEntry entry;
272 BPath path;
273 entry_ref ref;
274 BMessage *msg;
275
276 msg = (BMessage *) message;
277 rc = msg->FindRef (name, index, &ref);
278
279 if (rc != B_OK)
280 return 1;
281
282 rc = entry.SetTo (&ref, 0);
283
284 if (rc != B_OK)
285 return 1;
286
287 rc = entry.GetPath (&path);
288
289 if (rc != B_OK)
290 return 1;
291
292 *path_buffer = strdup (path.Path ());
293 return 0;
294 }
295
296 int
297 be_get_point_data (void *message, const char *name,
298 int32 index, float *x, float *y)
299 {
300 status_t rc;
301 BMessage *msg;
302 BPoint point;
303
304 msg = (BMessage *) message;
305 rc = msg->FindPoint (name, index, &point);
306
307 if (rc != B_OK)
308 return 1;
309
310 *x = point.x;
311 *y = point.y;
312
313 return 0;
314 }
315
316 int
317 be_get_message_data (void *message, const char *name,
318 int32 type_code, int32 index,
319 const void **buf_return,
320 ssize_t *size_return)
321 {
322 BMessage *msg = (BMessage *) message;
323
324 return msg->FindData (name, type_code,
325 index, buf_return, size_return) != B_OK;
326 }
327
328 uint32
329 be_get_message_type (void *message)
330 {
331 BMessage *msg = (BMessage *) message;
332
333 return msg->what;
334 }
335
336 void
337 be_set_message_type (void *message, uint32 what)
338 {
339 BMessage *msg = (BMessage *) message;
340
341 msg->what = what;
342 }
343
344 void *
345 be_get_message_message (void *message, const char *name,
346 int32 index)
347 {
348 BMessage *msg = (BMessage *) message;
349 BMessage *out = new (std::nothrow) BMessage;
350
351 if (!out)
352 return NULL;
353
354 if (msg->FindMessage (name, index, out) != B_OK)
355 {
356 delete out;
357 return NULL;
358 }
359
360 return out;
361 }
362
363 void *
364 be_create_simple_message (void)
365 {
366 return new BMessage (B_SIMPLE_DATA);
367 }
368
369 int
370 be_add_message_data (void *message, const char *name,
371 int32 type_code, const void *buf,
372 ssize_t buf_size)
373 {
374 BMessage *msg = (BMessage *) message;
375
376 return msg->AddData (name, type_code, buf, buf_size) != B_OK;
377 }
378
379 int
380 be_add_refs_data (void *message, const char *name,
381 const char *filename)
382 {
383 BEntry entry (filename);
384 entry_ref ref;
385 BMessage *msg = (BMessage *) message;
386
387 if (entry.InitCheck () != B_OK)
388 return 1;
389
390 if (entry.GetRef (&ref) != B_OK)
391 return 1;
392
393 return msg->AddRef (name, &ref) != B_OK;
394 }
395
396 int
397 be_add_point_data (void *message, const char *name,
398 float x, float y)
399 {
400 BMessage *msg = (BMessage *) message;
401
402 return msg->AddPoint (name, BPoint (x, y)) != B_OK;
403 }
404
405 int
406 be_add_message_message (void *message, const char *name,
407 void *data)
408 {
409 BMessage *msg = (BMessage *) message;
410 BMessage *data_message = (BMessage *) data;
411
412 if (msg->AddMessage (name, data_message) != B_OK)
413 return 1;
414
415 return 0;
416 }
417
418 int
419 be_lock_clipboard_message (enum haiku_clipboard clipboard,
420 void **message_return, bool clear)
421 {
422 BClipboard *board;
423
424 board = get_clipboard_object (clipboard);
425
426 if (!board->Lock ())
427 return 1;
428
429 if (clear)
430 board->Clear ();
431
432 *message_return = board->Data ();
433 return 0;
434 }
435
436 void
437 be_unlock_clipboard (enum haiku_clipboard clipboard, bool discard)
438 {
439 BClipboard *board;
440
441 board = get_clipboard_object (clipboard);
442
443 if (discard)
444 board->Revert ();
445 else
446 board->Commit ();
447
448 board->Unlock ();
449 }
450
451 void
452 be_handle_clipboard_changed_message (void)
453 {
454 int64 n_clipboard, n_primary, n_secondary;
455
456 n_clipboard = system_clipboard->SystemCount ();
457 n_primary = primary->SystemCount ();
458 n_secondary = secondary->SystemCount ();
459
460 if (count_clipboard != -1
461 && (n_clipboard > count_clipboard + 1)
462 && owned_clipboard)
463 {
464 owned_clipboard = false;
465 haiku_selection_disowned (CLIPBOARD_CLIPBOARD,
466 n_clipboard);
467 }
468
469 if (count_primary != -1
470 && (n_primary > count_primary + 1)
471 && owned_primary)
472 {
473 owned_primary = false;
474 haiku_selection_disowned (CLIPBOARD_PRIMARY,
475 n_primary);
476 }
477
478 if (count_secondary != -1
479 && (n_secondary > count_secondary + 1)
480 && owned_secondary)
481 {
482 owned_secondary = false;
483 haiku_selection_disowned (CLIPBOARD_SECONDARY,
484 n_secondary);
485 }
486 }
487
488 void
489 be_start_watching_selection (enum haiku_clipboard id)
490 {
491 BClipboard *clipboard;
492
493 clipboard = get_clipboard_object (id);
494 clipboard->StartWatching (be_app);
495 }
496
497 bool
498 be_selection_outdated_p (enum haiku_clipboard id, int64 count)
499 {
500 if (id == CLIPBOARD_CLIPBOARD && count_clipboard > count)
501 return true;
502
503 if (id == CLIPBOARD_PRIMARY && count_primary > count)
504 return true;
505
506 if (id == CLIPBOARD_SECONDARY && count_secondary > count)
507 return true;
508
509 return false;
510 }
511
512 int64
513 be_get_clipboard_count (enum haiku_clipboard id)
514 {
515 BClipboard *clipboard;
516
517 clipboard = get_clipboard_object (id);
518 return clipboard->SystemCount ();
519 }