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