1 /* Copyright (C) 2000, 2002, 2003, 2005  Free Software Foundation
2 
3    This file is part of libgcj.
4 
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8 
9 package gnu.awt.xlib;
10 
11 import java.awt.*;
12 import java.awt.dnd.*;
13 import java.awt.dnd.peer.*;
14 import java.awt.font.*;
15 import java.awt.im.*;
16 import java.awt.peer.*;
17 import java.awt.image.ImageProducer;
18 import java.awt.image.ImageObserver;
19 import java.net.*;
20 import java.awt.datatransfer.Clipboard;
21 import java.io.InputStream;
22 import java.text.AttributedString;
23 import java.util.Map;
24 import java.util.Properties;
25 import gnu.gcj.xlib.Display;
26 import gnu.gcj.xlib.Screen;
27 import gnu.gcj.xlib.Visual;
28 import gnu.java.awt.ClasspathToolkit;
29 import gnu.java.awt.EmbeddedWindow;
30 import gnu.java.awt.peer.ClasspathFontPeer;
31 import gnu.java.awt.peer.EmbeddedWindowPeer;
32 
33 public class XToolkit extends ClasspathToolkit
34 {
35   static XToolkit INSTANCE;
36 
37   Display display;
38 
39   EventQueue queue;
40   XEventLoop eventLoop;
41 
42   XGraphicsConfiguration defaultConfig;
43 
XToolkit()44   public XToolkit()
45   {
46     INSTANCE = this;
47     display = new Display();
48     synchronized (display)
49       {
50 	queue = new XEventQueue(display);
51 	eventLoop = new XEventLoop(display, queue);
52       }
53   }
54 
flushIfIdle()55   public void flushIfIdle()
56   {
57     eventLoop.flushIfIdle();
58   }
59 
createButton(Button frontend)60   protected ButtonPeer createButton(Button frontend)
61   {
62     // FIXME: Stubbed out, needs Swing:
63     /*
64     XCanvasPeer realPeer = new XCanvasPeer(frontend);
65     SButtonPeer sbPeer = new SButtonPeer(frontend, realPeer);
66     return sbPeer;
67     */
68     return null;
69   }
70 
createTextField(TextField frontend)71   protected TextFieldPeer createTextField(TextField frontend)
72   {
73     return null; // FIXME
74   }
75 
createLabel(Label frontend)76   protected LabelPeer createLabel(Label frontend)
77   {
78     return null; // FIXME
79   }
80 
createList(List frontend)81   protected ListPeer createList(List frontend)
82   {
83     return null; // FIXME
84   }
85 
createCheckbox(Checkbox frontend)86   protected CheckboxPeer createCheckbox(Checkbox frontend)
87   {
88     return null; // FIXME
89   }
90 
createScrollbar(Scrollbar frontend)91   protected ScrollbarPeer createScrollbar(Scrollbar frontend)
92   {
93     return null; // FIXME
94   }
95 
createScrollPane(ScrollPane frontend)96   protected ScrollPanePeer createScrollPane(ScrollPane frontend)
97   {
98     return null; // FIXME
99   }
100 
createTextArea(TextArea frontend)101   protected TextAreaPeer createTextArea(TextArea frontend)
102   {
103     return null; // FIXME
104   }
105 
createChoice(Choice frontend)106   protected ChoicePeer createChoice(Choice frontend)
107   {
108     return null; // FIXME
109   }
110 
createFrame(Frame frontend)111   protected FramePeer createFrame(Frame frontend) {
112     return new XFramePeer(frontend);
113   }
114 
createCanvas(Canvas frontend)115   protected CanvasPeer createCanvas(Canvas frontend) {
116     XCanvasPeer peer = new XCanvasPeer(frontend);
117     return peer;
118   }
119 
createPanel(Panel frontend)120   protected PanelPeer createPanel(Panel frontend) {
121     return new XPanelPeer(frontend);
122   }
123 
createWindow(Window frontend)124   protected WindowPeer createWindow(Window frontend)
125   {
126     return null; // FIXME
127   }
128 
createDialog(Dialog frontend)129   protected DialogPeer createDialog(Dialog frontend)
130   {
131     return null; // FIXME
132   }
133 
createMenuBar(MenuBar frontend)134   protected MenuBarPeer createMenuBar(MenuBar frontend)
135   {
136     return null; // FIXME
137   }
138 
createMenu(Menu frontend)139   protected MenuPeer createMenu(Menu frontend)
140   {
141     return null; // FIXME
142   }
143 
createPopupMenu(PopupMenu frontend)144   protected PopupMenuPeer createPopupMenu(PopupMenu frontend)
145   {
146     return null; // FIXME
147   }
148 
createMenuItem(MenuItem frontend)149   protected MenuItemPeer createMenuItem(MenuItem frontend)
150   {
151     return null; // FIXME
152   }
153 
createFileDialog(FileDialog frontend)154   protected FileDialogPeer createFileDialog(FileDialog frontend)
155   {
156     return null; // FIXME
157   }
158 
159   protected CheckboxMenuItemPeer
createCheckboxMenuItem(CheckboxMenuItem frontend)160       createCheckboxMenuItem(CheckboxMenuItem frontend)
161   {
162     return null; // FIXME
163   }
164 
getFontPeer(String name, int style)165   protected java.awt.peer.FontPeer getFontPeer(String name, int style)
166   {
167     return new XFontPeer (name,style);
168   }
169 
getScreenSize()170   public Dimension getScreenSize()
171   {
172     throw new UnsupportedOperationException("not implemented yet");
173   }
174 
getScreenResolution()175   public int getScreenResolution()
176   {
177     throw new UnsupportedOperationException("not implemented yet");
178   }
179 
getColorModel()180   public java.awt.image.ColorModel getColorModel()
181   {
182     return getDefaultXGraphicsConfiguration().getColorModel();
183   }
184 
getFontList()185   public String[] getFontList()
186   {
187     throw new UnsupportedOperationException("not implemented yet");
188   }
189 
getFontMetrics(Font font)190   public FontMetrics getFontMetrics(Font font)
191   {
192     return getDefaultXGraphicsConfiguration().getXFontMetrics(font);
193   }
194 
sync()195   public void sync()
196   {
197     flushIfIdle ();
198     // FIXME: should instead wait for eventLoop to go idle
199     // (perhaps send a dummy event there and block till it makes
200     // it through the queue)
201   }
202 
getImage(String filename)203   public Image getImage(String filename)
204   {
205     return createImage(filename);
206   }
207 
getImage(URL url)208   public Image getImage(URL url)
209   {
210     throw new UnsupportedOperationException("not implemented yet");
211   }
212 
createImage(String filename)213   public Image createImage(String filename)
214   {
215     // FIXME: Stubbed out. We need a proper image I/O API.
216 
217     /*
218     BufferedImage jpeg;
219     FileInputStream fis = openFile(filename);
220     if (fis == null)
221       return null;
222 
223     BasicRasterImageConsumer consumer = new BasicRasterImageConsumer();
224     JPEGImageDecoder jid = new JPEGImageDecoder(fis);
225 
226     jid.startProduction(consumer);
227     jpeg = consumer.getImage();
228 
229     int w = jpeg.getWidth();
230     int h = jpeg.getHeight();
231 
232     BufferedImage img =
233       getDefaultXGraphicsConfiguration().createCompatibleImage(w, h);
234 
235     Renderers renderers = Renderers.getInstance();
236 
237     RasterOp renderer = renderers.createRenderer(jpeg.getColorModel(),
238 						 jpeg.getSampleModel(),
239 						 img.getColorModel(),
240 						 img.getSampleModel());
241 
242     if (renderer == null)
243       {
244 	throw new UnsupportedOperationException("couldn't find renderer");
245       }
246 
247     renderer.filter(jpeg.getRaster(), img.getRaster());
248 
249     return img;
250     */
251 
252     return null;
253   }
254 
createImage(URL url)255   public Image createImage(URL url)
256   {
257     throw new UnsupportedOperationException("not implemented yet");
258   }
259 
prepareImage(Image image, int width, int height, ImageObserver observer)260   public boolean prepareImage(Image image,
261 			      int width,
262 			      int height,
263 			      ImageObserver observer)
264   {
265     throw new UnsupportedOperationException("not implemented yet");
266   }
267 
checkImage(Image image, int width, int height, ImageObserver observer)268   public int checkImage(Image image,
269 			int width,
270 			int height,
271 			ImageObserver observer)
272   {
273     throw new UnsupportedOperationException("not implemented yet");
274   }
275 
createImage(ImageProducer producer)276   public Image createImage(ImageProducer producer)
277   {
278     throw new UnsupportedOperationException("not implemented yet");
279   }
280 
createImage(byte[] imagedata, int imageoffset, int imagelength)281   public Image createImage(byte[] imagedata,
282 			   int imageoffset,
283 			   int imagelength)
284   {
285     throw new UnsupportedOperationException("not implemented yet");
286   }
287 
288   /*
289     public PrintJob getPrintJob(Frame frame,
290 				String jobtitle,
291 				Properties props);
292   */
293 
beep()294   public void beep()
295   {
296     throw new UnsupportedOperationException("not implemented yet");
297   }
298 
getSystemClipboard()299   public Clipboard getSystemClipboard()
300   {
301     return null; // FIXME
302   }
303 
getSystemEventQueueImpl()304   protected EventQueue getSystemEventQueueImpl()
305   {
306     return queue;
307   }
308 
getPrintJob(Frame frame, String title, Properties props)309   public PrintJob getPrintJob (Frame frame, String title, Properties props)
310   {
311     return null;		// FIXME
312   }
313 
getDefaultXGraphicsConfiguration()314   XGraphicsConfiguration getDefaultXGraphicsConfiguration()
315   {
316     if (defaultConfig == null)
317       {
318 	Screen screen = display.getDefaultScreen();
319 	Visual visual = screen.getRootVisual();
320 	defaultConfig = new XGraphicsConfiguration(visual);
321 
322 	// ASSERT:
323 	if (!defaultConfig.getVisual().getScreen().equals(screen))
324 	  {
325 	    String msg = "screen of graphics configuration is not " +
326 	      "default screen";
327 	    throw new Error(msg);
328 	  }
329       }
330 
331     return defaultConfig;
332   }
333 
334   public DragSourceContextPeer
createDragSourceContextPeer(DragGestureEvent dge)335     createDragSourceContextPeer(DragGestureEvent dge)
336     throws InvalidDnDOperationException
337   {
338     throw new UnsupportedOperationException("not implemented");
339   }
340 
341   public DragGestureRecognizer
createDragGestureRecognizer(Class abstractRecognizerClass, DragSource ds, Component c, int srcActions, DragGestureListener dgl)342     createDragGestureRecognizer(Class abstractRecognizerClass,
343 				DragSource ds, Component c,
344 				int srcActions, DragGestureListener dgl)
345   {
346     throw new UnsupportedOperationException("not implemented");
347   }
348 
349 
mapInputMethodHighlight(InputMethodHighlight highlight)350   public Map mapInputMethodHighlight(InputMethodHighlight highlight)
351   {
352     throw new UnsupportedOperationException("not implemented");
353   }
354 
355   /** Returns a shared instance of the local, platform-specific
356    * graphics environment.
357    *
358    * <p>This method is specific to GNU Classpath. It gets called by
359    * the Classpath implementation of {@link
360    * GraphicsEnvironment.getLocalGraphcisEnvironment()}.
361    */
getLocalGraphicsEnvironment()362   public GraphicsEnvironment getLocalGraphicsEnvironment ()
363   {
364     return new XGraphicsEnvironment (this);
365   }
366 
367   /** Acquires an appropriate {@link ClasspathFontPeer}, for use in
368    * classpath's implementation of {@link java.awt.Font}.
369    *
370    * @param name The logical name of the font. This may be either a face
371    * name or a logical font name, or may even be null. A default
372    * implementation of name decoding is provided in
373    * {@link ClasspathFontPeer}, but may be overridden in other toolkits.
374    *
375    * @param attrs Any extra {@link java.awt.font.TextAttribute} attributes
376    * this font peer should have, such as size, weight, family name, or
377    * transformation.
378    */
getClasspathFontPeer(String name, Map attrs)379   public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
380   {
381     int style = Font.PLAIN;
382     float size = 12;
383 
384     if (attrs.containsKey (TextAttribute.WEIGHT))
385       {
386         Float weight = (Float) attrs.get (TextAttribute.WEIGHT);
387         if (weight.floatValue () >= TextAttribute.WEIGHT_BOLD.floatValue ())
388           style += Font.BOLD;
389       }
390 
391     if (attrs.containsKey (TextAttribute.POSTURE))
392       {
393         Float posture = (Float) attrs.get (TextAttribute.POSTURE);
394         if (posture.floatValue () >= TextAttribute.POSTURE_OBLIQUE.floatValue ())
395           style += Font.ITALIC;
396       }
397 
398     if (attrs.containsKey (TextAttribute.SIZE))
399       {
400         Float fsize = (Float) attrs.get (TextAttribute.SIZE);
401         size = fsize.floatValue ();
402       }
403 
404     return new XFontPeer (name,style,size);
405   }
406 
407   /** Creates a font, reading the glyph definitions from a stream.
408    *
409    * <p>This method provides the platform-specific implementation for
410    * the static factory method {@link Font#createFont(int,
411    * java.io.InputStream)}.
412    *
413    * @param format the format of the font data, such as {@link
414    * Font#TRUETYPE_FONT}. An implementation may ignore this argument
415    * if it is able to automatically recognize the font format from the
416    * provided data.
417    *
418    * @param stream an input stream from where the font data is read
419    * in. The stream will be advanced to the position after the font
420    * data, but not closed.
421    *
422    * @throws IllegalArgumentException if <code>format</code> is
423    * not supported.
424    *
425    * @throws FontFormatException if <code>stream</code> does not
426    * contain data in the expected format, or if required tables are
427    * missing from a font.
428    *
429    * @throws IOException if a problem occurs while reading in the
430    * contents of <code>stream</code>.
431    */
createFont(int format, InputStream stream)432   public Font createFont (int format, InputStream stream)
433   {
434     throw new java.lang.UnsupportedOperationException ();
435   }
436 
createRobot(GraphicsDevice screen)437   public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
438   {
439     throw new java.lang.UnsupportedOperationException ();
440   }
441 
createEmbeddedWindow(EmbeddedWindow w)442   public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
443   {
444     throw new java.lang.UnsupportedOperationException ();
445   }
446 
nativeQueueEmpty()447   public boolean nativeQueueEmpty()
448   {
449     // Tell EventQueue the native queue is empty, because XEventLoop
450     // separately ensures that native events are posted to AWT.
451     return true;
452   }
453 
wakeNativeQueue()454   public void wakeNativeQueue()
455   {
456     // Not implemented, because the native queue is always awake.
457     // (i.e. it's polled in a thread separate from the AWT dispatch thread)
458   }
459 
460   /** Checks the native event queue for events.  If blocking, waits until an
461    * event is available before returning, unless interrupted by
462    * wakeNativeQueue.  If non-blocking, returns immediately even if no
463    * event is available.
464    *
465    * @param locked The calling EventQueue
466    * @param block If true, waits for a native event before returning
467    */
iterateNativeQueue(java.awt.EventQueue locked, boolean block)468   public void iterateNativeQueue(java.awt.EventQueue locked, boolean block)
469   {
470     // There is nothing to do here except block, because XEventLoop
471     // iterates the queue in a dedicated thread.
472     if (block)
473     {
474       try
475       {
476         queue.wait ();
477       }
478       catch (InterruptedException ie)
479       {
480         // InterruptedException intentionally ignored
481       }
482     }
483   }
484 
setAlwaysOnTop(boolean b)485   public void setAlwaysOnTop(boolean b)
486   {
487     // TODO: Implement properly.
488   }
489 
isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType)490   public boolean isModalExclusionTypeSupported
491     (Dialog.ModalExclusionType modalExclusionType)
492   {
493     // TODO: Implement properly.
494     return false;
495   }
496 
isModalityTypeSupported(Dialog.ModalityType modalityType)497   public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
498   {
499     // TODO: Implement properly.
500     return false;
501   }
502 }
503