1 /* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
2 Copyright (C) 2021 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
18
19 #include <config.h>
20
21 #include <Clipboard.h>
22
23 #include <cstdlib>
24 #include <cstring>
25
26 #include "haikuselect.h"
27
28
29 static BClipboard *primary = NULL;
30 static BClipboard *secondary = NULL;
31 static BClipboard *system_clipboard = NULL;
32
33 int selection_state_flag;
34
35 static char *
BClipboard_find_data(BClipboard * cb,const char * type,ssize_t * len)36 BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
37 {
38 if (!cb->Lock ())
39 return 0;
40
41 BMessage *dat = cb->Data ();
42 if (!dat)
43 {
44 cb->Unlock ();
45 return 0;
46 }
47
48 const char *ptr;
49 ssize_t bt;
50 dat->FindData (type, B_MIME_TYPE, (const void **) &ptr, &bt);
51
52 if (!ptr)
53 {
54 cb->Unlock ();
55 return NULL;
56 }
57
58 if (len)
59 *len = bt;
60
61 cb->Unlock ();
62
63 return strndup (ptr, bt);
64 }
65
66 static void
BClipboard_get_targets(BClipboard * cb,char ** buf,int buf_size)67 BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size)
68 {
69 BMessage *data;
70 char *name;
71 int32 count_found;
72 type_code type;
73 int32 i;
74 int index;
75
76 if (!cb->Lock ())
77 {
78 buf[0] = NULL;
79 return;
80 }
81
82 data = cb->Data ();
83 index = 0;
84
85 if (!data)
86 {
87 buf[0] = NULL;
88 cb->Unlock ();
89 return;
90 }
91
92 for (i = 0; (data->GetInfo (B_ANY_TYPE, i, &name,
93 &type, &count_found)
94 == B_OK); ++i)
95 {
96 if (type == B_MIME_TYPE)
97 {
98 if (index < (buf_size - 1))
99 {
100 buf[index++] = strdup (name);
101
102 if (!buf[index - 1])
103 break;
104 }
105 }
106 }
107
108 buf[index] = NULL;
109
110 cb->Unlock ();
111 }
112
113 static void
BClipboard_set_data(BClipboard * cb,const char * type,const char * dat,ssize_t len,bool clear)114 BClipboard_set_data (BClipboard *cb, const char *type, const char *dat,
115 ssize_t len, bool clear)
116 {
117 if (!cb->Lock ())
118 return;
119
120 if (clear)
121 cb->Clear ();
122
123 BMessage *mdat = cb->Data ();
124 if (!mdat)
125 {
126 cb->Unlock ();
127 return;
128 }
129
130 if (dat)
131 {
132 if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len)
133 == B_NAME_NOT_FOUND)
134 mdat->AddData (type, B_MIME_TYPE, dat, len);
135 }
136 else
137 mdat->RemoveName (type);
138 cb->Commit ();
139 cb->Unlock ();
140 }
141
142 char *
BClipboard_find_system_data(const char * type,ssize_t * len)143 BClipboard_find_system_data (const char *type, ssize_t *len)
144 {
145 if (!system_clipboard)
146 return 0;
147
148 return BClipboard_find_data (system_clipboard, type, len);
149 }
150
151 char *
BClipboard_find_primary_selection_data(const char * type,ssize_t * len)152 BClipboard_find_primary_selection_data (const char *type, ssize_t *len)
153 {
154 if (!primary)
155 return 0;
156
157 return BClipboard_find_data (primary, type, len);
158 }
159
160 char *
BClipboard_find_secondary_selection_data(const char * type,ssize_t * len)161 BClipboard_find_secondary_selection_data (const char *type, ssize_t *len)
162 {
163 if (!secondary)
164 return 0;
165
166 return BClipboard_find_data (secondary, type, len);
167 }
168
169 void
BClipboard_set_system_data(const char * type,const char * data,ssize_t len,bool clear)170 BClipboard_set_system_data (const char *type, const char *data,
171 ssize_t len, bool clear)
172 {
173 if (!system_clipboard)
174 return;
175
176 BClipboard_set_data (system_clipboard, type, data, len, clear);
177 }
178
179 void
BClipboard_set_primary_selection_data(const char * type,const char * data,ssize_t len,bool clear)180 BClipboard_set_primary_selection_data (const char *type, const char *data,
181 ssize_t len, bool clear)
182 {
183 if (!primary)
184 return;
185
186 BClipboard_set_data (primary, type, data, len, clear);
187 }
188
189 void
BClipboard_set_secondary_selection_data(const char * type,const char * data,ssize_t len,bool clear)190 BClipboard_set_secondary_selection_data (const char *type, const char *data,
191 ssize_t len, bool clear)
192 {
193 if (!secondary)
194 return;
195
196 BClipboard_set_data (secondary, type, data, len, clear);
197 }
198
199 void
BClipboard_free_data(void * ptr)200 BClipboard_free_data (void *ptr)
201 {
202 std::free (ptr);
203 }
204
205 void
BClipboard_system_targets(char ** buf,int len)206 BClipboard_system_targets (char **buf, int len)
207 {
208 BClipboard_get_targets (system_clipboard, buf, len);
209 }
210
211 void
BClipboard_primary_targets(char ** buf,int len)212 BClipboard_primary_targets (char **buf, int len)
213 {
214 BClipboard_get_targets (primary, buf, len);
215 }
216
217 void
BClipboard_secondary_targets(char ** buf,int len)218 BClipboard_secondary_targets (char **buf, int len)
219 {
220 BClipboard_get_targets (secondary, buf, len);
221 }
222
223 void
init_haiku_select(void)224 init_haiku_select (void)
225 {
226 system_clipboard = new BClipboard ("system");
227 primary = new BClipboard ("primary");
228 secondary = new BClipboard ("secondary");
229 }
230