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:
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:
95: private Rectangle currentPaintArea;
96:
97:
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:
158:
159:
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:
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:
246:
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:
304:
305: protected void paintComponent (PaintEvent event)
306: {
307:
308:
309: if (!awtComponent.isShowing()
310: || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
311: return;
312:
313:
314:
315:
316:
317:
318:
319:
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:
344:
345: protected void updateComponent (PaintEvent event)
346: {
347:
348:
349: if (!awtComponent.isShowing()
350: || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
351: return;
352:
353:
354:
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:
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:
485:
486:
487:
488:
489:
490:
491:
492:
493:
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:
505:
506: if (parent instanceof Window)
507: {
508: GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer ();
509:
510:
511:
512:
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:
527:
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:
570:
571:
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:
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:
624:
625:
626:
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:
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:
662:
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:
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:
708: GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
709: GraphicsDevice dev = env.getDefaultScreenDevice();
710: return dev.getDefaultConfiguration();
711: }
712:
713: public void setEventMask (long mask)
714: {
715:
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:
735: retval = true;
736: else
737: {
738:
739:
740:
741:
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:
758:
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:
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:
825:
826: public VolatileImage createVolatileImage (int width, int height)
827: {
828: return new GtkVolatileImage (this, width, height, null);
829: }
830:
831:
832: public void createBuffers (int numBuffers, BufferCapabilities caps)
833: throws AWTException
834: {
835:
836:
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:
848: public Image getBackBuffer ()
849: {
850: return backBuffer;
851: }
852:
853:
854: public void flip (BufferCapabilities.FlipContents contents)
855: {
856: getGraphics().drawImage(backBuffer,
857: awtComponent.getWidth(),
858: awtComponent.getHeight(),
859: null);
860:
861:
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:
871: }
872:
873:
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:
886: return null;
887: }
888: public void reparent(ContainerPeer parent)
889: {
890:
891:
892: }
893: public void setBounds(int x, int y, int width, int height, int z)
894: {
895:
896: setBounds (x, y, width, height);
897:
898: }
899: public boolean isReparentSupported()
900: {
901:
902:
903: return false;
904: }
905: public void layout()
906: {
907:
908:
909: }
910:
911: public boolean requestFocus(Component lightweightChild, boolean temporary,
912: boolean focusedWindowChangeAllowed,
913: long time, sun.awt.CausedFocusEvent.Cause cause)
914: {
915:
916:
917: return true;
918: }
919:
920: }