From 56bba8cf57d0aa75d0266486595efe0d070af0b7 Mon Sep 17 00:00:00 2001
From: Hans Boehm <Hans_Boehm@hp.com>
Date: Wed, 19 Feb 2003 00:35:35 +0000
Subject: [PATCH] XToolkit.java (getFontMetrics): initialize if necessary.

2003-02-18  Hans Boehm  <Hans.Boehm@hp.com>

	* gnu/awt/xlib/XToolkit.java (getFontMetrics): initialize
	if necessary.

	* gnu/java/awt/peer/gtk/GtkButtonPeer.java,
	gnu/java/awt/peer/gtk/GtkTextAreaPeer.java,
	gnu/java/awt/peer/gtk/GtkTextFieldPeer.java,
	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c,
	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c,
	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
	(setFont, gtkSetFont): add.
	gnu/java/awt/peer/gtk/GtkComponentPeer.java (GtkComponentPeer):
	Propagate font to peer.  (setFont): add FIXME comment.

	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
	(gtkTextGetSize): fix height, width computation.

	* gnu/java/awt/peer/gtk/GtkFontPeer.java (GtkFontPeer):
	Make X font name a bit less bogus.

	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
	(post_adjustment_event): Pass on GTK_SCROLL_NONE.

	* java/awt/Scrollbar.java (setValues): Fix visibleAmount range check.
	(processAdjustmentEvent): Adjust value.

	* java/awt/FlowLayout.java (layoutContainer) Fix 2 indexing and one
	logic errors.

	* java/awt/Component.java (setVisible, show, hide): Call show and
	hide methods in subclasses.
	(getPreferredSize): don't set prefSize before we have peer.

	* java/awt/TextArea.java, java/awt/TextField.java (getPreferredSize):
	Guess (0,0) if we don't have peer.

From-SVN: r63077
---
 libjava/ChangeLog                             | 38 ++++++++++++++++
 libjava/gnu/awt/xlib/XToolkit.java            |  2 +-
 .../gnu/java/awt/peer/gtk/GtkButtonPeer.java  |  7 +++
 .../java/awt/peer/gtk/GtkComponentPeer.java   |  8 +++-
 .../gnu/java/awt/peer/gtk/GtkFontPeer.java    | 24 +++++++++-
 .../java/awt/peer/gtk/GtkTextAreaPeer.java    |  7 +++
 .../java/awt/peer/gtk/GtkTextFieldPeer.java   |  7 +++
 libjava/java/awt/Component.java               | 21 ++++++---
 libjava/java/awt/FlowLayout.java              |  6 +--
 libjava/java/awt/Scrollbar.java               |  5 ++-
 libjava/java/awt/TextArea.java                |  6 ++-
 libjava/java/awt/TextField.java               |  5 ++-
 .../gnu_java_awt_peer_gtk_GtkButtonPeer.c     | 36 +++++++++++++++
 .../gnu_java_awt_peer_gtk_GtkScrollBarPeer.c  |  3 +-
 .../gnu_java_awt_peer_gtk_GtkTextAreaPeer.c   | 45 +++++++++++++++++--
 .../gnu_java_awt_peer_gtk_GtkTextFieldPeer.c  | 33 ++++++++++++++
 16 files changed, 229 insertions(+), 24 deletions(-)

diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index db934865344d..116d2a10ec0a 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,41 @@
+2003-02-18  Hans Boehm  <Hans.Boehm@hp.com>
+
+	* gnu/awt/xlib/XToolkit.java (getFontMetrics): initialize
+	if necessary.
+	
+	* gnu/java/awt/peer/gtk/GtkButtonPeer.java,
+	gnu/java/awt/peer/gtk/GtkTextAreaPeer.java,
+	gnu/java/awt/peer/gtk/GtkTextFieldPeer.java,
+	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c,
+	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c,
+	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
+	(setFont, gtkSetFont): add.
+	gnu/java/awt/peer/gtk/GtkComponentPeer.java (GtkComponentPeer):
+	Propagate font to peer.  (setFont): add FIXME comment.
+
+	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
+	(gtkTextGetSize): fix height, width computation.
+
+	* gnu/java/awt/peer/gtk/GtkFontPeer.java (GtkFontPeer):
+	Make X font name a bit less bogus.
+
+	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
+	(post_adjustment_event): Pass on GTK_SCROLL_NONE.
+
+	* java/awt/Scrollbar.java (setValues): Fix visibleAmount range check.
+	(processAdjustmentEvent): Adjust value.
+
+	* java/awt/FlowLayout.java (layoutContainer) Fix 2 indexing and one
+	logic errors.
+
+	* java/awt/Component.java (setVisible, show, hide): Call show and
+	hide methods in subclasses.
+	(getPreferredSize): don't set prefSize before we have peer.
+
+	* java/awt/TextArea.java, java/awt/TextField.java (getPreferredSize):
+	Guess (0,0) if we don't have peer.
+
+
 2003-02-18  Michael Koch  <konqueror@gmx.de>
 
 	* java/nio/channels/FileChannel.java
diff --git a/libjava/gnu/awt/xlib/XToolkit.java b/libjava/gnu/awt/xlib/XToolkit.java
index c71b39d0f800..df3a2b6b5952 100644
--- a/libjava/gnu/awt/xlib/XToolkit.java
+++ b/libjava/gnu/awt/xlib/XToolkit.java
@@ -183,7 +183,7 @@ public class XToolkit extends Toolkit
 
   public FontMetrics getFontMetrics(Font font)
   {
-    return defaultConfig.getXFontMetrics(font);
+    return getDefaultXGraphicsConfiguration().getXFontMetrics(font);
   }
 
   public void sync()
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java
index 94603c0d3c92..a609f7ad818e 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java
@@ -47,6 +47,8 @@ public class GtkButtonPeer extends GtkComponentPeer
 {
   native void create ();
 
+  native void gtkSetFont(String xlfd, int size);
+
   public GtkButtonPeer (Button b)
   {
     super (b);
@@ -86,4 +88,9 @@ public class GtkButtonPeer extends GtkComponentPeer
 
     args.add ("label", ((Button)component).getLabel ());
   }
+
+  public void setFont (Font f)
+  {
+    gtkSetFont(((GtkFontPeer)f.getPeer()).getXLFD(), f.getSize());
+  }
 }
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index 6e3b25290c84..b3a4525314e3 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -88,6 +88,8 @@ public class GtkComponentPeer extends GtkGenericPeer
 	awtComponent.setBackground (getBackground ());
       //        if (c.getFont () == null)
       //  	c.setFont (cp.getFont ());
+      if (awtComponent.getFont() != null)
+	setFont(awtComponent.getFont());
       
       if (! (awtComponent instanceof Window))
 	{
@@ -273,6 +275,9 @@ public class GtkComponentPeer extends GtkGenericPeer
 
   public void setFont (Font f)
   {
+    // FIXME: This should really affect the widget tree below me.
+    // Currently this is only handled if the call is made directly on
+    // a text widget, which implements setFont() itself.
   }
 
   public void setForeground (Color c) 
@@ -352,7 +357,8 @@ public class GtkComponentPeer extends GtkGenericPeer
 	p = component.getPeer ();
       } while (p instanceof java.awt.peer.LightweightPeer);
     
-    args.add ("parent", p);
+    if (p != null)
+      args.add ("parent", p);
   }
 
   native void set (String name, String value);
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
index 47a46e81865b..d3130a905e98 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java
@@ -57,14 +57,34 @@ public class GtkFontPeer implements FontPeer
       }
   }
 
-  final private String Xname;
+  final private String Xname; // uses %d for font size.
 
   public GtkFontPeer (String name, int style)
   {
     if (bundle != null)
       Xname = bundle.getString (name.toLowerCase () + "." + style);
     else
-      Xname = "-*-*-medium-r-normal-*-12-*-*-*-c-*-*-*";
+      {
+	String weight;
+	String slant;
+	String spacing;
+
+	if (style == Font.ITALIC || (style == (Font.BOLD+Font.ITALIC)))
+	  slant = "i";
+	else
+	  slant = "r";
+	if (style == Font.BOLD || (style == (Font.BOLD+Font.ITALIC)))
+	  weight = "bold";
+	else
+	  weight = "medium";
+	if (name.equals("Serif") || name.equals("SansSerif")
+	    || name.equals("Helvetica") || name.equals("Times"))
+	  spacing = "p";
+	else
+	  spacing = "c";
+
+        Xname = "-*-*-" + weight + "-" + slant + "-normal-*-%d-*-*-*-" + spacing + "-*-*-*";
+      }
   }
 
   public String getXLFD ()
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
index 7a648b913add..ad83008cb8a3 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
@@ -45,6 +45,8 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer
 {
   native void create (int scrollbarVisibility);
 
+  native void gtkSetFont(String xlfd, int size);
+
   void create ()
   {
     create (((TextArea)awtComponent).getScrollbarVisibility ());
@@ -99,4 +101,9 @@ public class GtkTextAreaPeer extends GtkTextComponentPeer
   {
     insert (str, pos);
   }
+
+  public void setFont (Font f)
+  {
+    gtkSetFont(((GtkFontPeer)f.getPeer()).getXLFD(), f.getSize());
+  }
 }
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
index 4dc23f8ba55f..628cdd627aec 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
@@ -51,6 +51,8 @@ public class GtkTextFieldPeer extends GtkTextComponentPeer
 
   native void gtkEntryGetSize (int cols, int dims[]);
 
+  native void gtkSetFont(String xlfd, int size);
+
   public GtkTextFieldPeer (TextField tf)
   {
     super (tf);
@@ -95,4 +97,9 @@ public class GtkTextFieldPeer extends GtkTextComponentPeer
   {
     setEchoChar (c);
   }
+
+  public void setFont (Font f)
+  {
+    gtkSetFont(((GtkFontPeer)f.getPeer()).getXLFD(), f.getSize());
+  }
 }
diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java
index d61db055f56e..88f91810dc0b 100644
--- a/libjava/java/awt/Component.java
+++ b/libjava/java/awt/Component.java
@@ -844,9 +844,10 @@ public abstract class Component
     // Inspection by subclassing shows that Sun's implementation calls
     // show(boolean) which then calls show() or hide(). It is the show()
     // method that is overriden in subclasses like Window.
-    if (peer != null)
-      peer.setVisible(b);
-    this.visible = b;
+    if (b)
+      show();
+    else
+      hide();
   }
 
   /**
@@ -856,7 +857,9 @@ public abstract class Component
    */
   public void show()
   {
-    setVisible(true);
+    if (peer != null)
+      peer.setVisible(true);
+    this.visible = true;
   }
 
   /**
@@ -877,7 +880,9 @@ public abstract class Component
    */
   public void hide()
   {
-    setVisible(false);
+    if (peer != null)
+      peer.setVisible(false);
+    this.visible = false;
   }
 
   /**
@@ -1448,8 +1453,10 @@ public abstract class Component
   public Dimension getPreferredSize()
   {
     if (prefSize == null)
-      prefSize = (peer != null ? peer.getPreferredSize()
-                       : new Dimension(width, height));
+      if (peer == null)
+	return new Dimension(width, height);
+      else 
+        prefSize = peer.getPreferredSize();
     return prefSize;
   }
 
diff --git a/libjava/java/awt/FlowLayout.java b/libjava/java/awt/FlowLayout.java
index 1f9465e4bf96..795dfd8e61ff 100644
--- a/libjava/java/awt/FlowLayout.java
+++ b/libjava/java/awt/FlowLayout.java
@@ -171,13 +171,13 @@ public class FlowLayout implements LayoutManager, Serializable
 	    int new_h = 0;
 	    int j;
 	    boolean found_one = false;
-	    for (j = i; j < num && ! found_one; ++j)
+	    for (j = i; j < num; ++j)
 	      {
 		// Skip invisible items.
-		if (! comps[i].visible)
+		if (! comps[j].visible)
 		  continue;
 
-		Dimension c = comps[i].getPreferredSize ();
+		Dimension c = comps[j].getPreferredSize ();
 
 		int next_w = new_w + hgap + c.width;
 		if (next_w <= d.width || ! found_one)
diff --git a/libjava/java/awt/Scrollbar.java b/libjava/java/awt/Scrollbar.java
index f78f402d3c9f..b9a81a53b0fe 100644
--- a/libjava/java/awt/Scrollbar.java
+++ b/libjava/java/awt/Scrollbar.java
@@ -390,8 +390,8 @@ setValues(int value, int visibleAmount, int minimum, int maximum)
   if (value > maximum)
     value = maximum;
 
-  if (visibleAmount > value)
-    visibleAmount = value;
+  if (visibleAmount > maximum - minimum)
+    visibleAmount = maximum - minimum;
 
   this.value = value;
   this.visibleAmount = visibleAmount;
@@ -664,6 +664,7 @@ processEvent(AWTEvent event)
 protected void
 processAdjustmentEvent(AdjustmentEvent event)
 {
+  value = event.getValue();
   if (adjustment_listeners != null)
     adjustment_listeners.adjustmentValueChanged(event);
 }
diff --git a/libjava/java/awt/TextArea.java b/libjava/java/awt/TextArea.java
index f458f9b75e5f..ec87f87d4917 100644
--- a/libjava/java/awt/TextArea.java
+++ b/libjava/java/awt/TextArea.java
@@ -370,7 +370,11 @@ getPreferredSize(int rows, int columns)
 {
   TextAreaPeer tap = (TextAreaPeer)getPeer();
   if (tap == null)
-    return(null); // FIXME: What do we do if there is no peer?
+    {
+      // Sun's JDK just seems to return Dimension(0,0) in this case.
+      // we do the same.
+      return new Dimension(0, 0);
+    }
 
   return(tap.getPreferredSize(rows, columns));
 }
diff --git a/libjava/java/awt/TextField.java b/libjava/java/awt/TextField.java
index c2c2be7215e5..13275e3104af 100644
--- a/libjava/java/awt/TextField.java
+++ b/libjava/java/awt/TextField.java
@@ -345,8 +345,9 @@ getPreferredSize(int columns)
 {
   TextFieldPeer tfp = (TextFieldPeer)getPeer();
   if (tfp == null)
-    return(null); // FIXME: What do we do if there is no peer?
-
+    {
+      return new Dimension(0, 0);
+    }
   return(tfp.getPreferredSize(columns));
 }
 
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
index ebebc438ae87..e33aff046fcd 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
@@ -50,3 +50,39 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkButtonPeer_create
 
   NSA_SET_PTR (env, obj, widget);
 }
+
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring jname, jint size)
+{
+  const char *xlfd;
+# define FBUFSZ 200
+  char buf[FBUFSZ];
+  void *ptr;
+  GdkFont * new_font;
+  GtkStyle * style;
+  GtkWidget * button;
+  GtkWidget * label;
+
+  ptr = NSA_GET_PTR (env, obj);
+  button = GTK_WIDGET (ptr);
+  label = GTK_BIN(button)->child;
+  
+  if (label == NULL) return;
+  xlfd = (*env)->GetStringUTFChars (env, jname, NULL);
+  snprintf(buf, FBUFSZ, xlfd, size);
+  (*env)->ReleaseStringUTFChars (env, jname, xlfd);
+  gdk_threads_enter();
+  new_font = gdk_font_load (buf);  /* FIXME: deprecated. Replacement?	*/
+  if (new_font == NULL)
+    {
+      /* Fail quietly for now. */
+      gdk_threads_leave();
+      return;
+    }
+  style = gtk_style_copy (gtk_widget_get_style (label));
+  style -> font = new_font;
+  gtk_widget_set_style (label, style);
+  /* FIXME: Documentation varies as to whether we should unref style. */
+  gdk_threads_leave();
+}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
index 4b8787e7d931..9237a01b5a85 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c
@@ -65,9 +65,10 @@ post_adjustment_event (GtkAdjustment *adj, struct range_scrollbar *rs)
       type = AWT_ADJUSTMENT_BLOCK_DECREMENT;
       break;
     case GTK_SCROLL_JUMP:
+    case GTK_SCROLL_NONE:  /* Apparently generated when slider is dragged. */
       type = AWT_ADJUSTMENT_TRACK;
       break;
-    default: /* GTK_SCROLL_NONE */
+    default: /* Can this happen?  If so, is this right? */
       return;
     }
   
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
index 8f58623d573f..27f274615183 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
@@ -135,27 +135,32 @@ Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkTextGetSize
   text = GTK_WIDGET (TEXT_FROM_SW (ptr));
   sw = GTK_SCROLLED_WINDOW (ptr);
 
-  gtk_signal_emit_by_name (GTK_OBJECT (GTK_SCROLLED_WINDOW(sw)->hscrollbar), 
+  gtk_signal_emit_by_name (GTK_OBJECT (GTK_SCROLLED_WINDOW(sw)->vscrollbar), 
 			   "size_request", &myreq);
   //gtk_widget_size_request(GTK_WIDGET (GTK_SCROLLED_WINDOW(sw)->hscrollbar), 
   //				      &myreq);
   dims[0]=myreq.width+GTK_SCROLLED_WINDOW_CLASS 
     (GTK_OBJECT (sw)->klass)->scrollbar_spacing;
 
-  gtk_signal_emit_by_name (GTK_OBJECT (GTK_SCROLLED_WINDOW(sw)->vscrollbar), 
+  gtk_signal_emit_by_name (GTK_OBJECT (GTK_SCROLLED_WINDOW(sw)->hscrollbar), 
 			   "size_request", &myreq);
   //gtk_widget_size_request(GTK_WIDGET (GTK_SCROLLED_WINDOW(sw)->vscrollbar), 
   //				      &myreq);
-  dims[1]=myreq.width+GTK_SCROLLED_WINDOW_CLASS 
+  dims[1]=myreq.height+GTK_SCROLLED_WINDOW_CLASS 
     (GTK_OBJECT (sw)->klass)->scrollbar_spacing;
   
   /* The '1' in the following assignments is from 
      #define TEXT_BORDER_ROOM         1
      in gtktext.c */
 
+  /* Gtk text seems to wrap slightly prematurely.  Compensate. */
+    ++cols;
+    ++dims[0];
+
   dims[0] += ((cols * gdk_char_width (text->style->font, 'W'))
 	     + (2 * (text->style->klass->xthickness + 1)));
-  dims[1] += ((rows * gdk_char_height (text->style->font, 'W'))
+  /* Guess at the height.  Is there a better way?	*/
+  dims[1] += ((rows * gdk_string_height (text->style->font, "Wg"))
 	     + (2 * (text->style->klass->ythickness + 1)));
 
   gdk_threads_leave ();
@@ -207,3 +212,35 @@ Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange
   (*env)->ReleaseStringUTFChars (env, contents, str);
 }
 
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring jname, jint size)
+{
+  const char *xlfd;
+# define FBUFSZ 200
+  char buf[FBUFSZ];
+  void *ptr;
+  GdkFont * new_font;
+  GtkStyle * style;
+  GtkWidget * text;
+
+  ptr = NSA_GET_PTR (env, obj);
+  text = GTK_WIDGET (TEXT_FROM_SW (ptr));
+  
+  xlfd = (*env)->GetStringUTFChars (env, jname, NULL);
+    snprintf(buf, FBUFSZ, xlfd, size);
+  (*env)->ReleaseStringUTFChars (env, jname, xlfd);
+  gdk_threads_enter();
+  new_font = gdk_font_load (buf);  /* FIXME: deprecated. Replacement?	*/
+  if (new_font == NULL)
+    {
+      /* Fail quietly for now. */
+      gdk_threads_leave();
+      return;
+    }
+  style = gtk_style_copy (gtk_widget_get_style (text));
+  style -> font = new_font;
+  gtk_widget_set_style (text , style);
+  /* FIXME: Documentation varies as to whether we should unref style. */
+  gdk_threads_leave();
+}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
index 9085a57937da..658c8639bb72 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
@@ -148,3 +148,36 @@ Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
 
   gdk_threads_leave ();
 }
+
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkSetFont
+  (JNIEnv *env, jobject obj, jstring jname, jint size)
+{
+  const char *xlfd;
+# define FBUFSZ 200
+  char buf[FBUFSZ];
+  void *ptr;
+  GdkFont * new_font;
+  GtkStyle * style;
+  GtkWidget * text;
+
+  ptr = NSA_GET_PTR (env, obj);
+  text = GTK_WIDGET (ptr);
+  
+  xlfd = (*env)->GetStringUTFChars (env, jname, NULL);
+  snprintf(buf, FBUFSZ, xlfd, size);
+  (*env)->ReleaseStringUTFChars (env, jname, xlfd);
+  gdk_threads_enter();
+  new_font = gdk_font_load(buf);  /* FIXME: deprecated. Replacement?	*/
+  if (new_font == NULL)
+    {
+      /* Fail quietly for now. */
+      gdk_threads_leave();
+      return;
+    }
+  style = gtk_style_copy (gtk_widget_get_style (text));
+  style -> font = new_font;
+  gtk_widget_set_style (text , style);
+  /* FIXME: Documentation varies as to whether we should unref style. */
+  gdk_threads_leave();
+}
-- 
GitLab