001: /*
002: * @(#)GToolkit.java 1.33 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.awt.gtk;
029:
030: import java.awt.*;
031: import sun.awt.peer.*;
032: import java.awt.image.*;
033: import java.net.*;
034: import java.util.Properties;
035: import java.awt.datatransfer.Clipboard;
036: import sun.awt.SunToolkit;
037: import sun.awt.im.*;
038: import sun.awt.AppContext;
039: import sun.awt.PeerBasedToolkit;
040: import sun.awt.image.BufferedImagePeer;
041:
042: public class GToolkit extends PeerBasedToolkit implements Runnable {
043: private static native void initIDs();
044:
045: private Clipboard systemClipboard;
046:
047: /** Runs the gtk_main function for event processing. */
048:
049: public native void run();
050:
051: static {
052: java.security.AccessController
053: .doPrivileged(new sun.security.action.LoadLibraryAction(
054: "gtkawt"));
055: initIDs();
056: }
057:
058: public GToolkit() {
059: // fix for 4705956 - need to initialize SunToolkit
060: super ();
061: systemClipboard = new GtkClipboard("system");
062: // Create a thread for processing main Gtk events.
063:
064: Thread mainThread = new Thread(this , "AWT-Gtk");
065: mainThread.setDaemon(false); // Don't exit when main finishes.
066: mainThread.start();
067:
068: // Create a thread to flush drawing events to the server
069:
070: FlushThread flushThread = new FlushThread(this );
071:
072: Runtime.getRuntime().addShutdownHook(
073: new ShutdownHook(mainThread, flushThread));
074: }
075:
076: static native BufferedImagePeer getBufferedImagePeer(
077: BufferedImage image);
078:
079: static native BufferedImage createBufferedImage(
080: BufferedImagePeer peer);
081:
082: /*
083: * Gets the default encoding used on the current platform
084: * to transfer text (character) data.
085: */
086: public String getDefaultCharacterEncoding() {
087: return "iso8859-1";
088: }
089:
090: /**
091: * Creates this toolkit's implementation of <code>Button</code> using
092: * the specified peer interface.
093: * @param target the button to be implemented.
094: * @return this toolkit's implementation of <code>Button</code>.
095: * @see java.awt.Button
096: * @see sun.awt.peer.ButtonPeer
097: * @since JDK1.0
098: */
099: public ButtonPeer createButton(Button target) {
100: return new GButtonPeer(this , target);
101: }
102:
103: /**
104: * Creates this toolkit's implementation of <code>TextField</code> using
105: * the specified peer interface.
106: * @param target the text field to be implemented.
107: * @return this toolkit's implementation of <code>TextField</code>.
108: * @see java.awt.TextField
109: * @see sun.awt.peer.TextFieldPeer
110: * @since JDK1.0
111: */
112: public TextFieldPeer createTextField(TextField target) {
113: return new GTextFieldPeer(this , target);
114: }
115:
116: /**
117: * Creates this toolkit's implementation of <code>Label</code> using
118: * the specified peer interface.
119: * @param target the label to be implemented.
120: * @return this toolkit's implementation of <code>Label</code>.
121: * @see java.awt.Label
122: * @see sun.awt.peer.LabelPeer
123: * @since JDK1.0
124: */
125: public LabelPeer createLabel(Label target) {
126: return new GLabelPeer(this , target);
127: }
128:
129: /**
130: * Creates this toolkit's implementation of <code>List</code> using
131: * the specified peer interface.
132: * @param target the list to be implemented.
133: * @return this toolkit's implementation of <code>List</code>.
134: * @see java.awt.List
135: * @see sun.awt.peer.ListPeer
136: * @since JDK1.0
137: */
138: public ListPeer createList(List target) {
139: return new GListPeer(this , target);
140: }
141:
142: /**
143: * Creates this toolkit's implementation of <code>Checkbox</code> using
144: * the specified peer interface.
145: * @param target the check box to be implemented.
146: * @return this toolkit's implementation of <code>Checkbox</code>.
147: * @see java.awt.Checkbox
148: * @see sun.awt.peer.CheckboxPeer
149: * @since JDK1.0
150: */
151: public CheckboxPeer createCheckbox(Checkbox target) {
152: return new GCheckboxPeer(this , target);
153: }
154:
155: /**
156: * Creates this toolkit's implementation of <code>Scrollbar</code> using
157: * the specified peer interface.
158: * @param target the scroll bar to be implemented.
159: * @return this toolkit's implementation of <code>Scrollbar</code>.
160: * @see java.awt.Scrollbar
161: * @see sun.awt.peer.ScrollbarPeer
162: * @since JDK1.0
163: */
164: public ScrollbarPeer createScrollbar(Scrollbar target) {
165: return new GScrollbarPeer(this , target);
166: }
167:
168: /**
169: * Creates this toolkit's implementation of <code>ScrollPane</code> using
170: * the specified peer interface.
171: * @param target the scroll pane to be implemented.
172: * @return this toolkit's implementation of <code>ScrollPane</code>.
173: * @see java.awt.ScrollPane
174: * @see sun.awt.peer.ScrollPanePeer
175: * @since JDK1.1
176: */
177: public ScrollPanePeer createScrollPane(ScrollPane target) {
178: return new GScrollPanePeer(this , target);
179: }
180:
181: /**
182: * Creates this toolkit's implementation of <code>TextArea</code> using
183: * the specified peer interface.
184: * @param target the text area to be implemented.
185: * @return this toolkit's implementation of <code>TextArea</code>.
186: * @see java.awt.TextArea
187: * @see sun.awt.peer.TextAreaPeer
188: * @since JDK1.0
189: */
190: public TextAreaPeer createTextArea(TextArea target) {
191: return new GTextAreaPeer(this , target);
192: }
193:
194: /**
195: * Creates this toolkit's implementation of <code>Choice</code> using
196: * the specified peer interface.
197: * @param target the choice to be implemented.
198: * @return this toolkit's implementation of <code>Choice</code>.
199: * @see java.awt.Choice
200: * @see sun.awt.peer.ChoicePeer
201: * @since JDK1.0
202: */
203: public ChoicePeer createChoice(Choice target) {
204: return new GChoicePeer(this , target);
205: }
206:
207: /**
208: * Creates this toolkit's implementation of <code>Frame</code> using
209: * the specified peer interface.
210: * @param target the frame to be implemented.
211: * @return this toolkit's implementation of <code>Frame</code>.
212: * @see java.awt.Frame
213: * @see sun.awt.peer.FramePeer
214: * @since JDK1.0
215: */
216: public FramePeer createFrame(Frame target) {
217: return new GFramePeer(this , target);
218: }
219:
220: /**
221: * Creates this toolkit's implementation of <code>Canvas</code> using
222: * the specified peer interface.
223: * @param target the canvas to be implemented.
224: * @return this toolkit's implementation of <code>Canvas</code>.
225: * @see java.awt.Canvas
226: * @see sun.awt.peer.CanvasPeer
227: * @since JDK1.0
228: */
229: public CanvasPeer createCanvas(Canvas target) {
230: return new GCanvasPeer(this , target);
231: }
232:
233: /**
234: * Creates this toolkit's implementation of <code>Panel</code> using
235: * the specified peer interface.
236: * @param target the panel to be implemented.
237: * @return this toolkit's implementation of <code>Panel</code>.
238: * @see java.awt.Panel
239: * @see sun.awt.peer.PanelPeer
240: * @since JDK1.0
241: */
242: public PanelPeer createPanel(Panel target) {
243: return new GPanelPeer(this , target);
244: }
245:
246: /**
247: * Creates this toolkit's implementation of <code>Window</code> using
248: * the specified peer interface.
249: * @param target the window to be implemented.
250: * @return this toolkit's implementation of <code>Window</code>.
251: * @see java.awt.Window
252: * @see sun.awt.peer.WindowPeer
253: * @since JDK1.0
254: */
255: public WindowPeer createWindow(Window target) {
256: return new GWindowPeer(this , target);
257: }
258:
259: /**
260: * Creates this toolkit's implementation of <code>Dialog</code> using
261: * the specified peer interface.
262: * @param target the dialog to be implemented.
263: * @return this toolkit's implementation of <code>Dialog</code>.
264: * @see java.awt.Dialog
265: * @see sun.awt.peer.DialogPeer
266: * @since JDK1.0
267: */
268: public DialogPeer createDialog(Dialog target) {
269: return new GDialogPeer(this , target);
270: }
271:
272: /**
273: * Creates this toolkit's implementation of <code>MenuBar</code> using
274: * the specified peer interface.
275: * @param target the menu bar to be implemented.
276: * @return this toolkit's implementation of <code>MenuBar</code>.
277: * @see java.awt.MenuBar
278: * @see sun.awt.peer.MenuBarPeer
279: * @since JDK1.0
280: */
281: public MenuBarPeer createMenuBar(MenuBar target) {
282: return new GMenuBarPeer(target);
283: }
284:
285: /**
286: * Creates this toolkit's implementation of <code>Menu</code> using
287: * the specified peer interface.
288: * @param target the menu to be implemented.
289: * @return this toolkit's implementation of <code>Menu</code>.
290: * @see java.awt.Menu
291: * @see sun.awt.peer.MenuPeer
292: * @since JDK1.0
293: */
294: public MenuPeer createMenu(Menu target) {
295: return new GMenuPeer(target);
296: }
297:
298: /**
299: * Creates this toolkit's implementation of <code>PopupMenu</code> using
300: * the specified peer interface.
301: * @param target the popup menu to be implemented.
302: * @return this toolkit's implementation of <code>PopupMenu</code>.
303: * @see java.awt.PopupMenu
304: * @see sun.awt.peer.PopupMenuPeer
305: * @since JDK1.1
306: */
307: public PopupMenuPeer createPopupMenu(PopupMenu target) {
308: return new GPopupMenuPeer(target);
309: }
310:
311: /**
312: * Creates this toolkit's implementation of <code>MenuItem</code> using
313: * the specified peer interface.
314: * @param target the menu item to be implemented.
315: * @return this toolkit's implementation of <code>MenuItem</code>.
316: * @see java.awt.MenuItem
317: * @see sun.awt.peer.MenuItemPeer
318: * @since JDK1.0
319: */
320: public MenuItemPeer createMenuItem(MenuItem target) {
321: return new GMenuItemPeer(target);
322: }
323:
324: /**
325: * Creates this toolkit's implementation of <code>FileDialog</code> using
326: * the specified peer interface.
327: * @param target the file dialog to be implemented.
328: * @return this toolkit's implementation of <code>FileDialog</code>.
329: * @see java.awt.FileDialog
330: * @see sun.awt.peer.FileDialogPeer
331: * @since JDK1.0
332: */
333: public FileDialogPeer createFileDialog(FileDialog target) {
334: return new GFileDialogPeer(this , target);
335: }
336:
337: /**
338: * Creates this toolkit's implementation of <code>CheckboxMenuItem</code> using
339: * the specified peer interface.
340: * @param target the checkbox menu item to be implemented.
341: * @return this toolkit's implementation of <code>CheckboxMenuItem</code>.
342: * @see java.awt.CheckboxMenuItem
343: * @see sun.awt.peer.CheckboxMenuItemPeer
344: * @since JDK1.0
345: */
346: public CheckboxMenuItemPeer createCheckboxMenuItem(
347: CheckboxMenuItem target) {
348: return new GCheckboxMenuItemPeer(target);
349: }
350:
351: /**
352: * Creates this toolkit's implementation of <code>Font</code> using
353: * the specified peer interface.
354: * @param target the font to be implemented.
355: * @return this toolkit's implementation of <code>Font</code>.
356: * @see java.awt.Font
357: * @see sun.awt.peer.FontPeer
358: * @since JDK1.0
359: */
360: public FontPeer getFontPeer(Font target) {
361: return GFontPeer.getFontPeer(target);
362: }
363:
364: /**
365: * Fills in the integer array that is supplied as an argument
366: * with the current system color values.
367: * <p>
368: * This method is called by the method <code>updateSystemColors</code>
369: * in the <code>SystemColor</code> class.
370: * @param an integer array.
371: * @see java.awt.SystemColor#updateSystemColors
372: * @since JDK1.1
373: */
374: protected void loadSystemColors(int[] systemColors) {
375: }
376:
377: public native int getScreenWidth();
378:
379: public native int getScreenHeight();
380:
381: /**
382: * Returns the screen resolution in dots-per-inch.
383: * @return this toolkit's screen resolution, in dots-per-inch.
384: * @since JDK1.0
385: */
386: public int getScreenResolution() {
387: return 72;
388: }
389:
390: /**
391: * Determines the color model of this toolkit's screen.
392: * <p>
393: * <code>ColorModel</code> is an abstract class that
394: * encapsulates the ability to translate between the
395: * pixel values of an image and its red, green, blue,
396: * and alpha components.
397: * <p>
398: * This toolkit method is called by the
399: * <code>getColorModel</code> method
400: * of the <code>Component</code> class.
401: * @return the color model of this toolkit's screen.
402: * @see java.awt.image.ColorModel
403: * @see java.awt.Component#getColorModel
404: * @since JDK1.0
405: */
406: public native ColorModel getColorModel();
407:
408: /**
409: * Gets the screen metrics of the font.
410: * @param font a font.
411: * @return the screen metrics of the specified font in this toolkit.
412: * @since JDK1.0
413: */
414: public FontMetrics getFontMetrics(Font font) {
415: return (FontMetrics) this .getFontPeer(font);
416: }
417:
418: /**
419: * Synchronizes this toolkit's graphics state. Some window systems
420: * may do buffering of graphics events.
421: * <p>
422: * This method ensures that the display is up-to-date. It is useful
423: * for animation.
424: * @since JDK1.0
425: */
426: public native void sync();
427:
428: /**
429: * Prepares an image for rendering.
430: * <p>
431: * If the values of the width and height arguments are both
432: * <code>-1</code>, this method prepares the image for rendering
433: * on the default screen; otherwise, this method prepares an image
434: * for rendering on the default screen at the specified width and height.
435: * <p>
436: * The image data is downloaded asynchronously in another thread,
437: * and an appropriately scaled screen representation of the image is
438: * generated.
439: * <p>
440: * This method is called by components <code>prepareImage</code>
441: * methods.
442: * <p>
443: * Information on the flags returned by this method can be found
444: * with the definition of the <code>ImageObserver</code> interface.
445:
446: * @param image the image for which to prepare a
447: * screen representation.
448: * @param width the width of the desired screen
449: * representation, or <code>-1</code>.
450: * @param height the height of the desired screen
451: * representation, or <code>-1</code>.
452: * @param observer the <code>ImageObserver</code>
453: * object to be notified as the
454: * image is being prepared.
455: * @return <code>true</code> if the image has already been
456: * fully prepared; <code>false</code> otherwise.
457: * @see java.awt.Component#prepareImage(java.awt.Image,
458: * java.awt.image.ImageObserver)
459: * @see java.awt.Component#prepareImage(java.awt.Image,
460: * int, int, java.awt.image.ImageObserver)
461: * @see java.awt.image.ImageObserver
462: * @since JDK1.0
463: */
464: static boolean prepareScrImage(Image img, int w, int h,
465: ImageObserver o) {
466: if (w == 0 || h == 0) {
467: return true;
468: }
469: if (!(img instanceof GdkImage)) {
470: return false;
471: }
472: GdkImage ximg = (GdkImage) img;
473: if (ximg.hasError()) {
474: if (o != null) {
475: o.imageUpdate(img, ImageObserver.ERROR
476: | ImageObserver.ABORT, -1, -1, -1, -1);
477: }
478: return false;
479: }
480: sun.awt.image.ImageRepresentation ir = ximg.getImageRep();
481: return ir.prepare(o);
482: }
483:
484: static int checkScrImage(Image img, int w, int h, ImageObserver o) {
485: if (!(img instanceof GdkImage)) {
486: return ImageObserver.ALLBITS;
487: }
488: GdkImage ximg = (GdkImage) img;
489: int repbits;
490: if (w == 0 || h == 0) {
491: repbits = ImageObserver.ALLBITS;
492: } else {
493: repbits = ximg.getImageRep().check(o);
494: }
495: return ximg.check(o) | repbits;
496: }
497:
498: public boolean prepareImage(Image img, int w, int h, ImageObserver o) {
499: return prepareScrImage(img, w, h, o);
500: }
501:
502: /**
503: * Indicates the construction status of a specified image that is
504: * being prepared for display.
505: * <p>
506: * If the values of the width and height arguments are both
507: * <code>-1</code>, this method returns the construction status of
508: * a screen representation of the specified image in this toolkit.
509: * Otherwise, this method returns the construction status of a
510: * scaled representation of the image at the specified width
511: * and height.
512: * <p>
513: * This method does not cause the image to begin loading.
514: * An application must call <code>prepareImage</code> to force
515: * the loading of an image.
516: * <p>
517: * This method is called by the component's <code>checkImage</code>
518: * methods.
519: * <p>
520: * Information on the flags returned by this method can be found
521: * with the definition of the <code>ImageObserver</code> interface.
522: * @param image the image whose status is being checked.
523: * @param width the width of the scaled version whose status is
524: * being checked, or <code>-1</code>.
525: * @param height the height of the scaled version whose status
526: * is being checked, or <code>-1</code>.
527: * @param observer the <code>ImageObserver</code> object to be
528: * notified as the image is being prepared.
529: * @return the bitwise inclusive <strong>OR</strong> of the
530: * <code>ImageObserver</code> flags for the
531: * image data that is currently available.
532: * @see java.awt.Toolkit#prepareImage(java.awt.Image,
533: * int, int, java.awt.image.ImageObserver)
534: * @see java.awt.Component#checkImage(java.awt.Image,
535: * java.awt.image.ImageObserver)
536: * @see java.awt.Component#checkImage(java.awt.Image,
537: * int, int, java.awt.image.ImageObserver)
538: * @see java.awt.image.ImageObserver
539: * @since JDK1.0
540: */
541: public int checkImage(Image img, int w, int h, ImageObserver o) {
542: return checkScrImage(img, w, h, o);
543: }
544:
545: /**
546: * Creates an image with the specified image producer.
547: * @param producer the image producer to be used.
548: * @return an image with the specified image producer.
549: * @see java.awt.Image
550: * @see java.awt.image.ImageProducer
551: * @see java.awt.Component#createImage(java.awt.image.ImageProducer)
552: * @since JDK1.0
553: */
554: public Image createImage(ImageProducer producer) {
555: return new GdkImage(producer);
556: }
557:
558: /**
559: * Gets a <code>PrintJob</code> object which is the result
560: * of initiating a print operation on the toolkit's platform.
561: * @return a <code>PrintJob</code> object, or
562: * <code>null</code> if the user
563: * cancelled the print job.
564: * @see java.awt.PrintJob
565: * @since JDK1.1
566: */
567: // public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) {throw new UnsupportedOperationException ();}
568: /**
569: * Emits an audio beep.
570: * @since JDK1.1
571: */
572: public native void beep();
573:
574: public static void postEvent(AWTEvent event) {
575: // Note that this might cause some problem in the future.
576: // In jdk's MToolkit, targetToAppContext() is called at a peer level
577: // with the peer's target as an argument. AWTEvent's source is not
578: // always the same as the peer's target.
579:
580: postEvent(targetToAppContext(event.getSource()), event);
581: }
582:
583: public static void postEvent(AppContext appContext, AWTEvent event) {
584: if (appContext == null) {
585: appContext = AppContext.getAppContext();
586: }
587: EventQueue theEventQueue = (EventQueue) appContext
588: .get(AppContext.EVENT_QUEUE_KEY);
589: theEventQueue.postEvent(event);
590: Thread.yield();
591: }
592:
593: /**
594: * Gets an instance of the system clipboard which interfaces
595: * with clipboard facilities provided by the native platform.
596: * <p>
597: * This clipboard enables data transfer between Java programs
598: * and native applications which use native clipboard facilities.
599: * @return an instance of the system clipboard.
600: * @see java.awt.datatransfer.Clipboard
601: * @since JDK1.1
602: */
603: public Clipboard getSystemClipboard() {
604: SecurityManager security = System.getSecurityManager();
605: if (security != null) {
606: security.checkSystemClipboardAccess();
607: }
608: return systemClipboard;
609: }
610:
611: /**
612: * Returns a new input method adapter for native input methods.
613: */
614: public InputMethod getInputMethodAdapter() throws AWTException {
615: throw new UnsupportedOperationException();
616: }
617: }
618:
619: /** A thread which periodically flushes any drawing calls to the server. */
620:
621: class FlushThread extends Thread {
622: public FlushThread(Toolkit toolkit) {
623: this .toolkit = toolkit;
624: start();
625: }
626:
627: public void run() {
628: while (!isInterrupted()) {
629: try {
630: Thread.sleep(100);
631: } catch (InterruptedException e) {
632: }
633:
634: toolkit.sync();
635: }
636: }
637:
638: private Toolkit toolkit;
639: }
640:
641: /** The thread which is run when the system is shutting down. */
642:
643: class ShutdownHook extends Thread {
644: public ShutdownHook(Thread mainThread, FlushThread flushThread) {
645: this .mainThread = mainThread;
646: this .flushThread = flushThread;
647: }
648:
649: public void run() {
650: // Ask the flush thread to finish
651:
652: flushThread.interrupt();
653:
654: // Ask the main gtk event processing thread to finish
655:
656: gtkMainQuit();
657:
658: // Wait for both threads to complete
659:
660: try {
661: mainThread.join(2000);
662: flushThread.join(2000);
663: } catch (InterruptedException e) {
664: }
665: }
666:
667: private native void gtkMainQuit();
668:
669: private Thread mainThread;
670: private FlushThread flushThread;
671: }
|