OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [peer/] [gtk/] [GtkComponentPeer.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* GtkComponentPeer.java -- Implements ComponentPeer with GTK
2
   Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package gnu.java.awt.peer.gtk;
41
 
42
import java.awt.AWTEvent;
43
import java.awt.AWTException;
44
import java.awt.BufferCapabilities;
45
import java.awt.Color;
46
import java.awt.Component;
47
import java.awt.Container;
48
import java.awt.Cursor;
49
import java.awt.Dimension;
50
import java.awt.EventQueue;
51
import java.awt.Font;
52
import java.awt.FontMetrics;
53
import java.awt.Graphics;
54
import java.awt.GraphicsConfiguration;
55
import java.awt.GraphicsDevice;
56
import java.awt.GraphicsEnvironment;
57
import java.awt.Image;
58
import java.awt.Insets;
59
import java.awt.ItemSelectable;
60
import java.awt.KeyboardFocusManager;
61
import java.awt.Point;
62
import java.awt.Rectangle;
63
import java.awt.Toolkit;
64
import java.awt.Window;
65
import java.awt.event.FocusEvent;
66
import java.awt.event.ItemEvent;
67
import java.awt.event.KeyEvent;
68
import java.awt.event.MouseEvent;
69
import java.awt.event.MouseWheelEvent;
70
import java.awt.event.PaintEvent;
71
import java.awt.event.TextEvent;
72
import java.awt.image.ColorModel;
73
import java.awt.image.ImageObserver;
74
import java.awt.image.ImageProducer;
75
import java.awt.image.VolatileImage;
76
import java.awt.peer.ComponentPeer;
77
import java.awt.peer.ContainerPeer;
78
import java.awt.peer.LightweightPeer;
79
import java.util.Timer;
80
import java.util.TimerTask;
81
 
82
public class GtkComponentPeer extends GtkGenericPeer
83
  implements ComponentPeer
84
{
85
  VolatileImage backBuffer;
86
  BufferCapabilities caps;
87
 
88
  Component awtComponent;
89
 
90
  Insets insets;
91
 
92
  /**
93
   * The current repaint area. Use should be guarded by synchronizing on this.
94
   */
95
  private Rectangle currentPaintArea;
96
 
97
  /* this isEnabled differs from Component.isEnabled, in that it
98
     knows if a parent is disabled.  In that case Component.isEnabled
99
     may return true, but our isEnabled will always return false */
100
  native boolean isEnabled ();
101
  static native boolean modalHasGrab();
102
 
103
  native int[] gtkWidgetGetForeground ();
104
  native int[] gtkWidgetGetBackground ();
105
  native void gtkWidgetGetDimensions (int[] dim);
106
  native void gtkWidgetGetPreferredDimensions (int[] dim);
107
  native void gtkWindowGetLocationOnScreen (int[] point);
108
  native void gtkWindowGetLocationOnScreenUnlocked (int[] point);
109
  native void gtkWidgetGetLocationOnScreen (int[] point);
110
  native void gtkWidgetGetLocationOnScreenUnlocked (int[] point);
111
  native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y);
112
  native void gtkWidgetSetCursorUnlocked (int type, GtkImage image,
113
                                          int x, int y);
114
  native void gtkWidgetSetBackground (int red, int green, int blue);
115
  native void gtkWidgetSetForeground (int red, int green, int blue);
116
  native void gtkWidgetSetSensitive (boolean sensitive);
117
  native void gtkWidgetSetParent (ComponentPeer parent);
118
  native void gtkWidgetRequestFocus ();
119
  native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
120
                                         int keyCode, int keyLocation);
121
  native boolean gtkWidgetHasFocus();
122
  native boolean gtkWidgetCanFocus();
123
 
124
  native void realize();
125
  native void setNativeEventMask ();
126
 
127
  void create ()
128
  {
129
    throw new RuntimeException ();
130
  }
131
 
132
  native void connectSignals ();
133
 
134
  protected GtkComponentPeer (Component awtComponent)
135
  {
136
    super (awtComponent);
137
    this.awtComponent = awtComponent;
138
    insets = new Insets (0, 0, 0, 0);
139
 
140
    create ();
141
 
142
    connectSignals ();
143
 
144
    if (awtComponent.getForeground () != null)
145
      setForeground (awtComponent.getForeground ());
146
    if (awtComponent.getBackground () != null)
147
      setBackground (awtComponent.getBackground ());
148
    if (awtComponent.getFont() != null)
149
      setFont(awtComponent.getFont());
150
 
151
    Component parent = awtComponent.getParent ();
152
 
153
    setParentAndBounds ();
154
 
155
    setNativeEventMask ();
156
 
157
    // This peer is guaranteed to have an X window upon construction.
158
    // That is, native methods such as those in GdkGraphics can rely
159
    // on this component's widget->window field being non-null.
160
    realize ();
161
 
162
    if (awtComponent.isCursorSet())
163
      setCursor ();
164
  }
165
 
166
  void setParentAndBounds ()
167
  {
168
    setParent ();
169
 
170
    setComponentBounds ();
171
 
172
    setVisibleAndEnabled ();
173
  }
174
 
175
  void setParent ()
176
  {
177
    ComponentPeer p;
178
    Component component = awtComponent;
179
    do
180
      {
181
        component = component.getParent ();
182
        p = component.getPeer ();
183
      }
184
    while (p instanceof java.awt.peer.LightweightPeer);
185
 
186
    if (p != null)
187
      gtkWidgetSetParent (p);
188
  }
189
 
190
  /*
191
   * Set the bounds of this peer's AWT Component based on dimensions
192
   * returned by the native windowing system.  Most Components impose
193
   * their dimensions on the peers which is what the default
194
   * implementation does.  However some peers, like GtkFileDialogPeer,
195
   * need to pass their size back to the AWT Component.
196
   */
197
  void setComponentBounds ()
198
  {
199
    Rectangle bounds = awtComponent.getBounds ();
200
    setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
201
  }
202
 
203
  void setVisibleAndEnabled ()
204
  {
205
    setVisible (awtComponent.isVisible ());
206
    setEnabled (awtComponent.isEnabled ());
207
  }
208
 
209
  public int checkImage (Image image, int width, int height,
210
                         ImageObserver observer)
211
  {
212
    return getToolkit().checkImage(image, width, height, observer);
213
  }
214
 
215
  public Image createImage (ImageProducer producer)
216
  {
217
    return new GtkImage (producer);
218
  }
219
 
220
  public Image createImage (int width, int height)
221
  {
222
    return CairoSurface.getBufferedImage(width, height);
223
  }
224
 
225
  public void disable ()
226
  {
227
    setEnabled (false);
228
  }
229
 
230
  public void enable ()
231
  {
232
    setEnabled (true);
233
  }
234
 
235
  public ColorModel getColorModel ()
236
  {
237
    return ColorModel.getRGBdefault ();
238
  }
239
 
240
  public FontMetrics getFontMetrics (Font font)
241
  {
242
    return getToolkit().getFontMetrics(font);
243
  }
244
 
245
  // getGraphics may be overridden by derived classes but it should
246
  // never return null.
247
  public Graphics getGraphics ()
248
  {
249
    return ComponentGraphics.getComponentGraphics(this);
250
  }
251
 
252
  public Point getLocationOnScreen ()
253
  {
254
    int point[] = new int[2];
255
    if (Thread.currentThread() == GtkMainThread.mainThread)
256
        gtkWidgetGetLocationOnScreenUnlocked (point);
257
    else
258
        gtkWidgetGetLocationOnScreen (point);
259
    return new Point (point[0], point[1]);
260
  }
261
 
262
  public Dimension getMinimumSize ()
263
  {
264
    return minimumSize ();
265
  }
266
 
267
  public Dimension getPreferredSize ()
268
  {
269
    return preferredSize ();
270
  }
271
 
272
  public Toolkit getToolkit ()
273
  {
274
    return Toolkit.getDefaultToolkit();
275
  }
276
 
277
  public void handleEvent (AWTEvent event)
278
  {
279
    int id = event.getID();
280
    KeyEvent ke = null;
281
 
282
    switch (id)
283
      {
284
      case PaintEvent.PAINT:
285
        paintComponent((PaintEvent) event);
286
        break;
287
      case PaintEvent.UPDATE:
288
        updateComponent((PaintEvent) event);
289
        break;
290
      case KeyEvent.KEY_PRESSED:
291
        ke = (KeyEvent) event;
292
        gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
293
                                   ke.getKeyCode (), ke.getKeyLocation ());
294
        break;
295
      case KeyEvent.KEY_RELEASED:
296
        ke = (KeyEvent) event;
297
        gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
298
                                   ke.getKeyCode (), ke.getKeyLocation ());
299
        break;
300
      }
301
  }
302
 
303
  // This method and its overrides are the only methods in the peers
304
  // that should call awtComponent.paint.
305
  protected void paintComponent (PaintEvent event)
306
  {
307
    // Do not call Component.paint if the component is not showing or
308
    // if its bounds form a degenerate rectangle.
309
    if (!awtComponent.isShowing()
310
        || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
311
      return;
312
 
313
    // Creating and disposing a GdkGraphics every time paint is called
314
    // seems expensive.  However, the graphics state does not carry
315
    // over between calls to paint, and resetting the graphics object
316
    // may even be more costly than simply creating a new one.
317
 
318
    // Make sure that the paintArea includes the area from the event
319
    // in the case when an application sends PaintEvents directly.
320
    coalescePaintEvent(event);
321
    Rectangle paintArea;
322
    synchronized (this)
323
      {
324
        paintArea = currentPaintArea;
325
        currentPaintArea = null;
326
      }
327
 
328
    if (paintArea != null)
329
      {
330
        Graphics g = getGraphics();
331
        try
332
          {
333
            g.setClip(paintArea);
334
            awtComponent.paint(g);
335
          }
336
        finally
337
          {
338
            g.dispose();
339
          }
340
      }
341
  }
342
 
343
  // This method and its overrides are the only methods in the peers
344
  // that should call awtComponent.update.
345
  protected void updateComponent (PaintEvent event)
346
  {
347
    // Do not call Component.update if the component is not showing or
348
    // if its bounds form a degenerate rectangle.
349
    if (!awtComponent.isShowing()
350
        || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
351
      return;
352
 
353
    // Make sure that the paintArea includes the area from the event
354
    // in the case when an application sends PaintEvents directly.
355
    coalescePaintEvent(event);
356
    Rectangle paintArea;
357
    synchronized (this)
358
      {
359
        paintArea = currentPaintArea;
360
        currentPaintArea = null;
361
      }
362
 
363
    if (paintArea != null)
364
    {
365
      Graphics g = getGraphics();
366
      try
367
        {
368
          g.setClip(paintArea);
369
          awtComponent.update(g);
370
        }
371
      finally
372
        {
373
          g.dispose();
374
        }
375
    }
376
  }
377
 
378
  public boolean isFocusTraversable ()
379
  {
380
    return true;
381
  }
382
 
383
  public Dimension minimumSize ()
384
  {
385
    int dim[] = new int[2];
386
 
387
    gtkWidgetGetPreferredDimensions (dim);
388
 
389
    return new Dimension (dim[0], dim[1]);
390
  }
391
 
392
  public void paint (Graphics g)
393
  {
394
  }
395
 
396
  public Dimension preferredSize ()
397
  {
398
    int dim[] = new int[2];
399
 
400
    gtkWidgetGetPreferredDimensions (dim);
401
 
402
    return new Dimension (dim[0], dim[1]);
403
  }
404
 
405
  public boolean prepareImage (Image image, int width, int height,
406
                               ImageObserver observer)
407
  {
408
    return getToolkit().prepareImage(image, width, height, observer);
409
  }
410
 
411
  public void print (Graphics g)
412
  {
413
    g.drawImage( ComponentGraphics.grab( this ), 0, 0, null );
414
  }
415
 
416
  public void repaint (long tm, int x, int y, int width, int height)
417
  {
418
    if (width < 1 || height < 1)
419
      return;
420
 
421
    if (tm <= 0)
422
      q().postEvent(new PaintEvent(awtComponent, PaintEvent.UPDATE,
423
                                   new Rectangle(x, y, width, height)));
424
    else
425
      RepaintTimerTask.schedule(tm, x, y, width, height, awtComponent);
426
  }
427
 
428
  /**
429
   * Used for scheduling delayed paint updates on the event queue.
430
   */
431
  private static class RepaintTimerTask extends TimerTask
432
  {
433
    private static final Timer repaintTimer = new Timer(true);
434
 
435
    private int x, y, width, height;
436
    private Component awtComponent;
437
 
438
    RepaintTimerTask(Component c, int x, int y, int width, int height)
439
    {
440
      this.x = x;
441
      this.y = y;
442
      this.width = width;
443
      this.height = height;
444
      this.awtComponent = c;
445
    }
446
 
447
    public void run()
448
    {
449
      q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE,
450
                                     new Rectangle (x, y, width, height)));
451
    }
452
 
453
    static void schedule(long tm, int x, int y, int width, int height,
454
                         Component c)
455
    {
456
      repaintTimer.schedule(new RepaintTimerTask(c, x, y, width, height), tm);
457
    }
458
  }
459
 
460
  public void requestFocus ()
461
  {
462
    assert false: "Call new requestFocus() method instead";
463
  }
464
 
465
  public void reshape (int x, int y, int width, int height)
466
  {
467
    setBounds (x, y, width, height);
468
  }
469
 
470
  public void setBackground (Color c)
471
  {
472
    gtkWidgetSetBackground (c.getRed(), c.getGreen(), c.getBlue());
473
  }
474
 
475
  native void setNativeBounds (int x, int y, int width, int height);
476
 
477
  public void setBounds (int x, int y, int width, int height)
478
  {
479
    int new_x = x;
480
    int new_y = y;
481
 
482
    Component parent = awtComponent.getParent ();
483
 
484
    // Heavyweight components that are children of one or more
485
    // lightweight containers have to be handled specially.  Because
486
    // calls to GLightweightPeer.setBounds do nothing, GTK has no
487
    // knowledge of the lightweight containers' positions.  So we have
488
    // to add the offsets manually when placing a heavyweight
489
    // component within a lightweight container.  The lightweight
490
    // container may itself be in a lightweight container and so on,
491
    // so we need to continue adding offsets until we reach a
492
    // container whose position GTK knows -- that is, the first
493
    // non-lightweight.
494
    Insets i;
495
    while (parent.isLightweight())
496
      {
497
        i = ((Container) parent).getInsets();
498
 
499
        new_x += parent.getX() + i.left;
500
        new_y += parent.getY() + i.top;
501
 
502
        parent = parent.getParent();
503
      }
504
    // We only need to convert from Java to GTK coordinates if we're
505
    // placing a heavyweight component in a Window.
506
    if (parent instanceof Window)
507
      {
508
        GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer ();
509
        // important: we want the window peer's insets here, not the
510
        // window's, since user sub-classes of Window can override
511
        // getInset and we only want to correct for the frame borders,
512
        // not for any user-defined inset values
513
        Insets insets = peer.getInsets ();
514
 
515
        int menuBarHeight = 0;
516
        if (peer instanceof GtkFramePeer)
517
          menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight ();
518
 
519
        new_x -= insets.left;
520
        new_y -= insets.top;
521
        new_y += menuBarHeight;
522
      }
523
 
524
    setNativeBounds (new_x, new_y, width, height);
525
 
526
    // If the height or width were (or are now) smaller than zero
527
    // then we want to adjust the visibility.
528
    setVisible(awtComponent.isVisible());
529
  }
530
 
531
  void setCursor ()
532
  {
533
    setCursor (awtComponent.getCursor ());
534
  }
535
 
536
  public void setCursor (Cursor cursor)
537
  {
538
    int x, y;
539
    GtkImage image;
540
    int type = cursor.getType();
541
    if (cursor instanceof GtkCursor)
542
      {
543
        GtkCursor gtkCursor = (GtkCursor) cursor;
544
        image = gtkCursor.getGtkImage();
545
        Point hotspot = gtkCursor.getHotspot();
546
        x = hotspot.x;
547
        y = hotspot.y;
548
      }
549
    else
550
      {
551
        image = null;
552
        x = 0;
553
        y = 0;
554
      }
555
 
556
    if (Thread.currentThread() == GtkMainThread.mainThread)
557
      gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y);
558
    else
559
      gtkWidgetSetCursor(cursor.getType(), image, x, y);
560
  }
561
 
562
  public void setEnabled (boolean b)
563
  {
564
    gtkWidgetSetSensitive (b);
565
  }
566
 
567
  public void setFont (Font f)
568
  {
569
    // FIXME: This should really affect the widget tree below me.
570
    // Currently this is only handled if the call is made directly on
571
    // a text widget, which implements setFont() itself.
572
    gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize());
573
  }
574
 
575
  public void setForeground (Color c)
576
  {
577
    gtkWidgetSetForeground (c.getRed(), c.getGreen(), c.getBlue());
578
  }
579
 
580
  public Color getForeground ()
581
  {
582
    int rgb[] = gtkWidgetGetForeground ();
583
    return new Color (rgb[0], rgb[1], rgb[2]);
584
  }
585
 
586
  public Color getBackground ()
587
  {
588
    int rgb[] = gtkWidgetGetBackground ();
589
    return new Color (rgb[0], rgb[1], rgb[2]);
590
  }
591
 
592
  public native void setVisibleNative (boolean b);
593
  public native void setVisibleNativeUnlocked (boolean b);
594
 
595
  public void setVisible (boolean b)
596
  {
597
    // Only really set visible when component is bigger than zero pixels.
598
    if (b && ! (awtComponent instanceof Window))
599
      {
600
        Rectangle bounds = awtComponent.getBounds();
601
        b = (bounds.width > 0) && (bounds.height > 0);
602
      }
603
 
604
    if (Thread.currentThread() == GtkMainThread.mainThread)
605
      setVisibleNativeUnlocked (b);
606
    else
607
      setVisibleNative (b);
608
  }
609
 
610
  public void hide ()
611
  {
612
    setVisible (false);
613
  }
614
 
615
  public void show ()
616
  {
617
    setVisible (true);
618
  }
619
 
620
  protected void postMouseEvent(int id, long when, int mods, int x, int y,
621
                                int clickCount, boolean popupTrigger)
622
  {
623
    // It is important to do the getLocationOnScreen() here, instead
624
    // of using the old MouseEvent constructors, because
625
    // Component.getLocationOnScreen() locks on the AWT lock, which can
626
    // trigger a deadlock. You don't want this.
627
    Point locOnScreen = getLocationOnScreen();
628
    q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y,
629
                                 locOnScreen.x + x, locOnScreen.y + y,
630
                                 clickCount, popupTrigger,
631
                                 MouseEvent.NOBUTTON));
632
  }
633
 
634
  /**
635
   * Callback for component_scroll_cb.
636
   */
637
  protected void postMouseWheelEvent(int id, long when, int mods,
638
                                     int x, int y, int clickCount,
639
                                     boolean popupTrigger,
640
                                     int type, int amount, int rotation)
641
  {
642
    q().postEvent(new MouseWheelEvent(awtComponent, id, when, mods,
643
                                      x, y, clickCount, popupTrigger,
644
                                      type, amount, rotation));
645
  }
646
 
647
  protected void postExposeEvent (int x, int y, int width, int height)
648
  {
649
    q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
650
                                   new Rectangle (x, y, width, height)));
651
  }
652
 
653
  protected void postKeyEvent (int id, long when, int mods,
654
                               int keyCode, char keyChar, int keyLocation)
655
  {
656
    KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods,
657
                                      keyCode, keyChar, keyLocation);
658
 
659
    EventQueue q = q();
660
 
661
    // Also post a KEY_TYPED event if keyEvent is a key press that
662
    // doesn't represent an action or modifier key.
663
    if (keyEvent.getID () == KeyEvent.KEY_PRESSED
664
        && (!keyEvent.isActionKey ()
665
            && keyCode != KeyEvent.VK_SHIFT
666
            && keyCode != KeyEvent.VK_CONTROL
667
            && keyCode != KeyEvent.VK_ALT))
668
      {
669
        synchronized(q)
670
          {
671
            q.postEvent(keyEvent);
672
            keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when,
673
                                    mods, KeyEvent.VK_UNDEFINED, keyChar,
674
                                    keyLocation);
675
            q.postEvent(keyEvent);
676
          }
677
      }
678
    else
679
      q.postEvent(keyEvent);
680
  }
681
 
682
  /**
683
   * Referenced from native code.
684
   *
685
   * @param id
686
   * @param temporary
687
   */
688
  protected void postFocusEvent (int id, boolean temporary)
689
  {
690
    q().postEvent (new FocusEvent (awtComponent, id, temporary));
691
  }
692
 
693
  protected void postItemEvent (Object item, int stateChange)
694
  {
695
    q().postEvent (new ItemEvent ((ItemSelectable)awtComponent,
696
                                  ItemEvent.ITEM_STATE_CHANGED,
697
                                  item, stateChange));
698
  }
699
 
700
  protected void postTextEvent ()
701
  {
702
    q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED));
703
  }
704
 
705
  public GraphicsConfiguration getGraphicsConfiguration ()
706
  {
707
    // FIXME: The component might be showing on a non-default screen.
708
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
709
    GraphicsDevice dev = env.getDefaultScreenDevice();
710
    return dev.getDefaultConfiguration();
711
  }
712
 
713
  public void setEventMask (long mask)
714
  {
715
    // FIXME: just a stub for now.
716
  }
717
 
718
  public boolean isFocusable ()
719
  {
720
    return false;
721
  }
722
 
723
  public boolean requestFocus (Component request, boolean temporary,
724
                               boolean allowWindowFocus, long time)
725
  {
726
    assert request == awtComponent || isLightweightDescendant(request);
727
    boolean retval = false;
728
    if (gtkWidgetHasFocus())
729
      {
730
        KeyboardFocusManager kfm =
731
          KeyboardFocusManager.getCurrentKeyboardFocusManager();
732
        Component currentFocus = kfm.getFocusOwner();
733
        if (currentFocus == request)
734
          // Nothing to do in this trivial case.
735
          retval = true;
736
        else
737
          {
738
            // Requested component is a lightweight descendant of this one
739
            // or the actual heavyweight.
740
            // Since this (native) component is already focused, we simply
741
            // change the actual focus and be done.
742
            postFocusEvent(FocusEvent.FOCUS_GAINED, temporary);
743
            retval = true;
744
          }
745
      }
746
    else
747
      {
748
        if (gtkWidgetCanFocus())
749
          {
750
            if (allowWindowFocus)
751
              {
752
                Window window = getWindowFor(request);
753
                GtkWindowPeer wPeer = (GtkWindowPeer) window.getPeer();
754
                if (! wPeer.gtkWindowHasFocus())
755
                  wPeer.requestWindowFocus();
756
              }
757
            // Store requested focus component so that the corresponding
758
            // event is dispatched correctly.
759
            gtkWidgetRequestFocus();
760
            retval = true;
761
          }
762
      }
763
    return retval;
764
  }
765
 
766
  private Window getWindowFor(Component c)
767
  {
768
    Component comp = c;
769
    while (! (comp instanceof Window))
770
      comp = comp.getParent();
771
    return (Window) comp;
772
  }
773
 
774
  /**
775
   * Returns <code>true</code> if the component is a direct (== no intermediate
776
   * heavyweights) lightweight descendant of this peer's component.
777
   *
778
   * @param c the component to check
779
   *
780
   * @return <code>true</code> if the component is a direct (== no intermediate
781
   *         heavyweights) lightweight descendant of this peer's component
782
   */
783
  protected boolean isLightweightDescendant(Component c)
784
  {
785
    Component comp = c;
786
    while (comp.getPeer() instanceof LightweightPeer)
787
      comp = comp.getParent();
788
    return comp == awtComponent;
789
  }
790
 
791
  public boolean isObscured ()
792
  {
793
    return false;
794
  }
795
 
796
  public boolean canDetermineObscurity ()
797
  {
798
    return false;
799
  }
800
 
801
  public void coalescePaintEvent (PaintEvent e)
802
  {
803
    synchronized (this)
804
    {
805
      Rectangle newRect = e.getUpdateRect();
806
      if (currentPaintArea == null)
807
        currentPaintArea = newRect;
808
      else
809
        Rectangle.union(currentPaintArea, newRect, currentPaintArea);
810
    }
811
  }
812
 
813
  public void updateCursorImmediately ()
814
  {
815
    if (awtComponent.getCursor() != null)
816
      setCursor(awtComponent.getCursor());
817
  }
818
 
819
  public boolean handlesWheelScrolling ()
820
  {
821
    return false;
822
  }
823
 
824
  // Convenience method to create a new volatile image on the screen
825
  // on which this component is displayed.
826
  public VolatileImage createVolatileImage (int width, int height)
827
  {
828
    return new GtkVolatileImage (this, width, height, null);
829
  }
830
 
831
  // Creates buffers used in a buffering strategy.
832
  public void createBuffers (int numBuffers, BufferCapabilities caps)
833
    throws AWTException
834
  {
835
    // numBuffers == 2 implies double-buffering, meaning one back
836
    // buffer and one front buffer.
837
    if (numBuffers == 2)
838
      backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(),
839
                                        awtComponent.getHeight(),
840
                                        caps.getBackBufferCapabilities());
841
    else
842
      throw new AWTException("GtkComponentPeer.createBuffers:"
843
                             + " multi-buffering not supported");
844
    this.caps = caps;
845
  }
846
 
847
  // Return the back buffer.
848
  public Image getBackBuffer ()
849
  {
850
    return backBuffer;
851
  }
852
 
853
  // FIXME: flip should be implemented as a fast native operation
854
  public void flip (BufferCapabilities.FlipContents contents)
855
  {
856
    getGraphics().drawImage(backBuffer,
857
                            awtComponent.getWidth(),
858
                            awtComponent.getHeight(),
859
                            null);
860
 
861
    // create new back buffer and clear it to the background color.
862
    if (contents == BufferCapabilities.FlipContents.BACKGROUND)
863
        {
864
          backBuffer = createVolatileImage(awtComponent.getWidth(),
865
                                           awtComponent.getHeight());
866
          backBuffer.getGraphics().clearRect(0, 0,
867
                                             awtComponent.getWidth(),
868
                                             awtComponent.getHeight());
869
        }
870
    // FIXME: support BufferCapabilities.FlipContents.PRIOR
871
  }
872
 
873
  // Release the resources allocated to back buffers.
874
  public void destroyBuffers ()
875
  {
876
    backBuffer.flush();
877
  }
878
 
879
  public String toString ()
880
  {
881
    return "peer of " + awtComponent.toString();
882
  }
883
  public Rectangle getBounds()
884
  {
885
      // FIXME: implement
886
    return null;
887
  }
888
  public void reparent(ContainerPeer parent)
889
  {
890
    // FIXME: implement
891
 
892
  }
893
  public void setBounds(int x, int y, int width, int height, int z)
894
  {
895
    // FIXME: implement
896
      setBounds (x, y, width, height);
897
 
898
  }
899
  public boolean isReparentSupported()
900
  {
901
    // FIXME: implement
902
 
903
    return false;
904
  }
905
  public void layout()
906
  {
907
    // FIXME: implement
908
 
909
  }
910
 
911
  public boolean requestFocus(Component lightweightChild, boolean temporary,
912
                              boolean focusedWindowChangeAllowed,
913
                              long time, sun.awt.CausedFocusEvent.Cause cause)
914
  {
915
    // TODO: Implement this properly and remove the other requestFocus()
916
    // methods.
917
    return true;
918
  }
919
 
920
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.