mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
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:
parent
26b1cc16f4
commit
57d25a64dd
4 changed files with 373 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
355
Tools/win32pbs.m
Executable 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;
|
||||
}
|
||||
|
Loading…
Reference in a new issue