Logo Search packages:      
Sourcecode: tcsh version File versions  Download package

clip.c

/*$Header: /src/pub/tcsh/win32/clip.c,v 1.7 2005/03/25 18:46:42 kim 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)(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;


   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,len;
      unsigned char *clipbuf;
      HANDLE hclipbuf;

      USE(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 = *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;



      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(1) {
            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){
                  rbsize <<=1;
                  realbuf = heap_realloc(realbuf,rbsize);
                  if (!realbuf)
                        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);
                  //break;
            }
      }
      CloseHandle(hinpipe);

      bread = rbsize-spleft;

      hclipbuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, bread+256);
      if (!hclipbuf) {
            is_dev_clipboard_active=0;
            return;
      }
      clipbuf = (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(c)
    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++ = '\\'  | (*cp & ~(*cp & CHAR) );
                  *bp++ = '\\'  | (*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(c)
    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(c) //blukas@broadcom.com
    Char c;
{
    USE(c);
      ConsolePageUpOrDown(TRUE);
      return (CC_REFRESH);
}
CCRETVAL
e_page_down(c)
    Char c;
{
    USE(c);
      ConsolePageUpOrDown(FALSE);
      return (CC_REFRESH);
}

Generated by  Doxygen 1.6.0   Back to index