OSDN Git Service

2006-08-14 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
1 /* gtktextfieldpeer.c -- Native implementation of GtkTextFieldPeer
2    Copyright (C) 1998, 1999, 2002 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_GtkTextFieldPeer.h"
41
42 /* the color used for highlighting when the foreground is black,
43    since black highlights aren't a Good Idea. */
44 #define BB_RED    16962
45 #define BB_GREEN  26985
46 #define BB_BLUE   31611
47
48 static jmethodID postTextEventID;
49
50 void
51 cp_gtk_textcomponent_init_jni (void)
52 {
53   jclass gtkcomponentpeer;
54
55   gtkcomponentpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
56                                               "gnu/java/awt/peer/gtk/GtkComponentPeer");
57
58   postTextEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
59                                              "postTextEvent",
60                                              "()V");
61 }
62
63 static void textcomponent_changed_cb (GtkEditable *editable, jobject peer);
64
65 static jint get_border_width (GtkWidget *entry);
66
67 JNIEXPORT void JNICALL 
68 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_create
69   (JNIEnv *env, jobject obj, jint text_width)
70 {
71   GtkWidget *entry;
72
73   gdk_threads_enter ();
74
75   /* Create global reference and save it for future use */
76   NSA_SET_GLOBAL_REF (env, obj);
77
78   entry = gtk_entry_new ();
79   gtk_widget_set_size_request (entry,
80                                text_width + 2 * get_border_width (entry), -1);
81
82   NSA_SET_PTR (env, obj, entry);
83
84   gdk_threads_leave ();
85 }
86
87 JNIEXPORT void JNICALL
88 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_connectSignals
89   (JNIEnv *env, jobject obj)
90 {
91   void *ptr;
92   jobject *gref;
93
94   gdk_threads_enter ();
95
96   ptr = NSA_GET_PTR (env, obj);
97   gref = NSA_GET_GLOBAL_REF (env, obj);
98
99   /* TextComponent signals */
100   cp_gtk_textcomponent_connect_signals (G_OBJECT (ptr), gref);
101
102   /* Component signals */
103   cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
104
105   gdk_threads_leave ();
106 }
107
108 JNIEXPORT void JNICALL
109 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetBackground
110   (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
111 {
112   GdkColor color;
113   void *ptr;
114
115   gdk_threads_enter ();
116
117   ptr = NSA_GET_PTR (env, obj);
118
119   color.red = (red / 255.0) * 65535;
120   color.green = (green / 255.0) * 65535;
121   color.blue = (blue / 255.0) * 65535;
122
123   gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
124
125   gdk_threads_leave ();
126 }
127
128 JNIEXPORT void JNICALL 
129 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetForeground
130   (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
131 {
132   GdkColor color;
133   void *ptr;
134
135   gdk_threads_enter ();
136
137   ptr = NSA_GET_PTR (env, obj);
138
139   color.red = (red / 255.0) * 65535;
140   color.green = (green / 255.0) * 65535;
141   color.blue = (blue / 255.0) * 65535;
142   
143   gtk_widget_modify_text (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
144
145   if ( red == 0 && green == 0 && blue == 0)
146     {
147       color.red = BB_RED;
148       color.green = BB_GREEN;
149       color.blue = BB_BLUE;
150     }
151   gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_SELECTED, &color);
152
153   gdk_threads_leave ();
154 }
155
156 JNIEXPORT jint JNICALL
157 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetBorderWidth
158   (JNIEnv *env, jobject obj)
159 {
160   void *ptr;
161   int border_width = 0;
162
163   gdk_threads_enter ();
164
165   ptr = NSA_GET_PTR (env, obj);
166
167   border_width = get_border_width (GTK_WIDGET (ptr));
168
169   gdk_threads_leave ();
170
171   return border_width;
172 }
173
174 /* GTK hard-codes this value.  It is the space between a GtkEntry's
175    frame and its text. */
176 #define INNER_BORDER 2
177
178 static jint
179 get_border_width (GtkWidget *entry)
180 {
181   gint focus_width;
182   gboolean interior_focus;
183   int x_border_width = INNER_BORDER;
184
185   gtk_widget_style_get (entry,
186                         "interior-focus", &interior_focus,
187                         "focus-line-width", &focus_width,
188                         NULL);
189
190   if (GTK_ENTRY (entry)->has_frame)
191     x_border_width += entry->style->xthickness;
192
193   if (!interior_focus)
194     x_border_width += focus_width;
195
196   return x_border_width;
197 }
198
199 #undef INNER_BORDER
200
201 JNIEXPORT void JNICALL 
202 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
203   (JNIEnv *env, jobject obj, jchar c)
204 {
205   void *ptr;
206   GtkEntry *entry;
207
208   gdk_threads_enter ();
209
210   ptr = NSA_GET_PTR (env, obj);
211
212   entry = GTK_ENTRY (ptr);
213
214   if (c != 0)
215     {
216       /* FIXME: use gtk_entry_set_invisible_char (GtkEntry *entry,
217          gunichar ch) here.  That means we must convert from jchar
218          (utf16) to gunichar (ucs4). */
219       gtk_entry_set_visibility (entry, FALSE);
220     }
221   else
222     gtk_entry_set_visibility (entry, TRUE);
223
224   gdk_threads_leave ();
225 }
226
227 JNIEXPORT jint JNICALL 
228 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getCaretPosition
229   (JNIEnv *env, jobject obj)
230 {
231   void *ptr;
232   int pos = 0;
233
234   gdk_threads_enter ();
235
236   ptr = NSA_GET_PTR (env, obj);
237
238   pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
239
240   gdk_threads_leave ();
241   
242   return pos;
243 }
244
245 JNIEXPORT void JNICALL 
246 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setCaretPosition
247   (JNIEnv *env, jobject obj, jint pos)
248 {
249   void *ptr;
250
251   gdk_threads_enter ();
252
253   ptr = NSA_GET_PTR (env, obj);
254
255   gtk_editable_set_position (GTK_EDITABLE (ptr), pos);
256
257   gdk_threads_leave ();
258 }
259
260 JNIEXPORT jint JNICALL 
261 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionStart
262   (JNIEnv *env, jobject obj)
263 {
264   void *ptr;
265   int pos = 0;
266   int starti, endi;
267
268   gdk_threads_enter ();
269
270   ptr = NSA_GET_PTR (env, obj);
271
272   if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
273     pos = starti;
274   else
275     pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
276
277   gdk_threads_leave ();
278
279   return pos;
280 }
281
282 JNIEXPORT jint JNICALL 
283 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionEnd
284   (JNIEnv *env, jobject obj)
285 {
286   void *ptr;
287   int pos = 0;
288   int starti, endi;
289
290   gdk_threads_enter ();
291
292   ptr = NSA_GET_PTR (env, obj);
293
294   if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
295     pos = endi;
296   else
297     pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
298
299   gdk_threads_leave ();
300
301   return pos;
302 }
303
304 JNIEXPORT void JNICALL 
305 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_select
306   (JNIEnv *env, jobject obj, jint start, jint end)
307 {
308   void *ptr;
309
310   gdk_threads_enter ();
311
312   ptr = NSA_GET_PTR (env, obj);
313
314   gtk_editable_select_region (GTK_EDITABLE (ptr), start, end);
315
316   gdk_threads_leave ();
317 }
318
319 JNIEXPORT void JNICALL 
320 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEditable
321   (JNIEnv *env, jobject obj, jboolean state)
322 {
323   void *ptr;
324
325   gdk_threads_enter ();
326
327   ptr = NSA_GET_PTR (env, obj);
328
329   gtk_editable_set_editable (GTK_EDITABLE (ptr), state);
330
331   gdk_threads_leave ();
332 }
333
334 JNIEXPORT jstring JNICALL
335 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getText
336   (JNIEnv *env, jobject obj)
337 {
338   void *ptr;
339   char *contents = NULL;
340   jstring jcontents;
341
342   gdk_threads_enter ();
343
344   ptr = NSA_GET_PTR (env, obj);
345   
346   contents = gtk_editable_get_chars (GTK_EDITABLE (ptr), 0, -1);
347
348   jcontents = (*env)->NewStringUTF (env, contents);
349
350   g_free (contents);
351
352   gdk_threads_leave ();
353
354   return jcontents;
355 }
356
357 JNIEXPORT void JNICALL 
358 Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setText
359   (JNIEnv *env, jobject obj, jstring contents)
360 {
361   void *ptr;
362   const char *str;
363
364   gdk_threads_enter ();
365
366   ptr = NSA_GET_PTR (env, obj);
367   str = (*env)->GetStringUTFChars (env, contents, NULL);
368   
369   gtk_entry_set_text (GTK_ENTRY (ptr), str);
370
371   (*env)->ReleaseStringUTFChars (env, contents, str);
372
373   gdk_threads_leave ();
374 }
375
376 void
377 cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref)
378 {
379   g_signal_connect (G_OBJECT(ptr), "changed",
380                     G_CALLBACK (textcomponent_changed_cb), *gref);
381 }
382
383 static void
384 textcomponent_changed_cb (GtkEditable *editable __attribute__((unused)),
385                           jobject peer)
386 {
387   (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postTextEventID);
388 }