Pasteboard example Carbon

Apprentice
Posts: 11
Joined: 2006.08
Post: #1
Hi!

I'm sorry for being so noob.
Well, basically, for porting my game I need to fill this functions:
One function that takes a wide string from the pasteboard (if there is one string in it)
Other function which puts a wide string into the pasteboard.
And one function to clear the pasteboard.

Reading the API documentation so far, I found the way to have a unique reference to the pasteboard, but after that I don't know what else I should do.

I'm asking if someone can point me to the right examples or documentation to learn to do what I'm asking for. If there were some cut and past c++ code it would be perfect!

I've seen some examples for Cocoa (?) but I need the functions to work on Carbon for evident reasons.

Here is the skeleton I need to fill.
Code:
PasteboardRef GetPasteboard( void )
{
    static PasteboardRef sPasteboard = NULL;

    if ( sPasteboard == NULL )
        PasteboardCreate( kPasteboardClipboard, &sPasteboard );

    return sPasteboard;
}

bool Get_WString_From_Clipboard(std::wstring& out)
{

    return false;
}

void Copy_WString_To_Clipboard( const wchar_t* text)
{

}

void Clear_Clipboard()
{

}

Thanks in advance!
Quote this message in a reply
⌘-R in Chief
Posts: 1,252
Joined: 2002.05
Post: #2
operator Wrote:I've seen some examples for Cocoa (?) but I need the functions to work on Carbon for evident reasons.

No you don't. You can use Cocoa just fine in there.

The Pasteboard Manager is still in 64-bit Carbon, so I guess there's no reason to not use it, though. Other than being icky of course.


The programming guide shows how to add a string to the pasteboard.

http://developer.apple.com/mac/library/D...ementID_10



It's a whole lot easier in Cocoa though.

Code:
NSPasteboard * pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[pb setString:string forType:NSStringPboardType];

string = [pb stringForType:NSStringPboardType];

(You'd have to go from whatever string representation you have to an NSString though, or use a slightly different method.)
Quote this message in a reply
Apprentice
Posts: 11
Joined: 2006.08
Post: #3
FreakSoftware Wrote:No you don't. You can use Cocoa just fine in there.

The Pasteboard Manager is still in 64-bit Carbon, so I guess there's no reason to not use it, though. Other than being icky of course.


The programming guide shows how to add a string to the pasteboard.

http://developer.apple.com/mac/library/D...ementID_10



It's a whole lot easier in Cocoa though.

Code:
NSPasteboard * pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[pb setString:string forType:NSStringPboardType];

string = [pb stringForType:NSStringPboardType];

(You'd have to go from whatever string representation you have to an NSString though, or use a slightly different method.)

I have read that document, but it gives me so many references I don't know were to look at Shock

Cocoa seems easier but I have no idea about that language, nor have idea on how to integrate it with my current project and its implications, dependencies, performance penalties and so Blush

Thanks for your help, I'm going to keep trying
Quote this message in a reply
⌘-R in Chief
Posts: 1,252
Joined: 2002.05
Post: #4
The code listing is pretty straight forward and has a good explanation of what it does.



Quote:1. PasteboardClear clears the current contents of the pasteboard and makes your application the pasteboard owner. You must clear the pasteboard before you can add any data of your own.

Clear as a bell.


Quote:2. You normally call PasteboardSynchronize when your application becomes active, in order to determine if the pasteboard contents have changed. However, it can also be useful to call this function from a plugin to determine if the host application has ownership of the pasteboard. If so, the plugin can go ahead and add data.

Ok, so if you want to know it changed, then call it.... pretty clear.


Quote:3. This code example and others in this section use Apple-defined error-checking macros. For more information about using these macros, see the header AssertMacros.h in /usr/include.

Alright. You don't really care about these specifically.


Quote:4. Call the MLTE function TXNGetSelection to obtain the start and end points of the selected text in the text object.

You're obviously not use MLTE so this is step isn't necessary.

Quote:5. Call the MLTE function TXNGetDataEncoded to extract the selection as non-Unicode text, which is then placed in dataHandle.

Still not using MLTE, but the result of this is to get the text that will be pasted, as Unicode data. You may not need it to be UTF-16, but you'll need your string data with a known encoding at least...


Quote:6. Pasteboards require data to be store as CFData objects, so you need to call CFDataCreate to create a CFData object containing the text data. After creating the object, you can release the original text data. Note that Unicode encoding requires two bytes per character.

Crystal clear.


Quote:7. Call PasteboardPutItemFlavor to place a flavor-variant of the selected text on the pasteboard. Each piece of data must have a flavor associated with it (plain text in this case), and an item ID. In this example, the item ID is simply set as 1, but you can assign any value you wish. If you wanted to add another flavor of the same selected text (say Unicode text), you would specify the same item ID, but a different flavor.

Flavors? Aha. Ok, got it.



Well.... that's it. Pretty simple.

What don't you understand?
Quote this message in a reply
Apprentice
Posts: 11
Joined: 2006.08
Post: #5
Thanks so much. I didn't expect you to take all the work for this explanation, it is really appreciated.

After reviewing it I think this is the way to put text in the pasteboard:

Code:
PasteboardClear( inPasteboard );
PasteboardSynchronize( inPasteboard );
CFDataRef   data = CFDataCreate( kCFAllocatorDefault, (UInt8*)text, (wcslen(text)+1) * sizeof(wchar_t) );
PasteboardPutItemFlavor( inPasteboard, (PasteboardItemID)1, CFSTR("public.utf16-plain-text"), data, 0 );

But to retrieve it, in which format it will it be?
Code:
ItemCount  itemCount;

PasteboardSynchronize( inPasteboard );
PasteboardGetItemCount( inPasteboard, &itemCount );
UInt32 itemIndex = 1; // should be 1 or the itemCount?

PasteboardItemID    itemID;
CFArrayRef          flavorTypeArray;
CFIndex             flavorCount;

PasteboardGetItemIdentifier( inPasteboard, itemIndex, &itemID );
PasteboardCopyItemFlavors( inPasteboard, itemID, &flavorTypeArray );

flavorCount = CFArrayGetCount( flavorTypeArray );

for(CFIndex flavorIndex = 0 ; flavorIndex < flavorCount; flavorIndex++ )
{
   CFStringRef  flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex );

   if (UTTypeConformsTo(flavorType, CFSTR("public.utf16-plain-text")))
   {
       CFDataRef   flavorData;
       PasteboardCopyItemFlavorData( inPasteboard, itemID,flavorType, &flavorData );

       CFIndex  flavorDataSize = CFDataGetLength( flavorData );
       out.resize( flavorDataSize/2 );
       memcpy(&out[0], flavorData, flavorDataSize);
       CFRelease (flavorData);
       break;
   }
}
CFRelease (flavorTypeArray);

A same item can be put in differents formats? for example utf-8 and utf-16? that's the intention of that flavors mechanism?

Should I have to implement different flavors handlers in case the text has been copied in utf-8, ascii or utf-16 ?


(the code above haven't been tested)
Quote this message in a reply
Post Reply