1 /* gtktextareapeer.c -- Native implementation of GtkTextAreaPeer
2 Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath 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 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 #include "gtkpeer.h"
40 #include "gnu_java_awt_peer_gtk_GtkTextAreaPeer.h"
41
42 #define AWT_TEXTAREA_SCROLLBARS_BOTH 0
43 #define AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY 1
44 #define AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY 2
45
46 static GtkWidget *textarea_get_widget (GtkWidget *widget);
47
48 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create(JNIEnv * env,jobject obj,jint textview_width,jint textview_height,jint scroll)49 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create
50 (JNIEnv *env, jobject obj,
51 jint textview_width, jint textview_height, jint scroll)
52 {
53 GtkWidget *text;
54 GtkWidget *sw;
55 GtkWidget *eventbox;
56
57 gdk_threads_enter ();
58
59 /* Create global reference and save it for future use */
60 gtkpeer_set_global_ref (env, obj);
61
62 text = gtk_text_view_new ();
63 gtk_widget_set_size_request (text, textview_width, textview_height);
64 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (text), TRUE);
65
66 gtk_widget_show (text);
67
68 eventbox = gtk_event_box_new ();
69 sw = gtk_scrolled_window_new (NULL, NULL);
70 gtk_container_add (GTK_CONTAINER (sw), text);
71 gtk_container_add (GTK_CONTAINER (eventbox), sw);
72 gtk_widget_show (sw);
73
74 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
75 /* horizontal scrollbar */
76 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
77 || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY) ?
78 GTK_POLICY_ALWAYS : GTK_POLICY_NEVER,
79 /* vertical scrollbar */
80 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
81 || scroll == AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY) ?
82 GTK_POLICY_ALWAYS : GTK_POLICY_NEVER);
83
84 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text),
85 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
86 || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY)
87 ? GTK_WRAP_NONE : GTK_WRAP_WORD);
88
89 gtkpeer_set_widget (env, obj, eventbox);
90
91 gdk_threads_leave ();
92 }
93
94 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals(JNIEnv * env,jobject obj)95 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals
96 (JNIEnv *env, jobject obj)
97 {
98 GtkWidget *text = NULL;
99 GtkTextBuffer *buf;
100 void *ptr;
101 jobject gref;
102
103 gdk_threads_enter ();
104
105 ptr = gtkpeer_get_widget (env, obj);
106 gref = gtkpeer_get_global_ref (env, obj);
107
108 /* Unwrap the text view from the scrolled window */
109 text = textarea_get_widget (GTK_WIDGET (ptr));
110
111 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
112
113 /* TextComponent signals */
114 cp_gtk_textcomponent_connect_signals (G_OBJECT (buf), gref);
115
116 /* Component signals */
117 cp_gtk_component_connect_signals (G_OBJECT (text), gref);
118
119 gdk_threads_leave ();
120 }
121
122 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert(JNIEnv * env,jobject obj,jstring contents,jint position)123 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert
124 (JNIEnv *env, jobject obj, jstring contents, jint position)
125 {
126 GtkTextBuffer *buf;
127 GtkTextIter iter;
128 GtkWidget *text;
129 void *ptr;
130 const char *str;
131
132 gdk_threads_enter ();
133
134 ptr = gtkpeer_get_widget (env, obj);
135 str = (*env)->GetStringUTFChars (env, contents, NULL);
136
137 text = textarea_get_widget (GTK_WIDGET (ptr));
138
139 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
140 gtk_text_buffer_get_iter_at_offset (buf, &iter, position);
141 gtk_text_buffer_insert (buf, &iter, str, strlen (str));
142
143 (*env)->ReleaseStringUTFChars (env, contents, str);
144
145 gdk_threads_leave ();
146 }
147
148 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange(JNIEnv * env,jobject obj,jstring contents,jint start,jint end)149 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange
150 (JNIEnv *env, jobject obj, jstring contents, jint start, jint end)
151 {
152 GtkWidget *text;
153 GtkTextBuffer *buf;
154 GtkTextIter iter, startIter, endIter;
155 void *ptr;
156 const char *str;
157 int mystart = start;
158 int myend = end;
159
160 gdk_threads_enter ();
161
162 ptr = gtkpeer_get_widget (env, obj);
163 str = (*env)->GetStringUTFChars (env, contents, NULL);
164
165 text = textarea_get_widget (GTK_WIDGET (ptr));
166
167 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
168
169 gtk_text_buffer_get_iter_at_offset (buf, &startIter, mystart);
170 gtk_text_buffer_get_iter_at_offset (buf, &endIter, myend);
171 gtk_text_buffer_delete (buf, &startIter, &endIter);
172
173 gtk_text_buffer_get_iter_at_offset (buf, &iter, mystart);
174 gtk_text_buffer_insert(buf, &iter, str, strlen (str));
175
176 (*env)->ReleaseStringUTFChars (env, contents, str);
177
178 gdk_threads_leave ();
179 }
180
181 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont(JNIEnv * env,jobject obj,jstring name,jint style,jint size)182 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont
183 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
184 {
185 const char *font_name;
186 void *ptr;
187 GtkWidget *text;
188 PangoFontDescription *font_desc;
189
190 gdk_threads_enter();
191
192 ptr = gtkpeer_get_widget (env, obj);
193
194 text = textarea_get_widget (GTK_WIDGET (ptr));
195
196 font_name = (*env)->GetStringUTFChars (env, name, NULL);
197
198 font_desc = pango_font_description_from_string (font_name);
199 pango_font_description_set_size (font_desc,
200 size * cp_gtk_dpi_conversion_factor);
201
202 if (style & AWT_STYLE_BOLD)
203 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
204
205 if (style & AWT_STYLE_ITALIC)
206 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
207
208 gtk_widget_modify_font (GTK_WIDGET (text), font_desc);
209
210 pango_font_description_free (font_desc);
211
212 (*env)->ReleaseStringUTFChars (env, name, font_name);
213
214 gdk_threads_leave();
215 }
216
217 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus(JNIEnv * env,jobject obj)218 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus
219 (JNIEnv *env, jobject obj)
220 {
221 void *ptr;
222 GtkWidget *text;
223
224 gdk_threads_enter ();
225
226 ptr = gtkpeer_get_widget (env, obj);
227
228 text = textarea_get_widget (GTK_WIDGET (ptr));
229
230 gtk_widget_grab_focus (text);
231
232 gdk_threads_leave ();
233 }
234
235 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight(JNIEnv * env,jobject obj)236 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight
237 (JNIEnv *env, jobject obj)
238 {
239 void *ptr;
240 GtkWidget *bin;
241 GtkScrolledWindow *sw;
242 GtkRequisition requisition;
243 jint height = 0;
244 jint spacing = 0;
245
246 gdk_threads_enter ();
247
248 ptr = gtkpeer_get_widget (env, obj);
249
250 bin = gtk_bin_get_child (GTK_BIN (ptr));
251 sw = GTK_SCROLLED_WINDOW (bin);
252
253 if (sw)
254 {
255 gtk_widget_size_request (sw->hscrollbar, &requisition);
256 gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
257 height = requisition.height + spacing;
258 }
259
260 gdk_threads_leave ();
261
262 return height;
263 }
264
265 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth(JNIEnv * env,jobject obj)266 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth
267 (JNIEnv *env, jobject obj)
268 {
269 void *ptr;
270 GtkWidget *bin;
271 GtkScrolledWindow *sw;
272 GtkRequisition requisition;
273 jint width = 0;
274 jint spacing = 0;
275
276 gdk_threads_enter ();
277
278 ptr = gtkpeer_get_widget (env, obj);
279
280 bin = gtk_bin_get_child (GTK_BIN (ptr));
281 sw = GTK_SCROLLED_WINDOW (bin);
282
283 if (sw)
284 {
285 gtk_widget_size_request (sw->vscrollbar, &requisition);
286 gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
287 width = requisition.width + spacing;
288 }
289
290 gdk_threads_leave ();
291
292 return width;
293 }
294
295 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition(JNIEnv * env,jobject obj)296 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition
297 (JNIEnv *env, jobject obj)
298 {
299 void *ptr;
300 int pos = 0;
301 GtkWidget *text = NULL;
302 GtkTextBuffer *buf;
303 GtkTextMark *mark;
304 GtkTextIter iter;
305
306 gdk_threads_enter ();
307
308 ptr = gtkpeer_get_widget (env, obj);
309
310 text = textarea_get_widget (GTK_WIDGET (ptr));
311
312 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
313 mark = gtk_text_buffer_get_insert (buf);
314 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
315 pos = gtk_text_iter_get_offset (&iter);
316
317 gdk_threads_leave ();
318
319 return pos;
320 }
321
322 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition(JNIEnv * env,jobject obj,jint pos)323 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition
324 (JNIEnv *env, jobject obj, jint pos)
325 {
326 void *ptr;
327 GtkWidget *text = NULL;
328 GtkTextBuffer *buf;
329 GtkTextIter iter;
330 GtkTextMark *oldmark;
331 GtkTextIter olditer;
332 int oldpos;
333
334 gdk_threads_enter ();
335
336 ptr = gtkpeer_get_widget (env, obj);
337
338 text = textarea_get_widget (GTK_WIDGET (ptr));
339
340 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
341
342 /* Save old position. */
343 oldmark = gtk_text_buffer_get_insert (buf);
344 gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
345 oldpos = gtk_text_iter_get_offset (&olditer);
346
347 /* Move to new position. */
348 gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
349 gtk_text_buffer_place_cursor (buf, &iter);
350
351 /* Scroll to new position. Alignment is determined
352 comparing the new position to the old position. */
353 if (oldpos > pos)
354 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
355 &iter, 0, TRUE, 0, 0);
356 else if (oldpos < pos)
357 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
358 &iter, 0, TRUE, 1, 1);
359
360 gdk_threads_leave ();
361 }
362
363 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart(JNIEnv * env,jobject obj)364 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart
365 (JNIEnv *env, jobject obj)
366 {
367 void *ptr;
368 int pos = 0;
369 GtkWidget *text = NULL;
370 GtkTextBuffer *buf;
371 GtkTextIter start;
372 GtkTextIter end;
373 GtkTextMark *mark;
374 GtkTextIter iter;
375
376 gdk_threads_enter ();
377
378 ptr = gtkpeer_get_widget (env, obj);
379
380 text = textarea_get_widget (GTK_WIDGET (ptr));
381
382 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
383
384 if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
385 {
386 pos = gtk_text_iter_get_offset (&start);
387 }
388 else
389 {
390 mark = gtk_text_buffer_get_insert (buf);
391 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
392 pos = gtk_text_iter_get_offset (&iter);
393 }
394
395 gdk_threads_leave ();
396
397 return pos;
398 }
399
400 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd(JNIEnv * env,jobject obj)401 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd
402 (JNIEnv *env, jobject obj)
403 {
404 void *ptr;
405 int pos = 0;
406 GtkWidget *text = NULL;
407 GtkTextBuffer *buf;
408 GtkTextIter start;
409 GtkTextIter end;
410 GtkTextMark *mark;
411 GtkTextIter iter;
412
413 gdk_threads_enter ();
414
415 ptr = gtkpeer_get_widget (env, obj);
416
417 text = textarea_get_widget (GTK_WIDGET (ptr));
418
419 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
420
421 if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
422 {
423 pos = gtk_text_iter_get_offset (&end);
424 }
425 else
426 {
427 mark = gtk_text_buffer_get_insert (buf);
428 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
429 pos = gtk_text_iter_get_offset (&iter);
430 }
431
432 gdk_threads_leave ();
433
434 return pos;
435 }
436
437 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select(JNIEnv * env,jobject obj,jint start,jint end)438 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select
439 (JNIEnv *env, jobject obj, jint start, jint end)
440 {
441 void *ptr;
442 GtkWidget *text = NULL;
443 GtkTextBuffer *buf;
444 GtkTextIter iter;
445
446 gdk_threads_enter ();
447
448 ptr = gtkpeer_get_widget (env, obj);
449
450 text = textarea_get_widget (GTK_WIDGET (ptr));
451
452 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
453 gtk_text_buffer_get_iter_at_offset (buf, &iter, start);
454 /* quickly move both 'insert' and 'selection_bound' to the
455 same position */
456 gtk_text_buffer_place_cursor (buf, &iter);
457 gtk_text_buffer_get_iter_at_offset (buf, &iter, end);
458 gtk_text_buffer_move_mark_by_name (buf, "selection_bound", &iter);
459
460 gdk_threads_leave ();
461 }
462
463 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable(JNIEnv * env,jobject obj,jboolean state)464 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable
465 (JNIEnv *env, jobject obj, jboolean state)
466 {
467 void *ptr;
468 GtkWidget *text = NULL;
469
470 gdk_threads_enter ();
471
472 ptr = gtkpeer_get_widget (env, obj);
473
474 text = textarea_get_widget (GTK_WIDGET (ptr));
475
476 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), state);
477
478 gdk_threads_leave ();
479 }
480
481 JNIEXPORT jstring JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText(JNIEnv * env,jobject obj)482 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText
483 (JNIEnv *env, jobject obj)
484 {
485 void *ptr;
486 char *contents = NULL;
487 jstring jcontents;
488 GtkWidget *text = NULL;
489 GtkTextBuffer *buf;
490 GtkTextIter start, end;
491
492 gdk_threads_enter ();
493
494 ptr = gtkpeer_get_widget (env, obj);
495
496 text = textarea_get_widget (GTK_WIDGET (ptr));
497
498 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
499 gtk_text_buffer_get_start_iter (buf, &start);
500 gtk_text_buffer_get_end_iter (buf, &end);
501 contents = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
502
503 jcontents = (*env)->NewStringUTF (env, contents);
504 g_free (contents);
505
506 gdk_threads_leave ();
507
508 return jcontents;
509 }
510
511 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText(JNIEnv * env,jobject obj,jstring contents)512 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText
513 (JNIEnv *env, jobject obj, jstring contents)
514 {
515 void *ptr;
516 const char *str;
517 GtkWidget *text = NULL;
518 GtkTextBuffer *buf;
519
520 gdk_threads_enter ();
521
522 ptr = gtkpeer_get_widget (env, obj);
523 str = (*env)->GetStringUTFChars (env, contents, NULL);
524
525 text = textarea_get_widget (GTK_WIDGET (ptr));
526
527 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
528 gtk_text_buffer_set_text (buf, str, strlen (str));
529
530 (*env)->ReleaseStringUTFChars (env, contents, str);
531
532 gdk_threads_leave ();
533 }
534
535 static GtkWidget *
textarea_get_widget(GtkWidget * widget)536 textarea_get_widget (GtkWidget *widget)
537 {
538 GtkWidget *wid;
539 g_assert (GTK_IS_EVENT_BOX (widget));
540
541 wid = gtk_bin_get_child (GTK_BIN (widget));
542 g_assert (GTK_IS_SCROLLED_WINDOW (wid));
543
544 wid = gtk_bin_get_child (GTK_BIN (wid));
545
546 return wid;
547 }
548