Source for gnu.java.awt.peer.qt.QtComponentPeer

   1: /* QtComponentPeer.java --
   2:    Copyright (C)  2005  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: package gnu.java.awt.peer.qt;
  39: 
  40: import java.awt.AWTEvent;
  41: import java.awt.AWTException;
  42: import java.awt.BufferCapabilities;
  43: import java.awt.Component;
  44: import java.awt.Container;
  45: import java.awt.Color;
  46: import java.awt.Cursor;
  47: import java.awt.Dimension;
  48: import java.awt.Font;
  49: import java.awt.FontMetrics;
  50: import java.awt.Image;
  51: import java.awt.Graphics;
  52: import java.awt.Graphics2D;
  53: import java.awt.GraphicsConfiguration;
  54: import java.awt.GraphicsDevice;
  55: import java.awt.KeyboardFocusManager;
  56: import java.awt.Point;
  57: import java.awt.Rectangle;
  58: import java.awt.Toolkit;
  59: import java.awt.Window;
  60: import java.awt.peer.ComponentPeer;
  61: import java.awt.peer.ContainerPeer;
  62: import java.awt.image.ColorModel;
  63: import java.awt.image.VolatileImage;
  64: import java.awt.image.ImageObserver;
  65: import java.awt.image.ImageProducer;
  66: import java.awt.event.ComponentEvent; // 100%
  67: import java.awt.event.FocusEvent; // 100%
  68: import java.awt.event.InputEvent; // (abstract)
  69: import java.awt.event.KeyEvent; // 2/3
  70: import java.awt.event.MouseEvent; // 70%? 
  71: import java.awt.event.PaintEvent; // Yup.
  72: import java.awt.event.WindowEvent; // 2/ 12
  73: import java.util.Timer;
  74: import java.util.TimerTask;
  75: 
  76: public class QtComponentPeer extends NativeWrapper implements ComponentPeer
  77: {
  78: 
  79:   /**
  80:    * Popup trigger button, may differ between platforms
  81:    */
  82:   protected static final int POPUP_TRIGGER = 3;
  83: 
  84:   /**
  85:    * The toolkit which manufactured this peer.
  86:    */
  87:   protected QtToolkit toolkit;
  88: 
  89:   /**
  90:    * The component which owns this peer.
  91:    */
  92:   Component owner;
  93: 
  94:   /**
  95:    * Classpath updates our eventMask.
  96:    */
  97:   private long eventMask;
  98: 
  99:   /**
 100:    * if the thing has mouse motion listeners or not.
 101:    */
 102:   private boolean hasMotionListeners;
 103: 
 104:   /**
 105:    * The component's double buffer for off-screen drawing.
 106:    */
 107:   protected QtImage backBuffer;
 108: 
 109:   protected long qtApp;
 110: 
 111:   private boolean settingUp;
 112: 
 113:   private boolean ignoreResize = false;
 114: 
 115:   QtComponentPeer( QtToolkit kit, Component owner )
 116:   {
 117:     this.owner = owner;
 118:     this.toolkit = kit;
 119:     qtApp = QtToolkit.guiThread.QApplicationPointer;
 120:     nativeObject = 0;
 121:     synchronized(this) 
 122:       {
 123:     callInit(); // Calls the init method FROM THE MAIN THREAD.
 124:     try
 125:       {    
 126:         wait(); // Wait for the thing to be created.
 127:       }
 128:     catch(InterruptedException e)
 129:       {
 130:       }
 131:       }
 132:     setup();
 133:     hasMotionListeners = false;
 134:   }
 135: 
 136:   protected native void callInit();
 137: 
 138:   /**
 139:    * Init does the creation of native widgets, it is therefore
 140:    * called from the main thread. (the constructor waits for this to happen.)
 141:    */
 142:   protected void init()
 143:   {
 144:   }
 145: 
 146:   protected void setup()
 147:   {
 148:     settingUp = true;
 149:     if (owner != null)
 150:       {
 151:       if (owner instanceof javax.swing.JComponent)
 152:         setBackground(owner.getBackground());
 153:       else
 154:       owner.setBackground(getNativeBackground());
 155:     
 156:     if (owner.getForeground() != null)
 157:       setForeground(owner.getForeground());
 158:     else
 159:       setForeground( Color.black );
 160: 
 161:     if (owner.getCursor() != null)
 162:       if (owner.getCursor().getType() != Cursor.DEFAULT_CURSOR)
 163:         setCursor(owner.getCursor());
 164:     
 165:     if (owner.getFont() != null)
 166:       setFont(owner.getFont());
 167: 
 168:     setEnabled( owner.isEnabled() );
 169: 
 170:     backBuffer = null;
 171:     updateBounds();
 172: 
 173:     setVisible( owner.isVisible() );
 174:     QtToolkit.repaintThread.queueComponent(this);
 175:       }
 176:     settingUp = false;
 177:   }
 178: 
 179:   native void QtUpdate();
 180:   native void QtUpdateArea( int x, int y, int w, int h );
 181:   private synchronized native void disposeNative();
 182:   private native void setGround( int r, int g, int b, boolean isForeground );
 183:   private native void setBoundsNative( int x, int y, int width, int height );
 184:   private native void setCursor( int ctype );
 185:   private native Color getNativeBackground();
 186:   private native void setFontNative( QtFontPeer fp );
 187:   private native int whichScreen();
 188:   private native void reparentNative( QtContainerPeer parent );
 189:   private native void getLocationOnScreenNative( Point p );
 190: 
 191:   private boolean drawableComponent()
 192:   {
 193:     return ((this instanceof QtContainerPeer && 
 194:          !(this instanceof QtScrollPanePeer)) || 
 195:         (this instanceof QtCanvasPeer));
 196:   }
 197: 
 198:   void updateBounds()
 199:   {
 200:     Rectangle r = owner.getBounds();
 201:     setBounds( r.x, r.y, r.width, r.height );
 202:   }
 203: 
 204:   synchronized void updateBackBuffer(int width, int height)
 205:   {
 206:     if(width <= 0 || height <= 0)
 207:       return;
 208:     
 209:     if( !drawableComponent() && backBuffer == null)
 210:       return;
 211: 
 212:     if( backBuffer != null )
 213:       {
 214:     if( width < backBuffer.width && height < backBuffer.height )
 215:       return;
 216:     backBuffer.dispose();
 217:       }
 218:     backBuffer = new QtImage(width, height);
 219:   }
 220:     
 221: 
 222:   // ************ Event methods *********************
 223: 
 224:   /**
 225:    * Window closing event
 226:    */
 227:   protected void closeEvent()
 228:   {
 229:     if (owner instanceof Window)
 230:       {
 231:     WindowEvent e = new WindowEvent((Window)owner, 
 232:                     WindowEvent.WINDOW_CLOSING);
 233:     QtToolkit.eventQueue.postEvent(e);
 234:       }
 235:   }
 236: 
 237:   protected void enterEvent(int modifiers, int x, int y, int dummy)
 238:   {
 239:     MouseEvent e = new MouseEvent(owner, 
 240:                   MouseEvent.MOUSE_ENTERED,
 241:                   System.currentTimeMillis(),
 242:                   (modifiers & 0x2FF), x, y, 0, false);
 243:     QtToolkit.eventQueue.postEvent(e);
 244:   }
 245: 
 246:   protected void focusInEvent()
 247:   {
 248:     FocusEvent e = new FocusEvent(owner, FocusEvent.FOCUS_GAINED);
 249:     QtToolkit.eventQueue.postEvent(e);
 250:    }
 251: 
 252:   protected void focusOutEvent()
 253:   {
 254:     FocusEvent e = new FocusEvent(owner, FocusEvent.FOCUS_LOST);
 255:     QtToolkit.eventQueue.postEvent(e);
 256:   }
 257: 
 258:   protected void keyPressEvent(int modifiers, int code, int unicode, int dummy)
 259:   {
 260:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
 261:     KeyEvent e = new KeyEvent(owner, 
 262:                   KeyEvent.KEY_PRESSED,
 263:                   System.currentTimeMillis(),
 264:                   modifiers, code, (char)(unicode & 0xFFFF),
 265:                   KeyEvent.KEY_LOCATION_UNKNOWN);
 266:     if (!manager.dispatchEvent (e))
 267:       QtToolkit.eventQueue.postEvent(e);
 268:   }
 269: 
 270:   protected void keyReleaseEvent(int modifiers, int code, int unicode, int dummy)
 271:   {
 272:     KeyEvent e = new KeyEvent(owner, 
 273:                   KeyEvent.KEY_RELEASED,
 274:                   System.currentTimeMillis(),
 275:                   modifiers, code, (char)(unicode & 0xFFFF),
 276:                   KeyEvent.KEY_LOCATION_UNKNOWN);
 277:     QtToolkit.eventQueue.postEvent(e);
 278:   }
 279: 
 280:   protected void leaveEvent(int modifiers, int x, int y, int dummy)
 281:   {
 282:     MouseEvent e = new MouseEvent(owner, 
 283:                   MouseEvent.MOUSE_EXITED,
 284:                   System.currentTimeMillis(),
 285:                   (modifiers & 0x2FF), x, y, 0, false);
 286:     QtToolkit.eventQueue.postEvent(e);
 287:   }
 288: 
 289:   // FIXME: Coalesce press-release events into clicks.
 290:   protected void mouseDoubleClickEvent( int modifiers, int x, int y, int clickCount)
 291:   {
 292:     if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 )
 293:       return;
 294:     int button = 0;
 295:     if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == 
 296:        InputEvent.BUTTON1_DOWN_MASK) button = 1;
 297:     if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == 
 298:        InputEvent.BUTTON2_DOWN_MASK) button = 2;
 299:     if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == 
 300:        InputEvent.BUTTON3_DOWN_MASK) button = 3;
 301:     MouseEvent e = new MouseEvent(owner, 
 302:                   MouseEvent.MOUSE_CLICKED,
 303:                   System.currentTimeMillis(),
 304:                   (modifiers & 0x2FF), x, y, clickCount, 
 305:                   false, button);
 306:     QtToolkit.eventQueue.postEvent(e);
 307:   }
 308: 
 309:   protected void mouseMoveEvent( int modifiers, int x, int y, int clickCount)
 310:   {
 311:     if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 )
 312:       return;
 313: 
 314:     int button = 0;
 315:     if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == 
 316:        InputEvent.BUTTON1_DOWN_MASK) button = 1;
 317:     if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == 
 318:        InputEvent.BUTTON2_DOWN_MASK) button = 2;
 319:     if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == 
 320:        InputEvent.BUTTON3_DOWN_MASK) button = 3;
 321: 
 322:     int type = (button != 0) ? 
 323:       MouseEvent.MOUSE_DRAGGED :MouseEvent.MOUSE_MOVED;
 324:     
 325:     MouseEvent e = new MouseEvent(owner, 
 326:                   type,
 327:                   System.currentTimeMillis(),
 328:                   (modifiers & 0x2FF), x, y, clickCount, 
 329:                   false, button);
 330:     QtToolkit.eventQueue.postEvent(e);
 331:   }
 332: 
 333:   protected void mousePressEvent( int modifiers, int x, int y, int clickCount)
 334:   {
 335:     if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 )
 336:       return;
 337:     int button = 0;
 338:     if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == 
 339:        InputEvent.BUTTON1_DOWN_MASK) button = 1;
 340:     if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == 
 341:        InputEvent.BUTTON2_DOWN_MASK) button = 2;
 342:     if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == 
 343:        InputEvent.BUTTON3_DOWN_MASK) button = 3;
 344:     MouseEvent e = new MouseEvent(owner, 
 345:                   MouseEvent.MOUSE_PRESSED,
 346:                   System.currentTimeMillis(),
 347:                   (modifiers & 0x2FF), x, y, clickCount, 
 348:                   ( button == POPUP_TRIGGER ), 
 349:                    button);
 350:     QtToolkit.eventQueue.postEvent(e);
 351:   }
 352: 
 353:   protected void mouseReleaseEvent( int modifiers, int x, int y, int clickCount)
 354:   {
 355:     if( (eventMask & AWTEvent.MOUSE_EVENT_MASK) == 0 )
 356:       return;
 357:     int button = 0;
 358:     if((modifiers & InputEvent.BUTTON1_DOWN_MASK) == 
 359:        InputEvent.BUTTON1_DOWN_MASK) button = 1;
 360:     if((modifiers & InputEvent.BUTTON2_DOWN_MASK) == 
 361:        InputEvent.BUTTON2_DOWN_MASK) button = 2;
 362:     if((modifiers & InputEvent.BUTTON3_DOWN_MASK) == 
 363:        InputEvent.BUTTON3_DOWN_MASK) button = 3;
 364: 
 365:     MouseEvent e = new MouseEvent(owner, 
 366:                   MouseEvent.MOUSE_RELEASED,
 367:                   System.currentTimeMillis(),
 368:                   (modifiers & 0x2FF), x, y, clickCount, 
 369:                   false, button);
 370:     QtToolkit.eventQueue.postEvent(e);
 371:   }
 372: 
 373:   protected void moveEvent(int x, int y, int oldx, int oldy)
 374:   {
 375:     if( !ignoreResize )
 376:       {
 377:     // Since Component.setLocation calls back to setBounds, 
 378:     // we need to ignore that.
 379:     ignoreResize = true; 
 380:     owner.setLocation( x, y );
 381:     ignoreResize = false;
 382:       }
 383:   }
 384: 
 385:   protected void resizeEvent(int oldWidth, int oldHeight, 
 386:                  int width, int height)
 387:   {
 388:     if(!(owner instanceof Window))
 389:       return;
 390:     updateBackBuffer(width, height);
 391:     ignoreResize = true;
 392:     owner.setSize(width, height);
 393:     ignoreResize = false;
 394:     ComponentEvent e = new ComponentEvent(owner, 
 395:                         ComponentEvent.COMPONENT_RESIZED);
 396:     QtToolkit.eventQueue.postEvent(e);
 397:     QtToolkit.repaintThread.queueComponent(this);
 398:   }
 399: 
 400:   protected void showEvent()
 401:   {
 402:     if (owner instanceof Window)
 403:       {
 404:     WindowEvent e = new WindowEvent((Window)owner, 
 405:                     WindowEvent.WINDOW_OPENED);
 406:     QtToolkit.eventQueue.postEvent(e);
 407:       }
 408:     else 
 409:       {
 410:     ComponentEvent e = new ComponentEvent(owner, 
 411:                           ComponentEvent.COMPONENT_SHOWN);
 412:     QtToolkit.eventQueue.postEvent(e);
 413:       }
 414:   }
 415: 
 416:   protected void hideEvent()
 417:   {
 418:     ComponentEvent e = new ComponentEvent(owner, 
 419:                       ComponentEvent.COMPONENT_HIDDEN);
 420:     QtToolkit.eventQueue.postEvent(e);
 421:   }
 422: 
 423:   // ************ Public methods *********************
 424: 
 425:   /** Classpath-specific method */
 426:   public void setEventMask(long x)
 427:   {
 428:     eventMask = x;
 429:   }
 430: 
 431: 
 432:   public boolean canDetermineObscurity()
 433:   {
 434:     return true;
 435:   } 
 436: 
 437:   public int checkImage(Image img,
 438:             int w,
 439:             int h,
 440:             ImageObserver o)
 441:   {
 442:     return toolkit.checkImage(img, w, h, o);
 443:   }
 444: 
 445:   public void createBuffers(int numBuffers, BufferCapabilities caps)
 446:     throws AWTException 
 447:   {
 448:     // FIXME
 449:   }
 450: 
 451:   public Image createImage(ImageProducer producer)
 452:   {
 453:     return toolkit.createImage(producer);
 454:   }
 455: 
 456:   public Image createImage(int width, int height)
 457:   {
 458:     return new QtImage(width, height);
 459:   }
 460: 
 461:   public void coalescePaintEvent(PaintEvent e)
 462:   {
 463:     // FIXME
 464:   }
 465: 
 466:   public VolatileImage createVolatileImage(int w, int h)
 467:   {
 468:     return new QtVolatileImage( w, h );
 469:   }
 470: 
 471:   public void destroyBuffers()
 472:   {
 473:     // FIXME
 474:   }
 475: 
 476:   public void disable()
 477:   {
 478:     setEnabled(false);
 479:   }
 480: 
 481:   public void dispose()
 482:   {
 483:     disposeNative();
 484:     if( backBuffer != null )
 485:       backBuffer.dispose();
 486:   }
 487: 
 488:   public void enable()
 489:   {
 490:     setEnabled(true);
 491:   }
 492: 
 493:   public void finalize()
 494:   {
 495:     dispose();
 496:   }
 497: 
 498:   public void flip(BufferCapabilities.FlipContents contents)
 499:   {
 500:   }
 501: 
 502:   public Image getBackBuffer()
 503:   {
 504:     return backBuffer;
 505:   }
 506: 
 507:   public ColorModel getColorModel()
 508:   {
 509:     return toolkit.getColorModel();
 510:   }
 511: 
 512:   public FontMetrics getFontMetrics(Font font)
 513:   {
 514:     return new QtFontMetrics( font, getGraphics() );
 515:   }
 516: 
 517:   public Graphics getGraphics()
 518:   {
 519:     if( backBuffer == null )
 520:       { 
 521:     Rectangle r = owner.getBounds();
 522:     backBuffer = new QtImage( r.width, r.height );
 523:       }
 524:     return backBuffer.getDirectGraphics( this );
 525:   }
 526: 
 527:   public GraphicsConfiguration getGraphicsConfiguration()
 528:   {
 529:     int id = whichScreen(); // get the ID of the screen the widget is on.
 530:     GraphicsDevice[] devs = QtToolkit.graphicsEnv.getScreenDevices();
 531:     return devs[id].getDefaultConfiguration();
 532:   }
 533: 
 534:   public Point getLocationOnScreen()
 535:   {
 536:     Point p = new Point();
 537:     synchronized( p ) 
 538:       {
 539:     getLocationOnScreenNative( p );
 540:     try
 541:       {    
 542:         p.wait(); // Wait for the thing to be created.
 543:       }
 544:     catch(InterruptedException e)
 545:       {
 546:       }
 547:       }
 548:     return p;
 549:   }
 550: 
 551:   private native void getSizeNative(Dimension d, boolean preferred);
 552: 
 553:   private Dimension getSize(boolean preferred)
 554:   {
 555:     Dimension d = new Dimension();
 556:     synchronized( d ) 
 557:       {
 558:     getSizeNative(d, preferred);
 559:     try
 560:       {    
 561:         d.wait(); // Wait for the thing to be created.
 562:       }
 563:     catch(InterruptedException e)
 564:       {
 565:       }
 566:       }
 567:     return d;
 568:   }
 569: 
 570:   public Dimension getMinimumSize()
 571:   {
 572:     return getSize( false );
 573:   }
 574:  
 575:   public Dimension getPreferredSize()
 576:   {
 577:     return getSize( true );
 578:   }
 579: 
 580:   public Toolkit getToolkit()
 581:   {
 582:     return toolkit;
 583:   }
 584: 
 585:   public native boolean handlesWheelScrolling();
 586:    
 587:   public void hide()
 588:   {
 589:     setVisible(false);
 590:   }
 591: 
 592:   public native boolean isFocusable();
 593: 
 594:   public boolean isFocusTraversable()
 595:   {
 596:     // FIXME
 597:     return false;
 598:   }
 599: 
 600:   public native boolean isObscured();
 601: 
 602:   public Dimension minimumSize()
 603:   {
 604:     return getMinimumSize();
 605:   }
 606: 
 607:   public Dimension preferredSize()
 608:   {
 609:     return getPreferredSize();
 610:   }
 611: 
 612:   public native void requestFocus();
 613: 
 614:   public boolean requestFocus (Component source, boolean bool1, 
 615:                    boolean bool2, long x)
 616:   {
 617:     // FIXME
 618:     return true;
 619:   }
 620: 
 621:   public void reshape(int x,
 622:               int y,
 623:               int width,
 624:               int height)
 625:   {
 626:     setBounds( x, y, width, height );
 627:   }
 628: 
 629:   public void setBackground(Color c)
 630:   {
 631:     if(c == null && !settingUp)
 632:       return;
 633:     setGround(c.getRed(), c.getGreen(), c.getBlue(), false);
 634:   }
 635: 
 636:   public void setBounds(int x, int y, int width, int height)
 637:   {
 638:     if( ignoreResize )
 639:       return;
 640:     updateBackBuffer(width, height);
 641:     QtToolkit.repaintThread.queueComponent(this);
 642:     setBoundsNative(x, y, width, height);
 643:   }
 644: 
 645:   public void setCursor(Cursor cursor)
 646:   {
 647:     if (cursor != null)
 648:       setCursor(cursor.getType());
 649:   }
 650: 
 651:   public native void setEnabled(boolean b);
 652: 
 653:   public void setFont(Font f)
 654:   {
 655:     if( f == null || f.getPeer() == null)
 656:       throw new IllegalArgumentException("Null font.");
 657:     setFontNative( (QtFontPeer)f.getPeer() );
 658:   }
 659: 
 660:   public void setForeground(Color c)
 661:   {
 662:     if(c == null && !settingUp)
 663:       return;
 664:     setGround(c.getRed(), c.getGreen(), c.getBlue(), true);
 665:   }
 666:   
 667:   public native void setVisible(boolean b);
 668: 
 669:   public void show()
 670:   {
 671:     setVisible(true);
 672:   }
 673: 
 674:   public void handleEvent (AWTEvent e)
 675:   {
 676:     int eventID = e.getID();
 677:     Rectangle r;
 678: 
 679:     switch (eventID)
 680:       {
 681:       case ComponentEvent.COMPONENT_SHOWN:
 682:     QtToolkit.repaintThread.queueComponent(this);
 683:         break;
 684:       case PaintEvent.PAINT:
 685:       case PaintEvent.UPDATE:    
 686:     r = ((PaintEvent)e).getUpdateRect();
 687:     QtToolkit.repaintThread.queueComponent(this, r.x, r.y,
 688:                            r.width, r.height);
 689:         break;
 690:       case KeyEvent.KEY_PRESSED:
 691:     break;
 692:       case KeyEvent.KEY_RELEASED:
 693:     break;
 694:       }
 695:   }
 696: 
 697:   /**
 698:    * paint() is called back from the native side in response to a native
 699:    * repaint event.
 700:    */  
 701:   public void paint(Graphics g)
 702:   {
 703:     Rectangle r = g.getClipBounds();
 704: 
 705:     if (backBuffer != null)
 706:       backBuffer.drawPixelsScaledFlipped ((QtGraphics) g, 
 707:                       0, 0, 0, /* bg colors */
 708:                       false, false, /* no flipping */
 709:                       r.x, r.y, r.width, r.height,
 710:                       r.x, r.y, r.width, r.height,
 711:                       false ); /* no compositing */
 712:   }
 713: 
 714:   public void paintBackBuffer() throws InterruptedException
 715:   {
 716:     if( backBuffer != null )
 717:       {
 718:     backBuffer.clear();
 719:     Graphics2D bbg = (Graphics2D)backBuffer.getGraphics();
 720:     owner.paint(bbg); 
 721:     bbg.dispose();
 722:       }
 723:   }
 724: 
 725:   public void paintBackBuffer(int x, int y, int w, int h) 
 726:     throws InterruptedException
 727:   {
 728:     if( backBuffer != null )
 729:       {
 730:     Graphics2D bbg = (Graphics2D)backBuffer.getGraphics();
 731:     bbg.setBackground( getNativeBackground() );
 732:     bbg.clearRect(x, y, w, h);
 733:     bbg.setClip(x, y, w, h);
 734:     owner.paint(bbg); 
 735:     bbg.dispose();
 736:       }
 737:   }
 738: 
 739:   public boolean prepareImage(Image img,
 740:                   int w,
 741:                   int h,
 742:                   ImageObserver o)
 743:   {
 744:     return toolkit.prepareImage(img, w, h, o);
 745:   }
 746:   
 747:   public void print(Graphics g)
 748:   {
 749:     // FIXME
 750:   }
 751: 
 752:   /**
 753:    * Schedules a timed repaint.
 754:    */
 755:   public void repaint(long tm,
 756:               int x,
 757:               int y,
 758:               int w,
 759:               int h)
 760:   {
 761:     if( tm <= 0 )
 762:       {
 763:     QtToolkit.repaintThread.queueComponent(this, x, y, w, h);
 764:     return;
 765:       }      
 766:     Timer t = new Timer();
 767:     t.schedule(new RepaintTimerTask(this, x, y, w, h), tm);
 768:   }
 769: 
 770:   /**
 771:    * Update the cursor (note that setCursor is usually not called)
 772:    */
 773:   public void updateCursorImmediately()
 774:   {
 775:     if (owner.getCursor() != null)
 776:       setCursor(owner.getCursor().getType());
 777:   }
 778: 
 779:   /**
 780:    * Timed repainter
 781:    */
 782:   private class RepaintTimerTask extends TimerTask 
 783:   {    
 784:     private int x, y, w, h;
 785:     private QtComponentPeer peer;
 786:     RepaintTimerTask(QtComponentPeer peer, int x, int y, int w, int h)
 787:     { 
 788:       this.x=x;
 789:       this.y=y;
 790:       this.w=w;
 791:       this.h=h; 
 792:       this.peer=peer;
 793:     }
 794:     public void run()
 795:     { 
 796:       QtToolkit.repaintThread.queueComponent(peer, x, y, w, h);
 797:     }
 798:   }
 799: 
 800:   public native Rectangle getBounds();
 801: 
 802:   public void reparent(ContainerPeer parent)
 803:   {
 804:     if(!(parent instanceof QtContainerPeer))
 805:       throw new IllegalArgumentException("Illegal peer.");
 806:     reparentNative((QtContainerPeer)parent);
 807:   }
 808: 
 809:   public void setBounds(int x, int y, int width, int height, int z)
 810:   {
 811:     // TODO Auto-generated method stub
 812:     
 813:   }
 814: 
 815:   public boolean isReparentSupported()
 816:   {
 817:     return true;
 818:   }
 819: 
 820:   // What does this do, anyway?
 821:   public void layout()
 822:   {
 823:     // TODO Auto-generated method stub
 824:   }
 825: }