1:
38:
39:
40: package ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82:
83: public class GtkComponentPeer extends GtkGenericPeer
84: implements ComponentPeer
85: {
86: VolatileImage backBuffer;
87: BufferCapabilities caps;
88:
89: Component awtComponent;
90:
91: Insets insets;
92:
93:
96: private Rectangle currentPaintArea;
97:
98:
101: native boolean isEnabled ();
102: static native boolean modalHasGrab();
103:
104: native int[] gtkWidgetGetForeground ();
105: native int[] gtkWidgetGetBackground ();
106: native void gtkWidgetGetDimensions (int[] dim);
107: native void gtkWidgetGetPreferredDimensions (int[] dim);
108: native void gtkWindowGetLocationOnScreen (int[] point);
109: native void gtkWidgetGetLocationOnScreen (int[] point);
110: native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y);
111: native void gtkWidgetSetCursorUnlocked (int type, GtkImage image,
112: int x, int y);
113: native void gtkWidgetSetBackground (int red, int green, int blue);
114: native void gtkWidgetSetForeground (int red, int green, int blue);
115: native void gtkWidgetSetSensitive (boolean sensitive);
116: native void gtkWidgetSetParent (ComponentPeer parent);
117: native void gtkWidgetRequestFocus ();
118: native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
119: int keyCode, int keyLocation);
120: native boolean gtkWidgetHasFocus();
121: native boolean gtkWidgetCanFocus();
122:
123: native void realize();
124: native void setNativeEventMask ();
125:
126: void create ()
127: {
128: throw new RuntimeException ();
129: }
130:
131: native void connectSignals ();
132:
133: protected GtkComponentPeer (Component awtComponent)
134: {
135: super (awtComponent);
136: this.awtComponent = awtComponent;
137: insets = new Insets (0, 0, 0, 0);
138:
139: create ();
140:
141: connectSignals ();
142:
143: if (awtComponent.getForeground () != null)
144: setForeground (awtComponent.getForeground ());
145: if (awtComponent.getBackground () != null)
146: setBackground (awtComponent.getBackground ());
147: if (awtComponent.getFont() != null)
148: setFont(awtComponent.getFont());
149:
150: Component parent = awtComponent.getParent ();
151:
152: setParentAndBounds ();
153:
154: setNativeEventMask ();
155:
156:
157:
158:
159: realize ();
160:
161: if (awtComponent.isCursorSet())
162: setCursor ();
163: }
164:
165: void setParentAndBounds ()
166: {
167: setParent ();
168:
169: setComponentBounds ();
170:
171: setVisibleAndEnabled ();
172: }
173:
174: void setParent ()
175: {
176: ComponentPeer p;
177: Component component = awtComponent;
178: do
179: {
180: component = component.getParent ();
181: p = component.getPeer ();
182: }
183: while (p instanceof java.awt.peer.LightweightPeer);
184:
185: if (p != null)
186: gtkWidgetSetParent (p);
187: }
188:
189:
196: void setComponentBounds ()
197: {
198: Rectangle bounds = awtComponent.getBounds ();
199: setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
200: }
201:
202: void setVisibleAndEnabled ()
203: {
204: setVisible (awtComponent.isVisible ());
205: setEnabled (awtComponent.isEnabled ());
206: }
207:
208: public int checkImage (Image image, int width, int height,
209: ImageObserver observer)
210: {
211: return getToolkit().checkImage(image, width, height, observer);
212: }
213:
214: public Image createImage (ImageProducer producer)
215: {
216: return new GtkImage (producer);
217: }
218:
219: public Image createImage (int width, int height)
220: {
221: return CairoSurface.getBufferedImage(width, height);
222: }
223:
224: public void disable ()
225: {
226: setEnabled (false);
227: }
228:
229: public void enable ()
230: {
231: setEnabled (true);
232: }
233:
234: public ColorModel getColorModel ()
235: {
236: return ColorModel.getRGBdefault ();
237: }
238:
239: public FontMetrics getFontMetrics (Font font)
240: {
241: return getToolkit().getFontMetrics(font);
242: }
243:
244:
245:
246: public Graphics getGraphics ()
247: {
248: return ComponentGraphics.getComponentGraphics(this);
249: }
250:
251: public Point getLocationOnScreen ()
252: {
253: int point[] = new int[2];
254: if( this instanceof WindowPeer )
255: gtkWindowGetLocationOnScreen (point);
256: else
257: gtkWidgetGetLocationOnScreen (point);
258: return new Point (point[0], point[1]);
259: }
260:
261: public Dimension getMinimumSize ()
262: {
263: return minimumSize ();
264: }
265:
266: public Dimension getPreferredSize ()
267: {
268: return preferredSize ();
269: }
270:
271: public Toolkit getToolkit ()
272: {
273: return Toolkit.getDefaultToolkit();
274: }
275:
276: public void handleEvent (AWTEvent event)
277: {
278: int id = event.getID();
279: KeyEvent ke = null;
280:
281: switch (id)
282: {
283: case PaintEvent.PAINT:
284: paintComponent((PaintEvent) event);
285: break;
286: case PaintEvent.UPDATE:
287: updateComponent((PaintEvent) event);
288: break;
289: case KeyEvent.KEY_PRESSED:
290: ke = (KeyEvent) event;
291: gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
292: ke.getKeyCode (), ke.getKeyLocation ());
293: break;
294: case KeyEvent.KEY_RELEASED:
295: ke = (KeyEvent) event;
296: gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
297: ke.getKeyCode (), ke.getKeyLocation ());
298: break;
299: }
300: }
301:
302:
303:
304: protected void paintComponent (PaintEvent event)
305: {
306:
307:
308: if (!awtComponent.isShowing()
309: || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
310: return;
311:
312:
313:
314:
315:
316:
317:
318:
319: coalescePaintEvent(event);
320: Rectangle paintArea;
321: synchronized (this)
322: {
323: paintArea = currentPaintArea;
324: currentPaintArea = null;
325: }
326:
327: if (paintArea != null)
328: {
329: Graphics g = getGraphics();
330: try
331: {
332: g.setClip(paintArea);
333: awtComponent.paint(g);
334: }
335: finally
336: {
337: g.dispose();
338: }
339: }
340: }
341:
342:
343:
344: protected void updateComponent (PaintEvent event)
345: {
346:
347:
348: if (!awtComponent.isShowing()
349: || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
350: return;
351:
352:
353:
354: coalescePaintEvent(event);
355: Rectangle paintArea;
356: synchronized (this)
357: {
358: paintArea = currentPaintArea;
359: currentPaintArea = null;
360: }
361:
362: if (paintArea != null)
363: {
364: Graphics g = getGraphics();
365: try
366: {
367: g.setClip(paintArea);
368: awtComponent.update(g);
369: }
370: finally
371: {
372: g.dispose();
373: }
374: }
375: }
376:
377: public boolean isFocusTraversable ()
378: {
379: return true;
380: }
381:
382: public Dimension minimumSize ()
383: {
384: int dim[] = new int[2];
385:
386: gtkWidgetGetPreferredDimensions (dim);
387:
388: return new Dimension (dim[0], dim[1]);
389: }
390:
391: public void paint (Graphics g)
392: {
393: }
394:
395: public Dimension preferredSize ()
396: {
397: int dim[] = new int[2];
398:
399: gtkWidgetGetPreferredDimensions (dim);
400:
401: return new Dimension (dim[0], dim[1]);
402: }
403:
404: public boolean prepareImage (Image image, int width, int height,
405: ImageObserver observer)
406: {
407: return getToolkit().prepareImage(image, width, height, observer);
408: }
409:
410: public void print (Graphics g)
411: {
412: g.drawImage( ComponentGraphics.grab( this ), 0, 0, null );
413: }
414:
415: public void repaint (long tm, int x, int y, int width, int height)
416: {
417: if (width < 1 || height < 1)
418: return;
419:
420: if (tm <= 0)
421: q().postEvent(new PaintEvent(awtComponent, PaintEvent.UPDATE,
422: new Rectangle(x, y, width, height)));
423: else
424: RepaintTimerTask.schedule(tm, x, y, width, height, awtComponent);
425: }
426:
427:
430: private static class RepaintTimerTask extends TimerTask
431: {
432: private static final Timer repaintTimer = new Timer(true);
433:
434: private int x, y, width, height;
435: private Component awtComponent;
436:
437: RepaintTimerTask(Component c, int x, int y, int width, int height)
438: {
439: this.x = x;
440: this.y = y;
441: this.width = width;
442: this.height = height;
443: this.awtComponent = c;
444: }
445:
446: public void run()
447: {
448: q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE,
449: new Rectangle (x, y, width, height)));
450: }
451:
452: static void schedule(long tm, int x, int y, int width, int height,
453: Component c)
454: {
455: repaintTimer.schedule(new RepaintTimerTask(c, x, y, width, height), tm);
456: }
457: }
458:
459: public void requestFocus ()
460: {
461: assert false: "Call new requestFocus() method instead";
462: }
463:
464: public void reshape (int x, int y, int width, int height)
465: {
466: setBounds (x, y, width, height);
467: }
468:
469: public void setBackground (Color c)
470: {
471: gtkWidgetSetBackground (c.getRed(), c.getGreen(), c.getBlue());
472: }
473:
474: native void setNativeBounds (int x, int y, int width, int height);
475:
476: public void setBounds (int x, int y, int width, int height)
477: {
478: int new_x = x;
479: int new_y = y;
480:
481: Component parent = awtComponent.getParent ();
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493: Insets i;
494: while (parent.isLightweight())
495: {
496: i = ((Container) parent).getInsets();
497:
498: new_x += parent.getX() + i.left;
499: new_y += parent.getY() + i.top;
500:
501: parent = parent.getParent();
502: }
503:
504:
505: if (parent instanceof Window)
506: {
507: GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer ();
508:
509:
510:
511:
512: Insets insets = peer.getInsets ();
513:
514: int menuBarHeight = 0;
515: if (peer instanceof GtkFramePeer)
516: menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight ();
517:
518: new_x -= insets.left;
519: new_y -= insets.top;
520: new_y += menuBarHeight;
521: }
522:
523: setNativeBounds (new_x, new_y, width, height);
524:
525:
526:
527: setVisible(awtComponent.isVisible());
528: }
529:
530: void setCursor ()
531: {
532: setCursor (awtComponent.getCursor ());
533: }
534:
535: public void setCursor (Cursor cursor)
536: {
537: int x, y;
538: GtkImage image;
539: int type = cursor.getType();
540: if (cursor instanceof GtkCursor)
541: {
542: GtkCursor gtkCursor = (GtkCursor) cursor;
543: image = gtkCursor.getGtkImage();
544: Point hotspot = gtkCursor.getHotspot();
545: x = hotspot.x;
546: y = hotspot.y;
547: }
548: else
549: {
550: image = null;
551: x = 0;
552: y = 0;
553: }
554:
555: if (Thread.currentThread() == GtkMainThread.mainThread)
556: gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y);
557: else
558: gtkWidgetSetCursor(cursor.getType(), image, x, y);
559: }
560:
561: public void setEnabled (boolean b)
562: {
563: gtkWidgetSetSensitive (b);
564: }
565:
566: public void setFont (Font f)
567: {
568:
569:
570:
571: gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize());
572: }
573:
574: public void setForeground (Color c)
575: {
576: gtkWidgetSetForeground (c.getRed(), c.getGreen(), c.getBlue());
577: }
578:
579: public Color getForeground ()
580: {
581: int rgb[] = gtkWidgetGetForeground ();
582: return new Color (rgb[0], rgb[1], rgb[2]);
583: }
584:
585: public Color getBackground ()
586: {
587: int rgb[] = gtkWidgetGetBackground ();
588: return new Color (rgb[0], rgb[1], rgb[2]);
589: }
590:
591: public native void setVisibleNative (boolean b);
592: public native void setVisibleNativeUnlocked (boolean b);
593:
594: public void setVisible (boolean b)
595: {
596:
597: if (b && ! (awtComponent instanceof Window))
598: {
599: Rectangle bounds = awtComponent.getBounds();
600: b = (bounds.width > 0) && (bounds.height > 0);
601: }
602:
603: if (Thread.currentThread() == GtkMainThread.mainThread)
604: setVisibleNativeUnlocked (b);
605: else
606: setVisibleNative (b);
607: }
608:
609: public void hide ()
610: {
611: setVisible (false);
612: }
613:
614: public void show ()
615: {
616: setVisible (true);
617: }
618:
619: protected void postMouseEvent(int id, long when, int mods, int x, int y,
620: int clickCount, boolean popupTrigger)
621: {
622:
623:
624:
625:
626: Point locOnScreen = getLocationOnScreen();
627: q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y,
628: locOnScreen.x + x, locOnScreen.y + y,
629: clickCount, popupTrigger,
630: MouseEvent.NOBUTTON));
631: }
632:
633:
636: protected void postMouseWheelEvent(int id, long when, int mods,
637: int x, int y, int clickCount,
638: boolean popupTrigger,
639: int type, int amount, int rotation)
640: {
641: q().postEvent(new MouseWheelEvent(awtComponent, id, when, mods,
642: x, y, clickCount, popupTrigger,
643: type, amount, rotation));
644: }
645:
646: protected void postExposeEvent (int x, int y, int width, int height)
647: {
648: q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
649: new Rectangle (x, y, width, height)));
650: }
651:
652: protected void postKeyEvent (int id, long when, int mods,
653: int keyCode, char keyChar, int keyLocation)
654: {
655: KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods,
656: keyCode, keyChar, keyLocation);
657:
658: EventQueue q = q();
659:
660:
661:
662: if (keyEvent.getID () == KeyEvent.KEY_PRESSED
663: && (!keyEvent.isActionKey ()
664: && keyCode != KeyEvent.VK_SHIFT
665: && keyCode != KeyEvent.VK_CONTROL
666: && keyCode != KeyEvent.VK_ALT))
667: {
668: synchronized(q)
669: {
670: q.postEvent(keyEvent);
671: keyEvent = new KeyEvent(awtComponent, KeyEvent.KEY_TYPED, when,
672: mods, KeyEvent.VK_UNDEFINED, keyChar,
673: keyLocation);
674: q.postEvent(keyEvent);
675: }
676: }
677: else
678: q.postEvent(keyEvent);
679: }
680:
681:
687: protected void postFocusEvent (int id, boolean temporary)
688: {
689: q().postEvent (new FocusEvent (awtComponent, id, temporary));
690: }
691:
692: protected void postItemEvent (Object item, int stateChange)
693: {
694: q().postEvent (new ItemEvent ((ItemSelectable)awtComponent,
695: ItemEvent.ITEM_STATE_CHANGED,
696: item, stateChange));
697: }
698:
699: protected void postTextEvent ()
700: {
701: q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED));
702: }
703:
704: public GraphicsConfiguration getGraphicsConfiguration ()
705: {
706:
707: GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
708: GraphicsDevice dev = env.getDefaultScreenDevice();
709: return dev.getDefaultConfiguration();
710: }
711:
712: public void setEventMask (long mask)
713: {
714:
715: }
716:
717: public boolean isFocusable ()
718: {
719: return false;
720: }
721:
722: public boolean requestFocus (Component request, boolean temporary,
723: boolean allowWindowFocus, long time)
724: {
725: assert request == awtComponent || isLightweightDescendant(request);
726: boolean retval = false;
727: if (gtkWidgetHasFocus())
728: {
729: KeyboardFocusManager kfm =
730: KeyboardFocusManager.getCurrentKeyboardFocusManager();
731: Component currentFocus = kfm.getFocusOwner();
732: if (currentFocus == request)
733:
734: retval = true;
735: else
736: {
737:
738:
739:
740:
741: postFocusEvent(FocusEvent.FOCUS_GAINED, temporary);
742: retval = true;
743: }
744: }
745: else
746: {
747: if (gtkWidgetCanFocus())
748: {
749: if (allowWindowFocus)
750: {
751: Window window = getWindowFor(request);
752: GtkWindowPeer wPeer = (GtkWindowPeer) window.getPeer();
753: if (! wPeer.gtkWindowHasFocus())
754: wPeer.requestWindowFocus();
755: }
756:
757:
758: gtkWidgetRequestFocus();
759: retval = true;
760: }
761: }
762: return retval;
763: }
764:
765: private Window getWindowFor(Component c)
766: {
767: Component comp = c;
768: while (! (comp instanceof Window))
769: comp = comp.getParent();
770: return (Window) comp;
771: }
772:
773:
782: protected boolean isLightweightDescendant(Component c)
783: {
784: Component comp = c;
785: while (comp.getPeer() instanceof LightweightPeer)
786: comp = comp.getParent();
787: return comp == awtComponent;
788: }
789:
790: public boolean isObscured ()
791: {
792: return false;
793: }
794:
795: public boolean canDetermineObscurity ()
796: {
797: return false;
798: }
799:
800: public void coalescePaintEvent (PaintEvent e)
801: {
802: synchronized (this)
803: {
804: Rectangle newRect = e.getUpdateRect();
805: if (currentPaintArea == null)
806: currentPaintArea = newRect;
807: else
808: Rectangle.union(currentPaintArea, newRect, currentPaintArea);
809: }
810: }
811:
812: public void updateCursorImmediately ()
813: {
814: if (awtComponent.getCursor() != null)
815: setCursor(awtComponent.getCursor());
816: }
817:
818: public boolean handlesWheelScrolling ()
819: {
820: return false;
821: }
822:
823:
824:
825: public VolatileImage createVolatileImage (int width, int height)
826: {
827: return new GtkVolatileImage (this, width, height, null);
828: }
829:
830:
831: public void createBuffers (int numBuffers, BufferCapabilities caps)
832: throws AWTException
833: {
834:
835:
836: if (numBuffers == 2)
837: backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(),
838: awtComponent.getHeight(),
839: caps.getBackBufferCapabilities());
840: else
841: throw new AWTException("GtkComponentPeer.createBuffers:"
842: + " multi-buffering not supported");
843: this.caps = caps;
844: }
845:
846:
847: public Image getBackBuffer ()
848: {
849: return backBuffer;
850: }
851:
852:
853: public void flip (BufferCapabilities.FlipContents contents)
854: {
855: getGraphics().drawImage(backBuffer,
856: awtComponent.getWidth(),
857: awtComponent.getHeight(),
858: null);
859:
860:
861: if (contents == BufferCapabilities.FlipContents.BACKGROUND)
862: {
863: backBuffer = createVolatileImage(awtComponent.getWidth(),
864: awtComponent.getHeight());
865: backBuffer.getGraphics().clearRect(0, 0,
866: awtComponent.getWidth(),
867: awtComponent.getHeight());
868: }
869:
870: }
871:
872:
873: public void destroyBuffers ()
874: {
875: backBuffer.flush();
876: }
877:
878: public String toString ()
879: {
880: return "peer of " + awtComponent.toString();
881: }
882: public Rectangle getBounds()
883: {
884:
885: return null;
886: }
887: public void reparent(ContainerPeer parent)
888: {
889:
890:
891: }
892: public void setBounds(int x, int y, int width, int height, int z)
893: {
894:
895: setBounds (x, y, width, height);
896:
897: }
898: public boolean isReparentSupported()
899: {
900:
901:
902: return false;
903: }
904: public void layout()
905: {
906:
907:
908: }
909:
910: public boolean requestFocus(Component lightweightChild, boolean temporary,
911: boolean focusedWindowChangeAllowed,
912: long time, sun.awt.CausedFocusEvent.Cause cause)
913: {
914:
915:
916: return true;
917: }
918:
919: }