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