mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			438 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			438 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* GtkWindowPeer.java -- Implements WindowPeer with GTK
 | |
|    Copyright (C) 1998, 1999, 2002, 2005, 2006  Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | |
| 02110-1301 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| 
 | |
| package gnu.java.awt.peer.gtk;
 | |
| 
 | |
| import gnu.java.awt.ComponentReshapeEvent;
 | |
| 
 | |
| import java.awt.Component;
 | |
| import java.awt.Font;
 | |
| import java.awt.Frame;
 | |
| import java.awt.Graphics;
 | |
| import java.awt.KeyboardFocusManager;
 | |
| import java.awt.Point;
 | |
| import java.awt.Rectangle;
 | |
| import java.awt.Window;
 | |
| import java.awt.event.ComponentEvent;
 | |
| import java.awt.event.FocusEvent;
 | |
| import java.awt.event.PaintEvent;
 | |
| import java.awt.event.WindowEvent;
 | |
| import java.awt.peer.WindowPeer;
 | |
| 
 | |
| public class GtkWindowPeer extends GtkContainerPeer
 | |
|   implements WindowPeer
 | |
| {
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_NORMAL = 0;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_DIALOG = 1;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_MENU = 2;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_TOOLBAR = 3;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_SPLASHSCREEN = 4;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_UTILITY = 5;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_DOCK = 6;
 | |
|   protected static final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7;
 | |
| 
 | |
|   protected int windowState = Frame.NORMAL;
 | |
| 
 | |
|   // Cached awt window component location, width and height.
 | |
|   private int x, y, width, height;
 | |
| 
 | |
|   native void gtkWindowSetTitle (String title);
 | |
|   native void gtkWindowSetResizable (boolean resizable);
 | |
|   native void gtkWindowSetModal (boolean modal);
 | |
|   native void gtkWindowSetAlwaysOnTop ( boolean alwaysOnTop );
 | |
|   native boolean gtkWindowHasFocus();
 | |
|   native void realize ();
 | |
| 
 | |
|   public void dispose()
 | |
|   {
 | |
|     super.dispose();
 | |
|     GtkMainThread.destroyWindow();
 | |
|   }
 | |
| 
 | |
|   /** Returns the cached width of the AWT window component. */
 | |
|   int getX ()
 | |
|   {
 | |
|     return x;
 | |
|   }
 | |
| 
 | |
|   /** Returns the cached width of the AWT window component. */
 | |
|   int getY ()
 | |
|   {
 | |
|     return y;
 | |
|   }
 | |
| 
 | |
|   /** Returns the cached width of the AWT window component. */
 | |
|   int getWidth ()
 | |
|   {
 | |
|     return width;
 | |
|   }
 | |
| 
 | |
|   /** Returns the cached height of the AWT window component. */
 | |
|   int getHeight ()
 | |
|   {
 | |
|     return height;
 | |
|   }
 | |
| 
 | |
|   native void create (int type, boolean decorated, GtkWindowPeer parent);
 | |
| 
 | |
|   void create (int type, boolean decorated)
 | |
|   {
 | |
|     Window window = (Window) awtComponent;
 | |
|     GtkWindowPeer parent_peer = null;
 | |
|     Component parent = awtComponent.getParent();
 | |
|     x = awtComponent.getX();
 | |
|     y = awtComponent.getY();
 | |
|     height = awtComponent.getHeight();
 | |
|     width = awtComponent.getWidth();
 | |
| 
 | |
|     if (!window.isFocusableWindow())
 | |
|       type = GDK_WINDOW_TYPE_HINT_MENU;
 | |
| 
 | |
|     if (parent != null)
 | |
|       parent_peer = (GtkWindowPeer) awtComponent.getParent().getPeer();
 | |
| 
 | |
|     create (type, decorated, parent_peer);
 | |
|   }
 | |
| 
 | |
|   void create ()
 | |
|   {
 | |
|     // Create a normal undecorated window.
 | |
|     create (GDK_WINDOW_TYPE_HINT_NORMAL, false);
 | |
|   }
 | |
| 
 | |
|   void setParent ()
 | |
|   {
 | |
|     setVisible (awtComponent.isVisible ());
 | |
|     setEnabled (awtComponent.isEnabled ());
 | |
|   }
 | |
| 
 | |
|   void setVisibleAndEnabled ()
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   public native void setVisibleNative (boolean b);
 | |
|   public native void setVisibleNativeUnlocked (boolean b);
 | |
| 
 | |
|   native void connectSignals ();
 | |
| 
 | |
|   public GtkWindowPeer (Window window)
 | |
|   {
 | |
|     super (window);
 | |
|     // Set reasonable font for the window.
 | |
|     window.setFont(new Font("Dialog", Font.PLAIN, 12));
 | |
|   }
 | |
| 
 | |
|   public native void toBack();
 | |
|   public native void toFront();
 | |
| 
 | |
|   native void nativeSetBounds (int x, int y, int width, int height);
 | |
|   native void nativeSetBoundsUnlocked (int x, int y, int width, int height);
 | |
|   native void nativeSetLocation (int x, int y);
 | |
|   native void nativeSetLocationUnlocked (int x, int y);
 | |
| 
 | |
|   // Called from show.
 | |
|   protected void setLocation (int x, int y)
 | |
|   {
 | |
|     nativeSetLocation (x, y);
 | |
|   }
 | |
| 
 | |
|   public void setBounds (int x, int y, int width, int height)
 | |
|   {
 | |
|     if (x != getX()     || y != getY() || width != getWidth()
 | |
|         || height != getHeight())
 | |
|       {
 | |
|         this.x = x;
 | |
|         this.y = y;
 | |
|         this.width = width;
 | |
|         this.height = height;
 | |
| 
 | |
|         nativeSetBounds (x, y,
 | |
|                          width - insets.left - insets.right,
 | |
|                          height - insets.top - insets.bottom);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public void setTitle (String title)
 | |
|   {
 | |
|     gtkWindowSetTitle (title);
 | |
|   }
 | |
| 
 | |
|   // Called from setResizable
 | |
|   protected native void setSize (int width, int height);
 | |
| 
 | |
|   /**
 | |
|    * Needed by both GtkFramePeer and GtkDialogPeer subclasses, so
 | |
|    * implemented here. But never actually called on a GtkWindowPeer
 | |
|    * itself.
 | |
|    */
 | |
|   public void setResizable (boolean resizable)
 | |
|   {
 | |
|     // Call setSize; otherwise when resizable is changed from true to
 | |
|     // false the window will shrink to the dimensions it had before it
 | |
|     // was resizable.
 | |
|     x = awtComponent.getX();
 | |
|     y = awtComponent.getY();
 | |
|     width = awtComponent.getWidth();
 | |
|     height = awtComponent.getHeight();
 | |
|     setSize (width - insets.left - insets.right,
 | |
|              height - insets.top - insets.bottom);
 | |
|     gtkWindowSetResizable (resizable);
 | |
|   }
 | |
| 
 | |
|   protected void postInsetsChangedEvent (int top, int left,
 | |
|                                          int bottom, int right)
 | |
|   {
 | |
|     insets.top = top;
 | |
|     insets.left = left;
 | |
|     insets.bottom = bottom;
 | |
|     insets.right = right;
 | |
|   }
 | |
| 
 | |
|   // called back by native side: window_configure_cb
 | |
|   // only called from GTK thread
 | |
|   protected void postConfigureEvent (int x, int y, int width, int height)
 | |
|   {
 | |
|     int frame_x = x - insets.left;
 | |
|     int frame_y = y - insets.top;
 | |
|     int frame_width = width + insets.left + insets.right;
 | |
|     int frame_height = height + insets.top + insets.bottom;
 | |
| 
 | |
|     // Update the component's knowledge about the size.
 | |
|     // Important: Please look at the big comment in ComponentReshapeEvent
 | |
|     // to learn why we did it this way. If you change this code, make
 | |
|     // sure that the peer->AWT bounds update still works.
 | |
|     // (for instance: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29448 )
 | |
| 
 | |
|     // We do this befor we post the ComponentEvent, because (in Window)
 | |
|     // we invalidate() / revalidate() when a ComponentEvent is seen,
 | |
|     // and the AWT must already know about the new size then.
 | |
|     if (frame_x != this.x || frame_y != this.y || frame_width != this.width
 | |
|         || frame_height != this.height)
 | |
|       {
 | |
|         ComponentReshapeEvent ev = new ComponentReshapeEvent(awtComponent,
 | |
|                                                              frame_x,
 | |
|                                                              frame_y,
 | |
|                                                              frame_width,
 | |
|                                                              frame_height);
 | |
|         awtComponent.dispatchEvent(ev);
 | |
|       }
 | |
| 
 | |
|     if (frame_width != getWidth() || frame_height != getHeight())
 | |
|       {
 | |
|         this.width = frame_width;
 | |
|         this.height = frame_height;
 | |
|         q().postEvent(new ComponentEvent(awtComponent,
 | |
|                                          ComponentEvent.COMPONENT_RESIZED));
 | |
|       }
 | |
| 
 | |
|     if (frame_x != getX() || frame_y != getY())
 | |
|       {
 | |
|         this.x = frame_x;
 | |
|         this.y = frame_y;
 | |
|         q().postEvent(new ComponentEvent(awtComponent,
 | |
|                                          ComponentEvent.COMPONENT_MOVED));
 | |
|       }
 | |
| 
 | |
|   }
 | |
| 
 | |
|   public void show ()
 | |
|   {
 | |
|     x = awtComponent.getX();
 | |
|     y = awtComponent.getY();
 | |
|     width = awtComponent.getWidth();
 | |
|     height = awtComponent.getHeight();
 | |
|     setLocation(x, y);
 | |
|     setVisible (true);
 | |
|   }
 | |
| 
 | |
|   void postWindowEvent (int id, Window opposite, int newState)
 | |
|   {
 | |
|     if (id == WindowEvent.WINDOW_STATE_CHANGED)
 | |
|       {
 | |
|         if (windowState != newState)
 | |
|           {
 | |
|             // Post old styleWindowEvent with WINDOW_ICONIFIED or
 | |
|             // WINDOW_DEICONIFIED if appropriate.
 | |
|             if ((windowState & Frame.ICONIFIED) != 0
 | |
|                 && (newState & Frame.ICONIFIED) == 0)
 | |
|               q().postEvent(new WindowEvent((Window) awtComponent,
 | |
|                                             WindowEvent.WINDOW_DEICONIFIED,
 | |
|                                             opposite, 0, 0));
 | |
|             else if ((windowState & Frame.ICONIFIED) == 0
 | |
|                 && (newState & Frame.ICONIFIED) != 0)
 | |
|               q().postEvent(new WindowEvent((Window) awtComponent,
 | |
|                                             WindowEvent.WINDOW_ICONIFIED,
 | |
|                                             opposite, 0, 0));
 | |
|             // Post new-style WindowStateEvent.
 | |
|             q().postEvent (new WindowEvent ((Window) awtComponent, id,
 | |
|                                             opposite, windowState, newState));
 | |
|             windowState = newState;
 | |
|           }
 | |
|       }
 | |
|     else
 | |
|       q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Update the always-on-top status of the native window.
 | |
|    */
 | |
|   public void updateAlwaysOnTop()
 | |
|   {
 | |
|     gtkWindowSetAlwaysOnTop( ((Window)awtComponent).isAlwaysOnTop() );
 | |
|   }
 | |
| 
 | |
|   protected void postExposeEvent (int x, int y, int width, int height)
 | |
|   {
 | |
|     // Translate GTK co-ordinates, which do not include a window
 | |
|     // frame's insets, to AWT co-ordinates, which do include a window
 | |
|     // frame's insets.  GtkWindowPeer should always have all-zero
 | |
|     // insets but GtkFramePeer and GtkDialogPeer insets will be
 | |
|     // non-zero.
 | |
|     q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
 | |
|                                    new Rectangle (x + insets.left,
 | |
|                                                   y + insets.top,
 | |
|                                                   width, height)));
 | |
|   }
 | |
| 
 | |
|   public boolean requestWindowFocus()
 | |
|   {
 | |
|     // TODO Auto-generated method stub
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   public boolean requestFocus (Component request, boolean temporary,
 | |
|                                boolean allowWindowFocus, long time)
 | |
|   {
 | |
|     assert request == awtComponent || isLightweightDescendant(request);
 | |
|     boolean retval = false;
 | |
|     if (gtkWindowHasFocus())
 | |
|       {
 | |
|         KeyboardFocusManager kfm =
 | |
|           KeyboardFocusManager.getCurrentKeyboardFocusManager();
 | |
|         Component currentFocus = kfm.getFocusOwner();
 | |
|         if (currentFocus == request)
 | |
|           // Nothing to do in this trivial case.
 | |
|           retval = true;
 | |
|         else
 | |
|           {
 | |
|             // Requested component is a lightweight descendant of this one
 | |
|             // or the actual heavyweight.
 | |
|             // Since this (native) component is already focused, we simply
 | |
|             // change the actual focus and be done.
 | |
|             postFocusEvent(FocusEvent.FOCUS_GAINED, temporary);
 | |
|             retval = true;
 | |
|           }
 | |
|       }
 | |
|     else
 | |
|       {
 | |
|         if (allowWindowFocus)
 | |
|           {
 | |
|             retval = requestWindowFocus();
 | |
|           }
 | |
|       }
 | |
|     return retval;
 | |
|   }
 | |
| 
 | |
|   public Graphics getGraphics ()
 | |
|   {
 | |
|     Graphics g = super.getGraphics ();
 | |
|     // Translate AWT co-ordinates, which include a window frame's
 | |
|     // insets, to GTK co-ordinates, which do not include a window
 | |
|     // frame's insets.  GtkWindowPeer should always have all-zero
 | |
|     // insets but GtkFramePeer and GtkDialogPeer insets will be
 | |
|     // non-zero.
 | |
|     g.translate (-insets.left, -insets.top);
 | |
|     return g;
 | |
|   }
 | |
| 
 | |
|   protected void postMouseEvent(int id, long when, int mods, int x, int y,
 | |
|                                 int clickCount, boolean popupTrigger)
 | |
|   {
 | |
|     // Translate AWT co-ordinates, which include a window frame's
 | |
|     // insets, to GTK co-ordinates, which do not include a window
 | |
|     // frame's insets.  GtkWindowPeer should always have all-zero
 | |
|     // insets but GtkFramePeer and GtkDialogPeer insets will be
 | |
|     // non-zero.
 | |
|     super.postMouseEvent (id, when, mods,
 | |
|                           x + insets.left, y + insets.top,
 | |
|                           clickCount, popupTrigger);
 | |
|   }
 | |
| 
 | |
|   public Point getLocationOnScreen()
 | |
|   {
 | |
|     int point[] = new int[2];
 | |
|     if (Thread.currentThread() == GtkMainThread.mainThread)
 | |
|       gtkWindowGetLocationOnScreenUnlocked(point);
 | |
|     else
 | |
|       gtkWindowGetLocationOnScreen(point);
 | |
|     return new Point(point[0], point[1]);
 | |
|   }
 | |
| 
 | |
|   // We override this to keep it in sync with our internal
 | |
|   // representation.
 | |
|   public Rectangle getBounds()
 | |
|   {
 | |
|     return new Rectangle(x, y, width, height);
 | |
|   }
 | |
| 
 | |
|   public void updateIconImages()
 | |
|   {
 | |
|     // TODO: Implement properly.
 | |
|   }
 | |
| 
 | |
|   public void updateMinimumSize()
 | |
|   {
 | |
|     // TODO: Implement properly.
 | |
|   }
 | |
| 
 | |
|   public void setModalBlocked(java.awt.Dialog d, boolean b)
 | |
|   {
 | |
|     // TODO: Implement properly.
 | |
|   }
 | |
| 
 | |
|   public void updateFocusableWindowState()
 | |
|   {
 | |
|     // TODO: Implement properly.
 | |
|   }
 | |
| 
 | |
|   public void setAlwaysOnTop(boolean b)
 | |
|   {
 | |
|     // TODO: Implement properly.
 | |
|   }
 | |
| }
 |