Added winodws clipboard interaction.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@18298 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2003-12-31 17:21:46 +00:00
parent 512be5eca2
commit 61c347194d
4 changed files with 373 additions and 1 deletions

View file

@ -1,3 +1,12 @@
2003-12-31 Fred Kiefer <FredKiefer@gmx.de>
* Tools/win32pbs.m New file to handle windows clipboard
interaction.
* Tools/GNUmakefile
Compile new file for windows backend.
* Tools/gpbs.m (PasteboardServer -init) for windows backends use
Win32PbOwner as the pasteboard owner class.
2003-12-30 Fred Kiefer <FredKiefer@gmx.de>
* Source/gsc/path.m (-GSSendBezierPath:) preset the count

View file

@ -49,6 +49,10 @@ gpbs_C_FILES += xdnd.c
endif
endif
ifeq ($(BUILD_SERVER),win32)
gpbs_OBJC_FILES += win32pbs.m
endif
MAN1_PAGES = gpbs.1
-include GNUmakefile.preamble

View file

@ -1039,9 +1039,13 @@ NSMutableDictionary *pasteboards = nil;
[permenant addObject: [self pasteboardWithName: NSFindPboard]];
/*
* Ensure that the X pasteboard system is initialised.
* Ensure that the OS pasteboard system is initialised.
*/
#if defined(__WIN32__) || defined(__CYGWIN__)
xPbClass = NSClassFromString(@"Win32PbOwner");
#else
xPbClass = NSClassFromString(@"XPbOwner");
#endif
[xPbClass class];
}
return self;

355
Tools/win32pbs.m Executable file
View file

@ -0,0 +1,355 @@
/*
win32pbs.m
GNUstep pasteboard server - Win32 extension
Copyright (C) 2003 Free Software Foundation, Inc.
Author: Fred Kiefer <fredkiefer@gmx.de>
Date: December 2003
This file is part of the GNUstep Project
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
You should have received a copy of the GNU General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/Foundation.h>
#include <Foundation/NSUserDefaults.h>
#include <AppKit/NSPasteboard.h>
#include <windows.h>
@interface Win32PbOwner : NSObject
{
NSPasteboard *_pb;
HINSTANCE _hinstance;
HWND _hwnd;
BOOL _ignore;
}
- (id) initWithOSPb: (NSPasteboard*) ospb;
- (void) clipboardHasData;
- (void) setClipboardData;
- (void) grapClipboard;
- (void) setupRunLoopInputSourcesForMode: (NSString*)mode;
@end
static Win32PbOwner *wpb = nil;
static HWND hwndNextViewer = NULL;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
@implementation Win32PbOwner
+ (void) initialize
{
if (self == [Win32PbOwner class])
{
wpb = [[Win32PbOwner alloc] initWithOSPb:
[NSPasteboard generalPasteboard]];
[wpb clipboardHasData];
}
}
+ (id) ownerByOsPb: (NSString*)p
{
if ([p isEqual: [NSPasteboard generalPasteboard]])
{
return wpb;
}
else
{
return nil;
}
}
- (id) initWithOSPb: (NSPasteboard*) ospb
{
WNDCLASSEX wc;
_ignore = NO;
_hinstance = (HINSTANCE)GetModuleHandle(NULL);
// Register the main window class.
wc.cbSize = sizeof(wc);
//wc.style = CS_OWNDC;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = _hinstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "GNUstepClipboardClass";
wc.hIconSm = NULL;
if (RegisterClassEx(&wc))
{
_hwnd = CreateWindowEx(0, "GNUstepClipboardClass", "GNUstepClipboard",
0, 0, 0, 10, 10,
HWND_MESSAGE, (HMENU)NULL, _hinstance, NULL);
}
ASSIGN(_pb, ospb);
[self setupRunLoopInputSourcesForMode: NSDefaultRunLoopMode];
return self;
}
- (void) dealloc
{
RELEASE(_pb);
DestroyWindow(_hwnd);
UnregisterClass("GNUstepClipboardClass", _hinstance);
[super dealloc];
}
- (void) clipboardHasString
{
if ((_hwnd != GetClipboardOwner()) &&
IsClipboardFormatAvailable(CF_UNICODETEXT))
{
[_pb declareTypes: [NSArray arrayWithObject: NSStringPboardType]
owner: self];
}
}
/*
The owner of the Windows clipboard did change. Check if this
results in some action for us.
*/
- (void) clipboardHasData
{
if (!_ignore)
{
_ignore = YES;
[self clipboardHasString];
_ignore = NO;
}
}
- (void) setClipboardString
{
HGLOBAL hglb;
LPWSTR lpwstr;
NSString *s;
unsigned int len;
s = [_pb stringForType: NSStringPboardType];
if (s == nil)
{
return;
}
len = [s length];
hglb = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(WCHAR));
if (hglb == NULL)
{
return;
}
// Lock the handle and copy the text to the buffer.
lpwstr = GlobalLock(hglb);
[s getCharacters: lpwstr];
lpwstr[len] = (WCHAR)0;
GlobalUnlock(hglb);
SetClipboardData(CF_UNICODETEXT, hglb);
}
/*
Data is requested from the Windows clipboard. We are already the
owner of the clipboard.
*/
- (void) setClipboardData
{
if (!_ignore)
{
_ignore = YES;
[self setClipboardString];
_ignore = NO;;
}
}
/*
Take over the ownership of the Windows clipboard, but don't provide data
*/
- (void) grapClipboard
{
if (!OpenClipboard(_hwnd))
{
NSLog(@"Failed to get the Win32 clipboard. %d", GetLastError());
return;
}
if (!EmptyClipboard())
{
NSLog(@"Failed to get the Win32 clipboard. %d", GetLastError());
CloseClipboard();
return;
}
SetClipboardData(CF_UNICODETEXT, NULL);
CloseClipboard();
}
/*
* If this gets called, a GNUstep object has grabbed the pasteboard
* or has changed the types of data available from the pasteboard
* so we must tell the Windows system, that we have the current selection.
*/
- (void) pasteboardChangedOwner: (NSPasteboard*)sender
{
if (!_ignore)
{
_ignore = YES;
[self grapClipboard];
_ignore = NO;;
}
}
- (void) provideStringTo: (NSPasteboard*)pb
{
HGLOBAL hglb;
if (!IsClipboardFormatAvailable(CF_UNICODETEXT) ||
!OpenClipboard(_hwnd))
{
return;
}
hglb = GetClipboardData(CF_UNICODETEXT);
if (hglb != NULL)
{
LPWSTR lpwstr;
lpwstr = GlobalLock(hglb);
if (lpwstr != NULL)
{
unsigned int len;
NSString *s;
len = lstrlenW(lpwstr);
s = [NSString stringWithCharacters: lpwstr
length: len];
[pb setString: s forType: NSStringPboardType];
GlobalUnlock(hglb);
}
}
CloseClipboard();
}
- (void) pasteboard: (NSPasteboard*)pb provideDataForType: (NSString*)type
{
if (!_ignore)
{
if ([type isEqual: NSStringPboardType])
{
_ignore = YES;
[self provideStringTo: pb];
_ignore = NO;;
}
}
}
- (void) callback: (id) sender
{
MSG msg;
WINBOOL bRet;
while ((bRet = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) != 0)
{
if (msg.message == WM_QUIT)
{
// Exit the program
return;
}
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
// Don't translate messages, as this would give extra character messages.
DispatchMessage(&msg);
}
}
}
- (void) setupRunLoopInputSourcesForMode: (NSString*)mode
{
// FIXME
NSTimer *timer;
timer = [NSTimer timerWithTimeInterval: 0.1
target: self
selector: @selector(callback:)
userInfo: nil
repeats: YES];
[[NSRunLoop currentRunLoop] addTimer: timer forMode: mode];
}
@end
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
// Add the window to the clipboard viewer chain.
hwndNextViewer = SetClipboardViewer(hwnd);
break;
case WM_CHANGECBCHAIN:
// If the next window is closing, repair the chain.
if ((HWND) wParam == hwndNextViewer)
hwndNextViewer = (HWND) lParam;
// Otherwise, pass the message to the next link.
else if (hwndNextViewer != NULL)
SendMessage(hwndNextViewer, uMsg, wParam, lParam);
break;
case WM_DESTROY:
ChangeClipboardChain(hwnd, hwndNextViewer);
PostQuitMessage(0);
break;
case WM_DRAWCLIPBOARD:
// clipboard contents changed.
if (wpb != nil)
[wpb clipboardHasData];
// Pass the message to the next window in clipboard
// viewer chain.
if (hwndNextViewer != NULL)
SendMessage(hwndNextViewer, uMsg, wParam, lParam);
break;
case WM_RENDERFORMAT:
[wpb setClipboardData];
break;
case WM_RENDERALLFORMATS:
[wpb setClipboardData];
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}