OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [peer/] [gtk/] [GtkSelection.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* GtkClipboard.java - Class representing gtk+ clipboard selection.
2
   Copyright (C) 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.awt.peer.gtk;
40
 
41
import gnu.classpath.Pointer;
42
 
43
import java.awt.datatransfer.*;
44
 
45
import java.io.*;
46
import java.net.*;
47
import java.util.*;
48
 
49
import java.awt.Image;
50
 
51
/**
52
 * Class representing the gtk+ clipboard selection. This is used when
53
 * another program owns the clipboard. Whenever the system clipboard
54
 * selection changes we create a new instance to notify the program
55
 * that the available flavors might have changed. When requested it
56
 * (lazily) caches the targets, and (text, image, or files/uris)
57
 * clipboard contents.
58
 */
59
public class GtkSelection implements Transferable
60
{
61
  /**
62
   * Static lock used for requests of mimetypes and contents retrieval.
63
   */
64
  static private Object requestLock = new Object();
65
 
66
  /**
67
   * Whether we belong to the Clipboard (true) or to the Primary selection.
68
   */
69
  private final boolean clipboard;
70
 
71
  /**
72
   * Whether a request for mimetypes, text, images, uris or byte[] is
73
   * currently in progress. Should only be tested or set with
74
   * requestLock held. When true no other requests should be made till
75
   * it is false again.
76
   */
77
  private boolean requestInProgress;
78
 
79
  /**
80
   * Indicates a requestMimeTypes() call was made and the
81
   * corresponding mimeTypesAvailable() callback was triggered.
82
   */
83
  private boolean mimeTypesDelivered;
84
 
85
  /**
86
   * Set and returned by getTransferDataFlavors. Only valid when
87
   * mimeTypesDelivered is true.
88
   */
89
  private DataFlavor[] dataFlavors;
90
 
91
  /**
92
   * Indicates a requestText() call was made and the corresponding
93
   * textAvailable() callback was triggered.
94
   */
95
  private boolean textDelivered;
96
 
97
  /**
98
   * Set as response to a requestText() call and possibly returned by
99
   * getTransferData() for text targets. Only valid when textDelivered
100
   * is true.
101
   */
102
  private String text;
103
 
104
  /**
105
   * Indicates a requestImage() call was made and the corresponding
106
   * imageAvailable() callback was triggered.
107
   */
108
  private boolean imageDelivered;
109
 
110
  /**
111
   * Set as response to a requestImage() call and possibly returned by
112
   * getTransferData() for image targets. Only valid when
113
   * imageDelivered is true and image is null.
114
   */
115
  private Pointer imagePointer;
116
 
117
  /**
118
   * Cached image value. Only valid when imageDelivered is
119
   * true. Created from imagePointer.
120
   */
121
  private Image image;
122
 
123
  /**
124
   * Indicates a requestUris() call was made and the corresponding
125
   * urisAvailable() callback was triggered.
126
   */
127
  private boolean urisDelivered;
128
 
129
  /**
130
   * Set as response to a requestURIs() call. Only valid when
131
   * urisDelivered is true
132
   */
133
  private List<File> uris;
134
 
135
  /**
136
   * Indicates a requestBytes(String) call was made and the
137
   * corresponding bytesAvailable() callback was triggered.
138
   */
139
  private boolean bytesDelivered;
140
 
141
  /**
142
   * Set as response to a requestBytes(String) call. Only valid when
143
   * bytesDelivered is true.
144
   */
145
  private byte[] bytes;
146
 
147
  /**
148
   * Should only be created by the GtkClipboard class. The clipboard
149
   * should be either GtkClipboard.clipboard or
150
   * GtkClipboard.selection.
151
   */
152
  GtkSelection(GtkClipboard clipboard)
153
  {
154
    this.clipboard = (clipboard == GtkClipboard.clipboard);
155
  }
156
 
157
  /**
158
   * Gets an array of mime-type strings from the gtk+ clipboard and
159
   * transforms them into an array of DataFlavors.
160
   */
161
  public DataFlavor[] getTransferDataFlavors()
162
  {
163
    DataFlavor[] result;
164
    synchronized (requestLock)
165
      {
166
        // Did we request already and cache the result?
167
        if (mimeTypesDelivered)
168
          result = (DataFlavor[]) dataFlavors.clone();
169
        else
170
          {
171
            // Wait till there are no pending requests.
172
            while (requestInProgress)
173
              {
174
                try
175
                  {
176
                    requestLock.wait();
177
                  }
178
                catch (InterruptedException ie)
179
                  {
180
                    // ignored
181
                  }
182
              }
183
 
184
            // If nobody else beat us and cached the result we try
185
            // ourselves to get it.
186
            if (! mimeTypesDelivered)
187
              {
188
                requestInProgress = true;
189
                requestMimeTypes(clipboard);
190
                while (! mimeTypesDelivered)
191
                  {
192
                    try
193
                      {
194
                        requestLock.wait();
195
                      }
196
                    catch (InterruptedException ie)
197
                      {
198
                        // ignored
199
                      }
200
                  }
201
                requestInProgress = false;
202
              }
203
            result = dataFlavors;
204
            if (! GtkClipboard.canCache)
205
              {
206
                dataFlavors = null;
207
                mimeTypesDelivered = false;
208
              }
209
            requestLock.notifyAll();
210
          }
211
      }
212
    return result;
213
  }
214
 
215
  /**
216
   * Callback that sets the available DataFlavors[]. Note that this
217
   * should not call any code that could need the main gdk lock.
218
   */
219
  private void mimeTypesAvailable(String[] mimeTypes)
220
  {
221
    synchronized (requestLock)
222
      {
223
        if (mimeTypes == null)
224
          dataFlavors = new DataFlavor[0];
225
        else
226
          {
227
            // Most likely the mimeTypes include text in which case we add an
228
            // extra element.
229
            ArrayList<DataFlavor> flavorsList =
230
              new ArrayList<DataFlavor>(mimeTypes.length + 1);
231
 
232
            for (int i = 0; i < mimeTypes.length; i++)
233
              {
234
                try
235
                  {
236
                    if (mimeTypes[i] == GtkClipboard.stringMimeType)
237
                      {
238
                        // XXX - Fix DataFlavor.getTextPlainUnicodeFlavor()
239
                        // and also add it to the list.
240
                        flavorsList.add(DataFlavor.stringFlavor);
241
                        flavorsList.add(DataFlavor.plainTextFlavor);
242
                      }
243
                    else if (mimeTypes[i] == GtkClipboard.imageMimeType)
244
                      flavorsList.add(DataFlavor.imageFlavor);
245
                    else if (mimeTypes[i] == GtkClipboard.filesMimeType)
246
                      flavorsList.add(DataFlavor.javaFileListFlavor);
247
                    else
248
                      {
249
                        // We check the target to prevent duplicates
250
                        // of the "magic" targets above.
251
                        DataFlavor target = new DataFlavor(mimeTypes[i]);
252
                        if (! flavorsList.contains(target))
253
                          flavorsList.add(target);
254
                      }
255
                  }
256
                catch (ClassNotFoundException cnfe)
257
                  {
258
                    cnfe.printStackTrace();
259
                  }
260
                catch (NullPointerException npe)
261
                  {
262
                    npe.printStackTrace();
263
                  }
264
              }
265
 
266
            dataFlavors = new DataFlavor[flavorsList.size()];
267
            flavorsList.toArray(dataFlavors);
268
          }
269
 
270
        mimeTypesDelivered = true;
271
        requestLock.notifyAll();
272
      }
273
  }
274
 
275
  /**
276
   * Gets the available data flavors for this selection and checks
277
   * that at least one of them is equal to the given DataFlavor.
278
   */
279
  public boolean isDataFlavorSupported(DataFlavor flavor)
280
  {
281
    DataFlavor[] dfs = getTransferDataFlavors();
282
    for (int i = 0; i < dfs.length; i++)
283
      if (flavor.equals(dfs[i]))
284
        return true;
285
 
286
    return false;
287
  }
288
 
289
  /**
290
   * Helper method that tests whether we already have the text for the
291
   * current gtk+ selection on the clipboard and if not requests it
292
   * and waits till it is available.
293
   */
294
  private String getText()
295
  {
296
    String result;
297
    synchronized (requestLock)
298
      {
299
        // Did we request already and cache the result?
300
        if (textDelivered)
301
          result = text;
302
        else
303
          {
304
            // Wait till there are no pending requests.
305
            while (requestInProgress)
306
              {
307
                try
308
                  {
309
                    requestLock.wait();
310
                  }
311
                catch (InterruptedException ie)
312
                  {
313
                    // ignored
314
                  }
315
              }
316
 
317
            // If nobody else beat us we try ourselves to get and
318
            // caching the result.
319
            if (! textDelivered)
320
              {
321
                requestInProgress = true;
322
                requestText(clipboard);
323
                while (! textDelivered)
324
                  {
325
                    try
326
                      {
327
                        requestLock.wait();
328
                      }
329
                    catch (InterruptedException ie)
330
                      {
331
                        // ignored
332
                      }
333
                  }
334
                requestInProgress = false;
335
              }
336
            result = text;
337
            if (! GtkClipboard.canCache)
338
              {
339
                text = null;
340
                textDelivered = false;
341
              }
342
            requestLock.notifyAll();
343
          }
344
      }
345
    return result;
346
  }
347
 
348
  /**
349
   * Callback that sets the available text on the clipboard. Note that
350
   * this should not call any code that could need the main gdk lock.
351
   */
352
  private void textAvailable(String text)
353
  {
354
    synchronized (requestLock)
355
      {
356
        this.text = text;
357
        textDelivered = true;
358
        requestLock.notifyAll();
359
      }
360
  }
361
 
362
  /**
363
   * Helper method that tests whether we already have an image for the
364
   * current gtk+ selection on the clipboard and if not requests it
365
   * and waits till it is available.
366
   */
367
  private Image getImage()
368
  {
369
    Image result;
370
    synchronized (requestLock)
371
      {
372
        // Did we request already and cache the result?
373
        if (imageDelivered)
374
          result = image;
375
        else
376
          {
377
            // Wait till there are no pending requests.
378
            while (requestInProgress)
379
              {
380
                try
381
                  {
382
                    requestLock.wait();
383
                  }
384
                catch (InterruptedException ie)
385
                  {
386
                    // ignored
387
                  }
388
              }
389
 
390
            // If nobody else beat us we try ourselves to get and
391
            // caching the result.
392
            if (! imageDelivered)
393
              {
394
                requestInProgress = true;
395
                requestImage(clipboard);
396
                while (! imageDelivered)
397
                  {
398
                    try
399
                      {
400
                        requestLock.wait();
401
                      }
402
                    catch (InterruptedException ie)
403
                      {
404
                        // ignored
405
                      }
406
                  }
407
                requestInProgress = false;
408
              }
409
 
410
            if (imagePointer != null)
411
              image = new GtkImage(imagePointer);
412
 
413
            imagePointer = null;
414
            result = image;
415
            if (! GtkClipboard.canCache)
416
              {
417
                image = null;
418
                imageDelivered = false;
419
              }
420
            requestLock.notifyAll();
421
          }
422
      }
423
    return result;
424
  }
425
 
426
  /**
427
   * Callback that sets the available image on the clipboard. Note
428
   * that this should not call any code that could need the main gdk
429
   * lock. Note that we get a Pointer to a GdkPixbuf which we cannot
430
   * turn into a real GtkImage at this point. That will be done on the
431
   * "user thread" in getImage().
432
   */
433
  private void imageAvailable(Pointer pointer)
434
  {
435
    synchronized (requestLock)
436
      {
437
        this.imagePointer = pointer;
438
        imageDelivered = true;
439
        requestLock.notifyAll();
440
      }
441
  }
442
 
443
  /**
444
   * Helper method that test whether we already have a list of
445
   * URIs/Files and if not requests them and waits till they are
446
   * available.
447
   */
448
  private List<File> getURIs()
449
  {
450
    List<File> result;
451
    synchronized (requestLock)
452
      {
453
        // Did we request already and cache the result?
454
        if (urisDelivered)
455
          result = uris;
456
        else
457
          {
458
            // Wait till there are no pending requests.
459
            while (requestInProgress)
460
              {
461
                try
462
                  {
463
                    requestLock.wait();
464
                  }
465
                catch (InterruptedException ie)
466
                  {
467
                    // ignored
468
                  }
469
              }
470
 
471
            // If nobody else beat us we try ourselves to get and
472
            // caching the result.
473
            if (! urisDelivered)
474
              {
475
                requestInProgress = true;
476
                requestURIs(clipboard);
477
                while (! urisDelivered)
478
                  {
479
                    try
480
                      {
481
                        requestLock.wait();
482
                      }
483
                    catch (InterruptedException ie)
484
                      {
485
                        // ignored
486
                      }
487
                  }
488
                requestInProgress = false;
489
              }
490
            result = uris;
491
            if (! GtkClipboard.canCache)
492
              {
493
                uris = null;
494
                urisDelivered = false;
495
              }
496
            requestLock.notifyAll();
497
          }
498
      }
499
    return result;
500
  }
501
 
502
  /**
503
   * Callback that sets the available File list. Note that this should
504
   * not call any code that could need the main gdk lock.
505
   */
506
  private void urisAvailable(String[] uris)
507
  {
508
    synchronized (requestLock)
509
      {
510
        if (uris != null && uris.length != 0)
511
          {
512
            ArrayList<File> list = new ArrayList<File>(uris.length);
513
            for (int i = 0; i < uris.length; i++)
514
              {
515
                try
516
                  {
517
                    URI uri = new URI(uris[i]);
518
                    if (uri.getScheme().equals("file"))
519
                      list.add(new File(uri));
520
                  }
521
                catch (URISyntaxException use)
522
                  {
523
                  }
524
              }
525
            this.uris = list;
526
          }
527
 
528
        urisDelivered = true;
529
        requestLock.notifyAll();
530
      }
531
  }
532
 
533
  /**
534
   * Helper method that requests a byte[] for the given target
535
   * mime-type flavor and waits till it is available. Note that unlike
536
   * the other get methods this one doesn't cache the result since
537
   * there are possibly many targets.
538
   */
539
  private byte[] getBytes(String target)
540
  {
541
    byte[] result;
542
    synchronized (requestLock)
543
      {
544
        // Wait till there are no pending requests.
545
        while (requestInProgress)
546
          {
547
            try
548
              {
549
                requestLock.wait();
550
              }
551
            catch (InterruptedException ie)
552
              {
553
                // ignored
554
              }
555
          }
556
 
557
        // Request bytes and wait till they are available.
558
        requestInProgress = true;
559
        requestBytes(clipboard, target);
560
        while (! bytesDelivered)
561
          {
562
            try
563
              {
564
                requestLock.wait();
565
              }
566
            catch (InterruptedException ie)
567
              {
568
                // ignored
569
              }
570
          }
571
        result = bytes;
572
        bytes = null;
573
        bytesDelivered = false;
574
        requestInProgress = false;
575
 
576
        requestLock.notifyAll();
577
      }
578
    return result;
579
  }
580
 
581
  /**
582
   * Callback that sets the available byte array on the
583
   * clipboard. Note that this should not call any code that could
584
   * need the main gdk lock.
585
   */
586
  private void bytesAvailable(byte[] bytes)
587
  {
588
    synchronized (requestLock)
589
      {
590
        this.bytes = bytes;
591
        bytesDelivered = true;
592
        requestLock.notifyAll();
593
      }
594
  }
595
 
596
  public Object getTransferData(DataFlavor flavor)
597
    throws UnsupportedFlavorException
598
  {
599
    // Note the fall throughs for the "magic targets" if they fail we
600
    // try one more time through getBytes().
601
    if (flavor.equals(DataFlavor.stringFlavor))
602
      {
603
        String text = getText();
604
        if (text != null)
605
          return text;
606
      }
607
 
608
    if (flavor.equals(DataFlavor.plainTextFlavor))
609
      {
610
        String text = getText();
611
        if (text != null)
612
          return new StringBufferInputStream(text);
613
      }
614
 
615
    if (flavor.equals(DataFlavor.imageFlavor))
616
      {
617
        Image image = getImage();
618
        if (image != null)
619
          return image;
620
      }
621
 
622
    if (flavor.equals(DataFlavor.javaFileListFlavor))
623
      {
624
        List<File> uris = getURIs();
625
        if (uris != null)
626
          return uris;
627
      }
628
 
629
    byte[] bytes = getBytes(flavor.getMimeType());
630
    if (bytes == null)
631
      throw new UnsupportedFlavorException(flavor);
632
 
633
    if (flavor.isMimeTypeSerializedObject())
634
      {
635
        try
636
          {
637
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
638
            ObjectInputStream ois = new ObjectInputStream(bais);
639
            return ois.readObject();
640
          }
641
        catch (IOException ioe)
642
          {
643
            ioe.printStackTrace();
644
          }
645
        catch (ClassNotFoundException cnfe)
646
          {
647
            cnfe.printStackTrace();
648
          }
649
      }
650
 
651
    if (flavor.isRepresentationClassInputStream())
652
      return new ByteArrayInputStream(bytes);
653
 
654
    // XXX, need some more conversions?
655
 
656
    throw new UnsupportedFlavorException(flavor);
657
  }
658
 
659
  /*
660
   * Requests text, Image or an byte[] for a particular target from the
661
   * other application. These methods return immediately. When the
662
   * content is available the contentLock will be notified through
663
   * textAvailable, imageAvailable, urisAvailable or bytesAvailable and the
664
   * appropriate field is set.
665
   * The clipboard argument is true if we want the Clipboard, and false
666
   * if we want the (primary) selection.
667
   */
668
  private native void requestText(boolean clipboard);
669
  private native void requestImage(boolean clipboard);
670
  private native void requestURIs(boolean clipboard);
671
  private native void requestBytes(boolean clipboard, String target);
672
 
673
  /* Similar to the above but for requesting the supported targets. */
674
  private native void requestMimeTypes(boolean clipboard);
675
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.