Source Code Cross Referenced for XSelection.java in  » 6.0-JDK-Platform » solaris » sun » awt » X11 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Platform » solaris » sun.awt.X11 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.awt.X11;
027:
028:        import java.awt.datatransfer.Transferable;
029:
030:        import java.io.ByteArrayOutputStream;
031:        import java.io.IOException;
032:
033:        import java.util.Hashtable;
034:        import java.util.Map;
035:        import java.util.Set;
036:        import java.util.HashSet;
037:        import java.util.Collections;
038:
039:        import sun.awt.AppContext;
040:        import sun.awt.SunToolkit;
041:        import sun.awt.UNIXToolkit;
042:
043:        import sun.awt.datatransfer.DataTransferer;
044:
045:        /**
046:         * A class which interfaces with the X11 selection service.
047:         */
048:        public class XSelection {
049:
050:            /* Maps atoms to XSelection instances. */
051:            private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
052:            /* Prevents from parallel selection data request processing. */
053:            private static final Object lock = new Object();
054:            /* The property in which the owner should place the requested data. */
055:            private static final XAtom selectionPropertyAtom = XAtom
056:                    .get("XAWT_SELECTION");
057:            /* The maximal length of the property data. */
058:            public static final long MAX_LENGTH = 1000000;
059:            /*
060:             * The maximum data size for ChangeProperty request.
061:             * 100 is for the structure prepended to the request.
062:             */
063:            public static final int MAX_PROPERTY_SIZE;
064:            static {
065:                XToolkit.awtLock();
066:                try {
067:                    MAX_PROPERTY_SIZE = (int) (XlibWrapper
068:                            .XMaxRequestSize(XToolkit.getDisplay()) * 4 - 100);
069:                } finally {
070:                    XToolkit.awtUnlock();
071:                }
072:            }
073:            /* The selection timeout. */
074:            private static long SELECTION_TIMEOUT = UNIXToolkit
075:                    .getDatatransferTimeout();
076:
077:            /* The PropertyNotify event handler for incremental data transfer. */
078:            private static final XEventDispatcher incrementalTransferHandler = new IncrementalTransferHandler();
079:            /* The context for the current request - protected with awtLock. */
080:            private static WindowPropertyGetter propertyGetter = null;
081:
082:            // The orders of the lock acquisition:
083:            //   XClipboard -> XSelection -> awtLock.
084:            //   lock -> awtLock.
085:
086:            /* The X atom for the underlying selection. */
087:            private final XAtom selectionAtom;
088:            /*
089:             * XClipboard.run() is to be called when we lose ownership.
090:             * XClipbioard.checkChange() is to be called when tracking changes of flavors.
091:             */
092:            private final XClipboard clipboard;
093:
094:            /*
095:             * Owner-related variables - protected with synchronized (this).
096:             */
097:
098:            /* The contents supplied by the current owner. */
099:            private Transferable contents = null;
100:            /* The format-to-flavor map for the current owner. */
101:            private Map formatMap = null;
102:            /* The formats supported by the current owner was set. */
103:            private long[] formats = null;
104:            /* The AppContext in which the current owner was set. */
105:            private AppContext appContext = null;
106:            // The X server time of the last XConvertSelection() call;
107:            // protected with 'lock' and awtLock.
108:            private static long lastRequestServerTime;
109:            /* The time at which the current owner was set. */
110:            private long ownershipTime = 0;
111:            // True if we are the owner of this selection.
112:            private boolean isOwner;
113:            // The property in which the owner should place requested targets
114:            // when tracking changes of available data flavors (practically targets).
115:            private volatile XAtom targetsPropertyAtom;
116:            // A set of these property atoms.
117:            private static volatile Set targetsPropertyAtoms;
118:            // The flag used not to call XConvertSelection() if the previous SelectionNotify
119:            // has not been processed by checkChange().
120:            private volatile boolean isSelectionNotifyProcessed;
121:            // Time of calling XConvertSelection().
122:            private long convertSelectionTime;
123:
124:            static {
125:                XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow()
126:                        .getWindow(), new SelectionEventHandler());
127:            }
128:
129:            /*
130:             * Returns the XSelection object for the specified selection atom or
131:             * <code>null</code> if none exists.
132:             */
133:            static XSelection getSelection(XAtom atom) {
134:                return table.get(atom);
135:            }
136:
137:            /**
138:             * Creates a selection object.
139:             *
140:             * @param atom   the selection atom.
141:             * @param clpbrd the corresponding clipoboard
142:             * @exception NullPointerException if atom is <code>null</code>.
143:             */
144:            public XSelection(XAtom atom, XClipboard clpbrd) {
145:                if (atom == null) {
146:                    throw new NullPointerException("Null atom");
147:                }
148:                selectionAtom = atom;
149:                clipboard = clpbrd;
150:                table.put(selectionAtom, this );
151:            }
152:
153:            public XAtom getSelectionAtom() {
154:                return selectionAtom;
155:            }
156:
157:            void initializeSelectionForTrackingChanges() {
158:                targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:"
159:                        + selectionAtom.getName());
160:                if (targetsPropertyAtoms == null) {
161:                    targetsPropertyAtoms = Collections
162:                            .synchronizedSet(new HashSet(2));
163:                }
164:                targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom
165:                        .getAtom()));
166:                // for XConvertSelection() to be called for the first time in getTargetsDelayed()
167:                isSelectionNotifyProcessed = true;
168:            }
169:
170:            void deinitializeSelectionForTrackingChanges() {
171:                if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
172:                    targetsPropertyAtoms.remove(Long
173:                            .valueOf(targetsPropertyAtom.getAtom()));
174:                }
175:                isSelectionNotifyProcessed = false;
176:            }
177:
178:            public synchronized boolean setOwner(Transferable contents,
179:                    Map formatMap, long[] formats, long time) {
180:                long owner = XWindow.getXAWTRootWindow().getWindow();
181:                long selection = selectionAtom.getAtom();
182:
183:                // ICCCM prescribes that CurrentTime should not be used for SetSelectionOwner.
184:                if (time == XlibWrapper.CurrentTime) {
185:                    time = XToolkit.getCurrentServerTime();
186:                }
187:
188:                this .contents = contents;
189:                this .formatMap = formatMap;
190:                this .formats = formats;
191:                this .appContext = AppContext.getAppContext();
192:                this .ownershipTime = time;
193:
194:                XToolkit.awtLock();
195:                try {
196:                    XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
197:                            selection, owner, time);
198:                    if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
199:                            selection) != owner) {
200:
201:                        reset();
202:                        return false;
203:                    }
204:                    isOwner = true;
205:                    if (clipboard != null) {
206:                        clipboard.checkChangeHere(contents);
207:                    }
208:                    return true;
209:                } finally {
210:                    XToolkit.awtUnlock();
211:                }
212:            }
213:
214:            /**
215:             * Blocks the current thread till SelectionNotify or PropertyNotify (in case of INCR transfer) arrives.
216:             */
217:            private static void waitForSelectionNotify(
218:                    WindowPropertyGetter dataGetter)
219:                    throws InterruptedException {
220:                long startTime = System.currentTimeMillis();
221:                XToolkit.awtLock();
222:                try {
223:                    do {
224:                        DataTransferer.getInstance()
225:                                .processDataConversionRequests();
226:                        XToolkit.awtLockWait(250);
227:                    } while (propertyGetter == dataGetter
228:                            && System.currentTimeMillis() < startTime
229:                                    + SELECTION_TIMEOUT);
230:                } finally {
231:                    XToolkit.awtUnlock();
232:                }
233:            }
234:
235:            /*
236:             * Returns the list of atoms that represent the targets for which an attempt
237:             * to convert the current selection will succeed.
238:             */
239:            public long[] getTargets(long time) {
240:                if (XToolkit.isToolkitThread()) {
241:                    throw new Error("UNIMPLEMENTED");
242:                }
243:
244:                long[] formats = null;
245:
246:                synchronized (lock) {
247:                    SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
248:
249:                    WindowPropertyGetter targetsGetter = new WindowPropertyGetter(
250:                            XWindow.getXAWTRootWindow().getWindow(),
251:                            selectionPropertyAtom, 0, MAX_LENGTH, true,
252:                            XlibWrapper.AnyPropertyType);
253:
254:                    try {
255:                        XToolkit.awtLock();
256:                        try {
257:                            propertyGetter = targetsGetter;
258:                            lastRequestServerTime = time;
259:
260:                            XlibWrapper.XConvertSelection(
261:                                    XToolkit.getDisplay(), getSelectionAtom()
262:                                            .getAtom(),
263:                                    XDataTransferer.TARGETS_ATOM.getAtom(),
264:                                    selectionPropertyAtom.getAtom(), XWindow
265:                                            .getXAWTRootWindow().getWindow(),
266:                                    time);
267:
268:                            // If the owner doesn't respond within the
269:                            // SELECTION_TIMEOUT, we report conversion failure.
270:                            try {
271:                                waitForSelectionNotify(targetsGetter);
272:                            } catch (InterruptedException ie) {
273:                                return new long[0];
274:                            } finally {
275:                                propertyGetter = null;
276:                            }
277:                        } finally {
278:                            XToolkit.awtUnlock();
279:                        }
280:                        formats = getFormats(targetsGetter);
281:                    } finally {
282:                        targetsGetter.dispose();
283:                    }
284:                }
285:                return formats;
286:            }
287:
288:            private static long[] getFormats(WindowPropertyGetter targetsGetter) {
289:                long[] formats = null;
290:
291:                if (targetsGetter.isExecuted()
292:                        && !targetsGetter.isDisposed()
293:                        && (targetsGetter.getActualType() == XAtom.XA_ATOM || targetsGetter
294:                                .getActualType() == XDataTransferer.TARGETS_ATOM
295:                                .getAtom())
296:                        && targetsGetter.getActualFormat() == 32) {
297:
298:                    int count = (int) targetsGetter.getNumberOfItems();
299:                    if (count > 0) {
300:                        long atoms = targetsGetter.getData();
301:                        formats = new long[count];
302:                        for (int index = 0; index < count; index++) {
303:                            formats[index] = Native.getLong(atoms + index
304:                                    * XAtom.getAtomSize());
305:                        }
306:                    }
307:                }
308:
309:                return formats != null ? formats : new long[0];
310:            }
311:
312:            // checkChange() will be called on SelectionNotify
313:            void getTargetsDelayed() {
314:                XToolkit.awtLock();
315:                try {
316:                    long curTime = System.currentTimeMillis();
317:                    if (isSelectionNotifyProcessed
318:                            || curTime >= convertSelectionTime
319:                                    + SELECTION_TIMEOUT) {
320:                        convertSelectionTime = curTime;
321:                        XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
322:                                getSelectionAtom().getAtom(),
323:                                XDataTransferer.TARGETS_ATOM.getAtom(),
324:                                targetsPropertyAtom.getAtom(), XWindow
325:                                        .getXAWTRootWindow().getWindow(),
326:                                XlibWrapper.CurrentTime);
327:                        isSelectionNotifyProcessed = false;
328:                    }
329:                } finally {
330:                    XToolkit.awtUnlock();
331:                }
332:            }
333:
334:            /*
335:             * Requests the selection data in the specified format and returns 
336:             * the data provided by the owner.
337:             */
338:            public byte[] getData(long format, long time) throws IOException {
339:                if (XToolkit.isToolkitThread()) {
340:                    throw new Error("UNIMPLEMENTED");
341:                }
342:
343:                byte[] data = null;
344:
345:                synchronized (lock) {
346:                    SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
347:
348:                    WindowPropertyGetter dataGetter = new WindowPropertyGetter(
349:                            XWindow.getXAWTRootWindow().getWindow(),
350:                            selectionPropertyAtom, 0, MAX_LENGTH, false, // don't delete to handle INCR properly.
351:                            XlibWrapper.AnyPropertyType);
352:
353:                    try {
354:                        XToolkit.awtLock();
355:                        try {
356:                            propertyGetter = dataGetter;
357:                            lastRequestServerTime = time;
358:
359:                            XlibWrapper.XConvertSelection(
360:                                    XToolkit.getDisplay(), getSelectionAtom()
361:                                            .getAtom(), format,
362:                                    selectionPropertyAtom.getAtom(), XWindow
363:                                            .getXAWTRootWindow().getWindow(),
364:                                    time);
365:
366:                            // If the owner doesn't respond within the
367:                            // SELECTION_TIMEOUT, we report conversion failure.
368:                            try {
369:                                waitForSelectionNotify(dataGetter);
370:                            } catch (InterruptedException ie) {
371:                                return new byte[0];
372:                            } finally {
373:                                propertyGetter = null;
374:                            }
375:                        } finally {
376:                            XToolkit.awtUnlock();
377:                        }
378:                        if (!dataGetter.isExecuted()) {
379:                            throw new IOException("Owner timed out");
380:                        }
381:
382:                        if (dataGetter.isDisposed()) {
383:                            throw new IOException(
384:                                    "Owner failed to convert data");
385:                        }
386:
387:                        // Handle incremental transfer.
388:                        if (dataGetter.getActualType() == XDataTransferer.INCR_ATOM
389:                                .getAtom()) {
390:
391:                            if (dataGetter.getActualFormat() != 32) {
392:                                throw new IOException(
393:                                        "Unsupported INCR format: "
394:                                                + dataGetter.getActualFormat());
395:                            }
396:
397:                            int count = (int) dataGetter.getNumberOfItems();
398:
399:                            if (count <= 0) {
400:                                throw new IOException("INCR data is missed.");
401:                            }
402:
403:                            long ptr = dataGetter.getData();
404:
405:                            int len = 0;
406:
407:                            {
408:                                // Following Xt sources use the last element.
409:                                long longLength = Native
410:                                        .getLong(ptr, count - 1);
411:
412:                                if (longLength <= 0) {
413:                                    return new byte[0];
414:                                }
415:
416:                                if (longLength > Integer.MAX_VALUE) {
417:                                    throw new IOException(
418:                                            "Can't handle large data block: "
419:                                                    + longLength + " bytes");
420:                                }
421:
422:                                len = (int) longLength;
423:                            }
424:
425:                            dataGetter.dispose();
426:
427:                            ByteArrayOutputStream dataStream = new ByteArrayOutputStream(
428:                                    len);
429:
430:                            while (true) {
431:                                WindowPropertyGetter incrDataGetter = new WindowPropertyGetter(
432:                                        XWindow.getXAWTRootWindow().getWindow(),
433:                                        selectionPropertyAtom, 0, MAX_LENGTH,
434:                                        false, XlibWrapper.AnyPropertyType);
435:
436:                                try {
437:                                    XToolkit.awtLock();
438:                                    XToolkit.addEventDispatcher(XWindow
439:                                            .getXAWTRootWindow().getWindow(),
440:                                            incrementalTransferHandler);
441:
442:                                    propertyGetter = incrDataGetter;
443:
444:                                    try {
445:                                        XlibWrapper
446:                                                .XDeleteProperty(XToolkit
447:                                                        .getDisplay(), XWindow
448:                                                        .getXAWTRootWindow()
449:                                                        .getWindow(),
450:                                                        selectionPropertyAtom
451:                                                                .getAtom());
452:
453:                                        // If the owner doesn't respond within the
454:                                        // SELECTION_TIMEOUT, we terminate incremental
455:                                        // transfer.
456:                                        waitForSelectionNotify(incrDataGetter);
457:                                    } catch (InterruptedException ie) {
458:                                        break;
459:                                    } finally {
460:                                        propertyGetter = null;
461:                                        XToolkit.removeEventDispatcher(XWindow
462:                                                .getXAWTRootWindow()
463:                                                .getWindow(),
464:                                                incrementalTransferHandler);
465:                                        XToolkit.awtUnlock();
466:                                    }
467:
468:                                    // The owner didn't respond - terminate the transfer.
469:                                    if (!incrDataGetter.isExecuted()) {
470:                                        throw new IOException("Owner timed out");
471:                                    }
472:
473:                                    if (incrDataGetter.isDisposed()) {
474:                                        throw new IOException(
475:                                                "Owner failed to convert data");
476:                                    }
477:
478:                                    if (incrDataGetter.getActualFormat() != 8) {
479:                                        throw new IOException(
480:                                                "Unsupported data format: "
481:                                                        + incrDataGetter
482:                                                                .getActualFormat());
483:                                    }
484:
485:                                    count = (int) incrDataGetter
486:                                            .getNumberOfItems();
487:
488:                                    if (count == 0) {
489:                                        break;
490:                                    }
491:
492:                                    if (count > 0) {
493:                                        ptr = incrDataGetter.getData();
494:                                        for (int index = 0; index < count; index++) {
495:                                            dataStream.write(Native.getByte(ptr
496:                                                    + index));
497:                                        }
498:                                    }
499:
500:                                    data = dataStream.toByteArray();
501:
502:                                } finally {
503:                                    incrDataGetter.dispose();
504:                                }
505:                            }
506:                        } else {
507:                            XToolkit.awtLock();
508:                            try {
509:                                XlibWrapper.XDeleteProperty(XToolkit
510:                                        .getDisplay(), XWindow
511:                                        .getXAWTRootWindow().getWindow(),
512:                                        selectionPropertyAtom.getAtom());
513:                            } finally {
514:                                XToolkit.awtUnlock();
515:                            }
516:
517:                            if (dataGetter.getActualFormat() != 8) {
518:                                throw new IOException(
519:                                        "Unsupported data format: "
520:                                                + dataGetter.getActualFormat());
521:                            }
522:
523:                            int count = (int) dataGetter.getNumberOfItems();
524:                            if (count > 0) {
525:                                data = new byte[count];
526:                                long ptr = dataGetter.getData();
527:                                for (int index = 0; index < count; index++) {
528:                                    data[index] = Native.getByte(ptr + index);
529:                                }
530:                            }
531:                        }
532:                    } finally {
533:                        dataGetter.dispose();
534:                    }
535:                }
536:
537:                return data != null ? data : new byte[0];
538:            }
539:
540:            // To be MT-safe this method should be called under awtLock.
541:            boolean isOwner() {
542:                return isOwner;
543:            }
544:
545:            public void lostOwnership() {
546:                isOwner = false;
547:                if (clipboard != null) {
548:                    clipboard.run();
549:                }
550:            }
551:
552:            public synchronized void reset() {
553:                contents = null;
554:                formatMap = null;
555:                formats = null;
556:                appContext = null;
557:                ownershipTime = 0;
558:            }
559:
560:            // Converts the data to the 'format' and if the conversion succeeded stores
561:            // the data in the 'property' on the 'requestor' window.
562:            // Returns true if the conversion succeeded.
563:            private boolean convertAndStore(long requestor, long format,
564:                    long property) {
565:                int dataFormat = 8; /* Can choose between 8,16,32. */
566:                byte[] byteData = null;
567:                long nativeDataPtr = 0;
568:                int count = 0;
569:
570:                try {
571:                    SunToolkit.insertTargetMapping(this , appContext);
572:
573:                    byteData = DataTransferer.getInstance().convertData(this ,
574:                            contents, format, formatMap,
575:                            XToolkit.isToolkitThread());
576:                } catch (IOException ioe) {
577:                    return false;
578:                }
579:
580:                if (byteData == null) {
581:                    return false;
582:                }
583:
584:                count = byteData.length;
585:
586:                try {
587:                    if (count > 0) {
588:                        if (count <= MAX_PROPERTY_SIZE) {
589:                            nativeDataPtr = Native.toData(byteData);
590:                        } else {
591:                            // Initiate incremental data transfer.
592:                            new IncrementalDataProvider(requestor, property,
593:                                    format, 8, byteData);
594:
595:                            nativeDataPtr = XlibWrapper.unsafe
596:                                    .allocateMemory(XAtom.getAtomSize());
597:
598:                            Native.putLong(nativeDataPtr, (long) count);
599:
600:                            format = XDataTransferer.INCR_ATOM.getAtom();
601:                            dataFormat = 32;
602:                            count = 1;
603:                        }
604:
605:                    }
606:
607:                    XToolkit.awtLock();
608:                    try {
609:                        XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
610:                                requestor, property, format, dataFormat,
611:                                XlibWrapper.PropModeReplace, nativeDataPtr,
612:                                count);
613:                    } finally {
614:                        XToolkit.awtUnlock();
615:                    }
616:                } finally {
617:                    if (nativeDataPtr != 0) {
618:                        XlibWrapper.unsafe.freeMemory(nativeDataPtr);
619:                        nativeDataPtr = 0;
620:                    }
621:                }
622:
623:                return true;
624:            }
625:
626:            private void handleSelectionRequest(XSelectionRequestEvent xsre) {
627:                long property = xsre.get_property();
628:                long requestor = xsre.get_requestor();
629:                long requestTime = xsre.get_time();
630:                long format = xsre.get_target();
631:                int dataFormat = 0;
632:                boolean conversionSucceeded = false;
633:
634:                if (ownershipTime != 0
635:                        && (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime)) {
636:
637:                    property = xsre.get_property();
638:
639:                    // Handle MULTIPLE requests as per ICCCM.
640:                    if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
641:                        // The property cannot be 0 for a MULTIPLE request.
642:                        if (property != 0) {
643:                            // First retrieve the list of requested targets.
644:                            WindowPropertyGetter wpg = new WindowPropertyGetter(
645:                                    requestor, XAtom.get(property), 0,
646:                                    MAX_LENGTH, false,
647:                                    XlibWrapper.AnyPropertyType);
648:                            try {
649:                                wpg.execute();
650:
651:                                if (wpg.getActualFormat() == 32
652:                                        && (wpg.getNumberOfItems() % 2) == 0) {
653:                                    long count = wpg.getNumberOfItems() / 2;
654:                                    long pairsPtr = wpg.getData();
655:                                    boolean writeBack = false;
656:                                    for (int i = 0; i < count; i++) {
657:                                        long target = Native.getLong(pairsPtr,
658:                                                2 * i);
659:                                        long prop = Native.getLong(pairsPtr,
660:                                                2 * i + 1);
661:
662:                                        if (!convertAndStore(requestor, target,
663:                                                prop)) {
664:                                            // To report failure, we should replace the
665:                                            // target atom with 0 in the MULTIPLE property.
666:                                            Native.putLong(pairsPtr, 2 * i, 0);
667:                                            writeBack = true;
668:                                        }
669:                                    }
670:                                    if (writeBack) {
671:                                        XToolkit.awtLock();
672:                                        try {
673:                                            XlibWrapper
674:                                                    .XChangeProperty(
675:                                                            XToolkit
676:                                                                    .getDisplay(),
677:                                                            requestor,
678:                                                            property,
679:                                                            wpg.getActualType(),
680:                                                            wpg
681:                                                                    .getActualFormat(),
682:                                                            XlibWrapper.PropModeReplace,
683:                                                            wpg.getData(),
684:                                                            wpg
685:                                                                    .getNumberOfItems());
686:                                        } finally {
687:                                            XToolkit.awtUnlock();
688:                                        }
689:                                    }
690:                                    conversionSucceeded = true;
691:                                }
692:                            } finally {
693:                                wpg.dispose();
694:                            }
695:                        }
696:                    } else {
697:
698:                        // Support for obsolete clients as per ICCCM.
699:                        if (property == 0) {
700:                            property = format;
701:                        }
702:
703:                        if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
704:                            long nativeDataPtr = 0;
705:                            int count = 0;
706:                            dataFormat = 32;
707:
708:                            // Use a local copy to avoid synchronization.
709:                            long[] formatsLocal = formats;
710:
711:                            if (formatsLocal == null) {
712:                                throw new IllegalStateException("Not an owner.");
713:                            }
714:
715:                            count = formatsLocal.length;
716:
717:                            try {
718:                                if (count > 0) {
719:                                    nativeDataPtr = Native
720:                                            .allocateLongArray(count);
721:                                    Native.put(nativeDataPtr, formatsLocal);
722:                                }
723:
724:                                conversionSucceeded = true;
725:
726:                                XToolkit.awtLock();
727:                                try {
728:                                    XlibWrapper.XChangeProperty(XToolkit
729:                                            .getDisplay(), requestor, property,
730:                                            format, dataFormat,
731:                                            XlibWrapper.PropModeReplace,
732:                                            nativeDataPtr, count);
733:                                } finally {
734:                                    XToolkit.awtUnlock();
735:                                }
736:                            } finally {
737:                                if (nativeDataPtr != 0) {
738:                                    XlibWrapper.unsafe
739:                                            .freeMemory(nativeDataPtr);
740:                                    nativeDataPtr = 0;
741:                                }
742:                            }
743:                        } else {
744:                            conversionSucceeded = convertAndStore(requestor,
745:                                    format, property);
746:                        }
747:                    }
748:                }
749:
750:                if (!conversionSucceeded) {
751:                    // Zero property indicates conversion failure.
752:                    property = 0;
753:                }
754:
755:                XSelectionEvent xse = new XSelectionEvent();
756:                try {
757:                    xse.set_type((int) XlibWrapper.SelectionNotify);
758:                    xse.set_send_event(true);
759:                    xse.set_requestor(requestor);
760:                    xse.set_selection(selectionAtom.getAtom());
761:                    xse.set_target(format);
762:                    xse.set_property(property);
763:                    xse.set_time(requestTime);
764:
765:                    XToolkit.awtLock();
766:                    try {
767:                        XlibWrapper.XSendEvent(XToolkit.getDisplay(),
768:                                requestor, false, XlibWrapper.NoEventMask,
769:                                xse.pData);
770:                    } finally {
771:                        XToolkit.awtUnlock();
772:                    }
773:                } finally {
774:                    xse.dispose();
775:                }
776:            }
777:
778:            private static void checkChange(XSelectionEvent xse) {
779:                if (targetsPropertyAtoms == null
780:                        || targetsPropertyAtoms.isEmpty()) {
781:                    // We are not tracking changes.
782:                    return;
783:                }
784:
785:                long propertyAtom = xse.get_property();
786:                long[] formats = null;
787:
788:                if (propertyAtom == XlibWrapper.None) {
789:                    // We threat None property atom as "empty selection".
790:                    formats = new long[0];
791:                } else if (!targetsPropertyAtoms.contains(Long
792:                        .valueOf(propertyAtom))) {
793:                    return;
794:                } else {
795:                    WindowPropertyGetter targetsGetter = new WindowPropertyGetter(
796:                            XWindow.getXAWTRootWindow().getWindow(), XAtom
797:                                    .get(propertyAtom), 0, MAX_LENGTH, true,
798:                            XlibWrapper.AnyPropertyType);
799:                    try {
800:                        targetsGetter.execute();
801:                        formats = getFormats(targetsGetter);
802:                    } finally {
803:                        targetsGetter.dispose();
804:                    }
805:                }
806:
807:                XAtom selectionAtom = XAtom.get(xse.get_selection());
808:                XSelection selection = getSelection(selectionAtom);
809:                if (selection != null) {
810:                    selection.isSelectionNotifyProcessed = true;
811:                    if (selection.clipboard != null) {
812:                        selection.clipboard.checkChange(formats);
813:                    }
814:                }
815:            }
816:
817:            private static class SelectionEventHandler implements 
818:                    XEventDispatcher {
819:                public void dispatchEvent(XEvent ev) {
820:                    switch (ev.get_type()) {
821:                    case XlibWrapper.SelectionNotify: {
822:                        XSelectionEvent xse = ev.get_xselection();
823:                        checkChange(xse);
824:                        XToolkit.awtLock();
825:                        try {
826:                            // Ignore the SelectionNotify event if it is not the response to our last request.
827:                            if (propertyGetter != null
828:                                    && xse.get_time() == lastRequestServerTime) {
829:                                // The property will be None in case of convertion failure.
830:                                if (xse.get_property() == selectionPropertyAtom
831:                                        .getAtom()) {
832:                                    propertyGetter.execute();
833:                                    propertyGetter = null;
834:                                } else if (xse.get_property() == 0) {
835:                                    propertyGetter.dispose();
836:                                    propertyGetter = null;
837:                                }
838:                            }
839:                            XToolkit.awtLockNotifyAll();
840:                        } finally {
841:                            XToolkit.awtUnlock();
842:                        }
843:                        break;
844:                    }
845:                    case XlibWrapper.SelectionRequest: {
846:                        XSelectionRequestEvent xsre = ev
847:                                .get_xselectionrequest();
848:                        long atom = xsre.get_selection();
849:                        XSelection selection = XSelection.getSelection(XAtom
850:                                .get(atom));
851:
852:                        if (selection != null) {
853:                            selection.handleSelectionRequest(xsre);
854:                        }
855:                        break;
856:                    }
857:                    case XlibWrapper.SelectionClear: {
858:                        XSelectionClearEvent xsce = ev.get_xselectionclear();
859:                        long atom = xsce.get_selection();
860:                        XSelection selection = XSelection.getSelection(XAtom
861:                                .get(atom));
862:
863:                        if (selection != null) {
864:                            selection.lostOwnership();
865:                        }
866:
867:                        XToolkit.awtLock();
868:                        try {
869:                            XToolkit.awtLockNotifyAll();
870:                        } finally {
871:                            XToolkit.awtUnlock();
872:                        }
873:                        break;
874:                    }
875:                    }
876:                }
877:            };
878:
879:            private static class IncrementalDataProvider implements 
880:                    XEventDispatcher {
881:                private final long requestor;
882:                private final long property;
883:                private final long target;
884:                private final int format;
885:                private final byte[] data;
886:                private int offset = 0;
887:
888:                // NOTE: formats other than 8 are not supported.
889:                public IncrementalDataProvider(long requestor, long property,
890:                        long target, int format, byte[] data) {
891:                    if (format != 8) {
892:                        throw new IllegalArgumentException(
893:                                "Unsupported format: " + format);
894:                    }
895:
896:                    this .requestor = requestor;
897:                    this .property = property;
898:                    this .target = target;
899:                    this .format = format;
900:                    this .data = data;
901:
902:                    XWindowAttributes wattr = new XWindowAttributes();
903:                    try {
904:                        XToolkit.awtLock();
905:                        try {
906:                            XlibWrapper.XGetWindowAttributes(XToolkit
907:                                    .getDisplay(), requestor, wattr.pData);
908:                            XlibWrapper.XSelectInput(XToolkit.getDisplay(),
909:                                    requestor, wattr.get_your_event_mask()
910:                                            | XlibWrapper.PropertyChangeMask);
911:                        } finally {
912:                            XToolkit.awtUnlock();
913:                        }
914:                    } finally {
915:                        wattr.dispose();
916:                    }
917:                    XToolkit.addEventDispatcher(requestor, this );
918:                }
919:
920:                public void dispatchEvent(XEvent ev) {
921:                    switch (ev.get_type()) {
922:                    case XlibWrapper.PropertyNotify:
923:                        XPropertyEvent xpe = ev.get_xproperty();
924:                        if (xpe.get_window() == requestor
925:                                && xpe.get_state() == XlibWrapper.PropertyDelete
926:                                && xpe.get_atom() == property) {
927:
928:                            int count = data.length - offset;
929:                            long nativeDataPtr = 0;
930:                            if (count > MAX_PROPERTY_SIZE) {
931:                                count = MAX_PROPERTY_SIZE;
932:                            }
933:
934:                            if (count > 0) {
935:                                nativeDataPtr = XlibWrapper.unsafe
936:                                        .allocateMemory(count);
937:                                for (int i = 0; i < count; i++) {
938:                                    Native.putByte(nativeDataPtr + i,
939:                                            data[offset + i]);
940:                                }
941:                            } else {
942:                                assert (count == 0);
943:                                // All data has been transferred.
944:                                // This zero-length data indicates end of transfer.
945:                                XToolkit.removeEventDispatcher(requestor, this );
946:                            }
947:
948:                            XToolkit.awtLock();
949:                            try {
950:                                XlibWrapper.XChangeProperty(XToolkit
951:                                        .getDisplay(), requestor, property,
952:                                        target, format,
953:                                        XlibWrapper.PropModeReplace,
954:                                        nativeDataPtr, count);
955:                            } finally {
956:                                XToolkit.awtUnlock();
957:                            }
958:                            if (nativeDataPtr != 0) {
959:                                XlibWrapper.unsafe.freeMemory(nativeDataPtr);
960:                                nativeDataPtr = 0;
961:                            }
962:
963:                            offset += count;
964:                        }
965:                    }
966:                }
967:            }
968:
969:            private static class IncrementalTransferHandler implements 
970:                    XEventDispatcher {
971:                public void dispatchEvent(XEvent ev) {
972:                    switch (ev.get_type()) {
973:                    case XlibWrapper.PropertyNotify:
974:                        XPropertyEvent xpe = ev.get_xproperty();
975:                        if (xpe.get_state() == XlibWrapper.PropertyNewValue
976:                                && xpe.get_atom() == selectionPropertyAtom
977:                                        .getAtom()) {
978:                            XToolkit.awtLock();
979:                            try {
980:                                if (propertyGetter != null) {
981:                                    propertyGetter.execute();
982:                                    propertyGetter = null;
983:                                }
984:                                XToolkit.awtLockNotifyAll();
985:                            } finally {
986:                                XToolkit.awtUnlock();
987:                            }
988:                        }
989:                        break;
990:                    }
991:                }
992:            };
993:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.