Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkTextComponentPeer.c
blob6eb06e073f00b4e5a9983b8903c7be71c056c797
1 /* gtktextcomponentpeer.c -- Native implementation of GtkTextComponentPeer
2 Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
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.
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. */
39 #include "gtkpeer.h"
40 #include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
41 #include "gnu_java_awt_peer_gtk_GtkTextComponentPeer.h"
43 static void textcomponent_changed_cb (GtkEditable *editable,
44 jobject peer);
46 JNIEXPORT void JNICALL
47 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_connectSignals
48 (JNIEnv *env, jobject obj)
50 GtkTextView *text = NULL;
51 GtkTextBuffer *buf;
52 void *ptr = NSA_GET_PTR (env, obj);
53 jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
54 g_assert (gref);
56 gdk_threads_enter ();
58 if (GTK_IS_ENTRY(ptr))
60 g_signal_connect (GTK_EDITABLE (ptr), "changed",
61 G_CALLBACK (textcomponent_changed_cb), *gref);
63 gdk_threads_leave ();
65 /* Connect the superclass signals. */
66 Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, *gref);
68 else
70 if (GTK_IS_SCROLLED_WINDOW (ptr))
72 text = GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child);
74 else if (GTK_IS_TEXT_VIEW (ptr))
76 text = GTK_TEXT_VIEW (ptr);
79 if (text)
81 buf = gtk_text_view_get_buffer (text);
82 if (buf)
83 g_signal_connect (buf, "changed",
84 G_CALLBACK (textcomponent_changed_cb), *gref);
86 /* Connect the superclass signals. */
87 /* FIXME: Cannot do that here or it will get the sw and not the list.
88 We must a generic way of doing this. */
89 /* Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env,
90 obj); */
91 g_signal_connect (GTK_OBJECT (text), "event",
92 G_CALLBACK (pre_event_handler), *gref);
94 gdk_threads_leave ();
99 JNIEXPORT jint JNICALL
100 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getCaretPosition
101 (JNIEnv *env, jobject obj)
103 void *ptr;
104 int pos = 0;
105 GtkEditable *editable;
106 GtkWidget *text = NULL;
107 GtkTextBuffer *buf;
108 GtkTextMark *mark;
109 GtkTextIter iter;
111 ptr = NSA_GET_PTR (env, obj);
113 gdk_threads_enter ();
115 if (GTK_IS_EDITABLE (ptr))
117 editable = GTK_EDITABLE (ptr);
118 pos = gtk_editable_get_position (editable);
120 else
122 if (GTK_IS_SCROLLED_WINDOW (ptr))
124 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
126 else if (GTK_IS_TEXT_VIEW (ptr))
128 text = GTK_WIDGET (ptr);
131 if (text)
133 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
134 mark = gtk_text_buffer_get_insert (buf);
135 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
136 pos = gtk_text_iter_get_offset (&iter);
140 gdk_threads_leave ();
142 return pos;
145 JNIEXPORT void JNICALL
146 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setCaretPosition
147 (JNIEnv *env, jobject obj, jint pos)
149 void *ptr;
150 GtkEditable *editable;
151 GtkWidget *text = NULL;
152 GtkTextBuffer *buf;
153 GtkTextIter iter;
154 GtkTextMark *oldmark;
155 GtkTextIter olditer;
156 int oldpos;
158 ptr = NSA_GET_PTR (env, obj);
160 gdk_threads_enter ();
161 if (GTK_IS_EDITABLE (ptr))
163 editable = GTK_EDITABLE (ptr);
164 gtk_editable_set_position (editable, pos);
166 else
168 if (GTK_IS_SCROLLED_WINDOW (ptr))
170 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
172 else if (GTK_IS_TEXT_VIEW (ptr))
174 text = GTK_WIDGET (ptr);
177 if (text)
179 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
181 /* Save old position. */
182 oldmark = gtk_text_buffer_get_insert (buf);
183 gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
184 oldpos = gtk_text_iter_get_offset (&olditer);
186 /* Move to new position. */
187 gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
188 gtk_text_buffer_place_cursor (buf, &iter);
190 /* Scroll to new position. Alignment is determined
191 comparing the new position to the old position. */
192 if (oldpos > pos)
193 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
194 &iter, 0, TRUE, 0, 0);
195 else if (oldpos < pos)
196 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
197 &iter, 0, TRUE, 1, 1);
201 gdk_threads_leave ();
204 JNIEXPORT jint JNICALL
205 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getSelectionStart
206 (JNIEnv *env, jobject obj)
208 void *ptr;
209 int pos = 0;
210 GtkEditable *editable;
211 GtkWidget *text = NULL;
212 GtkTextBuffer *buf;
213 GtkTextIter start;
214 GtkTextIter end;
215 int starti, endi;
216 GtkTextMark *mark;
217 GtkTextIter iter;
219 ptr = NSA_GET_PTR (env, obj);
221 gdk_threads_enter ();
223 if (GTK_IS_EDITABLE (ptr))
225 editable = GTK_EDITABLE (ptr);
226 if (gtk_editable_get_selection_bounds (editable, &starti, &endi))
227 pos = starti;
228 else
229 pos = gtk_editable_get_position (editable);
231 else
233 if (GTK_IS_SCROLLED_WINDOW (ptr))
235 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
237 else if (GTK_IS_TEXT_VIEW (ptr))
239 text = GTK_WIDGET (ptr);
242 if (text)
244 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
245 if (gtk_text_buffer_get_selection_bounds(buf, &start, &end))
246 pos = gtk_text_iter_get_offset (&start);
247 else
249 mark = gtk_text_buffer_get_insert (buf);
250 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
251 pos = gtk_text_iter_get_offset (&iter);
256 gdk_threads_leave ();
258 return pos;
261 JNIEXPORT jint JNICALL
262 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getSelectionEnd
263 (JNIEnv *env, jobject obj)
265 void *ptr;
266 int pos = 0;
267 GtkEditable *editable;
268 GtkWidget *text = NULL;
269 GtkTextBuffer *buf;
270 GtkTextIter start;
271 GtkTextIter end;
272 int starti, endi;
273 GtkTextMark *mark;
274 GtkTextIter iter;
276 ptr = NSA_GET_PTR (env, obj);
278 gdk_threads_enter ();
280 if (GTK_IS_EDITABLE (ptr))
282 editable = GTK_EDITABLE (ptr);
283 if (gtk_editable_get_selection_bounds (editable, &starti, &endi))
284 pos = endi;
285 else
286 pos = gtk_editable_get_position (editable);
288 else
290 if (GTK_IS_SCROLLED_WINDOW (ptr))
292 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
294 else if (GTK_IS_TEXT_VIEW (ptr))
296 text = GTK_WIDGET (ptr);
299 if (text)
301 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
302 if (gtk_text_buffer_get_selection_bounds(buf, &start, &end))
303 pos = gtk_text_iter_get_offset (&end);
304 else
306 mark = gtk_text_buffer_get_insert (buf);
307 gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
308 pos = gtk_text_iter_get_offset (&iter);
313 gdk_threads_leave ();
315 return pos;
318 JNIEXPORT void JNICALL
319 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_select
320 (JNIEnv *env, jobject obj, jint start, jint end)
322 void *ptr;
323 GtkEditable *editable;
324 GtkWidget *text = NULL;
325 GtkTextBuffer *buf;
326 GtkTextIter iter;
328 ptr = NSA_GET_PTR (env, obj);
330 gdk_threads_enter ();
333 if (GTK_IS_EDITABLE (ptr))
335 editable = GTK_EDITABLE (ptr);
336 gtk_editable_select_region (editable, start, end);
338 else
340 if (GTK_IS_SCROLLED_WINDOW (ptr))
342 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
344 else if (GTK_IS_TEXT_VIEW (ptr))
346 text = GTK_WIDGET (ptr);
349 if (text)
351 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
352 gtk_text_buffer_get_iter_at_offset (buf, &iter, start);
353 /* quickly move both 'insert' and 'selection_bound' to the
354 same position */
355 gtk_text_buffer_place_cursor (buf, &iter);
356 gtk_text_buffer_get_iter_at_offset (buf, &iter, end);
357 gtk_text_buffer_move_mark_by_name (buf, "selection_bound", &iter);
361 gdk_threads_leave ();
364 JNIEXPORT void JNICALL
365 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setEditable
366 (JNIEnv *env, jobject obj, jboolean state)
368 void *ptr;
369 GtkEditable *editable;
370 GtkWidget *text = NULL;
372 ptr = NSA_GET_PTR (env, obj);
374 gdk_threads_enter ();
376 if (GTK_IS_EDITABLE (ptr))
378 editable = GTK_EDITABLE (ptr);
379 gtk_editable_set_editable (editable, state);
381 else
383 if (GTK_IS_SCROLLED_WINDOW (ptr))
385 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
387 else if (GTK_IS_TEXT_VIEW (ptr))
389 text = GTK_WIDGET (ptr);
392 if (text)
394 gtk_text_view_set_editable (GTK_TEXT_VIEW (text), state);
398 gdk_threads_leave ();
401 JNIEXPORT jstring JNICALL
402 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_getText
403 (JNIEnv *env, jobject obj)
405 void *ptr;
406 char *contents = NULL;
407 jstring jcontents;
408 GtkEditable *editable;
409 GtkWidget *text = NULL;
410 GtkTextBuffer *buf;
411 GtkTextIter start, end;
413 ptr = NSA_GET_PTR (env, obj);
415 gdk_threads_enter ();
417 if (GTK_IS_EDITABLE (ptr))
419 editable = GTK_EDITABLE (ptr);
420 contents = gtk_editable_get_chars (editable, 0, -1);
422 else
424 if (GTK_IS_SCROLLED_WINDOW (ptr))
426 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
428 else if (GTK_IS_TEXT_VIEW (ptr))
430 text = GTK_WIDGET (ptr);
433 if (text)
435 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
436 gtk_text_buffer_get_start_iter (buf, &start);
437 gtk_text_buffer_get_end_iter (buf, &end);
438 contents = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
442 gdk_threads_leave ();
444 jcontents = (*env)->NewStringUTF (env, contents);
445 g_free (contents);
447 return jcontents;
450 JNIEXPORT void JNICALL
451 Java_gnu_java_awt_peer_gtk_GtkTextComponentPeer_setText
452 (JNIEnv *env, jobject obj, jstring contents)
454 void *ptr;
455 const char *str;
456 GtkWidget *text = NULL;
457 GtkTextBuffer *buf;
459 ptr = NSA_GET_PTR (env, obj);
460 str = (*env)->GetStringUTFChars (env, contents, NULL);
462 gdk_threads_enter ();
464 if (GTK_IS_EDITABLE (ptr))
466 gtk_entry_set_text (GTK_ENTRY (ptr), str);
468 else
470 if (GTK_IS_SCROLLED_WINDOW (ptr))
472 text = GTK_WIDGET (GTK_TEXT_VIEW (GTK_SCROLLED_WINDOW (ptr)->container.child));
474 else if (GTK_IS_TEXT_VIEW (ptr))
476 text = GTK_WIDGET (ptr);
479 if (text)
481 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
482 gtk_text_buffer_set_text (buf, str, strlen (str));
486 gdk_threads_leave ();
488 (*env)->ReleaseStringUTFChars (env, contents, str);
491 static void
492 textcomponent_changed_cb (GtkEditable *editable __attribute__((unused)),
493 jobject peer)
495 gdk_threads_leave ();
496 (*gdk_env())->CallVoidMethod (gdk_env(), peer, postTextEventID);
497 gdk_threads_enter ();