JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem
  (JNIEnv *env, jobject obj, jobject menuitempeer, jint key, jboolean shift)
{
  void *ptr1, *ptr2;
  GtkWidget *menu;

  gdk_threads_enter ();

  ptr1 = gtkpeer_get_widget (env, obj);
  ptr2 = gtkpeer_get_widget (env, menuitempeer);

  menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
  gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));

  if (key)
    {
      gtk_widget_add_accelerator (GTK_WIDGET (ptr2), "activate",
				  gtk_menu_get_accel_group (GTK_MENU (menu)), key, 
				  (GDK_CONTROL_MASK
				   | ((shift) ? GDK_SHIFT_MASK : 0)), 
				  GTK_ACCEL_VISIBLE);
    }

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_setupAccelGroup
  (JNIEnv *env, jobject obj, jobject parent)
{
  void *ptr1, *ptr2;

  gdk_threads_enter ();

  ptr1 = gtkpeer_get_widget (env, obj);

  if (!parent)
    {
      gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu), 
				gtk_accel_group_new ());
    }
  else
    {
      GtkAccelGroup *parent_accel;

      ptr2 = gtkpeer_get_widget (env, parent);
      parent_accel = gtk_menu_get_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr2)->submenu));
      
      gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu),
				parent_accel);
    }
      
  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
  (JNIEnv *env, jobject obj, jint start, jint end)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeIter iter;
  GtkTreeModel *list_store;
  jint i;
  jint num_items;
    
  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

  /* Special case: remove all rows. */
  if (end == -1)
    gtk_list_store_clear (GTK_LIST_STORE (list_store));
  else
    {
      i = 0;
      num_items = end - start + 1;
      gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
      while (i < num_items)
	{
	  gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
	  i++;
	}
    }

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_add
  (JNIEnv *env, jobject obj, jstring text, jint index)
{
  void *ptr;
  const char *str;
  GtkWidget *list;
  GtkTreeIter iter;
  GtkTreeModel *list_store;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  str = (*env)->GetStringUTFChars (env, text, NULL);

  list = list_get_widget (GTK_WIDGET (ptr));
  list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));

  if (index == -1)
    gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
  else
    gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);

  gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
                      COLUMN_STRING, str, -1);

  (*env)->ReleaseStringUTFChars (env, text, str);

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
  (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
  const char *font_name;
  void *ptr;
  GtkWidget *list;
  PangoFontDescription *font_desc;

  gdk_threads_enter();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));

  font_name = (*env)->GetStringUTFChars (env, name, NULL);

  font_desc = pango_font_description_from_string (font_name);
  pango_font_description_set_size (font_desc,
                                   size * cp_gtk_dpi_conversion_factor);

  if (style & AWT_STYLE_BOLD)
    pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);

  if (style & AWT_STYLE_ITALIC)
    pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);

  gtk_widget_modify_font (GTK_WIDGET (list), font_desc);

  pango_font_description_free (font_desc);

  (*env)->ReleaseStringUTFChars (env, name, font_name);

  gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectSignals
(JNIEnv *env, jobject obj)
{
    void *ptr;
    jobject gref;

    gdk_threads_enter ();

    ptr = gtkpeer_get_widget (env, obj);
    gref = gtkpeer_get_global_ref (env, obj);

    /* Panel signals.  These callbacks prevent expose events being
       delivered to the panel when it is focused. */
    g_signal_connect (G_OBJECT (ptr), "focus-in-event",
                      G_CALLBACK (panel_focus_in_cb), gref);

    g_signal_connect (G_OBJECT (ptr), "focus-out-event",
                      G_CALLBACK (panel_focus_out_cb), gref);

    /* Component signals.  Exclude focus signals. */
    cp_gtk_component_connect_expose_signals (ptr, gref);
    cp_gtk_component_connect_mouse_signals (ptr, gref);

    gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_setPolicy
  (JNIEnv *env, jobject obj, jint policy)
{
  void *ptr;
  GtkWidget *sw;
  
  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  switch (policy)
    {
    case AWT_SCROLLPANE_SCROLLBARS_AS_NEEDED:
      policy = GTK_POLICY_AUTOMATIC;
      break;
    case AWT_SCROLLPANE_SCROLLBARS_ALWAYS:
      policy = GTK_POLICY_ALWAYS;
      break;
    case AWT_SCROLLPANE_SCROLLBARS_NEVER:
      policy = GTK_POLICY_NEVER;
      break;
    }

  sw = scrollpane_get_widget (GTK_WIDGET (ptr));
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), policy, policy);

  gdk_threads_leave ();
}
Exemple #8
0
/* Does not require locking: meant to be called after the drawing
   surface is locked. */
VisualID
classpath_jawt_get_visualID (JNIEnv* env, jobject canvas)
{
  GtkWidget *widget;
  Visual *visual;
  void *ptr;
  jobject peer;
  jclass class_id;
  jmethodID method_id;

  class_id = (*env)->GetObjectClass (env, canvas);

  method_id = (*env)->GetMethodID (env, class_id,
				   "getPeer",
				   "()Ljava/awt/peer/ComponentPeer;");

  peer = (*env)->CallObjectMethod (env, canvas, method_id);

  ptr = gtkpeer_get_widget (env, peer);

  widget = GTK_WIDGET (ptr);

  if (GTK_WIDGET_REALIZED (widget))
    {
      visual = gdk_x11_visual_get_xvisual (gtk_widget_get_visual (widget));
      g_assert (visual != NULL);

      return visual->visualid;
    }
  else
    return (VisualID) NULL;
}
/**
 * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
 */
JNIEXPORT jlong JNICALL 
Java_gnu_java_awt_peer_gtk_GtkVolatileImage_init (JNIEnv *env, 
						  jobject obj __attribute__ ((__unused__)), 
						  jobject peer,
						  jint width, jint height)
{
  GtkWidget *widget = NULL;
  GdkPixmap* pixmap;
  void *ptr = NULL;

  gdk_threads_enter();

  if( peer != NULL )
    {
      ptr = gtkpeer_get_widget (env, peer);
      g_assert (ptr != NULL);
      
      widget = GTK_WIDGET (ptr);
      g_assert (widget != NULL);
      pixmap = gdk_pixmap_new( widget->window, width, height, -1 );
    }
  else
    pixmap = gdk_pixmap_new( NULL, width, height, 
			     gdk_rgb_get_visual()->depth );

  gdk_threads_leave();

  g_assert( pixmap != NULL );

  return PTR_TO_JLONG( pixmap );
}
Exemple #10
0
/* Does not require locking: meant to be called after the drawing
   surface is locked. */
Drawable
classpath_jawt_get_drawable (JNIEnv* env, jobject canvas)
{
  GtkWidget *widget;
  int drawable;
  void *ptr;
  jobject peer;
  jclass class_id;
  jmethodID method_id;

  class_id = (*env)->GetObjectClass (env, canvas);

  method_id = (*env)->GetMethodID (env, class_id,
				   "getPeer",
				   "()Ljava/awt/peer/ComponentPeer;");

  peer = (*env)->CallObjectMethod (env, canvas, method_id);

  ptr = gtkpeer_get_widget (env, peer);

  widget = GTK_WIDGET (ptr);

  if (GTK_WIDGET_REALIZED (widget))
    {
      drawable = GDK_DRAWABLE_XID (widget->window);

      return drawable;
    }
  else
    return (Drawable) NULL;
}
JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetBackground
  (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
  GdkColor normal_color;
  GdkColor active_color;
  GtkWidget *widget;
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  normal_color.red = (red / 255.0) * 65535;
  normal_color.green = (green / 255.0) * 65535;
  normal_color.blue = (blue / 255.0) * 65535;

  /* This calculation only approximates the active colors produced by
     Sun's AWT. */
  active_color.red = 0.85 * (red / 255.0) * 65535;
  active_color.green = 0.85 * (green / 255.0) * 65535;
  active_color.blue = 0.85 * (blue / 255.0) * 65535;

  widget = find_bg_color_widget (GTK_WIDGET (ptr));

  gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &normal_color);
  gtk_widget_modify_bg (widget, GTK_STATE_ACTIVE, &active_color);
  gtk_widget_modify_bg (widget, GTK_STATE_PRELIGHT, &normal_color);

  gdk_threads_leave ();
}
JNIEXPORT jintArray JNICALL 
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetForeground
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  jintArray array;
  jint *rgb;
  GdkColor fg;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  fg = get_widget(GTK_WIDGET (ptr))->style->fg[GTK_STATE_NORMAL];

  array = (*env)->NewIntArray (env, 3);

  rgb = (*env)->GetIntArrayElements (env, array, NULL);
  /* convert color data from 16 bit values down to 8 bit values */
  rgb[0] = fg.red   >> 8;
  rgb[1] = fg.green >> 8;
  rgb[2] = fg.blue  >> 8;
  (*env)->ReleaseIntArrayElements (env, array, rgb, 0);

  gdk_threads_leave ();

  return array;
}
Exemple #13
0
/* Does not require locking: meant to be called after the drawing
   surface is locked. */
Display*
classpath_jawt_get_default_display (JNIEnv* env, jobject canvas)
{
  GdkDisplay *display;
  Display *xdisplay;
  GtkWidget *widget;
  void *ptr;
  jobject peer;
  jclass class_id;
  jmethodID method_id;

  /* retrieve peer object */
  class_id = (*env)->GetObjectClass (env, canvas);

  method_id = (*env)->GetMethodID (env, class_id,
				   "getPeer",
				   "()Ljava/awt/peer/ComponentPeer;");

  peer = (*env)->CallObjectMethod (env, canvas, method_id);

  ptr = gtkpeer_get_widget (env, peer);

  widget = GTK_WIDGET (ptr);

  if (GTK_WIDGET_REALIZED (widget))
    {
      display = gtk_widget_get_display (widget);

      xdisplay = GDK_DISPLAY_XDISPLAY (display);

      return xdisplay;
    }
  else
    return NULL;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer
(JNIEnv *env, jobject obj)
{
    void *ptr;
    void *mptr;
    void *fixed;
    GList* children;

    gdk_threads_enter ();

    ptr = gtkpeer_get_widget (env, obj);

    fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
    children = gtk_container_get_children (GTK_CONTAINER (fixed));

    while (children != NULL && !GTK_IS_MENU_SHELL (children->data))
    {
        children = children->next;
    }

    /* If there's a menu bar, remove it. */
    if (children != NULL)
    {
        mptr = children->data;

        /* This will actually destroy the MenuBar. By removing it from
           its parent, the reference count for the MenuBar widget will
           decrement to 0. The widget will be automatically destroyed by
           GTK. */
        gtk_container_remove (GTK_CONTAINER (fixed), GTK_WIDGET (mptr));
    }

    gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
  (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
  GtkWidget *widget;
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  widget = GTK_WIDGET (ptr);

  /* We assume that -1 is a width or height and not a request for the
     widget's natural size. */
  width = width < 0 ? 0 : width;
  height = height < 0 ? 0 : height;

  if (!(width == 0 && height == 0))
    {
      gtk_widget_set_size_request (widget, width, height);
      /* The GTK_IS_FIXED check here prevents gtk_fixed_move being
         called when our parent is a GtkScrolledWindow.  In that
         case though, moving the child widget is invalid since a
         ScrollPane only has one child and that child is always
         located at (0, 0) in viewport coordinates. */
      if (widget->parent != NULL && GTK_IS_FIXED (widget->parent))
        gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
    }

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetParent
  (JNIEnv *env, jobject obj, jobject parent)
{
  void *ptr;
  void *parent_ptr;
  GtkWidget *widget;
  GtkWidget *parent_widget;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  parent_ptr = gtkpeer_get_widget (env, parent);
  
  widget = GTK_WIDGET (ptr);
  parent_widget = get_widget(GTK_WIDGET (parent_ptr));

  if (widget->parent == NULL)
    {
      if (GTK_IS_WINDOW (parent_widget))
	{
	  GList *children = gtk_container_get_children
	    (GTK_CONTAINER (parent_widget));

          if (GTK_IS_MENU_BAR (children->data))
            gtk_fixed_put (GTK_FIXED (children->next->data), widget, 0, 0);
          else
            gtk_fixed_put (GTK_FIXED (children->data), widget, 0, 0);
        }
      else
        if (GTK_IS_SCROLLED_WINDOW (parent_widget))
          {
            gtk_scrolled_window_add_with_viewport 
              (GTK_SCROLLED_WINDOW (parent_widget), widget);
            gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent), 
                                          GTK_SHADOW_NONE);

          }
        else
          {
            if (widget->parent == NULL)
              gtk_fixed_put (GTK_FIXED (parent_widget), widget, 0, 0);
          }
    }

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_deiconify
(JNIEnv *env, jobject obj)
{
    void *ptr;
    gdk_threads_enter ();
    ptr = gtkpeer_get_widget (env, obj);
    gtk_window_deiconify (GTK_WINDOW (ptr));
    gdk_threads_leave ();
}
JNIEXPORT jintArray JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  GtkWidget *list;
  GtkTreeSelection *selection;
  jintArray result_array;
  jint *result_array_iter;
  GList *current_row;
  GList *rows;
  gint *indices;
  jint count;
  jint i;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  list = list_get_widget (GTK_WIDGET (ptr));
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
  count = gtk_tree_selection_count_selected_rows (selection);
  if (count > 0)
    {
      current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);

      result_array = (*env)->NewIntArray (env, count);

      result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);

      for (i = 0; i < count; i++)
        {
          indices = gtk_tree_path_get_indices (current_row->data);
          result_array_iter[i] = indices ? indices[0] : -1;
          current_row = g_list_next (current_row);
        }

      if (rows)
        {
          g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
          g_list_free (rows);
        }

      (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
    }
  else
    result_array = NULL;

  gdk_threads_leave ();

  return result_array;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_realize (JNIEnv *env, jobject obj)
{
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  gtk_widget_realize (GTK_WIDGET (ptr));

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setVisibleNativeUnlocked
  (JNIEnv *env, jobject obj, jboolean visible)
{
  void *ptr;

  ptr = gtkpeer_get_widget (env, obj);

  if (visible)
    gtk_widget_show (GTK_WIDGET (ptr));
  else
    gtk_widget_hide (GTK_WIDGET (ptr));
}
JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWindowGetLocationOnScreenUnlocked
  (JNIEnv * env, jobject obj, jintArray jpoint)
{
  void *ptr;
  jint *point;

  ptr = gtkpeer_get_widget (env, obj);
  point = (*env)->GetIntArrayElements (env, jpoint, 0);

  gdk_window_get_root_origin (get_widget(GTK_WIDGET (ptr))->window, point, point+1);

  (*env)->ReleaseIntArrayElements(env, jpoint, point, 0);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetSensitive
  (JNIEnv *env, jobject obj, jboolean sensitive)
{
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  gtk_widget_set_sensitive (get_widget(GTK_WIDGET (ptr)), sensitive);

  gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer
(JNIEnv *env, jobject obj, jobject menubar)
{
    void *ptr;
    void *mptr;
    void *fixed;

    gdk_threads_enter ();

    ptr = gtkpeer_get_widget (env, obj);

    if (menubar)
    {
        mptr = gtkpeer_get_widget (env, menubar);

        fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
        gtk_fixed_put (GTK_FIXED (fixed), mptr, 0, 0);
        gtk_widget_show (mptr);
    }

    gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetRequestFocus
  (JNIEnv *env, jobject obj)
{
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  
  gtk_widget_grab_focus (get_widget(GTK_WIDGET (ptr)));

  gdk_threads_leave ();
}
/*
 * Find this widget's preferred size.
 */
JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetPreferredDimensions
  (JNIEnv *env, jobject obj, jintArray jdims)
{
  void *ptr;
  jint *dims;
  GtkRequisition current_req;
  GtkRequisition natural_req;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  dims = (*env)->GetIntArrayElements (env, jdims, 0);  
  dims[0] = dims[1] = 0;

  /* Widgets that extend GtkWindow such as GtkFileChooserDialog may have
     a default size.  These values seem more useful then the natural
     requisition values, particularly for GtkFileChooserDialog. */
  if (GTK_IS_WINDOW (get_widget(GTK_WIDGET (ptr))))
    {
      gint width, height;
      gtk_window_get_default_size (GTK_WINDOW (get_widget(GTK_WIDGET (ptr))), &width, &height);

      dims[0] = width;
      dims[1] = height;
    }
  else
    {
      /* Save the widget's current size request. */
      gtk_widget_size_request (get_widget(GTK_WIDGET (ptr)), &current_req);

      /* Get the widget's "natural" size request. */
      gtk_widget_set_size_request (get_widget(GTK_WIDGET (ptr)), -1, -1);
      gtk_widget_size_request (get_widget(GTK_WIDGET (ptr)), &natural_req);

      /* Reset the widget's size request. */
      gtk_widget_set_size_request (get_widget(GTK_WIDGET (ptr)),
			           current_req.width, current_req.height);

      dims[0] = natural_req.width;
      dims[1] = natural_req.height;
    }

  (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);

  gdk_threads_leave ();
}
JNIEXPORT jboolean JNICALL 
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled 
  (JNIEnv *env, jobject obj)
{
  void *ptr;
  jboolean ret_val;
  
  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  ret_val = GTK_WIDGET_IS_SENSITIVE (get_widget(GTK_WIDGET (ptr)));

  gdk_threads_leave ();

  return ret_val;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
(JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar)
{
    GtkWidget *ptr;
    GtkRequisition requisition;

    gdk_threads_enter ();

    ptr = gtkpeer_get_widget (env, menubar);

    gtk_widget_size_request (ptr, &requisition);

    gdk_threads_leave ();

    return requisition.height;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer_construct
  (JNIEnv *env, jobject obj, jlong socket_id)
{
  void *ptr;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);

  if (GTK_WIDGET_REALIZED (GTK_WIDGET (ptr)))
    g_printerr ("ERROR: GtkPlug is already realized\n");

  gtk_plug_construct (GTK_PLUG (ptr), (GdkNativeWindow) socket_id);

  gdk_threads_leave ();
}
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetCanFocus
(JNIEnv *env, jobject obj)
{
  void *ptr;
  jboolean retval;

  gdk_threads_enter ();

  ptr = gtkpeer_get_widget (env, obj);
  
  retval = GTK_WIDGET_CAN_FOCUS((GTK_WIDGET (ptr)));

  gdk_threads_leave ();

  return retval;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
  (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
{
  void *ptr;
  jint *dims;
  GtkRequisition current_req;
  GtkRequisition natural_req;
  GtkWidget* bin;

  gdk_threads_enter ();

  dims = (*env)->GetIntArrayElements (env, jdims, NULL);
  dims[0] = dims[1] = 0;

  ptr = gtkpeer_get_widget (env, obj);
  bin = list_get_widget (GTK_WIDGET (ptr));
  
  /* Save the widget's current size request. */
  gtk_widget_size_request (bin, &current_req);
      
  /* Get the widget's "natural" size request. */
  gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
  gtk_widget_size_request (bin, &natural_req);

  /* Reset the widget's size request. */
  gtk_widget_set_size_request (bin,
                               current_req.width, current_req.height);

  dims[0] = natural_req.width;

  /* Calculate the final height, by comparing the number of rows
     in the list to the number of rows requested by the caller.
     FIXME: Is there a GTK method that counts the number of rows
     in the list? If so, we don't need to bring visible_rows from
     the Java peer. */
  if (rows == visible_rows)
    dims[1] = natural_req.height;
  else
    dims[1] = natural_req.height / visible_rows * rows;

  (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);

  gdk_threads_leave ();
}