diff options
Diffstat (limited to 'win32/clip.c')
-rw-r--r-- | win32/clip.c | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/win32/clip.c b/win32/clip.c new file mode 100644 index 0000000000000..bc057d8b4e926 --- /dev/null +++ b/win32/clip.c @@ -0,0 +1,570 @@ +/*$Header: /p/tcsh/cvsroot/tcsh/win32/clip.c,v 1.9 2006/03/05 08:59:36 amold Exp $*/ +/*- + * Copyright (c) 1980, 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * clip.c : support for clipboard functions. + * -amol + * + */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <stdio.h> +#include "sh.h" +#include "ed.h" + +BOOL InitApplication(HINSTANCE); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); + + +HWND ghwndmain; + +extern int ctrl_handler(DWORD); +extern void c_insert(int); + +/* + * Creating a hidden window may not be strictly necessary on + * NT, but why tempt fate ? + * -amol + */ + +void clipper_thread(void) { + + MSG msg; + HINSTANCE hInstance = GetModuleHandle(NULL); + + + if (!InitApplication(hInstance)) { + return ; + } + + if (!InitInstance(hInstance, 0)) { + return ; + } + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if ( !ctrl_handler(CTRL_CLOSE_EVENT)) + init_clipboard(); + return; +} +void init_clipboard(void) { + HANDLE ht; + DWORD tid; + + ht = CreateThread(NULL,gdwStackSize, + (LPTHREAD_START_ROUTINE)clipper_thread, NULL,0,&tid); + + if (!ht) + abort(); + CloseHandle(ht); +} + +BOOL InitApplication(HINSTANCE hInstance) +{ + WNDCLASS wc; + + + // Fill in window class structure with parameters that describe + // the main window. + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL;//LoadIcon (hInstance, szAppName); + wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)IntToPtr(COLOR_WINDOW+1); + + wc.lpszMenuName = NULL; + wc.lpszClassName = "tcshclipboard"; + + return RegisterClass(&wc); +} + +// +// FUNCTION: InitInstance(HANDLE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { + HWND hWnd; + + + UNREFERENCED_PARAMETER(nCmdShow); + + hWnd = CreateWindow("tcshclipboard", "tcshclipboard", + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, + NULL, NULL, hInstance, NULL); + + if (!hWnd) { + return (FALSE); + } + + UpdateWindow(hWnd); + ghwndmain = hWnd; + + return (TRUE); +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + + switch (message) { + + case WM_DESTROYCLIPBOARD: + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + return (0); +} + +CCRETVAL e_copy_to_clipboard(Char c) { + unsigned char *cbp; + Char *kp; + int err; + size_t len; + unsigned char *clipbuf; + HANDLE hclipbuf; + + UNREFERENCED_PARAMETER(c); + + if (!ghwndmain) + return (CC_ERROR); + + if (KillRingLen == 0) + return (CC_ERROR); + + len = Strlen(KillRing[YankPos].buf); + + hclipbuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, len+2); + if (!hclipbuf) + return (CC_ERROR); + clipbuf = (unsigned char*)GlobalLock(hclipbuf); + + if (!clipbuf){ + err = GetLastError(); + GlobalFree(hclipbuf); + return (CC_ERROR); + } + + kp = KillRing[YankPos].buf; + cbp = clipbuf; + + while(*kp != '\0') { + *cbp = (u_char)(*kp & CHAR); + cbp++;kp++; + } + *cbp = 0; + + GlobalUnlock(clipbuf); + + if (!OpenClipboard(ghwndmain)) + goto error; + + if (!EmptyClipboard()) + goto error; + + if (SetClipboardData(CF_TEXT,hclipbuf) != hclipbuf){ + err = GetLastError(); + goto error; + + } + + CloseClipboard(); + return (CC_NORM); +error: + GlobalFree(hclipbuf); + CloseClipboard(); + return (CC_ERROR); +} +CCRETVAL e_paste_from_clipboard(Char c) { + HANDLE hclip; + unsigned char *cbp; + Char *cp; + int len; + unsigned char *clipbuf; + + + + UNREFERENCED_PARAMETER(c); + + if (!ghwndmain) + return (CC_ERROR); + if (!IsClipboardFormatAvailable(CF_TEXT)) + return CC_ERROR; + + if (!OpenClipboard(ghwndmain)) + return CC_ERROR; + + + hclip = GetClipboardData(CF_TEXT); + if (hclip) { + clipbuf = (unsigned char*)GlobalLock(hclip); + + cbp = clipbuf; + len = 0; + + while(*cbp && *cbp != '\r') { + len++; + cbp++; + } + cbp = clipbuf; + + cp = Cursor; + + c_insert(len); + + if (LastChar + len >= InputLim) + goto error; + + while(*cbp && *cbp !='\r' && (cp <LastChar) ) { + *cp = *cbp ; + cp++;cbp++; + } + Cursor = cp; + GlobalUnlock(hclip); + } + CloseClipboard(); + + return (CC_REFRESH); +error: + return (CC_ERROR); +} + +int is_dev_clipboard_active=0; +HANDLE ghdevclipthread; + +/* Reads from pipe and write to clipboard */ +void clip_writer_proc(HANDLE hinpipe) { + unsigned char *realbuf; + unsigned char *clipbuf; + unsigned char *ptr; + DWORD bread=0,spleft,err,i,rbsize; + DWORD ptrloc; + HANDLE hclipbuf; + + + rbsize = 4096; + realbuf = heap_alloc(rbsize); + ptr = realbuf; + ptrloc = 0; + spleft = rbsize; + + while(spleft) { + if (!ReadFile(hinpipe,ptr,spleft,&bread,NULL)) { + spleft = GetLastError(); + dprintf("hinpipe returend %d\n",spleft); + if (spleft == ERROR_BROKEN_PIPE) + break; + } + if (bread == 0) + break; + ptr += bread; + ptrloc += bread; + spleft -=bread; + + if (spleft <=0){ + u_char *tmp; + + rbsize <<=1; + + tmp = realbuf; + realbuf = heap_realloc(realbuf,rbsize); + if (!realbuf) { + realbuf = tmp; + break; + } + spleft += rbsize >> 1; + + ptr = realbuf+ptrloc; + + dprintf("updated size now %d, splef %d, ptrloc %d, ptr 0x%08x, realbuf 0x%08x\n",rbsize,spleft,ptrloc,ptr,realbuf); + } + } + CloseHandle(hinpipe); + + bread = rbsize-spleft; + + hclipbuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, bread+256); + if (!hclipbuf) { + is_dev_clipboard_active=0; + return; + } + clipbuf = (u_char*)GlobalLock(hclipbuf); + + if (!clipbuf){ + err = GetLastError(); + GlobalFree(hclipbuf); + is_dev_clipboard_active=0; + return ; + } + ptr = clipbuf; + for (i=0;i <bread;i++) { + + if (realbuf[i] == '\n' && (i >0 && realbuf[i-1] != '\r') ) + *ptr++ = '\r'; + + *ptr++ =realbuf[i]; + + if ((ptr - clipbuf) >= rbsize) + break; + } + *ptr=0; + + heap_free(realbuf); + + GlobalUnlock(clipbuf); + + if (!OpenClipboard(ghwndmain)) + goto error; + + if (!EmptyClipboard()) + goto error; + + if (SetClipboardData(CF_TEXT,hclipbuf) != hclipbuf){ + err = GetLastError(); + goto error; + + } + CloseClipboard(); + is_dev_clipboard_active=0; + return ; +error: + is_dev_clipboard_active=0; + GlobalFree(hclipbuf); + CloseClipboard(); +} +HANDLE create_clip_writer_thread(void) { + HANDLE hread,hwrite; + DWORD tid; + SECURITY_ATTRIBUTES secd; + + if (is_dev_clipboard_active) + return INVALID_HANDLE_VALUE; + secd.nLength=sizeof(secd); + secd.lpSecurityDescriptor=NULL; + secd.bInheritHandle=FALSE; + + if (!CreatePipe(&hread,&hwrite,&secd,0)) { + abort(); + } + is_dev_clipboard_active = 1; + ghdevclipthread = CreateThread(NULL,gdwStackSize, + (LPTHREAD_START_ROUTINE)clip_writer_proc, hread,0,&tid); +// CloseHandle(ht); + return hwrite; +} + +/* Read from clipboard and write to pipe */ +void clip_reader_proc(HANDLE houtpipe) { + + HANDLE hclip; + unsigned char *cbp; + unsigned char *clipbuf; + unsigned char * outbuf,*ptr; + DWORD bwrote, len; + DWORD obsize; + + obsize = 4096; + outbuf = heap_alloc(obsize); + ptr = outbuf; + + + if (!IsClipboardFormatAvailable(CF_TEXT)) + goto done ; + + if (!OpenClipboard(ghwndmain)) + goto done ; + + + len = 0; + hclip = GetClipboardData(CF_TEXT); + if (hclip) { + clipbuf = (unsigned char*)GlobalLock(hclip); + + cbp = clipbuf; + + while(*cbp ) { + *ptr++ = *cbp++; + len++; + if (len == obsize) { + obsize <<= 1; + outbuf = heap_realloc(outbuf,obsize); + if (!outbuf) + break; + ptr = outbuf+len; + } + } + GlobalUnlock(hclip); + } + CloseClipboard(); + + if (!WriteFile(houtpipe,outbuf,len,&bwrote,NULL)) { + ; + } + CloseHandle(houtpipe); + heap_free(outbuf); + +done: + is_dev_clipboard_active=0; + return; +} +HANDLE create_clip_reader_thread(void) { + HANDLE hread,hwrite; + DWORD tid; + SECURITY_ATTRIBUTES secd; + + if (is_dev_clipboard_active) + return INVALID_HANDLE_VALUE; + + secd.nLength=sizeof(secd); + secd.lpSecurityDescriptor=NULL; + secd.bInheritHandle=FALSE; + + if (!CreatePipe(&hread,&hwrite,&secd,0)) { + abort(); + } + is_dev_clipboard_active = 1; + ghdevclipthread = CreateThread(NULL,gdwStackSize, + (LPTHREAD_START_ROUTINE)clip_reader_proc, hwrite,0,&tid); + return hread; +} + +CCRETVAL +e_dosify_next(Char c) +{ + register Char *cp, *buf, *bp; + int len; + BOOL bDone = FALSE; + + + USE(c); + if (Cursor == LastChar) + return(CC_ERROR); + + // worst case assumption + buf = heap_alloc(( LastChar - Cursor + 1)*2*sizeof(Char)); + + cp = Cursor; + bp = buf; + len = 0; + + while( cp < LastChar) { + if ( ((*cp & CHAR) == ' ') && ((cp[-1] & CHAR) != '\\') ) + bDone = TRUE; + if (!bDone && (*cp & CHAR) == '/') { + *bp++ = '\\' | (Char)(*cp & ~(*cp & CHAR) ); + *bp++ = '\\' | (Char)(*cp & ~(*cp & CHAR) ); + + len++; + + cp++; + } + else + *bp++ = *cp++; + + len++; + } + if (Cursor+ len >= InputLim) { + heap_free(buf); + return CC_ERROR; + } + cp = Cursor; + bp = buf; + while(len > 0) { + *cp++ = *bp++; + len--; + } + + heap_free(buf); + + Cursor = cp; + + if(LastChar < Cursor + len) + LastChar = Cursor + len; + + return (CC_REFRESH); +} +/*ARGSUSED*/ +CCRETVAL +e_dosify_prev(Char c) +{ + register Char *cp; + + USE(c); + if (Cursor == InputBuf) + return(CC_ERROR); + /* else */ + + cp = Cursor-1; + /* Skip trailing spaces */ + while ((cp > InputBuf) && ( (*cp & CHAR) == ' ')) + cp--; + + while (cp > InputBuf) { + if ( ((*cp & CHAR) == ' ') && ((cp[-1] & CHAR) != '\\') ) + break; + cp--; + } + if(cp != InputBuf) + Cursor = cp + 1; + else + Cursor = cp; + + return e_dosify_next(0); +} +extern BOOL ConsolePageUpOrDown(BOOL); +CCRETVAL +e_page_up(Char c) //blukas@broadcom.com +{ + USE(c); + ConsolePageUpOrDown(TRUE); + return (CC_REFRESH); +} +CCRETVAL +e_page_down(Char c) +{ + USE(c); + ConsolePageUpOrDown(FALSE); + return (CC_REFRESH); +} |