/*
* tkMacOSXServices.c --
*\
* This file allows the integration of Tk and the Cocoa NSServices API.
*
* Copyright (c) 2010-2019 Kevin Walzer/WordTech Communications LLC.
* Copyright (c) 2019 Marc Culler.
* Copyright (c) 2010 Adrian Robert.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <tkInt.h>
#include <tkMacOSXInt.h>
/*
* Event proc which calls the PerformService procedure.
*/
static int
ServicesEventProc(
TCL_UNUSED(Tcl_Event *),
TCL_UNUSED(int))
{
TkMainInfo *info = TkGetMainInfoList();
Tcl_GlobalEval(info->interp, "::tk::mac::PerformService");
return 1;
}
/*
* The Wish application can send the current selection in the Tk clipboard
* to other applications which accept messages of type NSString. The TkService
* object provides this service via its provideService method. (The method
* must be specified in the application's Info.plist file for this to work.)
*/
@interface TkService : NSObject {
}
+ (void) initialize;
- (void) provideService:(NSPasteboard *)pboard
userData:(NSString *)data
error:(NSString **)error;
- (BOOL) writeSelectionToPasteboard:(NSPasteboard *)pboard
types:(NSArray *)types;
@end
/*
* Class methods.
*/
@implementation TkService
+ (void) initialize {
NSArray *sendTypes = [NSArray arrayWithObjects:@"NSStringPboardType",
@"NSPasteboardTypeString", nil];
[NSApp registerServicesMenuSendTypes:sendTypes returnTypes:sendTypes];
return;
}
/*
* Get the current Tk selection and copy it to the system pasteboard.
*/
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
types:(NSArray *)types
{
NSArray *typesDeclared = nil;
NSString *pboardType = nil;
TkMainInfo *info = TkGetMainInfoList();
for (NSString *typeString in types) {
if ([typeString isEqualToString:@"NSStringPboardType"] ||
[typeString isEqualToString:@"NSPasteboardTypeString"]) {
typesDeclared = [NSArray arrayWithObject:typeString];
pboardType = typeString;
break;
}
}
if (!typesDeclared) {
return NO;
}
Tcl_Eval(info->interp, "selection get");
char *copystring = Tcl_GetString(Tcl_GetObjResult(info->interp));
NSString *writestring = [NSString stringWithUTF8String:copystring];
[pboard declareTypes:typesDeclared owner:nil];
return [pboard setString:writestring forType:pboardType];
}
/*
* This is the method that actually calls the Tk service; it must be specified
* in Info.plist.
*/
- (void)provideService:(NSPasteboard *)pboard
userData:(NSString *)data
error:(NSString **)error
{
NSString *pboardString = nil, *pboardType = nil;
NSArray *types = [pboard types];
Tcl_Event *event;
(void)data;
(void)error;
/*
* Get a string from the private pasteboard and copy it to the general
* pasteboard to make it available to other applications.
*/
for (NSString *typeString in types) {
if ([typeString isEqualToString:@"NSStringPboardType"] ||
[typeString isEqualToString:@"NSPasteboardTypeString"]) {
pboardString = [pboard stringForType:typeString];
pboardType = typeString;
break;
}
}
if (pboardString) {
NSPasteboard *generalpasteboard = [NSPasteboard generalPasteboard];
[generalpasteboard declareTypes:[NSArray arrayWithObjects:pboardType, nil]
owner:nil];
[generalpasteboard setString:pboardString forType:pboardType];
event = (Tcl_Event *)ckalloc(sizeof(Tcl_Event));
event->proc = ServicesEventProc;
Tcl_QueueEvent((Tcl_Event *)event, TCL_QUEUE_TAIL);
}
}
@end
/*
* Instantiate a TkService object and register it with the NSApplication.
* This is called exactly one time from TkpInit.
*/
int
TkMacOSXServices_Init(
TCL_UNUSED(Tcl_Interp *))
{
/*
* Initialize an instance of TkService and register it with the NSApp.
*/
TkService *service = [[TkService alloc] init];
[NSApp setServicesProvider:service];
return TCL_OK;
}
/*
* Local Variables:
* mode: objc
* c-basic-offset: 4
* fill-column: 79
* coding: utf-8
* End:
*/