1:
38:
39:
40: package ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48:
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: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109: import ;
110: import ;
111: import ;
112: import ;
113: import ;
114: import ;
115: import ;
116: import ;
117: import ;
118: import ;
119: import ;
120: import ;
121: import ;
122: import ;
123: import ;
124: import ;
125:
126: import ;
127:
128:
134:
135: public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
136: {
137: static final Object GTK_LOCK;
138:
139: private static EventQueue q;
140:
141: static native void gtkInit(int portableNativeSync, Object lock);
142:
143: static native void gtkMain();
144:
145: static native void gtkQuit();
146:
147:
150: private static native void initIDs();
151:
152:
155: private static boolean initializedGlobalIDs = false;
156:
157:
162: static synchronized void initializeGlobalIDs()
163: {
164: if (! initializedGlobalIDs)
165: {
166: initIDs();
167: initializedGlobalIDs = true;
168: }
169: }
170:
171: static
172: {
173: System.loadLibrary("gtkpeer");
174:
175:
178: initializeGlobalIDs();
179:
180: int portableNativeSync;
181: String portNatSyncProp =
182: System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
183:
184: if (portNatSyncProp == null)
185: portableNativeSync = -1;
186: else if (Boolean.valueOf(portNatSyncProp).booleanValue())
187: portableNativeSync = 1;
188: else
189: portableNativeSync = 0;
190:
191: GTK_LOCK = new String("GTK LOCK");
192: gtkInit(portableNativeSync, GTK_LOCK);
193: }
194:
195: public GtkToolkit ()
196: {
197: }
198:
199: public native void beep();
200:
201: private native void getScreenSizeDimensions(int[] xy);
202:
203: public int checkImage (Image image, int width, int height,
204: ImageObserver observer)
205: {
206: int status = ImageObserver.ALLBITS
207: | ImageObserver.WIDTH
208: | ImageObserver.HEIGHT;
209:
210: if (image instanceof GtkImage)
211: return ((GtkImage) image).checkImage (observer);
212:
213: if (image instanceof AsyncImage)
214: return ((AsyncImage) image).checkImage(observer);
215:
216: if (observer != null)
217: observer.imageUpdate (image, status,
218: -1, -1,
219: image.getWidth (observer),
220: image.getHeight (observer));
221:
222: return status;
223: }
224:
225:
229: static Image imageOrError(Image b)
230: {
231: if (b == null)
232: return GtkImage.getErrorImage();
233: else
234: return b;
235: }
236:
237: public Image createImage (String filename)
238: {
239: if (filename.length() == 0)
240: return new GtkImage ();
241:
242: Image image;
243: try
244: {
245: image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
246: }
247: catch (IllegalArgumentException iae)
248: {
249: image = null;
250: }
251: return imageOrError(image);
252: }
253:
254: public Image createImage (URL url)
255: {
256: return new AsyncImage(url);
257: }
258:
259: public Image createImage (ImageProducer producer)
260: {
261: if (producer == null)
262: return null;
263:
264: Image image;
265: try
266: {
267: image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
268: }
269: catch (IllegalArgumentException iae)
270: {
271: image = null;
272: }
273: return imageOrError(image);
274: }
275:
276: public Image createImage (byte[] imagedata, int imageoffset,
277: int imagelength)
278: {
279: Image image;
280: try
281: {
282: byte[] data = new byte[ imagelength ];
283: System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
284: image = CairoSurface.getBufferedImage( new GtkImage( data ) );
285: }
286: catch (IllegalArgumentException iae)
287: {
288: image = null;
289: }
290: return imageOrError(image);
291: }
292:
293:
299: public ImageProducer createImageProducer(URL url)
300: {
301: return createImage( url ).getSource();
302: }
303:
304:
308: public ColorModel getColorModel ()
309: {
310:
311: return new DirectColorModel(32,
312: 0x000000FF,
313: 0x0000FF00,
314: 0x00FF0000,
315: 0xFF000000);
316: }
317:
318: public String[] getFontList ()
319: {
320: return (new String[] { "Dialog",
321: "DialogInput",
322: "Monospaced",
323: "Serif",
324: "SansSerif" });
325: }
326:
327: static class LRUCache<K,V> extends LinkedHashMap<K,V>
328: {
329: int max_entries;
330: public LRUCache(int max)
331: {
332: super(max, 0.75f, true);
333: max_entries = max;
334: }
335: protected boolean removeEldestEntry(Map.Entry eldest)
336: {
337: return size() > max_entries;
338: }
339: }
340:
341: private LRUCache<Map,ClasspathFontPeer> fontCache =
342: new LRUCache<Map,ClasspathFontPeer>(50);
343: private LRUCache<Object,Image> imageCache = new LRUCache<Object,Image>(50);
344:
345: public FontMetrics getFontMetrics (Font font)
346: {
347: return ((GdkFontPeer) font.getPeer()).getFontMetrics(font);
348: }
349:
350: public Image getImage (String filename)
351: {
352: if (imageCache.containsKey(filename))
353: return imageCache.get(filename);
354: else
355: {
356: Image im = createImage(filename);
357: imageCache.put(filename, im);
358: return im;
359: }
360: }
361:
362: public Image getImage (URL url)
363: {
364: if (imageCache.containsKey(url))
365: return imageCache.get(url);
366: else
367: {
368: Image im = createImage(url);
369: imageCache.put(url, im);
370: return im;
371: }
372: }
373:
374: public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props)
375: {
376: SecurityManager sm;
377: sm = System.getSecurityManager();
378: if (sm != null)
379: sm.checkPrintJobAccess();
380:
381: return null;
382: }
383:
384: public native int getScreenResolution();
385:
386: public Dimension getScreenSize ()
387: {
388: int dim[] = new int[2];
389: getScreenSizeDimensions(dim);
390: return new Dimension(dim[0], dim[1]);
391: }
392:
393: public Clipboard getSystemClipboard()
394: {
395: SecurityManager secman = System.getSecurityManager();
396: if (secman != null)
397: secman.checkSystemClipboardAccess();
398:
399: return GtkClipboard.getClipboardInstance();
400: }
401:
402: public Clipboard getSystemSelection()
403: {
404: SecurityManager secman = System.getSecurityManager();
405: if (secman != null)
406: secman.checkSystemClipboardAccess();
407:
408: return GtkClipboard.getSelectionInstance();
409: }
410:
411:
415: public boolean prepareImage (Image image, int width, int height,
416: ImageObserver observer)
417: {
418:
419: if (image instanceof GtkImage)
420: return ((((GtkImage)image).checkImage (observer)
421: & ImageObserver.ALLBITS) != 0);
422:
423: if (image instanceof AsyncImage)
424: {
425: AsyncImage aImg = (AsyncImage) image;
426: aImg.addObserver(observer);
427: return aImg.realImage != null;
428: }
429:
430:
431: return true;
432: }
433:
434: public native void sync();
435:
436: protected void setComponentState (Component c, GtkComponentPeer cp)
437: {
438:
439: if (c.getForeground () == null)
440: c.setForeground (cp.getForeground ());
441: if (c.getBackground () == null)
442: c.setBackground (cp.getBackground ());
443:
444:
445:
446:
447: if (! (c instanceof Window))
448: {
449: cp.setCursor (c.getCursor ());
450:
451: Rectangle bounds = c.getBounds ();
452: cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
453: cp.setVisible (c.isVisible ());
454: }
455: }
456:
457: protected ButtonPeer createButton (Button b)
458: {
459: checkHeadless();
460: return new GtkButtonPeer (b);
461: }
462:
463: protected CanvasPeer createCanvas (Canvas c)
464: {
465: checkHeadless();
466: return new GtkCanvasPeer (c);
467: }
468:
469: protected CheckboxPeer createCheckbox (Checkbox cb)
470: {
471: checkHeadless();
472: return new GtkCheckboxPeer (cb);
473: }
474:
475: protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)
476: {
477: checkHeadless();
478: return new GtkCheckboxMenuItemPeer (cmi);
479: }
480:
481: protected ChoicePeer createChoice (Choice c)
482: {
483: checkHeadless();
484: return new GtkChoicePeer (c);
485: }
486:
487: protected DialogPeer createDialog (Dialog d)
488: {
489: checkHeadless();
490: GtkMainThread.createWindow();
491: return new GtkDialogPeer (d);
492: }
493:
494: protected FileDialogPeer createFileDialog (FileDialog fd)
495: {
496: checkHeadless();
497: return new GtkFileDialogPeer (fd);
498: }
499:
500: protected FramePeer createFrame (Frame f)
501: {
502: checkHeadless();
503: GtkMainThread.createWindow();
504: return new GtkFramePeer (f);
505: }
506:
507: protected LabelPeer createLabel (Label label)
508: {
509: checkHeadless();
510: return new GtkLabelPeer (label);
511: }
512:
513: protected ListPeer createList (List list)
514: {
515: checkHeadless();
516: return new GtkListPeer (list);
517: }
518:
519: protected MenuPeer createMenu (Menu m)
520: {
521: checkHeadless();
522: return new GtkMenuPeer (m);
523: }
524:
525: protected MenuBarPeer createMenuBar (MenuBar mb)
526: {
527: checkHeadless();
528: return new GtkMenuBarPeer (mb);
529: }
530:
531: protected MenuItemPeer createMenuItem (MenuItem mi)
532: {
533: checkHeadless();
534: return new GtkMenuItemPeer (mi);
535: }
536:
537: protected PanelPeer createPanel (Panel p)
538: {
539: checkHeadless();
540: return new GtkPanelPeer (p);
541: }
542:
543: protected PopupMenuPeer createPopupMenu (PopupMenu target)
544: {
545: checkHeadless();
546: return new GtkPopupMenuPeer (target);
547: }
548:
549: protected ScrollPanePeer createScrollPane (ScrollPane sp)
550: {
551: checkHeadless();
552: return new GtkScrollPanePeer (sp);
553: }
554:
555: protected ScrollbarPeer createScrollbar (Scrollbar sb)
556: {
557: checkHeadless();
558: return new GtkScrollbarPeer (sb);
559: }
560:
561: protected TextAreaPeer createTextArea (TextArea ta)
562: {
563: checkHeadless();
564: return new GtkTextAreaPeer (ta);
565: }
566:
567: protected TextFieldPeer createTextField (TextField tf)
568: {
569: checkHeadless();
570: return new GtkTextFieldPeer (tf);
571: }
572:
573: protected WindowPeer createWindow (Window w)
574: {
575: checkHeadless();
576: GtkMainThread.createWindow();
577: return new GtkWindowPeer (w);
578: }
579:
580: public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
581: {
582: checkHeadless();
583: GtkMainThread.createWindow();
584: return new GtkEmbeddedWindowPeer (w);
585: }
586:
587:
591: protected FontPeer getFontPeer (String name, int style) {
592:
593: return getFontPeer(name, style, 12);
594: }
595:
596:
599: private FontPeer getFontPeer (String name, int style, int size)
600: {
601: Map<TextAttribute,Object> attrs = new HashMap<TextAttribute,Object>();
602: ClasspathFontPeer.copyStyleToAttrs (style, attrs);
603: ClasspathFontPeer.copySizeToAttrs (size, attrs);
604: return getClasspathFontPeer (name, attrs);
605: }
606:
607:
612:
613: public ClasspathFontPeer getClasspathFontPeer (String name,
614: Map<?,?> attrs)
615: {
616: Map<Object,Object> keyMap = new HashMap<Object,Object>(attrs);
617:
618:
619:
620:
621: keyMap.put ("GtkToolkit.RequestedFontName", name);
622: if (fontCache.containsKey (keyMap))
623: return fontCache.get (keyMap);
624: else
625: {
626: ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
627: fontCache.put (keyMap, newPeer);
628: return newPeer;
629: }
630: }
631:
632: protected EventQueue getSystemEventQueueImpl()
633: {
634: synchronized (GtkToolkit.class)
635: {
636: if (q == null)
637: {
638: q = new EventQueue();
639: }
640: }
641: return q;
642: }
643:
644: public Cursor createCustomCursor(Image image, Point hotspot, String name)
645: {
646: return new GtkCursor(image, hotspot, name);
647: }
648:
649: protected native void loadSystemColors (int[] systemColors);
650:
651: public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
652: {
653: if (GraphicsEnvironment.isHeadless())
654: throw new InvalidDnDOperationException();
655: return new GtkDragSourceContextPeer(e);
656: }
657:
658: public <T extends DragGestureRecognizer> T
659: createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
660: Component comp, int actions,
661: DragGestureListener l)
662: {
663: if (recognizer.getName().equals("java.awt.dnd.MouseDragGestureRecognizer")
664: && ! GraphicsEnvironment.isHeadless())
665: {
666: GtkMouseDragGestureRecognizer gestureRecognizer
667: = new GtkMouseDragGestureRecognizer(ds, comp, actions, l);
668: gestureRecognizer.registerListeners();
669: return recognizer.cast(gestureRecognizer);
670: }
671: else
672: {
673: return null;
674: }
675: }
676:
677: public Map<TextAttribute,?> mapInputMethodHighlight(InputMethodHighlight highlight)
678: {
679: throw new Error("not implemented");
680: }
681:
682: public Rectangle getBounds()
683: {
684: int[] dims = new int[2];
685: getScreenSizeDimensions(dims);
686: return new Rectangle(0, 0, dims[0], dims[1]);
687: }
688:
689:
690:
691: public GraphicsEnvironment getLocalGraphicsEnvironment()
692: {
693: return new GdkGraphicsEnvironment();
694: }
695:
696: public Font createFont(int format, InputStream stream)
697: {
698: throw new UnsupportedOperationException();
699: }
700:
701: public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
702: {
703: return new GdkRobotPeer (screen);
704: }
705:
706: public boolean getLockingKeyState(int keyCode)
707: {
708: int state = getLockState(keyCode);
709:
710: if (state != -1)
711: return state == 1;
712:
713: if (AWTUtilities.isValidKey(keyCode))
714: throw new UnsupportedOperationException
715: ("cannot get locking state of key code " + keyCode);
716:
717: throw new IllegalArgumentException("invalid key code " + keyCode);
718: }
719:
720: protected native int getLockState(int keyCode);
721:
722: public void registerImageIOSpis(IIORegistry reg)
723: {
724: GdkPixbufDecoder.registerSpis(reg);
725: }
726:
727: protected MouseInfoPeer getMouseInfoPeer()
728: {
729: return new GtkMouseInfoPeer();
730: }
731:
732: public boolean isFrameStateSupported(int state)
733: {
734:
735:
736: return state == Frame.NORMAL || state == Frame.ICONIFIED
737: || state == Frame.MAXIMIZED_BOTH;
738: }
739:
740: private void checkHeadless()
741: {
742: if (GraphicsEnvironment.isHeadless())
743: throw new HeadlessException();
744: }
745:
746: public native int getMouseNumberOfButtons();
747:
748: @Override
749: public boolean isModalExclusionTypeSupported
750: (Dialog.ModalExclusionType modalExclusionType)
751: {
752: return false;
753: }
754:
755: @Override
756: public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
757: {
758: return false;
759: }
760:
761: }