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