162 lines
4.1 KiB
C
162 lines
4.1 KiB
C
/*
|
||
* 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:
|
||
*/
|