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 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create(JNIEnv * env,jobject obj,jint textview_width,jint textview_height,jint scroll)47 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create
48 (JNIEnv *env, jobject obj,
49 jint textview_width, jint textview_height, jint scroll)
50 {
51 GtkWidget *text, *sw;
52
53 gdk_threads_enter ();
54
55 /* Create global reference and save it for future use */
56 NSA_SET_GLOBAL_REF (env, obj);
57
58 text = gtk_text_view_new ();
59 gtk_widget_set_size_request (text, textview_width, textview_height);
60 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (text), TRUE);
61
62 gtk_widget_show (text);
63
64 sw = gtk_scrolled_window_new (NULL, NULL);
65 gtk_container_add (GTK_CONTAINER (sw), text);
66
67 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
68 /* horizontal scrollbar */
69 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
70 || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY) ?
71 GTK_POLICY_ALWAYS : GTK_POLICY_NEVER,
72 /* vertical scrollbar */
73 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
74 || scroll == AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY) ?
75 GTK_POLICY_ALWAYS : GTK_POLICY_NEVER);
76
77 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text),
78 (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
79 || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY)
80 ? GTK_WRAP_NONE : GTK_WRAP_WORD);
81
82 NSA_SET_PTR (env, obj, sw);
83
84 gdk_threads_leave ();
85 }
86
87 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals(JNIEnv * env,jobject obj)88 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals
89 (JNIEnv *env, jobject obj)
90 {
91 GtkWidget *text = NULL;
92 GtkTextBuffer *buf;
93 void *ptr;
94 jobject *gref;
95
96 gdk_threads_enter ();
97
98 ptr = NSA_GET_PTR (env, obj);
99 gref = NSA_GET_GLOBAL_REF (env, obj);
100
101 /* Unwrap the text view from the scrolled window */
102 text = gtk_bin_get_child (GTK_BIN (ptr));
103
104 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
105
106 /* TextComponent signals */
107 cp_gtk_textcomponent_connect_signals (G_OBJECT (buf), gref);
108
109 /* Component signals */
110 cp_gtk_component_connect_signals (G_OBJECT (text), gref);
111
112 gdk_threads_leave ();
113 }
114
115 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert(JNIEnv * env,jobject obj,jstring contents,jint position)116 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert
117 (JNIEnv *env, jobject obj, jstring contents, jint position)
118 {
119 GtkTextBuffer *buf;
120 GtkTextIter iter;
121 GtkWidget *text;
122 void *ptr;
123 const char *str;
124
125 gdk_threads_enter ();
126
127 ptr = NSA_GET_PTR (env, obj);
128 str = (*env)->GetStringUTFChars (env, contents, NULL);
129
130 text = gtk_bin_get_child (GTK_BIN (ptr));
131
132 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
133 gtk_text_buffer_get_iter_at_offset (buf, &iter, position);
134 gtk_text_buffer_insert (buf, &iter, str, strlen (str));
135
136 (*env)->ReleaseStringUTFChars (env, contents, str);
137
138 gdk_threads_leave ();
139 }
140
141 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange(JNIEnv * env,jobject obj,jstring contents,jint start,jint end)142 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange
143 (JNIEnv *env, jobject obj, jstring contents, jint start, jint end)
144 {
145 GtkWidget *text;
146 GtkTextBuffer *buf;
147 GtkTextIter iter, startIter, endIter;
148 void *ptr;
149 const char *str;
150 int mystart = start;
151 int myend = end;
152
153 gdk_threads_enter ();
154
155 ptr = NSA_GET_PTR (env, obj);
156 str = (*env)->GetStringUTFChars (env, contents, NULL);
157
158 text = gtk_bin_get_child (GTK_BIN (ptr));
159
160 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
161
162 gtk_text_buffer_get_iter_at_offset (buf, &startIter, mystart);
163 gtk_text_buffer_get_iter_at_offset (buf, &endIter, myend);
164 gtk_text_buffer_delete (buf, &startIter, &endIter);
165
166 gtk_text_buffer_get_iter_at_offset (buf, &iter, mystart);
167 gtk_text_buffer_insert(buf, &iter, str, strlen (str));
168
169 (*env)->ReleaseStringUTFChars (env, contents, str);
170
171 gdk_threads_leave ();
172 }
173
174 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont(JNIEnv * env,jobject obj,jstring name,jint style,jint size)175 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont
176 (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
177 {
178 const char *font_name;
179 void *ptr;
180 GtkWidget *text;
181 PangoFontDescription *font_desc;
182
183 gdk_threads_enter();
184
185 ptr = NSA_GET_PTR (env, obj);
186
187 text = gtk_bin_get_child (GTK_BIN (ptr));
188
189 font_name = (*env)->GetStringUTFChars (env, name, NULL);
190
191 font_desc = pango_font_description_from_string (font_name);
192 pango_font_description_set_size (font_desc,
193 size * cp_gtk_dpi_conversion_factor);
194
195 if (style & AWT_STYLE_BOLD)
196 pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
197
198 if (style & AWT_STYLE_ITALIC)
199 pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
200
201 gtk_widget_modify_font (GTK_WIDGET (text), font_desc);
202
203 pango_font_description_free (font_desc);
204
205 (*env)->ReleaseStringUTFChars (env, name, font_name);
206
207 gdk_threads_leave();
208 }
209
210 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus(JNIEnv * env,jobject obj)211 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus
212 (JNIEnv *env, jobject obj)
213 {
214 void *ptr;
215 GtkWidget *text;
216
217 gdk_threads_enter ();
218
219 ptr = NSA_GET_PTR (env, obj);
220
221 text = gtk_bin_get_child (GTK_BIN (ptr));
222
223 gtk_widget_grab_focus (text);
224
225 gdk_threads_leave ();
226 }
227
228 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight(JNIEnv * env,jobject obj)229 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight
230 (JNIEnv *env, jobject obj)
231 {
232 void *ptr;
233 GtkScrolledWindow *sw;
234 GtkRequisition requisition;
235 jint height = 0;
236 jint spacing = 0;
237
238 gdk_threads_enter ();
239
240 ptr = NSA_GET_PTR (env, obj);
241
242 sw = GTK_SCROLLED_WINDOW (ptr);
243
244 if (sw)
245 {
246 gtk_widget_size_request (sw->hscrollbar, &requisition);
247 gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
248 height = requisition.height + spacing;
249 }
250
251 gdk_threads_leave ();
252
253 return height;
254 }
255
256 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth(JNIEnv * env,jobject obj)257 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth
258 (JNIEnv *env, jobject obj)
259 {
260 void *ptr;
261 GtkScrolledWindow *sw;
262 GtkRequisition requisition;
263 jint width = 0;
264 jint spacing = 0;
265
266 gdk_threads_enter ();
267
268 ptr = NSA_GET_PTR (env, obj);
269
270 sw = GTK_SCROLLED_WINDOW (ptr);
271
272 if (sw)
273 {
274 gtk_widget_size_request (sw->vscrollbar, &requisition);
275 gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
276 width = requisition.width + spacing;
277 }
278
279 gdk_threads_leave ();
280
281 return width;
282 }
283
284 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition(JNIEnv * env,jobject obj)285 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition
286 (JNIEnv *env, jobject obj)
287 {
288 void *ptr;
289 int pos = 0;
290 GtkWidget *text = NULL;
291 GtkTextBuffer *buf;
292 GtkTextMark *mark;
293 GtkTextIter iter;
294
295 gdk_threads_enter ();
296
297 ptr = NSA_GET_PTR (env, obj);
298
299 text = gtk_bin_get_child (GTK_BIN (ptr));
300
301 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
302 mark = gtk_text_buffer_get_insert (buf);
303 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
304 pos = gtk_text_iter_get_offset (&iter);
305
306 gdk_threads_leave ();
307
308 return pos;
309 }
310
311 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition(JNIEnv * env,jobject obj,jint pos)312 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition
313 (JNIEnv *env, jobject obj, jint pos)
314 {
315 void *ptr;
316 GtkWidget *text = NULL;
317 GtkTextBuffer *buf;
318 GtkTextIter iter;
319 GtkTextMark *oldmark;
320 GtkTextIter olditer;
321 int oldpos;
322
323 gdk_threads_enter ();
324
325 ptr = NSA_GET_PTR (env, obj);
326
327 text = gtk_bin_get_child (GTK_BIN (ptr));
328
329 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
330
331 /* Save old position. */
332 oldmark = gtk_text_buffer_get_insert (buf);
333 gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
334 oldpos = gtk_text_iter_get_offset (&olditer);
335
336 /* Move to new position. */
337 gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
338 gtk_text_buffer_place_cursor (buf, &iter);
339
340 /* Scroll to new position. Alignment is determined
341 comparing the new position to the old position. */
342 if (oldpos > pos)
343 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
344 &iter, 0, TRUE, 0, 0);
345 else if (oldpos < pos)
346 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
347 &iter, 0, TRUE, 1, 1);
348
349 gdk_threads_leave ();
350 }
351
352 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart(JNIEnv * env,jobject obj)353 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart
354 (JNIEnv *env, jobject obj)
355 {
356 void *ptr;
357 int pos = 0;
358 GtkWidget *text = NULL;
359 GtkTextBuffer *buf;
360 GtkTextIter start;
361 GtkTextIter end;
362 GtkTextMark *mark;
363 GtkTextIter iter;
364
365 gdk_threads_enter ();
366
367 ptr = NSA_GET_PTR (env, obj);
368
369 text = gtk_bin_get_child (GTK_BIN (ptr));
370
371 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
372
373 if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
374 {
375 pos = gtk_text_iter_get_offset (&start);
376 }
377 else
378 {
379 mark = gtk_text_buffer_get_insert (buf);
380 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
381 pos = gtk_text_iter_get_offset (&iter);
382 }
383
384 gdk_threads_leave ();
385
386 return pos;
387 }
388
389 JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd(JNIEnv * env,jobject obj)390 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd
391 (JNIEnv *env, jobject obj)
392 {
393 void *ptr;
394 int pos = 0;
395 GtkWidget *text = NULL;
396 GtkTextBuffer *buf;
397 GtkTextIter start;
398 GtkTextIter end;
399 GtkTextMark *mark;
400 GtkTextIter iter;
401
402 gdk_threads_enter ();
403
404 ptr = NSA_GET_PTR (env, obj);
405
406 text = gtk_bin_get_child (GTK_BIN (ptr));
407
408 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
409
410 if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
411 {
412 pos = gtk_text_iter_get_offset (&end);
413 }
414 else
415 {
416 mark = gtk_text_buffer_get_insert (buf);
417 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
418 pos = gtk_text_iter_get_offset (&iter);
419 }
420
421 gdk_threads_leave ();
422
423 return pos;
424 }
425
426 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select(JNIEnv * env,jobject obj,jint start,jint end)427 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select
428 (JNIEnv *env, jobject obj, jint start, jint end)
429 {
430 void *ptr;
431 GtkWidget *text = NULL;
432 GtkTextBuffer *buf;
433 GtkTextIter iter;
434
435 gdk_threads_enter ();
436
437 ptr = NSA_GET_PTR (env, obj);
438
439 text = gtk_bin_get_child (GTK_BIN (ptr));
440
441 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
442 gtk_text_buffer_get_iter_at_offset (buf, &iter, start);
443 /* quickly move both 'insert' and 'selection_bound' to the
444 same position */
445 gtk_text_buffer_place_cursor (buf, &iter);
446 gtk_text_buffer_get_iter_at_offset (buf, &iter, end);
447 gtk_text_buffer_move_mark_by_name (buf, "selection_bound", &iter);
448
449 gdk_threads_leave ();
450 }
451
452 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable(JNIEnv * env,jobject obj,jboolean state)453 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable
454 (JNIEnv *env, jobject obj, jboolean state)
455 {
456 void *ptr;
457 GtkWidget *text = NULL;
458
459 gdk_threads_enter ();
460
461 ptr = NSA_GET_PTR (env, obj);
462
463 text = gtk_bin_get_child (GTK_BIN (ptr));
464
465 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), state);
466
467 gdk_threads_leave ();
468 }
469
470 JNIEXPORT jstring JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText(JNIEnv * env,jobject obj)471 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText
472 (JNIEnv *env, jobject obj)
473 {
474 void *ptr;
475 char *contents = NULL;
476 jstring jcontents;
477 GtkWidget *text = NULL;
478 GtkTextBuffer *buf;
479 GtkTextIter start, end;
480
481 gdk_threads_enter ();
482
483 ptr = NSA_GET_PTR (env, obj);
484
485 text = gtk_bin_get_child (GTK_BIN (ptr));
486
487 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
488 gtk_text_buffer_get_start_iter (buf, &start);
489 gtk_text_buffer_get_end_iter (buf, &end);
490 contents = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
491
492 jcontents = (*env)->NewStringUTF (env, contents);
493 g_free (contents);
494
495 gdk_threads_leave ();
496
497 return jcontents;
498 }
499
500 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText(JNIEnv * env,jobject obj,jstring contents)501 Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText
502 (JNIEnv *env, jobject obj, jstring contents)
503 {
504 void *ptr;
505 const char *str;
506 GtkWidget *text = NULL;
507 GtkTextBuffer *buf;
508
509 gdk_threads_enter ();
510
511 ptr = NSA_GET_PTR (env, obj);
512 str = (*env)->GetStringUTFChars (env, contents, NULL);
513
514 text = gtk_bin_get_child (GTK_BIN (ptr));
515
516 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
517 gtk_text_buffer_set_text (buf, str, strlen (str));
518
519 (*env)->ReleaseStringUTFChars (env, contents, str);
520
521 gdk_threads_leave ();
522 }
523