The Application Kit: BClipboard

Derived from: none

Declared in: <app/Clipboard.h>


Overview

The clipboard is a single, system-wide, temporary repository of data. In its normal use, the clipboard is a vehicle for transferring data between applications, or between different parts of the same application. An application adds some amount of data to the clipboard, then some other application (or the same application) retrieves (or "finds") that data. This mechanism permits, most notably, the ability to cut, copy, and paste data items. For example, the BTextView object, in the Interface Kit, uses the clipboard to perform just such operations on text.

The BClipboard class represents the clipboard. As there is but a single clipboard per system, the BClipboard class allows only one BClipboard object. You don't create this object directly in your application; it's created automatically when you boot the machine (so there's no public constructor or destructor for the class). Each application knows this object as be_clipboard . The be_clipboard variable in your application points (ultimately) to the same object as does every other be_clipboard in all other applications.


Using the Clipboard

The central BClipboard functions are these:

You must bracket calls to AddData() and FindData() with calls to Lock() and Unlock() . This prevents other applications from accessing the clipboard while your application is using it. Conversely, if some other application (or if another thread in your application) holds the lock to the clipboard when you call Lock() , your application (or thread) will hang until the current lock holder calls Unlock()--in other words, Lock() will always succeed, even if it has to wait forever to do so. Currently, unfortunately, there's no way to tell if the clipboard is already locked, nor can you specify a time limit beyond which you won't wait for the lock.

AddData() calls should also be bracketed by calls to Clear() and Commit() (see the example below for the calling sequence). Clearing the clipboard removes all data that it currently holds. This may seem harsh, but somebody has to keep the clipboard tidy. The Commit() function tells the clipboard that you're serious about the item-additions that you requested in the previous AddData() calls. If you don't commit your additions, they'll be lost.

The Lock()/Unlock() and Clear()/ Commit() calls can bracket groups of AddData() and FindData() calls. The following code fragments demonstrate the expected sequences of function calls with regard to adding and retrieving clipboard data (the arguments to FindData() and AddData() aren't fully shown in the examples; see the function descriptions, below, for argument details).

Example 1: Adding Data to the Clipboard

   /* Lock the clipboard. */
   be_clipboard->Lock();
   
   /* Clear the clipboard. */
   be_clipboard->Clear();
   
   /* Add some items. */
   be_clipboard->AddData(B_DOUBLE_TYPE, . . .);
   be_clipboard->AddData(B_FLOAT_TYPE, . . .);
   
   /* Commit the additions and unlock the clipboard. */
   be_clipboard->Commit();
   be_clipboard->Unlock();

Example 2: Retrieving Data from the Clipboard

   /* Lock the clipboard. */
   be_clipboard->Lock();
   
   /* Find a bool. */
   bool *bp = (bool *)be_clipboard->FindData(B_BOOL_TYPE, . . .);
   
   /* Copy the bool value (for reasons that are explained in the
    * FindData() description). 
    */
   bool yesOrNo = *bp;
   
   /* Unlock the clipboard */
   be_clipboard->Unlock();

It's possible to mix AddData() and FindData() calls within the same "session," but such a pursuit doesn't correspond to traditional manipulations on selected data.


Member Functions


AddData(), AddText()

      void AddData(ulong type, const void *data, long numBytes)
      void AddText(const char *string)

These functions add a buffer of data to the clipboard. The AddData() function copies numBytes bytes of data starting at data. The clipboard thinks this data is of the type given by the type argument (one of the data type constants--B_BOOL_TYPE, B_DOUBLE_TYPE, B_FLOAT_TYPE, and so on--declared in AppDefs.h).

AddText() is a convenience function that adds a copy of string to the clipboard. Text items are declared to be B_ASCII_TYPE.

You must call Lock() before calling AddData() or AddText(). If you don't, your application will visit the debugger. Furthermore, you must call Unlock() after you've added your items. Multiple invocations of AddData() or AddText() (or both) can be performed within the same Lock()/Unlock() pair. You can add any number of items of the same or different types while you have the clipboard locked.

By convention, you should call Clear() immediately before calling AddData() or AddText() (but after calling Lock()). This will remove all items that the clipboard is currently holding.

After you've added your items to the clipboard (but before you call Unlock()), you must commit the additions by calling Commit(). If you don't commit before you unlock, your additions won't be recorded.

The FindData() and FindText() functions retrieve data that's been added through AddData() and AddText() calls.


Clear()

      void Clear(void)

Erases all items that are currently on the clipboard. Normally, you call Clear() just before you add new data to the clipboard (through invocations of AddData() and AddText()). You must call Lock() before calling Clear(); if you don't, the debugger will tap you on the shoulder.


Commit()

      void Commit(void)

Forces the clipboard to notice the items you added. All calls (or sequence of calls) to AddData() or AddText() must be followed by a call to Commit(), or you'll lose the additions. The call to Commit() must precede the call to Unlock() that balances the call to Lock() that preceded the call to Clear() that worried the cat that killed the rat that ate the malt . . .


CountEntries()

      long CountEntries(ulong type)

Returns the number of items on the clipboard that are of the specified type. The type argument must be one of the data type constants defined in app/AppDefs.h . If type is B_ANY_TYPE, the function returns the total number of current clipboard items.

You must call Lock() before invoking this function; if you don't, it returns NULL.


DataOwner()

      BMessenger DataOwner(void)

Returns a BMessenger object for the application that last committed data to the clipboard. The BMessenger targets that application's BApplication object.


FindData(), FindText()

      void *FindData(ulong type, long *numBytes)
      void *FindData(ulong type, long index, long *numBytes)

      const char *FindText(long *numBytes)

These functions return a pointer to a particular item on the clipboard.

FindData() returns an item of the requested type , which can be any of the data type constants defined in AppDefs.h or an application-defined type code. If an index is provided, it returns the item at that index; indices begin at 0 and count only items of the specified type. If an index isn't supplied, FindData() finds the first item on the clipboard matching the requested type.

FindText() always searches for the first item of type B_ASCII_TYPE .

If the item is found, a pointer to it is returned directly by the function, and the number of bytes of data that comprise the item is returned by reference in numBytes . Keep in mind that this pointer points to data that lies on the clipboard; if you want a permanent copy of the data, you must copy the data that the pointer points to before you unlock the clipboard (as shown in the example in the section Using the Clipboard ).

An individual call or sequence of calls to FindData() and FindText() must be bracketed by invocations of Lock() and Unlock() .

If the function can't find the specified item--for example, if the clipboard doesn't have data of the requested type or the index passed to FindData() is out-of-range--it returns a NULL pointer and, perhaps more telling, sets numBytes to 0. If you don't lock the clipboard before invoking either FindData() or FindText(), you'll find the debugger.


Lock(), Unlock()

      bool Lock(void)
      void Unlock(void)

These functions lock and unlock the clipboard. Locking the clipboard gives your application exclusive permission to invoke the other BClipboard functions. (More accurately, the permission extends only to the very thread in which Lock() is called.) If some other thread already has the clipboard locked when your thread calls Lock(), your thread will wait until the lock-holding thread calls Unlock(). Your thread should also invoke Unlock() when you're done manipulating the clipboard.

Lock() should invariably be successful and return TRUE.

See also: BLooper::Lock()






The Be Book, HTML Edition, for Developer Release 8 of the Be Operating System.

Copyright © 1996 Be, Inc. All rights reserved.

Be, the Be logo, BeBox, BeOS, BeWare, and GeekPort are trademarks of Be, Inc.

Last modified September 6, 1996.