Source for gnu.awt.xlib.XToolkit

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