--- /dev/null
+/*
+ * 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;
+}
+\f
+/*
+ * 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
+\f
+/*
+ * 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
+\f
+/*
+ * 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;
+}
+\f
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */