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